From 7bec16c7b9190a239189631328bc553944e25ab7 Mon Sep 17 00:00:00 2001 From: Grayson Riffe Date: Mon, 17 Feb 2025 00:24:06 -0600 Subject: [PATCH] Create first vertex buffer --- NothinFancy/res/shaders/output.vert.glsl | 19 ++--- .../src/client/render/RenderEngine.cpp | 75 ++++++++++++++++++- NothinFancy/src/client/render/RenderEngine.h | 4 + NothinFancy/src/pch.h | 3 + 4 files changed, 87 insertions(+), 14 deletions(-) diff --git a/NothinFancy/res/shaders/output.vert.glsl b/NothinFancy/res/shaders/output.vert.glsl index 4f7b59f..357b4f9 100644 --- a/NothinFancy/res/shaders/output.vert.glsl +++ b/NothinFancy/res/shaders/output.vert.glsl @@ -1,20 +1,13 @@ #version 450 -vec2 trianglePositions[3] = vec2[] ( - vec2(0.0, -0.5), - vec2(0.5, 0.5), - vec2(-0.5, 0.5) -); - -vec3 triangleColors[3] = vec3[] ( - vec3(1.0, 0.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, 1.0) -); +// Inputs +layout(location = 0) in vec2 inPosition; +layout(location = 1) in vec3 inColor; +// Outputs layout(location = 0) out vec3 fragColor; void main() { - fragColor = triangleColors[gl_VertexIndex]; - gl_Position = vec4(trianglePositions[gl_VertexIndex], 0.0, 1.0); + fragColor = inColor; + gl_Position = vec4(inPosition, 0.0, 1.0); } diff --git a/NothinFancy/src/client/render/RenderEngine.cpp b/NothinFancy/src/client/render/RenderEngine.cpp index 8ea9b0d..8e2b961 100644 --- a/NothinFancy/src/client/render/RenderEngine.cpp +++ b/NothinFancy/src/client/render/RenderEngine.cpp @@ -6,6 +6,12 @@ #include "ShaderModule.h" namespace nf::client::render { + // Vertex layout definition + struct Vertex { + glm::vec2 position; + glm::vec3 color; + }; + RenderEngine::RenderEngine(std::shared_ptr window, DisplayConfig display) : m_window(window) , m_display(display) @@ -30,6 +36,8 @@ namespace nf::client::render { , m_numFramesInFlight(2) , m_frameExecutors() , m_currentFrameExecutor() + , m_bufferVertex() + , m_memoryVertexBuffer() { NFLog("Initializing render engine"); m_window->setDisplay(m_display); @@ -42,6 +50,7 @@ namespace nf::client::render { createOutputRenderPass(); createSwapchainFramebuffers(); createOutputPipeline(); + createVertexBuffer(); createFrameExecutors(); m_window->show(); @@ -333,13 +342,26 @@ namespace nf::client::render { outputShaderStages[1].module = outputShaderFragmentModule.getHandle(); // Specify dynamic state - std::vector dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dynamicStateCI = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + std::vector dynamicStates = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; dynamicStateCI.dynamicStateCount = dynamicStates.size(); dynamicStateCI.pDynamicStates = dynamicStates.data(); // Specify vertex input state VkPipelineVertexInputStateCreateInfo vertexInputStateCI = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; + VkVertexInputBindingDescription vertexBindingDescription = {}; + vertexBindingDescription.stride = sizeof(Vertex); + std::array vertexAttributeDescriptions = {}; + vertexAttributeDescriptions[0].location = 0; + vertexAttributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT; + vertexAttributeDescriptions[0].offset = offsetof(Vertex, position); + vertexAttributeDescriptions[1].location = 1; + vertexAttributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; + vertexAttributeDescriptions[1].offset = offsetof(Vertex, color); + vertexInputStateCI.vertexBindingDescriptionCount = 1; + vertexInputStateCI.pVertexBindingDescriptions = &vertexBindingDescription; + vertexInputStateCI.vertexAttributeDescriptionCount = vertexAttributeDescriptions.size(); + vertexInputStateCI.pVertexAttributeDescriptions = vertexAttributeDescriptions.data(); // Specify input assembly state VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; @@ -391,6 +413,50 @@ namespace nf::client::render { NFError("Could not create graphics pipeline."); } + void RenderEngine::createVertexBuffer() { + std::vector triangleData = { + {{0.0, -0.5}, {1.0, 0.0, 0.0}}, + {{0.5, 0.5}, {0.0, 1.0, 0.0}}, + {{-0.5, 0.5}, {0.0, 0.0, 1.0}} + }; + + VkBufferCreateInfo bufferCI = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + bufferCI.size = sizeof(triangleData[0]) * triangleData.size(); + bufferCI.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + + if (vkCreateBuffer(m_device, &bufferCI, nullptr, &m_bufferVertex) != VK_SUCCESS) + NFError("Could not create vertex buffer."); + + VkMemoryRequirements memoryRequirements = {}; + vkGetBufferMemoryRequirements(m_device, m_bufferVertex, &memoryRequirements); + + VkPhysicalDeviceMemoryProperties memoryProperties = {}; + vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &memoryProperties); + + VkMemoryPropertyFlags properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + std::optional memoryTypeIndex; + for (int i = 0; i < memoryProperties.memoryTypeCount; i++) + if (memoryRequirements.memoryTypeBits & (1 << i) && (memoryProperties.memoryTypes[i].propertyFlags & properties) == properties) + memoryTypeIndex = i; + + if (!memoryTypeIndex.has_value()) + NFError("Could not find suitable memory type."); + + VkMemoryAllocateInfo allocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + allocateInfo.allocationSize = memoryRequirements.size; + allocateInfo.memoryTypeIndex = memoryTypeIndex.value(); + + if (vkAllocateMemory(m_device, &allocateInfo, nullptr, &m_memoryVertexBuffer) != VK_SUCCESS) + NFError("Could not allocate video memory."); + + vkBindBufferMemory(m_device, m_bufferVertex, m_memoryVertexBuffer, 0); + + void* bufferPointer = nullptr; + vkMapMemory(m_device, m_memoryVertexBuffer, 0, bufferCI.size, 0, &bufferPointer); + std::memcpy(bufferPointer, triangleData.data(), bufferCI.size); + vkUnmapMemory(m_device, m_memoryVertexBuffer); + } + void RenderEngine::createFrameExecutors() { VkCommandPoolCreateInfo commandPoolCI = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; commandPoolCI.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; @@ -467,6 +533,10 @@ namespace nf::client::render { VkRect2D scissor = { {}, m_swapchainExtent }; vkCmdSetScissor(commandBuffer, 0, 1, &scissor); + // Bind vertex buffer + VkDeviceSize vertexBufferOffset = 0; + vkCmdBindVertexBuffers(commandBuffer, 0, 1, &m_bufferVertex, &vertexBufferOffset); + // Draw vkCmdDraw(commandBuffer, 3, 1, 0, 0); @@ -546,6 +616,9 @@ namespace nf::client::render { vkDestroySemaphore(m_device, m_frameExecutors[i].semaphoreImageAvailable, nullptr); } + vkFreeMemory(m_device, m_memoryVertexBuffer, nullptr); + vkDestroyBuffer(m_device, m_bufferVertex, nullptr); + destroySwapchain(); vkDestroyCommandPool(m_device, m_commandPool, nullptr); vkDestroyPipeline(m_device, m_pipelineOutput, nullptr); diff --git a/NothinFancy/src/client/render/RenderEngine.h b/NothinFancy/src/client/render/RenderEngine.h index 456459f..ee89fac 100644 --- a/NothinFancy/src/client/render/RenderEngine.h +++ b/NothinFancy/src/client/render/RenderEngine.h @@ -28,6 +28,7 @@ namespace nf::client::render { void createOutputRenderPass(); void createSwapchainFramebuffers(); void createOutputPipeline(); + void createVertexBuffer(); void createFrameExecutors(); void recreateSwapchain(); @@ -64,5 +65,8 @@ namespace nf::client::render { const uint32_t m_numFramesInFlight; std::vector m_frameExecutors; uint32_t m_currentFrameExecutor; + + VkBuffer m_bufferVertex; + VkDeviceMemory m_memoryVertexBuffer; }; } diff --git a/NothinFancy/src/pch.h b/NothinFancy/src/pch.h index f907c21..723622e 100644 --- a/NothinFancy/src/pch.h +++ b/NothinFancy/src/pch.h @@ -42,3 +42,6 @@ // Vulkan #define VK_USE_PLATFORM_WIN32_KHR #include + +// GLM +#include