diff options
-rw-r--r-- | engine/src/opengl/buffer.rs | 63 | ||||
-rw-r--r-- | engine/src/opengl/currently_bound.rs | 20 | ||||
-rw-r--r-- | engine/src/opengl/mod.rs | 1 | ||||
-rw-r--r-- | engine/src/opengl/shader.rs | 40 | ||||
-rw-r--r-- | engine/src/opengl/texture.rs | 105 | ||||
-rw-r--r-- | engine/src/opengl/vertex_array.rs | 132 | ||||
-rw-r--r-- | engine/src/renderer/mod.rs | 206 | ||||
-rw-r--r-- | engine/src/texture.rs | 25 | ||||
-rw-r--r-- | engine/src/vertex.rs | 13 |
9 files changed, 263 insertions, 342 deletions
diff --git a/engine/src/opengl/buffer.rs b/engine/src/opengl/buffer.rs index 1622804..68a75fb 100644 --- a/engine/src/opengl/buffer.rs +++ b/engine/src/opengl/buffer.rs @@ -1,62 +1,50 @@ use std::marker::PhantomData; use std::mem::size_of_val; -use crate::opengl::currently_bound::CurrentlyBound; - #[derive(Debug)] -pub struct Buffer<Item, ModeT: Mode> +pub struct Buffer<Item> { buf: gl::types::GLuint, - _pd: PhantomData<(Item, ModeT)>, + _pd: PhantomData<Item>, } -impl<Item, ModeT: Mode> Buffer<Item, ModeT> +impl<Item> Buffer<Item> { pub fn new() -> Self { let mut buffer = gl::types::GLuint::default(); unsafe { - gl::GenBuffers(1, &mut buffer); + gl::CreateBuffers(1, &mut buffer); }; Self { buf: buffer, _pd: PhantomData } } - #[allow(clippy::inline_always)] - #[inline(always)] - pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>)) - { - unsafe { - gl::BindBuffer(ModeT::GL_ENUM, self.buf); - } - - // SAFETY: The buffer object is bound above - let currently_bound = unsafe { CurrentlyBound::new() }; - - cb(currently_bound); - } - /// Stores items in the currently bound buffer. - pub fn store(_currently_bound: &CurrentlyBound<Self>, items: &[Item], usage: Usage) + pub fn store(&mut self, items: &[Item], usage: Usage) { unsafe { #[allow(clippy::cast_possible_wrap)] - gl::BufferData( - ModeT::GL_ENUM, + gl::NamedBufferData( + self.buf, size_of_val(items) as gl::types::GLsizeiptr, items.as_ptr().cast(), usage.into_gl(), ); } } + + pub fn object(&self) -> gl::types::GLuint + { + self.buf + } } -impl<Item, ModeT: Mode> Drop for Buffer<Item, ModeT> +impl<Item> Drop for Buffer<Item> { fn drop(&mut self) { - #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] unsafe { gl::DeleteBuffers(1, &self.buf); } @@ -89,28 +77,3 @@ impl Usage } } } - -/// Buffer mode. -pub trait Mode -{ - #[doc(hidden)] - const GL_ENUM: gl::types::GLenum; -} - -/// Array buffer kind. -#[derive(Debug)] -pub struct ArrayKind; - -impl Mode for ArrayKind -{ - const GL_ENUM: gl::types::GLenum = gl::ARRAY_BUFFER; -} - -/// Element array buffer kind. -#[derive(Debug)] -pub struct ElementArrayKind; - -impl Mode for ElementArrayKind -{ - const GL_ENUM: gl::types::GLenum = gl::ELEMENT_ARRAY_BUFFER; -} diff --git a/engine/src/opengl/currently_bound.rs b/engine/src/opengl/currently_bound.rs deleted file mode 100644 index be01841..0000000 --- a/engine/src/opengl/currently_bound.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::marker::PhantomData; - -/// A token signifying a OpenGL object is currently bound. -pub struct CurrentlyBound<'token, Object> -{ - _token: PhantomData<&'token Object>, -} - -impl<'token, Object> CurrentlyBound<'token, Object> -{ - /// Returns a new `CurrentlyBound`. - /// - /// # Safety - /// A object must actually be currently bound. Otherwise, UB can occur. - #[must_use] - pub unsafe fn new() -> Self - { - Self { _token: PhantomData } - } -} diff --git a/engine/src/opengl/mod.rs b/engine/src/opengl/mod.rs index 6898c49..edf6372 100644 --- a/engine/src/opengl/mod.rs +++ b/engine/src/opengl/mod.rs @@ -4,7 +4,6 @@ use crate::data_types::dimens::Dimens; use crate::vector::Vec2; pub mod buffer; -pub mod currently_bound; pub mod shader; pub mod texture; pub mod vertex_array; diff --git a/engine/src/opengl/shader.rs b/engine/src/opengl/shader.rs index 2312adc..070897e 100644 --- a/engine/src/opengl/shader.rs +++ b/engine/src/opengl/shader.rs @@ -2,7 +2,6 @@ use std::ffi::CStr; use std::ptr::null_mut; use crate::matrix::Matrix; -use crate::opengl::currently_bound::CurrentlyBound; use crate::shader::Kind; use crate::vector::Vec3; @@ -146,65 +145,56 @@ impl Program Ok(()) } - pub fn activate<Ret>(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>) -> Ret) -> Ret + pub fn activate(&self) { unsafe { gl::UseProgram(self.program); } - - // SAFETY: The shader program object is bound above - let currently_bound = unsafe { CurrentlyBound::new() }; - - cb(currently_bound) } - pub fn set_uniform_matrix_4fv( - &self, - _: &CurrentlyBound<Self>, - name: &CStr, - matrix: &Matrix<f32, 4, 4>, - ) + pub fn set_uniform_matrix_4fv(&mut self, name: &CStr, matrix: &Matrix<f32, 4, 4>) { let uniform_location = unsafe { gl::GetUniformLocation(self.program, name.as_ptr().cast()) }; unsafe { - gl::UniformMatrix4fv(uniform_location, 1, gl::FALSE, matrix.as_ptr()); + gl::ProgramUniformMatrix4fv( + self.program, + uniform_location, + 1, + gl::FALSE, + matrix.as_ptr(), + ); } } - pub fn set_uniform_vec_3fv( - &self, - _: &CurrentlyBound<Self>, - name: &CStr, - vec: &Vec3<f32>, - ) + pub fn set_uniform_vec_3fv(&mut self, name: &CStr, vec: &Vec3<f32>) { let uniform_location = unsafe { gl::GetUniformLocation(self.program, name.as_ptr().cast()) }; unsafe { - gl::Uniform3fv(uniform_location, 1, vec.as_ptr()); + gl::ProgramUniform3fv(self.program, uniform_location, 1, vec.as_ptr()); } } - pub fn set_uniform_1fv(&self, _: &CurrentlyBound<Self>, name: &CStr, num: f32) + pub fn set_uniform_1fv(&mut self, name: &CStr, num: f32) { let uniform_location = unsafe { gl::GetUniformLocation(self.program, name.as_ptr().cast()) }; unsafe { - gl::Uniform1fv(uniform_location, 1, &num); + gl::ProgramUniform1fv(self.program, uniform_location, 1, &num); } } - pub fn set_uniform_1i(&self, _: &CurrentlyBound<Self>, name: &CStr, num: i32) + pub fn set_uniform_1i(&mut self, name: &CStr, num: i32) { let uniform_location = unsafe { gl::GetUniformLocation(self.program, name.as_ptr().cast()) }; unsafe { - gl::Uniform1i(uniform_location, num); + gl::ProgramUniform1i(self.program, uniform_location, num); } } diff --git a/engine/src/opengl/texture.rs b/engine/src/opengl/texture.rs index 5d12729..074ade7 100644 --- a/engine/src/opengl/texture.rs +++ b/engine/src/opengl/texture.rs @@ -1,8 +1,5 @@ -use std::ptr::null; - -use crate::opengl::currently_bound::CurrentlyBound; +use crate::data_types::dimens::Dimens; use crate::texture::{Id, Properties}; -use crate::vector::Vec2; #[derive(Debug)] pub struct Texture @@ -17,88 +14,73 @@ impl Texture let mut texture = gl::types::GLuint::default(); unsafe { - gl::GenTextures(1, &mut texture); + gl::CreateTextures(gl::TEXTURE_2D, 1, &mut texture); }; Self { texture } } - pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>)) + pub fn bind(&self) { unsafe { gl::BindTexture(gl::TEXTURE_2D, self.texture); } - - // SAFETY: The buffer object is bound above - let currently_bound = unsafe { CurrentlyBound::new() }; - - cb(currently_bound); } pub fn generate( - curr_bound: &CurrentlyBound<Self>, - dimens: &Vec2<u32>, + &mut self, + dimens: Dimens<u32>, data: &[u8], pixel_data_format: PixelDataFormat, ) { - Self::alloc_image(curr_bound, pixel_data_format, dimens, Some(data)); + self.alloc_image(pixel_data_format, dimens, data); unsafe { - gl::GenerateMipmap(gl::TEXTURE_2D); + gl::GenerateTextureMipmap(self.texture); } } - pub fn apply_properties(&self, properties: &Properties) + pub fn apply_properties(&mut self, properties: &Properties) { - self.bind(|texture_curr_bound| { - Texture::set_wrap(&texture_curr_bound, properties.wrap); - - Texture::set_magnifying_filter( - &texture_curr_bound, - properties.magnifying_filter, - ); - - Texture::set_minifying_filter( - &texture_curr_bound, - properties.minifying_filter, - ); - }); + self.set_wrap(properties.wrap); + self.set_magnifying_filter(properties.magnifying_filter); + self.set_minifying_filter(properties.minifying_filter); } - pub fn set_wrap(_: &CurrentlyBound<Self>, wrapping: Wrapping) + pub fn set_wrap(&mut self, wrapping: Wrapping) { let wrapping_gl = wrapping.to_gl(); #[allow(clippy::cast_possible_wrap)] unsafe { - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, wrapping_gl as i32); - gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, wrapping_gl as i32); + gl::TextureParameteri(self.texture, gl::TEXTURE_WRAP_S, wrapping_gl as i32); + gl::TextureParameteri(self.texture, gl::TEXTURE_WRAP_T, wrapping_gl as i32); } } - pub fn set_magnifying_filter(_: &CurrentlyBound<Self>, filtering: Filtering) + pub fn set_magnifying_filter(&mut self, filtering: Filtering) { let filtering_gl = filtering.to_gl(); #[allow(clippy::cast_possible_wrap)] unsafe { - gl::TexParameteri( - gl::TEXTURE_2D, + gl::TextureParameteri( + self.texture, gl::TEXTURE_MAG_FILTER, filtering_gl as i32, ); } } - pub fn set_minifying_filter(_: &CurrentlyBound<Self>, filtering: Filtering) + pub fn set_minifying_filter(&mut self, filtering: Filtering) { let filtering_gl = filtering.to_gl(); #[allow(clippy::cast_possible_wrap)] unsafe { - gl::TexParameteri( - gl::TEXTURE_2D, + gl::TextureParameteri( + self.texture, gl::TEXTURE_MIN_FILTER, filtering_gl as i32, ); @@ -106,24 +88,33 @@ impl Texture } fn alloc_image( - _: &CurrentlyBound<Self>, + &mut self, pixel_data_format: PixelDataFormat, - dimens: &Vec2<u32>, - data: Option<&[u8]>, + dimens: Dimens<u32>, + data: &[u8], ) { unsafe { #[allow(clippy::cast_possible_wrap)] - gl::TexImage2D( - gl::TEXTURE_2D, + gl::TextureStorage2D( + self.texture, + 1, + pixel_data_format.to_sized_internal_format(), + dimens.width as i32, + dimens.height as i32, + ); + + #[allow(clippy::cast_possible_wrap)] + gl::TextureSubImage2D( + self.texture, + 0, 0, - pixel_data_format.to_gl() as i32, - dimens.x as i32, - dimens.y as i32, 0, - pixel_data_format.to_gl(), + dimens.width as i32, + dimens.height as i32, + pixel_data_format.to_format(), gl::UNSIGNED_BYTE, - data.map_or_else(null, |data| data.as_ptr().cast()), + data.as_ptr().cast(), ); } } @@ -184,17 +175,25 @@ impl Filtering #[derive(Debug, Clone, Copy)] pub enum PixelDataFormat { - Rgb, - Rgba, + Rgb8, + Rgba8, } impl PixelDataFormat { - fn to_gl(self) -> gl::types::GLenum + fn to_sized_internal_format(self) -> gl::types::GLenum + { + match self { + Self::Rgb8 => gl::RGB8, + Self::Rgba8 => gl::RGBA8, + } + } + + fn to_format(self) -> gl::types::GLenum { match self { - Self::Rgb => gl::RGB, - Self::Rgba => gl::RGBA, + Self::Rgb8 => gl::RGB, + Self::Rgba8 => gl::RGBA, } } } diff --git a/engine/src/opengl/vertex_array.rs b/engine/src/opengl/vertex_array.rs index 6b6065c..e1e1a15 100644 --- a/engine/src/opengl/vertex_array.rs +++ b/engine/src/opengl/vertex_array.rs @@ -1,10 +1,10 @@ use std::mem::size_of; -use crate::opengl::buffer::{ArrayKind as ArrayBufferKind, Buffer}; -use crate::opengl::currently_bound::CurrentlyBound; -use crate::vertex::{Attribute, AttributeComponentType, Vertex}; +use crate::opengl::buffer::Buffer; +use crate::vertex::Vertex; -const VERTEX_STRIDE: usize = size_of::<Vertex>(); +#[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)] +const VERTEX_STRIDE: i32 = size_of::<Vertex>() as i32; #[derive(Debug)] pub struct VertexArray @@ -19,19 +19,14 @@ impl VertexArray let mut array = 0; unsafe { - gl::GenVertexArrays(1, &mut array); + gl::CreateVertexArrays(1, &mut array); } Self { array } } /// Draws the currently bound vertex array. - pub fn draw_arrays( - _currently_bound: &CurrentlyBound<Self>, - primitive_kind: PrimitiveKind, - start_index: u32, - cnt: u32, - ) + pub fn draw_arrays(primitive_kind: PrimitiveKind, start_index: u32, cnt: u32) { unsafe { #[allow(clippy::cast_possible_wrap)] @@ -44,12 +39,7 @@ impl VertexArray } /// Draws the currently bound vertex array. - pub fn draw_elements( - _currently_bound: &CurrentlyBound<Self>, - primitive_kind: PrimitiveKind, - offset: u32, - cnt: u32, - ) + pub fn draw_elements(primitive_kind: PrimitiveKind, offset: u32, cnt: u32) { unsafe { #[allow(clippy::cast_possible_wrap)] @@ -62,64 +52,78 @@ impl VertexArray } } - pub fn configure_attrs( - _currently_bound: &CurrentlyBound<Self>, - _vert_buf_curr_bound: &CurrentlyBound<Buffer<Vertex, ArrayBufferKind>>, - ) + pub fn bind_element_buffer(&mut self, element_buffer: &Buffer<u32>) { - let mut offset = 0; - - for attr in Vertex::attrs() { - Self::vertex_attrib_ptr(attr, offset); - - Self::enable_vertex_attrib_array(attr.index); - - offset += attr.component_size * attr.component_cnt as usize; + unsafe { + gl::VertexArrayElementBuffer(self.array, element_buffer.object()); } } - #[allow(clippy::inline_always)] - #[inline(always)] - pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>)) + pub fn bind_vertex_buffer( + &mut self, + binding_index: u32, + vertex_buffer: &Buffer<Vertex>, + offset: isize, + ) { - unsafe { gl::BindVertexArray(self.array) } - - // SAFETY: A vertex array object is currently bound - let currently_bound = unsafe { CurrentlyBound::new() }; + unsafe { + gl::VertexArrayVertexBuffer( + self.array, + binding_index, + vertex_buffer.object(), + offset, + VERTEX_STRIDE, + ); + } + } - cb(currently_bound); + pub fn enable_attrib(&mut self, attrib_index: u32) + { + unsafe { + gl::EnableVertexArrayAttrib(self.array, attrib_index as gl::types::GLuint); + } } - fn vertex_attrib_ptr(vertex_attr: &Attribute, offset: usize) + pub fn set_attrib_format( + &mut self, + attrib_index: u32, + data_type: DataType, + normalized: bool, + offset: u32, + ) { unsafe { - #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] - gl::VertexAttribPointer( - vertex_attr.index as gl::types::GLuint, - vertex_attr.component_cnt as i32, - Self::vertex_attr_type_to_gl(&vertex_attr.component_type), - gl::FALSE, - VERTEX_STRIDE as gl::types::GLsizei, - offset as *const _, + #[allow(clippy::cast_possible_wrap)] + gl::VertexArrayAttribFormat( + self.array, + attrib_index, + data_type.size() as gl::types::GLint, + data_type as u32, + if normalized { gl::TRUE } else { gl::FALSE }, + offset, ); } } - fn enable_vertex_attrib_array(index: usize) + /// Associate a vertex attribute and a vertex buffer binding. + pub fn set_attrib_vertex_buf_binding( + &mut self, + attrib_index: u32, + vertex_buf_binding_index: u32, + ) { unsafe { - #[allow(clippy::cast_possible_truncation)] - gl::EnableVertexAttribArray(index as gl::types::GLuint); + gl::VertexArrayAttribBinding( + self.array, + attrib_index, + vertex_buf_binding_index, + ); } } - fn vertex_attr_type_to_gl( - vertex_attr_type: &AttributeComponentType, - ) -> gl::types::GLenum + pub fn bind(&self) { - match vertex_attr_type { - AttributeComponentType::Float => gl::FLOAT, - } + unsafe { gl::BindVertexArray(self.array) } } } @@ -148,3 +152,21 @@ impl PrimitiveKind } } } + +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +pub enum DataType +{ + Float = gl::FLOAT, +} + +impl DataType +{ + pub fn size(self) -> u32 + { + #[allow(clippy::cast_possible_truncation)] + match self { + Self::Float => size_of::<gl::types::GLfloat>() as u32, + } + } +} diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs index 9b4acb4..617c60f 100644 --- a/engine/src/renderer/mod.rs +++ b/engine/src/renderer/mod.rs @@ -16,13 +16,7 @@ use crate::lighting::LightSource; use crate::material::Material; use crate::matrix::Matrix; use crate::mesh::Mesh; -use crate::opengl::buffer::{ - ArrayKind as ArrayBufferKind, - Buffer, - ElementArrayKind as ElementArrayBufferKind, - Usage as BufferUsage, -}; -use crate::opengl::currently_bound::CurrentlyBound; +use crate::opengl::buffer::{Buffer, Usage as BufferUsage}; #[cfg(feature = "debug")] use crate::opengl::debug::{MessageSeverity, MessageSource, MessageType}; use crate::opengl::shader::{ @@ -35,14 +29,18 @@ use crate::opengl::texture::{ Texture as GlTexture, TextureUnit, }; -use crate::opengl::vertex_array::{PrimitiveKind, VertexArray}; +use crate::opengl::vertex_array::{ + DataType as VertexArrayDataType, + PrimitiveKind, + VertexArray, +}; use crate::opengl::{clear_buffers, enable, BufferClearMask, Capability}; use crate::projection::new_perspective; use crate::shader::Program as ShaderProgram; use crate::texture::{Id as TextureId, List as TextureMap, Texture}; use crate::transform::Transform; use crate::vector::{Vec2, Vec3}; -use crate::vertex::Vertex; +use crate::vertex::{AttributeComponentType, Vertex}; use crate::window::Window; #[derive(Debug, Default)] @@ -124,45 +122,38 @@ fn render( clear_buffers(BufferClearMask::COLOR | BufferClearMask::DEPTH); - for (mesh, texture_map, shader_program, material, transform) in &query { + for (mesh, texture_list, shader_program, material, transform) in &query { let shader_program = gl_shader_programs .entry(shader_program.u64_hash()) .or_insert_with(|| create_gl_shader_program(&shader_program).unwrap()); - shader_program.activate(|shader_program_curr_bound| { - apply_transformation_matrices( - &transform, - shader_program, - &camera, - window.size().expect("Failed to get window size"), - &shader_program_curr_bound, - ); + apply_transformation_matrices( + &transform, + shader_program, + &camera, + window.size().expect("Failed to get window size"), + ); - apply_light( - &material, - shader_program, - light_source.as_deref(), - &camera, - &shader_program_curr_bound, - ); + apply_light(&material, shader_program, light_source.as_deref(), &camera); - for texture in &texture_map.list { - let gl_texture = gl_textures - .entry(texture.id()) - .or_insert_with(|| create_gl_texture(texture)); + for texture in &texture_list.list { + let gl_texture = gl_textures + .entry(texture.id()) + .or_insert_with(|| create_gl_texture(texture)); - let texture_unit = TextureUnit::from_texture_id(texture.id()) - .unwrap_or_else(|| { - panic!("Texture id {} is a invalid texture unit", texture.id()); - }); + let texture_unit = + TextureUnit::from_texture_id(texture.id()).unwrap_or_else(|| { + panic!("Texture id {} is a invalid texture unit", texture.id()); + }); - set_active_texture_unit(texture_unit); + set_active_texture_unit(texture_unit); - gl_texture.bind(|_| {}); - } + gl_texture.bind(); + } - draw_mesh(&mesh); - }); + shader_program.activate(); + + draw_mesh(&mesh); } } @@ -201,37 +192,24 @@ fn draw_mesh(mesh: &Mesh) // should be rethinked let renderable = Renderable::new(mesh.vertices(), 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, - 0, - index_info.cnt, - ); - } else { - VertexArray::draw_arrays( - &vert_arr_curr_bound, - PrimitiveKind::Triangles, - 0, - 3, - ); - } - }); + renderable.vertex_arr.bind(); + + if let Some(index_info) = &renderable.index_info { + VertexArray::draw_elements(PrimitiveKind::Triangles, 0, index_info.cnt); + } else { + VertexArray::draw_arrays(PrimitiveKind::Triangles, 0, 3); + } } fn create_gl_texture(texture: &Texture) -> GlTexture { - let gl_texture = GlTexture::new(); - - gl_texture.bind(|texture_curr_bound| { - GlTexture::generate( - &texture_curr_bound, - texture.dimensions(), - texture.image().as_bytes(), - texture.pixel_data_format(), - ); - }); + let mut gl_texture = GlTexture::new(); + + gl_texture.generate( + *texture.dimensions(), + texture.image().as_bytes(), + texture.pixel_data_format(), + ); gl_texture.apply_properties(texture.properties()); @@ -272,7 +250,7 @@ struct Renderable vertex_arr: VertexArray, /// Vertex and index buffer has to live as long as the vertex array - _vertex_buffer: Buffer<Vertex, ArrayBufferKind>, + _vertex_buffer: Buffer<Vertex>, index_info: Option<IndexInfo>, } @@ -280,31 +258,46 @@ impl Renderable { fn new(vertices: &[Vertex], indices: Option<&[u32]>) -> Self { - let vertex_arr = VertexArray::new(); - let vertex_buffer = Buffer::new(); + let mut vertex_arr = VertexArray::new(); + let mut vertex_buffer = Buffer::new(); let mut index_info = None; - vertex_arr.bind(|vert_arr_curr_bound| { - vertex_buffer.bind(|vert_buf_curr_bound| { - Buffer::store(&vert_buf_curr_bound, vertices, BufferUsage::Static); + vertex_buffer.store(vertices, BufferUsage::Static); - VertexArray::configure_attrs(&vert_arr_curr_bound, &vert_buf_curr_bound); - }); + vertex_arr.bind_vertex_buffer(0, &vertex_buffer, 0); - if let Some(indices) = indices { - let new_index_buffer = Buffer::new(); + let mut offset = 0u32; - new_index_buffer.bind(|index_buf_curr_bound| { - Buffer::store(&index_buf_curr_bound, indices, BufferUsage::Static); - }); + for attrib in Vertex::attrs() { + vertex_arr.enable_attrib(attrib.index); - index_info = Some(IndexInfo { - _buffer: new_index_buffer, - cnt: indices.len().try_into().unwrap(), - }); - } - }); + vertex_arr.set_attrib_format( + attrib.index, + match attrib.component_type { + AttributeComponentType::Float => VertexArrayDataType::Float, + }, + false, + offset, + ); + + vertex_arr.set_attrib_vertex_buf_binding(attrib.index, 0); + + offset += attrib.component_size * attrib.component_cnt as u32; + } + + if let Some(indices) = indices { + let mut index_buffer = Buffer::new(); + + index_buffer.store(indices, BufferUsage::Static); + + vertex_arr.bind_element_buffer(&index_buffer); + + index_info = Some(IndexInfo { + _buffer: index_buffer, + cnt: indices.len().try_into().unwrap(), + }); + } Self { vertex_arr, @@ -316,25 +309,16 @@ impl Renderable fn apply_transformation_matrices( transform: &Transform, - gl_shader_program: &GlShaderProgram, + gl_shader_program: &mut GlShaderProgram, camera: &Camera, window_size: Dimens<u32>, - shader_program_curr_bound: &CurrentlyBound<GlShaderProgram>, ) { - gl_shader_program.set_uniform_matrix_4fv( - shader_program_curr_bound, - cstr!("model"), - &transform.as_matrix(), - ); + gl_shader_program.set_uniform_matrix_4fv(cstr!("model"), &transform.as_matrix()); let view = create_view(camera); - gl_shader_program.set_uniform_matrix_4fv( - shader_program_curr_bound, - cstr!("view"), - &view, - ); + gl_shader_program.set_uniform_matrix_4fv(cstr!("view"), &view); #[allow(clippy::cast_precision_loss)] let projection = new_perspective( @@ -344,23 +328,17 @@ fn apply_transformation_matrices( 0.1, ); - gl_shader_program.set_uniform_matrix_4fv( - shader_program_curr_bound, - cstr!("projection"), - &projection, - ); + gl_shader_program.set_uniform_matrix_4fv(cstr!("projection"), &projection); } fn apply_light( material: &Material, - gl_shader_program: &GlShaderProgram, + gl_shader_program: &mut GlShaderProgram, light_source: Option<&LightSource>, camera: &Camera, - shader_program_curr_bound: &CurrentlyBound<GlShaderProgram>, ) { gl_shader_program.set_uniform_vec_3fv( - shader_program_curr_bound, cstr!("light.position"), &light_source.map_or_else(Vec3::default, |light_source| { light_source.position().clone() @@ -368,7 +346,6 @@ fn apply_light( ); gl_shader_program.set_uniform_vec_3fv( - shader_program_curr_bound, cstr!("light.ambient"), &light_source .map_or(Color::WHITE_F32, |light_source| { @@ -378,7 +355,6 @@ fn apply_light( ); gl_shader_program.set_uniform_vec_3fv( - shader_program_curr_bound, cstr!("light.diffuse"), &light_source .map_or(Color::WHITE_F32, |light_source| { @@ -388,7 +364,6 @@ fn apply_light( ); gl_shader_program.set_uniform_vec_3fv( - shader_program_curr_bound, cstr!("light.specular"), &light_source .map_or(Color::WHITE_F32, |light_source| { @@ -399,36 +374,25 @@ fn apply_light( #[allow(clippy::cast_possible_wrap)] gl_shader_program.set_uniform_1i( - shader_program_curr_bound, cstr!("material.ambient"), material.ambient_map().into_inner() as i32, ); #[allow(clippy::cast_possible_wrap)] gl_shader_program.set_uniform_1i( - shader_program_curr_bound, cstr!("material.diffuse"), material.diffuse_map().into_inner() as i32, ); #[allow(clippy::cast_possible_wrap)] gl_shader_program.set_uniform_1i( - shader_program_curr_bound, cstr!("material.specular"), material.specular_map().into_inner() as i32, ); - gl_shader_program.set_uniform_1fv( - shader_program_curr_bound, - cstr!("material.shininess"), - material.shininess(), - ); + gl_shader_program.set_uniform_1fv(cstr!("material.shininess"), material.shininess()); - gl_shader_program.set_uniform_vec_3fv( - shader_program_curr_bound, - cstr!("view_pos"), - &camera.position, - ); + gl_shader_program.set_uniform_vec_3fv(cstr!("view_pos"), &camera.position); } fn create_view(camera: &Camera) -> Matrix<f32, 4, 4> @@ -486,6 +450,6 @@ fn opengl_debug_message_cb( #[derive(Debug)] struct IndexInfo { - _buffer: Buffer<u32, ElementArrayBufferKind>, + _buffer: Buffer<u32>, cnt: u32, } diff --git a/engine/src/texture.rs b/engine/src/texture.rs index 5cea9ff..88c57bd 100644 --- a/engine/src/texture.rs +++ b/engine/src/texture.rs @@ -7,8 +7,8 @@ use image::io::Reader as ImageReader; use image::{DynamicImage, ImageError, Rgb, RgbImage}; use crate::color::Color; +use crate::data_types::dimens::Dimens; use crate::opengl::texture::PixelDataFormat; -use crate::vector::Vec2; static NEXT_ID: AtomicU32 = AtomicU32::new(0); @@ -25,7 +25,7 @@ pub struct Texture id: Id, image: DynamicImage, pixel_data_format: PixelDataFormat, - dimensions: Vec2<u32>, + dimensions: Dimens<u32>, properties: Properties, } @@ -46,14 +46,17 @@ impl Texture .map_err(Error::DecodeImageFailed)?; let pixel_data_format = match &image { - DynamicImage::ImageRgb8(_) => PixelDataFormat::Rgb, - DynamicImage::ImageRgba8(_) => PixelDataFormat::Rgba, + DynamicImage::ImageRgb8(_) => PixelDataFormat::Rgb8, + DynamicImage::ImageRgba8(_) => PixelDataFormat::Rgba8, _ => { return Err(Error::UnsupportedImageDataKind); } }; - let dimensions = Vec2 { x: image.width(), y: image.height() }; + let dimensions = Dimens { + width: image.width(), + height: image.height(), + }; let id = NEXT_ID.fetch_add(1, Ordering::Relaxed); @@ -67,11 +70,11 @@ impl Texture } #[must_use] - pub fn new_from_color(dimensions: &Vec2<u32>, color: &Color<u8>) -> Self + pub fn new_from_color(dimensions: &Dimens<u32>, color: &Color<u8>) -> Self { let image = RgbImage::from_pixel( - dimensions.x, - dimensions.y, + dimensions.width, + dimensions.height, Rgb([color.red, color.green, color.blue]), ); @@ -80,8 +83,8 @@ impl Texture Self { id: Id::new(id), image: image.into(), - pixel_data_format: PixelDataFormat::Rgb, - dimensions: dimensions.clone(), + pixel_data_format: PixelDataFormat::Rgb8, + dimensions: *dimensions, properties: Properties::default(), } } @@ -104,7 +107,7 @@ impl Texture } #[must_use] - pub fn dimensions(&self) -> &Vec2<u32> + pub fn dimensions(&self) -> &Dimens<u32> { &self.dimensions } diff --git a/engine/src/vertex.rs b/engine/src/vertex.rs index bb0e890..37a6c51 100644 --- a/engine/src/vertex.rs +++ b/engine/src/vertex.rs @@ -82,30 +82,31 @@ impl Vertex { pub(crate) fn attrs() -> &'static [Attribute] { + #[allow(clippy::cast_possible_truncation)] &[ Attribute { index: 0, component_type: AttributeComponentType::Float, component_cnt: AttributeComponentCnt::Three, - component_size: size_of::<f32>(), + component_size: size_of::<f32>() as u32, }, Attribute { index: 1, component_type: AttributeComponentType::Float, component_cnt: AttributeComponentCnt::Three, - component_size: size_of::<f32>(), + component_size: size_of::<f32>() as u32, }, Attribute { index: 2, component_type: AttributeComponentType::Float, component_cnt: AttributeComponentCnt::Two, - component_size: size_of::<f32>(), + component_size: size_of::<f32>() as u32, }, Attribute { index: 3, component_type: AttributeComponentType::Float, component_cnt: AttributeComponentCnt::Three, - component_size: size_of::<f32>(), + component_size: size_of::<f32>() as u32, }, ] } @@ -113,10 +114,10 @@ impl Vertex pub(crate) struct Attribute { - pub(crate) index: usize, + pub(crate) index: u32, pub(crate) component_type: AttributeComponentType, pub(crate) component_cnt: AttributeComponentCnt, - pub(crate) component_size: usize, + pub(crate) component_size: u32, } pub(crate) enum AttributeComponentType |