tiny_game_framework/graphics/
mesh.rs

1use std::ptr;
2
3use crate::{bind_buffer, cstr, events::EventLoop, gen_attrib_pointers, InstanceData, InstanceMesh, ShaderType, FULL_SHADER_FS, FULL_SHADER_VS, LIGHT_MESH_SHADER_FS, LIGHT_MESH_SHADER_VS};
4use std::ffi::CString;
5
6use super::{Renderer, Shader, Vertex, DEFAULT_MESH_SHADER_FS, DEFAULT_MESH_SHADER_VS};
7
8use gl::{*, types::GLsizei};
9use glam::{Mat4, Quat, Vec3, Vec4};
10use once_cell::sync::Lazy;
11
12pub static DEFAULT_SHADER: Lazy<Shader> = Lazy::new(|| {
13    Shader::new_pipeline(DEFAULT_MESH_SHADER_VS, DEFAULT_MESH_SHADER_FS)
14});
15
16pub static LIGHT_SHADER: Lazy<Shader> = Lazy::new(|| {
17    Shader::new_pipeline(LIGHT_MESH_SHADER_VS, LIGHT_MESH_SHADER_FS)
18});
19
20pub static FULL_SHADER: Lazy<Shader> = Lazy::new(|| {
21    Shader::new_pipeline(FULL_SHADER_VS, FULL_SHADER_FS)
22});
23
24#[derive(PartialEq, Debug, Clone)]
25pub struct Mesh {
26    pub vertices: Vec<Vertex>,
27    pub indices: Vec<u32>,
28
29    pub VAO: u32,
30    EBO: u32,
31    VBO: u32,
32
33    pub position: Vec3,
34    pub rotation: Quat,
35    pub scale: Vec3,
36
37    pub texture: u32,
38    shader: Shader,
39    pub parent: Option<Box<Mesh>>,
40    pub children: Vec<Box<Mesh>>,
41}
42
43impl Mesh {
44    pub fn new(vertices: &Vec<Vertex>, indices: &Vec<u32>) -> Self {
45        let mesh = Mesh {
46            vertices: vertices.to_vec(), indices: indices.to_vec(),
47            VAO: 0, VBO: 0, EBO: 0,
48            position: Vec3::ZERO,
49            rotation: Quat::from_euler(glam::EulerRot::XYZ, 0.0, 0.0, 0.0),
50            scale: Vec3::ONE,
51            texture: 0,
52            shader: *DEFAULT_SHADER,
53            parent: None,
54            children: Vec::new(),
55        };
56
57        mesh
58    }
59
60    pub fn set_shader_type(&mut self, shader_type: &ShaderType) {
61        let shader: Shader;
62
63        match shader_type{
64            ShaderType::Default => {
65                shader = *DEFAULT_SHADER;
66            }
67            ShaderType::Light => {
68                shader = *LIGHT_SHADER;
69            }
70            ShaderType::Full => {
71                shader = *FULL_SHADER;
72            }
73        }
74
75        self.shader = shader;
76    }
77
78    pub fn set_texture(&mut self, texture_name: &str, renderer: &Renderer) {
79        self.texture = renderer.get_texture(texture_name.to_owned());
80        unsafe {
81            self.shader.uniform_1i(cstr!("has_texture"), 1);
82        }
83    }
84
85    pub fn to_instance(&mut self, data: Vec<InstanceData>, n: usize) -> InstanceMesh {
86        let mut new_mesh = InstanceMesh::new(&self.vertices, &self.indices, n);
87
88        new_mesh.instance_data = data;
89
90        unsafe { new_mesh.setup_mesh() };
91
92        drop(self);
93
94        new_mesh
95    }
96
97    pub fn set_parent(&mut self, parent: Mesh){
98        self.parent = Some(Box::new(parent));
99    }
100
101    pub fn add_child(&mut self, mut child: Mesh){
102        child.set_parent(self.clone());
103        self.children.push(Box::new(child));
104    }
105
106    pub fn set_color(&mut self, color: Vec4){
107        for vert in self.vertices.iter_mut(){
108            vert.color = color;
109        }
110    }
111
112    pub fn set_position(&mut self, position: Vec3){
113        self.position = position;
114        for child in self.children.as_mut_slice(){
115            child.set_position(position + child.position)
116        }
117    }
118
119    pub fn add_position(&mut self, position: Vec3){
120        self.position += position;
121        for child in self.children.as_mut_slice(){
122            child.add_position(position)
123        }
124    }
125
126    pub fn set_scale(&mut self, scale: Vec3){
127        self.scale = scale;
128        for child in self.children.as_mut_slice(){
129            child.set_scale(scale);
130        }
131    }
132
133    pub fn scale(&mut self, scale: Vec3){
134        self.scale *= scale;
135        for child in self.children.as_mut_slice(){
136            child.scale(scale);
137        }
138    }
139
140    pub fn set_rotation(&mut self, rotation: Quat){
141        self.rotation = rotation;
142        for child in self.children.as_mut_slice(){
143            child.set_rotation(rotation);
144        }
145    }
146
147    pub fn rotate(&mut self, rotation: Quat){
148        self.rotation = self.rotation + rotation;
149        for child in self.children.as_mut_slice(){
150            child.rotate(rotation);
151        }
152    }
153
154    pub fn setup_mesh(&mut self) {
155        unsafe {
156            GenVertexArrays(1, &mut self.VAO);
157            GenBuffers(1, &mut self.VBO);
158            GenBuffers(1, &mut self.EBO);
159    
160            BindVertexArray(self.VAO);
161    
162            bind_buffer!(ARRAY_BUFFER, self.VBO, self.vertices);
163            bind_buffer!(ELEMENT_ARRAY_BUFFER, self.EBO, self.indices);
164            gen_attrib_pointers!(Vertex, 0 => position: 3, 1 => color: 4, 2 => tex_coords: 2, 3 => normal: 3);
165    
166            gl::BindTexture(gl::TEXTURE_2D, self.texture);
167
168            BindVertexArray(0);
169        }
170    }
171    
172    pub unsafe fn draw(&self) {
173        let model_matrix = 
174            Mat4::from_translation(self.position) *
175            Mat4::from_quat(self.rotation) *
176            Mat4::from_scale(self.scale);
177
178        BindVertexArray(self.VAO);
179        self.shader.use_shader();
180
181
182        // Set uniforms and draw
183        self.shader.uniform_mat4fv(cstr!("model"), &model_matrix.to_cols_array());
184        self.shader.uniform_vec3f(cstr!("pos"), &self.position);
185        
186        BindTexture(TEXTURE_2D, self.texture);
187
188        DrawElements(TRIANGLES, self.indices.len() as i32, UNSIGNED_INT, ptr::null());
189
190        BindVertexArray(0);
191        UseProgram(0);
192    }
193}
194
195impl Renderer {
196    pub fn add_mesh_from_vertices_and_indices(&mut self, name: &str, vertices: Vec<Vertex>, indices: Vec<u32>) -> Result<(), String> {
197        if self.meshes.contains_key(name) {
198            return Err(format!("Mesh with name '{}' already exists", name));
199        }
200
201        let mesh = Mesh::new(&vertices, &indices);
202        
203        self.meshes.insert(name.to_owned(), mesh);
204        Ok(())
205    }
206
207    pub fn add_mesh(&mut self, name: &str, mesh: Mesh) -> Result<(), String> {
208        if self.meshes.contains_key(name) {
209            return Err(format!("Mesh with name '{}' already exists", name));
210        }
211
212        self.meshes.insert(name.to_owned(), mesh);
213        Ok(())
214    }
215
216    pub fn get_mesh_mut(&mut self, name: &str) -> Option<&mut Mesh> {
217        self.meshes.get_mut(name)
218    }
219
220    pub fn get_mesh(&self, name: &str) -> Option<&Mesh> {
221        self.meshes.get(name)
222    }
223
224    pub fn destroy_mesh(&mut self, name: &str) -> Result<(), String> {
225        if self.meshes.remove(name).is_some() {
226            Ok(())
227        } else {
228            Err(format!("No mesh found with name '{}'", name))
229        }
230    }
231}
232
233
234impl Drop for Mesh {
235    fn drop(&mut self) {
236        unsafe {
237            DeleteVertexArrays(1, &self.VAO);
238            DeleteBuffers(1, &self.EBO);
239            DeleteBuffers(1, &self.VBO);
240        }
241    }
242}