diff options
| -rw-r--r-- | engine/src/currently_bound.rs | 22 | ||||
| -rw-r--r-- | engine/src/lib.rs | 1 | ||||
| -rw-r--r-- | engine/src/renderer/mod.rs | 15 | ||||
| -rw-r--r-- | engine/src/renderer/vertex_array.rs | 26 | ||||
| -rw-r--r-- | engine/src/renderer/vertex_buffer.rs | 18 | 
5 files changed, 70 insertions, 12 deletions
diff --git a/engine/src/currently_bound.rs b/engine/src/currently_bound.rs new file mode 100644 index 0000000..eefa239 --- /dev/null +++ b/engine/src/currently_bound.rs @@ -0,0 +1,22 @@ +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/lib.rs b/engine/src/lib.rs index b93a0bb..5b313ec 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -10,6 +10,7 @@ mod renderer;  mod shader;  pub mod color; +pub mod currently_bound;  pub mod object;  pub mod vector;  pub mod vertex; diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs index 364b7f4..a23d5a0 100644 --- a/engine/src/renderer/mod.rs +++ b/engine/src/renderer/mod.rs @@ -45,7 +45,9 @@ pub fn render<'renderable>(renderables: impl IntoIterator<Item = &'renderable Re      for renderable in renderables {          renderable.shader_program.activate(); -        renderable.vertex_arr.draw(PrimitiveKind::Triangles, 0, 3); +        renderable.vertex_arr.bind(|vert_arr_curr_bound| { +            VertexArray::draw(&vert_arr_curr_bound, PrimitiveKind::Triangles, 0, 3); +        });      }  } @@ -64,14 +66,15 @@ impl Renderable      pub fn new(shader_program: crate::shader::Program, vertices: &[Vertex]) -> Self      {          let vertex_arr = VertexArray::new(); - -        vertex_arr.bind(); -          let vertex_buffer = VertexBuffer::new(); -        vertex_buffer.store(vertices, BufferUsage::Static); +        vertex_arr.bind(|vert_arr_curr_bound| { +            vertex_buffer.bind(|vert_buf_curr_bound| { +                VertexBuffer::store(&vert_buf_curr_bound, vertices, BufferUsage::Static); -        VertexArray::configure_attrs(); +                VertexArray::configure_attrs(&vert_arr_curr_bound, &vert_buf_curr_bound); +            }); +        });          Self {              shader_program, diff --git a/engine/src/renderer/vertex_array.rs b/engine/src/renderer/vertex_array.rs index b0aac81..2bd6a5b 100644 --- a/engine/src/renderer/vertex_array.rs +++ b/engine/src/renderer/vertex_array.rs @@ -1,5 +1,7 @@  use std::mem::size_of; +use crate::currently_bound::CurrentlyBound; +use crate::renderer::vertex_buffer::VertexBuffer;  use crate::vertex::{Attribute, AttributeComponentType, Vertex};  const VERTEX_STRIDE: usize = size_of::<Vertex>(); @@ -23,10 +25,14 @@ impl VertexArray          Self { array }      } -    pub fn draw(&self, primitive_kind: PrimitiveKind, start_index: u32, index_cnt: u32) +    /// Draws the currently bound vertex array. +    pub fn draw( +        _currently_bound: &CurrentlyBound<Self>, +        primitive_kind: PrimitiveKind, +        start_index: u32, +        index_cnt: u32, +    )      { -        self.bind(); -          unsafe {              #[allow(clippy::cast_possible_wrap)]              gl::DrawArrays( @@ -37,7 +43,10 @@ impl VertexArray          }      } -    pub fn configure_attrs() +    pub fn configure_attrs( +        _currently_bound: &CurrentlyBound<Self>, +        _vert_buf_curr_bound: &CurrentlyBound<VertexBuffer>, +    )      {          let mut offset = 0; @@ -50,9 +59,16 @@ impl VertexArray          }      } -    pub fn bind(&self) +    #[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) diff --git a/engine/src/renderer/vertex_buffer.rs b/engine/src/renderer/vertex_buffer.rs index 27ed705..57debc3 100644 --- a/engine/src/renderer/vertex_buffer.rs +++ b/engine/src/renderer/vertex_buffer.rs @@ -1,5 +1,6 @@  use std::mem::size_of_val; +use crate::currently_bound::CurrentlyBound;  use crate::vertex::Vertex;  #[derive(Debug)] @@ -21,12 +22,27 @@ impl VertexBuffer          Self { buffer }      } -    pub fn store(&self, vertices: &[Vertex], usage: BufferUsage) +    #[allow(clippy::inline_always)] +    #[inline(always)] +    pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>))      {          unsafe {              gl::BindBuffer(gl::ARRAY_BUFFER, self.buffer);          } +        // SAFETY: A vertex array object is currently bound +        let currently_bound = unsafe { CurrentlyBound::new() }; + +        cb(currently_bound); +    } + +    /// Stores vertices in the currently bound vertex bound. +    pub fn store( +        _currently_bound: &CurrentlyBound<Self>, +        vertices: &[Vertex], +        usage: BufferUsage, +    ) +    {          unsafe {              #[allow(clippy::cast_possible_wrap)]              gl::BufferData(  | 
