Now rendering scene models at correct positions + reverse-z

This commit is contained in:
antopilo
2025-01-03 23:35:05 -05:00
parent 1164bd4b0f
commit 90c6652074
30 changed files with 915 additions and 247 deletions

View File

@@ -60,6 +60,7 @@
#include <Tracy.hpp>
#include "src/Rendering/Vulkan/VulkanRenderer.h"
#include <src/Rendering/Vulkan/VkResources.h>
namespace Nuake {
@@ -655,7 +656,7 @@ namespace Nuake {
Input::SetEditorViewportSize(m_ViewportPos, viewportPanelSize);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
m_ViewportPos = { imagePos.x, imagePos.y };
ImGui::Image(VkRenderer::Get().GetDrawImage()->GetImGuiDescriptorSet(), regionAvail);
ImGui::Image(VkRenderer::Get().GetDrawImage()->GetImGuiDescriptorSet(), regionAvail, { 0, 1 }, { 1, 0 });
ImGui::PopStyleVar();
const Vector2& mousePos = Input::GetMousePosition();
@@ -2335,6 +2336,12 @@ namespace Nuake {
Nuake::Logger::Log("Copied Nuake.Net Assemblies.");
SetStatusMessage("Nuake.Net assemblies succesfully copied.");
}
if (ImGui::MenuItem("GPU Resources", 0, m_ShowGpuResources))
{
m_ShowGpuResources = !m_ShowGpuResources;
}
#endif // NK_DEBUG
ImGui::EndMenu();
@@ -2540,6 +2547,36 @@ namespace Nuake {
m_TrenchhbroomConfigurator.Draw();
}
if (m_ShowGpuResources)
{
if (ImGui::Begin("GPU Resources"))
{
GPUResources& gpu = GPUResources::Get();
auto buffers = gpu.GetAllBuffers();
ImGui::BeginTable("Buffers", 2);
ImGui::TableSetupColumn("UUID", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_IndentDisable | ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
ImGui::TableNextColumn();
for (auto& buffer : buffers)
{
ImGui::Text(std::to_string(buffer->GetID()).c_str());
ImGui::TableNextColumn();
ImGui::Text(std::to_string(buffer->GetSize()).c_str());
ImGui::TableNextColumn();
}
ImGui::EndTable();
}
ImGui::End();
}
if (m_ShowMapImporter)
{
m_MapImporter.Draw();

View File

@@ -52,6 +52,7 @@ namespace Nuake
bool m_IsRenaming = false;
bool m_ShouldUnfoldEntityTree = false;
bool m_ShowTrenchbroomConfigurator = false;
bool m_ShowGpuResources = false;
bool m_ShowProjectSettings = false;
bool m_ShowMapImporter = false;
Vector2 m_ViewportPos = {0, 0};

View File

@@ -27,8 +27,8 @@ namespace Nuake
Matrix4 m_Perspective;
Matrix4 m_View;
float Near = 0.001f;
float Far = 400.0f;
float Near = 400.0f;
float Far = 0.001f;
public:
float AspectRatio = 16.0f / 9.0f;

View File

@@ -12,6 +12,7 @@
#include <future>
#include <src/Resource/ResourceLoader.h>
#include <src/Rendering/Vulkan/VkResources.h>
namespace Nuake
{
@@ -82,43 +83,46 @@ namespace Nuake
void Mesh::SetupMesh()
{
m_VertexArray = CreateScope<VertexArray>();
m_VertexArray->Bind();
m_VertexBuffer = CreateScope<VertexBuffer>(m_Vertices.data(), static_cast<uint32_t>(m_Vertices.size() * sizeof(Vertex)));
m_ElementBuffer = CreateScope<VertexBuffer>(m_Indices.data(), m_Indices.size() * sizeof(unsigned int), RendererEnum::ELEMENT_ARRAY_BUFFER);
GPUResources& resources = GPUResources::Get();
m_Mesh = resources.CreateMesh(m_Vertices, m_Indices);
VertexBufferLayout bufferLayout = VertexBufferLayout();
bufferLayout.Push<float>(3); // Position
bufferLayout.Push<float>(2); // UV
bufferLayout.Push<float>(3); // Normal
bufferLayout.Push<float>(3); // Tangent
bufferLayout.Push<float>(3); // Bitangent
m_VertexArray->AddBuffer(*m_VertexBuffer, bufferLayout);
m_VertexArray->Unbind();
//m_VertexArray = CreateScope<VertexArray>();
//m_VertexArray->Bind();
//m_VertexBuffer = CreateScope<VertexBuffer>(m_Vertices.data(), static_cast<uint32_t>(m_Vertices.size() * sizeof(Vertex)));
//m_ElementBuffer = CreateScope<VertexBuffer>(m_Indices.data(), m_Indices.size() * sizeof(unsigned int), RendererEnum::ELEMENT_ARRAY_BUFFER);
//
//VertexBufferLayout bufferLayout = VertexBufferLayout();
//bufferLayout.Push<float>(3); // Position
//bufferLayout.Push<float>(2); // UV
//bufferLayout.Push<float>(3); // Normal
//bufferLayout.Push<float>(3); // Tangent
//bufferLayout.Push<float>(3); // Bitangent
//
//m_VertexArray->AddBuffer(*m_VertexBuffer, bufferLayout);
//m_VertexArray->Unbind();
}
void Mesh::Bind() const
{
m_VertexArray->Bind();
//m_VertexArray->Bind();
}
void Mesh::Draw(Shader* shader, bool bindMaterial)
{
if (bindMaterial)
m_Material->Bind(shader);
m_VertexArray->Bind();
RenderCommand::DrawElements(RendererEnum::TRIANGLES, m_IndicesCount, RendererEnum::UINT, 0);
//if (bindMaterial)
// m_Material->Bind(shader);
//
//m_VertexArray->Bind();
//RenderCommand::DrawElements(RendererEnum::TRIANGLES, m_IndicesCount, RendererEnum::UINT, 0);
}
void Mesh::DebugDraw()
{
Renderer::m_DebugShader->Bind();
Renderer::m_DebugShader->SetUniform("u_Color", 1.0f, 0.0f, 0.0f, 1.f);
m_VertexArray->Bind();
RenderCommand::DrawElements(RendererEnum::TRIANGLES, m_IndicesCount, RendererEnum::UINT, 0);
//Renderer::m_DebugShader->Bind();
//Renderer::m_DebugShader->SetUniform("u_Color", 1.0f, 0.0f, 0.0f, 1.f);
//
//m_VertexArray->Bind();
//RenderCommand::DrawElements(RendererEnum::TRIANGLES, m_IndicesCount, RendererEnum::UINT, 0);
}
json Mesh::Serialize()
@@ -139,8 +143,8 @@ namespace Nuake
v["Position"]["y"] = m_Vertices[i].position.y;
v["Position"]["z"] = m_Vertices[i].position.z;
v["UV"]["x"] = m_Vertices[i].uv.x;
v["UV"]["y"] = m_Vertices[i].uv.y;
v["UV"]["x"] = m_Vertices[i].uv_x;
v["UV"]["y"] = m_Vertices[i].uv_y;
v["Normal"]["x"] = m_Vertices[i].normal.x;
v["Normal"]["y"] = m_Vertices[i].normal.y;
@@ -196,15 +200,17 @@ namespace Nuake
{
Vertex vertex;
try {
DESERIALIZE_VEC2(v["UV"], vertex.uv)
vertex.uv_x = v["UV"]["X"];
vertex.uv_y = v["UV"]["Y"];
}
catch (std::exception& /*e*/) {
vertex.uv = { 0.0, 0.0 };
vertex.uv_x = 0.0f;
vertex.uv_y = 1.0f;
}
DESERIALIZE_VEC3(v["Position"], vertex.position)
DESERIALIZE_VEC3(v["Normal"], vertex.normal)
DESERIALIZE_VEC3(v["Tangent"], vertex.tangent)
DESERIALIZE_VEC3(v["Bitangent"], vertex.bitangent)
DESERIALIZE_VEC3_INTO4(v["Tangent"], vertex.tangent)
DESERIALIZE_VEC3_INTO4(v["Bitangent"], vertex.bitangent)
vertices.push_back(vertex);
}

View File

@@ -3,6 +3,8 @@
#include "src/Rendering/AABB.h"
#include "src/Resource/Resource.h"
#include "src/Resource/Serializable.h"
#include "src/Rendering/Vulkan/VkMesh.h"
namespace Nuake
{
@@ -34,6 +36,11 @@ namespace Nuake
json Serialize() override;
bool Deserialize(const json& j) override;
Ref<VkMesh> GetVkMesh()
{
return m_Mesh;
}
private:
Ref<Material> m_Material = nullptr;
std::vector<uint32_t> m_Indices;
@@ -42,9 +49,10 @@ namespace Nuake
uint32_t m_IndicesCount;
uint32_t m_VerticesCount;
Scope<VertexBuffer> m_VertexBuffer;
Scope<VertexArray> m_VertexArray;
Scope<VertexBuffer> m_ElementBuffer;
Ref<VkMesh> m_Mesh;
//Scope<VertexBuffer> m_VertexBuffer;
//Scope<VertexArray> m_VertexArray;
//Scope<VertexBuffer> m_ElementBuffer;
void SetupMesh();

View File

@@ -49,54 +49,54 @@ namespace Nuake
std::vector<Vertex> CubeVertices
{
{ Vector3(-1.0f, 1.0f, -1.0f), Vector2(0, 0), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, -1.0f, -1.0f), Vector2(1, 0), Vector3(-1,-1, 0) },
{ Vector3(1.0f, -1.0f, -1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, -1.0f, -1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, 1.0f, -1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, 1.0f, -1.0f), Vector2(1, 0), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, -1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, -1.0f, -1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, 1.0f, -1.0f), Vector2(0, 0), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, 1.0f, -1.0f), Vector2(1, 0), Vector3(-1,-1, 0) },
{ Vector3(-1.0f, 1.0f, 1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, -1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, -1.0f, -1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, -1.0f, 1.0f), Vector2(1, 0), Vector3(-1, 0, 0) },
{ Vector3(1.0f, 1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, 1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, 1.0f, -1.0f), Vector2(0, 0), Vector3(-1, 0, 0) },
{ Vector3(1.0f, -1.0f, -1.0f), Vector2(1, 0), Vector3(-1,-1, 0) },
{ Vector3(-1.0f, -1.0f, 1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, 1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, 1.0f, 1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, 1.0f, 1.0f), Vector2(1, 0), Vector3(-1, 0, 0) },
{ Vector3(1.0f, -1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, -1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, 1.0f, -1.0f), Vector2(0, 0), Vector3(-1, 0, 0) },
{ Vector3(1.0f, 1.0f, -1.0f), Vector2(1, 0), Vector3(-1,-1, 0) },
{ Vector3(1.0f, 1.0f, 1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, 1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, 1.0f, 1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, 1.0f, -1.0f), Vector2(1, 0), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, -1.0f, -1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(-1.0f, -1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, -1.0f, -1.0f), Vector2(0, 0), Vector3(-1, 0, 0) },
{ Vector3(1.0f, -1.0f, -1.0f), Vector2(1, 0), Vector3(-1,-1, 0) },
{ Vector3(-1.0f, -1.0f, 1.0f), Vector2(0, 1), Vector3(-1, 0, 0) },
{ Vector3(1.0f, -1.0f, 1.0f), Vector2(1, 1), Vector3(-1, 0, 0) }
{ Vector3(-1.0f, 1.0f, -1.0f), 0.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(-1.0f, -1.0f, -1.0f), 1.0f, Vector3(-1,-1, 0), 0.0f },
{ Vector3(1.0f, -1.0f, -1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, -1.0f, -1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, 1.0f, -1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, 1.0f, -1.0f), 1.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(-1.0f, -1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, -1.0f, -1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, 1.0f, -1.0f), 0.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(-1.0f, 1.0f, -1.0f), 1.0f, Vector3(-1,-1, 0), 0.0f },
{ Vector3(-1.0f, 1.0f, 1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, -1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, -1.0f, -1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, -1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(1.0f, 1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, 1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, 1.0f, -1.0f), 0.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(1.0f, -1.0f, -1.0f), 1.0f, Vector3(-1,-1, 0), 0.0f },
{ Vector3(-1.0f, -1.0f, 1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, 1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, 1.0f, 1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, 1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(1.0f, -1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, -1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, 1.0f, -1.0f), 0.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(1.0f, 1.0f, -1.0f), 1.0f, Vector3(-1,-1, 0), 0.0f },
{ Vector3(1.0f, 1.0f, 1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, 1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, 1.0f, 1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, 1.0f, -1.0f), 1.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(-1.0f, -1.0f, -1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(-1.0f, -1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, -1.0f, -1.0f), 0.0f, Vector3(-1, 0, 0), 0.0f },
{ Vector3(1.0f, -1.0f, -1.0f), 1.0f, Vector3(-1,-1, 0), 0.0f },
{ Vector3(-1.0f, -1.0f, 1.0f), 0.0f, Vector3(-1, 0, 0), 1.0f },
{ Vector3(1.0f, -1.0f, 1.0f), 1.0f, Vector3(-1, 0, 0), 1.0f }
};
std::vector<uint32_t> CubeIndices;
std::vector<Vertex> QuadVertices
{
{ Vector3(-1.0f, 1.0f, 0.0f), Vector2(0.0f, 1.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), Vector2(0, 0), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(1.0f, -1.0f, 0.0f), Vector2(1.0f, 0.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), Vector2(0.0f, 0.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) }
{ Vector3(-1.0f, 1.0f, 0.0f), 0.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), 1.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), 0.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(1.0f, -1.0f, 0.0f), 1.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), 0.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), 1.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) }
};
@@ -227,7 +227,8 @@ namespace Nuake
s = (float)j / sectorCount * 4.f;
t = (float)i / stackCount * 4.f;
newVertex.uv = { t, s };
newVertex.uv_x = t;
newVertex.uv_y = s;
finalVertices.push_back(newVertex);
}
@@ -399,8 +400,8 @@ namespace Nuake
std::vector<Vertex> vertices
{
{start, Vector2(0, 0), Vector3(-1, 0, 0)},
{end, Vector2(1, 0), Vector3(-1, -1, 0)}
{start, 0.0f, Vector3(-1, 0, 0), 1.0f},
{end, 1.0f, Vector3(-1, -1, 0), 0.0f}
};
VertexArray lineVertexArray = VertexArray();

