updated tag syntax; scene renders in middle
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 27 Feb 2022 02:17:06 +0000 (20:17 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 27 Feb 2022 02:17:06 +0000 (20:17 -0600)
12 files changed:
run_tree/scenes/default.items
run_tree/scenes/quick_save_new.scene
src/build.onyx
src/entity/editor.onyx
src/entity/items.onyx
src/entity/manager.onyx
src/entity/player.onyx
src/game.onyx
src/gfx/canvas.onyx
src/gfx/shader.onyx
src/main.onyx
src/utils/vecmath.onyx

index 99408993faee53282bdfe56b714a8bd0b0fef2e8..5b797fead8b788afd26c6f09e7d61f002fd185fa 100644 (file)
@@ -1,6 +1,5 @@
 :beer
 name="Beer"
 texture_path="./assets/images/beer-1.png"
-weight=12.34
 
 
index 4b15a33701dc83b544e355744c3e11f45c330f31..ce7e1f9ac764af54df6dde8519d4023f81c6b916 100644 (file)
@@ -1,26 +1,26 @@
 [Wall]
 id = 10
 flags = 2
-pos.x = 168.0000
-pos.y = 320.0000
-size.x = 336.0000
-size.y = 32.0000
+pos.x = 176.0000
+pos.y = 312.0000
+size.x = 352.0000
+size.y = 16.0000
 
 [Wall]
 id = 11
 flags = 2
-pos.x = 448.0000
-pos.y = 168.0000
-size.x = 32.0000
-size.y = 336.0000
+pos.x = 440.0000
+pos.y = 160.0000
+size.x = 16.0000
+size.y = 320.0000
 
 [Player]
 id = 12
 flags = 2
-pos.x = 342.9302
-pos.y = 205.3930
-size.x = 48.0000
-size.y = 48.0000
+pos.x = 452.6227
+pos.y = 356.0881
+size.x = 32.0000
+size.y = 32.0000
 :PlayerComponent
 color.r = 1.0000
 color.g = 1.0000
@@ -34,27 +34,27 @@ controls.left = 65
 controls.right = 68
 controls.interact = 70
 controls.pick_up = 71
-facing = 4
+facing = 1
 
 [Door]
 id = 13
 flags = 3
 pos.x = 352.0000
-pos.y = 320.0000
+pos.y = 312.0000
 size.x = 160.0000
-size.y = 32.0000
+size.y = 16.0000
 :DoorComponent
 max_openness = 0.8000
-target_openness = 0.0000
-openness = 0.0000
+target_openness = 0.8000
+openness = 0.8000
 
 [Item_Entity]
 id = 14
 flags = 4
-pos.x = 386.9302
-pos.y = 205.3930
-size.x = 32.0000
-size.y = 32.0000
+pos.x = 508.3851
+pos.y = 375.2260
+size.x = 16.0000
+size.y = 16.0000
 :ItemComponent
 item = "beer"
 
index cea7606defe4280f94030babfaa4a1ea7388e6e7..b949ecfb05f8c4cd1f11555422c20ee74e09e182 100644 (file)
@@ -23,6 +23,7 @@ DEBUG :: false
 #load "entity/player"
 #load "entity/store"
 
+#load "gfx/canvas"
 #load "gfx/font"
 #load "gfx/immediate"
 #load "gfx/mesh"
index 4ec0f08f5a2177595ee97283db23adbf6d239e60..dcf2cf724b9750193f14346abad2ff84621b932b 100644 (file)
@@ -13,6 +13,7 @@ use package glfw3
 
 Editor_Range        :: struct {min, max: f32;}
 Editor_Disabled     :: struct {}
+Editor_Hidden       :: struct {}
 Editor_Custom_Field :: struct { func: () -> void; }
 
 editor_init :: () {
@@ -22,6 +23,7 @@ editor_init :: () {
 }
 
 editor_shown :: () => editor_openness != 0.0f || editor_target_openness != 0.0f;
+editor_open_percent :: () => editor_openness;
 
 editor_toggle :: () {
     editor_target_openness = 1.0f - editor_target_openness;
@@ -52,7 +54,7 @@ editor_update :: (dt: f32) {
 
 #local handle_placing_entities :: () {
     if active_index < 0 do return;
-    mouse_pos := mouse_get_position_vector();
+    mouse_pos := mouse_get_position_vector() - scene_render_offset;
 
     if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) && mouse_pos.x < ~~window_width - sidebar_width && mouse_pos.y > menubar_height {
         schematic := scene.schematics.entries[active_index].value;
@@ -66,7 +68,7 @@ editor_update :: (dt: f32) {
 }
 
 #local handle_entity_selction_and_dragging :: (dt: f32) {
-    mouse_pos := mouse_get_position_vector();
+    mouse_pos := mouse_get_position_vector() - scene_render_offset;
 
     if mouse_pos.x < ~~window_width - sidebar_width && mouse_pos.y > menubar_height {
         if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) || is_button_just_down(GLFW_MOUSE_BUTTON_RIGHT) {
@@ -98,7 +100,7 @@ editor_update :: (dt: f32) {
 
         if dragging {
             if editor_grid_shown {
-                new_top_left := mouse_get_position_vector();
+                new_top_left := mouse_get_position_vector() - scene_render_offset;
                 new_top_left.x = editor_grid_size * math.floor(new_top_left.x / editor_grid_size);
                 new_top_left.y = editor_grid_size * math.floor(new_top_left.y / editor_grid_size);
 
@@ -120,7 +122,7 @@ editor_update :: (dt: f32) {
         if resizing {
             if editor_grid_shown {
                 rect := Entity.get_rect(selected_entity);
-                new_size := mouse_get_position_vector() - Rect.top_left(rect);
+                new_size := mouse_get_position_vector() - Rect.top_left(rect) - scene_render_offset;
                 new_size.x = editor_grid_size * math.floor(new_size.x / editor_grid_size);
                 new_size.y = editor_grid_size * math.floor(new_size.y / editor_grid_size);
                 new_rect := Rect.{ rect.x, rect.y, new_size.x, new_size.y };
@@ -141,30 +143,31 @@ editor_update :: (dt: f32) {
 
 editor_draw :: () {
     if editor_grid_shown {
-        width := cast(f32) window_width;
-        height := cast(f32) window_height;
+        width := cast(f32) scene_canvas.width;
+        height := cast(f32) scene_canvas.height;
         xcount := cast(i32) math.ceil(height / editor_grid_size);
         ycount := cast(i32) math.ceil(width / editor_grid_size);
 
         immediate_set_color(.{1,1,0});
         for xcount {
-            y := ~~it * editor_grid_size;
-            immediate_line(0, y, width, y);
+            y := ~~it * editor_grid_size + scene_render_offset.y;
+            immediate_line(scene_render_offset.x, y, width + scene_render_offset.x, y);
         }
 
         for ycount {
-            x := ~~it * editor_grid_size;
-            immediate_line(x, 0, x, height);
+            x := ~~it * editor_grid_size + scene_render_offset.x;
+            immediate_line(x, scene_render_offset.y, x, height + scene_render_offset.y);
         }
     }
 
-    scene->draw();
     immediate_flush();
 
     if selected_entity_id != Entity_Nothing {
         selected_entity := scene->get(selected_entity_id);
 
         r := Entity.get_rect(selected_entity);
+        r.x += scene_render_offset.x;
+        r.y += scene_render_offset.y;
         immediate_set_color(.{1,1,0,0.5});
         immediate_rectangle(r.x-2, r.y-2, r.w+4, r.h+4);
         immediate_rectangle(r.x, r.y, r.w, r.h);
@@ -284,6 +287,11 @@ editor_draw :: () {
 
     info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(v.type);
     for^ info.members {
+        for^ it.tags {
+            if it.type != type_expr do continue;
+            if *cast(^type_expr) it.data == Editor_Hidden do continue continue;
+        }
+
         i += 1;
         y += Field_Height;
 
index c53bb904636c3d0a75b19eb32548a25c270cb3bb..5229ccac6ca4971f9b731fabe92f5804d64b2b62 100644 (file)
@@ -4,7 +4,6 @@ use package core
 
 Item :: struct {
     name: str;
-    weight := 10.0f;
 
     color        := Color.{ 1, 1, 1 };
     texture_path : str;
@@ -87,7 +86,9 @@ item_store_get_item :: (use this: ^Item_Store, id: str) -> ^Item {
     return items[id];
 }
 
-#local Item_Entity :: struct [Entity_Schematic.{create}] {
+#local Item_Entity :: struct {
+    #struct_tag Entity_Schematic.{create}
+
     create :: (scene) => {
         this := scene->make();
         this.pos = .{0, 0};
@@ -123,7 +124,7 @@ item_store_get_item :: (use this: ^Item_Store, id: str) -> ^Item {
 ItemComponent :: struct {
     use base: Component;
 
-    [Editor_Custom_Field.{render_item_picker}]
+    #tag Editor_Custom_Field.{render_item_picker}
     item: str;
 }
 
index 1f0dd3388b50cb9aeb1e0fcced6c426bd44f8c75..d1b5787d70b400bb58733edc5efb0179f03c6df3 100644 (file)
@@ -21,8 +21,11 @@ Entity_ID :: #distinct u32
 }
 
 Component :: struct {
-    [Entity_Store.Skip] use vtable: ^Component_Vtable;
-    [Entity_Store.Skip]     type: type_expr;
+    #tag Editor_Hidden, Entity_Store.Skip
+    use vtable: ^Component_Vtable;
+
+    #tag Editor_Hidden, Entity_Store.Skip
+    type: type_expr;
 }
 
 IsComponent :: interface (c: $C) {
@@ -32,23 +35,30 @@ IsComponent :: interface (c: $C) {
 RenderComponent :: struct {
     use base: Component;
     func : (e: ^Entity) -> void;
+
+    #struct_tag Entity_Store.Skip
 }
 
-SizeComponent :: struct [Entity_Store.Skip] {
+SizeComponent :: struct {
     use base: Component;
     func : (e: ^Entity) -> Rect;
+
+    #struct_tag Entity_Store.Skip
 }
 
-InteractableComponent :: struct [Entity_Store.Skip] {
+InteractableComponent :: struct {
     use base: Component;
     interact: (e: ^Entity, interactor: ^Entity) -> void;
+
+    #struct_tag Entity_Store.Skip
 }
 
 Entity :: struct {
     id: Entity_ID;
     flags: Entity_Flags;
 
-    [Entity_Store.Skip] schematic: type_expr;
+    #tag Entity_Store.Skip
+    schematic: type_expr;
 
     pos:  Vector2;
 
@@ -60,8 +70,9 @@ Entity :: struct {
         return Rect.{ pos.x - size.x / 2, pos.y - size.y / 2, size.x, size.y };
     };
 
-    [Entity_Store.Skip]
+    #tag Entity_Store.Skip
     components: Map(type_expr, ^Component);
+
     has :: (use this: ^Entity,  component_type: type_expr) => components->has(component_type);
     get :: (use this: ^Entity, $component_type: type_expr) => cast(^component_type) components[component_type];
     add :: (use this: ^Entity,  component: ^Component) => {
index d4dad61a67284c3452d9eb99cce694f29c39ab61..9118d799ffcc0ed330a7fb878c024e62a63aec8f 100644 (file)
@@ -45,7 +45,8 @@ facing_to_direction_vector :: macro (f: Facing) -> Vector2 {
     }
 }
 
-#local Player :: struct [Entity_Schematic.{create}] {
+#local Player :: struct {
+    #struct_tag Entity_Schematic.{create}
     create :: (scene: ^Entity_Manager) => player_create(scene, .{0,0});
 }
 
@@ -193,15 +194,17 @@ PlayerComponent :: struct {
     }
 }
 
-#local Wall :: struct [Entity_Schematic.{create}] {
-    create :: (scene) => wall_create(scene, .{0,0}, .{0,0});
-
-    draw :: (use this: ^Entity) {
+#local Wall :: struct {
+    render :: (use this: ^Entity) {
         immediate_set_color(.{1,1,1});
 
         r := Entity.get_rect(this);
         immediate_rectangle(r.x, r.y, r.w, r.h);
     }
+
+    #struct_tag Entity_Schematic.{
+        (scene) => wall_create(scene, .{0,0}, .{0,0})
+    }
 }
 
 wall_create :: (scene: ^Entity_Manager, pos, size: Vector2) -> ^Entity {
@@ -211,18 +214,19 @@ wall_create :: (scene: ^Entity_Manager, pos, size: Vector2) -> ^Entity {
     this.flags |= .Solid;
 
     scene->create_and_add(this, RenderComponent) {
-        comp.func = Wall.draw;
+        comp.func = Wall.render;
     }
 
     return this;
 }
 
 player_assets: struct {
-    ["assets/images/player.png"] texture: Texture;
+    #tag "assets/images/player.png"
+    texture: Texture;
 }
 
-#local Door :: struct [Entity_Schematic.{create}] {
-    create :: (scene) => door_create(scene, .{0, 0}, .{0, 0});
+#local Door :: struct {
+    create :: (scene) => door_create(scene, .Zero, .Zero);
 
     render :: (use this: ^Entity) {
         immediate_set_color(.{0.7, 0.7, 0.1});
@@ -244,6 +248,8 @@ player_assets: struct {
             door->toggle_open();
         }
     }
+
+    #struct_tag Entity_Schematic.{create}
 }
 
 DoorComponent :: struct {
index d2ca9f52adac53d91c4095123d160dd5876db185..29d421a27ad272879c6df881a1a8c206a1737562 100644 (file)
@@ -1,6 +1,7 @@
 
 use package core
 use package glfw3
+use package opengles
 
 //
 // Game Global Variables
@@ -9,7 +10,12 @@ use package glfw3
 scene: Entity_Manager;
 item_store: Item_Store;
 
+scene_render_offset: Vector2;
+scene_canvas: Canvas;
+
 game_init :: () {
+    scene_canvas = canvas_make(800, 600);
+
     // This process of queueing the asset bucket should
     // be made automatic somehow...
     queue_assets(^player_assets);
@@ -45,6 +51,27 @@ game_update :: (dt: f32) {
 }
 
 game_draw :: () {
+    canvas_use(^scene_canvas);
+    immediate_clear(.{0.15, 0.15, 0.2});
+    scene->draw();
+    immediate_flush();
+    canvas_use(null);
+    
+    immediate_clear(.{0, 0, 0});
+
+    texture := canvas_to_texture(^scene_canvas);
+    view_rect: Rect;
+    view_rect.x = math.lerp(editor_open_percent(), cast(f32) ((window_width - scene_canvas.width) / 2), 0);
+    view_rect.y = ~~ ((window_height - scene_canvas.height) / 2);
+    view_rect.w = ~~ scene_canvas.width;
+    view_rect.h = ~~ scene_canvas.height;
+    scene_render_offset = Rect.top_left(view_rect);
+
+    glDisable(GL_CULL_FACE);
+    immediate_image(^texture, view_rect.x, ~~window_height - view_rect.y, view_rect.w, -view_rect.h);
+    immediate_flush();
+    glEnable(GL_CULL_FACE);
+
     update_world_matrix();
     update_model_matrix(.{0,0});
 
@@ -53,5 +80,4 @@ game_draw :: () {
         return;
     }
 
-    scene->draw();
 }
index d2f08e4a3e037b2ddfd764749cf2181503d17825..eb2af3fdce4fe63c7395918635f33acc0a1e342c 100644 (file)
@@ -4,21 +4,58 @@ use package opengles
 
 
 Canvas :: struct {
+    width, height: i32;
+
     framebuffer: GLint;
     depth_stencil_buffer: GLint;
     color_texture: GLint;
 }
 
-canvas_make :: () -> Canvas {
+canvas_make :: (width, height: i32) -> Canvas {
     canvas: Canvas;
+    canvas.width = width;
+    canvas.height = height;
+
+    glGenFramebuffers(1, ^canvas.framebuffer);
+    glBindFramebuffer(GL_FRAMEBUFFER, canvas.framebuffer);
+
+    glGenTextures(1, ^canvas.color_texture);
+    glBindTexture(GL_TEXTURE_2D, canvas.color_texture);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, null);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, canvas.color_texture, 0);
+
+    glGenRenderbuffers(1, ^canvas.depth_stencil_buffer);
+    glBindRenderbuffer(GL_RENDERBUFFER, canvas.depth_stencil_buffer);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+    glBindRenderbuffer(GL_RENDERBUFFER, 0);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, canvas.depth_stencil_buffer);
+
+    if glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE {
+        debug_log(.Error, "Framebuffer is not complete!");
+    }
+
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);  
+    return canvas;
+}
+
+canvas_free :: (use canvas: ^Canvas) {
+    glDeleteFramebuffers(1, ^canvas.framebuffer);
+    glDeleteTextures(1, ^canvas.color_texture);
+    glDeleteRenderbuffers(1, ^canvas.depth_stencil_buffer);
 }
 
 canvas_use :: (use canvas: ^Canvas) {
     if canvas == null {
         glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        update_view_matrix(window_width, window_height);
     } else {
         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+        update_view_matrix(width, height);
     }
 }
 
+canvas_to_texture :: (canvas: ^Canvas) => Texture.{ canvas.color_texture, canvas.width, canvas.height, 3, "<canvas>" };
 
index 246c3d1802deb261e02c176e334ce6ceb30dc948..d2b05e7ec0c592d963886ec15de7cb939378e932 100644 (file)
@@ -74,12 +74,12 @@ shader_set_uniform :: (shader: Shader, uniform: cstr, value: $T) {
     }
 }
 
-update_view_matrix :: () {
+update_view_matrix :: (width, height: u32) {
     matrix : [16] f32;
     top    := 0.0f;
     left   := 0.0f;
-    right  := cast(f32) window_width;
-    bottom := cast(f32) window_height;
+    right  := cast(f32) width;
+    bottom := cast(f32) height;
     far    := 10.0f;
     near   := 0f;
     
@@ -94,6 +94,8 @@ update_view_matrix :: () {
     glBindBuffer(GL_UNIFORM_BUFFER, window_matrix_block_buffer);
     glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof typeof matrix, ^matrix);
     glBindBuffer(GL_UNIFORM_BUFFER, -1);
+
+    glViewport(0, 0, width, height);
 }
 
 update_world_matrix :: () {
index 12cdd27aee90660d6fc4e8a2647a6a4ad7414359..3c7c6ddd2731a903b688581bc8fa6f60561078da 100644 (file)
@@ -34,8 +34,7 @@ init :: () {
     game_init();
 
     glfwGetWindowSize(window, ^window_width, ^window_height);
-    glViewport(0, 0, window_width, window_height);
-    update_view_matrix();
+    update_view_matrix(window_width, window_height);
 
     #if DEBUG { debug_font = font_lookup(.{"./assets/fonts/calibri.ttf", 16}); }
 }
@@ -127,7 +126,7 @@ create_window :: () => {
         glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
         glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
     }
-    window := glfwCreateWindow(800, 600, #cstr "Bar simulator");
+    window := glfwCreateWindow(1200, 900, #cstr "Bar simulator");
 
     glfwMakeContextCurrent(window);
     glfwSwapInterval(1);
@@ -136,10 +135,9 @@ create_window :: () => {
 }
 
 #export "on_resize" (window: GLFWwindow_p, width, height: u32) {
-    glViewport(0, 0, width, height);
     window_width = width;
     window_height = height;
-    update_view_matrix();
+    update_view_matrix(width, height);
 }
 
 main :: (args) => {
index 07423f56411fa3c14efb5268c1db7630a6cb43a9..9dbf7c17f0e67cbbdbca781a9355ee4fea06a2d4 100644 (file)
@@ -1,14 +1,18 @@
-Vector2 :: struct [conv.Custom_Format.{format_vector2}] {
+Vector2 :: struct {
     x, y: f32;
 
     mag :: macro (v: Vector2) => math.sqrt(v.x * v.x + v.y * v.y);
+    Zero :: Vector2.{0, 0}
+
+    #struct_tag conv.Custom_Format.{format_vector2}
 }
 
-Vector3i :: struct [conv.Custom_Format.{format_vector3i}] {
+Vector3i :: struct {
     x, y, z: i32;
+    #struct_tag conv.Custom_Format.{format_vector3i}
 }
 
-Vector3 :: struct [conv.Custom_Format.{format_vector3}] {
+Vector3 :: struct {
     x, y, z: f32;
 
     mag :: macro (v: Vector3) => math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
@@ -39,6 +43,8 @@ Vector3 :: struct [conv.Custom_Format.{format_vector3}] {
             math.clamp(v.z, min.z, max.z),
         };
     }
+
+    #struct_tag conv.Custom_Format.{format_vector3}
 }
 
 #operator + macro (v1, v2: Vector2)    => (typeof v1).{ v1.x + v2.x, v1.y + v2.y };