summaryrefslogtreecommitdiff
path: root/engine/src/opengl
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-04-14 14:33:44 +0200
committerHampusM <hampus@hampusmat.com>2024-04-15 22:07:42 +0200
commit97bb50d42d7c1f475bf63861449a2162f665be26 (patch)
treeb25091d4ab06b60863b4ea1bf08f1ef36ad083a6 /engine/src/opengl
parent73c5bb19e7274b3e4048f70a19a7b9a2d361bfa1 (diff)
refactor(engine): use OpenGL DSA functions
Diffstat (limited to 'engine/src/opengl')
-rw-r--r--engine/src/opengl/buffer.rs63
-rw-r--r--engine/src/opengl/currently_bound.rs20
-rw-r--r--engine/src/opengl/mod.rs1
-rw-r--r--engine/src/opengl/shader.rs40
-rw-r--r--engine/src/opengl/texture.rs105
-rw-r--r--engine/src/opengl/vertex_array.rs132
6 files changed, 157 insertions, 204 deletions
diff --git a/engine/src/opengl/buffer.rs b/engine/src/opengl/buffer.rs
index 1622804..68a75fb 100644
--- a/engine/src/opengl/buffer.rs
+++ b/engine/src/opengl/buffer.rs
@@ -1,62 +1,50 @@
use std::marker::PhantomData;
use std::mem::size_of_val;
-use crate::opengl::currently_bound::CurrentlyBound;
-
#[derive(Debug)]
-pub struct Buffer<Item, ModeT: Mode>
+pub struct Buffer<Item>
{
buf: gl::types::GLuint,
- _pd: PhantomData<(Item, ModeT)>,
+ _pd: PhantomData<Item>,
}
-impl<Item, ModeT: Mode> Buffer<Item, ModeT>
+impl<Item> Buffer<Item>
{
pub fn new() -> Self
{
let mut buffer = gl::types::GLuint::default();
unsafe {
- gl::GenBuffers(1, &mut buffer);
+ gl::CreateBuffers(1, &mut buffer);
};
Self { buf: buffer, _pd: PhantomData }
}
- #[allow(clippy::inline_always)]
- #[inline(always)]
- pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>))
- {
- unsafe {
- gl::BindBuffer(ModeT::GL_ENUM, self.buf);
- }
-
- // SAFETY: The buffer object is bound above
- let currently_bound = unsafe { CurrentlyBound::new() };
-
- cb(currently_bound);
- }
-
/// Stores items in the currently bound buffer.
- pub fn store(_currently_bound: &CurrentlyBound<Self>, items: &[Item], usage: Usage)
+ pub fn store(&mut self, items: &[Item], usage: Usage)
{
unsafe {
#[allow(clippy::cast_possible_wrap)]
- gl::BufferData(
- ModeT::GL_ENUM,
+ gl::NamedBufferData(
+ self.buf,
size_of_val(items) as gl::types::GLsizeiptr,
items.as_ptr().cast(),
usage.into_gl(),
);
}
}
+
+ pub fn object(&self) -> gl::types::GLuint
+ {
+ self.buf
+ }
}
-impl<Item, ModeT: Mode> Drop for Buffer<Item, ModeT>
+impl<Item> Drop for Buffer<Item>
{
fn drop(&mut self)
{
- #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)]
unsafe {
gl::DeleteBuffers(1, &self.buf);
}
@@ -89,28 +77,3 @@ impl Usage
}
}
}
-
-/// Buffer mode.
-pub trait Mode
-{
- #[doc(hidden)]
- const GL_ENUM: gl::types::GLenum;
-}
-
-/// Array buffer kind.
-#[derive(Debug)]
-pub struct ArrayKind;
-
-impl Mode for ArrayKind
-{
- const GL_ENUM: gl::types::GLenum = gl::ARRAY_BUFFER;
-}
-
-/// Element array buffer kind.
-#[derive(Debug)]
-pub struct ElementArrayKind;
-
-impl Mode for ElementArrayKind
-{
- const GL_ENUM: gl::types::GLenum = gl::ELEMENT_ARRAY_BUFFER;
-}
diff --git a/engine/src/opengl/currently_bound.rs b/engine/src/opengl/currently_bound.rs
deleted file mode 100644
index be01841..0000000
--- a/engine/src/opengl/currently_bound.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-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/opengl/mod.rs b/engine/src/opengl/mod.rs
index 6898c49..edf6372 100644
--- a/engine/src/opengl/mod.rs
+++ b/engine/src/opengl/mod.rs
@@ -4,7 +4,6 @@ use crate::data_types::dimens::Dimens;
use crate::vector::Vec2;
pub mod buffer;
-pub mod currently_bound;
pub mod shader;
pub mod texture;
pub mod vertex_array;
diff --git a/engine/src/opengl/shader.rs b/engine/src/opengl/shader.rs
index 2312adc..070897e 100644
--- a/engine/src/opengl/shader.rs
+++ b/engine/src/opengl/shader.rs
@@ -2,7 +2,6 @@ use std::ffi::CStr;
use std::ptr::null_mut;
use crate::matrix::Matrix;
-use crate::opengl::currently_bound::CurrentlyBound;
use crate::shader::Kind;
use crate::vector::Vec3;
@@ -146,65 +145,56 @@ impl Program
Ok(())
}
- pub fn activate<Ret>(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>) -> Ret) -> Ret
+ pub fn activate(&self)
{
unsafe {
gl::UseProgram(self.program);
}
-
- // SAFETY: The shader program object is bound above
- let currently_bound = unsafe { CurrentlyBound::new() };
-
- cb(currently_bound)
}
- pub fn set_uniform_matrix_4fv(
- &self,
- _: &CurrentlyBound<Self>,
- name: &CStr,
- matrix: &Matrix<f32, 4, 4>,
- )
+ pub fn set_uniform_matrix_4fv(&mut self, name: &CStr, matrix: &Matrix<f32, 4, 4>)
{
let uniform_location =
unsafe { gl::GetUniformLocation(self.program, name.as_ptr().cast()) };
unsafe {
- gl::UniformMatrix4fv(uniform_location, 1, gl::FALSE, matrix.as_ptr());
+ gl::ProgramUniformMatrix4fv(
+ self.program,
+ uniform_location,
+ 1,
+ gl::FALSE,
+ matrix.as_ptr(),
+ );
}
}
- pub fn set_uniform_vec_3fv(
- &self,
- _: &CurrentlyBound<Self>,
- name: &CStr,
- vec: &Vec3<f32>,
- )
+ pub fn set_uniform_vec_3fv(&mut self, name: &CStr, vec: &Vec3<f32>)
{
let uniform_location =
unsafe { gl::GetUniformLocation(self.program, name.as_ptr().cast()) };
unsafe {
- gl::Uniform3fv(uniform_location, 1, vec.as_ptr());
+ gl::ProgramUniform3fv(self.program, uniform_location, 1, vec.as_ptr());
}
}
- pub fn set_uniform_1fv(&self, _: &CurrentlyBound<Self>, name: &CStr, num: f32)
+ pub fn set_uniform_1fv(&mut self, name: &CStr, num: f32)
{
let uniform_location =
unsafe { gl::GetUniformLocation(self.program, name.as_ptr().cast()) };
unsafe {
- gl::Uniform1fv(uniform_location, 1, &num);
+ gl::ProgramUniform1fv(self.program, uniform_location, 1, &num);
}
}
- pub fn set_uniform_1i(&self, _: &CurrentlyBound<Self>, name: &CStr, num: i32)
+ pub fn set_uniform_1i(&mut self, name: &CStr, num: i32)
{
let uniform_location =
unsafe { gl::GetUniformLocation(self.program, name.as_ptr().cast()) };
unsafe {
- gl::Uniform1i(uniform_location, num);
+ gl::ProgramUniform1i(self.program, uniform_location, num);
}
}
diff --git a/engine/src/opengl/texture.rs b/engine/src/opengl/texture.rs
index 5d12729..074ade7 100644
--- a/engine/src/opengl/texture.rs
+++ b/engine/src/opengl/texture.rs
@@ -1,8 +1,5 @@
-use std::ptr::null;
-
-use crate::opengl::currently_bound::CurrentlyBound;
+use crate::data_types::dimens::Dimens;
use crate::texture::{Id, Properties};
-use crate::vector::Vec2;
#[derive(Debug)]
pub struct Texture
@@ -17,88 +14,73 @@ impl Texture
let mut texture = gl::types::GLuint::default();
unsafe {
- gl::GenTextures(1, &mut texture);
+ gl::CreateTextures(gl::TEXTURE_2D, 1, &mut texture);
};
Self { texture }
}
- pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>))
+ pub fn bind(&self)
{
unsafe {
gl::BindTexture(gl::TEXTURE_2D, self.texture);
}
-
- // SAFETY: The buffer object is bound above
- let currently_bound = unsafe { CurrentlyBound::new() };
-
- cb(currently_bound);
}
pub fn generate(
- curr_bound: &CurrentlyBound<Self>,
- dimens: &Vec2<u32>,
+ &mut self,
+ dimens: Dimens<u32>,
data: &[u8],
pixel_data_format: PixelDataFormat,
)
{
- Self::alloc_image(curr_bound, pixel_data_format, dimens, Some(data));
+ self.alloc_image(pixel_data_format, dimens, data);
unsafe {
- gl::GenerateMipmap(gl::TEXTURE_2D);
+ gl::GenerateTextureMipmap(self.texture);
}
}
- pub fn apply_properties(&self, properties: &Properties)
+ pub fn apply_properties(&mut self, properties: &Properties)
{
- self.bind(|texture_curr_bound| {
- Texture::set_wrap(&texture_curr_bound, properties.wrap);
-
- Texture::set_magnifying_filter(
- &texture_curr_bound,
- properties.magnifying_filter,
- );
-
- Texture::set_minifying_filter(
- &texture_curr_bound,
- properties.minifying_filter,
- );
- });
+ self.set_wrap(properties.wrap);
+ self.set_magnifying_filter(properties.magnifying_filter);
+ self.set_minifying_filter(properties.minifying_filter);
}
- pub fn set_wrap(_: &CurrentlyBound<Self>, wrapping: Wrapping)
+ pub fn set_wrap(&mut self, wrapping: Wrapping)
{
let wrapping_gl = wrapping.to_gl();
#[allow(clippy::cast_possible_wrap)]
unsafe {
- gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, wrapping_gl as i32);
- gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, wrapping_gl as i32);
+ gl::TextureParameteri(self.texture, gl::TEXTURE_WRAP_S, wrapping_gl as i32);
+ gl::TextureParameteri(self.texture, gl::TEXTURE_WRAP_T, wrapping_gl as i32);
}
}
- pub fn set_magnifying_filter(_: &CurrentlyBound<Self>, filtering: Filtering)
+ pub fn set_magnifying_filter(&mut self, filtering: Filtering)
{
let filtering_gl = filtering.to_gl();
#[allow(clippy::cast_possible_wrap)]
unsafe {
- gl::TexParameteri(
- gl::TEXTURE_2D,
+ gl::TextureParameteri(
+ self.texture,
gl::TEXTURE_MAG_FILTER,
filtering_gl as i32,
);
}
}
- pub fn set_minifying_filter(_: &CurrentlyBound<Self>, filtering: Filtering)
+ pub fn set_minifying_filter(&mut self, filtering: Filtering)
{
let filtering_gl = filtering.to_gl();
#[allow(clippy::cast_possible_wrap)]
unsafe {
- gl::TexParameteri(
- gl::TEXTURE_2D,
+ gl::TextureParameteri(
+ self.texture,
gl::TEXTURE_MIN_FILTER,
filtering_gl as i32,
);
@@ -106,24 +88,33 @@ impl Texture
}
fn alloc_image(
- _: &CurrentlyBound<Self>,
+ &mut self,
pixel_data_format: PixelDataFormat,
- dimens: &Vec2<u32>,
- data: Option<&[u8]>,
+ dimens: Dimens<u32>,
+ data: &[u8],
)
{
unsafe {
#[allow(clippy::cast_possible_wrap)]
- gl::TexImage2D(
- gl::TEXTURE_2D,
+ gl::TextureStorage2D(
+ self.texture,
+ 1,
+ pixel_data_format.to_sized_internal_format(),
+ dimens.width as i32,
+ dimens.height as i32,
+ );
+
+ #[allow(clippy::cast_possible_wrap)]
+ gl::TextureSubImage2D(
+ self.texture,
+ 0,
0,
- pixel_data_format.to_gl() as i32,
- dimens.x as i32,
- dimens.y as i32,
0,
- pixel_data_format.to_gl(),
+ dimens.width as i32,
+ dimens.height as i32,
+ pixel_data_format.to_format(),
gl::UNSIGNED_BYTE,
- data.map_or_else(null, |data| data.as_ptr().cast()),
+ data.as_ptr().cast(),
);
}
}
@@ -184,17 +175,25 @@ impl Filtering
#[derive(Debug, Clone, Copy)]
pub enum PixelDataFormat
{
- Rgb,
- Rgba,
+ Rgb8,
+ Rgba8,
}
impl PixelDataFormat
{
- fn to_gl(self) -> gl::types::GLenum
+ fn to_sized_internal_format(self) -> gl::types::GLenum
+ {
+ match self {
+ Self::Rgb8 => gl::RGB8,
+ Self::Rgba8 => gl::RGBA8,
+ }
+ }
+
+ fn to_format(self) -> gl::types::GLenum
{
match self {
- Self::Rgb => gl::RGB,
- Self::Rgba => gl::RGBA,
+ Self::Rgb8 => gl::RGB,
+ Self::Rgba8 => gl::RGBA,
}
}
}
diff --git a/engine/src/opengl/vertex_array.rs b/engine/src/opengl/vertex_array.rs
index 6b6065c..e1e1a15 100644
--- a/engine/src/opengl/vertex_array.rs
+++ b/engine/src/opengl/vertex_array.rs
@@ -1,10 +1,10 @@
use std::mem::size_of;
-use crate::opengl::buffer::{ArrayKind as ArrayBufferKind, Buffer};
-use crate::opengl::currently_bound::CurrentlyBound;
-use crate::vertex::{Attribute, AttributeComponentType, Vertex};
+use crate::opengl::buffer::Buffer;
+use crate::vertex::Vertex;
-const VERTEX_STRIDE: usize = size_of::<Vertex>();
+#[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
+const VERTEX_STRIDE: i32 = size_of::<Vertex>() as i32;
#[derive(Debug)]
pub struct VertexArray
@@ -19,19 +19,14 @@ impl VertexArray
let mut array = 0;
unsafe {
- gl::GenVertexArrays(1, &mut array);
+ gl::CreateVertexArrays(1, &mut array);
}
Self { array }
}
/// Draws the currently bound vertex array.
- pub fn draw_arrays(
- _currently_bound: &CurrentlyBound<Self>,
- primitive_kind: PrimitiveKind,
- start_index: u32,
- cnt: u32,
- )
+ pub fn draw_arrays(primitive_kind: PrimitiveKind, start_index: u32, cnt: u32)
{
unsafe {
#[allow(clippy::cast_possible_wrap)]
@@ -44,12 +39,7 @@ impl VertexArray
}
/// Draws the currently bound vertex array.
- pub fn draw_elements(
- _currently_bound: &CurrentlyBound<Self>,
- primitive_kind: PrimitiveKind,
- offset: u32,
- cnt: u32,
- )
+ pub fn draw_elements(primitive_kind: PrimitiveKind, offset: u32, cnt: u32)
{
unsafe {
#[allow(clippy::cast_possible_wrap)]
@@ -62,64 +52,78 @@ impl VertexArray
}
}
- pub fn configure_attrs(
- _currently_bound: &CurrentlyBound<Self>,
- _vert_buf_curr_bound: &CurrentlyBound<Buffer<Vertex, ArrayBufferKind>>,
- )
+ pub fn bind_element_buffer(&mut self, element_buffer: &Buffer<u32>)
{
- let mut offset = 0;
-
- for attr in Vertex::attrs() {
- Self::vertex_attrib_ptr(attr, offset);
-
- Self::enable_vertex_attrib_array(attr.index);
-
- offset += attr.component_size * attr.component_cnt as usize;
+ unsafe {
+ gl::VertexArrayElementBuffer(self.array, element_buffer.object());
}
}
- #[allow(clippy::inline_always)]
- #[inline(always)]
- pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>))
+ pub fn bind_vertex_buffer(
+ &mut self,
+ binding_index: u32,
+ vertex_buffer: &Buffer<Vertex>,
+ offset: isize,
+ )
{
- unsafe { gl::BindVertexArray(self.array) }
-
- // SAFETY: A vertex array object is currently bound
- let currently_bound = unsafe { CurrentlyBound::new() };
+ unsafe {
+ gl::VertexArrayVertexBuffer(
+ self.array,
+ binding_index,
+ vertex_buffer.object(),
+ offset,
+ VERTEX_STRIDE,
+ );
+ }
+ }
- cb(currently_bound);
+ pub fn enable_attrib(&mut self, attrib_index: u32)
+ {
+ unsafe {
+ gl::EnableVertexArrayAttrib(self.array, attrib_index as gl::types::GLuint);
+ }
}
- fn vertex_attrib_ptr(vertex_attr: &Attribute, offset: usize)
+ pub fn set_attrib_format(
+ &mut self,
+ attrib_index: u32,
+ data_type: DataType,
+ normalized: bool,
+ offset: u32,
+ )
{
unsafe {
- #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)]
- gl::VertexAttribPointer(
- vertex_attr.index as gl::types::GLuint,
- vertex_attr.component_cnt as i32,
- Self::vertex_attr_type_to_gl(&vertex_attr.component_type),
- gl::FALSE,
- VERTEX_STRIDE as gl::types::GLsizei,
- offset as *const _,
+ #[allow(clippy::cast_possible_wrap)]
+ gl::VertexArrayAttribFormat(
+ self.array,
+ attrib_index,
+ data_type.size() as gl::types::GLint,
+ data_type as u32,
+ if normalized { gl::TRUE } else { gl::FALSE },
+ offset,
);
}
}
- fn enable_vertex_attrib_array(index: usize)
+ /// Associate a vertex attribute and a vertex buffer binding.
+ pub fn set_attrib_vertex_buf_binding(
+ &mut self,
+ attrib_index: u32,
+ vertex_buf_binding_index: u32,
+ )
{
unsafe {
- #[allow(clippy::cast_possible_truncation)]
- gl::EnableVertexAttribArray(index as gl::types::GLuint);
+ gl::VertexArrayAttribBinding(
+ self.array,
+ attrib_index,
+ vertex_buf_binding_index,
+ );
}
}
- fn vertex_attr_type_to_gl(
- vertex_attr_type: &AttributeComponentType,
- ) -> gl::types::GLenum
+ pub fn bind(&self)
{
- match vertex_attr_type {
- AttributeComponentType::Float => gl::FLOAT,
- }
+ unsafe { gl::BindVertexArray(self.array) }
}
}
@@ -148,3 +152,21 @@ impl PrimitiveKind
}
}
}
+
+#[derive(Debug, Clone, Copy)]
+#[repr(u32)]
+pub enum DataType
+{
+ Float = gl::FLOAT,
+}
+
+impl DataType
+{
+ pub fn size(self) -> u32
+ {
+ #[allow(clippy::cast_possible_truncation)]
+ match self {
+ Self::Float => size_of::<gl::types::GLfloat>() as u32,
+ }
+ }
+}