View File

@@ -102,8 +102,8 @@ namespace Nuake
// Generate debug meshes
std::vector<Vertex> lineVertices
{
{ Vector3(0, 0, 0), Vector2(0, 0), Vector3(0, 0, 0) },
{ Vector3(1, 1, 1), Vector2(0, 0), Vector3(0, 0, 0) }
{ Vector3(0, 0, 0), 0.0f, Vector3(0, 0, 0), 0.0f },
{ Vector3(1, 1, 1), 0.0f, Vector3(0, 0, 0), 0.0f }
};
std::vector<uint32_t> lineIndices

View File

@@ -6,10 +6,11 @@ namespace Nuake
struct Vertex
{
Vector3 position;
Vector2 uv;
float uv_x;
Vector3 normal;
Vector3 tangent = Vector3(0, 1, 0);
Vector3 bitangent = Vector3(1, 0, 0);
float uv_y;
Vector4 tangent = Vector4(0, 1, 0, 0);
Vector4 bitangent = Vector4(1, 0, 0, 0);
};
const uint32_t MAX_BONE_INFLUENCE = 4;

View File

@@ -10,7 +10,10 @@ void PipelineBuilder::Clear()
{
InputAssembly = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
Rasterizer = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
Rasterizer = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE
};
ColorBlendAttachment = {};
@@ -162,3 +165,40 @@ void PipelineBuilder::DisableDepthTest()
DepthStencil.minDepthBounds = 0.f;
DepthStencil.maxDepthBounds = 1.f;
}
void PipelineBuilder::EnableDepthTest(bool depthWriteEnable, VkCompareOp op)
{
DepthStencil.depthTestEnable = VK_TRUE;
DepthStencil.depthWriteEnable = depthWriteEnable;
DepthStencil.depthCompareOp = op;
DepthStencil.depthBoundsTestEnable = VK_FALSE;
DepthStencil.stencilTestEnable = VK_FALSE;
DepthStencil.front = {};
DepthStencil.back = {};
DepthStencil.minDepthBounds = 1.f;
DepthStencil.maxDepthBounds = 0.f;
}
void PipelineBuilder::EnableBlendingAdditive()
{
ColorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
ColorBlendAttachment.blendEnable = VK_TRUE;
ColorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
ColorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
ColorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
ColorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
ColorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
ColorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
}
void PipelineBuilder::EnableBlendingAlphaBlend()
{
ColorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
ColorBlendAttachment.blendEnable = VK_TRUE;
ColorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
ColorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
ColorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
ColorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
ColorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
ColorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
}

