Vertex buffer input description & creation

This commit is contained in:
Mars 2024-10-09 23:00:45 -04:00
parent 1eade711ba
commit 31b93deecb
Signed by: pupbrained
GPG key ID: 874E22DF2F9DFCB5
4 changed files with 95 additions and 20 deletions

View file

@ -7,6 +7,7 @@ Checks: >
-bugprone-implicit-widening-of-multiplication-result,
-cert-env33-c,
-concurrency-mt-unsafe,
-cppcoreguidelines-avoid-const-or-ref-data-members,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-pro-type-member-init,

View file

@ -1,5 +1,6 @@
#include <fmt/format.h>
#include <fstream>
#include <glm/glm.hpp>
#include <iostream>
#include <set>
@ -76,9 +77,45 @@ class VulkanApp {
std::vector<vk::UniqueSemaphore> mRenderFinishedSemaphores;
std::vector<vk::UniqueFence> mInFlightFences;
vk::UniqueBuffer mVertexBuffer;
vk::UniqueDeviceMemory mVertexBufferMemory;
bool mFramebufferResized = false;
u32 mCurrentFrame = 0;
struct Vertex {
glm::vec2 pos;
glm::vec3 color;
static fn getBindingDescription() -> vk::VertexInputBindingDescription {
vk::VertexInputBindingDescription bindingDescription { .binding = 0,
.stride = sizeof(Vertex),
.inputRate = vk::VertexInputRate::eVertex };
return bindingDescription;
}
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 2> {
std::array<vk::VertexInputAttributeDescription, 2> attributeDescriptions {};
attributeDescriptions[0] = {
.location = 0, .binding = 0, .format = vk::Format::eR32G32Sfloat, .offset = offsetof(Vertex, pos)
};
attributeDescriptions[1] = {
.location = 1, .binding = 0, .format = vk::Format::eR32G32B32Sfloat, .offset = offsetof(Vertex, color)
};
return attributeDescriptions;
}
};
const std::vector<Vertex> mVertices = {
{ { 0.0F, -0.5F }, { 1.0F, 1.0F, 1.0F } },
{ { 0.5F, 0.5F }, { 0.0F, 1.0F, 0.0F } },
{ { -0.5F, 0.5F }, { 0.0F, 0.0F, 1.0F } }
};
struct QueueFamilyIndices {
std::optional<u32> graphics_family;
std::optional<u32> present_family;
@ -115,7 +152,6 @@ class VulkanApp {
vkfw::WindowHints hints;
hints.clientAPI = vkfw::ClientAPI::eNone;
// hints.resizable = false;
mWindow = vkfw::createWindowUnique(WIDTH, HEIGHT, "Vulkan", hints);
mWindow->setUserPointer(this);
@ -140,6 +176,7 @@ class VulkanApp {
createGraphicsPipeline();
createFramebuffers();
createCommandPool();
createVertexBuffer();
createCommandBuffers();
createSyncObjects();
}
@ -422,11 +459,15 @@ class VulkanApp {
std::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = { vertShaderStageInfo,
fragShaderStageInfo };
vk::VertexInputBindingDescription bindingDescription = Vertex::getBindingDescription();
std::array<vk::VertexInputAttributeDescription, 2> attributeDescriptions =
Vertex::getAttributeDescriptions();
vk::PipelineVertexInputStateCreateInfo vertexInputInfo {
.vertexBindingDescriptionCount = 0,
.pVertexBindingDescriptions = nullptr,
.vertexAttributeDescriptionCount = 0,
.pVertexAttributeDescriptions = nullptr,
.vertexBindingDescriptionCount = 1,
.pVertexBindingDescriptions = &bindingDescription,
.vertexAttributeDescriptionCount = static_cast<u32>(attributeDescriptions.size()),
.pVertexAttributeDescriptions = attributeDescriptions.data(),
};
vk::PipelineInputAssemblyStateCreateInfo inputAssembly {
@ -536,6 +577,45 @@ class VulkanApp {
mCommandPool = mDevice->createCommandPoolUnique(poolInfo);
}
fn createVertexBuffer() -> void {
vk::BufferCreateInfo bufferInfo {
.size = sizeof(mVertices[0]) * mVertices.size(),
.usage = vk::BufferUsageFlagBits::eVertexBuffer,
.sharingMode = vk::SharingMode::eExclusive,
};
mVertexBuffer = mDevice->createBufferUnique(bufferInfo, nullptr);
vk::MemoryRequirements memRequirements = mDevice->getBufferMemoryRequirements(mVertexBuffer.get());
vk::MemoryAllocateInfo allocInfo {
.allocationSize = memRequirements.size,
.memoryTypeIndex = findMemoryType(
memRequirements.memoryTypeBits,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent
),
};
mVertexBufferMemory = mDevice->allocateMemoryUnique(allocInfo);
mDevice->bindBufferMemory(mVertexBuffer.get(), mVertexBufferMemory.get(), 0);
void* data = mDevice->mapMemory(mVertexBufferMemory.get(), 0, bufferInfo.size);
memcpy(data, mVertices.data(), static_cast<usize>(bufferInfo.size));
mDevice->unmapMemory(mVertexBufferMemory.get());
}
fn findMemoryType(u32 typeFilter, vk::MemoryPropertyFlags properties) -> u32 {
vk::PhysicalDeviceMemoryProperties memProperties = mPhysicalDevice.getMemoryProperties();
for (u32 i = 0; i < memProperties.memoryTypeCount; i++)
if ((typeFilter & (1 << i)) &&
(memProperties.memoryTypes.at(i).propertyFlags & properties) == properties)
return i;
throw std::runtime_error("Failed to find a suitable memory type!");
}
fn createCommandBuffers() -> void {
mCommandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
@ -573,6 +653,7 @@ class VulkanApp {
.minDepth = 0.0F,
.maxDepth = 1.0F,
};
vk::Rect2D scissor {
.offset = { 0, 0 },
.extent = mSwapChainExtent,
@ -581,7 +662,9 @@ class VulkanApp {
commandBuffer.setViewport(0, viewport);
commandBuffer.setScissor(0, scissor);
commandBuffer.draw(3, 1, 0, 0);
commandBuffer.bindVertexBuffers(0, mVertexBuffer.get(), { 0 });
commandBuffer.draw(static_cast<u32>(mVertices.size()), 1, 0, 0);
commandBuffer.endRenderPass();

View file

@ -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;
}

Binary file not shown.