diff options
Diffstat (limited to 'engine')
| -rw-r--r-- | engine/res/default_shader.slang | 15 | ||||
| -rw-r--r-- | engine/src/data_types/matrix.rs | 243 | ||||
| -rw-r--r-- | engine/src/projection.rs | 32 | ||||
| -rw-r--r-- | engine/src/rendering/backend/opengl.rs | 37 | ||||
| -rw-r--r-- | engine/src/rendering/shader.rs | 5 |
5 files changed, 174 insertions, 158 deletions
diff --git a/engine/res/default_shader.slang b/engine/res/default_shader.slang index 04e897e..e42b83a 100644 --- a/engine/res/default_shader.slang +++ b/engine/res/default_shader.slang @@ -232,20 +232,11 @@ VertexStageOutput vertex_main(Vertex vertex: VERTEX) { VertexStageOutput stage_output; - // TODO: Investigate why mul arguments need to be ordered this way. - // The mul arguments are reordered in the GLSL output + float4x4 proj_view = mul(model_3d.projection, model_3d.view); - // float4x4 proj_view = mul(model_3d.projection, model_3d.view); - float4x4 proj_view = mul(model_3d.view, model_3d.projection); + float4x4 proj_view_model = mul(proj_view, model_3d.model); - // float4x4 proj_view_model = - // mul(proj_view, model_3d.model); - - float4x4 proj_view_model = mul(model_3d.model, proj_view); - - // stage_output.sv_position = mul(proj_view_model, float4(vertex.pos, 1.0)); - - stage_output.sv_position = mul(float4(vertex.pos, 1.0), proj_view_model); + stage_output.sv_position = mul(proj_view_model, float4(vertex.pos, 1.0)); float4 vertex_pos = float4(vertex.pos, 1.0); diff --git a/engine/src/data_types/matrix.rs b/engine/src/data_types/matrix.rs index cc43e7b..48796bf 100644 --- a/engine/src/data_types/matrix.rs +++ b/engine/src/data_types/matrix.rs @@ -1,12 +1,11 @@ -use std::ops::Mul; +use std::ops::{Index, IndexMut, Mul}; use crate::vector::{Vec3, Vec4}; #[derive(Debug, Clone)] pub struct Matrix<Value, const ROWS: usize, const COLUMNS: usize> { - /// Items must be layed out this way for it to work with OpenGL shaders. - pub items: [[Value; ROWS]; COLUMNS], + items: [[Value; COLUMNS]; ROWS], } impl<Value, const ROWS: usize, const COLUMNS: usize> Matrix<Value, ROWS, COLUMNS> @@ -25,21 +24,32 @@ impl<Value, const ROWS: usize, const COLUMNS: usize> Matrix<Value, ROWS, COLUMNS pub fn from_columns<Column>(columns: [Column; COLUMNS]) -> Self where Column: Into<[Value; ROWS]>, + Value: Default, { - Self { - items: columns.map(|column| column.into()), + let mut items = + std::array::from_fn(|_| std::array::from_fn(|_| Value::default())); + + for (column_index, column) in columns.into_iter().enumerate() { + for (row_index, item) in column.into().into_iter().enumerate() { + items[row_index][column_index] = item; + } } + + Self { items } } - /// Sets the value at the specified cell. - pub fn set_cell(&mut self, row: usize, column: usize, value: Value) + pub fn get_column_copied(&self, column_index: usize) -> [Value; ROWS] + where + Value: Default + Copy, { - self.items[column][row] = value; + std::array::from_fn::<Value, ROWS, _>(|row_index| { + self[CellPos { row: row_index, col: column_index }] + }) } - pub fn items(&self) -> &[[Value; ROWS]; COLUMNS] + pub fn items(&self) -> &[Value] { - &self.items + &self.items.as_flattened() } } @@ -60,19 +70,13 @@ impl<const ROWS_COLS: usize> Matrix<f32, ROWS_COLS, ROWS_COLS> #[must_use] pub fn new_identity() -> Self { - let mut index = 0; - - let items = [(); ROWS_COLS].map(|()| { - let mut columns = [0.0; ROWS_COLS]; + let mut identity = Self::new(); - columns[index] = 1.0; - - index += 1; - - columns - }); + for index in 0..ROWS_COLS { + identity[CellPos { row: index, col: index }] = 1.0; + } - Self { items } + identity } } @@ -80,18 +84,18 @@ impl Matrix<f32, 4, 4> { pub fn translate(&mut self, translation: &Vec3<f32>) { - self.set_cell(0, 3, translation.x); - self.set_cell(1, 3, translation.y); - self.set_cell(2, 3, translation.z); - self.set_cell(3, 3, 1.0); + self[CellPos { row: 0, col: 3 }] = translation.x; + self[CellPos { row: 1, col: 3 }] = translation.y; + self[CellPos { row: 2, col: 3 }] = translation.z; + self[CellPos { row: 3, col: 3 }] = 1.0; } pub fn scale(&mut self, scaling: &Vec3<f32>) { - self.set_cell(0, 0, scaling.x); - self.set_cell(1, 1, scaling.y); - self.set_cell(2, 2, scaling.z); - self.set_cell(3, 3, 1.0); + self[CellPos { row: 0, col: 0 }] = scaling.x; + self[CellPos { row: 1, col: 1 }] = scaling.y; + self[CellPos { row: 2, col: 2 }] = scaling.z; + self[CellPos { row: 3, col: 3 }] = 1.0; } pub fn look_at(&mut self, eye: Vec3<f32>, target: Vec3<f32>, up: Vec3<f32>) @@ -102,17 +106,17 @@ impl Matrix<f32, 4, 4> let camera_up = rev_target_direction.cross(&camera_right); - self.set_cell(0, 0, camera_right.x); - self.set_cell(0, 1, camera_right.y); - self.set_cell(0, 2, camera_right.z); + self[CellPos { row: 0, col: 0 }] = camera_right.x; + self[CellPos { row: 0, col: 1 }] = camera_right.y; + self[CellPos { row: 0, col: 2 }] = camera_right.z; - self.set_cell(1, 0, camera_up.x); - self.set_cell(1, 1, camera_up.y); - self.set_cell(1, 2, camera_up.z); + self[CellPos { row: 1, col: 0 }] = camera_up.x; + self[CellPos { row: 1, col: 1 }] = camera_up.y; + self[CellPos { row: 1, col: 2 }] = camera_up.z; - self.set_cell(2, 0, rev_target_direction.x); - self.set_cell(2, 1, rev_target_direction.y); - self.set_cell(2, 2, rev_target_direction.z); + self[CellPos { row: 2, col: 0 }] = rev_target_direction.x; + self[CellPos { row: 2, col: 1 }] = rev_target_direction.y; + self[CellPos { row: 2, col: 2 }] = rev_target_direction.z; // The vector is negated since we want the world to be translated in the opposite // direction of where we want the camera to move. @@ -122,56 +126,56 @@ impl Matrix<f32, 4, 4> z: rev_target_direction.dot(&eye), }; - self.set_cell(0, 3, camera_pos.x); - self.set_cell(1, 3, camera_pos.y); - self.set_cell(2, 3, camera_pos.z); + self[CellPos { row: 0, col: 3 }] = camera_pos.x; + self[CellPos { row: 1, col: 3 }] = camera_pos.y; + self[CellPos { row: 2, col: 3 }] = camera_pos.z; - self.set_cell(3, 3, 1.0); + self[CellPos { row: 3, col: 3 }] = 1.0; } pub fn inverse(&self) -> Self { - let coef_00 = - self.items[2][2] * self.items[3][3] - self.items[3][2] * self.items[2][3]; - let coef_02 = - self.items[1][2] * self.items[3][3] - self.items[3][2] * self.items[1][3]; - let coef_03 = - self.items[1][2] * self.items[2][3] - self.items[2][2] * self.items[1][3]; - - let coef_04 = - self.items[2][1] * self.items[3][3] - self.items[3][1] * self.items[2][3]; - let coef_06 = - self.items[1][1] * self.items[3][3] - self.items[3][1] * self.items[1][3]; - let coef_07 = - self.items[1][1] * self.items[2][3] - self.items[2][1] * self.items[1][3]; - - let coef_08 = - self.items[2][1] * self.items[3][2] - self.items[3][1] * self.items[2][2]; - let coef_10 = - self.items[1][1] * self.items[3][2] - self.items[3][1] * self.items[1][2]; - let coef_11 = - self.items[1][1] * self.items[2][2] - self.items[2][1] * self.items[1][2]; - - let coef_12 = - self.items[2][0] * self.items[3][3] - self.items[3][0] * self.items[2][3]; - let coef_14 = - self.items[1][0] * self.items[3][3] - self.items[3][0] * self.items[1][3]; - let coef_15 = - self.items[1][0] * self.items[2][3] - self.items[2][0] * self.items[1][3]; - - let coef_16 = - self.items[2][0] * self.items[3][2] - self.items[3][0] * self.items[2][2]; - let coef_18 = - self.items[1][0] * self.items[3][2] - self.items[3][0] * self.items[1][2]; - let coef_19 = - self.items[1][0] * self.items[2][2] - self.items[2][0] * self.items[1][2]; - - let coef_20 = - self.items[2][0] * self.items[3][1] - self.items[3][0] * self.items[2][1]; - let coef_22 = - self.items[1][0] * self.items[3][1] - self.items[3][0] * self.items[1][1]; - let coef_23 = - self.items[1][0] * self.items[2][1] - self.items[2][0] * self.items[1][1]; + let coef_00 = self[CellPos { row: 2, col: 2 }] * self[CellPos { row: 3, col: 3 }] + - self[CellPos { row: 2, col: 3 }] * self[CellPos { row: 3, col: 2 }]; + let coef_02 = self[CellPos { row: 2, col: 1 }] * self[CellPos { row: 3, col: 3 }] + - self[CellPos { row: 2, col: 3 }] * self[CellPos { row: 3, col: 1 }]; + let coef_03 = self[CellPos { row: 2, col: 1 }] * self[CellPos { row: 3, col: 2 }] + - self[CellPos { row: 2, col: 2 }] * self[CellPos { row: 3, col: 1 }]; + + let coef_04 = self[CellPos { row: 1, col: 2 }] * self[CellPos { row: 3, col: 3 }] + - self[CellPos { row: 1, col: 3 }] * self[CellPos { row: 3, col: 2 }]; + let coef_06 = self[CellPos { row: 1, col: 1 }] * self[CellPos { row: 3, col: 3 }] + - self[CellPos { row: 1, col: 3 }] * self[CellPos { row: 3, col: 1 }]; + let coef_07 = self[CellPos { row: 1, col: 1 }] * self[CellPos { row: 3, col: 2 }] + - self[CellPos { row: 1, col: 2 }] * self[CellPos { row: 3, col: 1 }]; + + let coef_08 = self[CellPos { row: 1, col: 2 }] * self[CellPos { row: 2, col: 3 }] + - self[CellPos { row: 1, col: 3 }] * self[CellPos { row: 2, col: 2 }]; + let coef_10 = self[CellPos { row: 1, col: 1 }] * self[CellPos { row: 2, col: 3 }] + - self[CellPos { row: 1, col: 3 }] * self[CellPos { row: 2, col: 1 }]; + let coef_11 = self[CellPos { row: 1, col: 1 }] * self[CellPos { row: 2, col: 2 }] + - self[CellPos { row: 1, col: 2 }] * self[CellPos { row: 2, col: 1 }]; + + let coef_12 = self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 3, col: 3 }] + - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 3, col: 2 }]; + let coef_14 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 3, col: 3 }] + - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 3, col: 1 }]; + let coef_15 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 3, col: 2 }] + - self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 3, col: 1 }]; + + let coef_16 = self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 2, col: 3 }] + - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 2, col: 2 }]; + let coef_18 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 2, col: 3 }] + - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 2, col: 1 }]; + let coef_19 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 2, col: 2 }] + - self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 2, col: 1 }]; + + let coef_20 = self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 1, col: 3 }] + - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 1, col: 2 }]; + let coef_22 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 1, col: 3 }] + - self[CellPos { row: 0, col: 3 }] * self[CellPos { row: 1, col: 1 }]; + let coef_23 = self[CellPos { row: 0, col: 1 }] * self[CellPos { row: 1, col: 2 }] + - self[CellPos { row: 0, col: 2 }] * self[CellPos { row: 1, col: 1 }]; let fac_0 = Vec4 { x: coef_00, @@ -211,28 +215,28 @@ impl Matrix<f32, 4, 4> }; let vec_0 = Vec4 { - x: self.items[1][0], - y: self.items[0][0], - z: self.items[0][0], - w: self.items[0][0], + x: self[CellPos { row: 0, col: 1 }], + y: self[CellPos { row: 0, col: 0 }], + z: self[CellPos { row: 0, col: 0 }], + w: self[CellPos { row: 0, col: 0 }], }; let vec_1 = Vec4 { - x: self.items[1][1], - y: self.items[0][1], - z: self.items[0][1], - w: self.items[0][1], + x: self[CellPos { row: 1, col: 1 }], + y: self[CellPos { row: 1, col: 0 }], + z: self[CellPos { row: 1, col: 0 }], + w: self[CellPos { row: 1, col: 0 }], }; let vec_2 = Vec4 { - x: self.items[1][2], - y: self.items[0][2], - z: self.items[0][2], - w: self.items[0][2], + x: self[CellPos { row: 2, col: 1 }], + y: self[CellPos { row: 2, col: 0 }], + z: self[CellPos { row: 2, col: 0 }], + w: self[CellPos { row: 2, col: 0 }], }; let vec_3 = Vec4 { - x: self.items[1][3], - y: self.items[0][3], - z: self.items[0][3], - w: self.items[0][3], + x: self[CellPos { row: 3, col: 1 }], + y: self[CellPos { row: 3, col: 0 }], + z: self[CellPos { row: 3, col: 0 }], + w: self[CellPos { row: 3, col: 0 }], }; let inv_0 = vec_1 * fac_0 - vec_2 * fac_1 + vec_3 * fac_2; @@ -251,13 +255,13 @@ impl Matrix<f32, 4, 4> ]); let row_0 = Vec4 { - x: inverse.items[0][0], - y: inverse.items[1][0], - z: inverse.items[2][0], - w: inverse.items[3][0], + x: inverse[CellPos { row: 0, col: 0 }], + y: inverse[CellPos { row: 0, col: 1 }], + z: inverse[CellPos { row: 0, col: 2 }], + w: inverse[CellPos { row: 0, col: 3 }], }; - let dot_0 = Vec4::<f32>::from(self.items[0]) * row_0; + let dot_0 = Vec4::<f32>::from(self.get_column_copied(0)) * row_0; let dot_1 = (dot_0.x + dot_0.y) + (dot_0.z + dot_0.w); @@ -274,9 +278,34 @@ impl Mul<f32> for Matrix<f32, 4, 4> fn mul(self, scalar: f32) -> Self::Output { Self { - items: self - .items - .map(|column| (Vec4::from(column) * scalar).into()), + items: self.items.map(|row| (Vec4::from(row) * scalar).into()), } } } + +impl<Value, const ROWS: usize, const COLUMNS: usize> Index<CellPos> + for Matrix<Value, ROWS, COLUMNS> +{ + type Output = Value; + + fn index(&self, cell_pos: CellPos) -> &Self::Output + { + &self.items[cell_pos.row][cell_pos.col] + } +} + +impl<Value, const ROWS: usize, const COLUMNS: usize> IndexMut<CellPos> + for Matrix<Value, ROWS, COLUMNS> +{ + fn index_mut(&mut self, cell_pos: CellPos) -> &mut Self::Output + { + &mut self.items[cell_pos.row][cell_pos.col] + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct CellPos +{ + pub row: usize, + pub col: usize, +} diff --git a/engine/src/projection.rs b/engine/src/projection.rs index ea3d7ed..747b8a8 100644 --- a/engine/src/projection.rs +++ b/engine/src/projection.rs @@ -1,6 +1,6 @@ use crate::builder; use crate::data_types::dimens::Dimens; -use crate::matrix::Matrix; +use crate::matrix::{CellPos as MatrixCellPos, Matrix}; use crate::reflection::Reflection; use crate::vector::Vec2; @@ -32,11 +32,15 @@ impl Perspective match clip_volume { ClipVolume::NegOneToOne => { - out.set_cell(0, 0, (1.0 / (self.fov_radians / 2.0).tan()) / aspect); - out.set_cell(1, 1, 1.0 / (self.fov_radians / 2.0).tan()); - out.set_cell(2, 2, (self.near + self.far) / (self.near - self.far)); - out.set_cell(2, 3, (2.0 * self.near * self.far) / (self.near - self.far)); - out.set_cell(3, 2, -1.0); + out[MatrixCellPos { row: 0, col: 0 }] = + (1.0 / (self.fov_radians / 2.0).tan()) / aspect; + out[MatrixCellPos { row: 1, col: 1 }] = + 1.0 / (self.fov_radians / 2.0).tan(); + out[MatrixCellPos { row: 2, col: 2 }] = + (self.near + self.far) / (self.near - self.far); + out[MatrixCellPos { row: 2, col: 3 }] = + (2.0 * self.near * self.far) / (self.near - self.far); + out[MatrixCellPos { row: 3, col: 2 }] = -1.0; } } @@ -113,13 +117,15 @@ impl Orthographic match clip_volume { ClipVolume::NegOneToOne => { - result.set_cell(0, 0, 2.0 / (right - left)); - result.set_cell(1, 1, 2.0 / (top - bottom)); - result.set_cell(2, 2, -2.0 / (far - near)); - result.set_cell(0, 3, -(right + left) / (right - left)); - result.set_cell(1, 3, -(top + bottom) / (top - bottom)); - result.set_cell(2, 3, -(far + near) / (far - near)); - result.set_cell(3, 3, 1.0); + result[MatrixCellPos { row: 0, col: 0 }] = 2.0 / (right - left); + result[MatrixCellPos { row: 1, col: 1 }] = 2.0 / (top - bottom); + result[MatrixCellPos { row: 2, col: 2 }] = -2.0 / (far - near); + result[MatrixCellPos { row: 0, col: 3 }] = + -(right + left) / (right - left); + result[MatrixCellPos { row: 1, col: 3 }] = + -(top + bottom) / (top - bottom); + result[MatrixCellPos { row: 2, col: 3 }] = -(far + near) / (far - near); + result[MatrixCellPos { row: 3, col: 3 }] = 1.0; } } diff --git a/engine/src/rendering/backend/opengl.rs b/engine/src/rendering/backend/opengl.rs index 1253c7b..f88fe38 100644 --- a/engine/src/rendering/backend/opengl.rs +++ b/engine/src/rendering/backend/opengl.rs @@ -76,7 +76,6 @@ use crate::ecs::query::term::Without; use crate::ecs::sole::Single; use crate::ecs::{Component, Query, Sole}; use crate::image::{ColorType as ImageColorType, Image}; -use crate::matrix::Matrix; use crate::reflection::EnumReflectionExt; use crate::rendering::backend::opengl::glutin_compat::{ DisplayBuilder, @@ -187,16 +186,14 @@ impl crate::ecs::extension::Extension for Extension } fn prepare_windows( - window_query: Query< - ( - Option<&Window>, - &mut WindowCreationAttributes, - With<TargetWindow>, - Without<CreationReady>, - Without<WindowGlConfig>, - Without<WindowClosed>, - ), - >, + window_query: Query<( + Option<&Window>, + &mut WindowCreationAttributes, + With<TargetWindow>, + Without<CreationReady>, + Without<WindowGlConfig>, + Without<WindowClosed>, + )>, windowing_context: Single<WindowingContext>, graphics_props: Single<GraphicsProperties>, mut actions: Actions, @@ -272,9 +269,12 @@ fn prepare_windows( #[tracing::instrument(skip_all)] fn init_window_graphics( - window_query: Query< - (&Window, &WindowGlConfig, With<TargetWindow>, Without<SurfaceSpec>), - >, + window_query: Query<( + &Window, + &WindowGlConfig, + With<TargetWindow>, + Without<SurfaceSpec>, + )>, windowing_context: Single<WindowingContext>, graphics_props: Single<GraphicsProperties>, mut graphics_ctx: Single<GraphicsContext>, @@ -1485,15 +1485,6 @@ impl<Value: ReprC + IntoBytes + Copy> From<Vec3<Value>> } } -impl<Value: ReprC + Copy> From<Matrix<Value, 4, 4>> - for opengl_bindings::data_types::Matrix<Value, 4, 4> -{ - fn from(matrix: Matrix<Value, 4, 4>) -> Self - { - Self { items: matrix.items } - } -} - impl<Value: Copy> From<Dimens<Value>> for opengl_bindings::data_types::Dimens<Value> { fn from(dimens: Dimens<Value>) -> Self diff --git a/engine/src/rendering/shader.rs b/engine/src/rendering/shader.rs index 7d5bd51..b508670 100644 --- a/engine/src/rendering/shader.rs +++ b/engine/src/rendering/shader.rs @@ -28,12 +28,11 @@ use crate::asset::{ Submitter as AssetSubmitter, HANDLE_ASSETS_PHASE, }; -use crate::ecs::pair; use crate::builder; use crate::ecs::pair::ChildOf; use crate::ecs::phase::{Phase, POST_UPDATE as POST_UPDATE_PHASE}; use crate::ecs::sole::Single; -use crate::ecs::{declare_entity, Component, Sole}; +use crate::ecs::{declare_entity, pair, Component, Sole}; pub mod cursor; pub mod default; @@ -1018,7 +1017,7 @@ pub(super) fn prepare(collector: &mut crate::ecs::extension::Collector<'_>) let session_options = shader_slang::CompilerOptions::default() .optimization(shader_slang::OptimizationLevel::None) - .matrix_layout_column(true) + .matrix_layout_row(true) .debug_information(SlangDebugInfoLevel::Maximal) .no_mangle(true); |
