summaryrefslogtreecommitdiff
path: root/engine/src/opengl/vertex_array.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-10-13 23:32:00 +0200
committerHampusM <hampus@hampusmat.com>2023-10-13 23:32:00 +0200
commit12f48046b2606fc77a1312a6d5e5fc7ff9feff88 (patch)
tree644f4abd6785a5f0c066c7fbadcfc5e820a41ebf /engine/src/opengl/vertex_array.rs
parentcfa73b1ea42fa491ff9e00bb5efb5e5a5d860578 (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.rs131
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,
+ }
+ }
+}