This commit is contained in:
@@ -4,13 +4,28 @@
|
||||
#include "VulkanFramebuffers.h"
|
||||
#include "VulkanSwapChain.h"
|
||||
#include "VulkanVertexBuffer.h"
|
||||
|
||||
#include "utilities/Logger.h"
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_vulkan.h"
|
||||
#include "utilities/Logger.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/fwd.hpp>
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
VulkanContext::VulkanContext()
|
||||
{
|
||||
@@ -20,7 +35,7 @@ VulkanContext::~VulkanContext()
|
||||
{
|
||||
}
|
||||
|
||||
void VulkanContext::Initialize(FVulkanConfig& InConfig, const std::vector<Vertex>& InVertices)
|
||||
void VulkanContext::Initialize(FVulkanConfig& InConfig, const std::vector<Vertex>& InVertices, const std::vector<uint16_t>& InIndices)
|
||||
{
|
||||
Config = InConfig;
|
||||
|
||||
@@ -62,8 +77,10 @@ void VulkanContext::Initialize(FVulkanConfig& InConfig, const std::vector<Vertex
|
||||
RenderPass.Initialize(DeviceManager.GetDevice());
|
||||
RenderPass.CreateRenderPass(SwapChain.GetSwapChainImageFormat());
|
||||
|
||||
CreateDescriptorSetLayout();
|
||||
|
||||
GraphicsPipeline.Initialize(DeviceManager.GetDevice());
|
||||
GraphicsPipeline.CreateGraphicsPipeline(SwapChain.GetSwapChainExtent(), RenderPass.GetRenderPass());
|
||||
GraphicsPipeline.CreateGraphicsPipeline(SwapChain.GetSwapChainExtent(), RenderPass.GetRenderPass(), DescriptorSetLayout);
|
||||
|
||||
Framebuffers.Initialize(FFramebufferConfig(
|
||||
DeviceManager.GetDevice(),
|
||||
@@ -75,8 +92,19 @@ void VulkanContext::Initialize(FVulkanConfig& InConfig, const std::vector<Vertex
|
||||
CommandBuffers.Initialize(DeviceManager.GetDevice(), RenderPass.GetRenderPass());
|
||||
CommandBuffers.CreateCommandPool(DeviceManager.GetPhysicalQueueFamilies().GraphicsFamily);
|
||||
|
||||
VertexBuffer.Initialize(FVertexBufferConfig(DeviceManager.GetDevice(), DeviceManager.GetPhysicalDevice()));
|
||||
CreateTextureImage("textures/texture.jpg");
|
||||
|
||||
VertexBuffer.Initialize(FVertexBufferConfig(
|
||||
DeviceManager.GetDevice(),
|
||||
DeviceManager.GetPhysicalDevice(),
|
||||
CommandBuffers.GetCommandPool(),
|
||||
DeviceManager.GetGraphicsQueue()));
|
||||
VertexBuffer.CreateVertexBuffer(InVertices);
|
||||
VertexBuffer.CreateIndexBuffer(InIndices);
|
||||
VertexBuffer.CreateUniformBuffers(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
CreateDescriptorPool();
|
||||
CreateDescriptorSets();
|
||||
|
||||
CommandBuffers.CreateCommandBuffers(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
@@ -118,7 +146,10 @@ void VulkanContext::Cleanup()
|
||||
|
||||
CleanupSwapChain();
|
||||
|
||||
VertexBuffer.Cleanup();
|
||||
vkDestroyDescriptorPool(DeviceManager.GetDevice(), DescriptorPool, nullptr);
|
||||
vkDestroyDescriptorSetLayout(DeviceManager.GetDevice(), DescriptorSetLayout, nullptr);
|
||||
|
||||
VertexBuffer.Cleanup(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
GraphicsPipeline.Cleanup();
|
||||
RenderPass.Cleanup();
|
||||
@@ -183,6 +214,187 @@ void VulkanContext::CreateSurface(GLFWwindow* Window)
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanContext::CreateDescriptorSetLayout()
|
||||
{
|
||||
VkDescriptorSetLayoutBinding UboLayoutBinding{};
|
||||
UboLayoutBinding.binding = 0;
|
||||
UboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
UboLayoutBinding.descriptorCount = 1;
|
||||
UboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
UboLayoutBinding.pImmutableSamplers = nullptr;
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo LayoutInfo{};
|
||||
LayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
LayoutInfo.bindingCount = 1;
|
||||
LayoutInfo.pBindings = &UboLayoutBinding;
|
||||
|
||||
if (vkCreateDescriptorSetLayout(DeviceManager.GetDevice(), &LayoutInfo, nullptr, &DescriptorSetLayout) != VK_SUCCESS)
|
||||
{
|
||||
Log::Error("Failed to create descriptor set layout!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Info("Successfully created descriptor set layout.");
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanContext::CreateDescriptorPool()
|
||||
{
|
||||
VkDescriptorPoolSize PoolSize{};
|
||||
PoolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
PoolSize.descriptorCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
VkDescriptorPoolCreateInfo PoolInfo{};
|
||||
PoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
PoolInfo.poolSizeCount = 1;
|
||||
PoolInfo.pPoolSizes = &PoolSize;
|
||||
PoolInfo.maxSets = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
if (vkCreateDescriptorPool(DeviceManager.GetDevice(), &PoolInfo, nullptr, &DescriptorPool) != VK_SUCCESS)
|
||||
{
|
||||
Log::Error("Failed to create descriptor pool!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Info("Successfully created descriptor pool.");
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanContext::CreateDescriptorSets()
|
||||
{
|
||||
std::vector<VkDescriptorSetLayout> Layouts(MAX_FRAMES_IN_FLIGHT, DescriptorSetLayout);
|
||||
|
||||
VkDescriptorSetAllocateInfo AllocateInfo{};
|
||||
AllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
AllocateInfo.descriptorPool = DescriptorPool;
|
||||
AllocateInfo.descriptorSetCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
||||
AllocateInfo.pSetLayouts = Layouts.data();
|
||||
|
||||
DescriptorSets.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
if (vkAllocateDescriptorSets(DeviceManager.GetDevice(), &AllocateInfo, DescriptorSets.data()) != VK_SUCCESS)
|
||||
{
|
||||
Log::Error("Failed to allocate descriptor sets!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Info("Successfully allocated descriptor sets.");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
{
|
||||
VkDescriptorBufferInfo BufferInfo{};
|
||||
BufferInfo.buffer = VertexBuffer.GetUniformBuffers()[i];
|
||||
BufferInfo.offset = 0;
|
||||
BufferInfo.range = sizeof(UniformBufferObject);
|
||||
|
||||
VkWriteDescriptorSet DescriptorWrite{};
|
||||
DescriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
DescriptorWrite.dstSet = DescriptorSets[i];
|
||||
DescriptorWrite.dstBinding = 0;
|
||||
DescriptorWrite.dstArrayElement = 0;
|
||||
DescriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
DescriptorWrite.descriptorCount = 1;
|
||||
DescriptorWrite.pBufferInfo = &BufferInfo;
|
||||
DescriptorWrite.pImageInfo = nullptr;
|
||||
DescriptorWrite.pTexelBufferView = nullptr;
|
||||
|
||||
vkUpdateDescriptorSets(DeviceManager.GetDevice(), 1, &DescriptorWrite, 0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanContext::CreateImage(
|
||||
uint32_t Width,
|
||||
uint32_t Height,
|
||||
VkFormat Format,
|
||||
VkImageTiling Tiling,
|
||||
VkImageUsageFlags Usage,
|
||||
VkMemoryPropertyFlags Properties,
|
||||
VkImage& Image,
|
||||
VkDeviceMemory& ImageMemory)
|
||||
{
|
||||
|
||||
VkImageCreateInfo ImageInfo{};
|
||||
ImageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
ImageInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
ImageInfo.extent.width = Width;
|
||||
ImageInfo.extent.height = Height;
|
||||
ImageInfo.extent.depth = 1;
|
||||
ImageInfo.mipLevels = 1;
|
||||
ImageInfo.arrayLayers = 1;
|
||||
ImageInfo.format = Format;
|
||||
ImageInfo.tiling = Tiling;
|
||||
ImageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
ImageInfo.usage = Usage;
|
||||
ImageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
ImageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
if (vkCreateImage(DeviceManager.GetDevice(), &ImageInfo, nullptr, &Image) != VK_SUCCESS)
|
||||
{
|
||||
Log::Error("Failed to create image!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Info("Successfully created image.");
|
||||
}
|
||||
|
||||
VkMemoryRequirements MemoryRequirements;
|
||||
vkGetImageMemoryRequirements(DeviceManager.GetDevice(), Image, &MemoryRequirements);
|
||||
|
||||
VkMemoryAllocateInfo AllocateInfo{};
|
||||
AllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
AllocateInfo.allocationSize = MemoryRequirements.size;
|
||||
AllocateInfo.memoryTypeIndex = VertexBuffer.FindMemoryType(MemoryRequirements.memoryTypeBits, Properties);
|
||||
|
||||
if (vkAllocateMemory(DeviceManager.GetDevice(), &AllocateInfo, nullptr, &ImageMemory) != VK_SUCCESS)
|
||||
{
|
||||
Log::Error("Failed to allocate image memory!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Info("Successfully allocated imaged memory.");
|
||||
}
|
||||
|
||||
vkBindImageMemory(DeviceManager.GetDevice(), Image, ImageMemory, 0);
|
||||
}
|
||||
|
||||
void VulkanContext::CreateTextureImage(const char* FileName)
|
||||
{
|
||||
int TextureWidth, TextureHeight, TextureChannels;
|
||||
stbi_uc* Pixels = stbi_load(FileName, &TextureWidth, &TextureHeight, &TextureChannels, STBI_rgb_alpha);
|
||||
VkDeviceSize ImageSize = TextureWidth * TextureHeight * 4;
|
||||
|
||||
if (!Pixels)
|
||||
{
|
||||
Log::Error("Failed to load texture image!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Info("Successfully loaded texture image.");
|
||||
}
|
||||
|
||||
VkBuffer StagingBuffer;
|
||||
VkDeviceMemory StagingBufferMemory;
|
||||
|
||||
VertexBuffer.CreateBuffer(ImageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, StagingBuffer, StagingBufferMemory);
|
||||
|
||||
void* Data;
|
||||
vkMapMemory(DeviceManager.GetDevice(), StagingBufferMemory, 0, ImageSize, 0, &Data);
|
||||
memcpy(Data, Pixels, static_cast<size_t>(ImageSize));
|
||||
vkUnmapMemory(DeviceManager.GetDevice(), StagingBufferMemory);
|
||||
|
||||
stbi_image_free(Pixels);
|
||||
|
||||
CreateImage(
|
||||
TextureWidth,
|
||||
TextureHeight,
|
||||
VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
TextureImage,
|
||||
TextureImageMemory);
|
||||
}
|
||||
|
||||
void VulkanContext::CreateSyncObjects()
|
||||
{
|
||||
ImageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
@@ -211,7 +423,7 @@ void VulkanContext::CreateSyncObjects()
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanContext::DrawFrame(bool bDrawImGui, uint32_t InVerticesSize)
|
||||
void VulkanContext::DrawFrame(bool bDrawImGui, uint32_t InVerticesSize, uint32_t InIndexSize)
|
||||
{
|
||||
vkWaitForFences(DeviceManager.GetDevice(), 1, &InFlightFences[CurrentFrame], VK_TRUE, UINT64_MAX);
|
||||
|
||||
@@ -243,16 +455,22 @@ void VulkanContext::DrawFrame(bool bDrawImGui, uint32_t InVerticesSize)
|
||||
ImageIndex,
|
||||
VertexBuffer.GetVertexBuffer(),
|
||||
InVerticesSize,
|
||||
VertexBuffer.GetIndexBuffer(),
|
||||
InIndexSize,
|
||||
RenderPass.GetRenderPass(),
|
||||
SwapChain.GetSwapChainExtent(),
|
||||
GraphicsPipeline.GetGraphicsPipeline(),
|
||||
Framebuffers.GetSwapChainFrameBuffers(),
|
||||
DescriptorSets[CurrentFrame],
|
||||
GraphicsPipeline.GetPipelineLayout(),
|
||||
bDrawImGui
|
||||
// DrawData
|
||||
};
|
||||
|
||||
CommandBuffers.RecordCommandBuffer(Params);
|
||||
|
||||
UpdateUniformBuffer(CurrentFrame);
|
||||
|
||||
VkSubmitInfo SubmitInfo{};
|
||||
SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
|
||||
@@ -302,6 +520,23 @@ void VulkanContext::DrawFrame(bool bDrawImGui, uint32_t InVerticesSize)
|
||||
CurrentFrame = (CurrentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||
}
|
||||
|
||||
void VulkanContext::UpdateUniformBuffer(uint32_t CurrentImage)
|
||||
{
|
||||
static auto StartTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto CurrentTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
float Time = std::chrono::duration<float, std::chrono::seconds::period>(CurrentTime - StartTime).count();
|
||||
|
||||
UniformBufferObject Ubo{};
|
||||
Ubo.Model = glm::rotate(glm::mat4(1.0f), Time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
Ubo.View = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
Ubo.Projection = glm::perspective(glm::radians(45.0f), SwapChain.GetSwapChainExtent().width / (float)SwapChain.GetSwapChainExtent().height, 0.1f, 10.0f);
|
||||
Ubo.Projection[1][1] *= -1;
|
||||
|
||||
memcpy(VertexBuffer.GetUniformBuffersMapped()[CurrentImage], &Ubo, sizeof(Ubo));
|
||||
}
|
||||
|
||||
void VulkanContext::RecreateSwapChain()
|
||||
{
|
||||
int Width = 0, Height = 0;
|
||||
|
||||
Reference in New Issue
Block a user