From 907170ea797c06911ab3d875f2cc13f927a0a3bc Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Tue, 6 Oct 2020 15:11:39 -0500 Subject: [PATCH] frame rate independence and font rendering --- js/environment.js | 2 +- res/tilemap.data | Bin 196608 -> 196608 bytes res/tilemap.png | Bin 3649 -> 23392 bytes src/gfx/atlas.onyx | 12 ++++++- src/gfx/font.onyx | 33 ++++++++++++++++++++ src/input.onyx | 24 +++++++------- src/main.onyx | 71 ++++++++++++++++++++++++++---------------- src/quad_tree.onyx | 3 +- src/shaders/quad.frag | 7 ++++- tags | 12 ++++--- 10 files changed, 117 insertions(+), 47 deletions(-) create mode 100644 src/gfx/font.onyx diff --git a/js/environment.js b/js/environment.js index b004561..d011d8d 100644 --- a/js/environment.js +++ b/js/environment.js @@ -9,7 +9,7 @@ async function start_game() { while (true) { await anim_frame(); - WASM_EXPORTS.new_frame_callback(); + WASM_EXPORTS.loop(); } } diff --git a/res/tilemap.data b/res/tilemap.data index e53b2339e3396ee16a9e244915a4d6c1d1e7caca..3c0ea7acc704902b164281857d1a142eb875d773 100644 GIT binary patch literal 196608 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 delta 118 qcmZo@;AsG&C5#U?D;hjvns`8Q^JP;5Eg*4$X|syKeOic|WdZ;QoHPRf diff --git a/res/tilemap.png b/res/tilemap.png index f165b3ddca8a6950f9f6eeda1d8f26e147b8b902..351e18d35dfdee907babb508fb1148944a4d89b7 100644 GIT binary patch literal 23392 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 literal 3649 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 BfJy)W diff --git a/src/gfx/atlas.onyx b/src/gfx/atlas.onyx index ae92c1c..03f227c 100644 --- a/src/gfx/atlas.onyx +++ b/src/gfx/atlas.onyx @@ -28,8 +28,18 @@ atlas_map :: proc (use atlas: ^Atlas, id: i32, sprite: AtlasSprite) { i32map_put(^map, id, sprite); } -atlas_lookup :: proc (use atlas: ^Atlas, id: i32) -> AtlasSprite { +atlas_lookup :: proc (use atlas: ^Atlas, id: i32, offset := 0) -> AtlasSprite { sprite := i32map_get(^map, id, AtlasSprite.{}); + + if offset != 0 { + sprite.x += ~~offset * sprite.w; + + while sprite.x >= ~~texture.width { + sprite.y += sprite.h; + sprite.x -= ~~texture.width; + } + } + sprite.x /= ~~texture.width; sprite.y /= ~~texture.width; sprite.w /= ~~texture.width; diff --git a/src/gfx/font.onyx b/src/gfx/font.onyx new file mode 100644 index 0000000..f3e4415 --- /dev/null +++ b/src/gfx/font.onyx @@ -0,0 +1,33 @@ +package gfx + +use package core +use package globals +use package vecmath +use package main { RenderContext, draw_textured_rect } + +#private_file +font_chars :: "0123456789!\"#$% ABCDEFGHIJKLMNOPQRSTUVWXYZ'()*+,abcdefghijklmnopqrstuvwxyz,-./\\,^:;<=>?[]~|_"; + +#private_file +char_to_tex_offset :: proc (ch: u8) -> u32 { + loc := 0; + for c: font_chars { + if c == ch do break; + loc += 1; + } + return loc; +} + +draw_text :: proc (renderer: ^RenderContext, s: string, pos: V2f, scale := 1.0f) { + x := pos.x; + y := pos.y; + + font_size := scale * 16.0f; + + for ch: s { + char_sprite := atlas_lookup(^atlas, 2, char_to_tex_offset(ch)); + draw_textured_rect(renderer, x, y, font_size, font_size, char_sprite.x, char_sprite.y, char_sprite.w, char_sprite.h); + + x += font_size * 0.85f; + } +} \ No newline at end of file diff --git a/src/input.onyx b/src/input.onyx index ba86a0f..00ea2ee 100644 --- a/src/input.onyx +++ b/src/input.onyx @@ -64,29 +64,29 @@ process_event :: proc (use state: ^InputState, ev: ^event.Event) { } case MouseDown { - mouse.dx += (ev.mouse.pos_x - half_window_width) - mouse.x; - mouse.dy += (ev.mouse.pos_y - half_window_height) - mouse.y; - mouse.x = ev.mouse.pos_x - half_window_width; - mouse.y = ev.mouse.pos_y - half_window_height; + mouse.dx += ev.mouse.pos_x - mouse.x; + mouse.dy += ev.mouse.pos_y - mouse.y; + mouse.x = ev.mouse.pos_x; + mouse.y = ev.mouse.pos_y; mouse.buttons_just_down[cast(u32) ev.mouse.button] = !mouse.buttons_down[cast(u32) ev.mouse.button]; mouse.buttons_down[cast(u32) ev.mouse.button] = true; } case MouseUp { - mouse.dx += (ev.mouse.pos_x - half_window_width) - mouse.x; - mouse.dy += (ev.mouse.pos_y - half_window_height) - mouse.y; - mouse.x = ev.mouse.pos_x - half_window_width; - mouse.y = ev.mouse.pos_y - half_window_height; + mouse.dx += ev.mouse.pos_x - mouse.x; + mouse.dy += ev.mouse.pos_y - mouse.y; + mouse.x = ev.mouse.pos_x; + mouse.y = ev.mouse.pos_y; mouse.buttons_down[cast(u32) ev.mouse.button] = false; mouse.buttons_just_down[cast(u32) ev.mouse.button] = false; } case MouseMove { - mouse.dx += (ev.mouse.pos_x - half_window_width) - mouse.x; - mouse.dy += (ev.mouse.pos_y - half_window_height) - mouse.y; - mouse.x = ev.mouse.pos_x - half_window_width; - mouse.y = ev.mouse.pos_y - half_window_height; + mouse.dx += ev.mouse.pos_x - mouse.x; + mouse.dy += ev.mouse.pos_y - mouse.y; + mouse.x = ev.mouse.pos_x; + mouse.y = ev.mouse.pos_y; } case MouseWheel { diff --git a/src/main.onyx b/src/main.onyx index 5016653..af6df41 100644 --- a/src/main.onyx +++ b/src/main.onyx @@ -8,6 +8,7 @@ package main #include_file "gfx/quad_renderer" #include_file "gfx/texture" #include_file "gfx/atlas" +#include_file "gfx/font" #include_file "events" #include_file "input" #include_file "font" @@ -92,7 +93,7 @@ draw_quad :: proc (use rc: ^RenderContext, quad: ^Quad) { } render_context_ui :: proc (use rc: ^RenderContext) { - quad_renderer_update_world(quad_renderer, 1.0f, 1.0f, 0.0f, 0.0f); + quad_renderer_update_world(quad_renderer, 1.0f, 1.0f, ~~-half_window_width, ~~-half_window_height); quad_rebuffer_data(quad_renderer); quad_renderer_draw(quad_renderer, curr_quad_idx); @@ -136,17 +137,17 @@ poll_events :: proc () { quad_scratch_buffer : [512 * 1024] u8; simulating := true; -update :: proc () { +update :: proc (dt: f32) { input.preupdate(^input_state); defer input.postupdate(^input_state); poll_events(); if input.key_just_down(^input_state, Key.Space) do simulating = !simulating; - if input.key_down(^input_state, Key.ArrowUp) do renderer.trans_y += 15.0f / renderer.scale; - if input.key_down(^input_state, Key.ArrowDown) do renderer.trans_y -= 15.0f / renderer.scale; - if input.key_down(^input_state, Key.ArrowLeft) do renderer.trans_x += 15.0f / renderer.scale; - if input.key_down(^input_state, Key.ArrowRight) do renderer.trans_x -= 15.0f / renderer.scale; + if input.key_down(^input_state, Key.ArrowUp) do renderer.trans_y += (500.0f / renderer.scale) * dt; + if input.key_down(^input_state, Key.ArrowDown) do renderer.trans_y -= (500.0f / renderer.scale) * dt; + if input.key_down(^input_state, Key.ArrowLeft) do renderer.trans_x += (500.0f / renderer.scale) * dt; + if input.key_down(^input_state, Key.ArrowRight) do renderer.trans_x -= (500.0f / renderer.scale) * dt; if input_state.mouse.wheel_ups > ~~0 do renderer.scale *= 1.125f; if input_state.mouse.wheel_downs > ~~0 do renderer.scale /= 1.125f; @@ -165,10 +166,10 @@ update :: proc () { quadtree_init(^dude_tree, AABB.{ ~~-half_window_width, ~~-half_window_height, ~~window_width, ~~window_height }); for ^d: dudes do quadtree_insert(^dude_tree, d, quad_alloc); - for ^d: dudes do dude_update(d, ^dude_tree); + for ^d: dudes do dude_update(d, dt, ^dude_tree); for ^d: dudes { - if d.can_move_x do d.pos.x += d.vel.x; - if d.can_move_y do d.pos.y += d.vel.y; + if d.can_move_x do d.pos.x += d.vel.x * dt; + if d.can_move_y do d.pos.y += d.vel.y * dt; if !d.can_move_x && !d.can_move_y do d.couldnt_move_count += ~~1; } @@ -204,6 +205,12 @@ draw :: proc () { // UI Rendering renderer.color = Color4f32.{ 0.0f, 0.0f, 0.0f, 1.0f }; draw_rect(^renderer, ~~input_state.mouse.x, ~~input_state.mouse.y, 10f, 10f); + + renderer.color = Color4f32.{ 1.0f, 1.0f, 1.0f, 1.0f }; + draw_rect(^renderer, 10.0f, 10.0f, 500.0f, 50.0f); + + renderer.color = Color4f32.{ 0.0f, 0.0f, 0.0f, 1.0f }; + draw_text(^renderer, "Hello. Test(12486),$! 0AaQq:", V2f.{ 10.0f, 10.0f }, 1.0f); render_context_ui(^renderer); } @@ -211,8 +218,19 @@ draw :: proc () { debugger :: proc () #foreign "dummy" "breakable" --- // This procedure is called asynchronously from JS every frame. -new_frame_callback :: proc () #export { - update(); + +// @CLEANUP: Add local persistant variables so this can go in the loop() body. +last_time := 0; + +loop :: proc () #export { + time_now :: proc () -> u32 #foreign "time" "now" ---; + + curr_time := time_now(); + if last_time == 0 do last_time = curr_time; + delta := curr_time - last_time; + last_time = curr_time; + + update(~~delta / 1000.0f); draw(); } @@ -237,6 +255,8 @@ main :: proc (args: [] cstring) { atlas_map(^atlas, 0, AtlasSprite.{ x = 16.0f, y = 0.0f, w = 16.0f, h = 16.0f }); atlas_map(^atlas, 1, AtlasSprite.{ x = 32.0f, y = 0.0f, w = 16.0f, h = 16.0f }); + atlas_map(^atlas, 2, AtlasSprite.{ x = 0.0f, y = 160.0f, w = 16.0f, h = 16.0f }); + event.init(); input.init(^input_state); @@ -245,7 +265,7 @@ main :: proc (args: [] cstring) { Dude_Color_Table[2] = Color4f32.{ 0.2f, 0.2f, 1.0f, 1.0f }; array_init(^dudes); - for i: 0 .. 500 { + for i: 0 .. 1000 { array_push(^dudes, dude_create_random()); } @@ -278,32 +298,31 @@ dude_create_random :: proc () -> Dude { }; } -dude_update :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { +dude_update :: proc (use dude: ^Dude, dt: f32, other_dudes: ^QuadTree(Dude)) { if random_between(0, 100) < 1 || couldnt_move_count >= ~~2 { - vel.x = random_float(-3.0f, 3.0f); - vel.y = random_float(-3.0f, 3.0f); + vel.x = random_float(-300.0f, 300.0f); + vel.y = random_float(-300.0f, 300.0f); couldnt_move_count = ~~0; } + dude_try_move(dude, dt, other_dudes); + if tile := tilemap_screen_coord_to_tile(^tilemap, pos); tile != null { target_r := cast(u8) cast(u32) (color.r * 255.0f); target_g := cast(u8) cast(u32) (color.g * 255.0f); target_b := cast(u8) cast(u32) (color.b * 255.0f); - diff_r := cast(i32) (target_r - tile.r) >>> 2; - diff_g := cast(i32) (target_g - tile.g) >>> 2; - diff_b := cast(i32) (target_b - tile.b) >>> 2; + diff_r := (cast(i32) target_r - cast(i32) tile.r) >>> 2; + diff_g := (cast(i32) target_g - cast(i32) tile.g) >>> 2; + diff_b := (cast(i32) target_b - cast(i32) tile.b) >>> 2; tile.r += ~~diff_r; tile.g += ~~diff_g; tile.b += ~~diff_b; } - - - dude_try_move(dude, other_dudes); } -dude_try_move :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { +dude_try_move :: proc (use dude: ^Dude, dt: f32, other_dudes: ^QuadTree(Dude)) { old_pos := pos; potential_dudes : [..] ^Dude; @@ -315,7 +334,7 @@ dude_try_move :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { collided := false; - pos.x += vel.x; + pos.x += vel.x * dt; if pos.x - size < ~~-half_window_width || pos.x + size >= ~~half_window_width do collided = true; dude_aabb := dude_get_aabb(dude); @@ -328,11 +347,11 @@ dude_try_move :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { } can_move_x = !collided; - pos.x -= vel.x; + pos.x -= vel.x * dt; collided = false; - pos.y += vel.y; + pos.y += vel.y * dt; if pos.y - size < ~~-half_window_height || pos.y + size >= ~~half_window_height do collided = true; dude_aabb = dude_get_aabb(dude); @@ -345,7 +364,7 @@ dude_try_move :: proc (use dude: ^Dude, other_dudes: ^QuadTree(Dude)) { } can_move_y = !collided; - pos.y -= vel.y; + pos.y -= vel.y * dt; } dude_get_aabb :: proc (use dude: ^Dude) -> AABB { diff --git a/src/quad_tree.onyx b/src/quad_tree.onyx index 58b3550..7c3f72d 100644 --- a/src/quad_tree.onyx +++ b/src/quad_tree.onyx @@ -2,6 +2,7 @@ package quad_tree use package core use package aabb +use package vecmath #private_file QUAD_TREE_MAX_POINTS :: 4; @@ -60,7 +61,7 @@ quadtree_subdivide :: proc (use qt: ^QuadTree($T), a: Allocator) { } quadtree_insert :: proc (use qt: ^QuadTree($T), t: ^T, alloc := context.allocator) -> bool { - pos := t.pos; // T is expected to have a 'pos' element. + pos: V2f = t.pos; // T is expected to have a 'pos' element. if !aabb_contains(region, pos) do return false; diff --git a/src/shaders/quad.frag b/src/shaders/quad.frag index 59ab7ef..2ab7cd2 100644 --- a/src/shaders/quad.frag +++ b/src/shaders/quad.frag @@ -13,6 +13,11 @@ void main() { if (v_tex_pos.x < 0.0) { fragColor = v_col; } else { - fragColor = v_col * texture(tex, v_tex_pos); + vec4 t_col = texture(tex, v_tex_pos); + if (t_col == vec4(1.0, 0.0, 1.0, 1.0)) { + fragColor = vec4(0.0, 0.0, 0.0, 0.0); + } else { + fragColor = v_col * texture(tex, v_tex_pos); + } } } diff --git a/tags b/tags index 4dd576e..92e0848 100644 --- a/tags +++ b/tags @@ -674,7 +674,7 @@ array_to_slice /usr/share/onyx/core/array.onyx /^array_to_slice :: proc (arr: ^[ atlas src/globals.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_lookup src/gfx/atlas.onyx /^atlas_lookup :: proc (use atlas: ^Atlas, id: i32) -> AtlasSprite {$/ +atlas_lookup src/gfx/atlas.onyx /^atlas_lookup :: proc (use atlas: ^Atlas, id: i32, offset := 0) -> AtlasSprite {$/ 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 {$/ @@ -755,12 +755,13 @@ drawElements /usr/share/onyx/core/js/webgl.onyx /^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_rect src/main.onyx /^draw_rect :: proc (use rc: ^RenderContext, x: f32, y: f32, w: f32, h: f32) {$/ +draw_text src/gfx/font.onyx /^draw_text :: proc (renderer: ^RenderContext, s: string, pos: V2f, scale := 1.0f) {$/ 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/globals.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)) {$/ +dude_try_move src/main.onyx /^dude_try_move :: proc (use dude: ^Dude, dt: f32, other_dudes: ^QuadTree(Dude)) {$/ +dude_update src/main.onyx /^dude_update :: proc (use dude: ^Dude, dt: f32, other_dudes: ^QuadTree(Dude)) {$/ dudes src/globals.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" ---$/ @@ -815,10 +816,12 @@ is_inside_polygon src/vecmath.onyx /^is_inside_polygon :: proc (polygon: [] V2($ key_down src/input.onyx /^key_down :: proc (use state: ^InputState, key: Key) -> bool {$/ key_just_down src/input.onyx /^key_just_down :: proc (use state: ^InputState, key: Key) -> bool {$/ key_up src/input.onyx /^key_up :: proc (use state: ^InputState, key: Key) -> bool {$/ +last_time src/main.onyx /^last_time := 0;$/ lineWidth /usr/share/onyx/core/js/webgl.onyx /^lineWidth :: proc (width: GLfloat) #foreign "gl" "lineWidth" ---$/ lines_intersect src/vecmath.onyx /^lines_intersect :: proc (p1: V2($T), q1: V2(T), p2: V2(T), q2: V2(T)) -> bool {$/ linkProgram /usr/share/onyx/core/js/webgl.onyx /^linkProgram :: proc (program: GLProgram) #foreign "gl" "linkProgram" ---$/ link_program src/utils/gl.onyx /^link_program :: proc (vertex_shader: gl.GLShader, frag_shader: gl.GLShader) -> gl.GLProgram {$/ +loop src/main.onyx /^loop :: proc () #export {$/ main src/main.onyx /^main :: proc (args: [] cstring) {$/ max_f32 /usr/share/onyx/core/intrinsics.onyx /^max_f32 :: proc (lhs: f32, rhs: f32) -> f32 #intrinsic ---$/ max_f64 /usr/share/onyx/core/intrinsics.onyx /^max_f64 :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/ @@ -833,7 +836,6 @@ min_f64 /usr/share/onyx/core/intrinsics.onyx /^min_f64 :: proc (lhs: f64, r min_poly /usr/share/onyx/core/math.onyx /^min_poly :: proc (a: $T, b: T) -> T {$/ nearest_f32 /usr/share/onyx/core/intrinsics.onyx /^nearest_f32 :: proc (val: f32) -> f32 #intrinsic ---$/ nearest_f64 /usr/share/onyx/core/intrinsics.onyx /^nearest_f64 :: proc (val: f64) -> f64 #intrinsic ---$/ -new_frame_callback src/main.onyx /^new_frame_callback :: proc () #export {$/ null /usr/share/onyx/core/builtin.onyx /^null :: cast(rawptr) 0;$/ or_i32 /usr/share/onyx/core/intrinsics.onyx /^or_i32 :: proc (lhs: i32, rhs: i32) -> i32 #intrinsic ---$/ or_i64 /usr/share/onyx/core/intrinsics.onyx /^or_i64 :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/ @@ -993,7 +995,7 @@ uniform4i /usr/share/onyx/core/js/webgl.onyx /^uniform4i :: uniformMatrix2 /usr/share/onyx/core/js/webgl.onyx /^uniformMatrix2 :: proc (loc: GLUniformLocation, transpose: GLboolean, value: GLMat2) #foreign "gl" "uniformMatrix2" ---$/ uniformMatrix3 /usr/share/onyx/core/js/webgl.onyx /^uniformMatrix3 :: proc (loc: GLUniformLocation, transpose: GLboolean, value: GLMat3) #foreign "gl" "uniformMatrix3" ---$/ uniformMatrix4 /usr/share/onyx/core/js/webgl.onyx /^uniformMatrix4 :: proc (loc: GLUniformLocation, transpose: GLboolean, value: GLMat4) #foreign "gl" "uniformMatrix4" ---$/ -update src/main.onyx /^update :: proc () {$/ +update src/main.onyx /^update :: proc (dt: f32) {$/ useProgram /usr/share/onyx/core/js/webgl.onyx /^useProgram :: proc (program: GLProgram) #foreign "gl" "useProgram" ---$/ v2_add src/vecmath.onyx /^v2_add :: proc (a: V2($T), b: V2(T)) -> V2(T) {$/ v2_equal src/vecmath.onyx /^v2_equal :: proc (a: V2($T), b: V2(T)) -> bool {$/ -- 2.25.1