View File

@@ -36,5 +36,9 @@ namespace Nuake
void SetColorAttachment(VkFormat format);
void SetDepthFormat(VkFormat depthFormat);
void DisableDepthTest();
void EnableDepthTest(bool depthWriteEnable, VkCompareOp op);
void EnableBlendingAdditive();
void EnableBlendingAlphaBlend();
};
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "src/Core/Core.h"
#include <volk/volk.h>
namespace Nuake
{
class Scene;
struct RenderContext
{
Ref<Scene> CurrentScene; // The scene we are rendering
VkCommandBuffer CommandBuffer; // The command buffer we are recording into
// ...
// We might add more to this!
};
}

View File

@@ -6,10 +6,10 @@
using namespace Nuake;
VkMesh::VkMesh(const std::vector<VkVertex>& vertices, const std::vector<uint32_t>& indices)
VkMesh::VkMesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices)
{
// First we allocate the buffers on the GPU
const size_t vertexBufferSize = vertices.size() * sizeof(VkVertex);
const size_t vertexBufferSize = vertices.size() * sizeof(Vertex);
const size_t indexBufferSize = indices.size() * sizeof(uint32_t);
GPUResources& resources = GPUResources::Get();
@@ -17,10 +17,10 @@ VkMesh::VkMesh(const std::vector<VkVertex>& vertices, const std::vector<uint32_t
IndexBuffer = resources.CreateBuffer(indexBufferSize, BufferUsage::INDEX_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::GPU_ONLY);
// Then we upload to data to those buffers.
UploadtoGPU(vertices, indices);
UploadToGPU(vertices, indices);
}
void VkMesh::UploadtoGPU(const std::vector<VkVertex>& vertices, const std::vector<uint32_t>& indices)
void VkMesh::UploadToGPU(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices)
{
// Create a staging buffer
AllocatedBuffer staging = AllocatedBuffer(VertexBuffer->GetSize() + IndexBuffer->GetSize(), BufferUsage::TRANSFER_SRC, MemoryUsage::CPU_ONLY);
@@ -49,4 +49,32 @@ void VkMesh::UploadtoGPU(const std::vector<VkVertex>& vertices, const std::vecto
vkCmdCopyBuffer(cmd, staging.GetBuffer(), IndexBuffer->GetBuffer(), 1, &indexCopy);
});
}
CreateDescriptorSet();
}
void VkMesh::CreateDescriptorSet()
{
DescriptorLayoutBuilder builder;
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
auto& vk = VkRenderer::Get();
auto device = vk.GetDevice();
DescriptorLayout = builder.Build(device, VK_SHADER_STAGE_VERTEX_BIT);
DescriptorSet = vk.GetDescriptorAllocator().Allocate(device, DescriptorLayout);
VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = GetVertexBuffer()->GetBuffer();
bufferInfo.offset = 0;
bufferInfo.range = VK_WHOLE_SIZE;
VkWriteDescriptorSet bufferWrite = {};
bufferWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
bufferWrite.pNext = nullptr;
bufferWrite.dstBinding = 0;
bufferWrite.dstSet = DescriptorSet;
bufferWrite.descriptorCount = 1;
bufferWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
bufferWrite.pBufferInfo = &bufferInfo;
vkUpdateDescriptorSets(device, 1, &bufferWrite, 0, nullptr);
}

View File

@@ -2,7 +2,9 @@
#include "src/Core/Core.h"
#include "src/Resource/UUID.h"
#include "src/Rendering/Vertex.h"
#include "volk/volk.h"
#include "VulkanAllocatedBuffer.h"
@@ -16,8 +18,11 @@ namespace Nuake
Ref<AllocatedBuffer> IndexBuffer;
Ref<AllocatedBuffer> VertexBuffer;
VkDescriptorSet DescriptorSet;
VkDescriptorSetLayout DescriptorLayout;
public:
VkMesh(const std::vector<VkVertex>& vertices, const std::vector<uint32_t>& indices);
VkMesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices);
~VkMesh() = default;
Ref<AllocatedBuffer> GetVertexBuffer() const { return VertexBuffer; }
@@ -25,7 +30,13 @@ namespace Nuake
UUID GetID() const { return ID; }
VkDescriptorSet GetDescriptorSet()
{
return DescriptorSet;
}
private:
void UploadtoGPU(const std::vector<VkVertex>& vertices, const std::vector<uint32_t>& indices);
void UploadToGPU(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices);
void CreateDescriptorSet();
};
}

View File

@@ -1,9 +1,9 @@
#pragma once
#include "src/Core/Core.h"
#include "src/Resource/UUID.h"
#include "src/Rendering/Vertex.h"
#include "VulkanAllocatedBuffer.h"
#include <src/Core/Logger.h>
#include "src/Core/Logger.h"
namespace Nuake
{
@@ -55,7 +55,18 @@ namespace Nuake
return nullptr;
}
Ref<VkMesh> CreateMesh(const std::vector<VkVertex>& vertices, const std::vector<uint32_t>& indices)
std::vector<Ref<AllocatedBuffer>> GetAllBuffers()
{
std::vector<Ref<AllocatedBuffer>> allBuffers;
allBuffers.reserve(Buffers.size());
for (const auto& [id, buffer] : Buffers)
{
allBuffers.push_back(buffer);
}
return allBuffers;
}
Ref<VkMesh> CreateMesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices)
{
Ref<VkMesh> mesh = CreateRef<VkMesh>(vertices, indices);
Meshes[mesh->GetID()] = mesh;

View File

@@ -12,7 +12,7 @@ using namespace Nuake;
#include "vk_mem_alloc.h"
VulkanImage::VulkanImage(ImageFormat inFormat, Vector2 inSize) :
VulkanImage::VulkanImage(ImageFormat inFormat, Vector2 inSize, ImageUsage usage) :
Format(inFormat),
Extent(inSize, 1),
ImGuiDescriptorSetGenerated(false)
@@ -25,11 +25,19 @@ VulkanImage::VulkanImage(ImageFormat inFormat, Vector2 inSize) :
};
VkImageUsageFlags drawImageUsages{};
drawImageUsages |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
drawImageUsages |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
drawImageUsages |= VK_IMAGE_USAGE_STORAGE_BIT;
drawImageUsages |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
drawImageUsages |= VK_IMAGE_USAGE_SAMPLED_BIT;
if (usage == ImageUsage::Default)
{
drawImageUsages |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
drawImageUsages |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
drawImageUsages |= VK_IMAGE_USAGE_STORAGE_BIT;
drawImageUsages |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
drawImageUsages |= VK_IMAGE_USAGE_SAMPLED_BIT;
}
else if (usage == ImageUsage::Depth)
{
drawImageUsages |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
}
VkImageCreateInfo imgCreateInfo = VulkanInit::ImageCreateInfo(static_cast<VkFormat>(inFormat), drawImageUsages, vkExtent);
@@ -39,7 +47,16 @@ VulkanImage::VulkanImage(ImageFormat inFormat, Vector2 inSize) :
vmaCreateImage(VulkanAllocator::Get().GetAllocator(), &imgCreateInfo, &imgAllocInfo, &Image, &Allocation, nullptr);
VkImageViewCreateInfo imageViewCreateInfo = VulkanInit::ImageviewCreateInfo(static_cast<VkFormat>(inFormat), Image, VK_IMAGE_ASPECT_COLOR_BIT);
VkImageViewCreateInfo imageViewCreateInfo;
if (usage == ImageUsage::Depth)
{
imageViewCreateInfo = VulkanInit::ImageviewCreateInfo(static_cast<VkFormat>(inFormat), Image, VK_IMAGE_ASPECT_DEPTH_BIT);
}
else
{
imageViewCreateInfo = VulkanInit::ImageviewCreateInfo(static_cast<VkFormat>(inFormat), Image, VK_IMAGE_ASPECT_COLOR_BIT);
}
VK_CALL(vkCreateImageView(VkRenderer::Get().GetDevice(), &imageViewCreateInfo, nullptr, &ImageView));
}

