diff options
author | HampusM <hampus@hampusmat.com> | 2023-10-13 23:32:00 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2023-10-13 23:32:00 +0200 |
commit | 12f48046b2606fc77a1312a6d5e5fc7ff9feff88 (patch) | |
tree | 644f4abd6785a5f0c066c7fbadcfc5e820a41ebf /engine/src/opengl/vertex_array.rs | |
parent | cfa73b1ea42fa491ff9e00bb5efb5e5a5d860578 (diff) |
refactor(engine): move uses of OpenGL to OpenGL module
Diffstat (limited to 'engine/src/opengl/vertex_array.rs')
-rw-r--r-- | engine/src/opengl/vertex_array.rs | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/engine/src/opengl/vertex_array.rs b/engine/src/opengl/vertex_array.rs new file mode 100644 index 0000000..f255b8a --- /dev/null +++ b/engine/src/opengl/vertex_array.rs @@ -0,0 +1,131 @@ +use std::mem::size_of; + +use crate::opengl::currently_bound::CurrentlyBound; +use crate::opengl::vertex_buffer::VertexBuffer; +use crate::vertex::{Attribute, AttributeComponentType, Vertex}; + +const VERTEX_STRIDE: usize = size_of::<Vertex>(); + +#[derive(Debug)] +pub struct VertexArray +{ + array: gl::types::GLuint, +} + +impl VertexArray +{ + pub fn new() -> Self + { + let mut array = 0; + + unsafe { + gl::GenVertexArrays(1, &mut array); + } + + Self { array } + } + + /// Draws the currently bound vertex array. + pub fn draw( + _currently_bound: &CurrentlyBound<Self>, + primitive_kind: PrimitiveKind, + start_index: u32, + index_cnt: u32, + ) + { + unsafe { + #[allow(clippy::cast_possible_wrap)] + gl::DrawArrays( + primitive_kind.into_gl(), + start_index as gl::types::GLint, + index_cnt as gl::types::GLsizei, + ); + } + } + + pub fn configure_attrs( + _currently_bound: &CurrentlyBound<Self>, + _vert_buf_curr_bound: &CurrentlyBound<VertexBuffer>, + ) + { + 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; + } + } + + #[allow(clippy::inline_always)] + #[inline(always)] + pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>)) + { + unsafe { gl::BindVertexArray(self.array) } + + // SAFETY: A vertex array object is currently bound + let currently_bound = unsafe { CurrentlyBound::new() }; + + cb(currently_bound); + } + + fn vertex_attrib_ptr(vertex_attr: &Attribute, offset: usize) + { + 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 _, + ); + } + } + + fn enable_vertex_attrib_array(index: usize) + { + unsafe { + #[allow(clippy::cast_possible_truncation)] + gl::EnableVertexAttribArray(index as gl::types::GLuint); + } + } + + fn vertex_attr_type_to_gl( + vertex_attr_type: &AttributeComponentType, + ) -> gl::types::GLenum + { + match vertex_attr_type { + AttributeComponentType::Float => gl::FLOAT, + } + } +} + +impl Drop for VertexArray +{ + fn drop(&mut self) + { + unsafe { + gl::DeleteVertexArrays(1, &self.array); + } + } +} + +#[derive(Debug)] +pub enum PrimitiveKind +{ + Triangles, +} + +impl PrimitiveKind +{ + fn into_gl(self) -> gl::types::GLenum + { + match self { + Self::Triangles => gl::TRIANGLES, + } + } +} |