Rendering from vertex buffer
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
Following the vulkan tutorial on :
|
Following the vulkan tutorial on :
|
||||||
https://vulkan-tutorial.com/en/Drawing_a_triangle/Drawing/Frames_in_flight
|
https://vulkan-tutorial.com/Vertex_buffers/Staging_buffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <array>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
const uint32_t WIDTH = 800;
|
const uint32_t WIDTH = 800;
|
||||||
@@ -34,8 +36,43 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
# else
|
# else
|
||||||
const bool enableValidationLayers = true;
|
const bool enableValidationLayers = true;
|
||||||
#endif
|
#endif
|
||||||
|
struct Vertex {
|
||||||
|
glm::vec2 pos;
|
||||||
|
glm::vec3 color;
|
||||||
|
|
||||||
|
static VkVertexInputBindingDescription getBindingDescription() {
|
||||||
|
VkVertexInputBindingDescription bindingDescription{};
|
||||||
|
bindingDescription.binding = 0;
|
||||||
|
bindingDescription.stride = sizeof(Vertex);
|
||||||
|
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||||
|
|
||||||
|
return bindingDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::array<VkVertexInputAttributeDescription, 2> getAttributeDescriptions() {
|
||||||
|
std::array<VkVertexInputAttributeDescription, 2> attributeDescription{};
|
||||||
|
|
||||||
|
attributeDescription[0].binding = 0;
|
||||||
|
attributeDescription[0].location = 0;
|
||||||
|
attributeDescription[0].format = VK_FORMAT_R32G32_SFLOAT;
|
||||||
|
attributeDescription[0].offset = offsetof(Vertex, pos);
|
||||||
|
|
||||||
|
|
||||||
|
attributeDescription[1].binding = 0;
|
||||||
|
attributeDescription[1].location = 1;
|
||||||
|
attributeDescription[1].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||||
|
attributeDescription[1].offset = offsetof(Vertex, color);
|
||||||
|
|
||||||
|
return attributeDescription;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector<Vertex> vertices = {
|
||||||
|
{{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}}
|
||||||
|
};
|
||||||
|
|
||||||
class HelloTriangleApplication {
|
class HelloTriangleApplication {
|
||||||
public:
|
public:
|
||||||
@@ -65,6 +102,8 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
VkPipeline graphicsPipeline;
|
VkPipeline graphicsPipeline;
|
||||||
std::vector<VkFramebuffer> swapchainFrameBuffers;
|
std::vector<VkFramebuffer> swapchainFrameBuffers;
|
||||||
VkCommandPool commandPool;
|
VkCommandPool commandPool;
|
||||||
|
VkBuffer vertexBuffer;
|
||||||
|
VkDeviceMemory vertexBufferMemory;
|
||||||
std::vector<VkCommandBuffer> commandBuffers;
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
std::vector<VkSemaphore> imageAvailableSemaphores;
|
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||||
std::vector<VkSemaphore> renderFinishedSemaphores;
|
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||||
@@ -109,10 +148,56 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
createGraphicsPipeline();
|
createGraphicsPipeline();
|
||||||
createFramebuffers();
|
createFramebuffers();
|
||||||
createCommandPool();
|
createCommandPool();
|
||||||
|
createVertexBuffer();
|
||||||
createCommandBuffers();
|
createCommandBuffers();
|
||||||
createSyncObjects();
|
createSyncObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
|
||||||
|
VkPhysicalDeviceMemoryProperties memProperties;
|
||||||
|
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
|
||||||
|
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("failed to find suitable memory type!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void createVertexBuffer() {
|
||||||
|
VkBufferCreateInfo bufferInfo{};
|
||||||
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
bufferInfo.size = sizeof(vertices[0]) * vertices.size();
|
||||||
|
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||||
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
if (vkCreateBuffer(device, &bufferInfo, nullptr, &vertexBuffer)!= VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to create vertex buffer!");
|
||||||
|
}
|
||||||
|
|
||||||
|
VkMemoryRequirements memRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(device, vertexBuffer, &memRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocInfo{};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocInfo.allocationSize = memRequirements.size;
|
||||||
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
|
|
||||||
|
if (vkAllocateMemory(device, &allocInfo, nullptr, &vertexBufferMemory)!= VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to allocate vertex buffer memory!");
|
||||||
|
}
|
||||||
|
vkBindBufferMemory(device, vertexBuffer, vertexBufferMemory, 0);
|
||||||
|
|
||||||
|
void* data;
|
||||||
|
vkMapMemory(device, vertexBufferMemory, 0, bufferInfo.size, 0, &data);
|
||||||
|
memcpy(data, vertices.data(), (size_t)bufferInfo.size);
|
||||||
|
vkUnmapMemory(device, vertexBufferMemory);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void recreateSwapChain() {
|
void recreateSwapChain() {
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
@@ -198,6 +283,10 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
|
||||||
|
|
||||||
|
VkBuffer vertexBuffers[] = { vertexBuffer };
|
||||||
|
VkDeviceSize offsets[] = { 0 };
|
||||||
|
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
|
||||||
|
|
||||||
VkViewport viewport{};
|
VkViewport viewport{};
|
||||||
viewport.x = 0.0f;
|
viewport.x = 0.0f;
|
||||||
viewport.y = 0.0f;
|
viewport.y = 0.0f;
|
||||||
@@ -212,7 +301,10 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
scissor.extent = swapChainExtent;
|
scissor.extent = swapChainExtent;
|
||||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||||
|
|
||||||
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
|
vkCmdDraw(commandBuffer, static_cast<uint32_t>(vertices.size()), 1, 0, 0);
|
||||||
|
|
||||||
vkCmdEndRenderPass(commandBuffer);
|
vkCmdEndRenderPass(commandBuffer);
|
||||||
|
|
||||||
@@ -450,12 +542,17 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
|
|
||||||
VkPipelineShaderStageCreateInfo shaderStages[] = { vertShaderStageInfo, fragShaderStageInfo };
|
VkPipelineShaderStageCreateInfo shaderStages[] = { vertShaderStageInfo, fragShaderStageInfo };
|
||||||
|
|
||||||
|
|
||||||
|
auto bindingDescription = Vertex::getBindingDescription();
|
||||||
|
auto attributeDescriptions = Vertex::getAttributeDescriptions();
|
||||||
|
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
|
VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
|
||||||
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
vertexInputInfo.vertexBindingDescriptionCount = 0;
|
vertexInputInfo.vertexBindingDescriptionCount = 1;
|
||||||
vertexInputInfo.pVertexBindingDescriptions = nullptr;
|
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
|
||||||
vertexInputInfo.vertexAttributeDescriptionCount = 0;
|
vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
|
||||||
vertexInputInfo.pVertexAttributeDescriptions = nullptr;
|
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
|
||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
|
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
|
||||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
@@ -975,7 +1072,8 @@ const std::vector<const char*> deviceExtensions = {
|
|||||||
void cleanup(){
|
void cleanup(){
|
||||||
cleanupSwapChain();
|
cleanupSwapChain();
|
||||||
|
|
||||||
|
vkDestroyBuffer(device, vertexBuffer, nullptr);
|
||||||
|
vkFreeMemory(device, vertexBufferMemory, nullptr);
|
||||||
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
vkDestroyRenderPass(device, renderPass, nullptr);
|
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||||
|
|||||||
@@ -1,22 +1,11 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 inPosition;
|
||||||
|
layout(location = 1) in vec3 inColor;
|
||||||
|
|
||||||
layout(location = 0) out vec3 fragColor;
|
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() {
|
void main() {
|
||||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
gl_Position = vec4(inPosition, 0.0 , 1.0);
|
||||||
fragColor = colors[gl_VertexIndex];
|
fragColor = inColor;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user