View File

@@ -11,7 +11,8 @@ namespace Nuake
enum class ImageFormat
{
RGBA8 = 41,
RGBA16F = 97
RGBA16F = 97,
D32F = 126,
};
enum class ImageUsage
@@ -23,7 +24,9 @@ namespace Nuake
ColorAttachment,
DepthStencilAttachment,
TransientAttachment,
InputAttachment
InputAttachment,
Depth,
Default
};
class VulkanImage
@@ -40,7 +43,7 @@ namespace Nuake
VkDescriptorSet ImGuiDescriptorSet;
public:
VulkanImage(ImageFormat format, Vector2 size);
VulkanImage(ImageFormat format, Vector2 size, ImageUsage usage = ImageUsage::Default);
VulkanImage(void* data, ImageFormat format, Vector2 size);
~VulkanImage();

View File

@@ -126,7 +126,7 @@ VkImageCreateInfo VulkanInit::ImageCreateInfo(VkFormat format, VkImageUsageFlags
info.samples = VK_SAMPLE_COUNT_1_BIT;
//optimal tiling, which means the image is stored on the best gpu format
info.tiling = VK_IMAGE_TILING_LINEAR;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = usageFlags;
return info;
@@ -169,6 +169,21 @@ VkRenderingAttachmentInfo VulkanInit::AttachmentInfo(VkImageView view, VkClearVa
return colorAttachment;
}
VkRenderingAttachmentInfo VulkanInit::DepthAttachmentInfo(VkImageView view, VkImageLayout layout)
{
VkRenderingAttachmentInfo depthAttachment{};
depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
depthAttachment.pNext = nullptr;
depthAttachment.imageView = view;
depthAttachment.imageLayout = layout;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
depthAttachment.clearValue.depthStencil.depth = 0.f;
return depthAttachment;
}
VkRenderingInfo VulkanInit::RenderingInfo(VkExtent2D renderExtent, VkRenderingAttachmentInfo* colorAttachment,
VkRenderingAttachmentInfo* depthAttachment)
{

View File

@@ -25,6 +25,7 @@ namespace Nuake
static VkImageViewCreateInfo ImageviewCreateInfo(VkFormat format, VkImage image, VkImageAspectFlags aspectFlags);
static VkRenderingAttachmentInfo AttachmentInfo(VkImageView view, VkClearValue* clear, VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
static VkRenderingAttachmentInfo DepthAttachmentInfo(VkImageView view, VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
static VkRenderingInfo RenderingInfo(VkExtent2D renderExtent, VkRenderingAttachmentInfo * colorAttachment, VkRenderingAttachmentInfo * depthAttachment);
static VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo();

View File

@@ -24,6 +24,8 @@
using namespace Nuake;
#include "vk_mem_alloc.h"
#include <src/Rendering/Vertex.h>
#include "VulkanSceneRenderer.h"
bool NKUseValidationLayer = true;
@@ -77,13 +79,13 @@ void VkRenderer::Initialize()
BackgroundShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/background.comp");
TriangleFragShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/triangle.frag");
std::vector<VkVertex> rect_vertices;
std::vector<Vertex> rect_vertices;
rect_vertices.resize(4);
rect_vertices[0].position = { 1, -1, 0 };
rect_vertices[1].position = { 1, 1, 0 };
rect_vertices[2].position = { -1, -1, 0 };
rect_vertices[3].position = { -1, 1, 0 };
rect_vertices[0].position = { 1.0f, -1.0f, 0 };
rect_vertices[1].position = { 1.0f, 1.0f, 0 };
rect_vertices[2].position = { -1.0f, -1.0f, 0 };
rect_vertices[3].position = { -1.0f, 1.0f, 0 };
rect_vertices[0].normal = { 0, 0, 1 };
rect_vertices[1].normal = { 0.5, 0.5,0.5 };
@@ -101,6 +103,17 @@ void VkRenderer::Initialize()
rect_indices[4] = 1;
rect_indices[5] = 3;
// Init global pool
std::vector<DescriptorAllocator::PoolSizeRatio> sizes =
{
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 8 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 50 }
};
GlobalDescriptorAllocator.InitPool(Device, 1000, sizes);
GPUResources& resources = GPUResources::Get();
rectangle = resources.CreateMesh(rect_vertices, rect_indices);
@@ -119,6 +132,9 @@ void VkRenderer::Initialize()
InitImgui();
SceneRenderer = CreateRef<VkSceneRenderer>();
SceneRenderer->Init();
IsInitialized = true;
}
@@ -250,6 +266,7 @@ void VkRenderer::CreateSwapchain(const Vector2& size)
};
DrawImage = CreateRef<VulkanImage>(ImageFormat::RGBA16F, size);
DepthImage = CreateRef<VulkanImage>(ImageFormat::D32F, size, ImageUsage::Depth);
}
void VkRenderer::DestroySwapchain()
@@ -278,6 +295,7 @@ void VkRenderer::InitCommands()
GPUResources& resources = GPUResources::Get();
Frames[i].CameraStagingBuffer = resources.CreateBuffer(sizeof(CameraData), BufferUsage::TRANSFER_SRC, MemoryUsage::CPU_ONLY);
Frames[i].ModelStagingBuffer = resources.CreateBuffer(sizeof(Matrix4) * MAX_MODEL_MATRIX, BufferUsage::TRANSFER_SRC, MemoryUsage::CPU_ONLY);
}
VK_CALL(vkCreateCommandPool(Device, &cmdPoolInfo, nullptr, &ImguiCommandPool));
@@ -316,14 +334,6 @@ void VkRenderer::InitSync()
void VkRenderer::InitDescriptors()
{
//create a descriptor pool that will hold 10 sets with 1 image each
std::vector<DescriptorAllocator::PoolSizeRatio> sizes =
{
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 8 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 50 }
};
GlobalDescriptorAllocator.InitPool(Device, 50, sizes);
//make the descriptor set layout for our compute draw
{
@@ -371,36 +381,36 @@ void VkRenderer::UpdateDescriptorSets()
vkUpdateDescriptorSets(Device, 1, &drawImageWrite, 0, nullptr);
// Update descriptor set for cameras
VkDescriptorBufferInfo camBufferInfo{};
camBufferInfo.buffer = CameraBuffer->GetBuffer();
camBufferInfo.offset = 0;
camBufferInfo.range = VK_WHOLE_SIZE;
VkWriteDescriptorSet bufferWriteCam = {};
bufferWriteCam.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
bufferWriteCam.pNext = nullptr;
bufferWriteCam.dstBinding = 0;
bufferWriteCam.dstSet = CameraBufferDescriptors;
bufferWriteCam.descriptorCount = 1;
bufferWriteCam.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
bufferWriteCam.pBufferInfo = &camBufferInfo;
vkUpdateDescriptorSets(Device, 1, &bufferWriteCam, 0, nullptr);
// Update descriptor set for TriangleBufferDescriptors
VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = rectangle->GetVertexBuffer()->GetBuffer();
bufferInfo.offset = 0;
bufferInfo.range = VK_WHOLE_SIZE;
VkWriteDescriptorSet bufferWrite = {};
bufferWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
bufferWrite.pNext = nullptr;
bufferWrite.dstBinding = 0;
bufferWrite.dstSet = TriangleBufferDescriptors;
bufferWrite.descriptorCount = 1;
bufferWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
bufferWrite.pBufferInfo = &bufferInfo;
vkUpdateDescriptorSets(Device, 1, &bufferWrite, 0, nullptr);
//VkDescriptorBufferInfo camBufferInfo{};
//camBufferInfo.buffer = CameraBuffer->GetBuffer();
//camBufferInfo.offset = 0;
//camBufferInfo.range = VK_WHOLE_SIZE;
//
//VkWriteDescriptorSet bufferWriteCam = {};
//bufferWriteCam.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
//bufferWriteCam.pNext = nullptr;
//bufferWriteCam.dstBinding = 0;
//bufferWriteCam.dstSet = CameraBufferDescriptors;
//bufferWriteCam.descriptorCount = 1;
//bufferWriteCam.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
//bufferWriteCam.pBufferInfo = &camBufferInfo;
//vkUpdateDescriptorSets(Device, 1, &bufferWriteCam, 0, nullptr);
//
//// Update descriptor set for TriangleBufferDescriptors
//VkDescriptorBufferInfo bufferInfo{};
//bufferInfo.buffer = rectangle->GetVertexBuffer()->GetBuffer();
//bufferInfo.offset = 0;
//bufferInfo.range = VK_WHOLE_SIZE;
//
//VkWriteDescriptorSet bufferWrite = {};
//bufferWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
//bufferWrite.pNext = nullptr;
//bufferWrite.dstBinding = 0;
//bufferWrite.dstSet = TriangleBufferDescriptors;
//bufferWrite.descriptorCount = 1;
//bufferWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
//bufferWrite.pBufferInfo = &bufferInfo;
//vkUpdateDescriptorSets(Device, 1, &bufferWrite, 0, nullptr);
}
void VkRenderer::InitPipeline()
@@ -475,6 +485,14 @@ void VkRenderer::InitTrianglePipeline()
});
}
void VkRenderer::DrawScene(RenderContext ctx)
{
SceneRenderer->BeginScene(ctx);
SceneRenderer->DrawScene();
SceneRenderer->EndScene();
}
void VkRenderer::DrawGeometry(VkCommandBuffer cmd)
{
//begin a render pass connected to our draw image
@@ -679,23 +697,28 @@ void VkRenderer::InitImgui()
});
}
void VkRenderer::BeginScene(const Matrix4 & view, const Matrix4 & projection)
void VkRenderer::BeginScene(const Matrix4& view, const Matrix4& projection)
{
UploadCameraData(CameraData{ view, projection });
CameraData newData = { view, projection };
//UploadCameraData(newData);
SceneRenderer->UpdateCameraData(newData);
}
void VkRenderer::Draw()
bool VkRenderer::Draw()
{
VK_CALL(vkWaitForFences(Device, 1, &GetCurrentFrame().RenderFence, true, 1000000000));
if (SurfaceSize != Window::Get()->GetSize())
{
RecreateSwapchain();
return;
FrameSkipped = true;
return false;
}
FrameSkipped = false;
//request image from the swapchain
uint32_t swapchainImageIndex;
VkResult result = vkAcquireNextImageKHR(Device, Swapchain, 1000000000, GetCurrentFrame().SwapchainSemaphore, nullptr, &swapchainImageIndex);
VK_CALL(vkResetFences(Device, 1, &GetCurrentFrame().RenderFence));
@@ -710,45 +733,54 @@ void VkRenderer::Draw()
DrawExtent.width = DrawImage->GetSize().x;
DrawExtent.height = DrawImage->GetSize().y;
VkCommandBufferSubmitInfo cmdinfo;
// Create commands
VK_CALL(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
// Transfer rendering image to general layout
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
// Execute compute shader that writes to the image
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, Pipeline);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, PipelineLayout, 0, 1, &DrawImageDescriptors, 0, nullptr);
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
//vkCmdDispatch(cmd, std::ceil(DrawExtent.width / 16.0), std::ceil(DrawExtent.height / 16.0), 1);
DrawBackground(cmd);
// Transition rendering iamge to transfert onto swapchain images
//VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VulkanUtil::TransitionImage(cmd, DepthImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
//DrawGeometry(cmd);
return true;
}
void VkRenderer::EndDraw()
{
if (FrameSkipped)
{
// Transfer rendering image to general layout
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
// Execute compute shader that writes to the image
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, Pipeline);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, PipelineLayout, 0, 1, &DrawImageDescriptors, 0, nullptr);
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
//vkCmdDispatch(cmd, std::ceil(DrawExtent.width / 16.0), std::ceil(DrawExtent.height / 16.0), 1);
DrawBackground(cmd);
// Transition rendering iamge to transfert onto swapchain images
//VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
DrawGeometry(cmd);
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
//draw imgui into the swapchain image
DrawImgui(cmd, SwapchainImageViews[swapchainImageIndex]);
// set swapchain image layout to Attachment Optimal so we can draw it
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
// set swapchain image layout to Present so we can draw it
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
// Transition the swapchain image to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR for presentation
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
return;
}
VkCommandBuffer cmd = GetCurrentFrame().CommandBuffer;
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
//draw imgui into the swapchain image
DrawImgui(cmd, SwapchainImageViews[swapchainImageIndex]);
// set swapchain image layout to Attachment Optimal so we can draw it
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
// set swapchain image layout to Present so we can draw it
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
// Transition the swapchain image to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR for presentation
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
VK_CALL(vkEndCommandBuffer(cmd));
cmdinfo = VulkanInit::CommandBufferSubmitInfo(cmd);
VkCommandBufferSubmitInfo cmdinfo = VulkanInit::CommandBufferSubmitInfo(cmd);
// Wait for both semaphore of swapchain and the texture of the frame.
VkSemaphoreSubmitInfo waitInfo = VulkanInit::SemaphoreSubmitInfo(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, GetCurrentFrame().SwapchainSemaphore);
@@ -835,12 +867,10 @@ void VkRenderer::ImmediateSubmit(std::function<void(VkCommandBuffer cmd)>&& func
void VkRenderer::UploadCameraData(const CameraData& data)
{
CameraData adjustedData = data;
adjustedData.Model = glm::translate(Matrix4(1.0f), Vector3(2.0f, 0, -2.5f));
adjustedData.View = Matrix4(1.0f); //data.View;
adjustedData.View = data.View;
adjustedData.Projection = glm::perspective(glm::radians(70.f), (float)DrawExtent.width / (float)DrawExtent.height, 0.0001f, 10000.0f);
adjustedData.Projection[1][1] *= -1;
//adjustedData.Projection[1][1] *= -1;
void* mappedData;
vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (GetCurrentFrame().CameraStagingBuffer->GetAllocation()), &mappedData);

View File

@@ -8,13 +8,13 @@
#include "VulkanImage/VulkanImage.h"
#include "VulkanTypes.h"
#include "VkVertex.h"
#include "RenderContext.h"
#include "VulkanAllocatedBuffer.h"
#include "VulkanSceneRenderer.h"
#include <functional>
#include <span>
#include "vk_mem_alloc.h"
#include "VkMesh.h"
@@ -22,7 +22,7 @@ namespace Nuake
{
class VulkanShader;
class GPUMeshBuffers;
class Scene;
struct AllocatedImage {
VkImage image;
@@ -83,6 +83,7 @@ namespace Nuake
VkCommandBuffer CommandBuffer; // You send commands in there.
Ref<AllocatedBuffer> CameraStagingBuffer;
Ref<AllocatedBuffer> ModelStagingBuffer;
// Semaphore are for GPU -> GPU sync
// Fence are for CPU -> GPU
@@ -121,18 +122,21 @@ namespace Nuake
VkDescriptorSet Allocate(VkDevice device, VkDescriptorSetLayout layout);
};
constexpr unsigned int FRAME_OVERLAP = 2;
struct CameraData
{
Matrix4 Model;
Matrix4 View;
Matrix4 Projection;
};
// Renderer configuration
constexpr uint32_t FRAME_OVERLAP = 2;
constexpr uint32_t MAX_MODEL_MATRIX = 3000;
class VkRenderer
{
private:
bool FrameSkipped = false;
bool IsInitialized = false;
Vector2 SurfaceSize;
VkInstance Instance;
@@ -143,7 +147,7 @@ namespace Nuake
vkb::Device VkbDevice;
VkSurfaceKHR Surface;
uint32_t swapchainImageIndex;
// Swap chain
VkFormat SwapchainImageFormat;
VkSwapchainKHR Swapchain;
@@ -154,11 +158,7 @@ namespace Nuake
// Frame data
uint32_t FrameNumber = 0;
FrameData Frames[FRAME_OVERLAP];
FrameData& GetCurrentFrame() { return Frames[FrameNumber % FRAME_OVERLAP]; };
Ref<VulkanImage> DrawImage;
VkExtent2D DrawExtent;
VkQueue GPUQueue;
uint32_t GPUQueueFamily;
@@ -196,8 +196,15 @@ namespace Nuake
Ref<VkMesh> rectangle;
Ref<AllocatedBuffer> CameraBuffer;
Ref<VkSceneRenderer> SceneRenderer;
public:
Ref<VulkanImage> DrawImage;
Ref<VulkanImage> DepthImage;
VkExtent2D DrawExtent;
FrameData& GetCurrentFrame() { return Frames[FrameNumber % FRAME_OVERLAP]; };
static VkRenderer& Get()
{
static VkRenderer instance;
@@ -230,12 +237,26 @@ namespace Nuake
void InitPipeline();
void InitBackgroundPipeline();
void InitTrianglePipeline();
void DrawScene(RenderContext ctx);
void DrawGeometry(VkCommandBuffer cmd);
void InitImgui();
void BeginScene(const Matrix4& view, const Matrix4& projection);
void Draw();
bool Draw();
void EndDraw();
DescriptorAllocator GetDescriptorAllocator()
{
return GlobalDescriptorAllocator;
}
VkCommandBuffer GetCurrentCmdBuffer()
{
return GetCurrentFrame().CommandBuffer;
}
void DrawBackground(VkCommandBuffer cmd);
void DrawImgui(VkCommandBuffer cmd, VkImageView targetImageView);

View File

@@ -1,28 +1,352 @@
#include "PipelineBuilder.h"
#include "ShaderCompiler.h"
#include "VulkanCheck.h"
#include "VulkanSceneRenderer.h"
#include "src/Rendering/Vulkan/VulkanAllocator.h"
#include "src/Rendering/Vulkan/VulkanInit.h"
#include "src/Rendering/Vulkan/VulkanRenderer.h"
#include "src/Rendering/Vulkan/VkResources.h"
#include "src/Scene/Scene.h"
#include "src/Scene/Entities/Entity.h"
#include <Tracy.hpp>
#include <src/Scene/Components/ModelComponent.h>
using namespace Nuake;
VkSceneRenderer::VkSceneRenderer()
{
}
VkSceneRenderer::~VkSceneRenderer()
{
}
void VkSceneRenderer::Init()
{
// Here we will create the pipeline for rendering a scene
LoadShaders();
CreateBuffers();
CreateDescriptors();
CreateBasicPipeline();
ModelMatrixMapping.clear();
}
void VkSceneRenderer::BeginScene()
void VkSceneRenderer::BeginScene(RenderContext inContext)
{
Context = inContext;
// Collect all global transform of things we will render
BuildMatrixBuffer();
UpdateTransformBuffer();
auto& cmd = Context.CommandBuffer;
auto& scene = Context.CurrentScene;
auto& vk = VkRenderer::Get();
VkRenderingAttachmentInfo colorAttachment = VulkanInit::AttachmentInfo(vk.DrawImage->GetImageView(), nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
VkRenderingAttachmentInfo depthAttachment = VulkanInit::DepthAttachmentInfo(vk.DepthImage->GetImageView(), VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
VkRenderingInfo renderInfo = VulkanInit::RenderingInfo(vk.DrawExtent, &colorAttachment, &depthAttachment);
vkCmdBeginRendering(cmd, &renderInfo);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, BasicPipeline);
std::vector<VkDescriptorSet> descriptors = { CameraBufferDescriptors, ModelBufferDescriptor };
// Bind camera settings
vkCmdBindDescriptorSets(
cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS,
BasicPipelineLayout,
0, // firstSet
2, // descriptorSetCount
descriptors.data(), // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
// Set viewport
VkViewport viewport = {};
viewport.x = 0;
viewport.y = 0;
viewport.width = vk.DrawExtent.width;
viewport.height = vk.DrawExtent.height;
viewport.minDepth = 0.f;
viewport.maxDepth = 1.f;
vkCmdSetViewport(cmd, 0, 1, &viewport);
VkRect2D scissor = {};
scissor.offset.x = 0;
scissor.offset.y = 0;
scissor.extent.width = vk.DrawExtent.width;
scissor.extent.height = vk.DrawExtent.height;
vkCmdSetScissor(cmd, 0, 1, &scissor);
}
void VkSceneRenderer::DrawScene()
{
ZoneScoped;
auto& cmd = Context.CommandBuffer;
auto& scene = Context.CurrentScene;
auto& vk = VkRenderer::Get();
// Draw the scene
{
ZoneScopedN("Render Models");
auto view = scene->m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
for (auto e : view)
{
auto [transform, mesh, visibility] = view.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
if (!mesh.ModelResource || !visibility.Visible)
{
continue;
}
Entity entity = Entity((entt::entity)e, scene.get());
for (auto& m : mesh.ModelResource->GetMeshes())
{
Ref<VkMesh> vkMesh = m->GetVkMesh();
Matrix4 globalTransform = transform.GetGlobalTransform();
auto descSet = vkMesh->GetDescriptorSet();
vkCmdBindDescriptorSets(
cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS,
BasicPipelineLayout,
2, // firstSet
1, // descriptorSetCount
&descSet, // pointer to the descriptor set(s)
0, // dynamicOffsetCount
nullptr // dynamicOffsets
);
ModelPushConstant modelPushConstant{};
modelPushConstant.Index = ModelMatrixMapping[entity.GetID()];
vkCmdPushConstants(
cmd,
BasicPipelineLayout,
VK_SHADER_STAGE_VERTEX_BIT, // Stage matching the pipeline layout
0, // Offset
sizeof(ModelPushConstant), // Size of the push constant
&modelPushConstant // Pointer to the value
);
vkCmdBindIndexBuffer(cmd, vkMesh->GetIndexBuffer()->GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(cmd, vkMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t), 1, 0, 0, 0);
}
}
}
// Quake
{
}
}
void VkSceneRenderer::EndScene()
{
vkCmdEndRendering(Context.CommandBuffer);
}
void VkSceneRenderer::CreateBuffers()
{
CameraData camData{};
camData.View = Matrix4(1.0f);
camData.Projection = Matrix4(1.0f);
// init camera buffer
GPUResources& resources = GPUResources::Get();
CameraBuffer = resources.CreateBuffer(sizeof(CameraData), BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::GPU_ONLY);
UpdateCameraData(camData);
ModelBuffer = resources.CreateBuffer(sizeof(Matrix4) * MAX_MODEL_MATRIX, BufferUsage::STORAGE_BUFFER | BufferUsage::TRANSFER_DST, MemoryUsage::GPU_ONLY);
}
void VkSceneRenderer::LoadShaders()
{
ShaderCompiler& shaderCompiler = ShaderCompiler::Get();
Shaders["basic_frag"] = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/triangle.frag");
Shaders["basic_vert"] = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/triangle.vert");
}
void VkSceneRenderer::CreateBasicPipeline()
{
VkPushConstantRange bufferRange{};
bufferRange.offset = 0;
auto sizeOfThing = sizeof(ModelPushConstant);
bufferRange.size = sizeOfThing;
bufferRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
VkDescriptorSetLayout layouts[] = { CameraBufferDescriptorLayout, ModelBufferDescriptorLayout, TriangleBufferDescriptorLayout };
VkPipelineLayoutCreateInfo pipeline_layout_info = VulkanInit::PipelineLayoutCreateInfo();
pipeline_layout_info.pPushConstantRanges = &bufferRange;
pipeline_layout_info.pushConstantRangeCount = 1;
pipeline_layout_info.pSetLayouts = layouts;
pipeline_layout_info.setLayoutCount = 3;
VK_CALL(vkCreatePipelineLayout(VkRenderer::Get().GetDevice(), &pipeline_layout_info, nullptr, &BasicPipelineLayout));
//use the triangle layout we created
PipelineBuilder pipelineBuilder;
pipelineBuilder.PipelineLayout = BasicPipelineLayout;
pipelineBuilder.SetShaders(Shaders["basic_vert"]->GetModule(), Shaders["basic_frag"]->GetModule());
pipelineBuilder.SetInputTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
pipelineBuilder.SetPolygonMode(VK_POLYGON_MODE_FILL);
pipelineBuilder.SetCullMode(VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE);
pipelineBuilder.SetMultiSamplingNone();
pipelineBuilder.EnableBlendingAlphaBlend();
pipelineBuilder.SetColorAttachment(static_cast<VkFormat>(VkRenderer::Get().DrawImage->GetFormat()));
pipelineBuilder.SetDepthFormat(static_cast<VkFormat>(VkRenderer::Get().DepthImage->GetFormat()));
pipelineBuilder.EnableDepthTest(true, VK_COMPARE_OP_GREATER_OR_EQUAL);
BasicPipeline = pipelineBuilder.BuildPipeline(VkRenderer::Get().GetDevice());
}
void VkSceneRenderer::CreateDescriptors()
{
auto vk = VkRenderer::Get();
auto device = vk.GetDevice();
// Camera
{
DescriptorLayoutBuilder builder;
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
CameraBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL);
}
{
// Triangle vertex buffer layout
DescriptorLayoutBuilder builder;
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
TriangleBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_VERTEX_BIT);
}
{
// Matrices
DescriptorLayoutBuilder builder;
builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
ModelBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL);
}
auto allocator = vk.GetDescriptorAllocator();
TriangleBufferDescriptors = allocator.Allocate(device, TriangleBufferDescriptorLayout);
CameraBufferDescriptors = allocator.Allocate(device, CameraBufferDescriptorLayout);
ModelBufferDescriptor = allocator.Allocate(device, ModelBufferDescriptorLayout);
// Update descriptor set for camera
VkDescriptorBufferInfo camBufferInfo{};
camBufferInfo.buffer = CameraBuffer->GetBuffer();
camBufferInfo.offset = 0;
camBufferInfo.range = VK_WHOLE_SIZE;
VkWriteDescriptorSet bufferWriteCam = {};
bufferWriteCam.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
bufferWriteCam.pNext = nullptr;
bufferWriteCam.dstBinding = 0;
bufferWriteCam.dstSet = CameraBufferDescriptors;
bufferWriteCam.descriptorCount = 1;
bufferWriteCam.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
bufferWriteCam.pBufferInfo = &camBufferInfo;
vkUpdateDescriptorSets(device, 1, &bufferWriteCam, 0, nullptr);
}
void VkSceneRenderer::UpdateCameraData(const CameraData& data)
{
CameraData adjustedData = data;
adjustedData.View = Matrix4(1.0f); //data.View;
adjustedData.View = data.View;
adjustedData.Projection = data.Projection;
//adjustedData.Projection[1][1] *= -1;
void* mappedData;
vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (VkRenderer::Get().GetCurrentFrame().CameraStagingBuffer->GetAllocation()), &mappedData);
memcpy(mappedData, &adjustedData, sizeof(CameraData));
VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd) {
VkBufferCopy copy{ 0 };
copy.dstOffset = 0;
copy.srcOffset = 0;
copy.size = sizeof(CameraData);
vkCmdCopyBuffer(cmd, VkRenderer::Get().GetCurrentFrame().CameraStagingBuffer->GetBuffer(), CameraBuffer->GetBuffer(), 1, &copy);
});
vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), VkRenderer::Get().GetCurrentFrame().CameraStagingBuffer->GetAllocation());
}
void VkSceneRenderer::BuildMatrixBuffer()
{
// This will scan and build the matrix buffer for the next frame.
// It will create a mapping between UUID and the corresponding index for the model matrix
ZoneScopedN("Build Matrix Buffer");
auto& scene = Context.CurrentScene;
std::array<Matrix4, MAX_MODEL_MATRIX> allTransforms;
uint32_t currentIndex = 0;
auto view = scene->m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();
for (auto e : view)
{
// Check if we've reached the maximum capacity of the array
if (currentIndex >= MAX_MODEL_MATRIX)
{
assert(false);
break;
}
auto [transform, mesh, visibility] = view.get<TransformComponent, ModelComponent, VisibilityComponent>(e);
if (!mesh.ModelResource || !visibility.Visible)
{
continue;
}
allTransforms[currentIndex] = transform.GetGlobalTransform();
Entity entity = Entity((entt::entity)e, scene.get());
ModelMatrixMapping[entity.GetID()] = currentIndex;
currentIndex++;
}
ModelTransforms = ModelData{ allTransforms };
}
void VkSceneRenderer::UpdateTransformBuffer()
{
void* mappedData;
vmaMapMemory(VulkanAllocator::Get().GetAllocator(), (VkRenderer::Get().GetCurrentFrame().ModelStagingBuffer->GetAllocation()), &mappedData);
memcpy(mappedData, &ModelTransforms, sizeof(ModelData));
VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd) {
VkBufferCopy copy{ 0 };
copy.dstOffset = 0;
copy.srcOffset = 0;
copy.size = sizeof(ModelData);
vkCmdCopyBuffer(cmd, VkRenderer::Get().GetCurrentFrame().ModelStagingBuffer->GetBuffer(), ModelBuffer->GetBuffer(), 1, &copy);
});
vmaUnmapMemory(VulkanAllocator::Get().GetAllocator(), VkRenderer::Get().GetCurrentFrame().ModelStagingBuffer->GetAllocation());
// Update descriptor set for camera
VkDescriptorBufferInfo transformBufferInfo{};
transformBufferInfo.buffer = ModelBuffer->GetBuffer();
transformBufferInfo.offset = 0;
transformBufferInfo.range = VK_WHOLE_SIZE;
VkWriteDescriptorSet bufferWriteModel = {};
bufferWriteModel.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
bufferWriteModel.pNext = nullptr;
bufferWriteModel.dstBinding = 0;
bufferWriteModel.dstSet = ModelBufferDescriptor;
bufferWriteModel.descriptorCount = 1;
bufferWriteModel.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
bufferWriteModel.pBufferInfo = &transformBufferInfo;
vkUpdateDescriptorSets(VkRenderer::Get().GetDevice(), 1, &bufferWriteModel, 0, nullptr);
}

