From 450670dbfb153f00adf431ad77379042a9114ab0 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sat, 18 Apr 2026 17:07:50 +0200 Subject: feat(engine): add scissor testing to renderer draw props --- engine/src/data_types/dimens.rs | 2 +- engine/src/data_types/vector.rs | 2 +- engine/src/renderer.rs | 30 ++++++++++++++++++++++++++++++ engine/src/renderer/opengl.rs | 39 +++++++++++++++++++++++++++++++++++++++ opengl-bindings/src/misc.rs | 27 +++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 2 deletions(-) diff --git a/engine/src/data_types/dimens.rs b/engine/src/data_types/dimens.rs index 8bf239f..12f912e 100644 --- a/engine/src/data_types/dimens.rs +++ b/engine/src/data_types/dimens.rs @@ -1,7 +1,7 @@ use std::num::NonZeroU32; /// 2D dimensions. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Dimens { pub width: Value, diff --git a/engine/src/data_types/vector.rs b/engine/src/data_types/vector.rs index e745387..933ca51 100644 --- a/engine/src/data_types/vector.rs +++ b/engine/src/data_types/vector.rs @@ -2,7 +2,7 @@ use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; use crate::color::Color; -#[derive(Debug, Default, Clone, Copy, PartialEq)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] pub struct Vec2 { pub x: Value, diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 3b6bdf0..52764db 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -14,6 +14,7 @@ use ecs::{Component, Query, Sole, declare_entity}; use crate::asset::{Assets, Handle as AssetHandle}; use crate::builder; +use crate::data_types::dimens::Dimens; use crate::draw_flags::{DrawFlags, NoDraw, PolygonModeConfig}; use crate::mesh::Mesh; use crate::model::{MaterialSearchResult, Model}; @@ -32,6 +33,7 @@ use crate::shader::{ Shader, }; use crate::texture::{Texture, WHITE_1X1_ASSET_LABEL as TEXTURE_WHITE_1X1_ASSET_LABEL}; +use crate::vector::Vec2; use crate::windowing::window::Window; pub mod blending; @@ -215,6 +217,28 @@ pub enum MeshUsage Dynamic, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ScissorBox +{ + /// Size of the scissor box in window coordinates. When `None`, the dimensions of the + /// window is used + pub size: Option>, + + /// Position (in window coordinates) of the lower left corner of the scissor box. + pub lower_left_corner_pos: Vec2, +} + +impl Default for ScissorBox +{ + fn default() -> Self + { + Self { + size: None, + lower_left_corner_pos: Vec2 { x: 0, y: 0 }, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub struct DrawProperties @@ -223,6 +247,8 @@ pub struct DrawProperties pub blending_enabled: bool, pub blending_config: BlendingConfig, pub depth_test_enabled: bool, + pub scissor_test_enabled: bool, + pub scissor_box: ScissorBox, } impl Default for DrawProperties @@ -234,6 +260,8 @@ impl Default for DrawProperties blending_enabled: false, blending_config: BlendingConfig::default(), depth_test_enabled: true, + scissor_test_enabled: false, + scissor_box: ScissorBox::default(), } } } @@ -246,6 +274,8 @@ bitflags! { const BLENDING_CONFIG = 1 << 1; const BLENDING_ENABLED = 1 << 2; const DEPTH_TEST_ENABLED = 1 << 3; + const SCISSOR_TEST_ENABLED = 1 << 4; + const SCISSOR_BOX = 1 << 5; } } diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs index df57b84..b434cd8 100644 --- a/engine/src/renderer/opengl.rs +++ b/engine/src/renderer/opengl.rs @@ -40,7 +40,9 @@ use opengl_bindings::misc::{ Capability, SetViewportError as GlSetViewportError, clear_buffers, + define_scissor_box as gl_define_scissor_box, enable, + get_viewport as gl_get_viewport, set_enabled, }; use opengl_bindings::shader::{ @@ -1203,6 +1205,43 @@ fn handle_commands( draw_props.depth_test_enabled, ); } + + if draw_props_update_flags + .contains(DrawPropertiesUpdateFlags::SCISSOR_TEST_ENABLED) + { + set_enabled( + curr_gl_ctx, + Capability::ScissorTest, + draw_props.scissor_test_enabled, + ); + } + + if draw_props_update_flags + .contains(DrawPropertiesUpdateFlags::SCISSOR_BOX) + { + gl_define_scissor_box( + curr_gl_ctx, + draw_props.scissor_box.lower_left_corner_pos.into(), + draw_props + .scissor_box + .size + .unwrap_or_else(|| { + let (_, viewport_size) = gl_get_viewport(curr_gl_ctx); + + Dimens:: { + width: viewport_size + .width + .try_into() + .expect("Viewport width too large"), + height: viewport_size + .height + .try_into() + .expect("Viewport height too large"), + } + }) + .into(), + ); + } } } } diff --git a/opengl-bindings/src/misc.rs b/opengl-bindings/src/misc.rs index 6206b79..3a3335d 100644 --- a/opengl-bindings/src/misc.rs +++ b/opengl-bindings/src/misc.rs @@ -54,6 +54,33 @@ pub fn set_viewport( Ok(()) } +pub fn get_viewport( + current_context: &CurrentContextWithFns<'_>, +) -> (Vec2, Dimens) +{ + let mut values = [0i32; 4]; + + unsafe { + current_context + .fns() + .GetIntegerv(crate::sys::VIEWPORT, values.as_mut_ptr()); + } + + let [x, y, width, height] = values; + + let pos = Vec2:: { + x: x.try_into().expect("Negative viewport x coordinate"), + y: y.try_into().expect("Negative viewport y coordinate"), + }; + + let size = Dimens:: { + width: width.try_into().expect("Negative viewport width"), + height: height.try_into().expect("Negative viewport height"), + }; + + (pos, size) +} + pub fn clear_buffers(current_context: &CurrentContextWithFns<'_>, mask: BufferClearMask) { unsafe { -- cgit v1.2.3-18-g5258