starting to work on ui
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 6 Jul 2021 03:26:02 +0000 (22:26 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 6 Jul 2021 03:26:02 +0000 (22:26 -0500)
res/colors.json [new file with mode: 0644]
server.sh [new file with mode: 0755]
site/js/webgl2.js
src/config.onyx
src/main.onyx

diff --git a/res/colors.json b/res/colors.json
new file mode 100644 (file)
index 0000000..31095c1
--- /dev/null
@@ -0,0 +1,19 @@
+{
+    "dark_background": [ 0.1,  0.1,  0.1  ],
+    "background":      [ 0.15, 0.15, 0.15 ],
+    "foreground":      [ 0.9,  0.9,  0.9  ],
+
+    "keyword":   [ 0.7, 0.7, 1.0 ],
+    "value":     [ 0.8, 1.0, 0.8 ],
+    "jumppoint": [ 1, 0.5, 0.5   ],
+
+    "primary":       [ 0.051, 0.278, 0.631 ],
+    "primary_light": [ 0.329, 0.451, 0.827 ],
+    "primary_dark":  [ 0,     0.129, 0.443 ],
+    "primary_text":  [ 1,     1,     1     ],
+
+    "secondary":       [ 0,     0.376, 0.392 ],
+    "secondary_light": [ 0.259, 0.557, 0.573 ],
+    "secondary_dark":  [ 0,     0.212, 0.227 ],
+    "secondary_text":  [ 1,     1,     1     ]
+}
diff --git a/server.sh b/server.sh
new file mode 100755 (executable)
index 0000000..da47832
--- /dev/null
+++ b/server.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+$(which python) -m http.server
\ No newline at end of file
index bd5339936379059d152f471dea94bb1e7f0dce32..df8936d2cddac644a318831807574d45c2bbe742 100644 (file)
@@ -38,10 +38,34 @@ window.ONYX_MODULES.push({
             gl.bindBuffer(target, buffers[buffer]);
         }
     },
-    bindFramebuffer(target, framebuffer) { gl.bindFramebuffer(target, framebuffers[framebuffer]); },
-    bindRenderbuffer(target, renderbuffer) { gl.bindRenderbuffer(target, renderbuffers[renderbuffer]); },
-    bindTexture(target, texture) { gl.bindTexture(target, textures[texture]); },
-    bindVertexArray(vertexArray) { gl.bindVertexArray(vertexArrays[vertexArray]); },
+    bindFramebuffer(target, framebuffer) {
+        if (framebuffer == -1) {
+            gl.bindFramebuffer(target, null);
+        } else {
+            gl.bindFramebuffer(target, framebuffers[framebuffer]);
+        }
+    },
+    bindRenderbuffer(target, renderbuffer) {
+        if (renderbuffer == -1) {
+            gl.bindRenderbuffer(target, null);
+        } else {
+            gl.bindRenderbuffer(target, renderbuffers[renderbuffer]);
+        }
+    },
+    bindTexture(target, texture) {
+        if (texture == -1) {
+            gl.bindTexture(target, null);
+        } else {
+            gl.bindTexture(target, textures[texture]);
+        }
+    },
+    bindVertexArray(vertexArray) {
+        if (vertexArray == -1) {
+            gl.bindVertexArray(null);
+        } else {
+            gl.bindVertexArray(vertexArrays[vertexArray]); 
+        }
+    },
 
     blendColor(red, green, blue, alpha) { gl.blendColor(red, green, blue, alpha); },
     blendEquation(mode) { gl.blendEquation(mode); },
@@ -67,7 +91,7 @@ window.ONYX_MODULES.push({
         canvas.width = width;
         canvas.height = height;
     },
-    checkFrameBufferStatus(target) { return gl.checkFrameBufferStatus(target); },
+    checkFramebufferStatus(target) { return gl.checkFramebufferStatus(target); },
     clear(bit) { gl.clear(bit); },
     clearColor(r, g, b, a) { gl.clearColor(r, g, b, a); },
     clearDepth(depth) { gl.clearDepth(depth); },
@@ -83,8 +107,8 @@ window.ONYX_MODULES.push({
         gl.compressedSubTexImage2D(target, level, internalformat, xoff, yoff, width, height, format, pixels);
     },
     copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size) { gl.copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); },
-    copyTexImage2D(target, level, internalforamt, x, y, width, height, border) {
-        gl.copyTexImage2D(target, level, internalforamt, x, y, width, height, border);
+    copyTexImage2D(target, level, internalformat, x, y, width, height, border) {
+        gl.copyTexImage2D(target, level, internalformat, x, y, width, height, border);
     },
     copyTexSubImage2D(target, level, xoff, yoff, x, y, width, height) {
         gl.copyTexSubImage2D(target, level, xoff, yoff, x, y, width, height);
@@ -229,8 +253,9 @@ window.ONYX_MODULES.push({
         gl.readPixels(x, y, width, height, format, type, pixeldata);
     },
     readBuffer(src) { gl.readBuffer(src); },
-    renderbufferStorageMultisample(target, samples, internalforamt, width, height) {
-        gl.renderbufferStorageMultisample(target, samples, internalforamt, width, height);
+    renderbufferStorage(target, internalformat, width, height) { gl.renderbufferStorage(target, internalformat, width, height); },
+    renderbufferStorageMultisample(target, samples, internalformat, width, height) {
+        gl.renderbufferStorageMultisample(target, samples, internalformat, width, height);
     },
     sampleCoverage(value, invert) { gl.sampleCoverage(value, invert); },
     scissor(x, y, width, height) { gl.scissor(x, y, width, height); },
@@ -248,12 +273,13 @@ window.ONYX_MODULES.push({
     stencilMaskSeparate(face, mask) { gl.stencilMaskSeparate(face, mask); },
     stencilOp(fail, zfail, mask) { gl.stencilOp(fail, zfail, mask); },
     stencilOpSeparate(face, fail, zfail, zpass) { gl.stencilOpSeparate(face, fail, zfail, zpass); },
-    texImage2D(target, level, internalforamt, width, height, border, format, type, pixels, pixelslen) {
+    texImage2D(target, level, internalformat, width, height, border, format, type, pixels, pixelslen) {
         const data = new Uint8Array(window.ONYX_MEMORY.buffer, pixels, pixelslen);
-        gl.texImage2D(target, level, internalforamt, width, height, border, format, type, data);
+        gl.texImage2D(target, level, internalformat, width, height, border, format, type, data);
     },
     texParameterf(target, pname, param) { gl.texParameterf(target, pname, param); },
     texParameteri(target, pname, param) { gl.texParameteri(target, pname, param); },
+    texStorage2D(target, levels, internalformat, width, height) { gl.texStorage2D(target, levels, internalformat, width, height); },
     texSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels, pixelslen) {
         const data = new Uint8Array(window.ONYX_MEMORY.buffer, pixels, pixelslen);
         gl.texSubImage2D(target, level, xoff, yoff, width, height, format, type, data);
index f3921b062d8ef2ea37803cfa7e8e91f6abfd18fc..fc36faca32ab9a8df1ab4a9b19f3fef5233c487b 100644 (file)
@@ -1,2 +1,27 @@
 package config
 
+#if (package runtime).Runtime != (package runtime).Runtime_Wasi {
+
+use package immediate_mode { Color4 }
+
+
+Colors : struct {
+    dark_background : Color4;
+    background      : Color4;
+    foreground      : Color4;
+
+    keyword   : Color4;
+    value     : Color4;
+    jumppoint : Color4;
+
+    primary         : Color4;
+    primary_light   : Color4;
+    primary_dark    : Color4;
+    primary_text    : Color4;
+    secondary       : Color4;
+    secondary_light : Color4;
+    secondary_dark  : Color4;
+    secondary_text  : Color4;
+}
+
+}
index 8e08565c22c67df5f43ca2f2b4b1cf5607a3243d..1ce53931848f6d28a588d65f3ad4fa58bb2ddd6f 100644 (file)
@@ -14,17 +14,87 @@ main :: (args: [] cstr) {
     start_loop();
 }
 
+test_canvas : gfx.Canvas;
+
 init :: () {
     gl.init("main_canvas");
     events.init();
     gfx.immediate_renderer_init();
+    load_colors();
 
     ui.init_ui();
 
     gl.enable(gl.BLEND);
     gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
+
+    test_canvas = gfx.create_canvas(1000, 1000);
+    {
+        time_now :: () -> i32 #foreign "decompiler" "time_now" ---
+        random.set_seed(time_now() / 1000);
+
+        gfx.use_canvas(^test_canvas);
+        defer gfx.use_canvas(null);
+
+        gl.clearColor(0, 0, 0, 0.6);
+        gl.clear(gl.COLOR_BUFFER_BIT);
+
+        gfx.set_mode(.Lines);
+        gfx.set_texture();
+        gl.lineWidth(10);
+
+        pv := gfx.Vector2.{ 0, 0 };
+        for i: 11 {
+            pv = .{ ~~random.between(0, 1000), ~~random.between(0, 1000) };
+            gfx.vertex(pv, config.Colors.primary);
+
+            pv = .{ ~~random.between(0, 1000), ~~random.between(0, 1000) };
+            gfx.vertex(pv, config.Colors.primary);
+        }
+
+        gfx.set_mode(.Triangles);
+    }
+
+    load_colors :: () {
+        json :: package json
+
+        @DynamicLoading // Currently, this file is just baked into the binary. When a mechanism
+        // is added to easily ask JS to make a fetch request for a file, that can be used here.
+        colors_json := #file_contents "res/colors.json";
+
+        arena := alloc.arena.make(context.allocator, 4096);
+        defer alloc.arena.free(^arena);
+        colors := json.decode(colors_json, alloc.arena.make_allocator(^arena));
+        defer json.free(colors);
+
+        config.Colors.dark_background = decode_color(colors.root["dark_background"]);
+        config.Colors.background      = decode_color(colors.root["background"]);
+        config.Colors.foreground      = decode_color(colors.root["foreground"]);
+
+        config.Colors.keyword         = decode_color(colors.root["keyword"]);
+        config.Colors.value           = decode_color(colors.root["value"]);
+        config.Colors.jumppoint       = decode_color(colors.root["jumppoint"]);
+
+        config.Colors.primary         = decode_color(colors.root["primary"]);
+        config.Colors.primary_light   = decode_color(colors.root["primary_light"]);
+        config.Colors.primary_dark    = decode_color(colors.root["primary_dark"]);
+        config.Colors.primary_text    = decode_color(colors.root["primary_text"]);
+
+        config.Colors.secondary       = decode_color(colors.root["secondary"]);
+        config.Colors.secondary_light = decode_color(colors.root["secondary_light"]);
+        config.Colors.secondary_dark  = decode_color(colors.root["secondary_dark"]);
+        config.Colors.secondary_text  = decode_color(colors.root["secondary_text"]);
+
+        decode_color :: (v: ^json.Value) -> gfx.Color4 {
+            return .{
+                r = ~~v[0]->as_float(),
+                g = ~~v[1]->as_float(),
+                b = ~~v[2]->as_float(),
+            };
+        }
+    }
 }
 
+
 last_time := 0;
 #export "loop" () {
     time_now :: () -> i32 #foreign "decompiler" "time_now" ---
@@ -94,8 +164,7 @@ poll_events :: () -> bool {
                 window_height = event.resize.height;
 
                 gl.setSize(event.resize.width, event.resize.height);
-                gl.viewport(0, 0, event.resize.width, event.resize.height);
-                gfx.use_ortho_projection(0, ~~window_width, 0, ~~window_height);
+                gfx.set_window_size(event.resize.width, event.resize.height);
             }
         }
     }
@@ -106,15 +175,71 @@ poll_events :: () -> bool {
 update :: (dt: f32) {
 }
 
-red := 1.0f;
 draw :: () {
-    gl.clearColor(red, 0, 0, 1);
+    bg_color := config.Colors.background;
+    gl.clearColor(bg_color.r, bg_color.g, bg_color.b, bg_color.a);
     gl.clear(gl.COLOR_BUFFER_BIT);
 
-    if ui.button(.{ 100, 100, 300, 200 }, "Test") {
-        red = 1 - red;
-    }
+    window_rectangle := ui.Rectangle.{ 0, 0, ~~window_width, ~~window_height };
+
+    draw_background_lines(~~window_width, ~~window_height, 0, 0, line_color=config.Colors.dark_background);
+    draw_menu_bar(window_rectangle);
+
+    gfx.set_texture(^test_canvas.color_texture);
+    gfx.textured_rect(.{ 300, 100 }, .{ 800, 400 }, .{ 0, 0 }, .{ 1, 1 });
+    gfx.set_texture();
 
     gfx.flush();
     ui.clear_buttons();
 }
+
+#private_file
+draw_menu_bar :: (window_rectangle: ui.Rectangle) {
+    menu_bar, _ := ui.Flow.split_horizontal(window_rectangle, top_height=32);
+
+    ui.draw_rect(menu_bar, color=.{ 0.2, 0.2, 0.2 });
+
+    menu_button_theme := ui.default_button_theme;
+    menu_button_theme.border_width = 2;
+    menu_button_theme.font_size = .9;
+
+    button_rect : ui.Rectangle;
+
+    button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100);
+    ui.button(button_rect, "File", theme=^menu_button_theme);
+    button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100);
+    ui.button(button_rect, "Edit", theme=^menu_button_theme);
+    button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100);
+    ui.button(button_rect, "View", theme=^menu_button_theme);
+    button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100);
+    ui.button(button_rect, "Help", theme=^menu_button_theme);
+}
+
+#private_file
+draw_background_lines :: (width: f32, height: f32, offset_x: f32, offset_y: f32, line_color := gfx.Color4.{0.2, 0.2, 0.2}, line_spacing := 32.0f) {
+    gl :: package gl
+
+    gfx.set_mode(.Lines);
+    gfx.set_texture();
+    gl.lineWidth(4);
+
+    // "Modulus" to the nearest (-line_spacing, line_spacing) for both x and y.
+    offset_x /= line_spacing;
+    offset_y /= line_spacing;
+    offset_x = line_spacing * (offset_x - math.trunc(offset_x));
+    offset_y = line_spacing * (offset_y - math.trunc(offset_y));
+
+    for i: cast(i32) (math.ceil(width / line_spacing)) + 1 {
+        x := offset_x + ~~i * line_spacing;
+        gfx.vertex(.{ x, 0 }, line_color);
+        gfx.vertex(.{ x, height }, line_color);
+    }
+
+    for i: cast(i32) (math.ceil(height / line_spacing)) + 1 {
+        y := offset_y + ~~i * line_spacing;
+        gfx.vertex(.{ 0, y }, line_color);
+        gfx.vertex(.{ width, y }, line_color);
+    }
+
+    gfx.set_mode(.Triangles);
+}