summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-10-13 22:55:56 +0200
committerHampusM <hampus@hampusmat.com>2023-10-13 22:55:56 +0200
commitcfa73b1ea42fa491ff9e00bb5efb5e5a5d860578 (patch)
tree95af08ec7e9598daef6a740ce3494c4e0f1c645d
parent25b5ca97c5e5597570360c37d7452662e0118a00 (diff)
refactor(engine): add OpenGL object currently bound guards
-rw-r--r--engine/src/currently_bound.rs22
-rw-r--r--engine/src/lib.rs1
-rw-r--r--engine/src/renderer/mod.rs15
-rw-r--r--engine/src/renderer/vertex_array.rs26
-rw-r--r--engine/src/renderer/vertex_buffer.rs18
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(