reverie_engine_opengl/
camera.rs1use 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}