View File

@@ -1,14 +1,75 @@
#pragma once
#include "src/Core/Core.h"
#include "src/Core/Maths.h"
#include "src/Rendering/Vulkan/RenderContext.h"
#include "src/Rendering/Vulkan/VulkanShader.h"
#include "src/Rendering/Vulkan/VulkanAllocatedBuffer.h"
#include <volk/volk.h>
#include <array>
#include <map>
#include <string>
namespace Nuake
{
struct CameraData;
struct ModelPushConstant
{
int Index;
char padding[124]; // 124 bytes to reach 128 bytes
};
struct ModelData
{
std::array<Matrix4, 3000> Data;
};
class VkSceneRenderer
{
private:
RenderContext Context;
std::map<std::string, Ref<VulkanShader>> Shaders;
VkPipeline BasicPipeline;
VkPipelineLayout BasicPipelineLayout;
Ref<AllocatedBuffer> CameraBuffer;
VkDescriptorSet TriangleBufferDescriptors;
VkDescriptorSetLayout TriangleBufferDescriptorLayout;
VkDescriptorSet CameraBufferDescriptors;
VkDescriptorSetLayout CameraBufferDescriptorLayout;
Ref<AllocatedBuffer> ModelBuffer;
VkDescriptorSet ModelBufferDescriptor;
VkDescriptorSetLayout ModelBufferDescriptorLayout;
ModelData ModelTransforms;
std::map<UUID, uint32_t> ModelMatrixMapping;
public:
VkSceneRenderer();
~VkSceneRenderer();
void Init();
void BeginScene();
void UpdateCameraData(const CameraData& data);
void BeginScene(RenderContext inContext);
void DrawScene();
void EndScene();
private:
void LoadShaders();
void CreateBuffers();
void CreateBasicPipeline();
void CreateDescriptors();
void BuildMatrixBuffer();
void UpdateTransformBuffer();
};
}

