From 341826e9a2b89713fc47ffbc914d18e23c7d9287 Mon Sep 17 00:00:00 2001 From: HampusM Date: Thu, 12 Oct 2023 21:29:36 +0200 Subject: feat(engine): add vertex coloring --- engine/fragment.glsl | 4 +- engine/src/color.rs | 8 +++ engine/src/lib.rs | 2 + engine/src/object.rs | 3 +- engine/src/renderer/mod.rs | 35 ++---------- engine/src/renderer/vertex_array.rs | 51 +++++++++++++++++ engine/src/renderer/vertex_buffers.rs | 4 +- engine/src/vector.rs | 9 +++ engine/src/vertex.rs | 101 ++++++++++++++++++++++++++++++++++ engine/vertex.glsl | 9 ++- 10 files changed, 190 insertions(+), 36 deletions(-) create mode 100644 engine/src/color.rs create mode 100644 engine/src/vertex.rs (limited to 'engine') diff --git a/engine/fragment.glsl b/engine/fragment.glsl index 0c56a32..8b209c4 100644 --- a/engine/fragment.glsl +++ b/engine/fragment.glsl @@ -1,7 +1,9 @@ #version 330 core out vec4 FragColor; +in vec3 in_frag_color; + void main() { - FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); + FragColor = vec4(in_frag_color, 1.0); } diff --git a/engine/src/color.rs b/engine/src/color.rs new file mode 100644 index 0000000..339b427 --- /dev/null +++ b/engine/src/color.rs @@ -0,0 +1,8 @@ +#[derive(Debug, Clone)] +#[repr(C)] +pub struct Color +{ + pub red: Value, + pub green: Value, + pub blue: Value, +} diff --git a/engine/src/lib.rs b/engine/src/lib.rs index ebb635f..b93a0bb 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -9,8 +9,10 @@ use crate::vector::Vec2; mod renderer; mod shader; +pub mod color; pub mod object; pub mod vector; +pub mod vertex; #[derive(Debug)] pub struct Engine diff --git a/engine/src/object.rs b/engine/src/object.rs index d1ac859..6b4bf4e 100644 --- a/engine/src/object.rs +++ b/engine/src/object.rs @@ -1,5 +1,6 @@ use crate::renderer::Renderable; use crate::shader::{Kind as ShaderKind, Program as ShaderProgram, Shader}; +use crate::vertex::Vertex; #[derive(Debug)] pub struct Object @@ -13,7 +14,7 @@ impl Object /// /// # Errors /// Will return `Err` if shader creation fails or if shader program linking fails. - pub fn new(vertices: &[f32]) -> Result + pub fn new(vertices: &[Vertex]) -> Result { let vertex_shader = Shader::new(ShaderKind::Vertex); diff --git a/engine/src/renderer/mod.rs b/engine/src/renderer/mod.rs index 13091fd..bbcb5e9 100644 --- a/engine/src/renderer/mod.rs +++ b/engine/src/renderer/mod.rs @@ -1,13 +1,12 @@ -use std::ffi::{c_float, c_void, CString}; -use std::mem::size_of; +use std::ffi::{c_void, CString}; use std::process::abort; -use std::ptr::null; use glfw::WindowSize; use crate::renderer::vertex_array::{PrimitiveKind, VertexArray}; use crate::renderer::vertex_buffers::{BufferUsage, VertexBuffers}; use crate::vector::Vec2; +use crate::vertex::Vertex; mod vertex_array; mod vertex_buffers; @@ -62,7 +61,7 @@ pub struct Renderable impl Renderable { - pub fn new(shader_program: crate::shader::Program, vertices: &[f32]) -> Self + pub fn new(shader_program: crate::shader::Program, vertices: &[Vertex]) -> Self { let vertex_arr = VertexArray::new(); @@ -74,8 +73,7 @@ impl Renderable .store(0, vertices, BufferUsage::Static) .unwrap(); - vertex_attrib_ptr(0); - enable_vertex_attrib_array(0); + VertexArray::configure_attrs(); Self { shader_program, @@ -105,28 +103,3 @@ pub enum Error #[error("Failed to get window size")] GetWindowSizeFailed(#[source] glfw::Error), } - -fn vertex_attrib_ptr(index: usize) -{ - let stride = 3 * size_of::(); - - unsafe { - #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] - gl::VertexAttribPointer( - index as gl::types::GLuint, - 3, - gl::FLOAT, - gl::FALSE, - stride as gl::types::GLsizei, - null(), - ); - } -} - -fn enable_vertex_attrib_array(index: usize) -{ - unsafe { - #[allow(clippy::cast_possible_truncation)] - gl::EnableVertexAttribArray(index as gl::types::GLuint); - } -} diff --git a/engine/src/renderer/vertex_array.rs b/engine/src/renderer/vertex_array.rs index 5862c7b..b0aac81 100644 --- a/engine/src/renderer/vertex_array.rs +++ b/engine/src/renderer/vertex_array.rs @@ -1,3 +1,9 @@ +use std::mem::size_of; + +use crate::vertex::{Attribute, AttributeComponentType, Vertex}; + +const VERTEX_STRIDE: usize = size_of::(); + #[derive(Debug)] pub struct VertexArray { @@ -31,10 +37,55 @@ impl VertexArray } } + pub fn configure_attrs() + { + 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; + } + } + pub fn bind(&self) { unsafe { gl::BindVertexArray(self.array) } } + + fn vertex_attrib_ptr(vertex_attr: &Attribute, offset: usize) + { + 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 _, + ); + } + } + + fn enable_vertex_attrib_array(index: usize) + { + unsafe { + #[allow(clippy::cast_possible_truncation)] + gl::EnableVertexAttribArray(index as gl::types::GLuint); + } + } + + fn vertex_attr_type_to_gl( + vertex_attr_type: &AttributeComponentType, + ) -> gl::types::GLenum + { + match vertex_attr_type { + AttributeComponentType::Float => gl::FLOAT, + } + } } impl Drop for VertexArray diff --git a/engine/src/renderer/vertex_buffers.rs b/engine/src/renderer/vertex_buffers.rs index bb988d9..e7cba91 100644 --- a/engine/src/renderer/vertex_buffers.rs +++ b/engine/src/renderer/vertex_buffers.rs @@ -1,5 +1,7 @@ use std::mem::size_of_val; +use crate::vertex::Vertex; + #[derive(Debug)] pub struct VertexBuffers { @@ -23,7 +25,7 @@ impl VertexBuffers pub fn store( &self, buffer_index: usize, - vertices: &[f32], + vertices: &[Vertex], usage: BufferUsage, ) -> Option<()> { diff --git a/engine/src/vector.rs b/engine/src/vector.rs index 48550fa..ada64c4 100644 --- a/engine/src/vector.rs +++ b/engine/src/vector.rs @@ -9,3 +9,12 @@ impl Vec2 { pub const ZERO: Self = Self { x: 0, y: 0 }; } + +#[derive(Debug)] +#[repr(C)] +pub struct Vec3 +{ + pub x: Value, + pub y: Value, + pub z: Value, +} diff --git a/engine/src/vertex.rs b/engine/src/vertex.rs new file mode 100644 index 0000000..e03eacb --- /dev/null +++ b/engine/src/vertex.rs @@ -0,0 +1,101 @@ +use std::mem::size_of; + +use crate::color::Color; +use crate::vector::Vec3; + +#[derive(Debug)] +#[repr(C)] +pub struct Vertex +{ + pos: Vec3, + color: Color, +} + +#[derive(Debug, Default)] +pub struct Builder +{ + pos: Option>, + color: Option>, +} + +impl Builder +{ + #[must_use] + pub fn new() -> Self + { + Self { + pos: None, + color: None, + } + } + + #[must_use] + pub fn pos(mut self, pos: Vec3) -> Self + { + self.pos = Some(pos); + + self + } + + #[must_use] + pub fn color(mut self, color: Color) -> Self + { + self.color = Some(color); + + self + } + + #[must_use] + pub fn build(self) -> Option + { + let pos = self.pos?; + let color = self.color?; + + Some(Vertex { pos, color }) + } +} + +impl Vertex +{ + pub(crate) fn attrs() -> &'static [Attribute] + { + &[ + Attribute { + index: 0, + component_type: AttributeComponentType::Float, + component_cnt: AttributeComponentCnt::Three, + component_size: size_of::(), + }, + Attribute { + index: 1, + component_type: AttributeComponentType::Float, + component_cnt: AttributeComponentCnt::Three, + component_size: size_of::(), + }, + ] + } +} + +pub(crate) struct Attribute +{ + pub(crate) index: usize, + pub(crate) component_type: AttributeComponentType, + pub(crate) component_cnt: AttributeComponentCnt, + pub(crate) component_size: usize, +} + +pub(crate) enum AttributeComponentType +{ + Float, +} + +#[derive(Debug, Clone, Copy)] +#[repr(u32)] +#[allow(dead_code)] +pub(crate) enum AttributeComponentCnt +{ + One = 1, + Two = 2, + Three = 3, + Four = 4, +} diff --git a/engine/vertex.glsl b/engine/vertex.glsl index c74ea10..37d5677 100644 --- a/engine/vertex.glsl +++ b/engine/vertex.glsl @@ -1,7 +1,12 @@ #version 330 core -layout (location = 0) in vec3 aPos; +layout (location = 0) in vec3 pos; +layout (location = 1) in vec3 color; + +out vec3 in_frag_color; void main() { - gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); + gl_Position = vec4(pos.x, pos.y, pos.z, 1.0); + + in_frag_color = color; } -- cgit v1.2.3-18-g5258