Skip to main content

steamengine_renderer_util/camera/
mod.rs

1use glam::*;
2
3/// Use and create cameras easily
4
5/// Implementation for orthographic camera
6/// Enable it with feature "orthographic-camera"
7#[cfg(feature = "orthographic-camera")]
8pub mod orthographic;
9/// Implementation for prespective camera
10/// Enable it with featurer "prespective-camera"
11#[cfg(feature = "prespective-camera")]
12pub mod prespective;
13
14/// Abstraction of a camera
15pub trait Camera: Send + Sync + Clone {
16    /// Create a view matrix for the camera
17    fn view(&self) -> Mat4;
18    /// Create a projection matrix
19    fn projection(&self) -> Mat4;
20    /// Poistion of the camera
21    fn eye(&mut self) -> &mut Vec3;
22    /// Direction of the camera
23    fn target(&mut self) -> &mut Vec3;
24    /// Up vector
25    fn up(&mut self) -> &mut Vec3;
26    /// Calculated and converted to WGPU matrix of the camera
27    fn matrix(&self) -> Mat4 {
28        let projection = self.projection();
29        let view = self.view();
30        let matrix = OPENGL_TO_WGPU_MATRIX * projection * view;
31        matrix
32    }
33}
34
35/// Constant for conversion of opengl camera to wgpu camera
36#[rustfmt::skip]
37pub const OPENGL_TO_WGPU_MATRIX: Mat4 = Mat4::from_cols(
38    vec4(1.0, 0.0, 0.0, 0.0),
39    vec4(0.0, 1.0, 0.0, 0.0),
40    vec4(0.0, 0.0, 0.5, 0.0),
41    vec4(0.0, 0.0, 0.5, 1.0),
42);
43
44/// Simple buffer Implementation for camera matrix
45#[cfg(feature = "simple-buffers")]
46pub struct CameraBuffer<'a> {
47    buffer: wgpu::Buffer,
48    renderer: std::sync::Arc<steamengine_renderer::Renderer<'a>>,
49    limit: u64,
50}
51#[cfg(feature = "simple-buffers")]
52impl<'a> crate::simple_buffer::SimpleBuffer<'a, [[f32; 4]; 4]> for CameraBuffer<'a> {
53    fn new(renderer: std::sync::Arc<steamengine_renderer::Renderer<'a>>, limit: u64) -> Self {
54        let lock = renderer.clone();
55        let buffer = lock.create_buffer(
56            "Camera buffer",
57            wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
58            size_of::<[[f32; 4]; 4]>() as u64 * limit,
59        );
60        Self {
61            renderer,
62            buffer,
63            limit,
64        }
65    }
66    fn as_entrie(&self) -> wgpu::BindingResource {
67        self.buffer.as_entire_binding()
68    }
69    fn buffer(&self) -> &wgpu::Buffer {
70        &self.buffer
71    }
72    fn limit(&self) -> u64 {
73        self.limit
74    }
75    fn renderer(&self) -> std::sync::Arc<steamengine_renderer::Renderer<'a>> {
76        self.renderer.clone()
77    }
78}
79#[cfg(feature = "simple-buffers")]
80impl CameraBuffer<'_> {
81    pub fn set_camera<T: Camera>(&self, camera: T) {
82        use crate::simple_buffer::SimpleBuffer;
83        let matrix: [[f32; 4]; 4] = camera.matrix().to_cols_array_2d();
84        self.set(0, matrix);
85    }
86}
87
88/// Function to create default bindings for a camera
89/// Create a bind group with label `Camera bindings` and a entry in binding *0* that contrains the
90/// matrix accesible in *vertex* shader stage
91#[cfg(feature = "simple-bindings")]
92pub fn create_bindings(
93    renderer: std::sync::Arc<steamengine_renderer::Renderer>,
94    buffer: wgpu::BindingResource,
95) -> crate::bindings::Bindings {
96    use crate::bindings::CreateBindings;
97    use steamengine_renderer::bind_group::BindGroupEntryBuilder;
98    let bindings = renderer.new_bindings(
99        "Camera Bindings",
100        &[BindGroupEntryBuilder::new(0)
101            .uniform()
102            .with(buffer)
103            .on(wgpu::ShaderStages::VERTEX)],
104    );
105    bindings
106}