starting working on the ui library; going to be part of onyx/modules when done
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 4 Jun 2021 03:44:39 +0000 (22:44 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 4 Jun 2021 03:44:39 +0000 (22:44 -0500)
build.sh
src/build.onyx
src/config.onyx [new file with mode: 0644]
src/font/bitmap_font.onyx
src/tower.onyx
src/ui/ui.onyx [new file with mode: 0644]

index 9953f849bdca99fc8c9a86d730a9cb3618996e1d..1bbe97e2c6eb7048d93d2b49d4a198cd4dd8f998 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -10,6 +10,6 @@ cp "$ONYX_INSTALLATION_FOLDER/bin/onyx-loader.js" ./site/js/onyx-loader.js
 cp "$ONYX_INSTALLATION_FOLDER/modules/webgl2/webgl2.js" ./site/js/webgl2.js
 cp "$ONYX_INSTALLATION_FOLDER/modules/js_events/js_events.js" ./site/js/js_events.js
 
-onyx -r js --use-post-mvp-features -V -o $TARGET \
+onyx -r js -V --use-post-mvp-features -o $TARGET \
     src/build.onyx \
     -I "$ONYX_INSTALLATION_FOLDER" # Include the folder that contains the "modules"
index 373d6bec477116a8c56db3a78bf91679cf4fabec..85329ace79b9b80554f35e89f6349e192ab5ee63 100644 (file)
@@ -8,5 +8,7 @@
 #load "modules/js_events/module"
 #load "modules/immediate_mode/module"
 
+#load "src/ui/ui"
+#load "src/config"
 #load "src/font/bitmap_font"
 #load "src/tower"
diff --git a/src/config.onyx b/src/config.onyx
new file mode 100644 (file)
index 0000000..7dab26d
--- /dev/null
@@ -0,0 +1,2 @@
+
+DEBUG :: true
index 88078626836a3d7a29150d8175914346666a3c33..5cb0afabe3b7c1e9982c2d6b5decc75edd88dedb 100644 (file)
@@ -42,6 +42,22 @@ Bitmap_Font :: struct {
     get_glyph :: (use bmp: ^Bitmap_Font, char: u8) -> ^Glyph {
         return map.get_ptr(^glyphs, ~~char);
     }
+
+    get_width :: (use bmp: ^Bitmap_Font, text: str, size: f32) -> f32 {
+        width: f32 = 0;
+        for char: text {
+            glyph := map.get_ptr(^glyphs, ~~char);
+
+            if glyph == null {
+                glyph = map.get_ptr(^glyphs, 255);
+                assert(glyph != null, "NO NULL GLYPH");
+            }
+
+            width += glyph.w * size * em;
+        }
+
+        return width;
+    }
 }
 
 Bitmap_Font_Texture :: struct {
@@ -128,4 +144,4 @@ bitmap_font_prepare_glyphs :: (use bmp: ^Bitmap_Font, glyph_str: str) -> bool {
     }
 
     return true;
-}
+}
\ No newline at end of file
index 47a97a4b6b888a6b13149e3cd3eb779fae31aecd..a59d2dfd7674effdae26bd51d8ed7de8730c4c07 100644 (file)
@@ -6,18 +6,15 @@ use package core
 #private_file gfx    :: package immediate_mode
 
 #private_file bitmap_font :: package bitmap_font
+#private_file ui :: package ui
 
 
-
-font : bitmap_font.Bitmap_Font;
-font_texture : gl.GLTexture;
-
 main :: (args: [] cstr) {
     gl.init("game");
     events.init();
     gfx.immediate_renderer_init();
 
-    init_font();
+    ui.init_ui();
 
     gl.enable(gl.BLEND);
     gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
@@ -26,27 +23,6 @@ main :: (args: [] cstr) {
     start_loop();
 }
 
-init_font :: () {
-    font_data := #file_contents "src/res/font_2.data";
-
-    bft := bitmap_font.Bitmap_Font_Texture.{
-        data = font_data,
-        width = 256,
-        height = 256,
-    };
-
-    font = bitmap_font.bitmap_font_create(bft, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 \xff:");
-
-    font_texture = gl.createTexture();
-    gl.bindTexture(gl.TEXTURE_2D, font_texture);
-    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, font_data);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
-    gl.bindTexture(gl.TEXTURE_2D, -1);
-}
-
 last_time := 0;
 #export "loop" () {
     time_now :: () -> i32 #foreign "game" "time_now" ---
@@ -81,16 +57,22 @@ poll_events :: () {
     }
 }
 
-fps := 0;
-fps_timer := 1.0f;
-frames := 0
+#if DEBUG {
+    fps := 0
+    fps_timer := 1.0f
+    frames := 0
+}
+
 update :: (dt: f32) {
-    fps_timer -= dt;
-    frames += 1;
-    if fps_timer < 0 {
-        fps = frames;
-        frames = 0;
-        fps_timer = 1.0f;
+
+    #if DEBUG { // Frame counting
+        fps_timer -= dt;
+        frames += 1;
+        if fps_timer < 0 {
+            fps = frames;
+            frames = 0;
+            fps_timer = 1.0f;
+        }
     }
 }
 
