From 154809b033c5bb4544daea10f2e0bc5d4d43e106 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 28 Sep 2020 22:37:16 -0500 Subject: [PATCH] added quadtree implementation --- res/tilemap.data | Bin 0 -> 196608 bytes res/tilemap.png | Bin 0 -> 1238 bytes src/aabb.onyx | 21 ++ src/font.onyx | 2 +- src/gfx/atlas.onyx | 37 ++++ src/gfx/quad_renderer.onyx | 49 +++-- src/gfx/texture.onyx | 14 ++ src/main.onyx | 248 ++++++++++++++------- src/main_backup.onyx | 297 ++++++++++++++++++++++++++ src/quad_tree.onyx | 97 +++++++++ src/shaders/{basic.frag => quad.frag} | 6 +- src/shaders/{basic.vert => quad.vert} | 7 +- tags | 47 +++- 13 files changed, 714 insertions(+), 111 deletions(-) create mode 100644 res/tilemap.data create mode 100644 res/tilemap.png create mode 100644 src/aabb.onyx create mode 100644 src/gfx/atlas.onyx create mode 100644 src/main_backup.onyx create mode 100644 src/quad_tree.onyx rename src/shaders/{basic.frag => quad.frag} (52%) rename src/shaders/{basic.vert => quad.vert} (72%) diff --git a/res/tilemap.data b/res/tilemap.data new file mode 100644 index 0000000000000000000000000000000000000000..dc86ab1b3d4e1319e8922bcbf327c565a76039ae GIT binary patch literal 196608 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 literal 0 HcmV?d00001 diff --git a/src/aabb.onyx b/src/aabb.onyx new file mode 100644 index 0000000..3209719 --- /dev/null +++ b/src/aabb.onyx @@ -0,0 +1,21 @@ +package aabb + +use package vecmath + +AABB :: struct { + x: f32; y: f32; w: f32; h: f32; +} + +aabb_contains :: proc (r: AABB, v: V2f) -> bool { + return v.x >= r.x + && v.x <= r.x + r.w + && v.y >= r.y + && v.y <= r.y + r.h; +} + +aabb_intersects :: proc (r1: AABB, r2: AABB) -> bool { + return r1.x < r2.x + r2.w + && r1.x + r1.w > r2.x + && r1.y < r2.y + r2.h + && r1.y + r1.h > r2.y; +} diff --git a/src/font.onyx b/src/font.onyx index 48597d1..72b96b5 100644 --- a/src/font.onyx +++ b/src/font.onyx @@ -598,7 +598,7 @@ ttf_lookup_horizontal_metrics :: proc (use ttf: ^TrueTypeFont, glyph_index: u32) // To be used with gl.LUMANIANCE ttf_render_glyph :: proc (use ttf: ^TrueTypeFont, glyph: ^TTGlyph, data: ^u8, width: u32, height: u32) { // Black background - for y: 0 .. height do for x: 0 .. width do data[x + y * width] = cast(u8) 0; + for y: 0 .. height do for x: 0 .. width do data[x + y * width] = cast(u8) 255; // scale := ~~cast(i32) units_per_em / cast(f32) height; diff --git a/src/gfx/atlas.onyx b/src/gfx/atlas.onyx new file mode 100644 index 0000000..54f230b --- /dev/null +++ b/src/gfx/atlas.onyx @@ -0,0 +1,37 @@ +package gfx + +use package core +use package gl as gl +use package gl_utils as gl_utils + +Atlas :: struct { + texture : ^Texture; + map : I32Map(AtlasSprite); +} + +AtlasSprite :: struct { + x : i32 = 0; + y : i32 = 0; + w : i32 = 0; + h : i32 = 0; +} + +atlas_create :: proc (tex: ^Texture) -> Atlas { + atlas : Atlas; + atlas.texture = tex; + i32map_init(^atlas.map); + + return atlas; +} + +atlas_map :: proc (use atlas: ^Atlas, id: i32, sprite: AtlasSprite) { + i32map_put(^map, id, sprite); +} + +atlas_apply_to_quad :: proc (use atlas: ^Atlas, id: i32, quad: ^Quad) { + sprite := i32map_get(^map, id, AtlasSprite.{}); + quad.tex_size.x = cast(f32) sprite.w / ~~texture.width; + quad.tex_size.y = cast(f32) sprite.h / ~~texture.height; + quad.tex_pos.x = cast(f32) sprite.x / ~~texture.width; + quad.tex_pos.y = cast(f32) sprite.y / ~~texture.height; +} diff --git a/src/gfx/quad_renderer.onyx b/src/gfx/quad_renderer.onyx index 64a1c87..eb8a7b1 100644 --- a/src/gfx/quad_renderer.onyx +++ b/src/gfx/quad_renderer.onyx @@ -3,12 +3,11 @@ package gfx use package core use package gl as gl use package gl_utils as gl_utils +use package vecmath use package main { window_width, window_height } -Vec2 :: struct { - x : f32; - y : f32; -} +#private_file +quad_program : gl.GLProgram = -1; QuadRenderer :: struct { quad_data : [..] Quad; @@ -18,8 +17,6 @@ QuadRenderer :: struct { indexBuffer : gl.GLBuffer; quadBuffer : gl.GLBuffer; - program : gl.GLProgram; - u_proj_loc : gl.GLUniformLocation; is_data_dirty : bool = false; @@ -28,11 +25,11 @@ QuadRenderer :: struct { Color4f32 :: struct { r: f32; g: f32; b: f32; a: f32; } Quad :: struct { - pos : Vec2 = Vec2.{ 0f, 0f }; - size : Vec2 = Vec2.{ 0f, 0f }; + pos : V2f = V2f.{ 0f, 0f }; + size : V2f = V2f.{ 0f, 0f }; - tex_pos : Vec2 = Vec2.{ 0f, 0f }; - tex_size : Vec2 = Vec2.{ 0f, 0f }; + tex_pos : V2f = V2f.{ 0f, 0f }; + tex_size : V2f = V2f.{ 0f, 0f }; color : Color4f32 = Color4f32.{ 0f, 0f, 0f, 0f }; } @@ -42,16 +39,16 @@ quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) { gl.bindVertexArray(vertexArray); // Set up vertex and index data - vertex_data : [4] Vec2; - vertex_data[0] = Vec2.{ 0.0f, 0.0f }; - vertex_data[1] = Vec2.{ 0.0f, 1.0f }; - vertex_data[2] = Vec2.{ 1.0f, 1.0f }; - vertex_data[3] = Vec2.{ 1.0f, 0.0f }; + vertex_data : [4] V2f; + vertex_data[0] = V2f.{ 0.0f, 0.0f }; + vertex_data[1] = V2f.{ 0.0f, 1.0f }; + vertex_data[2] = V2f.{ 1.0f, 1.0f }; + vertex_data[3] = V2f.{ 1.0f, 0.0f }; vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, Buffer.{ - count = sizeof [4] Vec2, + count = sizeof [4] V2f, data = cast(^void) vertex_data }, gl.STATIC_DRAW); @@ -103,18 +100,24 @@ quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) { gl.bindVertexArray(-1); - vertex_shader := gl_utils.compile_shader(gl.VERTEX_SHADER, #file_contents "./src/shaders/basic.vert"); - fragment_shader := gl_utils.compile_shader(gl.FRAGMENT_SHADER, #file_contents "./src/shaders/basic.frag"); - program = gl_utils.link_program(vertex_shader, fragment_shader); - gl.useProgram(program); + if quad_program == ~~ -1 { + vertex_shader := gl_utils.compile_shader(gl.VERTEX_SHADER, #file_contents "./src/shaders/quad.vert"); + fragment_shader := gl_utils.compile_shader(gl.FRAGMENT_SHADER, #file_contents "./src/shaders/quad.frag"); + quad_program = gl_utils.link_program(vertex_shader, fragment_shader); + gl.useProgram(quad_program); + } - u_proj_loc = gl.getUniformLocation(program, "u_proj"); + u_proj_loc = gl.getUniformLocation(quad_program, "u_proj"); quad_renderer_update_view(qr); } -quad_renderer_draw :: proc (use qr: ^QuadRenderer) { +quad_renderer_draw :: proc (use qr: ^QuadRenderer, count := -1) { + c := count; + if count == -1 do c = quad_data.count; + + gl.useProgram(quad_program); gl.bindVertexArray(vertexArray); - gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, quad_data.count); + gl.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, c); gl.bindVertexArray(-1); } diff --git a/src/gfx/texture.onyx b/src/gfx/texture.onyx index ed014a3..2928c3e 100644 --- a/src/gfx/texture.onyx +++ b/src/gfx/texture.onyx @@ -4,6 +4,20 @@ use package core use package gl as gl use package gl_utils as gl_utils +textures : struct { + tilemap : Texture; + smile : Texture; +} + +textures_init :: proc () { + textures.tilemap = texture_create(#file_contents "res/tilemap.data", 256, 256); + textures.smile = texture_create(#file_contents "res/smile.data", 32, 32); + + texture_prepare(^textures.tilemap); + texture_prepare(^textures.smile); +} + + Texture :: struct { // NOTE: After a texture is loaded, we may not want to keep the // raw texture data in memory any longer. This would not be possible diff --git a/src/main.onyx b/src/main.onyx index e07a9ff..407de6b 100644 --- a/src/main.onyx +++ b/src/main.onyx @@ -7,10 +7,13 @@ package main #include_file "utils/gl" #include_file "gfx/quad_renderer" #include_file "gfx/texture" +#include_file "gfx/atlas" #include_file "events" #include_file "input" #include_file "font" #include_file "vecmath" +#include_file "aabb" +#include_file "quad_tree" use package core use package gfx @@ -20,9 +23,10 @@ use package input as input { Key } use package vecmath use package ttf_font -NUM_QUADS :: 1 << 10 - +use package quad_tree +use package aabb +NUM_QUADS :: 1 << 17 RenderContext :: struct { quad_renderer: ^QuadRenderer; @@ -30,10 +34,6 @@ RenderContext :: struct { curr_quad_idx: i32 = 0; max_quad_idx: i32 = 0; - // @CLEANUP Allow for the syntax: - // color := Color4f32.{ ... } - // OR - // color: Color4f32 = .{ ... } color: Color4f32 = Color4f32.{ 1.0f, 1.0f, 1.0f, 1.0f }; } @@ -55,21 +55,42 @@ draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) { if curr_quad_idx >= max_quad_idx do return; quad_update_at_index(quad_renderer, curr_quad_idx, Quad.{ - pos = Vec2.{ x, y }, - size = Vec2.{ w, h }, + pos = V2f.{ x, y }, + size = V2f.{ w, h }, color = color, - tex_size = Vec2.{ 1.0f, 1.0f }, + tex_pos = V2f.{ -1.0f, -1.0f }, }); curr_quad_idx += 1; } +draw_textured_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32, tx: f32, ty: f32, tw: f32, th: f32) { + if curr_quad_idx >= max_quad_idx do return; + + quad_update_at_index(quad_renderer, curr_quad_idx, Quad.{ + pos = V2f.{ x, y }, + size = V2f.{ w, h }, + color = color, + + tex_pos = V2f.{ tx, ty }, + tex_size = V2f.{ tw, th }, + }); + + curr_quad_idx += 1; +} + +draw_quad :: proc (use rc: ^RenderContext, quad: ^Quad) { + if curr_quad_idx >= max_quad_idx do return; + quad_update_at_index(quad_renderer, curr_quad_idx, *quad); + curr_quad_idx += 1; +} + render_context_flush :: proc (use rc: ^RenderContext) { quad_rebuffer_data(quad_renderer); - quad_renderer_draw(quad_renderer); + quad_renderer_draw(quad_renderer, curr_quad_idx); - for i: 0 .. curr_quad_idx do quad_update_at_index(quad_renderer, i, Quad.{}); + // for i: 0 .. curr_quad_idx do quad_update_at_index(quad_renderer, i, Quad.{}); curr_quad_idx = 0; } @@ -82,13 +103,9 @@ window_height := 0 renderer : RenderContext input_state : input.InputState -ttf : TrueTypeFont -font_tex : Texture -smile : Texture - -Player :: struct { use pos : Vec2; } -player : Player - +atlas : Atlas +dudes : [..] Dude +dude_tree : QuadTree(Dude) poll_events :: proc () { use event.DomEventKind; @@ -109,69 +126,77 @@ poll_events :: proc () { } } +quad_scratch_buffer : [512 * 1024] u8; + update :: proc () { input.preupdate(^input_state); defer input.postupdate(^input_state); poll_events(); - player_speed :: 4f; + quad_scratch : ScratchState; + quad_alloc : Allocator; + scratch_state_init(^quad_scratch, ~~quad_scratch_buffer, 128 * 1024); + scratch_alloc_init(^quad_alloc, ^quad_scratch); - if input.key_down(^input_state, Key.ArrowUp) do player.y -= player_speed; - if input.key_down(^input_state, Key.ArrowDown) do player.y += player_speed; - if input.key_down(^input_state, Key.ArrowLeft) do player.x -= player_speed; - if input.key_down(^input_state, Key.ArrowRight) do player.x += player_speed; -} + quadtree_init(^dude_tree, AABB.{ 0.0f, 0.0f, ~~window_width, ~~window_height }); + for ^d: dudes do quadtree_insert(^dude_tree, d, quad_alloc); -glyph_size :: 64 -glyph_data : [glyph_size * glyph_size] u8 + for ^d: dudes do dude_update(d, ^dude_tree); + for ^d: dudes { + if d.can_move_x do d.pos.x += d.vel.x; + else do d.vel.x = -d.vel.x; + if d.can_move_y do d.pos.y += d.vel.y; + else do d.vel.y = -d.vel.y; + } +} draw :: proc () { - gl.clearColor(0.2f, 0.2f, 0.2f, 1.0f); - // gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f); + gl.clearColor(0.1f, 0.1f, 0.1f, 1.0f); gl.clear(gl.COLOR_BUFFER_BIT); - // renderer.color = Color4f32.{ 1f, 0f, 0f, 1f }; + texture_use(^textures.tilemap); + draw_quad_tree(^dude_tree); - // points : [6] V2f; - // points[0] = V2f.{ 500.0f, 700.0f }; - // points[1] = V2f.{ 600.0f, 200.0f }; - // points[2] = V2f.{ 700.0f, 400.0f }; - // points[3] = V2f.{ 1700.0f, 800.0f }; - // points[4] = V2f.{ 1800.0f, 400.0f }; - // points[5] = V2f.{ 1000.0f, 200.0f }; + draw_rect(^renderer, ~~input_state.mouse.x, ~~input_state.mouse.y, 10f, 10f); - // for i: 0 .. 200 { - // pos := bezier_curve(~~i / 200.0f, points[0 .. 6]); - // draw_rect(^renderer, pos.x, pos.y, 16f, 16f); - // } + for ^d: dudes { + aabb := dude_get_aabb(d); + draw_rect(^renderer, aabb.x, aabb.y, aabb.w, aabb.h); + } - // for y: 0 .. glyph_size do for x: 0 .. glyph_size { - // if glyph_data[x + y * glyph_size] != ~~0 { - // draw_rect(^renderer, ~~(x * 2 + 100), ~~(y * 2 + 100), 2f, 2f); - // } - // } + render_context_flush(^renderer); +} - // mets := ttf_lookup_horizontal_metrics(^ttf, glyph_index); - // println(cast(u32) mets.advance_width); +draw_quad_tree :: proc (qt: ^QuadTree($T), level := 0, corner := 0) { + col := cast(f32) (0.2f + 0.15f * ~~level); + if col > 1.0f do col = 1.0f; - // rx := 100.0f / ~~ cast(i32) (glyph.x_max - glyph.x_min); - // ry := 100.0f / ~~ cast(i32) (glyph.y_min - glyph.y_max); - // for p: glyph.points { - // if p.on_curve do continue; - // draw_rect(^renderer, ~~ cast(i32) p.x * rx + 100f, ~~ cast(i32) p.y * ry + 100f, 10f, 10f); - // } + color := Color4f32.{ 0.0f, 0.0f, 0.0f, 1.0f }; - texture_use(^font_tex); - draw_rect(^renderer, 100f, 100f, 256f, 256f); - render_context_flush(^renderer); + if corner == 1 do color.r = col; + if corner == 2 do color.g = col; + if corner == 3 do color.b = col; - texture_use(^smile); - draw_rect(^renderer, ~~input_state.mouse.x, ~~input_state.mouse.y, 10f, 10f); - draw_rect(^renderer, player.pos.x, player.pos.y, 100f, 100f); - render_context_flush(^renderer); + quad := Quad.{ + pos = V2f.{ qt.region.x, qt.region.y }, + size = V2f.{ qt.region.w, qt.region.h }, + color = color, + + tex_pos = V2f.{ -1.0f, -1.0f }, + }; + draw_quad(^renderer, ^quad); + + if qt.nw != null { + draw_quad_tree(qt.nw, level + 1, 1); + draw_quad_tree(qt.ne, level + 1, 2); + draw_quad_tree(qt.sw, level + 1, 3); + draw_quad_tree(qt.se, level + 1, 4); + } } +debugger :: proc () #foreign "dummy" "breakable" --- + // This procedure is called asynchronously from JS every frame. new_frame_callback :: proc () #export { update(); @@ -193,31 +218,104 @@ main :: proc (args: [] cstring) { gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); render_context_init(^renderer, null); + textures_init(); - image_data := #file_contents "res/smile.data"; - smile = texture_create(image_data, 32, 32); - texture_prepare(^smile); + atlas = atlas_create(^textures.tilemap); + atlas_map(^atlas, 0, AtlasSprite.{ x = 16, y = 0, w = 16, h = 16 }); event.init(); input.init(^input_state); - ttf_data := #file_contents "res/Hack-Regular.ttf"; - ttf = ttf_create(ttf_data); + array_init(^dudes); + for i: 0 .. 500 { + array_push(^dudes, dude_create_random()); + } - glyph : ^TTGlyph = null; - glyph_index := ttf_lookup_glyph_by_char(^ttf, ~~ #char "A"); - glyph = ttf_read_glyph(^ttf, glyph_index); - if glyph == null do return; - defer ttf_glyph_destroy(glyph); + game_launch :: proc () #foreign "game" "launch" ---; + game_launch(); +} - ttf_render_glyph(^ttf, glyph, ~~glyph_data, glyph_size, glyph_size); - font_tex = texture_create(glyph_data[0 .. glyph_size * glyph_size], glyph_size, glyph_size, TextureDataMode.BRIGHTNESS); - texture_prepare(^font_tex); - game_launch(); +Dude_Color_Table : [4] Color4f32; + +Dude :: struct { + pos : V2f; + vel : V2f; + size : f32; + color : Color4f32; + + can_move_x : bool = true; + can_move_y : bool = true; +} + +dude_create_random :: proc () -> Dude { + return Dude.{ + pos = V2f.{ random_float(0.0f, 300.0f), random_float(0.0f, 300.0f) }, + vel = V2f.{ random_float(-3.0f, 3.0f), random_float(-3.0f, 3.0f) }, + size = random_float(2.0f, 3.0f), + color = Dude_Color_Table[random_between(0, 3)], + }; +} + +dude_update :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { + // if random_between(0, 100) < 1 { + // vel.x = random_float(-2.0f, 2.0f); + // vel.y = random_float(-2.0f, 2.0f); + // } + + dude_try_move(dude, other_dudes); } +dude_try_move :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { + old_pos := pos; + potential_dudes : [..] ^Dude; + array_init(^potential_dudes); + defer array_free(^potential_dudes); -game_launch :: proc () #foreign "game" "launch" --- + around := AABB.{ x = pos.x - size * 5.0f, y = pos.y - size * 5.0f, w = size * 10.0f, h = size * 10.0f }; + quadtree_query(other_dudes, around, ^potential_dudes); + collided := false; + + pos.x += vel.x; + if pos.x - size < 0.0f || pos.x + size >= ~~window_width do collided = true; + + dude_aabb := dude_get_aabb(dude); + for other: potential_dudes { + if other == dude do continue; + + other_aabb := dude_get_aabb(other); + if aabb_intersects(dude_aabb, other_aabb) { + // printf("COLLISION\n"); + collided = true; + break; + } + } + + can_move_x = !collided; + pos.x -= vel.x; + + collided = false; + + pos.y += vel.y; + if pos.y - size < 0.0f || pos.y + size >= ~~window_height do collided = true; + + dude_aabb = dude_get_aabb(dude); + for other: potential_dudes { + if other == dude do continue; + + other_aabb := dude_get_aabb(other); + if aabb_intersects(dude_aabb, other_aabb) { + collided = true; + break; + } + } + + can_move_y = !collided; + pos.y -= vel.y; +} + +dude_get_aabb :: proc (use dude: ^Dude) -> AABB { + return AABB.{ x = pos.x - size, y = pos.y - size, w = size * 2.0f, h = size * 2.0f }; +} diff --git a/src/main_backup.onyx b/src/main_backup.onyx new file mode 100644 index 0000000..591514f --- /dev/null +++ b/src/main_backup.onyx @@ -0,0 +1,297 @@ +package main + +#include_file "core/std/js" +#include_file "core/js/webgl" + +#include_folder "src/" +#include_file "utils/gl" +#include_file "gfx/quad_renderer" +#include_file "gfx/texture" +#include_file "gfx/atlas" +#include_file "events" +#include_file "input" +#include_file "font" +#include_file "vecmath" +#include_file "aabb" +#include_file "quad_tree" + +use package core +use package gfx +use package gl as gl +use package event as event +use package input as input { Key } +use package vecmath +use package ttf_font + +use package quad_tree +use package aabb + +NUM_QUADS :: 1 << 10 + +RenderContext :: struct { + quad_renderer: ^QuadRenderer; + + curr_quad_idx: i32 = 0; + max_quad_idx: i32 = 0; + + color: Color4f32 = Color4f32.{ 1.0f, 1.0f, 1.0f, 1.0f }; +} + +render_context_init :: proc (use rc: ^RenderContext, qr: ^QuadRenderer = null) { + aqr := qr; + + if aqr == null { + aqr = calloc(sizeof QuadRenderer); + quad_renderer_init(aqr, NUM_QUADS); + } + + *rc = RenderContext.{ + quad_renderer = aqr, + max_quad_idx = qr.quad_data.count, + }; +} + +draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) { + if curr_quad_idx >= max_quad_idx do return; + + quad_update_at_index(quad_renderer, curr_quad_idx, Quad.{ + pos = V2f.{ x, y }, + size = V2f.{ w, h }, + color = color, + + tex_pos = V2f.{ -1.0f, -1.0f }, + }); + + curr_quad_idx += 1; +} + +draw_textured_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32, tx: f32, ty: f32, tw: f32, th: f32) { + if curr_quad_idx >= max_quad_idx do return; + + quad_update_at_index(quad_renderer, curr_quad_idx, Quad.{ + pos = V2f.{ x, y }, + size = V2f.{ w, h }, + color = color, + + tex_pos = V2f.{ tx, ty }, + tex_size = V2f.{ tw, th }, + }); + + curr_quad_idx += 1; +} + +draw_quad :: proc (use rc: ^RenderContext, quad: ^Quad) { + if curr_quad_idx >= max_quad_idx do return; + quad.color = color; + quad_update_at_index(quad_renderer, curr_quad_idx, *quad); + curr_quad_idx += 1; +} + +render_context_flush :: proc (use rc: ^RenderContext) { + quad_rebuffer_data(quad_renderer); + quad_renderer_draw(quad_renderer, curr_quad_idx); + + // for i: 0 .. curr_quad_idx do quad_update_at_index(quad_renderer, i, Quad.{}); + + curr_quad_idx = 0; +} + + + +// @Cleanup +window_width := 0 +window_height := 0 + +renderer : RenderContext +input_state : input.InputState +atlas : Atlas +dudes : [..] Dude +dude_tree : QuadTree(Dude) + +poll_events :: proc () { + use event.DomEventKind; + + ev : event.Event; + while event.poll(^ev) do switch ev.kind { + case KeyDown, KeyUp, MouseDown, MouseUp, MouseMove do input.process_event(^input_state, ^ev); + + case Resize { + window_width = ev.resize.width; + window_height = ev.resize.height; + + gl.canvasSize(window_width, window_height); + gl.viewport(0, 0, window_width, window_height); + + quad_renderer_update_view(renderer.quad_renderer); + } + } +} + +quad_scratch_buffer : [128 * 1024] u8; + +update :: proc () { + input.preupdate(^input_state); + defer input.postupdate(^input_state); + poll_events(); + + quad_scratch : ScratchState; + quad_alloc : Allocator; + scratch_state_init(^quad_scratch, ~~quad_scratch_buffer, 128 * 1024); + scratch_alloc_init(^quad_alloc, ^quad_scratch); + + quadtree_init(^dude_tree, AABB.{ 0.0f, 0.0f, ~~window_width, ~~window_height }); + for ^d: dudes do quadtree_insert(^dude_tree, d, quad_alloc); + + for ^d: dudes do dude_update(d, ^dude_tree); +} + +draw :: proc () { + gl.clearColor(0.1f, 0.1f, 0.1f, 1.0f); + gl.clear(gl.COLOR_BUFFER_BIT); + + texture_use(^textures.tilemap); + draw_rect(^renderer, ~~input_state.mouse.x, ~~input_state.mouse.y, 10f, 10f); + + for ^d: dudes { + aabb := dude_get_aabb(d); + draw_rect(^renderer, aabb.x, aabb.y, aabb.w, aabb.h); + } + + render_context_flush(^renderer); +} + +// This procedure is called asynchronously from JS every frame. +new_frame_callback :: proc () #export { + update(); + draw(); +} + +main :: proc (args: [] cstring) { + println("Setting up WebGL2 canvas..."); + + if !gl.init("gamecanvas") { + print("Failed to initialize GL canvas."); + return; + } + + gl.enable(gl.CULL_FACE); + gl.cullFace(gl.BACK); + + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + + render_context_init(^renderer, null); + textures_init(); + + atlas = atlas_create(^textures.tilemap); + atlas_map(^atlas, 0, AtlasSprite.{ x = 16, y = 0, w = 16, h = 16 }); + + event.init(); + input.init(^input_state); + + array_init(^dudes); + for i: 0 .. 50 { + array_push(^dudes, dude_create_random()); + } + // array_push(^dudes, Dude.{ + // pos = V2f.{ 100.0f, 100.0f }, + // vel = V2f.{ 2.0f, 0.0f }, + // size = 10.0f, + // color = Color4f32.{ 1.0f, 1.0f, 1.0f, 1.0f }, + // }); + + // array_push(^dudes, Dude.{ + // pos = V2f.{ 1000.0f, 100.0f }, + // vel = V2f.{ -2.0f, 0.0f }, + // size = 10.0f, + // color = Color4f32.{ 1.0f, 1.0f, 1.0f, 1.0f }, + // }); + + game_launch :: proc () #foreign "game" "launch" ---; + game_launch(); +} + + +Dude_Color_Table : [4] Color4f32; + +Dude :: struct { + pos : V2f; + vel : V2f; + size : f32; + color : Color4f32; +} + +dude_create_random :: proc () -> Dude { + return Dude.{ + pos = V2f.{ random_float(0.0f, 800.0f), random_float(0.0f, 800.0f) }, + vel = V2f.{ random_float(-3.0f, 3.0f), random_float(-3.0f, 3.0f) }, + size = random_float(5.0f, 30.0f), + color = Dude_Color_Table[random_between(0, 3)], + }; +} + +dude_update :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { + // if random_between(0, 100) < 2 { + // vel.x = random_float(-2.0f, 2.0f); + // vel.y = random_float(-2.0f, 2.0f); + // } + + dude_try_move(dude, other_dudes); +} + +dude_try_move :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { + old_pos := pos; + + potential_dudes : [..] ^Dude; + array_init(^potential_dudes); + defer array_free(^potential_dudes); + + around := AABB.{ x = pos.x - size * 10.0f, y = pos.y - size * 10.0f, w = size * 20.0f, h = size * 20.0f }; + quadtree_query(other_dudes, around, ^potential_dudes); + + collided := false; + + pos.x += vel.x; + if pos.x - size < 0.0f || pos.x + size >= ~~window_width do collided = true; + + dude_aabb := dude_get_aabb(dude); + for other: potential_dudes { + if other == dude do continue; + + other_aabb := dude_get_aabb(other); + if aabb_intersects(dude_aabb, other_aabb) { + collided = true; + break; + } + } + + if collided { + pos.x -= vel.x; + vel.x = -vel.x; + } + + collided = false; + + pos.y += vel.y; + if pos.y - size < 0.0f || pos.y + size >= ~~window_height do collided = true; + + dude_aabb = dude_get_aabb(dude); + for other: potential_dudes { + if other == dude do continue; + + other_aabb := dude_get_aabb(other); + if aabb_intersects(dude_aabb, other_aabb) { + collided = true; + break; + } + } + + if collided { + pos.y -= vel.y; + vel.y = -vel.y; + } +} + +dude_get_aabb :: proc (use dude: ^Dude) -> AABB { + return AABB.{ x = pos.x - size, y = pos.y - size, w = size * 2.0f, h = size * 2.0f }; +} diff --git a/src/quad_tree.onyx b/src/quad_tree.onyx new file mode 100644 index 0000000..4ec3e21 --- /dev/null +++ b/src/quad_tree.onyx @@ -0,0 +1,97 @@ +package quad_tree + +use package core +use package aabb + +#private_file +QUAD_TREE_ENTITY_STORAGE :: 2; + +QuadTree :: struct ($T) { + region : AABB; + + points : [QUAD_TREE_ENTITY_STORAGE] ^T; + points_count : u32 = 0; + + nw: ^QuadTree(T) = null; + ne: ^QuadTree(T) = null; + sw: ^QuadTree(T) = null; + se: ^QuadTree(T) = null; +} + +quadtree_init :: proc (qt: ^QuadTree($T), initial_region: AABB) { + qt.region = initial_region; + qt.nw = null; + qt.ne = null; + qt.sw = null; + qt.se = null; + qt.points_count = 0; + + for ^p: qt.points do *p = null; +} + +// quadtree_free :: proc (qt: ^QuadTree($T), initial := true) { +// if qt.nw != null { +// quadtree_free(qt.nw, false); +// quadtree_free(qt.ne, false); +// quadtree_free(qt.sw, false); +// quadtree_free(qt.se, false); +// } +// +// if !initial { +// cfree(qt); +// } +// } + +quadtree_subdivide :: proc (use qt: ^QuadTree($T), a: Allocator) { + if nw != null do return; + + hw := region.w / ~~ 2; + hh := region.h / ~~ 2; + + qt.nw = alloc(a, sizeof QuadTree(T)); + qt.ne = alloc(a, sizeof QuadTree(T)); + qt.sw = alloc(a, sizeof QuadTree(T)); + qt.se = alloc(a, sizeof QuadTree(T)); + + quadtree_init(qt.nw, AABB.{ region.x, region.y, hw, hh }); + quadtree_init(qt.ne, AABB.{ region.x + hw, region.y, hw, hh }); + quadtree_init(qt.sw, AABB.{ region.x, region.y + hh, hw, hh }); + quadtree_init(qt.se, AABB.{ region.x + hw, region.y + hh, hw, hh }); +} + +quadtree_insert :: proc (use qt: ^QuadTree($T), t: ^T, alloc := context.allocator) -> bool { + pos := t.pos; // T is expected to have a 'pos' element. + + if !aabb_contains(region, pos) do return false; + + if points_count < QUAD_TREE_ENTITY_STORAGE && nw == null { + points[points_count] = t; + points_count += 1; + return true; + } + + if nw == null do quadtree_subdivide(qt, alloc); + + if quadtree_insert(nw, t, alloc) do return true; + if quadtree_insert(ne, t, alloc) do return true; + if quadtree_insert(sw, t, alloc) do return true; + if quadtree_insert(se, t, alloc) do return true; + + return false; +} + +quadtree_query :: proc (use qt: ^QuadTree($T), r: AABB, p: ^[..] ^T) { + if !aabb_intersects(region, r) do return; + + while i := 0; i < points_count { + if aabb_contains(r, points[i].pos) do array_push(p, points[i]); + i += 1; + } + + if nw == null do return; + + quadtree_query(nw, r, p); + quadtree_query(ne, r, p); + quadtree_query(sw, r, p); + quadtree_query(se, r, p); +} diff --git a/src/shaders/basic.frag b/src/shaders/quad.frag similarity index 52% rename from src/shaders/basic.frag rename to src/shaders/quad.frag index 0d9552f..59ab7ef 100644 --- a/src/shaders/basic.frag +++ b/src/shaders/quad.frag @@ -10,5 +10,9 @@ in vec4 v_col; out vec4 fragColor; void main() { - fragColor = v_col * texture(tex, v_tex_pos); + if (v_tex_pos.x < 0.0) { + fragColor = v_col; + } else { + fragColor = v_col * texture(tex, v_tex_pos); + } } diff --git a/src/shaders/basic.vert b/src/shaders/quad.vert similarity index 72% rename from src/shaders/basic.vert rename to src/shaders/quad.vert index cb8a34b..c7fa396 100644 --- a/src/shaders/basic.vert +++ b/src/shaders/quad.vert @@ -11,6 +11,7 @@ layout(location = 4) in vec2 a_tex_size; layout(location = 5) in vec4 a_col; uniform mat4 u_proj; +// uniform mat4 u_world; out vec2 v_tex_pos; out vec4 v_col; @@ -19,5 +20,9 @@ void main() { gl_Position = u_proj * vec4(a_vert_pos * a_size + a_pos, 0, 1); v_col = a_col; - v_tex_pos = a_tex_pos + a_vert_pos * a_tex_size; + if (a_tex_pos.x < 0.0) { + v_tex_pos = vec2(-1.0, -1.0); + } else { + v_tex_pos = a_tex_pos + a_vert_pos * a_tex_size; + } } diff --git a/tags b/tags index cc29dd4..ed3f28b 100644 --- a/tags +++ b/tags @@ -6,6 +6,7 @@ !_TAG_PROGRAM_NAME Onyx Compiler !_TAG_PROGRAM_URL https://github.com/brendanfh/onyx !_TAG_PROGRAM_VERSION 0.0.1 +AABB src/aabb.onyx /^AABB :: struct {$/ ACTIVE_ATTRIBUTES /usr/share/onyx/core/js/webgl.onyx /^ACTIVE_ATTRIBUTES :: 0x8B89$/ ACTIVE_TEXTURE /usr/share/onyx/core/js/webgl.onyx /^ACTIVE_TEXTURE :: 0x84E0$/ ACTIVE_UNIFORMS /usr/share/onyx/core/js/webgl.onyx /^ACTIVE_UNIFORMS :: 0x8B86$/ @@ -23,6 +24,8 @@ ARRAY_BUFFER_BINDING /usr/share/onyx/core/js/webgl.onyx /^ARRAY_BUFFER_BINDING ATTACHED_SHADERS /usr/share/onyx/core/js/webgl.onyx /^ATTACHED_SHADERS :: 0x8B85$/ AllocAction /usr/share/onyx/core/builtin.onyx /^AllocAction :: enum {$/ Allocator /usr/share/onyx/core/builtin.onyx /^Allocator :: struct {$/ +Atlas src/gfx/atlas.onyx /^Atlas :: struct {$/ +AtlasSprite src/gfx/atlas.onyx /^AtlasSprite :: struct {$/ BACK /usr/share/onyx/core/js/webgl.onyx /^BACK :: 0x0405$/ BLEND /usr/share/onyx/core/js/webgl.onyx /^BLEND :: 0x0BE2$/ BLEND_COLOR /usr/share/onyx/core/js/webgl.onyx /^BLEND_COLOR :: 0x8005$/ @@ -132,6 +135,8 @@ DYNAMIC_DRAW /usr/share/onyx/core/js/webgl.onyx /^DYNAMIC_DRAW DYNAMIC_READ /usr/share/onyx/core/js/webgl.onyx /^DYNAMIC_READ :: 0x88E9$/ DomEvent src/events.onyx /^DomEvent :: struct {$/ DomEventKind src/events.onyx /^DomEventKind :: enum {$/ +Dude src/main.onyx /^Dude :: struct {$/ +Dude_Color_Table src/main.onyx /^Dude_Color_Table : [4] Color4f32;$/ ELEMENT_ARRAY_BUFFER /usr/share/onyx/core/js/webgl.onyx /^ELEMENT_ARRAY_BUFFER :: 0x8893$/ ELEMENT_ARRAY_BUFFER_BINDING /usr/share/onyx/core/js/webgl.onyx /^ELEMENT_ARRAY_BUFFER_BINDING :: 0x8895$/ EQUAL /usr/share/onyx/core/js/webgl.onyx /^EQUAL :: 0x0202$/ @@ -331,13 +336,13 @@ POINTS /usr/share/onyx/core/js/webgl.onyx /^POINTS :: 0x POLYGON_OFFSET_FACTOR /usr/share/onyx/core/js/webgl.onyx /^POLYGON_OFFSET_FACTOR :: 0x8038$/ POLYGON_OFFSET_FILL /usr/share/onyx/core/js/webgl.onyx /^POLYGON_OFFSET_FILL :: 0x8037$/ POLYGON_OFFSET_UNITS /usr/share/onyx/core/js/webgl.onyx /^POLYGON_OFFSET_UNITS :: 0x2A00$/ -Player src/main.onyx /^Player :: struct { use pos : Vec2; }$/ PtrMap /usr/share/onyx/core/ptrmap.onyx /^PtrMap :: struct {$/ PtrMapEntry /usr/share/onyx/core/ptrmap.onyx /^PtrMapEntry :: struct {$/ QUERY_RESULT /usr/share/onyx/core/js/webgl.onyx /^QUERY_RESULT :: 0x8866$/ QUERY_RESULT_AVAILABLE /usr/share/onyx/core/js/webgl.onyx /^QUERY_RESULT_AVAILABLE :: 0x8867$/ Quad src/gfx/quad_renderer.onyx /^Quad :: struct {$/ QuadRenderer src/gfx/quad_renderer.onyx /^QuadRenderer :: struct {$/ +QuadTree src/quad_tree.onyx /^QuadTree :: struct ($T) {$/ R11F_G11F_B10F /usr/share/onyx/core/js/webgl.onyx /^R11F_G11F_B10F :: 0x8C3A$/ R16F /usr/share/onyx/core/js/webgl.onyx /^R16F :: 0x822D$/ R16I /usr/share/onyx/core/js/webgl.onyx /^R16I :: 0x8233$/ @@ -635,9 +640,10 @@ VERTEX_ATTRIB_ARRAY_STRIDE /usr/share/onyx/core/js/webgl.onyx /^VERTEX_ATTRIB_AR VERTEX_ATTRIB_ARRAY_TYPE /usr/share/onyx/core/js/webgl.onyx /^VERTEX_ATTRIB_ARRAY_TYPE :: 0x8625$/ VERTEX_SHADER /usr/share/onyx/core/js/webgl.onyx /^VERTEX_SHADER :: 0x8B31$/ VIEWPORT /usr/share/onyx/core/js/webgl.onyx /^VIEWPORT :: 0x0BA2$/ -Vec2 src/gfx/quad_renderer.onyx /^Vec2 :: struct {$/ WAIT_FAILED /usr/share/onyx/core/js/webgl.onyx /^WAIT_FAILED :: 0x911D$/ ZERO /usr/share/onyx/core/js/webgl.onyx /^ZERO :: 0$/ +aabb_contains src/aabb.onyx /^aabb_contains :: proc (r: AABB, v: V2f) -> bool {$/ +aabb_intersects src/aabb.onyx /^aabb_intersects :: proc (r1: AABB, r2: AABB) -> bool {$/ abs_f32 /usr/share/onyx/core/intrinsics.onyx /^abs_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ abs_f64 /usr/share/onyx/core/intrinsics.onyx /^abs_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ activeTexture /usr/share/onyx/core/js/webgl.onyx /^activeTexture :: proc (texture: GLenum) #foreign "gl" "activeTexture" ---$/ @@ -662,6 +668,10 @@ array_push /usr/share/onyx/core/array.onyx /^array_push :: proc (arr: ^[..] $T, array_remove /usr/share/onyx/core/array.onyx /^array_remove :: proc (arr: ^[..] $T, elem: T) {$/ array_sort /usr/share/onyx/core/array.onyx /^array_sort :: proc (arr: ^[..] $T, cmp: proc (T, T) -> i32) {$/ array_to_slice /usr/share/onyx/core/array.onyx /^array_to_slice :: proc (arr: ^[..] $T) -> [] T {$/ +atlas src/main.onyx /^atlas : Atlas$/ +atlas_apply_to_quad src/gfx/atlas.onyx /^atlas_apply_to_quad :: proc (use atlas: ^Atlas, id: i32, quad: ^Quad) {$/ +atlas_create src/gfx/atlas.onyx /^atlas_create :: proc (tex: ^Texture) -> Atlas {$/ +atlas_map src/gfx/atlas.onyx /^atlas_map :: proc (use atlas: ^Atlas, id: i32, sprite: AtlasSprite) {$/ attachShader /usr/share/onyx/core/js/webgl.onyx /^attachShader :: proc (program: GLProgram, shader: GLShader) -> GLProgram #foreign "gl" "attachShader" ---$/ bezier_curve src/font.onyx /^bezier_curve :: proc (t: f32, ps: [] V2f) -> V2f {$/ binary_reader_create src/font.onyx /^binary_reader_create :: proc (data: [] u8, initial_pos := 0) -> BinaryReader {$/ @@ -738,20 +748,28 @@ drawArrays /usr/share/onyx/core/js/webgl.onyx /^drawArrays : drawArraysInstanced /usr/share/onyx/core/js/webgl.onyx /^drawArraysInstanced :: proc (mode: GLenum, first: GLint, count: GLsizei, instanceCount: GLsizei) #foreign "gl" "drawArraysInstanced" ---$/ drawElements /usr/share/onyx/core/js/webgl.onyx /^drawElements :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint) #foreign "gl" "drawElements" ---$/ drawElementsInstanced /usr/share/onyx/core/js/webgl.onyx /^drawElementsInstanced :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint, instanceCount: GLsizei) #foreign "gl" "drawElementsInstanced" ---$/ +draw_quad src/main.onyx /^draw_quad :: proc (use rc: ^RenderContext, quad: ^Quad) {$/ +draw_quad_tree src/main.onyx /^draw_quad_tree :: proc (qt: ^QuadTree($T), level := 0, corner := 4) {$/ draw_rect src/main.onyx /^draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) {$/ +draw_textured_rect src/main.onyx /^draw_textured_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32, tx: f32, ty: f32, tw: f32, th: f32) {$/ +dude_create_random src/main.onyx /^dude_create_random :: proc () -> Dude {$/ +dude_get_aabb src/main.onyx /^dude_get_aabb :: proc (use dude: ^Dude) -> AABB {$/ +dude_tree src/main.onyx /^dude_tree : QuadTree(Dude)$/ +dude_try_move src/main.onyx /^dude_try_move :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) {$/ +dude_update src/main.onyx /^dude_update :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) {$/ +dudes src/main.onyx /^dudes : [..] Dude$/ enable /usr/share/onyx/core/js/webgl.onyx /^enable :: proc (cap: GLenum) #foreign "gl" "enable" ---$/ enableVertexAttribArray /usr/share/onyx/core/js/webgl.onyx /^enableVertexAttribArray :: proc (index: GLuint) #foreign "gl" "enableVertexAttribArray" ---$/ +f64_to_string /usr/share/onyx/core/string.onyx /^f64_to_string :: proc (f: f64, buf: [] u8) -> string {$/ finish /usr/share/onyx/core/js/webgl.onyx /^finish :: proc () #foreign "gl" "finish" ---$/ floor_f32 /usr/share/onyx/core/intrinsics.onyx /^floor_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ floor_f64 /usr/share/onyx/core/intrinsics.onyx /^floor_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ flush /usr/share/onyx/core/js/webgl.onyx /^flush :: proc () #foreign "gl" "flush" ---$/ -font_tex src/main.onyx /^font_tex : Texture$/ framebufferRenderbuffer /usr/share/onyx/core/js/webgl.onyx /^framebufferRenderbuffer :: proc (target: GLenum, attachment: GLenum, renderbuffertarget: GLenum, renderbuffer: GLRenderbuffer) #foreign "gl" "framebufferRenderbuffer" ---$/ framebufferTexture2D /usr/share/onyx/core/js/webgl.onyx /^framebufferTexture2D :: proc (target: GLenum, attachment: GLenum, textarget: GLenum, texture: GLTexture, level: GLint) #foreign "gl" "framebufferTexture2D" ---$/ framebufferTextureLayer /usr/share/onyx/core/js/webgl.onyx /^framebufferTextureLayer :: proc (target: GLenum, attachment: GLenum, texture: GLTexture, level: GLint, layer: GLint) #foreign "gl" "framebufferTextureLayer" ---$/ free /usr/share/onyx/core/builtin.onyx /^free :: proc (use a: Allocator, ptr: rawptr) {$/ frontFace /usr/share/onyx/core/js/webgl.onyx /^frontFace :: proc (mode: GLenum) #foreign "gl" "frontFace" ---$/ -game_launch src/main.onyx /^game_launch :: proc () #foreign "game" "launch" ---$/ generateMipmap /usr/share/onyx/core/js/webgl.onyx /^generateMipmap :: proc (target: GLenum) #foreign "gl" "generateMipmap" ---$/ getActiveAttrib /usr/share/onyx/core/js/webgl.onyx /^getActiveAttrib :: proc (program: GLProgram, index: GLuint, out: ^GLActiveInfo) #foreign "gl" "getActiveAttrib" ---$/ getActiveUniform /usr/share/onyx/core/js/webgl.onyx /^getActiveUniform :: proc (program: GLProgram, index: GLuint, out: ^GLActiveInfo) #foreign "gl" "getActiveUniform" ---$/ @@ -763,8 +781,6 @@ getProgramParameter /usr/share/onyx/core/js/webgl.onyx /^getProgramParameter getShaderParameter /usr/share/onyx/core/js/webgl.onyx /^getShaderParameter :: proc (shader: GLShader, pname: GLenum) -> GLenum #foreign "gl" "getShaderParameter" ---$/ getUniformLocation /usr/share/onyx/core/js/webgl.onyx /^getUniformLocation :: proc (program: GLProgram, name: string) -> GLUniformLocation #foreign "gl" "getUniformLocation" ---$/ getVertexAttribOffset /usr/share/onyx/core/js/webgl.onyx /^getVertexAttribOffset :: proc (index: GLuint, pname: GLenum) #foreign "gl" "getVertexAttribOffset" ---$/ -glyph_data src/main.onyx /^glyph_data : [glyph_size * glyph_size] u8$/ -glyph_size src/main.onyx /^glyph_size :: 64$/ heap_alloc /usr/share/onyx/core/alloc.onyx /^heap_alloc :: proc (size_: u32, align: u32) -> rawptr {$/ heap_alloc_proc /usr/share/onyx/core/alloc.onyx /^heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, oldptr: rawptr) -> rawptr {$/ heap_allocator /usr/share/onyx/core/alloc.onyx /^heap_allocator : Allocator;$/ @@ -804,6 +820,7 @@ max_poly /usr/share/onyx/core/math.onyx /^max_poly :: proc (a: $T, b: T) -> T {$ memory_copy /usr/share/onyx/core/memory.onyx /^memory_copy :: proc (dst_: rawptr, src_: rawptr, len: u32) {$/ memory_grow /usr/share/onyx/core/intrinsics.onyx /^memory_grow :: proc (val: i32) -> i32 #intrinsic ---$/ memory_init /usr/share/onyx/core/alloc.onyx /^memory_init :: proc () {$/ +memory_set /usr/share/onyx/core/memory.onyx /^memory_set :: proc (start: rawptr, length: u32, value: u8) {$/ memory_size /usr/share/onyx/core/intrinsics.onyx /^memory_size :: proc () -> i32 #intrinsic ---$/ min_f32 /usr/share/onyx/core/intrinsics.onyx /^min_f32 :: proc (lhs: f32, rhs: f32) -> f32 #intrinsic ---$/ min_f64 /usr/share/onyx/core/intrinsics.onyx /^min_f64 :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/ @@ -816,7 +833,6 @@ or_i32 /usr/share/onyx/core/intrinsics.onyx /^or_i32 :: proc (lhs: i32, rh or_i64 /usr/share/onyx/core/intrinsics.onyx /^or_i64 :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/ output_string /usr/share/onyx/core/sys/js.onyx /^output_string :: proc (s: string) -> u32 #foreign "host" "print_str" ---$/ pixelStorei /usr/share/onyx/core/js/webgl.onyx /^pixelStorei :: proc (pname: GLenum, param: GLenum) #foreign "gl" "pixelStorei" ---$/ -player src/main.onyx /^player : Player$/ poll src/events.onyx /^poll :: proc (ev: ^Event) -> bool {$/ poll_events src/main.onyx /^poll_events :: proc () {$/ polygonOffset /usr/share/onyx/core/js/webgl.onyx /^polygonOffset :: proc (factor: GLfloat, units: GLfloat) #foreign "gl" "polygonOffset" ---$/ @@ -831,12 +847,15 @@ print_array /usr/share/onyx/core/stdio.onyx /^print_array :: proc (arr: $T, sep print_bool /usr/share/onyx/core/stdio.onyx /^print_bool :: proc (b: bool) do string_builder_append(^print_buffer, b);$/ print_buffer_flush /usr/share/onyx/core/stdio.onyx /^print_buffer_flush :: proc () {$/ print_cstring /usr/share/onyx/core/stdio.onyx /^print_cstring :: proc (s: cstring) do string_builder_append(^print_buffer, s);$/ +print_f32 /usr/share/onyx/core/stdio.onyx /^print_f32 :: proc (n: f32) do string_builder_append(^print_buffer, cast(f64) n);$/ +print_f64 /usr/share/onyx/core/stdio.onyx /^print_f64 :: proc (n: f64) do string_builder_append(^print_buffer, n);$/ print_i32 /usr/share/onyx/core/stdio.onyx /^print_i32 :: proc (n: i32, base := 10) do string_builder_append(^print_buffer, cast(i64) n, cast(u64) base);$/ print_i64 /usr/share/onyx/core/stdio.onyx /^print_i64 :: proc (n: i64, base := 10l) do string_builder_append(^print_buffer, n, base);$/ print_ptr /usr/share/onyx/core/stdio.onyx /^print_ptr :: proc (p: ^void) do string_builder_append(^print_buffer, cast(i64) p, 16l);$/ print_range /usr/share/onyx/core/stdio.onyx /^print_range :: proc (r: range, sep := " ") {$/ print_string /usr/share/onyx/core/stdio.onyx /^print_string :: proc (s: string) {$/ print_vec src/vecmath.onyx /^print_vec :: proc (v: V2($T)) {$/ +printf /usr/share/onyx/core/stdio.onyx /^printf :: proc (format: string, va: ...) {$/ println /usr/share/onyx/core/stdio.onyx /^println :: proc (x: $T) {$/ process_event src/input.onyx /^process_event :: proc (use state: ^InputState, ev: ^event.Event) {$/ ptrmap_clear /usr/share/onyx/core/ptrmap.onyx /^ptrmap_clear :: proc (use pmap: ^PtrMap) {$/ @@ -847,10 +866,15 @@ ptrmap_has /usr/share/onyx/core/ptrmap.onyx /^ptrmap_has :: proc (use pmap: ^Ptr ptrmap_init /usr/share/onyx/core/ptrmap.onyx /^ptrmap_init :: proc (use pmap: ^PtrMap, hash_count: i32 = 16) {$/ ptrmap_put /usr/share/onyx/core/ptrmap.onyx /^ptrmap_put :: proc (use pmap: ^PtrMap, key: rawptr, value: rawptr) {$/ quad_rebuffer_data src/gfx/quad_renderer.onyx /^quad_rebuffer_data :: proc (use qr: ^QuadRenderer) {$/ -quad_renderer_draw src/gfx/quad_renderer.onyx /^quad_renderer_draw :: proc (use qr: ^QuadRenderer) {$/ +quad_renderer_draw src/gfx/quad_renderer.onyx /^quad_renderer_draw :: proc (use qr: ^QuadRenderer, count := -1) {$/ quad_renderer_init src/gfx/quad_renderer.onyx /^quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {$/ quad_renderer_update_view src/gfx/quad_renderer.onyx /^quad_renderer_update_view :: proc (use qr: ^QuadRenderer) {$/ +quad_scratch_buffer src/main.onyx /^quad_scratch_buffer : [128 * 1024] u8;$/ quad_update_at_index src/gfx/quad_renderer.onyx /^quad_update_at_index :: proc (use qr: ^QuadRenderer, idx: i32, quad: Quad) {$/ +quadtree_init src/quad_tree.onyx /^quadtree_init :: proc (qt: ^QuadTree($T), initial_region: AABB) {$/ +quadtree_insert src/quad_tree.onyx /^quadtree_insert :: proc (use qt: ^QuadTree($T), t: ^T, alloc := context.allocator) -> bool {$/ +quadtree_query src/quad_tree.onyx /^quadtree_query :: proc (use qt: ^QuadTree($T), r: AABB, p: ^[..] ^T) {$/ +quadtree_subdivide src/quad_tree.onyx /^quadtree_subdivide :: proc (use qt: ^QuadTree($T), a: Allocator) {$/ random /usr/share/onyx/core/random.onyx /^random :: proc (s := ^seed) -> u32 {$/ random_between /usr/share/onyx/core/random.onyx /^random_between :: proc (lo: i32, hi: i32) -> i32 do return random() % (hi + 1 - lo) + lo;$/ random_float /usr/share/onyx/core/random.onyx /^random_float :: proc (lo := 0.0f, hi := 1.0f) -> f32 {$/ @@ -881,7 +905,6 @@ shl_i64 /usr/share/onyx/core/intrinsics.onyx /^shl_i64 :: proc (lhs: i64, r sin /usr/share/onyx/core/math.onyx /^sin :: proc (t_: f32) -> f32 {$/ slr_i32 /usr/share/onyx/core/intrinsics.onyx /^slr_i32 :: proc (lhs: i32, rhs: i32) -> i32 #intrinsic ---$/ slr_i64 /usr/share/onyx/core/intrinsics.onyx /^slr_i64 :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/ -smile src/main.onyx /^smile : Texture$/ sqrt_f32 /usr/share/onyx/core/intrinsics.onyx /^sqrt_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ sqrt_f64 /usr/share/onyx/core/intrinsics.onyx /^sqrt_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ sqrt_i32 /usr/share/onyx/core/math.onyx /^sqrt_i32 :: proc (x: i32) -> i32 {$/ @@ -896,6 +919,7 @@ string /usr/share/onyx/core/builtin.onyx /^string :: #type []u8;$/ string_advance_line /usr/share/onyx/core/string.onyx /^string_advance_line :: proc (str: ^string) {$/ string_builder_add_bool /usr/share/onyx/core/string.onyx /^string_builder_add_bool :: proc (use sb: ^StringBuilder, b: bool) -> ^StringBuilder {$/ string_builder_add_cstring /usr/share/onyx/core/string.onyx /^string_builder_add_cstring :: proc (use sb: ^StringBuilder, cstr: cstring) -> ^StringBuilder {$/ +string_builder_add_f64 /usr/share/onyx/core/string.onyx /^string_builder_add_f64 :: proc (use sb: ^StringBuilder, f: f64) -> ^StringBuilder {$/ string_builder_add_i64 /usr/share/onyx/core/string.onyx /^string_builder_add_i64 :: proc (use sb: ^StringBuilder, n: i64, base := 10l) -> ^StringBuilder {$/ string_builder_add_string /usr/share/onyx/core/string.onyx /^string_builder_add_string :: proc (use sb: ^StringBuilder, str: string) -> ^StringBuilder {$/ string_builder_append /usr/share/onyx/core/string.onyx /^string_builder_append :: proc {$/ @@ -923,9 +947,10 @@ texSubImage2D /usr/share/onyx/core/js/webgl.onyx /^texSubImage2D texture_create src/gfx/texture.onyx /^texture_create :: proc (texdata: [] u8, width: i32, height: i32, data_mode := TextureDataMode.RGB) -> Texture {$/ texture_prepare src/gfx/texture.onyx /^texture_prepare :: proc (use tex: ^Texture) {$/ texture_use src/gfx/texture.onyx /^texture_use :: proc (use tex: ^Texture) {$/ +textures src/gfx/texture.onyx /^textures : struct {$/ +textures_init src/gfx/texture.onyx /^textures_init :: proc () {$/ trunc_f32 /usr/share/onyx/core/intrinsics.onyx /^trunc_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ trunc_f64 /usr/share/onyx/core/intrinsics.onyx /^trunc_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ -ttf src/main.onyx /^ttf : TrueTypeFont$/ ttf_create src/font.onyx /^ttf_create :: proc (ttf_data: [] u8) -> TrueTypeFont {$/ ttf_glyph_count src/font.onyx /^ttf_glyph_count :: proc (use ttf: ^TrueTypeFont) -> u32 {$/ ttf_glyph_destroy src/font.onyx /^ttf_glyph_destroy :: proc (glyph: ^TTGlyph) {$/ @@ -963,6 +988,8 @@ v2_orientation src/vecmath.onyx /^v2_orientation :: proc (a: V2($T), b: V2(T), c v2_square_dist src/vecmath.onyx /^v2_square_dist :: proc (a: V2($T), b: V2(T)) -> T {$/ v2_sub src/vecmath.onyx /^v2_sub :: proc (a: V2($T), b: V2(T)) -> V2(T) {$/ validateProgram /usr/share/onyx/core/js/webgl.onyx /^validateProgram :: proc (program: GLProgram) #foreign "gl" "validateProgram" ---$/ +vararg /usr/share/onyx/core/builtin.onyx /^vararg :: #type ^struct {$/ +vararg_get /usr/share/onyx/core/builtin.onyx /^vararg_get :: proc (va: vararg, ret: ^$T) -> bool {$/ vertexAttrib1f /usr/share/onyx/core/js/webgl.onyx /^vertexAttrib1f :: proc (idx: GLuint, x: GLfloat) #foreign "gl" "vertexAttrib1f" ---$/ vertexAttrib2f /usr/share/onyx/core/js/webgl.onyx /^vertexAttrib2f :: proc (idx: GLuint, x: GLfloat, y: GLfloat) #foreign "gl" "vertexAttrib2f" ---$/ vertexAttrib3f /usr/share/onyx/core/js/webgl.onyx /^vertexAttrib3f :: proc (idx: GLuint, x: GLfloat, y: GLfloat, z: GLfloat) #foreign "gl" "vertexAttrib3f" ---$/ -- 2.25.1