--- /dev/null
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
+ // for the documentation about the tasks.json format
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Run game",
+ "type": "shell",
+ "options": {
+ "cwd": "${workspaceFolder}/run_tree"
+ },
+ "problemMatcher": "$onyx",
+ "command": "onyx run -V -I ../src build",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ }
+ ]
+}
\ No newline at end of file
#load "main"
+#load "entity/manager"
+#load "entity/player"
+
#load "gfx/font"
-#load "gfx/imgui"
+#load "gfx/immediate"
#load "gfx/mesh"
#load "gfx/shader"
#load "gfx/texture"
--- /dev/null
+
+use package core
+use package glfw3
+
+Entity_Vtable :: struct {
+ draw : (entity: ^Entity) -> void;
+ update : (entity: ^Entity, dt: f32) -> void;
+}
+
+Entity :: struct {
+ use vtable: ^Entity_Vtable;
+ id: u32;
+}
+
+Entity_Manager :: struct {
+ // The allocator for these entity pointers is assumed to be the
+ // context allocator.
+ entities: [..] ^Entity;
+
+ next_entity_id: u32;
+
+ update :: entity_manager_update;
+ register :: entity_manager_register;
+ draw :: entity_manager_draw;
+}
+
+entity_manager_make :: () -> Entity_Manager {
+ em: Entity_Manager;
+
+ array.init(^em.entities, 4);
+
+ // Entity ID 0 is reserved as a "empty / null" entity
+ em.next_entity_id = 1;
+
+ return em;
+}
+
+entity_manager_register :: (use this: ^Entity_Manager, entity: ^Entity) -> u32 {
+ id := next_entity_id;
+ next_entity_id += 1;
+
+ entity.id = id;
+ entities << entity;
+ return id;
+}
+
+entity_manager_update :: (use this: ^Entity_Manager, dt: f32) {
+ for entities {
+ if it.vtable == null do continue;
+
+ if it.update != null_proc {
+ it->update(dt);
+ }
+ }
+}
+
+entity_manager_draw :: (use this: ^Entity_Manager) {
+ // Entities should be sorted by z-order.
+ for entities {
+ if it.vtable == null do continue;
+
+ if it.draw != null_proc {
+ it->draw();
+ }
+ }
+}
+
+
--- /dev/null
+
+use package core
+use package glfw3
+
+Player :: struct {
+ use entity: Entity;
+
+ pos: Vector2;
+}
+
+player_make :: () -> ^Player {
+ player := new(Player);
+ player.vtable = ^player_vtable;
+
+ player.pos = .{0,0};
+ return player;
+}
+
+player_update :: (use this: ^Player, dt: f32) {
+ if is_key_down(GLFW_KEY_W) do pos.y -= 100 * dt;
+ if is_key_down(GLFW_KEY_S) do pos.y += 100 * dt;
+ if is_key_down(GLFW_KEY_A) do pos.x -= 100 * dt;
+ if is_key_down(GLFW_KEY_D) do pos.x += 100 * dt;
+}
+
+player_draw :: (use this: ^Player) {
+ immediate_set_color(.{0.4,0.4,1});
+ immediate_rectangle(pos.x, pos.y, 50, 50);
+}
+
+#local player_vtable := Entity_Vtable.{ update=player_update, draw=player_draw };
+++ /dev/null
-
-use package core
-use package opengles
-use package glfw3
-
-immediate_init :: () {
- memory.alloc_slice(^vertex_data, Maximum_Vertex_Count);
- vertex_count = 0;
-
- imgui_shader = shader_make(Shader_Vertex_Path, Shader_Fragment_Path);
- shader_use(imgui_shader);
- shader_link_window_matrix_block(imgui_shader);
- shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
- shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
-
- immediate_mesh = mesh_make(vertex_data, .[], GL_DYNAMIC_DRAW);
- immediate_color = .{0,0,0};
-}
-
-immediate_flush :: () {
- if vertex_count == 0 do return;
-
- shader_use(imgui_shader);
- immediate_mesh.vertex_count = vertex_count;
- mesh_update_verticies(immediate_mesh, vertex_data);
-
- mesh_draw(immediate_mesh);
-
- shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
- vertex_count = 0;
-}
-
-immediate_clear :: (color: Color) {
- glClearColor(color.r, color.g, color.b, color.a);
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
-immediate_set_color :: (color: Color) {
- immediate_color = color;
-}
-
-immediate_vertex :: (x, y: f32, t_x := 0.0f, t_y := 0.0f) {
- if vertex_count >= Maximum_Vertex_Count do immediate_flush();
-
- vertex_data[vertex_count] = .{ .{x, y}, .{t_x, t_y}, immediate_color };
-}
-
-immediate_triangle :: (x1, x2, x3: Vector2) {
- if vertex_count + 3 > Maximum_Vertex_Count do immediate_flush();
-
- vertex_data[vertex_count + 0] = .{ x1, .{0,0}, immediate_color };
- vertex_data[vertex_count + 1] = .{ x2, .{0,0}, immediate_color };
- vertex_data[vertex_count + 2] = .{ x3, .{0,0}, immediate_color };
- vertex_count += 3;
-}
-
-immediate_rectangle :: (x, y, w, h: f32) {
- if vertex_count + 6 > Maximum_Vertex_Count do immediate_flush();
-
- vertex_data[vertex_count + 0] = .{ .{x, y}, .{0,0}, immediate_color };
- vertex_data[vertex_count + 1] = .{ .{x+w, y}, .{0,0}, immediate_color };
- vertex_data[vertex_count + 2] = .{ .{x+w, y+h}, .{0,0}, immediate_color };
- vertex_data[vertex_count + 3] = .{ .{x, y}, .{0,0}, immediate_color };
- vertex_data[vertex_count + 4] = .{ .{x+w, y+h}, .{0,0}, immediate_color };
- vertex_data[vertex_count + 5] = .{ .{x, y+h}, .{0,0}, immediate_color };
- vertex_count += 6;
-}
-
-immediate_image :: (image: ^Texture, x, y, w, h: f32) {
- if vertex_count > 0 do immediate_flush();
-
- texture_use(image);
- shader_use(imgui_shader);
- shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 1.0f);
- shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
-
- vertex_data[vertex_count + 0] = .{ .{x, y}, .{0,0}, immediate_color };
- vertex_data[vertex_count + 1] = .{ .{x+w, y}, .{1,0}, immediate_color };
- vertex_data[vertex_count + 2] = .{ .{x+w, y+h}, .{1,1}, immediate_color };
- vertex_data[vertex_count + 3] = .{ .{x, y}, .{0,0}, immediate_color };
- vertex_data[vertex_count + 4] = .{ .{x+w, y+h}, .{1,1}, immediate_color };
- vertex_data[vertex_count + 5] = .{ .{x, y+h}, .{0,1}, immediate_color };
- vertex_count += 6;
-
- immediate_flush();
-}
-
-immediate_ellipse :: () {}
-
-Color :: struct {
- r, g, b : f32;
- a := 1.0f;
-}
-
-Immediate_Vertex :: struct {
- pos: Vector2;
- tex: Vector2;
- color: Color;
-}
-
-#local {
- Shader_Vertex_Path :: "./assets/shaders/imgui_vertex.glsl"
- Shader_Fragment_Path :: "./assets/shaders/imgui_fragment.glsl"
- imgui_shader: Shader;
-
- Maximum_Vertex_Count :: 1023;
- vertex_count: i32;
- vertex_data: [] Immediate_Vertex;
-
- immediate_color: Color;
-
- immediate_mesh: ^Mesh(Immediate_Vertex);
-}
--- /dev/null
+
+use package core
+use package opengles
+use package glfw3
+
+immediate_init :: () {
+ memory.alloc_slice(^vertex_data, Maximum_Vertex_Count);
+ vertex_count = 0;
+
+ imgui_shader = shader_make(Shader_Vertex_Path, Shader_Fragment_Path);
+ shader_use(imgui_shader);
+ shader_link_window_matrix_block(imgui_shader);
+ shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
+ shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
+
+ immediate_mesh = mesh_make(vertex_data, .[], GL_DYNAMIC_DRAW);
+ immediate_color = .{0,0,0};
+}
+
+immediate_flush :: () {
+ if vertex_count == 0 do return;
+
+ shader_use(imgui_shader);
+ immediate_mesh.vertex_count = vertex_count;
+ mesh_update_verticies(immediate_mesh, vertex_data);
+
+ mesh_draw(immediate_mesh);
+
+ shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
+ vertex_count = 0;
+}
+
+immediate_clear :: (color: Color) {
+ glClearColor(color.r, color.g, color.b, color.a);
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+immediate_set_color :: (color: Color) {
+ immediate_color = color;
+}
+
+immediate_vertex :: (x, y: f32, t_x := 0.0f, t_y := 0.0f) {
+ if vertex_count >= Maximum_Vertex_Count do immediate_flush();
+
+ vertex_data[vertex_count] = .{ .{x, y}, .{t_x, t_y}, immediate_color };
+}
+
+immediate_triangle :: (x1, x2, x3: Vector2) {
+ if vertex_count + 3 > Maximum_Vertex_Count do immediate_flush();
+
+ vertex_data[vertex_count + 0] = .{ x1, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 1] = .{ x2, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 2] = .{ x3, .{0,0}, immediate_color };
+ vertex_count += 3;
+}
+
+immediate_rectangle :: (x, y, w, h: f32) {
+ if vertex_count + 6 > Maximum_Vertex_Count do immediate_flush();
+
+ vertex_data[vertex_count + 0] = .{ .{x, y}, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 1] = .{ .{x+w, y}, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 2] = .{ .{x+w, y+h}, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 3] = .{ .{x, y}, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 4] = .{ .{x+w, y+h}, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 5] = .{ .{x, y+h}, .{0,0}, immediate_color };
+ vertex_count += 6;
+}
+
+immediate_image :: (image: ^Texture, x, y, w, h: f32) {
+ if vertex_count > 0 do immediate_flush();
+
+ texture_use(image);
+ shader_use(imgui_shader);
+ shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 1.0f);
+ shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
+
+ vertex_data[vertex_count + 0] = .{ .{x, y}, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 1] = .{ .{x+w, y}, .{1,0}, immediate_color };
+ vertex_data[vertex_count + 2] = .{ .{x+w, y+h}, .{1,1}, immediate_color };
+ vertex_data[vertex_count + 3] = .{ .{x, y}, .{0,0}, immediate_color };
+ vertex_data[vertex_count + 4] = .{ .{x+w, y+h}, .{1,1}, immediate_color };
+ vertex_data[vertex_count + 5] = .{ .{x, y+h}, .{0,1}, immediate_color };
+ vertex_count += 6;
+
+ immediate_flush();
+}
+
+immediate_ellipse :: () {}
+
+Color :: struct {
+ r, g, b : f32;
+ a := 1.0f;
+}
+
+Immediate_Vertex :: struct {
+ pos: Vector2;
+ tex: Vector2;
+ color: Color;
+}
+
+#local {
+ Shader_Vertex_Path :: "./assets/shaders/imgui_vertex.glsl"
+ Shader_Fragment_Path :: "./assets/shaders/imgui_fragment.glsl"
+ imgui_shader: Shader;
+
+ Maximum_Vertex_Count :: 1023;
+ vertex_count: i32;
+ vertex_data: [] Immediate_Vertex;
+
+ immediate_color: Color;
+
+ immediate_mesh: ^Mesh(Immediate_Vertex);
+}
player_texture: Texture;
main_font: Font;
+entity_manager: Entity_Manager;
+
init :: () {
create_window();
glInit(glfwGetLoadProcAddress());
player_texture = texture_make(#cstr "./assets/images/player.png");
main_font = font_make(.{"./assets/fonts/calibri.ttf", 32});
+
+ entity_manager = entity_manager_make();
+ player := player_make();
+ entity_manager->register(player);
}
update :: (dt: f32) {
input_update();
defer input_post_update();
+
+ entity_manager->update(dt);
}
draw :: () {
immediate_image(^player_texture, ~~(100 + 64 * i), 50, 64, 64);
}
+ entity_manager->draw();
+
+ mx, my := mouse_get_position();
+ immediate_set_color(.{1,1,1});
+ immediate_rectangle(~~mx, ~~my, 10, 10);
+
immediate_flush();
font_set_color(.{1,0,0});
mouse_get_delta :: () -> (f64, f64) {
return mouse_x - last_mouse_x, mouse_y - last_mouse_y;
}
+
+mouse_get_position :: () -> (f64, f64) {
+ return mouse_x, mouse_y;
+}
\ No newline at end of file