@@ -98,46 +80,37 @@ draw :: () {
     gl.clearColor(0.1, 0.1, 0.1, 1);
     gl.clear(gl.COLOR_BUFFER_BIT);
 
-    fps_buffer : [16] u8;
-    fps_str := conv.str_format("FPS: %i", ~~ fps_buffer, fps);
-    draw_text(fps_str, 0, 0, 32, .{0,1,0});
+    #if false {
+        ui.draw_text("Hello World", 100, 100, 128);
+        ui.draw_text("something else...", 100, 230, 32, .{1,0,0});
 
-    draw_text("Hello World", 100, 100, 128);
-    draw_text("something else...", 100, 230, 32, .{1,0,0});
+        ui.draw_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 100, 300, 16);
+        ui.draw_text("abcdefghijklmnopqrstuvwxyz", 100, 340, 16);
 
-    draw_text("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 100, 300, 16);
-    draw_text("abcdefghijklmnopqrstuvwxyz", 100, 340, 16);
+        gfx.set_texture();
+        gfx.rect(.{100, 400}, .{200, 200}, .{0, 0, 1});
+    }
 
-    gfx.flush();
-}
+    master_rectangle := ui.Rectangle.{ x1 = ~~window_width, y1 = ~~window_height };
 
+    left, right := ui.Flow.split_vertical(master_rectangle, left_percent=0.4);
+    right_top, right_bottom := ui.Flow.split_horizontal(right, top_height=200);
 
+    ui.draw_rect(left,  .{ 0.5, 0, 0.5 });
+    ui.draw_rect(right, .{ 0, 0.25, 0.5 });
+    ui.draw_rect(right_top, .{ 1, 0, 0 });
+    ui.draw_text("Something here", right_bottom.x0, right_bottom.y0, 48, .{ 1, 1, 1 });
 
+    #if DEBUG {
+        fps_buffer : [16] u8;
+        fps_str := conv.str_format("FPS: %i", ~~ fps_buffer, fps);
+        ui.draw_text(fps_str, 0, 0, 32, .{0,1,0});
+    }
 
 
-draw_text :: (text: str, x: f32, y: f32, size := 32.0f, color := gfx.Color4.{1,1,1}) {
+    gfx.flush();
+}
 
-    gl.bindTexture(gl.TEXTURE_2D, font_texture);
-    gfx.set_texture(0);
 
