reverie_engine_opengl/
camera.rs

1use reverie_util::math::{
2    self,
3    nalgebra::{Matrix4, Point3, Vector3},
4    Deg, Rad,
5};
6
7use crate::{
8    gl::Gl,
9    shader::Program,
10    texture::ImageLoadInfo,
11    vao::{Phong3DRenderer, Phong3DRenderingInfo, PhongRenderingInfo, Renderer, Vao},
12};
13
14#[derive(Debug)]
15pub struct Camera {
16    pos: Point3<f32>,
17    yaw: Rad<f32>,
18    pitch: Rad<f32>,
19    fov: Deg<f32>,
20    gl: Gl,
21    renderer: Phong3DRenderer,
22}
23
24impl Camera {
25    pub fn new(gl: Gl, pos: Point3<f32>, yaw: Rad<f32>, pitch: Rad<f32>, fov: Deg<f32>) -> Self {
26        let shader = Program::default_uv(gl.clone()).unwrap();
27        let renderer = Phong3DRenderer::new(shader);
28        Self {
29            pos,
30            yaw,
31            pitch,
32            fov,
33            gl,
34            renderer,
35        }
36    }
37
38    pub fn render(
39        &self,
40        vao: &Vao,
41        model_matrix: &Matrix4<f32>,
42        width: u32,
43        height: u32,
44        phong_info: &PhongRenderingInfo,
45        block_atlas_texture: &ImageLoadInfo,
46    ) {
47        let view_matrix = self.view_matrix();
48        let projection_matrix = self.projection_matrix(width, height);
49
50        let info = &Phong3DRenderingInfo {
51            phong: phong_info,
52            model_matrix,
53            view_matrix: &view_matrix,
54            projection_matrix: &projection_matrix,
55            camera_pos: &self.pos,
56            texture: block_atlas_texture,
57        };
58        self.renderer.render(self.gl.clone(), vao, info);
59    }
60
61    pub fn view_matrix(&self) -> Matrix4<f32> {
62        let (front, _right, up) = math::calc_front_right_up(self.yaw, self.pitch);
63        Matrix4::<f32>::look_at_rh(&self.pos, &(self.pos + front), &up)
64    }
65
66    pub fn projection_matrix(&self, width: u32, height: u32) -> Matrix4<f32> {
67        Matrix4::new_perspective(
68            width as f32 / height as f32,
69            self.fov.to_rad().into(),
70            0.1,
71            100.0,
72        )
73    }
74
75    pub fn set_pos(&mut self, pos: Point3<f32>) {
76        self.pos = pos;
77    }
78
79    pub fn move_pos(&mut self, d: Vector3<f32>) {
80        self.pos += d;
81    }
82
83    pub fn set_yaw(&mut self, yaw: Rad<f32>) {
84        self.yaw = yaw;
85    }
86
87    pub fn add_yaw(&mut self, yaw_d: Rad<f32>) {
88        self.yaw += yaw_d;
89    }
90
91    pub fn set_pitch(&mut self, pitch: Rad<f32>) {
92        self.pitch = pitch;
93    }
94
95    pub fn add_pitch(&mut self, pitch_d: Rad<f32>) {
96        self.pitch += pitch_d;
97    }
98
99    pub fn set_fov(&mut self, fov: Deg<f32>) {
100        self.fov = fov;
101    }
102
103    pub const fn pos(&self) -> Point3<f32> {
104        self.pos
105    }
106
107    pub const fn yaw(&self) -> Rad<f32> {
108        self.yaw
109    }
110
111    pub const fn pitch(&self) -> Rad<f32> {
112        self.pitch
113    }
114
115    pub const fn fov(&self) -> Deg<f32> {
116        self.fov
117    }
118}