summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-04-15 23:09:11 +0200
committerHampusM <hampus@hampusmat.com>2024-04-15 23:09:11 +0200
commit9778d9668f8b5d651aaed1f64414f7ed195d153d (patch)
treee7c67bec8e03816e75aad7b1dd89730912908c8d
parentb748977205eea249dc61e6f755bd6ff86c8f535b (diff)
feat(engine): add projection options to camera component
-rw-r--r--TODO.md2
-rw-r--r--engine/src/camera.rs3
-rw-r--r--engine/src/lib.rs2
-rw-r--r--engine/src/projection.rs56
-rw-r--r--engine/src/renderer/mod.rs14
5 files changed, 58 insertions, 19 deletions
diff --git a/TODO.md b/TODO.md
index 3d35ef8..a0a2a95 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,5 +1,5 @@
- [ ] Support for multiple textures
-- [ ] Non-hardcoded projection settings
+- [x] Non-hardcoded projection settings
- [ ] Model importing
- [ ] Animations
- [ ] Physics
diff --git a/engine/src/camera.rs b/engine/src/camera.rs
index 5347e83..640c1f4 100644
--- a/engine/src/camera.rs
+++ b/engine/src/camera.rs
@@ -1,5 +1,6 @@
use ecs::Component;
+use crate::projection::{Perspective, Projection};
use crate::vector::Vec3;
#[derive(Debug, Component)]
@@ -9,6 +10,7 @@ pub struct Camera
pub target: Vec3<f32>,
pub global_up: Vec3<f32>,
pub current: bool,
+ pub projection: Projection,
}
impl Default for Camera
@@ -20,6 +22,7 @@ impl Default for Camera
target: Vec3::default(),
global_up: Vec3::UP,
current: false,
+ projection: Projection::Perspective(Perspective::default()),
}
}
}
diff --git a/engine/src/lib.rs b/engine/src/lib.rs
index f83d85b..b3f4aa1 100644
--- a/engine/src/lib.rs
+++ b/engine/src/lib.rs
@@ -18,7 +18,6 @@ use crate::event::{
};
mod opengl;
-mod projection;
mod shader_preprocessor;
pub mod camera;
@@ -30,6 +29,7 @@ pub mod lighting;
pub mod material;
pub mod math;
pub mod mesh;
+pub mod projection;
pub mod renderer;
pub mod shader;
pub mod texture;
diff --git a/engine/src/projection.rs b/engine/src/projection.rs
index d5186ba..aa84a9f 100644
--- a/engine/src/projection.rs
+++ b/engine/src/projection.rs
@@ -1,20 +1,56 @@
use crate::matrix::Matrix;
-/// Creates a new perspective projection matrix.
-#[must_use]
-pub fn new_perspective(
- fov_radians: f32,
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum Projection
+{
+ Perspective(Perspective),
+}
+
+/// Perspective projection parameters.
+#[derive(Debug)]
+pub struct Perspective
+{
+ pub fov_radians: f32,
+ pub far: f32,
+ pub near: f32,
+}
+
+impl Default for Perspective
+{
+ fn default() -> Self
+ {
+ Self {
+ fov_radians: 80.0f32.to_radians(),
+ far: 100.0,
+ near: 0.1,
+ }
+ }
+}
+
+pub(crate) fn new_perspective_matrix(
+ perspective: &Perspective,
aspect: f32,
- far: f32,
- near: f32,
) -> Matrix<f32, 4, 4>
{
let mut out = Matrix::new();
- out.set_cell(0, 0, (1.0 / (fov_radians / 2.0).tan()) / aspect);
- out.set_cell(1, 1, 1.0 / (fov_radians / 2.0).tan());
- out.set_cell(2, 2, (near + far) / (near - far));
- out.set_cell(2, 3, (2.0 * near * far) / (near - far));
+ out.set_cell(0, 0, (1.0 / (perspective.fov_radians / 2.0).tan()) / aspect);
+
+ out.set_cell(1, 1, 1.0 / (perspective.fov_radians / 2.0).tan());
+
+ out.set_cell(
+ 2,
+ 2,
+ (perspective.near + perspective.far) / (perspective.near - perspective.far),
+ );
+
+ out.set_cell(
+ 2,
+ 3,
+ (2.0 * perspective.near * perspective.far) / (perspective.near - perspective.far),
+ );
+
out.set_cell(3, 2, -1.0);
out
diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs
index 617c60f..3052969 100644
--- a/engine/src/renderer/mod.rs
+++ b/engine/src/renderer/mod.rs
@@ -35,7 +35,7 @@ use crate::opengl::vertex_array::{
VertexArray,
};
use crate::opengl::{clear_buffers, enable, BufferClearMask, Capability};
-use crate::projection::new_perspective;
+use crate::projection::{new_perspective_matrix, Projection};
use crate::shader::Program as ShaderProgram;
use crate::texture::{Id as TextureId, List as TextureMap, Texture};
use crate::transform::Transform;
@@ -321,12 +321,12 @@ fn apply_transformation_matrices(
gl_shader_program.set_uniform_matrix_4fv(cstr!("view"), &view);
#[allow(clippy::cast_precision_loss)]
- let projection = new_perspective(
- 80.0f32.to_radians(),
- window_size.width as f32 / window_size.height as f32,
- 100.0,
- 0.1,
- );
+ let projection = match &camera.projection {
+ Projection::Perspective(perspective) => new_perspective_matrix(
+ perspective,
+ window_size.width as f32 / window_size.height as f32,
+ ),
+ };
gl_shader_program.set_uniform_matrix_4fv(cstr!("projection"), &projection);
}