diff options
-rw-r--r-- | engine/src/lib.rs | 1 | ||||
-rw-r--r-- | engine/src/mesh.rs | 29 | ||||
-rw-r--r-- | engine/src/object.rs | 22 | ||||
-rw-r--r-- | engine/src/renderer/mod.rs | 81 |
4 files changed, 81 insertions, 52 deletions
diff --git a/engine/src/lib.rs b/engine/src/lib.rs index f84c0ad..fdd79a4 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -24,6 +24,7 @@ pub mod color; pub mod lighting; pub mod material; pub mod math; +pub mod mesh; pub mod object; pub mod texture; pub mod vector; diff --git a/engine/src/mesh.rs b/engine/src/mesh.rs new file mode 100644 index 0000000..67b26cc --- /dev/null +++ b/engine/src/mesh.rs @@ -0,0 +1,29 @@ +use crate::vertex::Vertex; + +#[derive(Debug)] +pub struct Mesh +{ + vertices: Vec<Vertex>, + indices: Option<Vec<u32>>, +} + +impl Mesh +{ + #[must_use] + pub fn new(vertices: Vec<Vertex>, indices: Option<Vec<u32>>) -> Self + { + Self { vertices, indices } + } + + #[must_use] + pub fn vertices(&self) -> &[Vertex] + { + &self.vertices + } + + #[must_use] + pub fn indices(&self) -> Option<&[u32]> + { + self.indices.as_deref() + } +} diff --git a/engine/src/object.rs b/engine/src/object.rs index 4e143a0..5391cf5 100644 --- a/engine/src/object.rs +++ b/engine/src/object.rs @@ -4,13 +4,13 @@ use std::io::Error as IoError; use std::path::{Path, PathBuf}; use crate::material::Material; +use crate::mesh::Mesh; use crate::opengl::shader::{ Error as ShaderError, Kind as ShaderKind, Program as ShaderProgram, Shader, }; -use crate::renderer::Renderable; use crate::shader_preprocessor::{Error as ShaderPreprocessorError, ShaderPreprocessor}; use crate::texture::{Id as TextureId, Texture}; use crate::transform::Transform; @@ -26,7 +26,8 @@ const FRAGMENT_SHADER_FILE: &str = "fragment.glsl"; pub struct Object { id: Id, - renderable: Renderable, + mesh: Mesh, + shader: ShaderProgram, transform: Transform, textures: HashMap<TextureId, Texture>, material: Material, @@ -69,9 +70,16 @@ impl Object &self.material } - pub(crate) fn renderable(&self) -> &Renderable + #[must_use] + pub fn mesh(&self) -> &Mesh + { + &self.mesh + } + + #[must_use] + pub fn shader(&self) -> &ShaderProgram { - &self.renderable + &self.shader } pub(crate) fn transform(&self) -> &Transform @@ -207,14 +215,14 @@ impl Builder .link() .map_err(Error::LinkShaderProgramFailed)?; - let renderable = - Renderable::new(shader_program, &self.vertices, self.indices.as_deref()); + let mesh = Mesh::new(self.vertices, self.indices); let transform = Transform::new(); Ok(Object { id, - renderable, + mesh, + shader: shader_program, transform, textures: self.textures, material: self.material.ok_or(Error::NoMaterial)?, diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs index 9996551..c72e1ce 100644 --- a/engine/src/renderer/mod.rs +++ b/engine/src/renderer/mod.rs @@ -76,36 +76,29 @@ where clear_buffers(BufferClearMask::COLOR | BufferClearMask::DEPTH); for obj in objects { - obj.renderable() - .shader_program - .activate(|shader_program_curr_bound| { - apply_transformation_matrices( - obj, - &self.camera, - window_size, - &shader_program_curr_bound, - ); + obj.shader().activate(|shader_program_curr_bound| { + apply_transformation_matrices( + obj, + &self.camera, + window_size, + &shader_program_curr_bound, + ); - apply_light( - obj, - light_source, - &self.camera, - &shader_program_curr_bound, - ); + apply_light(obj, light_source, &self.camera, &shader_program_curr_bound); - for (texture_id, texture) in obj.textures() { - let texture_unit = TextureUnit::from_texture_id(*texture_id) - .ok_or(Error::TextureIdIsInvalidTextureUnit)?; + for (texture_id, texture) in obj.textures() { + let texture_unit = TextureUnit::from_texture_id(*texture_id) + .ok_or(Error::TextureIdIsInvalidTextureUnit)?; - set_active_texture_unit(texture_unit); + set_active_texture_unit(texture_unit); - texture.inner().bind(|_| {}); - } + texture.inner().bind(|_| {}); + } - Self::draw_object(obj); + Self::draw_object(obj); - Ok(()) - })?; + Ok(()) + })?; } Ok(()) @@ -146,8 +139,12 @@ where fn draw_object(obj: &Object) { - obj.renderable().vertex_arr.bind(|vert_arr_curr_bound| { - if let Some(index_info) = &obj.renderable().index_info { + // TODO: Creating a new vertex buffer each draw is really dumb and slow this + // should be rethinked + let renderable = Renderable::new(obj.mesh().vertices(), obj.mesh().indices()); + + renderable.vertex_arr.bind(|vert_arr_curr_bound| { + if let Some(index_info) = &renderable.index_info { VertexArray::draw_elements( &vert_arr_curr_bound, PrimitiveKind::Triangles, @@ -169,7 +166,6 @@ where #[derive(Debug)] pub struct Renderable { - shader_program: ShaderProgram, vertex_arr: VertexArray, /// Vertex and index buffer has to live as long as the vertex array @@ -179,11 +175,7 @@ pub struct Renderable impl Renderable { - pub fn new( - shader_program: ShaderProgram, - vertices: &[Vertex], - indices: Option<&[u32]>, - ) -> Self + pub fn new(vertices: &[Vertex], indices: Option<&[u32]>) -> Self { let vertex_arr = VertexArray::new(); let vertex_buffer = Buffer::new(); @@ -212,7 +204,6 @@ impl Renderable }); Self { - shader_program, vertex_arr, _vertex_buffer: vertex_buffer, index_info, @@ -238,7 +229,7 @@ fn apply_transformation_matrices( shader_program_curr_bound: &CurrentlyBound<ShaderProgram>, ) { - object.renderable().shader_program.set_uniform_matrix_4fv( + object.shader().set_uniform_matrix_4fv( shader_program_curr_bound, cstr!("model"), &object.transform().as_matrix(), @@ -246,7 +237,7 @@ fn apply_transformation_matrices( let view = create_view(camera); - object.renderable().shader_program.set_uniform_matrix_4fv( + object.shader().set_uniform_matrix_4fv( shader_program_curr_bound, cstr!("view"), &view, @@ -260,7 +251,7 @@ fn apply_transformation_matrices( 0.1, ); - object.renderable().shader_program.set_uniform_matrix_4fv( + object.shader().set_uniform_matrix_4fv( shader_program_curr_bound, cstr!("projection"), &projection, @@ -274,7 +265,7 @@ fn apply_light( shader_program_curr_bound: &CurrentlyBound<ShaderProgram>, ) { - obj.renderable().shader_program.set_uniform_vec_3fv( + obj.shader().set_uniform_vec_3fv( shader_program_curr_bound, cstr!("light.position"), &light_source.map_or_else(Vec3::default, |light_source| { @@ -282,7 +273,7 @@ fn apply_light( }), ); - obj.renderable().shader_program.set_uniform_vec_3fv( + obj.shader().set_uniform_vec_3fv( shader_program_curr_bound, cstr!("light.ambient"), &light_source @@ -292,7 +283,7 @@ fn apply_light( .into(), ); - obj.renderable().shader_program.set_uniform_vec_3fv( + obj.shader().set_uniform_vec_3fv( shader_program_curr_bound, cstr!("light.diffuse"), &light_source @@ -302,7 +293,7 @@ fn apply_light( .into(), ); - obj.renderable().shader_program.set_uniform_vec_3fv( + obj.shader().set_uniform_vec_3fv( shader_program_curr_bound, cstr!("light.specular"), &light_source @@ -313,33 +304,33 @@ fn apply_light( ); #[allow(clippy::cast_possible_wrap)] - obj.renderable().shader_program.set_uniform_1i( + obj.shader().set_uniform_1i( shader_program_curr_bound, cstr!("material.ambient"), obj.material().ambient_map().into_inner() as i32, ); #[allow(clippy::cast_possible_wrap)] - obj.renderable().shader_program.set_uniform_1i( + obj.shader().set_uniform_1i( shader_program_curr_bound, cstr!("material.diffuse"), obj.material().diffuse_map().into_inner() as i32, ); #[allow(clippy::cast_possible_wrap)] - obj.renderable().shader_program.set_uniform_1i( + obj.shader().set_uniform_1i( shader_program_curr_bound, cstr!("material.specular"), obj.material().specular_map().into_inner() as i32, ); - obj.renderable().shader_program.set_uniform_1fv( + obj.shader().set_uniform_1fv( shader_program_curr_bound, cstr!("material.shininess"), obj.material().shininess(), ); - obj.renderable().shader_program.set_uniform_vec_3fv( + obj.shader().set_uniform_vec_3fv( shader_program_curr_bound, cstr!("view_pos"), &camera.position(), |