From f13ff0ad6a7581cd99fb00797f4492de3525ace4 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 29 Mar 2026 21:12:30 +0200 Subject: feat(opengl-bindings): add VertexArray::draw_elements vertex offset param --- opengl-bindings/Cargo.toml | 2 +- opengl-bindings/src/vertex_array.rs | 99 ++++++++++++++++++++++++------------- 2 files changed, 67 insertions(+), 34 deletions(-) diff --git a/opengl-bindings/Cargo.toml b/opengl-bindings/Cargo.toml index b21cd74..a2f7ade 100644 --- a/opengl-bindings/Cargo.toml +++ b/opengl-bindings/Cargo.toml @@ -22,7 +22,7 @@ gl_commands = [ "NamedBufferSubData", "CreateVertexArrays", "DrawArrays", - "DrawElements", + "DrawElementsBaseVertex", "VertexArrayElementBuffer", "VertexArrayVertexBuffer", "EnableVertexArrayAttrib", diff --git a/opengl-bindings/src/vertex_array.rs b/opengl-bindings/src/vertex_array.rs index 3dc5cb6..5de59d8 100644 --- a/opengl-bindings/src/vertex_array.rs +++ b/opengl-bindings/src/vertex_array.rs @@ -29,33 +29,37 @@ impl VertexArray /// /// # Errors /// Returns `Err` if: - /// - `start_index` is too large - /// - `cnt` is too large + /// - `vertex_offset` is too large + /// - `vertex_cnt` is too large pub fn draw_arrays( current_context: &CurrentContextWithFns<'_>, primitive_kind: PrimitiveKind, - start_index: u32, - cnt: u32, + vertex_offset: u32, + vertex_cnt: u32, ) -> Result<(), DrawError> { - let start_index: crate::sys::types::GLint = - start_index - .try_into() - .map_err(|_| DrawError::StartIndexValueTooLarge { - value: start_index, + let vertex_offset: crate::sys::types::GLint = + vertex_offset.try_into().map_err(|_| { + DrawError::VertexOffsetValueTooLarge { + value: vertex_offset, max_value: crate::sys::types::GLint::MAX as u32, - })?; - - let cnt: crate::sys::types::GLsizei = - cnt.try_into().map_err(|_| DrawError::CountValueTooLarge { - value: cnt, - max_value: crate::sys::types::GLsizei::MAX as u32, + } })?; + let vertex_cnt: crate::sys::types::GLsizei = + vertex_cnt + .try_into() + .map_err(|_| DrawError::VertexCountValueTooLarge { + value: vertex_cnt, + max_value: crate::sys::types::GLsizei::MAX as u32, + })?; + unsafe { - current_context - .fns() - .DrawArrays(primitive_kind.into_gl(), start_index, cnt); + current_context.fns().DrawArrays( + primitive_kind.into_gl(), + vertex_offset, + vertex_cnt, + ); } Ok(()) @@ -67,26 +71,40 @@ impl VertexArray /// Returns `Err` if `cnt` is too large. pub fn draw_elements( current_context: &CurrentContextWithFns<'_>, - primitive_kind: PrimitiveKind, - start_index: u32, - cnt: u32, + DrawElementsOptions { + primitive_kind, + element_offset, + element_cnt, + vertex_offset, + }: DrawElementsOptions, ) -> Result<(), DrawError> { - let cnt: crate::sys::types::GLsizei = - cnt.try_into().map_err(|_| DrawError::CountValueTooLarge { - value: cnt, - max_value: crate::sys::types::GLsizei::MAX as u32, + let element_cnt: crate::sys::types::GLsizei = + element_cnt + .try_into() + .map_err(|_| DrawError::ElementCountValueTooLarge { + value: element_cnt, + max_value: crate::sys::types::GLsizei::MAX as u32, + })?; + + let vertex_offset: crate::sys::types::GLint = + vertex_offset.try_into().map_err(|_| { + DrawError::VertexOffsetValueTooLarge { + value: vertex_offset, + max_value: crate::sys::types::GLint::MAX as u32, + } })?; unsafe { - current_context.fns().DrawElements( + current_context.fns().DrawElementsBaseVertex( primitive_kind.into_gl(), - cnt, + element_cnt, crate::sys::UNSIGNED_INT, // TODO: Make this not sometimes UB. DrawElements expects a actual // pointer to a memory location when no VBO is bound. // See: https://stackoverflow.com/q/21706113 - std::ptr::without_provenance::(start_index as usize), + std::ptr::without_provenance::(element_offset as usize), + vertex_offset, ); } @@ -212,7 +230,7 @@ impl VertexArray } } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub enum PrimitiveKind { Triangles, @@ -261,17 +279,32 @@ pub struct VertexBufferSpec pub vertex_size: usize, } +#[derive(Debug, Clone)] +pub struct DrawElementsOptions +{ + pub primitive_kind: PrimitiveKind, + pub element_offset: u32, + pub element_cnt: u32, + pub vertex_offset: u32, +} + #[derive(Debug, thiserror::Error)] pub enum DrawError { - #[error("Start index value {value} is too large. Must be < {max_value}")] - StartIndexValueTooLarge + #[error("Vertex offset value {value} is too large. Must be < {max_value}")] + VertexOffsetValueTooLarge + { + value: u32, max_value: u32 + }, + + #[error("Vertex count value {value} is too large. Must be < {max_value}")] + VertexCountValueTooLarge { value: u32, max_value: u32 }, - #[error("Count value {value} is too large. Must be < {max_value}")] - CountValueTooLarge + #[error("Element count value {value} is too large. Must be < {max_value}")] + ElementCountValueTooLarge { value: u32, max_value: u32 }, -- cgit v1.2.3-18-g5258