-    for char: text {
-        glyph := font->get_glyph(char);
-        
-        if glyph == null {
-            glyph = font->get_glyph(255);
-            assert(glyph != null, "NO NULL GLYPH");
-        }
 
-        gfx.textured_rect(
-            .{ x, y },
-            .{ glyph.w * size * font.em, glyph.h * size * font.em },
-            .{ glyph.x0, glyph.y0 },
-            .{ glyph.x1 - glyph.x0, glyph.y1 - glyph.y0 },
-            color = color);
 
-        x += glyph.w * size * 16;
-    }
-    
-    gfx.flush();
-    gl.bindTexture(gl.TEXTURE_2D, -1);
-}
diff --git a/src/ui/ui.onyx b/src/ui/ui.onyx
new file mode 100644 (file)
index 0000000..ccb6b2f
--- /dev/null
@@ -0,0 +1,168 @@
+package ui
+
+#private_file gfx :: package immediate_mode
+#private_file bitmap_font :: package bitmap_font
+#private_file gl :: package gl
+#private_file math :: package core.math
+
+#private font : bitmap_font.Bitmap_Font;
+#private font_texture : gl.GLTexture;
+
+@Temporary
+DEFAULT_TEXT_SIZE :: 32.0f
+
+
+init_ui :: () {
+    init_font();
+}
+
+#private init_font :: () {
+    font_data := #file_contents "./../res/font_2.data";
+
+    bft := bitmap_font.Bitmap_Font_Texture.{
+        data = font_data,
+        width = 256,
+        height = 256,
+    };
+
+    font = bitmap_font.bitmap_font_create(bft, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 \xff:");
+
+    font_texture = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, font_texture);
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, font_data);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+    gl.bindTexture(gl.TEXTURE_2D, -1);
+}
+
+get_text_width :: (text: str, size: f32 = DEFAULT_TEXT_SIZE) -> f32 {
+    return font->get_width(text, size);
+}
+
+// 'x' and 'y' are the top-left coordinates of the text. 'y' is NOT the baseline.
+draw_text :: (text: str, x: f32, y: f32, size := DEFAULT_TEXT_SIZE, color := gfx.Color4.{1,1,1}) {
+    gl.bindTexture(gl.TEXTURE_2D, font_texture);
+    gfx.set_texture(0);
+
+    for char: text {
+        glyph := font->get_glyph(char);
+        
+        if glyph == null {
+            glyph = font->get_glyph(255);
+            assert(glyph != null, "NO NULL GLYPH");
+        }
+
+        gfx.textured_rect(
+            .{ x, y },
+            .{ glyph.w * size * font.em, glyph.h * size * font.em },
+            .{ glyph.x0, glyph.y0 },
+            .{ glyph.x1 - glyph.x0, glyph.y1 - glyph.y0 },
+            color = color);
+
+        x += glyph.w * size * font.em;
+    }
+    
+    gfx.flush();
+    gl.bindTexture(gl.TEXTURE_2D, -1);
+}
+
+draw_rect :: proc {
+    (use r: Rectangle, color := gfx.Color4.{1,1,1}) {
+        gfx.set_texture();
+
+        width, height := Rectangle.dimensions(r);
+        gfx.rect(.{ x0, y0 }, .{ width, height }, color);
+    },
+
+    (x: f32, y: f32, w: f32, h: f32, color := gfx.Color4.{1,1,1}) {
+        gfx.set_texture();
+        gfx.rect(.{ x, y }, .{ w, h }, color);
+    }
+}
+
+
+
+Rectangle :: struct {
+    //
+    // x0,y0 ------------+
+    //   |               |
+    //   |               |
+    //   +------------ x1, y1
+    //
+
+    x0: f32 = 0;
+    y0: f32 = 0;
+    x1: f32 = 0;
+    y1: f32 = 0;
+
+    width  :: (use r: Rectangle) -> f32 do return math.abs(x1 - x0);
+    height :: (use r: Rectangle) -> f32 do return math.abs(y1 - y0);
+
+    dimensions :: (use r: Rectangle) -> (width: f32, height: f32) {
+        return math.abs(x1 - x0), math.abs(y1 - y0);
+    }
+
+    top_left     :: (use r: Rectangle) -> (x: f32, y: f32) do return math.min(x0, x1), math.min(y0, y1);
+    bottom_right :: (use r: Rectangle) -> (x: f32, y: f32) do return math.max(x0, x1), math.max(y0, y1);
+}
+
+
+
+// UI Flow
+
+Flow :: struct {
+    split_vertical :: proc {
+        (r: Rectangle, left_percent: f32) -> (left: Rectangle, right: Rectangle) {
+            return split_vertical(r, left_width=left_percent * Rectangle.width(r));
+        },
+
+        (r: Rectangle, right_percent: f32) -> (left: Rectangle, right: Rectangle) {
+            return split_vertical(r, right_width=right_percent * Rectangle.width(r));
+        },
+
+        (r: Rectangle, left_width: f32) -> (left: Rectangle, right: Rectangle) {
+            x0, y0 := Rectangle.top_left(r);
+            x1, y1 := Rectangle.bottom_right(r);
+
+            return .{ x0=x0, x1=x0+left_width, y0=y0, y1=y1 },
+                   .{ x0=x0+left_width, x1=x1, y0=y0, y1=y1 };
+        },
+
+        (r: Rectangle, right_width: f32) -> (left: Rectangle, right: Rectangle) {
+            x0, y0 := Rectangle.top_left(r);
+            x1, y1 := Rectangle.bottom_right(r);
+
+            return .{ x0=x0, x1=x1-right_width, y0=y0, y1=y1 },
+                   .{ x0=x1-right_width, x1=x1, y0=y0, y1=y1 };
+        }
+    }
+
+
+    split_horizontal :: proc {
+        (r: Rectangle, top_percent: f32) -> (top: Rectangle, bottom: Rectangle) {
+            return split_horizontal(r, top_height=top_percent * Rectangle.height(r));
+        },
+
+        (r: Rectangle, bottom_percent: f32) -> (top: Rectangle, bottom: Rectangle) {
+            return split_horizontal(r, bottom_height=bottom_percent * Rectangle.height(r));
+        },
+
+        (r: Rectangle, top_height: f32) -> (top: Rectangle, bottom: Rectangle) {
+            x0, y0 := Rectangle.top_left(r);
+            x1, y1 := Rectangle.bottom_right(r);
+
+            return .{ x0=x0, x1=x1, y0=y0, y1=y0+top_height },
+                   .{ x0=x0, x1=x1, y0=y0+top_height, y1=y1 };
+        },
+
+        (r: Rectangle, bottom_height: f32) -> (top: Rectangle, bottom: Rectangle) {
+            x0, y0 := Rectangle.top_left(r);
+            x1, y1 := Rectangle.bottom_right(r);
+
+            return .{ x0=x0, x1=x1, y0=y0, y1=y1-bottom_height },
+                   .{ x0=x0, x1=x1, y0=y1-bottom_height, y1=y1 };
+        }
+    }
+}
\ No newline at end of file