summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-10-23 20:25:42 +0200
committerHampusM <hampus@hampusmat.com>2023-10-23 20:25:42 +0200
commitc12966c5b69841f49713f97f3d9fa7ba99fc42e7 (patch)
tree8a445fca96bf893d45f7d816c5aca24a5d72354c
parentbd427836bfa6f7228951c18e43058d3e35577702 (diff)
feat(engine): add using element buffers
-rw-r--r--engine/src/object.rs8
-rw-r--r--engine/src/opengl/buffer.rs37
-rw-r--r--engine/src/opengl/vertex_array.rs29
-rw-r--r--engine/src/renderer/mod.rs59
4 files changed, 115 insertions, 18 deletions
diff --git a/engine/src/object.rs b/engine/src/object.rs
index c3d82d0..02ae97a 100644
--- a/engine/src/object.rs
+++ b/engine/src/object.rs
@@ -23,7 +23,11 @@ impl Object
///
/// # Errors
/// Will return `Err` if shader creation fails or if shader program linking fails.
- pub fn new(id: Id, vertices: &[Vertex]) -> Result<Self, Error>
+ pub fn new(
+ id: Id,
+ vertices: &[Vertex],
+ indices: Option<&[u32]>,
+ ) -> Result<Self, Error>
{
let vertex_shader = Shader::new(ShaderKind::Vertex);
@@ -54,7 +58,7 @@ impl Object
.link()
.map_err(Error::LinkShaderProgramFailed)?;
- let renderable = Renderable::new(shader_program, vertices);
+ let renderable = Renderable::new(shader_program, vertices, indices);
let transform = Transform::new();
diff --git a/engine/src/opengl/buffer.rs b/engine/src/opengl/buffer.rs
index 34514fd..3a4ecf0 100644
--- a/engine/src/opengl/buffer.rs
+++ b/engine/src/opengl/buffer.rs
@@ -4,13 +4,14 @@ use std::mem::size_of_val;
use crate::opengl::currently_bound::CurrentlyBound;
#[derive(Debug)]
-pub struct Buffer<Item>
+pub struct Buffer<Item, ModeT: Mode>
{
buffer: gl::types::GLuint,
_item_pd: PhantomData<Item>,
+ _mode_pd: PhantomData<ModeT>,
}
-impl<Item> Buffer<Item>
+impl<Item, ModeT: Mode> Buffer<Item, ModeT>
{
pub fn new() -> Self
{
@@ -23,6 +24,7 @@ impl<Item> Buffer<Item>
Self {
buffer,
_item_pd: PhantomData,
+ _mode_pd: PhantomData,
}
}
@@ -31,7 +33,7 @@ impl<Item> Buffer<Item>
pub fn bind(&self, cb: impl FnOnce(CurrentlyBound<'_, Self>))
{
unsafe {
- gl::BindBuffer(gl::ARRAY_BUFFER, self.buffer);
+ gl::BindBuffer(ModeT::GL_ENUM, self.buffer);
}
// SAFETY: The buffer object is bound above
@@ -46,7 +48,7 @@ impl<Item> Buffer<Item>
unsafe {
#[allow(clippy::cast_possible_wrap)]
gl::BufferData(
- gl::ARRAY_BUFFER,
+ ModeT::GL_ENUM,
size_of_val(items) as gl::types::GLsizeiptr,
items.as_ptr().cast(),
usage.into_gl(),
@@ -55,7 +57,7 @@ impl<Item> Buffer<Item>
}
}
-impl<Item> Drop for Buffer<Item>
+impl<Item, ModeT: Mode> Drop for Buffer<Item, ModeT>
{
fn drop(&mut self)
{
@@ -92,3 +94,28 @@ 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/vertex_array.rs b/engine/src/opengl/vertex_array.rs
index ba2ded2..6b6065c 100644
--- a/engine/src/opengl/vertex_array.rs
+++ b/engine/src/opengl/vertex_array.rs
@@ -1,6 +1,6 @@
use std::mem::size_of;
-use crate::opengl::buffer::Buffer;
+use crate::opengl::buffer::{ArrayKind as ArrayBufferKind, Buffer};
use crate::opengl::currently_bound::CurrentlyBound;
use crate::vertex::{Attribute, AttributeComponentType, Vertex};
@@ -26,11 +26,11 @@ impl VertexArray
}
/// Draws the currently bound vertex array.
- pub fn draw(
+ pub fn draw_arrays(
_currently_bound: &CurrentlyBound<Self>,
primitive_kind: PrimitiveKind,
start_index: u32,
- index_cnt: u32,
+ cnt: u32,
)
{
unsafe {
@@ -38,14 +38,33 @@ impl VertexArray
gl::DrawArrays(
primitive_kind.into_gl(),
start_index as gl::types::GLint,
- index_cnt as gl::types::GLsizei,
+ cnt as gl::types::GLsizei,
+ );
+ }
+ }
+
+ /// Draws the currently bound vertex array.
+ pub fn draw_elements(
+ _currently_bound: &CurrentlyBound<Self>,
+ primitive_kind: PrimitiveKind,
+ offset: u32,
+ cnt: u32,
+ )
+ {
+ unsafe {
+ #[allow(clippy::cast_possible_wrap)]
+ gl::DrawElements(
+ primitive_kind.into_gl(),
+ cnt as gl::types::GLsizei,
+ gl::UNSIGNED_INT,
+ (offset as gl::types::GLint) as *const _,
);
}
}
pub fn configure_attrs(
_currently_bound: &CurrentlyBound<Self>,
- _vert_buf_curr_bound: &CurrentlyBound<Buffer<Vertex>>,
+ _vert_buf_curr_bound: &CurrentlyBound<Buffer<Vertex, ArrayBufferKind>>,
)
{
let mut offset = 0;
diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs
index f31196d..a02bbc2 100644
--- a/engine/src/renderer/mod.rs
+++ b/engine/src/renderer/mod.rs
@@ -5,7 +5,12 @@ use cstr::cstr;
use glfw::WindowSize;
use crate::object::Object;
-use crate::opengl::buffer::{Buffer, Usage};
+use crate::opengl::buffer::{
+ ArrayKind as ArrayBufferKind,
+ Buffer,
+ ElementArrayKind as ElementArrayBufferKind,
+ Usage as BufferUsage,
+};
#[cfg(feature = "debug")]
use crate::opengl::debug::{MessageSeverity, MessageSource, MessageType};
use crate::opengl::shader::Program as ShaderProgram;
@@ -106,7 +111,21 @@ pub fn render<'obj>(objects: impl IntoIterator<Item = &'obj Object>)
.set_uniform_matrix_4fv(cstr!("transform"), &obj.transform().as_matrix());
obj.renderable().vertex_arr.bind(|vert_arr_curr_bound| {
- VertexArray::draw(&vert_arr_curr_bound, PrimitiveKind::Triangles, 0, 3);
+ if let Some(index_info) = &obj.renderable().index_info {
+ VertexArray::draw_elements(
+ &vert_arr_curr_bound,
+ PrimitiveKind::Triangles,
+ 0,
+ index_info.cnt,
+ );
+ } else {
+ VertexArray::draw_arrays(
+ &vert_arr_curr_bound,
+ PrimitiveKind::Triangles,
+ 0,
+ 3,
+ );
+ }
});
}
}
@@ -122,29 +141,57 @@ pub struct Renderable
shader_program: ShaderProgram,
vertex_arr: VertexArray,
- /// Vertex buffer has to live as long as the vertex array
- _vertex_buffer: Buffer<Vertex>,
+ /// Vertex and index buffer has to live as long as the vertex array
+ _vertex_buffer: Buffer<Vertex, ArrayBufferKind>,
+ index_info: Option<IndexInfo>,
+}
+
+#[derive(Debug)]
+struct IndexInfo
+{
+ _buffer: Buffer<u32, ElementArrayBufferKind>,
+ cnt: u32,
}
impl Renderable
{
- pub fn new(shader_program: ShaderProgram, vertices: &[Vertex]) -> Self
+ pub fn new(
+ shader_program: ShaderProgram,
+ vertices: &[Vertex],
+ indices: Option<&[u32]>,
+ ) -> Self
{
let vertex_arr = VertexArray::new();
let vertex_buffer = Buffer::new();
+ let mut index_info = None;
+
vertex_arr.bind(|vert_arr_curr_bound| {
vertex_buffer.bind(|vert_buf_curr_bound| {
- Buffer::store(&vert_buf_curr_bound, vertices, Usage::Static);
+ Buffer::store(&vert_buf_curr_bound, vertices, BufferUsage::Static);
VertexArray::configure_attrs(&vert_arr_curr_bound, &vert_buf_curr_bound);
});
+
+ if let Some(indices) = indices {
+ let new_index_buffer = Buffer::new();
+
+ new_index_buffer.bind(|index_buf_curr_bound| {
+ Buffer::store(&index_buf_curr_bound, indices, BufferUsage::Static);
+ });
+
+ index_info = Some(IndexInfo {
+ _buffer: new_index_buffer,
+ cnt: indices.len().try_into().unwrap(),
+ });
+ }
});
Self {
shader_program,
vertex_arr,
_vertex_buffer: vertex_buffer,
+ index_info,
}
}
}