diff options
| author | HampusM <hampus@hampusmat.com> | 2026-04-18 17:07:50 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-04-18 17:07:50 +0200 |
| commit | 450670dbfb153f00adf431ad77379042a9114ab0 (patch) | |
| tree | 7c31b0b672ddbfcbf4507e8b61f73e9af34909ff | |
| parent | bb2929df6b013fba82a866cc1dc14e842e94d0af (diff) | |
| -rw-r--r-- | engine/src/data_types/dimens.rs | 2 | ||||
| -rw-r--r-- | engine/src/data_types/vector.rs | 2 | ||||
| -rw-r--r-- | engine/src/renderer.rs | 30 | ||||
| -rw-r--r-- | engine/src/renderer/opengl.rs | 39 | ||||
| -rw-r--r-- | 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<Value> { 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<Value> { 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; @@ -216,6 +218,28 @@ pub enum MeshUsage } #[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<Dimens<u16>>, + + /// Position (in window coordinates) of the lower left corner of the scissor box. + pub lower_left_corner_pos: Vec2<u16>, +} + +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::<u16> { + 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<u32>, Dimens<u32>) +{ + 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::<u32> { + x: x.try_into().expect("Negative viewport x coordinate"), + y: y.try_into().expect("Negative viewport y coordinate"), + }; + + let size = Dimens::<u32> { + 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 { |