View File

@@ -79,10 +79,9 @@ namespace Nuake
{
for (auto& m : j["Meshes"])
{
Ref<Mesh> mesh = CreateRef<Mesh>();
mesh->Deserialize(m);
m_Meshes.push_back(mesh);
//Ref<Mesh> mesh = CreateRef<VkMesh>();
//mesh->Deserialize(m);
//m_Meshes.push_back(mesh);
}
}
}

View File

@@ -5,6 +5,7 @@
#include "src/Resource/Serializable.h"
#include "src/Rendering/Mesh/Mesh.h"
namespace Nuake
{
class Model : public Resource, ISerializable

View File

@@ -290,7 +290,8 @@ namespace Nuake
vertex.tangent = {
mesh->mTangents[i].x,
mesh->mTangents[i].z,
mesh->mTangents[i].y
mesh->mTangents[i].y,
0.0f
} ;
}
@@ -299,19 +300,19 @@ namespace Nuake
vertex.bitangent = {
mesh->mBitangents[i].x,
mesh->mBitangents[i].z,
mesh->mBitangents[i].y
mesh->mBitangents[i].y,
0.0f
};
}
vertex.uv = glm::vec2(0.0f, 0.0f);
vertex.uv_x = 0.0f;
vertex.uv_y = 0.0f;
// Does it contain UVs?
if (mesh->mTextureCoords[0])
{
vertex.uv = {
mesh->mTextureCoords[0][i].x,
mesh->mTextureCoords[0][i].y
};
vertex.uv_x = mesh->mTextureCoords[0][i].x;
vertex.uv_y = mesh->mTextureCoords[0][i].y;
}
vertices.push_back(std::move(vertex));

