From 07b384a6c771e827057d9320509446c4b8d02aee Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Fri, 15 Mar 2024 14:31:47 +0900 Subject: [PATCH] WIP "Vertex buffers: Vertex input description" TODO: "Vertex buffer creation" https://vulkan-tutorial.com/Vertex_buffers/Vertex_buffer_creation Note that triangle drawing doesn't work at this stage. --- shaders/shader.vert | 19 ++------ src/main.rs | 30 ++++++------ src/math3d.rs | 111 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 28 deletions(-) create mode 100644 src/math3d.rs diff --git a/shaders/shader.vert b/shaders/shader.vert index 5d75bc5..9f27f54 100644 --- a/shaders/shader.vert +++ b/shaders/shader.vert @@ -1,20 +1,11 @@ #version 450 +layout(location = 0) in vec2 inPosition; +layout(location = 1) in vec3 inColor; + layout(location = 0) out vec3 fragColor; -vec2 positions[3] = vec2[]( - vec2( 0.0, -0.5), - vec2( 0.5, 0.5), - vec2(-0.5, 0.5) -); - -vec3 colors[3] = vec3[]( - vec3(1.0, 0.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, 1.0) -); - void main() { - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); - fragColor = colors[gl_VertexIndex]; + gl_Position = vec4(inPosition, 0.0, 1.0); + fragColor = inColor; } diff --git a/src/main.rs b/src/main.rs index 1da8aa5..a848b7f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,11 @@ mod ffi; +mod math3d; use std::collections::HashSet; use std::ffi::{c_void, CStr, CString}; +use math3d::Vertex; + const WINDOW_WIDTH: i32 = 800; const WINDOW_HEIGHT: i32 = 600; @@ -926,7 +929,19 @@ impl VulkanApp { let shader_stages: [ffi::VkPipelineShaderStageCreateInfo; 2] = [vert_shader_stage_info, frag_shader_stage_info]; - let vertex_input_info = Self::create_vertex_input_state_info_struct(); + let mut vertex_input_info: ffi::VkPipelineVertexInputStateCreateInfo = + unsafe { std::mem::zeroed() }; + vertex_input_info.sType = + ffi::VkStructureType_VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + + let bind_desc = Vertex::get_binding_description(); + let attr_descs = Vertex::get_attribute_descriptions(); + + vertex_input_info.vertexBindingDescriptionCount = 1; + vertex_input_info.vertexAttributeDescriptionCount = attr_descs.len() as u32; + + vertex_input_info.pVertexBindingDescriptions = std::ptr::addr_of!(bind_desc); + vertex_input_info.pVertexAttributeDescriptions = attr_descs.as_ptr(); let mut input_assembly: ffi::VkPipelineInputAssemblyStateCreateInfo = unsafe { std::mem::zeroed() }; @@ -1074,19 +1089,6 @@ impl VulkanApp { dynamic_state } - fn create_vertex_input_state_info_struct() -> ffi::VkPipelineVertexInputStateCreateInfo { - let mut vertex_input_info: ffi::VkPipelineVertexInputStateCreateInfo = - unsafe { std::mem::zeroed() }; - vertex_input_info.sType = - ffi::VkStructureType_VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.vertexBindingDescriptionCount = 0; - vertex_input_info.pVertexBindingDescriptions = std::ptr::null(); - vertex_input_info.vertexAttributeDescriptionCount = 0; - vertex_input_info.pVertexBindingDescriptions = std::ptr::null(); - - vertex_input_info - } - fn create_viewport(&self) -> ffi::VkViewport { let mut viewport: ffi::VkViewport = unsafe { std::mem::zeroed() }; viewport.x = 0.0; diff --git a/src/math3d.rs b/src/math3d.rs new file mode 100644 index 0000000..381a175 --- /dev/null +++ b/src/math3d.rs @@ -0,0 +1,111 @@ +use crate::ffi; + +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct Vertex { + pos: [f32; 2], + color: [f32; 3], +} + +impl Default for Vertex { + fn default() -> Self { + Self { + pos: [0.0, 0.0], + color: [0.0, 0.0, 0.0], + } + } +} + +impl Vertex { + pub fn pos_offset() -> usize { + 0 + } + + pub fn color_offset() -> usize { + let mut offset = std::mem::size_of::<[f32; 2]>(); + let alignment = std::mem::align_of::<[f32; 3]>(); + while offset % alignment != 0 { + offset += 1; + } + + offset + } + + pub fn get_binding_description() -> ffi::VkVertexInputBindingDescription { + let mut bind_desc: ffi::VkVertexInputBindingDescription = unsafe { std::mem::zeroed() }; + + bind_desc.binding = 0; + bind_desc.stride = std::mem::size_of::() as u32; + bind_desc.inputRate = ffi::VkVertexInputRate_VK_VERTEX_INPUT_RATE_VERTEX; + + bind_desc + } + + pub fn get_attribute_descriptions() -> [ffi::VkVertexInputAttributeDescription; 2] { + let mut attr_descs: [ffi::VkVertexInputAttributeDescription; 2] = + unsafe { std::mem::zeroed() }; + + attr_descs[0].binding = 0; + attr_descs[0].location = 0; + attr_descs[0].format = ffi::VkFormat_VK_FORMAT_R32G32_SFLOAT; + attr_descs[0].offset = Self::pos_offset() as u32; + + attr_descs[1].binding = 0; + attr_descs[1].location = 1; + attr_descs[1].format = ffi::VkFormat_VK_FORMAT_R32G32B32_SFLOAT; + attr_descs[1].offset = Self::color_offset() as u32; + + attr_descs + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn offsets() { + let mut vertex = Vertex { + pos: [1.0, 2.0], + color: [3.0, 4.0, 5.0], + }; + + let root_ptr: *const f32 = &vertex as *const Vertex as *const f32; + + let pos_offset = Vertex::pos_offset(); + assert!(pos_offset + 4 <= std::mem::size_of::()); + + let pos_0_ptr = unsafe { root_ptr.byte_add(pos_offset) }; + assert_eq!(unsafe { *pos_0_ptr }, vertex.pos[0]); + + assert!(pos_offset + 8 <= std::mem::size_of::()); + let pos_1_ptr = unsafe { root_ptr.byte_add(pos_offset + 4) }; + assert_eq!(unsafe { *pos_1_ptr }, vertex.pos[1]); + + let color_offset = Vertex::color_offset(); + assert!(color_offset + 4 <= std::mem::size_of::()); + + let col_0_ptr = unsafe { root_ptr.byte_add(color_offset) }; + assert_eq!(unsafe { *col_0_ptr }, vertex.color[0]); + + assert!(color_offset + 8 <= std::mem::size_of::()); + let col_1_ptr = unsafe { root_ptr.byte_add(color_offset + 4) }; + assert_eq!(unsafe { *col_1_ptr }, vertex.color[1]); + + assert!(color_offset + 12 <= std::mem::size_of::()); + let col_2_ptr = unsafe { root_ptr.byte_add(color_offset + 8) }; + assert_eq!(unsafe { *col_2_ptr }, vertex.color[2]); + + vertex.pos[0] = 0.123; + vertex.pos[1] = 0.456; + vertex.color[0] = 0.789; + vertex.color[1] = 1.234; + vertex.color[2] = 1.567; + + assert_eq!(unsafe { *pos_0_ptr }, vertex.pos[0]); + assert_eq!(unsafe { *pos_1_ptr }, vertex.pos[1]); + assert_eq!(unsafe { *col_0_ptr }, vertex.color[0]); + assert_eq!(unsafe { *col_1_ptr }, vertex.color[1]); + assert_eq!(unsafe { *col_2_ptr }, vertex.color[2]); + } +}