summaryrefslogtreecommitdiff
path: root/engine/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-01-21 02:45:23 +0100
committerHampusM <hampus@hampusmat.com>2025-01-21 02:45:23 +0100
commit6249b9e2f450257e71baafb7af4a47c4eccaeb9e (patch)
treedf3550641e070e6020763bd814f74896287742c4 /engine/src
parentc5261577e3bf289215aa2f7aa09df0d2b89efa6f (diff)
refactor(engine): add GlObjects component later in opengl renderer
Diffstat (limited to 'engine/src')
-rw-r--r--engine/src/opengl/buffer.rs13
-rw-r--r--engine/src/opengl/vertex_array.rs11
-rw-r--r--engine/src/renderer/opengl.rs49
-rw-r--r--engine/src/util.rs73
4 files changed, 69 insertions, 77 deletions
diff --git a/engine/src/opengl/buffer.rs b/engine/src/opengl/buffer.rs
index 2be7f12..68a75fb 100644
--- a/engine/src/opengl/buffer.rs
+++ b/engine/src/opengl/buffer.rs
@@ -39,19 +39,6 @@ impl<Item> Buffer<Item>
{
self.buf
}
-
- /// Does a weak clone of this buffer. The buffer itself is NOT copied in any way this
- /// function only copies the internal buffer ID.
- ///
- /// # Safety
- /// The returned `Buffer` must not be dropped if another `Buffer` referencing the
- /// same buffer ID is used later or if a [`VertexArray`] is used later.
- ///
- /// [`VertexArray`]: crate::opengl::vertex_array::VertexArray
- pub unsafe fn clone_weak(&self) -> Self
- {
- Self { buf: self.buf, _pd: PhantomData }
- }
}
impl<Item> Drop for Buffer<Item>
diff --git a/engine/src/opengl/vertex_array.rs b/engine/src/opengl/vertex_array.rs
index da5d91e..e1e1a15 100644
--- a/engine/src/opengl/vertex_array.rs
+++ b/engine/src/opengl/vertex_array.rs
@@ -125,17 +125,6 @@ impl VertexArray
{
unsafe { gl::BindVertexArray(self.array) }
}
-
- /// Does a weak clone of this vertex array. The vertex array itself is NOT copied in
- /// any way this function only copies the internal vertex array ID.
- ///
- /// # Safety
- /// The returned `VertexArray` must not be dropped if another `VertexArray`
- /// referencing the same vertex array ID is used later.
- pub unsafe fn clone_unsafe(&self) -> Self
- {
- Self { array: self.array }
- }
}
impl Drop for VertexArray
diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs
index c098548..6a571eb 100644
--- a/engine/src/renderer/opengl.rs
+++ b/engine/src/renderer/opengl.rs
@@ -64,7 +64,7 @@ use crate::opengl::{
use crate::projection::{ClipVolume, Projection};
use crate::texture::{Id as TextureId, Texture};
use crate::transform::{Position, Scale};
-use crate::util::NeverDrop;
+use crate::util::{defer, Defer, RefOrValue};
use crate::vector::{Vec2, Vec3};
use crate::vertex::{AttributeComponentType, Vertex};
use crate::window::Window;
@@ -174,21 +174,17 @@ fn render(
.map(|material_flags| material_flags.clone())
.unwrap_or_default();
- let new_gl_objects;
-
- let gl_objects = if let Some(gl_objects) = gl_objects.as_deref() {
- gl_objects
- } else {
- // TODO: Account for when meshes are changed
- let gl_objects = GlObjects::new(&mesh);
-
- new_gl_objects = Some(gl_objects.clone());
-
- actions.add_components(euid, (gl_objects,));
-
- &*new_gl_objects.unwrap()
+ let gl_objs = match gl_objects.as_deref() {
+ Some(gl_objs) => RefOrValue::Ref(gl_objs),
+ None => RefOrValue::Value(Some(GlObjects::new(&mesh))),
};
+ defer!(|gl_objs| {
+ if let RefOrValue::Value(opt_gl_objs) = gl_objs {
+ actions.add_components(euid, (opt_gl_objs.take().unwrap(),));
+ };
+ });
+
apply_transformation_matrices(
Transformation {
position: position.map(|pos| *pos).unwrap_or_default().position,
@@ -235,7 +231,7 @@ fn render(
);
}
- draw_mesh(gl_objects);
+ draw_mesh(gl_objs.get().unwrap());
if draw_flags.is_some() {
let default_polygon_mode_config = PolygonModeConfig::default();
@@ -360,7 +356,7 @@ fn get_glsl_shader_content(path: &Path) -> Result<Vec<u8>, std::io::Error>
struct GlObjects
{
/// Vertex and index buffer has to live as long as the vertex array
- vertex_buffer: Buffer<Vertex>,
+ _vertex_buffer: Buffer<Vertex>,
index_buffer: Option<Buffer<u32>>,
element_cnt: u32,
@@ -415,7 +411,7 @@ impl GlObjects
vertex_arr.bind_element_buffer(&index_buffer);
return Self {
- vertex_buffer,
+ _vertex_buffer: vertex_buffer,
index_buffer: Some(index_buffer),
element_cnt: indices
.len()
@@ -426,7 +422,7 @@ impl GlObjects
}
Self {
- vertex_buffer,
+ _vertex_buffer: vertex_buffer,
index_buffer: None,
element_cnt: mesh
.vertices()
@@ -436,23 +432,6 @@ impl GlObjects
vertex_arr,
}
}
-
- pub fn clone(&self) -> NeverDrop<Self>
- {
- NeverDrop::new(Self {
- // SAFETY: The vertex buffer will never become dropped (NeverDrop ensures it)
- vertex_buffer: unsafe { self.vertex_buffer.clone_weak() },
- index_buffer: self
- .index_buffer
- .as_ref()
- // SAFETY: The index buffer will never become dropped (NeverDrop ensures
- // it)
- .map(|index_buffer| unsafe { index_buffer.clone_weak() }),
- element_cnt: self.element_cnt,
- // SAFETY: The vertex array will never become dropped (NeverDrop ensures it)
- vertex_arr: unsafe { self.vertex_arr.clone_unsafe() },
- })
- }
}
fn apply_transformation_matrices(
diff --git a/engine/src/util.rs b/engine/src/util.rs
index a505a38..0f6c78c 100644
--- a/engine/src/util.rs
+++ b/engine/src/util.rs
@@ -1,3 +1,5 @@
+use std::marker::PhantomData;
+
macro_rules! try_option {
($expr: expr) => {
match $expr {
@@ -9,9 +11,6 @@ macro_rules! try_option {
};
}
-use std::mem::ManuallyDrop;
-use std::ops::{Deref, DerefMut};
-
pub(crate) use try_option;
macro_rules! or {
@@ -97,36 +96,74 @@ macro_rules! builder {
pub(crate) use builder;
-/// Wrapper that ensures the contained value will never be dropped.
-#[derive(Debug)]
-pub struct NeverDrop<Value>
+pub enum RefOrValue<'a, T>
{
- value: ManuallyDrop<Value>,
+ Ref(&'a T),
+ Value(Option<T>),
}
-impl<Value> NeverDrop<Value>
+impl<'a, T> RefOrValue<'a, T>
{
- #[must_use]
- pub fn new(value: Value) -> Self
+ pub fn get(&self) -> Option<&T>
{
- Self { value: ManuallyDrop::new(value) }
+ match self {
+ Self::Ref(val_ref) => Some(val_ref),
+ Self::Value(val_cell) => val_cell.as_ref(),
+ }
}
}
-impl<Value> Deref for NeverDrop<Value>
+#[derive(Debug)]
+pub struct Defer<'func, Func, Data>
+where
+ Func: FnMut(&mut Data) + 'func,
{
- type Target = Value;
+ func: Func,
+ pub data: Data,
+ _pd: PhantomData<&'func ()>,
+}
- fn deref(&self) -> &Self::Target
+impl<'func, Func, Data> Defer<'func, Func, Data>
+where
+ Func: FnMut(&mut Data) + 'func,
+{
+ pub fn new(data: Data, func: Func) -> Self
{
- &self.value
+ Self { func, data, _pd: PhantomData }
}
}
-impl<Value> DerefMut for NeverDrop<Value>
+impl<'func, Func, Data> Drop for Defer<'func, Func, Data>
+where
+ Func: FnMut(&mut Data) + 'func,
{
- fn deref_mut(&mut self) -> &mut Self::Target
+ fn drop(&mut self)
{
- &mut self.value
+ (self.func)(&mut self.data)
}
}
+
+/// Defines a function that will be called at the end of the current scope.
+///
+/// Only captured variables that are later mutably borrowed needs to specified as
+/// captures.
+macro_rules! defer {
+ (|$capture: ident| {$($tt: tt)*}) => {
+ // This uses the automatic temporary lifetime extension behaviour introduced
+ // in Rust 1.79.0 (https://blog.rust-lang.org/2024/06/13/Rust-1.79.0.html) to
+ // create a unnamable variable for the Defer struct. The variable should be
+ // unnamable so that it cannot be missused and so that this macro can be used
+ // multiple times without having to give it a identifier for the Defer struct
+ // variable
+ let Defer { data: $capture, .. } = if true {
+ &Defer::new($capture, |$capture| {
+ $($tt)*
+ })
+ }
+ else {
+ unreachable!();
+ };
+ };
+}
+
+pub(crate) use defer;