View File

@@ -45,6 +45,9 @@ p = j[#p]; \
#define DESERIALIZE_VEC4(v, p) \
p = Vector4(v["x"], v["y"], v["z"], v["w"]);
#define DESERIALIZE_VEC3_INTO4(v, p) \
p = Vector4(v["x"], v["y"], v["z"], 0.0f);
#define DESERIALIZE_VEC3(v, p) \
p = Vector3(v["x"], v["y"], v["z"]);

View File

@@ -26,13 +26,13 @@ namespace Nuake
std::vector<Vertex> quadVertices =
{
{ Vector3(-1.0f, 1.0f, 0.0f), Vector2(0.0f, 1.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), Vector2(0, 0), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(-1.0f, 1.0f, 0.0f), 0.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), 1.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), 0.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(1.0f, -1.0f, 0.0f), Vector2(1.0f, 0.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), Vector2(0.0f, 0.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f), Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0) }
{ Vector3(1.0f, -1.0f, 0.0f), 1.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(-1.0f, -1.0f, 0.0f), 0.0f, Vector3(0, 0, 1), 0.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) },
{ Vector3(1.0f, 1.0f, 0.0f), 1.0f, Vector3(0, 0, 1), 1.0f, Vector4(1, 0, 0, 0), Vector4(0, 1, 0, 0) }
};
SpriteMesh = CreateRef<Mesh>();

