Add namespace to all classes
This commit is contained in:
@@ -192,7 +192,6 @@
|
|||||||
<ClInclude Include="src\VertexBuffer.h" />
|
<ClInclude Include="src\VertexBuffer.h" />
|
||||||
<ClInclude Include="src\VertexDescriptor.h" />
|
<ClInclude Include="src\VertexDescriptor.h" />
|
||||||
<ClInclude Include="src\VulkanException.h" />
|
<ClInclude Include="src\VulkanException.h" />
|
||||||
<ClInclude Include="src\Window.h" />
|
|
||||||
<ClInclude Include="src\VertexPassthrough.h" />
|
<ClInclude Include="src\VertexPassthrough.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -50,9 +50,6 @@
|
|||||||
<ClInclude Include="src\Instance.h">
|
<ClInclude Include="src\Instance.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="src\Window.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="src\Timer.h">
|
<ClInclude Include="src\Timer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
@@ -0,0 +1,239 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Buffer.h"
|
||||||
|
#include "DescriptorPool.h"
|
||||||
|
#include "DescriptorSet.h"
|
||||||
|
#include "Framebuffer.h"
|
||||||
|
#include "IndexBuffer.h"
|
||||||
|
#include "Instance.h"
|
||||||
|
#include "Pipeline.h"
|
||||||
|
#include "Texture2D.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
#include "UniformBuffer.h"
|
||||||
|
#include "Vertex.h"
|
||||||
|
#include "VertexBuffer.h"
|
||||||
|
#include "VertexPassthrough.h"
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Copium
|
||||||
|
{
|
||||||
|
const std::vector<Vertex> vertices = {
|
||||||
|
Vertex{{-0.5f, 0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
|
||||||
|
Vertex{{ 0.5f, 0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
|
||||||
|
Vertex{{ 0.5f, 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
|
||||||
|
Vertex{{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
|
||||||
|
Vertex{{-0.5f, 0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
|
||||||
|
Vertex{{ 0.5f, 0.0f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
|
||||||
|
Vertex{{ 0.5f, 0.0f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
|
||||||
|
Vertex{{-0.5f, 0.0f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<uint16_t> indices = {
|
||||||
|
0, 1, 2, 2, 3, 0,
|
||||||
|
4, 5, 6, 6, 7, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<VertexPassthrough> verticesPassthrough = {
|
||||||
|
VertexPassthrough{{-1.0f, -1.0f}},
|
||||||
|
VertexPassthrough{{ 1.0f, -1.0f}},
|
||||||
|
VertexPassthrough{{ 1.0f, 1.0f}},
|
||||||
|
VertexPassthrough{{-1.0f, 1.0f}},
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<uint16_t> indicesPassthrough = {
|
||||||
|
0, 1, 2, 2, 3, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct alignas(64) ShaderUniform
|
||||||
|
{
|
||||||
|
alignas(16) glm::mat4 projection;
|
||||||
|
alignas(16) glm::mat4 view;
|
||||||
|
alignas(16) glm::mat4 model;
|
||||||
|
alignas(16) glm::vec3 lightPos;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Application final
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Instance> instance;
|
||||||
|
std::unique_ptr<Pipeline> graphicsPipeline;
|
||||||
|
std::unique_ptr<Texture2D> texture2D;
|
||||||
|
std::unique_ptr<UniformBuffer> shaderUniformBuffer;
|
||||||
|
std::unique_ptr<DescriptorPool> descriptorPool;
|
||||||
|
std::unique_ptr<DescriptorSet> descriptorSet;
|
||||||
|
std::unique_ptr<VertexBuffer> vertexBuffer;
|
||||||
|
std::unique_ptr<IndexBuffer> indexBuffer;
|
||||||
|
std::unique_ptr<CommandBuffer> commandBuffer;
|
||||||
|
|
||||||
|
std::unique_ptr<Framebuffer> framebuffer;
|
||||||
|
std::unique_ptr<Pipeline> graphicsPipelinePassthrough;
|
||||||
|
std::unique_ptr<VertexBuffer> vertexBufferPassthrough;
|
||||||
|
std::unique_ptr<IndexBuffer> indexBufferPassthrough;
|
||||||
|
std::unique_ptr<DescriptorSet> descriptorSetPassthrough;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Application()
|
||||||
|
{
|
||||||
|
InitializeInstance();
|
||||||
|
InitializeFrameBuffer();
|
||||||
|
InitializeGraphicsPipeline();
|
||||||
|
InitializeTextureSampler();
|
||||||
|
InitializeUniformBuffer();
|
||||||
|
InitializeDescriptorSets();
|
||||||
|
InitializeVertexBuffer();
|
||||||
|
InitializeIndexBuffer();
|
||||||
|
InitializeCommandBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
~Application()
|
||||||
|
{
|
||||||
|
vkDeviceWaitIdle(instance->GetDevice());
|
||||||
|
}
|
||||||
|
|
||||||
|
Application(Application&&) = delete;
|
||||||
|
Application(const Application&) = delete;
|
||||||
|
Application& operator=(Application&&) = delete;
|
||||||
|
Application& operator=(const Application&) = delete;
|
||||||
|
|
||||||
|
bool Update()
|
||||||
|
{
|
||||||
|
if (!instance->BeginPresent())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
RecordCommandBuffer();
|
||||||
|
commandBuffer->SubmitAsGraphicsQueue();
|
||||||
|
|
||||||
|
return instance->EndPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void InitializeInstance()
|
||||||
|
{
|
||||||
|
instance = std::make_unique<Instance>("Copium Engine");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeFrameBuffer()
|
||||||
|
{
|
||||||
|
framebuffer = std::make_unique<Framebuffer>(*instance, instance->GetSwapChain().GetExtent().width, instance->GetSwapChain().GetExtent().height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeTextureSampler()
|
||||||
|
{
|
||||||
|
texture2D = std::make_unique<Texture2D>(*instance, "res/textures/texture.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeUniformBuffer()
|
||||||
|
{
|
||||||
|
shaderUniformBuffer = std::make_unique<UniformBuffer>(*instance, sizeof(ShaderUniform));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeDescriptorSets()
|
||||||
|
{
|
||||||
|
descriptorPool = std::make_unique<DescriptorPool>(*instance);
|
||||||
|
|
||||||
|
descriptorSet = std::make_unique<DescriptorSet>(*instance, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
|
||||||
|
descriptorSet->AddUniform(*shaderUniformBuffer, 0);
|
||||||
|
descriptorSet->AddTexture2D(*texture2D, 1);
|
||||||
|
|
||||||
|
descriptorSetPassthrough = std::make_unique<DescriptorSet>(*instance, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
|
||||||
|
descriptorSetPassthrough->AddTexture2D(framebuffer->GetTexture2D(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeGraphicsPipeline()
|
||||||
|
{
|
||||||
|
PipelineCreator creator{framebuffer->GetRenderPass(), "res/shaders/shader.vert", "res/shaders/shader.frag"};
|
||||||
|
creator.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT);
|
||||||
|
creator.AddDescriptorSetLayoutBinding(0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
|
creator.SetVertexDescriptor(Vertex::GetDescriptor());
|
||||||
|
creator.SetCullMode(VK_CULL_MODE_NONE);
|
||||||
|
graphicsPipeline = std::make_unique<Pipeline>(*instance, creator);
|
||||||
|
|
||||||
|
PipelineCreator creatorPassthrough{instance->GetSwapChain().GetRenderPass(), "res/shaders/passthrough.vert", "res/shaders/passthrough.frag"};
|
||||||
|
creatorPassthrough.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
|
creatorPassthrough.SetVertexDescriptor(VertexPassthrough::GetDescriptor());
|
||||||
|
creatorPassthrough.SetCullMode(VK_CULL_MODE_NONE);
|
||||||
|
graphicsPipelinePassthrough = std::make_unique<Pipeline>(*instance, creatorPassthrough);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeVertexBuffer()
|
||||||
|
{
|
||||||
|
vertexBuffer = std::make_unique<VertexBuffer>(*instance, Vertex::GetDescriptor(), vertices.size());
|
||||||
|
vertexBuffer->Update(0, (void*)vertices.data());
|
||||||
|
|
||||||
|
vertexBufferPassthrough = std::make_unique<VertexBuffer>(*instance, VertexPassthrough::GetDescriptor(), verticesPassthrough.size());
|
||||||
|
vertexBufferPassthrough->Update(0, (void*)verticesPassthrough.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeIndexBuffer()
|
||||||
|
{
|
||||||
|
indexBuffer = std::make_unique<IndexBuffer>(*instance, indices.size());
|
||||||
|
indexBuffer->UpdateStaging((void*)indices.data());
|
||||||
|
|
||||||
|
indexBufferPassthrough = std::make_unique<IndexBuffer>(*instance, indicesPassthrough.size());
|
||||||
|
indexBufferPassthrough->UpdateStaging((void*)indicesPassthrough.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeCommandBuffer()
|
||||||
|
{
|
||||||
|
commandBuffer = std::make_unique<CommandBuffer>(*instance, CommandBuffer::Type::Dynamic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecordCommandBuffer()
|
||||||
|
{
|
||||||
|
commandBuffer->Begin();
|
||||||
|
std::vector<VkClearValue> clearValues{2};
|
||||||
|
clearValues[0].color = {{0.0f, 0.0f, 0.0f, 1.0f}};
|
||||||
|
clearValues[1].depthStencil = {1.0f, 0};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
framebuffer->Bind(*commandBuffer);
|
||||||
|
graphicsPipeline->Bind(*commandBuffer);
|
||||||
|
|
||||||
|
UpdateUniformBuffer();
|
||||||
|
|
||||||
|
vertexBuffer->Bind(*commandBuffer);
|
||||||
|
indexBuffer->Bind(*commandBuffer);
|
||||||
|
|
||||||
|
graphicsPipeline->SetDescriptorSet(0, *descriptorSet);
|
||||||
|
graphicsPipeline->BindDescriptorSets(commandBuffer->GetHandle());
|
||||||
|
|
||||||
|
indexBuffer->Draw(*commandBuffer);
|
||||||
|
framebuffer->Unbind(*commandBuffer);
|
||||||
|
|
||||||
|
instance->GetSwapChain().BeginFrameBuffer(*commandBuffer);
|
||||||
|
|
||||||
|
graphicsPipelinePassthrough->Bind(*commandBuffer);
|
||||||
|
graphicsPipelinePassthrough->SetDescriptorSet(0, *descriptorSetPassthrough);
|
||||||
|
graphicsPipelinePassthrough->BindDescriptorSets(commandBuffer->GetHandle());
|
||||||
|
vertexBufferPassthrough->Bind(*commandBuffer);
|
||||||
|
indexBufferPassthrough->Bind(*commandBuffer);
|
||||||
|
indexBufferPassthrough->Draw(*commandBuffer);
|
||||||
|
|
||||||
|
instance->GetSwapChain().EndFrameBuffer(*commandBuffer);
|
||||||
|
commandBuffer->End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateUniformBuffer()
|
||||||
|
{
|
||||||
|
static Timer startTimer;
|
||||||
|
|
||||||
|
float time = startTimer.Elapsed();
|
||||||
|
ShaderUniform shaderUniform;
|
||||||
|
shaderUniform.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
shaderUniform.projection = glm::perspective(glm::radians(45.0f), instance->GetSwapChain().GetExtent().width / (float)instance->GetSwapChain().GetExtent().height, 0.1f, 10.0f);
|
||||||
|
shaderUniform.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
shaderUniform.projection[1][1] *= -1;
|
||||||
|
shaderUniform.lightPos = glm::rotate(glm::mat4{1.0f}, time * glm::radians(45.0f), glm::vec3(0, 1, 0)) * glm::vec4{0.3, 0.1, 0, 1};
|
||||||
|
|
||||||
|
shaderUniformBuffer->Update(shaderUniform);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
+7
-4
@@ -5,10 +5,12 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
class Buffer
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class Buffer
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Buffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Buffer);
|
||||||
protected:
|
protected:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
VkDeviceMemory memory;
|
VkDeviceMemory memory;
|
||||||
@@ -18,7 +20,7 @@ protected:
|
|||||||
|
|
||||||
void* mappedData = nullptr;
|
void* mappedData = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count)
|
Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count)
|
||||||
: instance{instance}, size{size}, count{count}
|
: instance{instance}, size{size}, count{count}
|
||||||
{
|
{
|
||||||
@@ -167,4 +169,5 @@ public:
|
|||||||
|
|
||||||
vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), 1, &commandBuffer);
|
vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), 1, &commandBuffer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
+18
-15
@@ -4,26 +4,28 @@
|
|||||||
#include "Instance.h"
|
#include "Instance.h"
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
enum class CommandBufferType
|
namespace Copium
|
||||||
{
|
|
||||||
SingleUse, Dynamic
|
|
||||||
};
|
|
||||||
|
|
||||||
class CommandBuffer
|
|
||||||
{
|
{
|
||||||
|
class CommandBuffer
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBuffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBuffer);
|
||||||
private:
|
public:
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
SingleUse, Dynamic
|
||||||
|
};
|
||||||
|
private:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
std::vector<VkCommandBuffer> commandBuffers;
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
const CommandBufferType type;
|
const Type type;
|
||||||
VkCommandBuffer currentCommandBuffer{VK_NULL_HANDLE};
|
VkCommandBuffer currentCommandBuffer{VK_NULL_HANDLE};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CommandBuffer(Instance& instance, CommandBufferType type)
|
CommandBuffer(Instance& instance, Type type)
|
||||||
: instance{instance}, type{type}
|
: instance{instance}, type{type}
|
||||||
{
|
{
|
||||||
if (type == CommandBufferType::Dynamic)
|
if (type == Type::Dynamic)
|
||||||
commandBuffers.resize(instance.GetMaxFramesInFlight());
|
commandBuffers.resize(instance.GetMaxFramesInFlight());
|
||||||
else
|
else
|
||||||
commandBuffers.resize(1);
|
commandBuffers.resize(1);
|
||||||
@@ -53,13 +55,13 @@ public:
|
|||||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
beginInfo.flags = 0;
|
beginInfo.flags = 0;
|
||||||
beginInfo.pInheritanceInfo = nullptr;
|
beginInfo.pInheritanceInfo = nullptr;
|
||||||
switch(type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case CommandBufferType::SingleUse:
|
case Type::SingleUse:
|
||||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
currentCommandBuffer = commandBuffers.front();
|
currentCommandBuffer = commandBuffers.front();
|
||||||
break;
|
break;
|
||||||
case CommandBufferType::Dynamic:
|
case Type::Dynamic:
|
||||||
currentCommandBuffer = commandBuffers[instance.GetFlightIndex()];
|
currentCommandBuffer = commandBuffers[instance.GetFlightIndex()];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -96,4 +98,5 @@ public:
|
|||||||
{
|
{
|
||||||
return currentCommandBuffer;
|
return currentCommandBuffer;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,12 +3,14 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "CommandBuffer.h"
|
#include "CommandBuffer.h"
|
||||||
|
|
||||||
class CommandBufferScoped : public CommandBuffer
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class CommandBufferScoped : public CommandBuffer
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBufferScoped);
|
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBufferScoped);
|
||||||
public:
|
public:
|
||||||
CommandBufferScoped(Instance& instance)
|
CommandBufferScoped(Instance& instance)
|
||||||
: CommandBuffer{instance, CommandBufferType::SingleUse}
|
: CommandBuffer{instance, Type::SingleUse}
|
||||||
{
|
{
|
||||||
CommandBuffer::Begin();
|
CommandBuffer::Begin();
|
||||||
}
|
}
|
||||||
@@ -18,4 +20,5 @@ public:
|
|||||||
CommandBuffer::End();
|
CommandBuffer::End();
|
||||||
CommandBuffer::Submit();
|
CommandBuffer::Submit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
+21
-19
@@ -3,29 +3,29 @@
|
|||||||
#include "VulkanException.h"
|
#include "VulkanException.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#define TERM_RED "\x1B[31m"
|
#define CP_TERM_RED "\x1B[31m"
|
||||||
#define TERM_GREEN "\x1B[32m"
|
#define CP_TERM_GREEN "\x1B[32m"
|
||||||
#define TERM_YELLOW "\x1B[33m"
|
#define CP_TERM_YELLOW "\x1B[33m"
|
||||||
#define TERM_GRAY "\x1B[90m"
|
#define CP_TERM_GRAY "\x1B[90m"
|
||||||
#define TERM_CLEAR "\033[0m"
|
#define CP_TERM_CLEAR "\033[0m"
|
||||||
|
|
||||||
#define CP_DEBUG(format, ...) std::cout << TERM_GRAY << "[DBG] " << StringFormat(format, __VA_ARGS__) << TERM_CLEAR << std::endl
|
#define CP_DEBUG(format, ...) std::cout << CP_TERM_GRAY << "[DBG] " << Copium::StringFormat(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||||
#define CP_INFO(format, ...) std::cout << "[INF] " << StringFormat(format, __VA_ARGS__) << std::endl
|
#define CP_INFO(format, ...) std::cout << "[INF] " << Copium::StringFormat(format, __VA_ARGS__) << std::endl
|
||||||
#define CP_WARN(format, ...) std::cout << TERM_YELLOW << "[WRN] " << StringFormat(format, __VA_ARGS__) << TERM_CLEAR << std::endl
|
#define CP_WARN(format, ...) std::cout << CP_TERM_YELLOW << "[WRN] " << Copium::StringFormat(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||||
#define CP_ERR(format, ...) std::cout << TERM_RED << "[ERR] " << StringFormat(format, __VA_ARGS__) << TERM_CLEAR << std::endl
|
#define CP_ERR(format, ...) std::cout << CP_TERM_RED << "[ERR] " << Copium::StringFormat(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||||
|
|
||||||
// Continue traces, will not print the [XXX] tag before the log
|
// Continue traces, will not print the [XXX] tag before the log
|
||||||
#define CP_DEBUG_CONT(format, ...) std::cout << TERM_GRAY << " " << StringFormat(format, __VA_ARGS__) << TERM_CLEAR << std::endl
|
#define CP_DEBUG_CONT(format, ...) std::cout << CP_TERM_GRAY << " " << Copium::StringFormat(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||||
#define CP_INFO_CONT(format, ...) std::cout << " " << StringFormat(format, __VA_ARGS__) << std::endl
|
#define CP_INFO_CONT(format, ...) std::cout << " " << Copium::StringFormat(format, __VA_ARGS__) << std::endl
|
||||||
#define CP_WARN_CONT(format, ...) std::cout << TERM_YELLOW << " " << StringFormat(format, __VA_ARGS__) << TERM_CLEAR << std::endl
|
#define CP_WARN_CONT(format, ...) std::cout << CP_TERM_YELLOW << " " << Copium::StringFormat(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||||
#define CP_ERR_CONT(format, ...) std::cout << TERM_RED << " " << StringFormat(format, __VA_ARGS__) << TERM_CLEAR << std::endl
|
#define CP_ERR_CONT(format, ...) std::cout << CP_TERM_RED << " " << Copium::StringFormat(format, __VA_ARGS__) << CP_TERM_CLEAR << std::endl
|
||||||
|
|
||||||
#define CP_UNIMPLEMENTED() CP_WARN("%s is unimplemented", __FUNCTION__)
|
#define CP_UNIMPLEMENTED() CP_WARN("%s is unimplemented", __FUNCTION__)
|
||||||
#define CP_ABORT(format, ...) \
|
#define CP_ABORT(format, ...) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
CP_ERR(format, __VA_ARGS__); \
|
CP_ERR(format, __VA_ARGS__); \
|
||||||
throw std::runtime_error(StringFormat(format, __VA_ARGS__)); \
|
throw std::runtime_error(Copium::StringFormat(format, __VA_ARGS__)); \
|
||||||
} while(false)
|
} while(false)
|
||||||
#define CP_ASSERT(Function, format, ...) \
|
#define CP_ASSERT(Function, format, ...) \
|
||||||
do \
|
do \
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
if(!(Function)) \
|
if(!(Function)) \
|
||||||
{ \
|
{ \
|
||||||
CP_ERR(format, __VA_ARGS__); \
|
CP_ERR(format, __VA_ARGS__); \
|
||||||
throw std::runtime_error(StringFormat(format, __VA_ARGS__)); \
|
throw std::runtime_error(Copium::StringFormat(format, __VA_ARGS__)); \
|
||||||
} \
|
} \
|
||||||
} while(false)
|
} while(false)
|
||||||
#define CP_VK_ASSERT(Function, format, ...) \
|
#define CP_VK_ASSERT(Function, format, ...) \
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
if(Function != VK_SUCCESS) \
|
if(Function != VK_SUCCESS) \
|
||||||
{ \
|
{ \
|
||||||
CP_ERR(format, __VA_ARGS__); \
|
CP_ERR(format, __VA_ARGS__); \
|
||||||
throw VulkanException(StringFormat(format, __VA_ARGS__)); \
|
throw VulkanException(Copium::StringFormat(format, __VA_ARGS__)); \
|
||||||
} \
|
} \
|
||||||
} while(false)
|
} while(false)
|
||||||
#define CP_DELETE_COPY_AND_MOVE_CTOR(ClassName) \
|
#define CP_DELETE_COPY_AND_MOVE_CTOR(ClassName) \
|
||||||
@@ -51,13 +51,15 @@
|
|||||||
ClassName& operator=(ClassName&&) = delete; \
|
ClassName& operator=(ClassName&&) = delete; \
|
||||||
ClassName& operator=(const ClassName&) = delete
|
ClassName& operator=(const ClassName&) = delete
|
||||||
|
|
||||||
template<typename ... Args>
|
namespace Copium
|
||||||
std::string StringFormat(const std::string& format, Args... args)
|
|
||||||
{
|
{
|
||||||
|
template<typename ... Args>
|
||||||
|
std::string StringFormat(const std::string& format, Args... args)
|
||||||
|
{
|
||||||
int size = std::snprintf(nullptr, 0, format.c_str(), args...) + 1;
|
int size = std::snprintf(nullptr, 0, format.c_str(), args...) + 1;
|
||||||
CP_ASSERT(size > 0, "Error during formatting");
|
CP_ASSERT(size > 0, "Error during formatting");
|
||||||
std::unique_ptr<char[]> buf(new char[size]);
|
std::unique_ptr<char[]> buf(new char[size]);
|
||||||
std::snprintf(buf.get(), size, format.c_str(), args...);
|
std::snprintf(buf.get(), size, format.c_str(), args...);
|
||||||
return std::string(buf.get(), buf.get() + size - 1);
|
return std::string(buf.get(), buf.get() + size - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-13
@@ -1,18 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
namespace Copium
|
||||||
class DebugMessenger
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class DebugMessenger
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(DebugMessenger);
|
CP_DELETE_COPY_AND_MOVE_CTOR(DebugMessenger);
|
||||||
public:
|
public:
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
VkDebugUtilsMessengerEXT debugMessenger;
|
VkDebugUtilsMessengerEXT debugMessenger;
|
||||||
|
|
||||||
DebugMessenger(VkInstance instance)
|
DebugMessenger(VkInstance instance)
|
||||||
: instance{instance}
|
: instance{instance}
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
VkDebugUtilsMessengerCreateInfoEXT createInfo{};
|
VkDebugUtilsMessengerCreateInfoEXT createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||||
createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
|
||||||
@@ -24,31 +26,31 @@ public:
|
|||||||
createInfo.pfnUserCallback = DebugCallback;
|
createInfo.pfnUserCallback = DebugCallback;
|
||||||
createInfo.pUserData = nullptr;
|
createInfo.pUserData = nullptr;
|
||||||
CP_VK_ASSERT(vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger), "Failed to initialze debug messenger");
|
CP_VK_ASSERT(vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger), "Failed to initialze debug messenger");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~DebugMessenger()
|
~DebugMessenger()
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
vkDestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
|
vkDestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddRequiredExtensions(std::vector<const char*>* extensions)
|
static void AddRequiredExtensions(std::vector<const char*>* extensions)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
extensions->emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
extensions->emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddRequiredLayers(std::vector<const char*>* layers)
|
static void AddRequiredLayers(std::vector<const char*>* layers)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
layers->emplace_back("VK_LAYER_KHRONOS_validation");
|
layers->emplace_back("VK_LAYER_KHRONOS_validation");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||||
@@ -85,4 +87,5 @@ private:
|
|||||||
func(instance, debugMessenger, pAllocator);
|
func(instance, debugMessenger, pAllocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,15 +4,17 @@
|
|||||||
#include "Instance.h"
|
#include "Instance.h"
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
class DescriptorPool final
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class DescriptorPool final
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorPool);
|
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorPool);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
VkDescriptorPool descriptorPool;
|
VkDescriptorPool descriptorPool;
|
||||||
static const int DESCRIPTOR_SET_COUNT = 100;
|
static const int DESCRIPTOR_SET_COUNT = 100;
|
||||||
public:
|
public:
|
||||||
DescriptorPool(Instance& instance)
|
DescriptorPool(Instance& instance)
|
||||||
: instance{instance}
|
: instance{instance}
|
||||||
{
|
{
|
||||||
@@ -58,4 +60,5 @@ public:
|
|||||||
{
|
{
|
||||||
vkFreeDescriptorSets(instance.GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data());
|
vkFreeDescriptorSets(instance.GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,17 +6,19 @@
|
|||||||
#include "UniformBuffer.h"
|
#include "UniformBuffer.h"
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
class DescriptorSet final
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class DescriptorSet final
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorSet);
|
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorSet);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
DescriptorPool& descriptorPool;
|
DescriptorPool& descriptorPool;
|
||||||
VkDescriptorSetLayout descriptorSetLayout;
|
VkDescriptorSetLayout descriptorSetLayout;
|
||||||
|
|
||||||
std::vector<VkDescriptorSet> descriptorSets;
|
std::vector<VkDescriptorSet> descriptorSets;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout)
|
DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout)
|
||||||
: instance{instance}, descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout}
|
: instance{instance}, descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout}
|
||||||
{
|
{
|
||||||
@@ -69,4 +71,5 @@ public:
|
|||||||
{
|
{
|
||||||
return descriptorSets[instance.GetFlightIndex()];
|
return descriptorSets[instance.GetFlightIndex()];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
@@ -8,14 +8,18 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
namespace FileSystem
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class FileSystem
|
||||||
|
{
|
||||||
|
FileSystem() = delete;
|
||||||
|
public:
|
||||||
static std::vector<char> ReadFile(const std::string& filename)
|
static std::vector<char> ReadFile(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
||||||
CP_ASSERT(file.is_open(), "Failed to open file");
|
CP_ASSERT(file.is_open(), "Failed to open file");
|
||||||
|
|
||||||
size_t fileSize = (size_t) file.tellg();
|
size_t fileSize = (size_t)file.tellg();
|
||||||
std::vector<char> buffer(fileSize);
|
std::vector<char> buffer(fileSize);
|
||||||
|
|
||||||
file.seekg(0);
|
file.seekg(0);
|
||||||
@@ -29,7 +33,7 @@ namespace FileSystem
|
|||||||
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
||||||
CP_ASSERT(file.is_open(), "Failed to open file");
|
CP_ASSERT(file.is_open(), "Failed to open file");
|
||||||
|
|
||||||
size_t fileSize = (size_t) file.tellg();
|
size_t fileSize = (size_t)file.tellg();
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
buffer.resize(fileSize);
|
buffer.resize(fileSize);
|
||||||
|
|
||||||
@@ -69,4 +73,5 @@ namespace FileSystem
|
|||||||
CP_ASSERT(stat(filename.c_str(), &result) == 0, "Cannot stat file %s", filename.c_str());
|
CP_ASSERT(stat(filename.c_str(), &result) == 0, "Cannot stat file %s", filename.c_str());
|
||||||
return (int64_t)result.st_mtime;
|
return (int64_t)result.st_mtime;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -7,11 +7,13 @@
|
|||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
// TODO: Add resizing (recreate image, depthImage, framebuffers)
|
namespace Copium
|
||||||
class Framebuffer
|
|
||||||
{
|
{
|
||||||
|
// TODO: Add resizing (recreate image, depthImage, framebuffers)
|
||||||
|
class Framebuffer
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
std::unique_ptr<Texture2D> image;
|
std::unique_ptr<Texture2D> image;
|
||||||
@@ -21,7 +23,7 @@ private:
|
|||||||
|
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
public:
|
public:
|
||||||
Framebuffer(Instance& instance, uint32_t width, uint32_t height)
|
Framebuffer(Instance& instance, uint32_t width, uint32_t height)
|
||||||
: instance{instance}, width{width}, height{height}
|
: instance{instance}, width{width}, height{height}
|
||||||
{
|
{
|
||||||
@@ -75,7 +77,7 @@ public:
|
|||||||
return *image;
|
return *image;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void InitializeImages()
|
void InitializeImages()
|
||||||
{
|
{
|
||||||
@@ -171,4 +173,5 @@ private:
|
|||||||
CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize swap chain framebuffer");
|
CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize swap chain framebuffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
+12
-7
@@ -6,10 +6,12 @@
|
|||||||
#include "CommandBufferScoped.h"
|
#include "CommandBufferScoped.h"
|
||||||
#include "Instance.h"
|
#include "Instance.h"
|
||||||
|
|
||||||
class Image
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class Image
|
||||||
|
{
|
||||||
Image() = delete;
|
Image() = delete;
|
||||||
public:
|
public:
|
||||||
static void InitializeImage(Instance& instance, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory)
|
static void InitializeImage(Instance& instance, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory)
|
||||||
{
|
{
|
||||||
VkImageCreateInfo createInfo{};
|
VkImageCreateInfo createInfo{};
|
||||||
@@ -91,7 +93,8 @@ public:
|
|||||||
if (HasStencilComponent(format)) {
|
if (HasStencilComponent(format)) {
|
||||||
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +104,8 @@ public:
|
|||||||
|
|
||||||
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
}
|
||||||
|
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
|
|
||||||
@@ -156,7 +160,7 @@ public:
|
|||||||
return SelectSupportedFormat(instance, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
return SelectSupportedFormat(instance, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool HasStencilComponent(VkFormat format)
|
static bool HasStencilComponent(VkFormat format)
|
||||||
{
|
{
|
||||||
return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
|
return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
|
||||||
@@ -168,7 +172,7 @@ private:
|
|||||||
{
|
{
|
||||||
VkFormatProperties properties;
|
VkFormatProperties properties;
|
||||||
vkGetPhysicalDeviceFormatProperties(instance.GetPhysicalDevice(), format, &properties);
|
vkGetPhysicalDeviceFormatProperties(instance.GetPhysicalDevice(), format, &properties);
|
||||||
if(tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
|
if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
|
||||||
{
|
{
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
@@ -179,4 +183,5 @@ private:
|
|||||||
}
|
}
|
||||||
CP_ABORT("SelectSupportedFormat : Failed to select supported format");
|
CP_ABORT("SelectSupportedFormat : Failed to select supported format");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
@@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
#include "Buffer.h"
|
#include "Buffer.h"
|
||||||
|
|
||||||
class IndexBuffer : public Buffer
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class IndexBuffer : public Buffer
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(IndexBuffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(IndexBuffer);
|
||||||
private:
|
private:
|
||||||
int indexCount;
|
int indexCount;
|
||||||
public:
|
public:
|
||||||
IndexBuffer(Instance& instance, int indexCount)
|
IndexBuffer(Instance& instance, int indexCount)
|
||||||
: Buffer{instance, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexCount * sizeof(uint16_t), 1}, indexCount{indexCount}
|
: Buffer{instance, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexCount * sizeof(uint16_t), 1}, indexCount{indexCount}
|
||||||
{}
|
{}
|
||||||
@@ -21,4 +23,5 @@ public:
|
|||||||
{
|
{
|
||||||
vkCmdDrawIndexed(commandBuffer, indexCount, 1, 0, 0, 0);
|
vkCmdDrawIndexed(commandBuffer, indexCount, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
+10
-7
@@ -9,10 +9,12 @@
|
|||||||
#include "SwapChain.h"
|
#include "SwapChain.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
|
||||||
class Instance final
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class Instance final
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Instance);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Instance);
|
||||||
private:
|
private:
|
||||||
static const int MAX_FRAMES_IN_FLIGHT = 2;
|
static const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||||
static const int WINDOW_WIDTH = 1920;
|
static const int WINDOW_WIDTH = 1920;
|
||||||
static const int WINDOW_HEIGHT = 1080;
|
static const int WINDOW_HEIGHT = 1080;
|
||||||
@@ -38,7 +40,7 @@ private:
|
|||||||
int frameCount = 0;
|
int frameCount = 0;
|
||||||
Timer timer;
|
Timer timer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Instance(const std::string& applicationName)
|
Instance(const std::string& applicationName)
|
||||||
{
|
{
|
||||||
timer.Start();
|
timer.Start();
|
||||||
@@ -170,7 +172,7 @@ public:
|
|||||||
throw std::runtime_error("Failed to find suitable memory type");
|
throw std::runtime_error("Failed to find suitable memory type");
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitializeWindow(const std::string& applicationName)
|
void InitializeWindow(const std::string& applicationName)
|
||||||
{
|
{
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
@@ -278,7 +280,7 @@ private:
|
|||||||
|
|
||||||
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
|
||||||
std::set<uint32_t> uniqueQueueFamilies{query.graphicsFamily.value(), query.presentFamily.value()};
|
std::set<uint32_t> uniqueQueueFamilies{query.graphicsFamily.value(), query.presentFamily.value()};
|
||||||
for(auto&& queueFamily : uniqueQueueFamilies)
|
for (auto&& queueFamily : uniqueQueueFamilies)
|
||||||
{
|
{
|
||||||
VkDeviceQueueCreateInfo queueCreateInfo{};
|
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||||
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
@@ -304,7 +306,7 @@ private:
|
|||||||
graphicsQueueIndex = query.graphicsFamily.value();
|
graphicsQueueIndex = query.graphicsFamily.value();
|
||||||
presentQueueIndex = query.presentFamily.value();
|
presentQueueIndex = query.presentFamily.value();
|
||||||
vkGetDeviceQueue(device, graphicsQueueIndex, 0, &graphicsQueue);
|
vkGetDeviceQueue(device, graphicsQueueIndex, 0, &graphicsQueue);
|
||||||
vkGetDeviceQueue(device, presentQueueIndex , 0, &presentQueue);
|
vkGetDeviceQueue(device, presentQueueIndex, 0, &presentQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeSwapChain()
|
void InitializeSwapChain()
|
||||||
@@ -444,4 +446,5 @@ private:
|
|||||||
Instance* instance = static_cast<Instance*>(glfwGetWindowUserPointer(window));
|
Instance* instance = static_cast<Instance*>(glfwGetWindowUserPointer(window));
|
||||||
instance->framebufferResized = true;
|
instance->framebufferResized = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,11 +11,12 @@
|
|||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
namespace Copium
|
||||||
class Pipeline
|
|
||||||
{
|
{
|
||||||
|
class Pipeline
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Pipeline);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Pipeline);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{};
|
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{};
|
||||||
@@ -23,7 +24,7 @@ private:
|
|||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
VkPipeline graphicsPipeline;
|
VkPipeline graphicsPipeline;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pipeline(Instance& instance, PipelineCreator creator)
|
Pipeline(Instance& instance, PipelineCreator creator)
|
||||||
: instance{instance}
|
: instance{instance}
|
||||||
{
|
{
|
||||||
@@ -75,7 +76,7 @@ public:
|
|||||||
return descriptorSetLayouts[setIndex];
|
return descriptorSetLayouts[setIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitializeDescriptorSetLayout(const PipelineCreator& creator)
|
void InitializeDescriptorSetLayout(const PipelineCreator& creator)
|
||||||
{
|
{
|
||||||
boundDescriptorSets.resize(creator.descriptorSetLayouts.size());
|
boundDescriptorSets.resize(creator.descriptorSetLayouts.size());
|
||||||
@@ -106,7 +107,7 @@ private:
|
|||||||
|
|
||||||
void InitializePipeline(const PipelineCreator& creator)
|
void InitializePipeline(const PipelineCreator& creator)
|
||||||
{
|
{
|
||||||
Shader shader{instance, ShaderType::GlslFile, creator.vertexShader, creator.fragmentShader};
|
Shader shader{instance, Shader::Type::GlslFile, creator.vertexShader, creator.fragmentShader};
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo{};
|
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo{};
|
||||||
vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
@@ -253,4 +254,5 @@ private:
|
|||||||
return shaderModule;
|
return shaderModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
@@ -6,8 +6,10 @@
|
|||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class PipelineCreator
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class PipelineCreator
|
||||||
|
{
|
||||||
struct DescriptorSetBinding
|
struct DescriptorSetBinding
|
||||||
{
|
{
|
||||||
uint32_t binding;
|
uint32_t binding;
|
||||||
@@ -16,7 +18,7 @@ class PipelineCreator
|
|||||||
VkShaderStageFlags flags;
|
VkShaderStageFlags flags;
|
||||||
};
|
};
|
||||||
friend class Pipeline;
|
friend class Pipeline;
|
||||||
private:
|
private:
|
||||||
std::map<uint32_t, std::vector<DescriptorSetBinding>> descriptorSetLayouts{};
|
std::map<uint32_t, std::vector<DescriptorSetBinding>> descriptorSetLayouts{};
|
||||||
|
|
||||||
std::string vertexShader;
|
std::string vertexShader;
|
||||||
@@ -27,7 +29,7 @@ private:
|
|||||||
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
|
VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader)
|
PipelineCreator(VkRenderPass renderPass, const std::string& vertexShader, const std::string& fragmentShader)
|
||||||
: vertexShader{vertexShader}, fragmentShader{fragmentShader}, renderPass{renderPass}
|
: vertexShader{vertexShader}, fragmentShader{fragmentShader}, renderPass{renderPass}
|
||||||
{}
|
{}
|
||||||
@@ -57,4 +59,5 @@ public:
|
|||||||
{
|
{
|
||||||
frontFace = cullFrontFace;
|
frontFace = cullFrontFace;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct QueueFamiliesQuery
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
struct QueueFamiliesQuery
|
||||||
|
{
|
||||||
std::optional<uint32_t> graphicsFamily;
|
std::optional<uint32_t> graphicsFamily;
|
||||||
std::optional<uint32_t> presentFamily;
|
std::optional<uint32_t> presentFamily;
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@ struct QueueFamiliesQuery
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto&& queueFamily : queueFamilies)
|
for (auto&& queueFamily : queueFamilies)
|
||||||
{
|
{
|
||||||
if(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||||
{
|
{
|
||||||
graphicsFamily = i;
|
graphicsFamily = i;
|
||||||
}
|
}
|
||||||
@@ -38,4 +40,5 @@ struct QueueFamiliesQuery
|
|||||||
{
|
{
|
||||||
return graphicsFamily.has_value() && presentFamily.has_value();
|
return graphicsFamily.has_value() && presentFamily.has_value();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
+25
-21
@@ -6,44 +6,47 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Instance.h"
|
#include "Instance.h"
|
||||||
|
|
||||||
enum class ShaderType
|
namespace Copium
|
||||||
{
|
|
||||||
GlslFile, GlslCode, SpvFile, SpvCode
|
|
||||||
};
|
|
||||||
|
|
||||||
class Shader
|
|
||||||
{
|
{
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Shader);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Shader);
|
||||||
private:
|
public:
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
GlslFile, GlslCode, SpvFile, SpvCode
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
VkShaderModule vertShaderModule;
|
VkShaderModule vertShaderModule;
|
||||||
VkShaderModule fragShaderModule;
|
VkShaderModule fragShaderModule;
|
||||||
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
||||||
public:
|
public:
|
||||||
Shader(Instance& instance, ShaderType shaderType, const std::string& vertexInput, const std::string& fragmentInput)
|
Shader(Instance& instance, Type type, const std::string& vertexInput, const std::string& fragmentInput)
|
||||||
: instance{instance}
|
: instance{instance}
|
||||||
{
|
{
|
||||||
switch (shaderType)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ShaderType::GlslCode:
|
case Type::GlslCode:
|
||||||
vertShaderModule = InitializeShaderModuleFromGlslCode(vertexInput, shaderc_vertex_shader);
|
vertShaderModule = InitializeShaderModuleFromGlslCode(vertexInput, shaderc_vertex_shader);
|
||||||
fragShaderModule = InitializeShaderModuleFromGlslCode(fragmentInput, shaderc_fragment_shader);
|
fragShaderModule = InitializeShaderModuleFromGlslCode(fragmentInput, shaderc_fragment_shader);
|
||||||
break;
|
break;
|
||||||
case ShaderType::GlslFile:
|
case Type::GlslFile:
|
||||||
vertShaderModule = InitializeShaderModuleFromGlslFile(vertexInput, shaderc_vertex_shader);
|
vertShaderModule = InitializeShaderModuleFromGlslFile(vertexInput, shaderc_vertex_shader);
|
||||||
fragShaderModule = InitializeShaderModuleFromGlslFile(fragmentInput, shaderc_fragment_shader);
|
fragShaderModule = InitializeShaderModuleFromGlslFile(fragmentInput, shaderc_fragment_shader);
|
||||||
break;
|
break;
|
||||||
case ShaderType::SpvCode:
|
case Type::SpvCode:
|
||||||
vertShaderModule = InitializeShaderModule(vertexInput);
|
vertShaderModule = InitializeShaderModule(vertexInput);
|
||||||
fragShaderModule = InitializeShaderModule(fragmentInput);
|
fragShaderModule = InitializeShaderModule(fragmentInput);
|
||||||
break;
|
break;
|
||||||
case ShaderType::SpvFile:
|
case Type::SpvFile:
|
||||||
vertShaderModule = InitializeShaderModule(FileSystem::ReadFile(vertexInput));
|
vertShaderModule = InitializeShaderModule(FileSystem::ReadFile(vertexInput));
|
||||||
fragShaderModule = InitializeShaderModule(FileSystem::ReadFile(fragmentInput));
|
fragShaderModule = InitializeShaderModule(FileSystem::ReadFile(fragmentInput));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CP_ASSERT(false, "Unreachable switch case %d", (int)shaderType);
|
CP_ASSERT(false, "Unreachable switch case %d", (int)type);
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderStages.resize(2);
|
shaderStages.resize(2);
|
||||||
@@ -71,7 +74,7 @@ public:
|
|||||||
return shaderStages;
|
return shaderStages;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkShaderModule InitializeShaderModule(const std::vector<uint32_t>& codeSpv)
|
VkShaderModule InitializeShaderModule(const std::vector<uint32_t>& codeSpv)
|
||||||
{
|
{
|
||||||
return InitializeShaderModule(codeSpv.data(), codeSpv.size() * sizeof(uint32_t));
|
return InitializeShaderModule(codeSpv.data(), codeSpv.size() * sizeof(uint32_t));
|
||||||
@@ -87,7 +90,7 @@ private:
|
|||||||
return InitializeShaderModule(reinterpret_cast<const uint32_t*>(codeSpv.data()), codeSpv.size());
|
return InitializeShaderModule(reinterpret_cast<const uint32_t*>(codeSpv.data()), codeSpv.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
VkShaderModule InitializeShaderModuleFromGlslFile(const std::string& filename, shaderc_shader_kind shaderType)
|
VkShaderModule InitializeShaderModuleFromGlslFile(const std::string& filename, shaderc_shader_kind type)
|
||||||
{
|
{
|
||||||
std::string spvFilename = ".cache/" + filename + ".spv";
|
std::string spvFilename = ".cache/" + filename + ".spv";
|
||||||
try
|
try
|
||||||
@@ -114,7 +117,7 @@ private:
|
|||||||
options.SetOptimizationLevel(shaderc_optimization_level_size);
|
options.SetOptimizationLevel(shaderc_optimization_level_size);
|
||||||
|
|
||||||
std::vector<char> glslCode = FileSystem::ReadFile(filename);
|
std::vector<char> glslCode = FileSystem::ReadFile(filename);
|
||||||
shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(glslCode.data(), glslCode.size(), shaderType, filename.c_str(), options);
|
shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(glslCode.data(), glslCode.size(), type, filename.c_str(), options);
|
||||||
CP_ASSERT(result.GetCompilationStatus() == shaderc_compilation_status_success, "Failed to compile shader: %s\n%s", filename.c_str(), result.GetErrorMessage().c_str());
|
CP_ASSERT(result.GetCompilationStatus() == shaderc_compilation_status_success, "Failed to compile shader: %s\n%s", filename.c_str(), result.GetErrorMessage().c_str());
|
||||||
|
|
||||||
std::vector<uint32_t> data{result.cbegin(), result.cend()};
|
std::vector<uint32_t> data{result.cbegin(), result.cend()};
|
||||||
@@ -122,14 +125,14 @@ private:
|
|||||||
return InitializeShaderModule(data.data(), data.size() * sizeof(uint32_t));
|
return InitializeShaderModule(data.data(), data.size() * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
VkShaderModule InitializeShaderModuleFromGlslCode(const std::string& code, shaderc_shader_kind shaderType)
|
VkShaderModule InitializeShaderModuleFromGlslCode(const std::string& code, shaderc_shader_kind type)
|
||||||
{
|
{
|
||||||
shaderc::Compiler compiler;
|
shaderc::Compiler compiler;
|
||||||
shaderc::CompileOptions options;
|
shaderc::CompileOptions options;
|
||||||
|
|
||||||
options.SetOptimizationLevel(shaderc_optimization_level_size);
|
options.SetOptimizationLevel(shaderc_optimization_level_size);
|
||||||
|
|
||||||
shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(code.data(), shaderType, "inline_shader_code", options);
|
shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(code.data(), type, "inline_shader_code", options);
|
||||||
CP_ASSERT(result.GetCompilationStatus() == shaderc_compilation_status_success, "Failed to compile inline shader code: %s", result.GetErrorMessage());
|
CP_ASSERT(result.GetCompilationStatus() == shaderc_compilation_status_success, "Failed to compile inline shader code: %s", result.GetErrorMessage());
|
||||||
|
|
||||||
std::vector<uint32_t> data{result.cbegin(), result.cend()};
|
std::vector<uint32_t> data{result.cbegin(), result.cend()};
|
||||||
@@ -148,4 +151,5 @@ private:
|
|||||||
|
|
||||||
return shaderModule;
|
return shaderModule;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
+67
-64
@@ -10,8 +10,10 @@
|
|||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice)
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice)
|
||||||
|
{
|
||||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities);
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities);
|
||||||
|
|
||||||
uint32_t formatCount;
|
uint32_t formatCount;
|
||||||
@@ -29,31 +31,31 @@ SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysica
|
|||||||
presentModes.resize(presentModeCount);
|
presentModes.resize(presentModeCount);
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data());
|
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwapChainSupportDetails::Valid()
|
bool SwapChainSupportDetails::Valid()
|
||||||
{
|
{
|
||||||
return !formats.empty() && !presentModes.empty();
|
return !formats.empty() && !presentModes.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapChain::SwapChain(Instance& instance)
|
SwapChain::SwapChain(Instance& instance)
|
||||||
: instance{instance}
|
: instance{instance}
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
InitializeImageViews();
|
InitializeImageViews();
|
||||||
InitializeDepthBuffer();
|
InitializeDepthBuffer();
|
||||||
InitializeRenderPass();
|
InitializeRenderPass();
|
||||||
InitializeFramebuffers();
|
InitializeFramebuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapChain::~SwapChain()
|
SwapChain::~SwapChain()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
|
vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::BeginFrameBuffer(const CommandBuffer& commandBuffer) const
|
void SwapChain::BeginFrameBuffer(const CommandBuffer& commandBuffer) const
|
||||||
{
|
{
|
||||||
std::vector<VkClearValue> clearValues{2};
|
std::vector<VkClearValue> clearValues{2};
|
||||||
clearValues[0].color = {{0.02f, 0.02f, 0.02f, 1.0f}};
|
clearValues[0].color = {{0.02f, 0.02f, 0.02f, 1.0f}};
|
||||||
clearValues[1].depthStencil = {1.0f, 0};
|
clearValues[1].depthStencil = {1.0f, 0};
|
||||||
@@ -67,35 +69,35 @@ void SwapChain::BeginFrameBuffer(const CommandBuffer& commandBuffer) const
|
|||||||
renderPassBeginInfo.clearValueCount = clearValues.size();
|
renderPassBeginInfo.clearValueCount = clearValues.size();
|
||||||
renderPassBeginInfo.pClearValues = clearValues.data();
|
renderPassBeginInfo.pClearValues = clearValues.data();
|
||||||
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::EndFrameBuffer(const CommandBuffer& commandBuffer) const
|
void SwapChain::EndFrameBuffer(const CommandBuffer& commandBuffer) const
|
||||||
{
|
{
|
||||||
vkCmdEndRenderPass(commandBuffer);
|
vkCmdEndRenderPass(commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSwapchainKHR SwapChain::GetHandle() const
|
VkSwapchainKHR SwapChain::GetHandle() const
|
||||||
{
|
{
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkRenderPass SwapChain::GetRenderPass() const
|
VkRenderPass SwapChain::GetRenderPass() const
|
||||||
{
|
{
|
||||||
return renderPass;
|
return renderPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkExtent2D SwapChain::GetExtent() const
|
VkExtent2D SwapChain::GetExtent() const
|
||||||
{
|
{
|
||||||
return extent;
|
return extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFramebuffer SwapChain::GetFramebuffer() const
|
VkFramebuffer SwapChain::GetFramebuffer() const
|
||||||
{
|
{
|
||||||
return framebuffers[imageIndex];
|
return framebuffers[imageIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwapChain::BeginPresent(VkSemaphore signalSemaphore)
|
bool SwapChain::BeginPresent(VkSemaphore signalSemaphore)
|
||||||
{
|
{
|
||||||
VkResult result = vkAcquireNextImageKHR(instance.GetDevice(), handle, UINT64_MAX, signalSemaphore, VK_NULL_HANDLE, &imageIndex);
|
VkResult result = vkAcquireNextImageKHR(instance.GetDevice(), handle, UINT64_MAX, signalSemaphore, VK_NULL_HANDLE, &imageIndex);
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
{
|
{
|
||||||
@@ -103,10 +105,10 @@ bool SwapChain::BeginPresent(VkSemaphore signalSemaphore)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, bool framebufferResized)
|
void SwapChain::EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, bool framebufferResized)
|
||||||
{
|
{
|
||||||
VkPresentInfoKHR presentInfo{};
|
VkPresentInfoKHR presentInfo{};
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
@@ -121,10 +123,10 @@ void SwapChain::EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, boo
|
|||||||
{
|
{
|
||||||
Recreate();
|
Recreate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::Recreate()
|
void SwapChain::Recreate()
|
||||||
{
|
{
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
glfwGetFramebufferSize(instance.GetWindow(), &width, &height);
|
glfwGetFramebufferSize(instance.GetWindow(), &width, &height);
|
||||||
@@ -142,10 +144,10 @@ void SwapChain::Recreate()
|
|||||||
InitializeImageViews();
|
InitializeImageViews();
|
||||||
InitializeDepthBuffer();
|
InitializeDepthBuffer();
|
||||||
InitializeFramebuffers();
|
InitializeFramebuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::Initialize()
|
void SwapChain::Initialize()
|
||||||
{
|
{
|
||||||
SwapChainSupportDetails swapChainSupport{instance.GetSurface(), instance.GetPhysicalDevice()};
|
SwapChainSupportDetails swapChainSupport{instance.GetSurface(), instance.GetPhysicalDevice()};
|
||||||
|
|
||||||
VkSurfaceFormatKHR format = SelectSwapSurfaceFormat(swapChainSupport.formats);
|
VkSurfaceFormatKHR format = SelectSwapSurfaceFormat(swapChainSupport.formats);
|
||||||
@@ -193,24 +195,24 @@ void SwapChain::Initialize()
|
|||||||
vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, nullptr);
|
vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, nullptr);
|
||||||
images.resize(imageCount);
|
images.resize(imageCount);
|
||||||
vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, images.data());
|
vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, images.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::InitializeImageViews()
|
void SwapChain::InitializeImageViews()
|
||||||
{
|
{
|
||||||
imageViews.resize(images.size());
|
imageViews.resize(images.size());
|
||||||
for (size_t i = 0; i < images.size(); i++)
|
for (size_t i = 0; i < images.size(); i++)
|
||||||
{
|
{
|
||||||
imageViews[i] = Image::InitializeImageView(instance, images[i], imageFormat, VK_IMAGE_ASPECT_COLOR_BIT);
|
imageViews[i] = Image::InitializeImageView(instance, images[i], imageFormat, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::InitializeDepthBuffer()
|
void SwapChain::InitializeDepthBuffer()
|
||||||
{
|
{
|
||||||
depthImage = std::make_unique<Texture2D>(instance, extent.width, extent.height, Texture2D::Type::Static, Texture2D::Format::Depth);
|
depthImage = std::make_unique<Texture2D>(instance, extent.width, extent.height, Texture2D::Type::Static, Texture2D::Format::Depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::InitializeRenderPass()
|
void SwapChain::InitializeRenderPass()
|
||||||
{
|
{
|
||||||
VkAttachmentDescription colorAttachment{};
|
VkAttachmentDescription colorAttachment{};
|
||||||
colorAttachment.format = imageFormat;
|
colorAttachment.format = imageFormat;
|
||||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
@@ -264,10 +266,10 @@ void SwapChain::InitializeRenderPass()
|
|||||||
renderPassCreateInfo.pDependencies = &dependency;
|
renderPassCreateInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "Failed to initialze render pass");
|
CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "Failed to initialze render pass");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::InitializeFramebuffers()
|
void SwapChain::InitializeFramebuffers()
|
||||||
{
|
{
|
||||||
framebuffers.resize(images.size());
|
framebuffers.resize(images.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < imageViews.size(); ++i)
|
for (size_t i = 0; i < imageViews.size(); ++i)
|
||||||
@@ -285,10 +287,10 @@ void SwapChain::InitializeFramebuffers()
|
|||||||
|
|
||||||
CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "Failed to initialize swap chain framebuffer");
|
CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "Failed to initialize swap chain framebuffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::Destroy()
|
void SwapChain::Destroy()
|
||||||
{
|
{
|
||||||
for (auto&& framebuffer : framebuffers)
|
for (auto&& framebuffer : framebuffers)
|
||||||
{
|
{
|
||||||
vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
|
vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
|
||||||
@@ -298,10 +300,10 @@ void SwapChain::Destroy()
|
|||||||
vkDestroyImageView(instance.GetDevice(), swapChainImageView, nullptr);
|
vkDestroyImageView(instance.GetDevice(), swapChainImageView, nullptr);
|
||||||
}
|
}
|
||||||
vkDestroySwapchainKHR(instance.GetDevice(), handle, nullptr);
|
vkDestroySwapchainKHR(instance.GetDevice(), handle, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceFormatKHR SwapChain::SelectSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)
|
VkSurfaceFormatKHR SwapChain::SelectSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)
|
||||||
{
|
{
|
||||||
for (auto&& availableFormat : availableFormats)
|
for (auto&& availableFormat : availableFormats)
|
||||||
{
|
{
|
||||||
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||||
@@ -310,10 +312,10 @@ VkSurfaceFormatKHR SwapChain::SelectSwapSurfaceFormat(const std::vector<VkSurfac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return availableFormats[0];
|
return availableFormats[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPresentModeKHR SwapChain::SelectSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes)
|
VkPresentModeKHR SwapChain::SelectSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes)
|
||||||
{
|
{
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
for (auto&& availablePresentMode : availablePresentModes)
|
for (auto&& availablePresentMode : availablePresentModes)
|
||||||
{
|
{
|
||||||
@@ -325,10 +327,10 @@ VkPresentModeKHR SwapChain::SelectSwapPresentMode(const std::vector<VkPresentMod
|
|||||||
|
|
||||||
// VK_PRESENT_MODE_FIFO_KHR is guaranteed to be present
|
// VK_PRESENT_MODE_FIFO_KHR is guaranteed to be present
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkExtent2D SwapChain::SelectSwapExtent(GLFWwindow* window, const VkSurfaceCapabilitiesKHR& capabilities)
|
VkExtent2D SwapChain::SelectSwapExtent(GLFWwindow* window, const VkSurfaceCapabilitiesKHR& capabilities)
|
||||||
{
|
{
|
||||||
if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max())
|
if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max())
|
||||||
return capabilities.currentExtent;
|
return capabilities.currentExtent;
|
||||||
|
|
||||||
@@ -339,4 +341,5 @@ VkExtent2D SwapChain::SelectSwapExtent(GLFWwindow* window, const VkSurfaceCapabi
|
|||||||
extent.width = std::clamp(extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
|
extent.width = std::clamp(extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
|
||||||
extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
|
extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
|
||||||
return extent;
|
return extent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-12
@@ -6,24 +6,26 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
class Instance;
|
namespace Copium
|
||||||
class CommandBuffer;
|
|
||||||
class Texture2D;
|
|
||||||
|
|
||||||
struct SwapChainSupportDetails
|
|
||||||
{
|
{
|
||||||
|
class Instance;
|
||||||
|
class CommandBuffer;
|
||||||
|
class Texture2D;
|
||||||
|
|
||||||
|
struct SwapChainSupportDetails
|
||||||
|
{
|
||||||
VkSurfaceCapabilitiesKHR capabilities;
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
std::vector<VkSurfaceFormatKHR> formats;
|
std::vector<VkSurfaceFormatKHR> formats;
|
||||||
std::vector<VkPresentModeKHR> presentModes;
|
std::vector<VkPresentModeKHR> presentModes;
|
||||||
|
|
||||||
SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice);
|
SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice);
|
||||||
bool Valid();
|
bool Valid();
|
||||||
};
|
};
|
||||||
|
|
||||||
class SwapChain final
|
class SwapChain final
|
||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(SwapChain);
|
CP_DELETE_COPY_AND_MOVE_CTOR(SwapChain);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
VkSwapchainKHR handle;
|
VkSwapchainKHR handle;
|
||||||
@@ -36,7 +38,7 @@ private:
|
|||||||
std::vector<VkFramebuffer> framebuffers;
|
std::vector<VkFramebuffer> framebuffers;
|
||||||
uint32_t imageIndex;
|
uint32_t imageIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SwapChain(Instance& instance);
|
SwapChain(Instance& instance);
|
||||||
~SwapChain();
|
~SwapChain();
|
||||||
|
|
||||||
@@ -51,7 +53,7 @@ public:
|
|||||||
void Recreate();
|
void Recreate();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void InitializeImageViews();
|
void InitializeImageViews();
|
||||||
void InitializeDepthBuffer();
|
void InitializeDepthBuffer();
|
||||||
@@ -62,4 +64,5 @@ private:
|
|||||||
VkSurfaceFormatKHR SelectSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
VkSurfaceFormatKHR SelectSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
||||||
VkPresentModeKHR SelectSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
|
VkPresentModeKHR SelectSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
|
||||||
VkExtent2D SelectSwapExtent(GLFWwindow* window, const VkSurfaceCapabilitiesKHR& capabilities);
|
VkExtent2D SelectSwapExtent(GLFWwindow* window, const VkSurfaceCapabilitiesKHR& capabilities);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
+32
-29
@@ -3,33 +3,35 @@
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb/stb_image.h>
|
#include <stb/stb_image.h>
|
||||||
|
|
||||||
Texture2D::Texture2D(Instance& instance, const std::string& filename)
|
namespace Copium
|
||||||
: instance{instance}, type{Type::Static}, format{Format::Image}
|
|
||||||
{
|
{
|
||||||
|
Texture2D::Texture2D(Instance& instance, const std::string& filename)
|
||||||
|
: instance{instance}, type{Type::Static}, format{Format::Image}
|
||||||
|
{
|
||||||
InitializeTextureImage(filename);
|
InitializeTextureImage(filename);
|
||||||
InitializeSampler();
|
InitializeSampler();
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D::Texture2D(Instance& instance, int width, int height, Type type, Format format)
|
Texture2D::Texture2D(Instance& instance, int width, int height, Type type, Format format)
|
||||||
: instance{instance}, type{type}, format{format}
|
: instance{instance}, type{type}, format{format}
|
||||||
{
|
{
|
||||||
InitializeTexture(width, height);
|
InitializeTexture(width, height);
|
||||||
InitializeSampler();
|
InitializeSampler();
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D::~Texture2D()
|
Texture2D::~Texture2D()
|
||||||
{
|
{
|
||||||
for(auto&& image : images)
|
for (auto&& image : images)
|
||||||
vkDestroyImage(instance.GetDevice(), image, nullptr);
|
vkDestroyImage(instance.GetDevice(), image, nullptr);
|
||||||
for(auto&& imageMemory : imageMemories)
|
for (auto&& imageMemory : imageMemories)
|
||||||
vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
|
vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
|
||||||
for(auto&& imageView : imageViews)
|
for (auto&& imageView : imageViews)
|
||||||
vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
|
vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
|
||||||
vkDestroySampler(instance.GetDevice(), sampler, nullptr);
|
vkDestroySampler(instance.GetDevice(), sampler, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const
|
VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const
|
||||||
{
|
{
|
||||||
VkDescriptorImageInfo imageInfo{};
|
VkDescriptorImageInfo imageInfo{};
|
||||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
imageInfo.sampler = sampler;
|
imageInfo.sampler = sampler;
|
||||||
@@ -47,22 +49,22 @@ VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
return imageInfo;
|
return imageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView Texture2D::GetImageView() const
|
VkImageView Texture2D::GetImageView() const
|
||||||
{
|
{
|
||||||
CP_ASSERT(type == Type::Static, "GetImageView : Texture2D is not static");
|
CP_ASSERT(type == Type::Static, "GetImageView : Texture2D is not static");
|
||||||
return imageViews.front();
|
return imageViews.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView Texture2D::GetImageView(int index)
|
VkImageView Texture2D::GetImageView(int index)
|
||||||
{
|
{
|
||||||
CP_ASSERT(type == Type::Dynamic && index >= 0 && index < imageViews.size(), "GetImageView : Texture2D is not dynamic or index out of bound for SystemTexture");
|
CP_ASSERT(type == Type::Dynamic && index >= 0 && index < imageViews.size(), "GetImageView : Texture2D is not dynamic or index out of bound for SystemTexture");
|
||||||
return imageViews[index];
|
return imageViews[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture2D::InitializeTextureImage(const std::string& filename)
|
void Texture2D::InitializeTextureImage(const std::string& filename)
|
||||||
{
|
{
|
||||||
int texWidth;
|
int texWidth;
|
||||||
int texHeight;
|
int texHeight;
|
||||||
int texChannels;
|
int texChannels;
|
||||||
@@ -85,10 +87,10 @@ void Texture2D::InitializeTextureImage(const std::string& filename)
|
|||||||
Image::CopyBufferToImage(instance, stagingBuffer, images.front(), texWidth, texHeight);
|
Image::CopyBufferToImage(instance, stagingBuffer, images.front(), texWidth, texHeight);
|
||||||
Image::TransitionImageLayout(instance, images.front(), VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
Image::TransitionImageLayout(instance, images.front(), VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
imageViews[0] = Image::InitializeImageView(instance, images.front(), VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
|
imageViews[0] = Image::InitializeImageView(instance, images.front(), VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture2D::InitializeTexture(int width, int height)
|
void Texture2D::InitializeTexture(int width, int height)
|
||||||
{
|
{
|
||||||
int count = 1;
|
int count = 1;
|
||||||
if (type == Type::Dynamic)
|
if (type == Type::Dynamic)
|
||||||
count = instance.GetMaxFramesInFlight();
|
count = instance.GetMaxFramesInFlight();
|
||||||
@@ -122,10 +124,10 @@ void Texture2D::InitializeTexture(int width, int height)
|
|||||||
CP_ABORT("InitializeTexture : Unreachable switch case");
|
CP_ABORT("InitializeTexture : Unreachable switch case");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture2D::InitializeSampler()
|
void Texture2D::InitializeSampler()
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceProperties properties{};
|
VkPhysicalDeviceProperties properties{};
|
||||||
vkGetPhysicalDeviceProperties(instance.GetPhysicalDevice(), &properties);
|
vkGetPhysicalDeviceProperties(instance.GetPhysicalDevice(), &properties);
|
||||||
|
|
||||||
@@ -147,4 +149,5 @@ void Texture2D::InitializeSampler()
|
|||||||
createInfo.maxLod = 0.0f;
|
createInfo.maxLod = 0.0f;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateSampler(instance.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler");
|
CP_VK_ASSERT(vkCreateSampler(instance.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-8
@@ -6,11 +6,13 @@
|
|||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Instance.h"
|
#include "Instance.h"
|
||||||
|
|
||||||
// TODO: Separate Texture2D and Framebuffer Attachments
|
namespace Copium
|
||||||
class Texture2D
|
|
||||||
{
|
{
|
||||||
|
// TODO: Separate Texture2D and Framebuffer Attachments
|
||||||
|
class Texture2D
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Texture2D);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Texture2D);
|
||||||
public:
|
public:
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
Static, Dynamic
|
Static, Dynamic
|
||||||
@@ -20,7 +22,7 @@ public:
|
|||||||
{
|
{
|
||||||
Image, Color, Depth
|
Image, Color, Depth
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
std::vector<VkImage> images;
|
std::vector<VkImage> images;
|
||||||
@@ -29,7 +31,7 @@ private:
|
|||||||
VkSampler sampler;
|
VkSampler sampler;
|
||||||
Type type;
|
Type type;
|
||||||
Format format;
|
Format format;
|
||||||
public:
|
public:
|
||||||
Texture2D(Instance& instance, const std::string& filename);
|
Texture2D(Instance& instance, const std::string& filename);
|
||||||
Texture2D(Instance& instance, int width, int height, Type type, Format format);
|
Texture2D(Instance& instance, int width, int height, Type type, Format format);
|
||||||
~Texture2D();
|
~Texture2D();
|
||||||
@@ -37,9 +39,9 @@ public:
|
|||||||
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const;
|
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const;
|
||||||
VkImageView GetImageView() const;
|
VkImageView GetImageView() const;
|
||||||
VkImageView GetImageView(int index);
|
VkImageView GetImageView(int index);
|
||||||
private:
|
private:
|
||||||
void InitializeTextureImage(const std::string& filename);
|
void InitializeTextureImage(const std::string& filename);
|
||||||
void InitializeTexture(int width, int height);
|
void InitializeTexture(int width, int height);
|
||||||
void InitializeSampler();
|
void InitializeSampler();
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
+7
-4
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
class Timer
|
namespace Copium
|
||||||
{
|
{
|
||||||
private:
|
class Timer
|
||||||
|
{
|
||||||
|
private:
|
||||||
std::chrono::time_point<std::chrono::steady_clock> startTime;
|
std::chrono::time_point<std::chrono::steady_clock> startTime;
|
||||||
public:
|
public:
|
||||||
Timer()
|
Timer()
|
||||||
: startTime{std::chrono::steady_clock::now()}
|
: startTime{std::chrono::steady_clock::now()}
|
||||||
{}
|
{}
|
||||||
@@ -20,4 +22,5 @@ public:
|
|||||||
{
|
{
|
||||||
return std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - startTime).count();
|
return std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - startTime).count();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,11 +4,13 @@
|
|||||||
#include "Buffer.h"
|
#include "Buffer.h"
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
class UniformBuffer : public Buffer
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class UniformBuffer : public Buffer
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(UniformBuffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(UniformBuffer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UniformBuffer(Instance& instance, VkDeviceSize size)
|
UniformBuffer(Instance& instance, VkDeviceSize size)
|
||||||
: Buffer{instance, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, instance.GetMaxFramesInFlight()}
|
: Buffer{instance, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, instance.GetMaxFramesInFlight()}
|
||||||
{}
|
{}
|
||||||
@@ -28,4 +30,5 @@ public:
|
|||||||
bufferInfo.range = size;
|
bufferInfo.range = size;
|
||||||
return bufferInfo;
|
return bufferInfo;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
+5
-2
@@ -4,7 +4,9 @@
|
|||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
#include "VertexDescriptor.h"
|
#include "VertexDescriptor.h"
|
||||||
|
|
||||||
struct Vertex {
|
namespace Copium
|
||||||
|
{
|
||||||
|
struct Vertex {
|
||||||
glm::vec3 pos;
|
glm::vec3 pos;
|
||||||
glm::vec3 color;
|
glm::vec3 color;
|
||||||
glm::vec2 texCoord;
|
glm::vec2 texCoord;
|
||||||
@@ -17,5 +19,6 @@ struct Vertex {
|
|||||||
descriptor.AddAttribute<Vertex>(0, 2, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, texCoord));
|
descriptor.AddAttribute<Vertex>(0, 2, VK_FORMAT_R32G32_SFLOAT, offsetof(Vertex, texCoord));
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,15 @@
|
|||||||
#include "Buffer.h"
|
#include "Buffer.h"
|
||||||
#include "VertexDescriptor.h"
|
#include "VertexDescriptor.h"
|
||||||
|
|
||||||
class VertexBuffer : public Buffer
|
namespace Copium
|
||||||
{
|
{
|
||||||
|
class VertexBuffer : public Buffer
|
||||||
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(VertexBuffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(VertexBuffer);
|
||||||
private:
|
private:
|
||||||
std::vector<VkDeviceSize> bindingOffsets;
|
std::vector<VkDeviceSize> bindingOffsets;
|
||||||
std::vector<VkDeviceSize> bindingSizes;
|
std::vector<VkDeviceSize> bindingSizes;
|
||||||
public:
|
public:
|
||||||
VertexBuffer(Instance& instance, const VertexDescriptor& descriptor, int vertexCount)
|
VertexBuffer(Instance& instance, const VertexDescriptor& descriptor, int vertexCount)
|
||||||
: Buffer{instance, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, descriptor.GetVertexSize() * vertexCount, 1}
|
: Buffer{instance, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, descriptor.GetVertexSize() * vertexCount, 1}
|
||||||
{
|
{
|
||||||
@@ -32,4 +34,5 @@ public:
|
|||||||
{
|
{
|
||||||
UpdateStaging(data, bindingOffsets[binding], bindingSizes[binding]);
|
UpdateStaging(data, bindingOffsets[binding], bindingSizes[binding]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,15 +2,16 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
namespace Copium
|
||||||
class VertexDescriptor
|
|
||||||
{
|
{
|
||||||
private:
|
class VertexDescriptor
|
||||||
|
{
|
||||||
|
private:
|
||||||
uint32_t bindingIndex = 0;
|
uint32_t bindingIndex = 0;
|
||||||
std::vector<VkVertexInputBindingDescription> bindings;
|
std::vector<VkVertexInputBindingDescription> bindings;
|
||||||
std::vector<VkVertexInputAttributeDescription> attributes;
|
std::vector<VkVertexInputAttributeDescription> attributes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void AddAttribute(uint32_t binding, uint32_t location, VkFormat format, uint32_t offset)
|
void AddAttribute(uint32_t binding, uint32_t location, VkFormat format, uint32_t offset)
|
||||||
{
|
{
|
||||||
@@ -47,7 +48,7 @@ public:
|
|||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t AddLayout(uint32_t binding, uint32_t size)
|
uint32_t AddLayout(uint32_t binding, uint32_t size)
|
||||||
{
|
{
|
||||||
VkVertexInputBindingDescription description{};
|
VkVertexInputBindingDescription description{};
|
||||||
@@ -57,4 +58,5 @@ private:
|
|||||||
bindings.emplace_back(description);
|
bindings.emplace_back(description);
|
||||||
return description.binding;
|
return description.binding;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,13 +4,16 @@
|
|||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
#include "VertexDescriptor.h"
|
#include "VertexDescriptor.h"
|
||||||
|
|
||||||
struct VertexPassthrough {
|
namespace Copium
|
||||||
|
{
|
||||||
|
struct VertexPassthrough {
|
||||||
glm::vec2 texCoord;
|
glm::vec2 texCoord;
|
||||||
|
|
||||||
static VertexDescriptor GetDescriptor()
|
static VertexDescriptor GetDescriptor()
|
||||||
{
|
{
|
||||||
VertexDescriptor descriptor{};
|
VertexDescriptor descriptor{};
|
||||||
descriptor.AddAttribute<VertexPassthrough>(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(VertexPassthrough , texCoord));
|
descriptor.AddAttribute<VertexPassthrough>(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(VertexPassthrough, texCoord));
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
class VulkanException : public std::runtime_error
|
namespace Copium
|
||||||
{
|
{
|
||||||
public:
|
class VulkanException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
VulkanException(const std::string& str)
|
VulkanException(const std::string& str)
|
||||||
: runtime_error{str.c_str()}
|
: runtime_error{str.c_str()}
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
class Window
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
+4
-239
@@ -1,250 +1,15 @@
|
|||||||
#include "Buffer.h"
|
#include "Application.h"
|
||||||
#include "DescriptorPool.h"
|
#include "Common.h"
|
||||||
#include "DescriptorSet.h"
|
|
||||||
#include "Framebuffer.h"
|
|
||||||
#include "IndexBuffer.h"
|
|
||||||
#include "Instance.h"
|
|
||||||
#include "Pipeline.h"
|
|
||||||
#include "Texture2D.h"
|
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "UniformBuffer.h"
|
|
||||||
#include "Vertex.h"
|
|
||||||
#include "VertexBuffer.h"
|
|
||||||
#include "VertexPassthrough.h"
|
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <chrono>
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
#include <optional>
|
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
const std::vector<Vertex> vertices = {
|
|
||||||
Vertex{{-0.5f, 0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
|
|
||||||
Vertex{{ 0.5f, 0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
|
|
||||||
Vertex{{ 0.5f, 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
|
|
||||||
Vertex{{-0.5f, 0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
|
|
||||||
Vertex{{-0.5f, 0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
|
|
||||||
Vertex{{ 0.5f, 0.0f, -0.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
|
|
||||||
Vertex{{ 0.5f, 0.0f, 0.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
|
|
||||||
Vertex{{-0.5f, 0.0f, 0.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}},
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::vector<uint16_t> indices = {
|
|
||||||
0, 1, 2, 2, 3, 0,
|
|
||||||
4, 5, 6, 6, 7, 4
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::vector<VertexPassthrough> verticesPassthrough = {
|
|
||||||
VertexPassthrough{{-1.0f, -1.0f}},
|
|
||||||
VertexPassthrough{{ 1.0f, -1.0f}},
|
|
||||||
VertexPassthrough{{ 1.0f, 1.0f}},
|
|
||||||
VertexPassthrough{{-1.0f, 1.0f}},
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::vector<uint16_t> indicesPassthrough = {
|
|
||||||
0, 1, 2, 2, 3, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct alignas(64) ShaderUniform
|
|
||||||
{
|
|
||||||
alignas(16) glm::mat4 projection;
|
|
||||||
alignas(16) glm::mat4 view;
|
|
||||||
alignas(16) glm::mat4 model;
|
|
||||||
alignas(16) glm::vec3 lightPos;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Application final
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::unique_ptr<Instance> instance;
|
|
||||||
std::unique_ptr<Pipeline> graphicsPipeline;
|
|
||||||
std::unique_ptr<Texture2D> texture2D;
|
|
||||||
std::unique_ptr<UniformBuffer> shaderUniformBuffer;
|
|
||||||
std::unique_ptr<DescriptorPool> descriptorPool;
|
|
||||||
std::unique_ptr<DescriptorSet> descriptorSet;
|
|
||||||
std::unique_ptr<VertexBuffer> vertexBuffer;
|
|
||||||
std::unique_ptr<IndexBuffer> indexBuffer;
|
|
||||||
std::unique_ptr<CommandBuffer> commandBuffer;
|
|
||||||
|
|
||||||
std::unique_ptr<Framebuffer> framebuffer;
|
|
||||||
std::unique_ptr<Pipeline> graphicsPipelinePassthrough;
|
|
||||||
std::unique_ptr<VertexBuffer> vertexBufferPassthrough;
|
|
||||||
std::unique_ptr<IndexBuffer> indexBufferPassthrough;
|
|
||||||
std::unique_ptr<DescriptorSet> descriptorSetPassthrough;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Application()
|
|
||||||
{
|
|
||||||
InitializeInstance();
|
|
||||||
InitializeFrameBuffer();
|
|
||||||
InitializeGraphicsPipeline();
|
|
||||||
InitializeTextureSampler();
|
|
||||||
InitializeUniformBuffer();
|
|
||||||
InitializeDescriptorSets();
|
|
||||||
InitializeVertexBuffer();
|
|
||||||
InitializeIndexBuffer();
|
|
||||||
InitializeCommandBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Application()
|
|
||||||
{
|
|
||||||
vkDeviceWaitIdle(instance->GetDevice());
|
|
||||||
}
|
|
||||||
|
|
||||||
Application(Application&&) = delete;
|
|
||||||
Application(const Application&) = delete;
|
|
||||||
Application& operator=(Application&&) = delete;
|
|
||||||
Application& operator=(const Application&) = delete;
|
|
||||||
|
|
||||||
bool Update()
|
|
||||||
{
|
|
||||||
if (!instance->BeginPresent())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
RecordCommandBuffer();
|
|
||||||
commandBuffer->SubmitAsGraphicsQueue();
|
|
||||||
|
|
||||||
return instance->EndPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void InitializeInstance()
|
|
||||||
{
|
|
||||||
instance = std::make_unique<Instance>("Copium Engine");
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeFrameBuffer()
|
|
||||||
{
|
|
||||||
framebuffer = std::make_unique<Framebuffer>(*instance, instance->GetSwapChain().GetExtent().width, instance->GetSwapChain().GetExtent().height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeTextureSampler()
|
|
||||||
{
|
|
||||||
texture2D = std::make_unique<Texture2D>(*instance, "res/textures/texture.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeUniformBuffer()
|
|
||||||
{
|
|
||||||
shaderUniformBuffer = std::make_unique<UniformBuffer>(*instance, sizeof(ShaderUniform));
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeDescriptorSets()
|
|
||||||
{
|
|
||||||
descriptorPool = std::make_unique<DescriptorPool>(*instance);
|
|
||||||
|
|
||||||
descriptorSet = std::make_unique<DescriptorSet>(*instance, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
|
|
||||||
descriptorSet->AddUniform(*shaderUniformBuffer, 0);
|
|
||||||
descriptorSet->AddTexture2D(*texture2D, 1);
|
|
||||||
|
|
||||||
descriptorSetPassthrough = std::make_unique<DescriptorSet>(*instance, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
|
|
||||||
descriptorSetPassthrough->AddTexture2D(framebuffer->GetTexture2D(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeGraphicsPipeline()
|
|
||||||
{
|
|
||||||
PipelineCreator creator{framebuffer->GetRenderPass(), "res/shaders/shader.vert", "res/shaders/shader.frag"};
|
|
||||||
creator.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT);
|
|
||||||
creator.AddDescriptorSetLayoutBinding(0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
|
||||||
creator.SetVertexDescriptor(Vertex::GetDescriptor());
|
|
||||||
creator.SetCullMode(VK_CULL_MODE_NONE);
|
|
||||||
graphicsPipeline = std::make_unique<Pipeline>(*instance, creator);
|
|
||||||
|
|
||||||
PipelineCreator creatorPassthrough{instance->GetSwapChain().GetRenderPass(), "res/shaders/passthrough.vert", "res/shaders/passthrough.frag"};
|
|
||||||
creatorPassthrough.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
|
||||||
creatorPassthrough.SetVertexDescriptor(VertexPassthrough::GetDescriptor());
|
|
||||||
creatorPassthrough.SetCullMode(VK_CULL_MODE_NONE);
|
|
||||||
graphicsPipelinePassthrough = std::make_unique<Pipeline>(*instance, creatorPassthrough);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeVertexBuffer()
|
|
||||||
{
|
|
||||||
vertexBuffer = std::make_unique<VertexBuffer>(*instance, Vertex::GetDescriptor(), vertices.size());
|
|
||||||
vertexBuffer->Update(0, (void*)vertices.data());
|
|
||||||
|
|
||||||
vertexBufferPassthrough = std::make_unique<VertexBuffer>(*instance, VertexPassthrough::GetDescriptor(), verticesPassthrough.size());
|
|
||||||
vertexBufferPassthrough->Update(0, (void*)verticesPassthrough.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeIndexBuffer()
|
|
||||||
{
|
|
||||||
indexBuffer = std::make_unique<IndexBuffer>(*instance, indices.size());
|
|
||||||
indexBuffer->UpdateStaging((void*)indices.data());
|
|
||||||
|
|
||||||
indexBufferPassthrough = std::make_unique<IndexBuffer>(*instance, indicesPassthrough.size());
|
|
||||||
indexBufferPassthrough->UpdateStaging((void*)indicesPassthrough.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeCommandBuffer()
|
|
||||||
{
|
|
||||||
commandBuffer = std::make_unique<CommandBuffer>(*instance, CommandBufferType::Dynamic);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RecordCommandBuffer()
|
|
||||||
{
|
|
||||||
commandBuffer->Begin();
|
|
||||||
std::vector<VkClearValue> clearValues{2};
|
|
||||||
clearValues[0].color = {{0.0f, 0.0f, 0.0f, 1.0f}};
|
|
||||||
clearValues[1].depthStencil = {1.0f, 0};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
framebuffer->Bind(*commandBuffer);
|
|
||||||
graphicsPipeline->Bind(*commandBuffer);
|
|
||||||
|
|
||||||
UpdateUniformBuffer();
|
|
||||||
|
|
||||||
vertexBuffer->Bind(*commandBuffer);
|
|
||||||
indexBuffer->Bind(*commandBuffer);
|
|
||||||
|
|
||||||
graphicsPipeline->SetDescriptorSet(0, *descriptorSet);
|
|
||||||
graphicsPipeline->BindDescriptorSets(commandBuffer->GetHandle());
|
|
||||||
|
|
||||||
indexBuffer->Draw(*commandBuffer);
|
|
||||||
framebuffer->Unbind(*commandBuffer);
|
|
||||||
|
|
||||||
instance->GetSwapChain().BeginFrameBuffer(*commandBuffer);
|
|
||||||
|
|
||||||
graphicsPipelinePassthrough->Bind(*commandBuffer);
|
|
||||||
graphicsPipelinePassthrough->SetDescriptorSet(0, *descriptorSetPassthrough);
|
|
||||||
graphicsPipelinePassthrough->BindDescriptorSets(commandBuffer->GetHandle());
|
|
||||||
vertexBufferPassthrough->Bind(*commandBuffer);
|
|
||||||
indexBufferPassthrough->Bind(*commandBuffer);
|
|
||||||
indexBufferPassthrough->Draw(*commandBuffer);
|
|
||||||
|
|
||||||
instance->GetSwapChain().EndFrameBuffer(*commandBuffer);
|
|
||||||
commandBuffer->End();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateUniformBuffer()
|
|
||||||
{
|
|
||||||
static Timer startTimer;
|
|
||||||
|
|
||||||
float time = startTimer.Elapsed();
|
|
||||||
ShaderUniform shaderUniform;
|
|
||||||
shaderUniform.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
|
||||||
shaderUniform.projection = glm::perspective(glm::radians(45.0f), instance->GetSwapChain().GetExtent().width / (float)instance->GetSwapChain().GetExtent().height, 0.1f, 10.0f);
|
|
||||||
shaderUniform.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
|
||||||
shaderUniform.projection[1][1] *= -1;
|
|
||||||
shaderUniform.lightPos = glm::rotate(glm::mat4{1.0f}, time * glm::radians(45.0f), glm::vec3(0, 1, 0)) * glm::vec4{0.3, 0.1, 0, 1};
|
|
||||||
|
|
||||||
shaderUniformBuffer->Update(shaderUniform);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void func(const int* ptr) {
|
|
||||||
*const_cast<int*>(ptr) = 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
CP_ASSERT(glfwInit() == GLFW_TRUE, "main : Failed to initialize the glfw context");
|
CP_ASSERT(glfwInit() == GLFW_TRUE, "main : Failed to initialize the glfw context");
|
||||||
{
|
{
|
||||||
Application application;
|
Copium::Application application;
|
||||||
Timer timer;
|
Copium::Timer timer;
|
||||||
int frames = 0;
|
int frames = 0;
|
||||||
while (application.Update())
|
while (application.Update())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user