summaryrefslogtreecommitdiff
path: root/engine/src/renderer/opengl/graphics_mesh.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-10-18 17:04:28 +0200
committerHampusM <hampus@hampusmat.com>2025-10-18 17:04:28 +0200
commit7083a19bf1029bff21a9550d40cc3260e99aac53 (patch)
tree524a8bd2e75ca712b0536218089804cf9838553b /engine/src/renderer/opengl/graphics_mesh.rs
parent7f3072ed7e016dff359439d7580403e36ad6b325 (diff)
refactor(engine): use winit instead of glfw
Diffstat (limited to 'engine/src/renderer/opengl/graphics_mesh.rs')
-rw-r--r--engine/src/renderer/opengl/graphics_mesh.rs120
1 files changed, 120 insertions, 0 deletions
diff --git a/engine/src/renderer/opengl/graphics_mesh.rs b/engine/src/renderer/opengl/graphics_mesh.rs
new file mode 100644
index 0000000..9b929c0
--- /dev/null
+++ b/engine/src/renderer/opengl/graphics_mesh.rs
@@ -0,0 +1,120 @@
+use opengl_bindings::buffer::{Buffer as GlBuffer, Usage as GlBufferUsage};
+use opengl_bindings::vertex_array::{
+ DataType as GlVertexArrayDataType,
+ VertexArray as GlVertexArray,
+};
+use opengl_bindings::CurrentContextWithFns as GlCurrentContextWithFns;
+
+use crate::mesh::Mesh;
+use crate::renderer::opengl::vertex::{
+ AttributeComponentType as VertexAttributeComponentType,
+ Vertex as RendererVertex,
+};
+
+#[derive(Debug)]
+pub struct GraphicsMesh
+{
+ /// Vertex and index buffer has to live as long as the vertex array
+ _vertex_buffer: GlBuffer<RendererVertex>,
+ pub index_buffer: Option<GlBuffer<u32>>,
+ pub element_cnt: u32,
+ pub vertex_arr: GlVertexArray,
+}
+
+impl GraphicsMesh
+{
+ #[tracing::instrument(skip_all)]
+ pub fn new(
+ current_context: &GlCurrentContextWithFns<'_>,
+ mesh: &Mesh,
+ ) -> Result<Self, Error>
+ {
+ tracing::trace!(
+ "Creating vertex array, vertex buffer{}",
+ if mesh.indices().is_some() {
+ " and index buffer"
+ } else {
+ ""
+ }
+ );
+
+ let vertex_arr = GlVertexArray::new(current_context);
+ let vertex_buffer = GlBuffer::new(current_context);
+
+ vertex_buffer
+ .store_mapped(
+ current_context,
+ mesh.vertices(),
+ GlBufferUsage::Static,
+ |vertex| RendererVertex {
+ pos: vertex.pos.into(),
+ texture_coords: vertex.texture_coords.into(),
+ normal: vertex.normal.into(),
+ },
+ )
+ .map_err(Error::StoreVerticesFailed)?;
+
+ vertex_arr.bind_vertex_buffer(current_context, 0, &vertex_buffer, 0);
+
+ let mut offset = 0u32;
+
+ for attrib in RendererVertex::attrs() {
+ vertex_arr.enable_attrib(current_context, attrib.index);
+
+ vertex_arr.set_attrib_format(
+ current_context,
+ attrib.index,
+ match attrib.component_type {
+ VertexAttributeComponentType::Float => GlVertexArrayDataType::Float,
+ },
+ false,
+ offset,
+ );
+
+ vertex_arr.set_attrib_vertex_buf_binding(current_context, attrib.index, 0);
+
+ offset += attrib.component_size * attrib.component_cnt as u32;
+ }
+
+ if let Some(indices) = mesh.indices() {
+ let index_buffer = GlBuffer::new(current_context);
+
+ index_buffer
+ .store(current_context, indices, GlBufferUsage::Static)
+ .map_err(Error::StoreIndicesFailed)?;
+
+ vertex_arr.bind_element_buffer(current_context, &index_buffer);
+
+ return Ok(Self {
+ _vertex_buffer: vertex_buffer,
+ index_buffer: Some(index_buffer),
+ element_cnt: indices
+ .len()
+ .try_into()
+ .expect("Mesh index count does not fit into a 32-bit unsigned int"),
+ vertex_arr,
+ });
+ }
+
+ Ok(Self {
+ _vertex_buffer: vertex_buffer,
+ index_buffer: None,
+ element_cnt: mesh
+ .vertices()
+ .len()
+ .try_into()
+ .expect("Mesh vertex count does not fit into a 32-bit unsigned int"),
+ vertex_arr,
+ })
+ }
+}
+
+#[derive(Debug, thiserror::Error)]
+pub enum Error
+{
+ #[error("Failed to store vertices in vertex buffer")]
+ StoreVerticesFailed(#[source] opengl_bindings::buffer::Error),
+
+ #[error("Failed to store indices in index buffer")]
+ StoreIndicesFailed(#[source] opengl_bindings::buffer::Error),
+}