View File

@@ -344,10 +344,11 @@ namespace Nuake {
vertices.push_back(Vertex{
vertexPos * (1.0f / 64.0f),
vertexUV,
vertexUV.x,
vertexNormal,
vertexTangent,
vertexBitangent
vertexUV.y,
Vector4(vertexTangent, 0),
Vector4(vertexBitangent, 0)
});
}
@@ -498,10 +499,11 @@ namespace Nuake {
vertices.push_back(Vertex {
vertexPos * (1.0f / 64.0f),
vertexUV,
vertexUV.x,
vertexNormal,
vertexTangent,
vertexBitangent
vertexUV.y,
Vector4(vertexTangent, 0),
Vector4(vertexBitangent, 0)
});
}

View File

@@ -213,7 +213,7 @@ void Window::Draw()
ZoneScopedN("Non-playmode Draw");
float resolutionScale = glm::clamp(Engine::GetProject()->Settings.ResolutionScale, 0.5f, 2.0f);
this->scene->m_EditorCamera->OnWindowResize(size.x * resolutionScale, size.y * resolutionScale);
VkRenderer::Get().BeginScene(scene->m_EditorCamera->GetPerspective(), scene->m_EditorCamera->GetTransform());
VkRenderer::Get().BeginScene(scene->m_EditorCamera->GetTransform(), scene->m_EditorCamera->GetPerspective());
this->scene->Draw(*this->framebuffer.get(), this->scene->m_EditorCamera->GetPerspective(), this->scene->m_EditorCamera->GetTransform());
}
@@ -233,7 +233,22 @@ void Window::EndDraw()
ImGui::Render();
}
VkRenderer::Get().Draw();
auto& vkRenderer = VkRenderer::Get();
if(vkRenderer.Draw())
{
// Render whatever we want in here :)
if (auto scene = GetScene(); scene != nullptr)
{
RenderContext ctx
{
scene,
vkRenderer.GetCurrentCmdBuffer()
};
vkRenderer.DrawScene(ctx);
}
}
vkRenderer.EndDraw();
//ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

View File

@@ -1,12 +1,17 @@
struct World
struct Camera
{
float4x4 model;
float4x4 view;
float4x4 proj;
};
[[vk::binding(0, 0)]]
StructuredBuffer<World> world : register(t0);
StructuredBuffer<Camera> camera : register(t0);
struct ModelData
{
float4x4 model;
};
[[vk::binding(0, 1)]]
StructuredBuffer<ModelData> model : register(t1);
struct Vertex
{
@@ -18,14 +23,17 @@ struct Vertex
float4 bitangent;
};
[[vk::binding(0, 1)]]
StructuredBuffer<Vertex> vertexBuffer : register(t1);
[[vk::binding(0, 2)]]
StructuredBuffer<Vertex> vertexBuffer : register(t2);
cbuffer PushConstants : register(b0)
{
float4x4 render_matrix;
struct ModelPushConstant
{
int modelIndex; // Push constant data
};
[[vk::push_constant]]
ModelPushConstant pushConstants;
// Outputs
struct VSOutput {
float4 Position : SV_Position;
@@ -38,14 +46,16 @@ VSOutput main(uint vertexIndex : SV_VertexID)
{
VSOutput output;
World worldData = world[0];
Camera camData = camera[0];
ModelData modelData = model[pushConstants.modelIndex];
// Load vertex data from the buffer
Vertex v = vertexBuffer[vertexIndex];
// Output the position of each vertex
output.Position = mul(worldData.proj, mul(worldData.view, mul(worldData.model, float4(v.position, 1.0f))));
output.Color = float3(v.normal.xyz);
output.Position = mul(camData.proj, mul(camData.view, mul(modelData.model, float4(v.position, 1.0f))));
output.Color = normalize(float3(v.position.xyz));
return output;
}