From 812d574082b951a6b60db5f61373bb5a87a01cbe Mon Sep 17 00:00:00 2001 From: HampusM Date: Thu, 2 Apr 2026 16:35:34 +0200 Subject: fix(engine): make orthographic camera projection actually usable --- engine/src/projection.rs | 61 ++++++++++++++++++++++++++++---------------- engine/src/shader/default.rs | 17 ++++++------ 2 files changed, 47 insertions(+), 31 deletions(-) (limited to 'engine') diff --git a/engine/src/projection.rs b/engine/src/projection.rs index 29636e7..46df6d4 100644 --- a/engine/src/projection.rs +++ b/engine/src/projection.rs @@ -1,7 +1,7 @@ use crate::builder; -use crate::data_types::dimens::Dimens3; +use crate::data_types::dimens::Dimens; use crate::matrix::Matrix; -use crate::vector::Vec3; +use crate::vector::Vec2; #[derive(Debug, Clone)] #[non_exhaustive] @@ -25,7 +25,7 @@ impl Perspective /// Creates a perspective projection matrix using right-handed coordinates. #[inline] pub fn to_matrix_rh(&self, aspect: f32, clip_volume: ClipVolume) - -> Matrix + -> Matrix { let mut out = Matrix::new(); @@ -55,13 +55,23 @@ impl Default for Perspective } } +#[derive(Debug, Clone)] +pub enum OrthographicSize +{ + FixedSize(Dimens), + WindowSize, +} + builder! { #[builder(name = OrthographicBuilder, derives=(Debug, Clone))] -#[derive(Debug, Clone, PartialEq, PartialOrd)] +#[derive(Debug, Clone)] #[non_exhaustive] pub struct Orthographic { - pub size: Dimens3, + pub near: f32, + pub far: f32, + pub viewport_origin: Vec2, + pub size: OrthographicSize, } } @@ -75,18 +85,28 @@ impl Orthographic /// Creates a orthographic projection matrix using right-handed coordinates. pub fn to_matrix_rh( &self, - center_pos: &Vec3, + window_size: Dimens, clip_volume: ClipVolume, ) -> Matrix { let mut result = Matrix::::new(); - let left = center_pos.x - (self.size.width / 2.0); - let right = center_pos.x + (self.size.width / 2.0); - let bottom = center_pos.y - (self.size.height / 2.0); - let top = center_pos.y + (self.size.height / 2.0); - let near = center_pos.z - (self.size.depth / 2.0); - let far = center_pos.z + (self.size.depth / 2.0); + let size = match self.size { + OrthographicSize::FixedSize(fixed_size) => fixed_size, + OrthographicSize::WindowSize => window_size, + }; + + let origin_x = size.width * self.viewport_origin.x; + let origin_y = size.height * self.viewport_origin.y; + + let left = -origin_x; + let right = size.width - origin_x; + + let bottom = -origin_y; + let top = size.height - origin_y; + + let near = self.near; + let far = self.far; match clip_volume { ClipVolume::NegOneToOne => { @@ -108,13 +128,7 @@ impl Default for Orthographic { fn default() -> Self { - Self { - size: Dimens3 { - width: 10.0, - height: 7.0, - depth: 10.0, - }, - } + Self::builder().build() } } @@ -122,9 +136,12 @@ impl Default for OrthographicBuilder { fn default() -> Self { - let orthographic = Orthographic::default(); - - OrthographicBuilder { size: orthographic.size } + Self { + near: 0.0, + far: 1000.0, + viewport_origin: Vec2 { x: 0.5, y: 0.5 }, + size: OrthographicSize::WindowSize, + } } } diff --git a/engine/src/shader/default.rs b/engine/src/shader/default.rs index bc8202c..8690eb9 100644 --- a/engine/src/shader/default.rs +++ b/engine/src/shader/default.rs @@ -148,12 +148,7 @@ pub fn enqueue_set_shader_bindings( ), ( model_3d_shader_cursor.field("projection"), - create_projection_matrix( - &camera, - &camera_world_pos.position, - window.inner_size(), - ) - .into(), + create_projection_matrix(&camera, window.inner_size()).into(), ), ( lighting_shader_cursor.field("view_pos"), @@ -340,7 +335,6 @@ fn create_view_matrix(camera: &Camera, camera_world_pos: &Vec3) fn create_projection_matrix( camera: &Camera, - camera_world_pos: &Vec3, window_size: &Dimens, ) -> Matrix { @@ -349,8 +343,13 @@ fn create_projection_matrix( window_size.width as f32 / window_size.height as f32, ProjectionClipVolume::NegOneToOne, ), - Projection::Orthographic(orthographic_proj) => orthographic_proj - .to_matrix_rh(camera_world_pos, ProjectionClipVolume::NegOneToOne), + Projection::Orthographic(orthographic_proj) => orthographic_proj.to_matrix_rh( + Dimens { + width: window_size.width as f32, + height: window_size.height as f32, + }, + ProjectionClipVolume::NegOneToOne, + ), } } -- cgit v1.2.3-18-g5258