Replaced Index and Vertex buffer descriptions using descriptor sets with the VMA Library, massively simplifying the creation of the Vertex and Index buffer, and uses push constants
This commit is contained in:
parent
f8bd7fdf3b
commit
d5190c8207
BIN
.cache/clangd/index/agnosiaimgui.cpp.D917B7EB41E8A56F.idx
Normal file
BIN
.cache/clangd/index/agnosiaimgui.cpp.D917B7EB41E8A56F.idx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.cache/clangd/index/types.h.2A872A9A515562E6.idx
Normal file
BIN
.cache/clangd/index/types.h.2A872A9A515562E6.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/vk_mem_alloc.h.F667345C57A24872.idx
Normal file
BIN
.cache/clangd/index/vk_mem_alloc.h.F667345C57A24872.idx
Normal file
Binary file not shown.
1
Makefile
1
Makefile
@ -2,7 +2,6 @@ CPPFLAGS=-std=c++23 -g
|
|||||||
CFLAGS = -g
|
CFLAGS = -g
|
||||||
LDFLAGS=-lglfw -Ilib -ldl -lpthread -lX11 -lXxf86vm -lXrandr -lXi -ltinyobjloader -Ilib/imgui -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
LDFLAGS=-lglfw -Ilib -ldl -lpthread -lX11 -lXxf86vm -lXrandr -lXi -ltinyobjloader -Ilib/imgui -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
||||||
MAKEFLAGS += -j16
|
MAKEFLAGS += -j16
|
||||||
|
|
||||||
SRC = $(shell find . -name "*.cpp")
|
SRC = $(shell find . -name "*.cpp")
|
||||||
CSRC = $(shell find . -name "*.c")
|
CSRC = $(shell find . -name "*.c")
|
||||||
SHDRSRC = $(shell find . -name "*.frag" -o -name "*vert")
|
SHDRSRC = $(shell find . -name "*.frag" -o -name "*vert")
|
||||||
|
12
assets/models/untitled.mtl
Normal file
12
assets/models/untitled.mtl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Blender 4.2.3 LTS MTL File: 'None'
|
||||||
|
# www.blender.org
|
||||||
|
|
||||||
|
newmtl Material
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.450000
|
||||||
|
d 1.000000
|
||||||
|
illum 2
|
||||||
|
map_Kd /home/lillian/Downloads/d41777258e68c9d7046fc03c4d1d1e89.png
|
30
assets/models/untitled.obj
Normal file
30
assets/models/untitled.obj
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Blender 4.2.3 LTS
|
||||||
|
# www.blender.org
|
||||||
|
mtllib untitled.mtl
|
||||||
|
o Cube
|
||||||
|
v 1.000000 1.000000 -1.000000
|
||||||
|
v 1.000000 -1.000000 -1.000000
|
||||||
|
v 1.000000 1.000000 1.000000
|
||||||
|
v 1.000000 -1.000000 1.000000
|
||||||
|
v -1.000000 1.000000 -1.000000
|
||||||
|
v -1.000000 -1.000000 -1.000000
|
||||||
|
v -1.000000 1.000000 1.000000
|
||||||
|
v -1.000000 -1.000000 1.000000
|
||||||
|
vn -0.0000 1.0000 -0.0000
|
||||||
|
vn -0.0000 -0.0000 1.0000
|
||||||
|
vn -1.0000 -0.0000 -0.0000
|
||||||
|
vn -0.0000 -1.0000 -0.0000
|
||||||
|
vn 1.0000 -0.0000 -0.0000
|
||||||
|
vn -0.0000 -0.0000 -1.0000
|
||||||
|
vt 1.000000 -0.000021
|
||||||
|
vt 1.000057 1.000011
|
||||||
|
vt -0.000000 1.000005
|
||||||
|
vt 0.000022 -0.000026
|
||||||
|
s 0
|
||||||
|
usemtl Material
|
||||||
|
f 1/1/1 5/2/1 7/3/1 3/4/1
|
||||||
|
f 4/2/2 3/3/2 7/4/2 8/1/2
|
||||||
|
f 8/2/3 7/3/3 5/4/3 6/1/3
|
||||||
|
f 6/1/4 2/2/4 4/3/4 8/4/4
|
||||||
|
f 2/2/5 1/3/5 3/4/5 4/1/5
|
||||||
|
f 6/2/6 5/3/6 1/4/6 2/1/6
|
BIN
assets/textures/aza.png
Normal file
BIN
assets/textures/aza.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 578 KiB |
@ -3,6 +3,6 @@ Pos=60,60
|
|||||||
Size=400,400
|
Size=400,400
|
||||||
|
|
||||||
[Window][Agnosia Debug]
|
[Window][Agnosia Debug]
|
||||||
Pos=194,438
|
Pos=522,0
|
||||||
Size=583,225
|
Size=583,202
|
||||||
|
|
||||||
|
18676
lib/vk_mem_alloc.h
Normal file
18676
lib/vk_mem_alloc.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -300,14 +300,19 @@ void DeviceControl::createLogicalDevice() {
|
|||||||
queueCreateSingularInfo.pQueuePriorities = &queuePriority;
|
queueCreateSingularInfo.pQueuePriorities = &queuePriority;
|
||||||
queueCreateInfos.push_back(queueCreateSingularInfo);
|
queueCreateInfos.push_back(queueCreateSingularInfo);
|
||||||
}
|
}
|
||||||
|
VkPhysicalDeviceVulkan12Features features12{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.bufferDeviceAddress = true,
|
||||||
|
};
|
||||||
VkPhysicalDeviceVulkan13Features features13{
|
VkPhysicalDeviceVulkan13Features features13{
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
|
||||||
.pNext = nullptr,
|
.pNext = &features12,
|
||||||
.synchronization2 = true,
|
.synchronization2 = true,
|
||||||
.dynamicRendering = true,
|
.dynamicRendering = true,
|
||||||
};
|
};
|
||||||
VkPhysicalDeviceFeatures featuresBase{
|
VkPhysicalDeviceFeatures featuresBase{
|
||||||
|
.robustBufferAccess = true,
|
||||||
.sampleRateShading = true,
|
.sampleRateShading = true,
|
||||||
.samplerAnisotropy = true,
|
.samplerAnisotropy = true,
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@ VkInstance vulkaninstance;
|
|||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
const uint32_t WIDTH = 800;
|
const uint32_t WIDTH = 800;
|
||||||
const uint32_t HEIGHT = 600;
|
const uint32_t HEIGHT = 600;
|
||||||
|
|
||||||
// Getters and Setters!
|
// Getters and Setters!
|
||||||
void EntryApp::setFramebufferResized(bool setter) {
|
void EntryApp::setFramebufferResized(bool setter) {
|
||||||
framebufferResized = setter;
|
framebufferResized = setter;
|
||||||
@ -76,12 +77,8 @@ void createInstance() {
|
|||||||
glfwExtensions + glfwExtensionCount);
|
glfwExtensions + glfwExtensionCount);
|
||||||
|
|
||||||
VkInstanceCreateInfo createInfo{}; // Define parameters of new vulkan instance
|
VkInstanceCreateInfo createInfo{}; // Define parameters of new vulkan instance
|
||||||
createInfo.sType =
|
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; // Tell vulkan this is a info
|
createInfo.pApplicationInfo = &appInfo;
|
||||||
// structure
|
|
||||||
createInfo.pApplicationInfo =
|
|
||||||
&appInfo; // We just created a new appInfo structure, so we pass the
|
|
||||||
// pointer to it.
|
|
||||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||||
createInfo.ppEnabledExtensionNames = extensions.data();
|
createInfo.ppEnabledExtensionNames = extensions.data();
|
||||||
|
|
||||||
@ -101,6 +98,7 @@ void initVulkan() {
|
|||||||
DeviceControl::createLogicalDevice();
|
DeviceControl::createLogicalDevice();
|
||||||
volkLoadDevice(DeviceControl::getDevice());
|
volkLoadDevice(DeviceControl::getDevice());
|
||||||
DeviceControl::createSwapChain(window);
|
DeviceControl::createSwapChain(window);
|
||||||
|
Buffers::createMemoryAllocator(vulkaninstance);
|
||||||
DeviceControl::createImageViews();
|
DeviceControl::createImageViews();
|
||||||
Buffers::createDescriptorSetLayout();
|
Buffers::createDescriptorSetLayout();
|
||||||
Graphics::createGraphicsPipeline();
|
Graphics::createGraphicsPipeline();
|
||||||
@ -110,14 +108,13 @@ void initVulkan() {
|
|||||||
Texture::createTextureImage();
|
Texture::createTextureImage();
|
||||||
Texture::createTextureImageView();
|
Texture::createTextureImageView();
|
||||||
Texture::createTextureSampler();
|
Texture::createTextureSampler();
|
||||||
Model::loadModel();
|
Model::loadModel(glm::vec3(0.0, 0.0, 0.0));
|
||||||
Buffers::createVertexBuffer();
|
|
||||||
Buffers::createIndexBuffer();
|
|
||||||
Buffers::createUniformBuffers();
|
Buffers::createUniformBuffers();
|
||||||
Buffers::createDescriptorPool();
|
Buffers::createDescriptorPool();
|
||||||
Buffers::createDescriptorSets();
|
Buffers::createDescriptorSets();
|
||||||
Graphics::createCommandBuffer();
|
Graphics::createCommandBuffer();
|
||||||
Render::createSyncObject();
|
Render::createSyncObject();
|
||||||
|
|
||||||
Gui::initImgui(vulkaninstance);
|
Gui::initImgui(vulkaninstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
class EntryApp {
|
class EntryApp {
|
||||||
public:
|
public:
|
||||||
static EntryApp &getInstance();
|
static EntryApp &getInstance();
|
||||||
|
@ -1,21 +1,34 @@
|
|||||||
#include "../devicelibrary.h"
|
#include "../devicelibrary.h"
|
||||||
|
#include "../types.h"
|
||||||
#include "buffers.h"
|
#include "buffers.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <functional>
|
||||||
#include <glm/ext/matrix_clip_space.hpp>
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||||
|
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
|
||||||
|
#define VMA_IMPLEMENTATION
|
||||||
|
#include "vk_mem_alloc.h"
|
||||||
|
|
||||||
VkBuffer vertexBuffer;
|
VkBuffer vertexBuffer;
|
||||||
VkDeviceMemory vertexBufferMemory;
|
VkDeviceMemory vertexBufferMemory;
|
||||||
VkBuffer indexBuffer;
|
VkBuffer indexBuffer;
|
||||||
VkDeviceMemory indexBufferMemory;
|
VkDeviceMemory indexBufferMemory;
|
||||||
|
|
||||||
std::vector<Buffers::Vertex> vertices;
|
std::vector<Agnosia_T::Vertex> vertices;
|
||||||
// Index buffer definition, showing which points to reuse.
|
// Index buffer definition, showing which points to reuse.
|
||||||
std::vector<uint32_t> indices;
|
std::vector<uint32_t> indices;
|
||||||
|
|
||||||
|
VmaAllocator _allocator;
|
||||||
|
Agnosia_T::GPUPushConstants pushConstants;
|
||||||
|
|
||||||
VkDescriptorPool descriptorPool;
|
VkDescriptorPool descriptorPool;
|
||||||
VkDescriptorSetLayout descriptorSetLayout;
|
VkDescriptorSetLayout descriptorSetLayout;
|
||||||
std::vector<VkDescriptorSet> descriptorSets;
|
std::vector<VkDescriptorSet> descriptorSets;
|
||||||
@ -60,6 +73,40 @@ uint32_t Buffers::findMemoryType(uint32_t typeFilter,
|
|||||||
throw std::runtime_error("failed to find suitable memory type!");
|
throw std::runtime_error("failed to find suitable memory type!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void immediate_submit(std::function<void(VkCommandBuffer cmd)> &&function) {
|
||||||
|
VkCommandBufferAllocateInfo allocInfo{};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
allocInfo.commandPool = commandPool;
|
||||||
|
allocInfo.commandBufferCount = 1;
|
||||||
|
|
||||||
|
VkCommandBuffer commandBuffer;
|
||||||
|
vkAllocateCommandBuffers(DeviceControl::getDevice(), &allocInfo,
|
||||||
|
&commandBuffer);
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo beginInfo{};
|
||||||
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
|
|
||||||
|
vkBeginCommandBuffer(commandBuffer, &beginInfo);
|
||||||
|
|
||||||
|
function(commandBuffer);
|
||||||
|
|
||||||
|
vkEndCommandBuffer(commandBuffer);
|
||||||
|
|
||||||
|
VkSubmitInfo submitInfo{};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &commandBuffer;
|
||||||
|
|
||||||
|
vkQueueSubmit(DeviceControl::getGraphicsQueue(), 1, &submitInfo,
|
||||||
|
VK_NULL_HANDLE);
|
||||||
|
vkQueueWaitIdle(DeviceControl::getGraphicsQueue());
|
||||||
|
|
||||||
|
vkFreeCommandBuffers(DeviceControl::getDevice(), commandPool, 1,
|
||||||
|
&commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
|
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
|
||||||
VkCommandBufferAllocateInfo allocInfo{};
|
VkCommandBufferAllocateInfo allocInfo{};
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
@ -95,6 +142,101 @@ void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
|
|||||||
vkFreeCommandBuffers(DeviceControl::getDevice(), commandPool, 1,
|
vkFreeCommandBuffers(DeviceControl::getDevice(), commandPool, 1,
|
||||||
&commandBuffer);
|
&commandBuffer);
|
||||||
}
|
}
|
||||||
|
void Buffers::createMemoryAllocator(VkInstance vkInstance) {
|
||||||
|
VmaVulkanFunctions vulkanFuncs{
|
||||||
|
.vkGetInstanceProcAddr = vkGetInstanceProcAddr,
|
||||||
|
.vkGetDeviceProcAddr = vkGetDeviceProcAddr,
|
||||||
|
};
|
||||||
|
VmaAllocatorCreateInfo allocInfo{
|
||||||
|
.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT,
|
||||||
|
.physicalDevice = DeviceControl::getPhysicalDevice(),
|
||||||
|
.device = DeviceControl::getDevice(),
|
||||||
|
.pVulkanFunctions = &vulkanFuncs,
|
||||||
|
.instance = vkInstance,
|
||||||
|
.vulkanApiVersion = VK_API_VERSION_1_3,
|
||||||
|
|
||||||
|
};
|
||||||
|
vmaCreateAllocator(&allocInfo, &_allocator);
|
||||||
|
}
|
||||||
|
Agnosia_T::AllocatedBuffer Buffers::createBuffer(size_t allocSize,
|
||||||
|
VkBufferUsageFlags usage,
|
||||||
|
VmaMemoryUsage memUsage) {
|
||||||
|
// Allocate the buffer we will use for Device Addresses
|
||||||
|
VkBufferCreateInfo bufferInfo{.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.size = allocSize,
|
||||||
|
.usage = usage};
|
||||||
|
VmaAllocationCreateInfo vmaAllocInfo{
|
||||||
|
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT, .usage = memUsage};
|
||||||
|
|
||||||
|
Agnosia_T::AllocatedBuffer newBuffer;
|
||||||
|
if (vmaCreateBuffer(_allocator, &bufferInfo, &vmaAllocInfo, &newBuffer.buffer,
|
||||||
|
&newBuffer.allocation, &newBuffer.info) != VK_SUCCESS) {
|
||||||
|
throw std::runtime_error("Failed to allocate a buffer using VMA!");
|
||||||
|
}
|
||||||
|
return newBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Agnosia_T::GPUMeshBuffers
|
||||||
|
Buffers::sendMesh(std::span<uint32_t> indices,
|
||||||
|
std::span<Agnosia_T::Vertex> vertices) {
|
||||||
|
|
||||||
|
const size_t vertexBufferSize = vertices.size() * sizeof(Agnosia_T::Vertex);
|
||||||
|
const size_t indexBufferSize = indices.size() * sizeof(uint32_t);
|
||||||
|
|
||||||
|
Agnosia_T::GPUMeshBuffers newSurface;
|
||||||
|
|
||||||
|
// Create a Vertex Buffer here, infinitely easier than the old Vulkan method!
|
||||||
|
newSurface.vertexBuffer = createBuffer(
|
||||||
|
vertexBufferSize,
|
||||||
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||||
|
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
|
||||||
|
VMA_MEMORY_USAGE_GPU_ONLY);
|
||||||
|
// Find the address of the vertex buffer!
|
||||||
|
VkBufferDeviceAddressInfo deviceAddressInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
|
||||||
|
.buffer = newSurface.vertexBuffer.buffer,
|
||||||
|
};
|
||||||
|
newSurface.vertexBufferAddress =
|
||||||
|
vkGetBufferDeviceAddress(DeviceControl::getDevice(), &deviceAddressInfo);
|
||||||
|
|
||||||
|
// Create the index buffer to iterate over and check for duplicate vertices
|
||||||
|
newSurface.indexBuffer = createBuffer(indexBufferSize,
|
||||||
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||||
|
VMA_MEMORY_USAGE_GPU_ONLY);
|
||||||
|
|
||||||
|
Agnosia_T::AllocatedBuffer stagingBuffer =
|
||||||
|
createBuffer(vertexBufferSize + indexBufferSize,
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
|
||||||
|
|
||||||
|
void *data = stagingBuffer.allocation->GetMappedData();
|
||||||
|
|
||||||
|
// Copy the vertex buffer
|
||||||
|
memcpy(data, vertices.data(), vertexBufferSize);
|
||||||
|
// Copy the index buffer
|
||||||
|
memcpy((char *)data + vertexBufferSize, indices.data(), indexBufferSize);
|
||||||
|
|
||||||
|
immediate_submit([&](VkCommandBuffer cmd) {
|
||||||
|
VkBufferCopy vertexCopy{0};
|
||||||
|
vertexCopy.dstOffset = 0;
|
||||||
|
vertexCopy.srcOffset = 0;
|
||||||
|
vertexCopy.size = vertexBufferSize;
|
||||||
|
|
||||||
|
vkCmdCopyBuffer(cmd, stagingBuffer.buffer, newSurface.vertexBuffer.buffer,
|
||||||
|
1, &vertexCopy);
|
||||||
|
|
||||||
|
VkBufferCopy indexCopy{0};
|
||||||
|
indexCopy.dstOffset = 0;
|
||||||
|
indexCopy.srcOffset = vertexBufferSize;
|
||||||
|
indexCopy.size = indexBufferSize;
|
||||||
|
|
||||||
|
vkCmdCopyBuffer(cmd, stagingBuffer.buffer, newSurface.indexBuffer.buffer, 1,
|
||||||
|
&indexCopy);
|
||||||
|
});
|
||||||
|
vmaDestroyBuffer(_allocator, stagingBuffer.buffer, stagingBuffer.allocation);
|
||||||
|
return newSurface;
|
||||||
|
}
|
||||||
|
|
||||||
void Buffers::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
|
void Buffers::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
|
||||||
VkMemoryPropertyFlags properties, VkBuffer &buffer,
|
VkMemoryPropertyFlags properties, VkBuffer &buffer,
|
||||||
@ -128,68 +270,6 @@ void Buffers::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
|
|||||||
vkBindBufferMemory(DeviceControl::getDevice(), buffer, bufferMemory, 0);
|
vkBindBufferMemory(DeviceControl::getDevice(), buffer, bufferMemory, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffers::createIndexBuffer() {
|
|
||||||
VkDeviceSize bufferSize = sizeof(indices[0]) * indices.size();
|
|
||||||
|
|
||||||
VkBuffer stagingBuffer;
|
|
||||||
VkDeviceMemory stagingBufferMemory;
|
|
||||||
|
|
||||||
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
|
||||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
stagingBuffer, stagingBufferMemory);
|
|
||||||
|
|
||||||
void *data;
|
|
||||||
vkMapMemory(DeviceControl::getDevice(), stagingBufferMemory, 0, bufferSize, 0,
|
|
||||||
&data);
|
|
||||||
memcpy(data, indices.data(), (size_t)bufferSize);
|
|
||||||
|
|
||||||
vkUnmapMemory(DeviceControl::getDevice(), stagingBufferMemory);
|
|
||||||
|
|
||||||
createBuffer(
|
|
||||||
bufferSize,
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);
|
|
||||||
|
|
||||||
copyBuffer(stagingBuffer, indexBuffer, bufferSize);
|
|
||||||
|
|
||||||
vkDestroyBuffer(DeviceControl::getDevice(), stagingBuffer, nullptr);
|
|
||||||
vkFreeMemory(DeviceControl::getDevice(), stagingBufferMemory, nullptr);
|
|
||||||
}
|
|
||||||
void Buffers::createVertexBuffer() {
|
|
||||||
// Create a Vertex Buffer to hold the vertex information in memory so it
|
|
||||||
// doesn't have to be hardcoded! Size denotes the size of the buffer in bytes,
|
|
||||||
// usage in this case is the buffer behaviour, using a bitwise OR. Sharing
|
|
||||||
// mode denostes the same as the images in the swap chain! in this case, only
|
|
||||||
// the graphics queue uses this buffer, so we make it exclusive.
|
|
||||||
VkDeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
|
|
||||||
|
|
||||||
VkBuffer stagingBuffer;
|
|
||||||
VkDeviceMemory stagingBufferMemory;
|
|
||||||
createBuffer(bufferSize,
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
|
||||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
|
||||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
||||||
stagingBuffer, stagingBufferMemory);
|
|
||||||
|
|
||||||
void *data;
|
|
||||||
vkMapMemory(DeviceControl::getDevice(), stagingBufferMemory, 0, bufferSize, 0,
|
|
||||||
&data);
|
|
||||||
memcpy(data, vertices.data(), (size_t)bufferSize);
|
|
||||||
vkUnmapMemory(DeviceControl::getDevice(), stagingBufferMemory);
|
|
||||||
|
|
||||||
createBuffer(
|
|
||||||
bufferSize,
|
|
||||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
|
||||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
|
|
||||||
|
|
||||||
copyBuffer(stagingBuffer, vertexBuffer, bufferSize);
|
|
||||||
|
|
||||||
vkDestroyBuffer(DeviceControl::getDevice(), stagingBuffer, nullptr);
|
|
||||||
vkFreeMemory(DeviceControl::getDevice(), stagingBufferMemory, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Buffers::destroyBuffers() {
|
void Buffers::destroyBuffers() {
|
||||||
vkDestroyBuffer(DeviceControl::getDevice(), indexBuffer, nullptr);
|
vkDestroyBuffer(DeviceControl::getDevice(), indexBuffer, nullptr);
|
||||||
vkFreeMemory(DeviceControl::getDevice(), indexBufferMemory, nullptr);
|
vkFreeMemory(DeviceControl::getDevice(), indexBufferMemory, nullptr);
|
||||||
@ -373,8 +453,6 @@ void Buffers::createDescriptorSets() {
|
|||||||
void Buffers::destroyDescriptorPool() {
|
void Buffers::destroyDescriptorPool() {
|
||||||
vkDestroyDescriptorPool(DeviceControl::getDevice(), descriptorPool, nullptr);
|
vkDestroyDescriptorPool(DeviceControl::getDevice(), descriptorPool, nullptr);
|
||||||
}
|
}
|
||||||
VkBuffer &Buffers::getVertexBuffer() { return vertexBuffer; }
|
|
||||||
VkBuffer &Buffers::getIndexBuffer() { return indexBuffer; }
|
|
||||||
VkDescriptorPool &Buffers::getDescriptorPool() { return descriptorPool; }
|
VkDescriptorPool &Buffers::getDescriptorPool() { return descriptorPool; }
|
||||||
std::vector<VkDescriptorSet> &Buffers::getDescriptorSets() {
|
std::vector<VkDescriptorSet> &Buffers::getDescriptorSets() {
|
||||||
return descriptorSets;
|
return descriptorSets;
|
||||||
@ -397,5 +475,5 @@ VkCommandPool &Buffers::getCommandPool() { return commandPool; }
|
|||||||
VkDescriptorSetLayout &Buffers::getDescriptorSetLayout() {
|
VkDescriptorSetLayout &Buffers::getDescriptorSetLayout() {
|
||||||
return descriptorSetLayout;
|
return descriptorSetLayout;
|
||||||
}
|
}
|
||||||
std::vector<Buffers::Vertex> &Buffers::getVertices() { return vertices; }
|
std::vector<Agnosia_T::Vertex> &Buffers::getVertices() { return vertices; }
|
||||||
std::vector<uint32_t> &Buffers::getIndices() { return indices; }
|
std::vector<uint32_t> &Buffers::getIndices() { return indices; }
|
||||||
|
@ -1,68 +1,29 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <span>
|
||||||
#define VK_NO_PROTOTYPES
|
#define VK_NO_PROTOTYPES
|
||||||
|
#include "../types.h"
|
||||||
#include "volk.h"
|
#include "volk.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <array>
|
|
||||||
|
|
||||||
class Buffers {
|
class Buffers {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct Vertex {
|
static Agnosia_T::AllocatedBuffer createBuffer(size_t allocSize,
|
||||||
// This defines what a vertex is!
|
VkBufferUsageFlags usage,
|
||||||
// We control the position, color and texture coordinate here!
|
VmaMemoryUsage memUsage);
|
||||||
glm::vec3 pos;
|
static void createMemoryAllocator(VkInstance vkInstance);
|
||||||
glm::vec3 color;
|
static Agnosia_T::GPUMeshBuffers
|
||||||
glm::vec2 texCoord;
|
sendMesh(std::span<uint32_t> indices, std::span<Agnosia_T::Vertex> vertices);
|
||||||
|
|
||||||
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, 3>
|
|
||||||
getAttributeDescriptions() {
|
|
||||||
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
|
|
||||||
|
|
||||||
attributeDescriptions[0].binding = 0;
|
|
||||||
attributeDescriptions[0].location = 0;
|
|
||||||
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
|
|
||||||
attributeDescriptions[0].offset = offsetof(Vertex, pos);
|
|
||||||
|
|
||||||
attributeDescriptions[1].binding = 0;
|
|
||||||
attributeDescriptions[1].location = 1;
|
|
||||||
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
|
|
||||||
attributeDescriptions[1].offset = offsetof(Vertex, color);
|
|
||||||
|
|
||||||
attributeDescriptions[2].binding = 0;
|
|
||||||
attributeDescriptions[2].location = 2;
|
|
||||||
attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
|
|
||||||
attributeDescriptions[2].offset = offsetof(Vertex, texCoord);
|
|
||||||
return attributeDescriptions;
|
|
||||||
}
|
|
||||||
bool operator==(const Vertex &other) const {
|
|
||||||
return pos == other.pos && color == other.color &&
|
|
||||||
texCoord == other.texCoord;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
|
static void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
|
||||||
VkMemoryPropertyFlags props, VkBuffer &buffer,
|
VkMemoryPropertyFlags props, VkBuffer &buffer,
|
||||||
VkDeviceMemory &bufferMemory);
|
VkDeviceMemory &bufferMemory);
|
||||||
static uint32_t findMemoryType(uint32_t typeFilter,
|
static uint32_t findMemoryType(uint32_t typeFilter,
|
||||||
VkMemoryPropertyFlags flags);
|
VkMemoryPropertyFlags flags);
|
||||||
static void createIndexBuffer();
|
|
||||||
static void createVertexBuffer();
|
|
||||||
static void destroyBuffers();
|
static void destroyBuffers();
|
||||||
static VkBuffer &getVertexBuffer();
|
|
||||||
static VkBuffer &getIndexBuffer();
|
|
||||||
static void createDescriptorSetLayout();
|
static void createDescriptorSetLayout();
|
||||||
static void createUniformBuffers();
|
static void createUniformBuffers();
|
||||||
static void updateUniformBuffer(uint32_t currentImage);
|
static void updateUniformBuffer(uint32_t currentImage);
|
||||||
@ -85,6 +46,6 @@ public:
|
|||||||
static std::vector<VkBuffer> &getUniformBuffers();
|
static std::vector<VkBuffer> &getUniformBuffers();
|
||||||
static std::vector<VkDeviceMemory> &getUniformBuffersMemory();
|
static std::vector<VkDeviceMemory> &getUniformBuffersMemory();
|
||||||
static VkCommandPool &getCommandPool();
|
static VkCommandPool &getCommandPool();
|
||||||
static std::vector<Vertex> &getVertices();
|
static std::vector<Agnosia_T::Vertex> &getVertices();
|
||||||
static std::vector<uint32_t> &getIndices();
|
static std::vector<uint32_t> &getIndices();
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
std::vector<VkDynamicState> dynamicStates = {VK_DYNAMIC_STATE_VIEWPORT,
|
std::vector<VkDynamicState> dynamicStates = {VK_DYNAMIC_STATE_VIEWPORT,
|
||||||
VK_DYNAMIC_STATE_SCISSOR};
|
VK_DYNAMIC_STATE_SCISSOR};
|
||||||
@ -83,8 +84,8 @@ void Graphics::createGraphicsPipeline() {
|
|||||||
vertexInputInfo.sType =
|
vertexInputInfo.sType =
|
||||||
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
|
|
||||||
auto bindingDescription = Buffers::Vertex::getBindingDescription();
|
auto bindingDescription = Agnosia_T::Vertex::getBindingDescription();
|
||||||
auto attributeDescriptions = Buffers::Vertex::getAttributeDescriptions();
|
auto attributeDescriptions = Agnosia_T::Vertex::getAttributeDescriptions();
|
||||||
|
|
||||||
vertexInputInfo.vertexBindingDescriptionCount = 1;
|
vertexInputInfo.vertexBindingDescriptionCount = 1;
|
||||||
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
|
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
|
||||||
@ -174,10 +175,18 @@ void Graphics::createGraphicsPipeline() {
|
|||||||
dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
|
dynamicState.dynamicStateCount = static_cast<uint32_t>(dynamicStates.size());
|
||||||
dynamicState.pDynamicStates = dynamicStates.data();
|
dynamicState.pDynamicStates = dynamicStates.data();
|
||||||
|
|
||||||
|
VkPushConstantRange pushConstant{
|
||||||
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
.offset = 0,
|
||||||
|
.size = sizeof(Agnosia_T::GPUPushConstants),
|
||||||
|
};
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
|
||||||
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
pipelineLayoutInfo.setLayoutCount = 1;
|
pipelineLayoutInfo.setLayoutCount = 1;
|
||||||
pipelineLayoutInfo.pSetLayouts = &Buffers::getDescriptorSetLayout();
|
pipelineLayoutInfo.pSetLayouts = &Buffers::getDescriptorSetLayout();
|
||||||
|
pipelineLayoutInfo.pPushConstantRanges = &pushConstant;
|
||||||
|
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
||||||
|
|
||||||
if (vkCreatePipelineLayout(DeviceControl::getDevice(), &pipelineLayoutInfo,
|
if (vkCreatePipelineLayout(DeviceControl::getDevice(), &pipelineLayoutInfo,
|
||||||
nullptr, &pipelineLayout) != VK_SUCCESS) {
|
nullptr, &pipelineLayout) != VK_SUCCESS) {
|
||||||
@ -256,7 +265,6 @@ void Graphics::createCommandBuffer() {
|
|||||||
throw std::runtime_error("Failed to allocate command buffers");
|
throw std::runtime_error("Failed to allocate command buffers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::recordCommandBuffer(VkCommandBuffer commandBuffer,
|
void Graphics::recordCommandBuffer(VkCommandBuffer commandBuffer,
|
||||||
uint32_t imageIndex) {
|
uint32_t imageIndex) {
|
||||||
VkCommandBufferBeginInfo beginInfo{};
|
VkCommandBufferBeginInfo beginInfo{};
|
||||||
@ -344,10 +352,15 @@ void Graphics::recordCommandBuffer(VkCommandBuffer commandBuffer,
|
|||||||
scissor.extent = DeviceControl::getSwapChainExtent();
|
scissor.extent = DeviceControl::getSwapChainExtent();
|
||||||
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
|
||||||
|
|
||||||
VkBuffer vertexBuffers[] = {Buffers::getVertexBuffer()};
|
Agnosia_T::GPUMeshBuffers Model =
|
||||||
VkDeviceSize offsets[] = {0};
|
Buffers::sendMesh(Buffers::getIndices(), Buffers::getVertices());
|
||||||
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
|
|
||||||
vkCmdBindIndexBuffer(commandBuffer, Buffers::getIndexBuffer(), 0,
|
Agnosia_T::GPUPushConstants pushConsts;
|
||||||
|
pushConsts.vertexBuffer = Model.vertexBufferAddress;
|
||||||
|
|
||||||
|
vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
0, sizeof(Agnosia_T::GPUPushConstants), &pushConsts);
|
||||||
|
vkCmdBindIndexBuffer(commandBuffer, Model.indexBuffer.buffer, 0,
|
||||||
VK_INDEX_TYPE_UINT32);
|
VK_INDEX_TYPE_UINT32);
|
||||||
|
|
||||||
vkCmdBindDescriptorSets(
|
vkCmdBindDescriptorSets(
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#include <glm/gtx/hash.hpp>
|
#include <glm/gtx/hash.hpp>
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template <> struct hash<Buffers::Vertex> {
|
template <> struct hash<Agnosia_T::Vertex> {
|
||||||
size_t operator()(Buffers::Vertex const &vertex) const {
|
size_t operator()(Agnosia_T::Vertex const &vertex) const {
|
||||||
return ((hash<glm::vec3>()(vertex.pos) ^
|
return ((hash<glm::vec3>()(vertex.pos) ^
|
||||||
(hash<glm::vec3>()(vertex.color) << 1)) >>
|
(hash<glm::vec3>()(vertex.color) << 1)) >>
|
||||||
1) ^
|
1) ^
|
||||||
@ -21,7 +21,7 @@ template <> struct hash<Buffers::Vertex> {
|
|||||||
|
|
||||||
const std::string MODEL_PATH = "assets/models/viking_room.obj";
|
const std::string MODEL_PATH = "assets/models/viking_room.obj";
|
||||||
|
|
||||||
void Model::loadModel() {
|
void Model::loadModel(glm::vec3 position) {
|
||||||
tinyobj::ObjReaderConfig readerConfig;
|
tinyobj::ObjReaderConfig readerConfig;
|
||||||
|
|
||||||
tinyobj::ObjReader reader;
|
tinyobj::ObjReader reader;
|
||||||
@ -38,15 +38,15 @@ void Model::loadModel() {
|
|||||||
auto &attrib = reader.GetAttrib();
|
auto &attrib = reader.GetAttrib();
|
||||||
auto &shapes = reader.GetShapes();
|
auto &shapes = reader.GetShapes();
|
||||||
auto &materials = reader.GetMaterials();
|
auto &materials = reader.GetMaterials();
|
||||||
std::unordered_map<Buffers::Vertex, uint32_t> uniqueVertices{};
|
std::unordered_map<Agnosia_T::Vertex, uint32_t> uniqueVertices{};
|
||||||
|
|
||||||
for (const auto &shape : shapes) {
|
for (const auto &shape : shapes) {
|
||||||
for (const auto &index : shape.mesh.indices) {
|
for (const auto &index : shape.mesh.indices) {
|
||||||
Buffers::Vertex vertex{};
|
Agnosia_T::Vertex vertex{};
|
||||||
|
|
||||||
vertex.pos = {attrib.vertices[3 * index.vertex_index + 0],
|
vertex.pos = {attrib.vertices[3 * index.vertex_index + 0] + position.x,
|
||||||
attrib.vertices[3 * index.vertex_index + 1],
|
attrib.vertices[3 * index.vertex_index + 1] + position.y,
|
||||||
attrib.vertices[3 * index.vertex_index + 2]};
|
attrib.vertices[3 * index.vertex_index + 2] + position.z};
|
||||||
|
|
||||||
// TODO: Small fix here, handle if there are no UV's unwrapped for the
|
// TODO: Small fix here, handle if there are no UV's unwrapped for the
|
||||||
// model.
|
// model.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||||
|
#include <glm/glm.hpp>
|
||||||
class Model {
|
class Model {
|
||||||
public:
|
public:
|
||||||
static void loadModel();
|
static void loadModel(glm::vec3 position);
|
||||||
};
|
};
|
||||||
|
@ -45,6 +45,7 @@ void recreateSwapChain() {
|
|||||||
void Render::drawFrame() {
|
void Render::drawFrame() {
|
||||||
vkWaitForFences(DeviceControl::getDevice(), 1, &inFlightFences[currentFrame],
|
vkWaitForFences(DeviceControl::getDevice(), 1, &inFlightFences[currentFrame],
|
||||||
VK_TRUE, UINT64_MAX);
|
VK_TRUE, UINT64_MAX);
|
||||||
|
|
||||||
vkResetFences(DeviceControl::getDevice(), 1, &inFlightFences[currentFrame]);
|
vkResetFences(DeviceControl::getDevice(), 1, &inFlightFences[currentFrame]);
|
||||||
|
|
||||||
uint32_t imageIndex;
|
uint32_t imageIndex;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "entrypoint.h"
|
#include "entrypoint.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define VOLK_IMPLEMENTATION
|
#define VOLK_IMPLEMENTATION
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
#extension GL_EXT_buffer_reference : require
|
||||||
|
|
||||||
layout(binding = 0) uniform UniformBufferObject {
|
layout(binding = 0) uniform UniformBufferObject {
|
||||||
float time;
|
float time;
|
||||||
@ -6,20 +7,26 @@ layout(binding = 0) uniform UniformBufferObject {
|
|||||||
mat4 view;
|
mat4 view;
|
||||||
mat4 proj;
|
mat4 proj;
|
||||||
} ubo;
|
} ubo;
|
||||||
|
struct Vertex {
|
||||||
|
|
||||||
// inPosition and inColor are vertex attributes, per-vertex properties defined in the vertex buffer!
|
vec3 pos;
|
||||||
// Layout assigns indices to access these inputs, dvec3 takes 2 slots so we must index it at 2. https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL)
|
vec3 color;
|
||||||
|
vec2 texCoord;
|
||||||
|
};
|
||||||
|
|
||||||
layout(location = 0) in vec3 inPosition;
|
layout(buffer_reference, std430) readonly buffer VertexBuffer{
|
||||||
layout(location = 1) in vec3 inColor;
|
Vertex vertices[];
|
||||||
layout(location = 2) in vec2 inTexCoord;
|
};
|
||||||
|
layout( push_constant ) uniform constants {
|
||||||
|
VertexBuffer vertBuffer;
|
||||||
|
}PushConstants;
|
||||||
|
|
||||||
layout(location = 0) out vec3 fragColor;
|
layout(location = 0) out vec3 fragColor;
|
||||||
layout(location = 1) out vec2 fragTexCoord;
|
layout(location = 1) out vec2 fragTexCoord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
Vertex v = PushConstants.vertBuffer.vertices[gl_VertexIndex];
|
||||||
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
|
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(v.pos, 1.0f);
|
||||||
fragColor = inColor;
|
fragColor = v.color.xyz;
|
||||||
fragTexCoord = inTexCoord;
|
fragTexCoord = v.texCoord;
|
||||||
}
|
}
|
||||||
|
64
src/types.h
Normal file
64
src/types.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||||
|
|
||||||
|
#include "vk_mem_alloc.h"
|
||||||
|
#include <array>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Agnosia_T {
|
||||||
|
public:
|
||||||
|
struct Vertex {
|
||||||
|
// This defines what a vertex is!
|
||||||
|
// We control the position, color and texture coordinate here!
|
||||||
|
alignas(16) glm::vec3 pos;
|
||||||
|
alignas(16) glm::vec3 color;
|
||||||
|
alignas(8) glm::vec2 texCoord;
|
||||||
|
|
||||||
|
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, 3>
|
||||||
|
getAttributeDescriptions() {
|
||||||
|
std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
|
||||||
|
|
||||||
|
attributeDescriptions[0].binding = 0;
|
||||||
|
attributeDescriptions[0].location = 0;
|
||||||
|
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||||
|
attributeDescriptions[0].offset = offsetof(Vertex, pos);
|
||||||
|
|
||||||
|
attributeDescriptions[1].binding = 0;
|
||||||
|
attributeDescriptions[1].location = 1;
|
||||||
|
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||||
|
attributeDescriptions[1].offset = offsetof(Vertex, color);
|
||||||
|
|
||||||
|
attributeDescriptions[2].binding = 0;
|
||||||
|
attributeDescriptions[2].location = 2;
|
||||||
|
attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
|
||||||
|
attributeDescriptions[2].offset = offsetof(Vertex, texCoord);
|
||||||
|
return attributeDescriptions;
|
||||||
|
}
|
||||||
|
bool operator==(const Vertex &other) const {
|
||||||
|
return pos == other.pos && color == other.color &&
|
||||||
|
texCoord == other.texCoord;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct AllocatedBuffer {
|
||||||
|
VkBuffer buffer;
|
||||||
|
VmaAllocation allocation;
|
||||||
|
VmaAllocationInfo info;
|
||||||
|
};
|
||||||
|
struct GPUMeshBuffers {
|
||||||
|
AllocatedBuffer indexBuffer;
|
||||||
|
AllocatedBuffer vertexBuffer;
|
||||||
|
VkDeviceAddress vertexBufferAddress;
|
||||||
|
};
|
||||||
|
struct GPUPushConstants {
|
||||||
|
VkDeviceAddress vertexBuffer;
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user