From d8125fdc73447763b3eba562a3770ebcef0faa51 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 7 Jul 2021 15:04:47 -0500 Subject: [PATCH] scissoring with respect to world transform matrix --- core/container/array.onyx | 2 +- .../immediate_mode/immediate_renderer.onyx | 46 +++++++++++++++++-- modules/ui/components/scrollable_area.onyx | 10 ++++ 3 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 modules/ui/components/scrollable_area.onyx diff --git a/core/container/array.onyx b/core/container/array.onyx index 7ec75b8d..c1d64feb 100644 --- a/core/container/array.onyx +++ b/core/container/array.onyx @@ -125,7 +125,7 @@ delete :: (arr: ^[..] $T, idx: u32) { fast_delete :: (arr: ^[..] $T, idx: u32) { if idx >= arr.count do return; - arr.data[idx] = arr.data[arr.count - 1]; + if idx != arr.count - 1 do arr.data[idx] = arr.data[arr.count - 1]; arr.count -= 1; } diff --git a/modules/immediate_mode/immediate_renderer.onyx b/modules/immediate_mode/immediate_renderer.onyx index 8be8a5a6..250ec88c 100644 --- a/modules/immediate_mode/immediate_renderer.onyx +++ b/modules/immediate_mode/immediate_renderer.onyx @@ -23,6 +23,10 @@ Immediate_Vertex :: struct { texture : Vector2; } +Scissor_State :: struct { + x, y, w, h: f32; +} + Immediate_Renderer :: struct { // Needs to be a multiple of 6!! Default_Max_Verticies :: 1020; @@ -54,6 +58,8 @@ Immediate_Renderer :: struct { world_transform_stack : [..] Transform; world_transform_dirty := false; // If the world transform matrix should be pushed to the shader uniform. + scissor_stack : [..] Scissor_State; + make :: (max_verticies := Default_Max_Verticies) -> Immediate_Renderer { ir : Immediate_Renderer; __initialize(^ir); @@ -85,6 +91,8 @@ Immediate_Renderer :: struct { world_transform_stack = array.make(Transform, capacity=1); array.insert_empty(^world_transform_stack, 0); transform_identity(array.get_ptr(^world_transform_stack, -1)); + + scissor_stack = array.make(Scissor_State); ir->init_shader_params(^simple_shader); ir->init_shader_params(^textured_shader); @@ -289,13 +297,39 @@ Immediate_Renderer :: struct { @Cleanup // right now, these are raw screen coordinates, with x and y being the bottom left of the screen. // This is backwards from what use_ortho_projections does, so it's not great to work with. - scissor :: (use ir: ^Immediate_Renderer, x: f32, y: f32, w: f32, h: f32) { + push_scissor :: (use ir: ^Immediate_Renderer, x: f32, y: f32, w: f32, h: f32, intersect_previous := true) { + if vertex_count > 0 do ir->flush(); + if !gl.isEnabled(gl.SCISSOR_TEST) { - ir->flush(); gl.enable(gl.SCISSOR_TEST); } - gl.scissor(~~x, ~~y, ~~w, ~~h); + world_matrix := ir->get_transform() + |> transform_to_matrix(); + + new_x0 := world_matrix[0] * x + world_matrix[1] * y + world_matrix[12] * 1; + new_y0 := world_matrix[4] * x + world_matrix[5] * y + world_matrix[13] * 1; + new_x1 := world_matrix[0] * (x + w) + world_matrix[1] * (y + h) + world_matrix[12] * 1; + new_y1 := world_matrix[4] * (x + w) + world_matrix[5] * (y + h) + world_matrix[13] * 1; + new_w := new_x1 - new_x0; + new_h := new_y1 - new_y0; + + array.push(^scissor_stack, .{ new_x0, new_y0, new_w, new_h }); + + gl.scissor(~~new_x0, ~~(-new_y0 + new_h * 2), ~~new_w, ~~new_h); + } + + pop_scissor :: (use ir: ^Immediate_Renderer) { + array.pop(^scissor_stack); + + if scissor_stack.count > 0 { + s := scissor_stack[scissor_stack.count - 1]; + + gl.scissor(~~s.x, ~~s.y, ~~s.w, ~~s.h); + + } else { + ir->scissor_disable(); + } } scissor_disable :: (use ir: ^Immediate_Renderer) { @@ -427,10 +461,12 @@ use_alpha_shader :: (texture_id: i32 = -1) { global_renderer->use_alpha_shader(texture_id); } -scissor :: (x: f32, y: f32, w: f32, h: f32) { - global_renderer->scissor(x, y, w, h); +push_scissor :: (x: f32, y: f32, w: f32, h: f32) { + global_renderer->push_scissor(x, y, w, h); } +pop_scissor :: () do global_renderer->pop_scissor(); + scissor_disable :: () { global_renderer->scissor_disable(); } diff --git a/modules/ui/components/scrollable_area.onyx b/modules/ui/components/scrollable_area.onyx new file mode 100644 index 00000000..5cab4ab9 --- /dev/null +++ b/modules/ui/components/scrollable_area.onyx @@ -0,0 +1,10 @@ +package ui +use package core + +scrollable_area_start :: (use r: Rectangle) { + +} + +scrollable_area_end :: () { + +} \ No newline at end of file -- 2.25.1