steamengine_renderer_util/camera/
mod.rs

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