diff --git a/Editor/src/Windows/EditorInterface.cpp b/Editor/src/Windows/EditorInterface.cpp index defa6a5b..d13a6ddb 100644 --- a/Editor/src/Windows/EditorInterface.cpp +++ b/Editor/src/Windows/EditorInterface.cpp @@ -60,6 +60,7 @@ #include #include "src/Rendering/Vulkan/VulkanRenderer.h" +#include 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(); diff --git a/Editor/src/Windows/EditorInterface.h b/Editor/src/Windows/EditorInterface.h index c3da76d5..b70afca0 100644 --- a/Editor/src/Windows/EditorInterface.h +++ b/Editor/src/Windows/EditorInterface.h @@ -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}; diff --git a/Nuake/src/Rendering/Camera.h b/Nuake/src/Rendering/Camera.h index 333e19f8..1dd6bf2b 100644 --- a/Nuake/src/Rendering/Camera.h +++ b/Nuake/src/Rendering/Camera.h @@ -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; diff --git a/Nuake/src/Rendering/Mesh/Mesh.cpp b/Nuake/src/Rendering/Mesh/Mesh.cpp index 1d493c2c..dc30a905 100644 --- a/Nuake/src/Rendering/Mesh/Mesh.cpp +++ b/Nuake/src/Rendering/Mesh/Mesh.cpp @@ -12,6 +12,7 @@ #include #include +#include namespace Nuake { @@ -82,43 +83,46 @@ namespace Nuake void Mesh::SetupMesh() { - m_VertexArray = CreateScope(); - m_VertexArray->Bind(); - m_VertexBuffer = CreateScope(m_Vertices.data(), static_cast(m_Vertices.size() * sizeof(Vertex))); - m_ElementBuffer = CreateScope(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(3); // Position - bufferLayout.Push(2); // UV - bufferLayout.Push(3); // Normal - bufferLayout.Push(3); // Tangent - bufferLayout.Push(3); // Bitangent - - m_VertexArray->AddBuffer(*m_VertexBuffer, bufferLayout); - m_VertexArray->Unbind(); + //m_VertexArray = CreateScope(); + //m_VertexArray->Bind(); + //m_VertexBuffer = CreateScope(m_Vertices.data(), static_cast(m_Vertices.size() * sizeof(Vertex))); + //m_ElementBuffer = CreateScope(m_Indices.data(), m_Indices.size() * sizeof(unsigned int), RendererEnum::ELEMENT_ARRAY_BUFFER); + // + //VertexBufferLayout bufferLayout = VertexBufferLayout(); + //bufferLayout.Push(3); // Position + //bufferLayout.Push(2); // UV + //bufferLayout.Push(3); // Normal + //bufferLayout.Push(3); // Tangent + //bufferLayout.Push(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); } diff --git a/Nuake/src/Rendering/Mesh/Mesh.h b/Nuake/src/Rendering/Mesh/Mesh.h index 20554c9f..862098b0 100644 --- a/Nuake/src/Rendering/Mesh/Mesh.h +++ b/Nuake/src/Rendering/Mesh/Mesh.h @@ -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 GetVkMesh() + { + return m_Mesh; + } + private: Ref m_Material = nullptr; std::vector m_Indices; @@ -42,9 +49,10 @@ namespace Nuake uint32_t m_IndicesCount; uint32_t m_VerticesCount; - Scope m_VertexBuffer; - Scope m_VertexArray; - Scope m_ElementBuffer; + Ref m_Mesh; + //Scope m_VertexBuffer; + //Scope m_VertexArray; + //Scope m_ElementBuffer; void SetupMesh(); diff --git a/Nuake/src/Rendering/Renderer.cpp b/Nuake/src/Rendering/Renderer.cpp index 169b8777..3ec3f9a9 100644 --- a/Nuake/src/Rendering/Renderer.cpp +++ b/Nuake/src/Rendering/Renderer.cpp @@ -49,54 +49,54 @@ namespace Nuake std::vector 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 CubeIndices; std::vector 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 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(); diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index 378c1b48..e714204e 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -102,8 +102,8 @@ namespace Nuake // Generate debug meshes std::vector 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 lineIndices diff --git a/Nuake/src/Rendering/Vertex.h b/Nuake/src/Rendering/Vertex.h index 1bfc9e72..4a347610 100644 --- a/Nuake/src/Rendering/Vertex.h +++ b/Nuake/src/Rendering/Vertex.h @@ -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; diff --git a/Nuake/src/Rendering/Vulkan/PipelineBuilder.cpp b/Nuake/src/Rendering/Vulkan/PipelineBuilder.cpp index 7ccf7464..1b807f06 100644 --- a/Nuake/src/Rendering/Vulkan/PipelineBuilder.cpp +++ b/Nuake/src/Rendering/Vulkan/PipelineBuilder.cpp @@ -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; +} \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/PipelineBuilder.h b/Nuake/src/Rendering/Vulkan/PipelineBuilder.h index 6ce0eb74..fb46ec44 100644 --- a/Nuake/src/Rendering/Vulkan/PipelineBuilder.h +++ b/Nuake/src/Rendering/Vulkan/PipelineBuilder.h @@ -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(); }; } \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/RenderContext.h b/Nuake/src/Rendering/Vulkan/RenderContext.h new file mode 100644 index 00000000..91ef17a4 --- /dev/null +++ b/Nuake/src/Rendering/Vulkan/RenderContext.h @@ -0,0 +1,17 @@ +#pragma once +#include "src/Core/Core.h" + +#include + +namespace Nuake +{ + class Scene; + + struct RenderContext + { + Ref CurrentScene; // The scene we are rendering + VkCommandBuffer CommandBuffer; // The command buffer we are recording into + // ... + // We might add more to this! + }; +} \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VkMesh.cpp b/Nuake/src/Rendering/Vulkan/VkMesh.cpp index 7d933af7..66d2e983 100644 --- a/Nuake/src/Rendering/Vulkan/VkMesh.cpp +++ b/Nuake/src/Rendering/Vulkan/VkMesh.cpp @@ -6,10 +6,10 @@ using namespace Nuake; -VkMesh::VkMesh(const std::vector& vertices, const std::vector& indices) +VkMesh::VkMesh(const std::vector& vertices, const std::vector& 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& vertices, const std::vector& vertices, const std::vector& indices) +void VkMesh::UploadToGPU(const std::vector& vertices, const std::vector& 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& vertices, const std::vecto vkCmdCopyBuffer(cmd, staging.GetBuffer(), IndexBuffer->GetBuffer(), 1, &indexCopy); }); -} \ No newline at end of file + + 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); +} diff --git a/Nuake/src/Rendering/Vulkan/VkMesh.h b/Nuake/src/Rendering/Vulkan/VkMesh.h index 715fa62d..1c6e3dad 100644 --- a/Nuake/src/Rendering/Vulkan/VkMesh.h +++ b/Nuake/src/Rendering/Vulkan/VkMesh.h @@ -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 IndexBuffer; Ref VertexBuffer; + VkDescriptorSet DescriptorSet; + VkDescriptorSetLayout DescriptorLayout; + public: - VkMesh(const std::vector& vertices, const std::vector& indices); + VkMesh(const std::vector& vertices, const std::vector& indices); ~VkMesh() = default; Ref 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& vertices, const std::vector& indices); + void UploadToGPU(const std::vector& vertices, const std::vector& indices); + void CreateDescriptorSet(); }; } \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VkResources.h b/Nuake/src/Rendering/Vulkan/VkResources.h index 3689002e..459013ff 100644 --- a/Nuake/src/Rendering/Vulkan/VkResources.h +++ b/Nuake/src/Rendering/Vulkan/VkResources.h @@ -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 +#include "src/Core/Logger.h" namespace Nuake { @@ -55,7 +55,18 @@ namespace Nuake return nullptr; } - Ref CreateMesh(const std::vector& vertices, const std::vector& indices) + std::vector> GetAllBuffers() + { + std::vector> allBuffers; + allBuffers.reserve(Buffers.size()); + for (const auto& [id, buffer] : Buffers) + { + allBuffers.push_back(buffer); + } + return allBuffers; + } + + Ref CreateMesh(const std::vector& vertices, const std::vector& indices) { Ref mesh = CreateRef(vertices, indices); Meshes[mesh->GetID()] = mesh; diff --git a/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.cpp b/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.cpp index 39a47de0..47872eb3 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.cpp @@ -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(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(inFormat), Image, VK_IMAGE_ASPECT_COLOR_BIT); + VkImageViewCreateInfo imageViewCreateInfo; + if (usage == ImageUsage::Depth) + { + imageViewCreateInfo = VulkanInit::ImageviewCreateInfo(static_cast(inFormat), Image, VK_IMAGE_ASPECT_DEPTH_BIT); + } + else + { + imageViewCreateInfo = VulkanInit::ImageviewCreateInfo(static_cast(inFormat), Image, VK_IMAGE_ASPECT_COLOR_BIT); + } + VK_CALL(vkCreateImageView(VkRenderer::Get().GetDevice(), &imageViewCreateInfo, nullptr, &ImageView)); } diff --git a/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.h b/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.h index 2568cd79..580acf65 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.h +++ b/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.h @@ -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(); diff --git a/Nuake/src/Rendering/Vulkan/VulkanInit.cpp b/Nuake/src/Rendering/Vulkan/VulkanInit.cpp index fd17162f..b297a471 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanInit.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanInit.cpp @@ -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) { diff --git a/Nuake/src/Rendering/Vulkan/VulkanInit.h b/Nuake/src/Rendering/Vulkan/VulkanInit.h index 97b01a4c..4bfd6459 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanInit.h +++ b/Nuake/src/Rendering/Vulkan/VulkanInit.h @@ -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(); diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp index cd2af6b1..1422e018 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp @@ -24,6 +24,8 @@ using namespace Nuake; #include "vk_mem_alloc.h" +#include +#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 rect_vertices; + std::vector 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 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(); + SceneRenderer->Init(); + IsInitialized = true; } @@ -250,6 +266,7 @@ void VkRenderer::CreateSwapchain(const Vector2& size) }; DrawImage = CreateRef(ImageFormat::RGBA16F, size); + DepthImage = CreateRef(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 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&& 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); diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h index ae62403d..112a8be6 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h @@ -8,13 +8,13 @@ #include "VulkanImage/VulkanImage.h" #include "VulkanTypes.h" #include "VkVertex.h" - +#include "RenderContext.h" #include "VulkanAllocatedBuffer.h" +#include "VulkanSceneRenderer.h" #include #include - #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 CameraStagingBuffer; + Ref 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 DrawImage; - VkExtent2D DrawExtent; - + VkQueue GPUQueue; uint32_t GPUQueueFamily; @@ -196,8 +196,15 @@ namespace Nuake Ref rectangle; Ref CameraBuffer; + Ref SceneRenderer; public: + + Ref DrawImage; + Ref 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); diff --git a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp index 28fb81cd..14e48e20 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp @@ -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 +#include + + 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 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(); + for (auto e : view) + { + auto [transform, mesh, visibility] = view.get(e); + + if (!mesh.ModelResource || !visibility.Visible) + { + continue; + } + + Entity entity = Entity((entt::entity)e, scene.get()); + for (auto& m : mesh.ModelResource->GetMeshes()) + { + Ref 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(VkRenderer::Get().DrawImage->GetFormat())); + pipelineBuilder.SetDepthFormat(static_cast(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, ©); + }); + + 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 allTransforms; + + uint32_t currentIndex = 0; + auto view = scene->m_Registry.view(); + 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(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, ©); + }); + + 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); } \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h index 807e305e..d41eb5c0 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h @@ -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 + +#include +#include +#include + + namespace Nuake { + struct CameraData; + + struct ModelPushConstant + { + int Index; + char padding[124]; // 124 bytes to reach 128 bytes + }; + + struct ModelData + { + std::array Data; + }; + class VkSceneRenderer { + private: + RenderContext Context; + + std::map> Shaders; + VkPipeline BasicPipeline; + VkPipelineLayout BasicPipelineLayout; + + Ref CameraBuffer; + + VkDescriptorSet TriangleBufferDescriptors; + VkDescriptorSetLayout TriangleBufferDescriptorLayout; + + VkDescriptorSet CameraBufferDescriptors; + VkDescriptorSetLayout CameraBufferDescriptorLayout; + + Ref ModelBuffer; + VkDescriptorSet ModelBufferDescriptor; + VkDescriptorSetLayout ModelBufferDescriptorLayout; + + ModelData ModelTransforms; + std::map 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(); }; } \ No newline at end of file diff --git a/Nuake/src/Resource/Model.cpp b/Nuake/src/Resource/Model.cpp index 3b306259..5dd9f5c5 100644 --- a/Nuake/src/Resource/Model.cpp +++ b/Nuake/src/Resource/Model.cpp @@ -79,10 +79,9 @@ namespace Nuake { for (auto& m : j["Meshes"]) { - Ref mesh = CreateRef(); - mesh->Deserialize(m); - - m_Meshes.push_back(mesh); + //Ref mesh = CreateRef(); + //mesh->Deserialize(m); + //m_Meshes.push_back(mesh); } } } diff --git a/Nuake/src/Resource/Model.h b/Nuake/src/Resource/Model.h index 4bfe6ed7..8ae59ac5 100644 --- a/Nuake/src/Resource/Model.h +++ b/Nuake/src/Resource/Model.h @@ -5,6 +5,7 @@ #include "src/Resource/Serializable.h" #include "src/Rendering/Mesh/Mesh.h" + namespace Nuake { class Model : public Resource, ISerializable diff --git a/Nuake/src/Resource/ModelLoader.cpp b/Nuake/src/Resource/ModelLoader.cpp index ec703407..7309fc13 100644 --- a/Nuake/src/Resource/ModelLoader.cpp +++ b/Nuake/src/Resource/ModelLoader.cpp @@ -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)); diff --git a/Nuake/src/Resource/Serializable.h b/Nuake/src/Resource/Serializable.h index f85a9ce2..69eb853e 100644 --- a/Nuake/src/Resource/Serializable.h +++ b/Nuake/src/Resource/Serializable.h @@ -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"]); diff --git a/Nuake/src/Scene/Components/SpriteComponent.cpp b/Nuake/src/Scene/Components/SpriteComponent.cpp index 67d91ab7..44537157 100644 --- a/Nuake/src/Scene/Components/SpriteComponent.cpp +++ b/Nuake/src/Scene/Components/SpriteComponent.cpp @@ -26,13 +26,13 @@ namespace Nuake std::vector 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(); diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp index b5e50d3b..6f5099e0 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp @@ -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) }); } diff --git a/Nuake/src/Window.cpp b/Nuake/src/Window.cpp index d6352558..90141a57 100644 --- a/Nuake/src/Window.cpp +++ b/Nuake/src/Window.cpp @@ -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()); diff --git a/Resources/Shaders/Vulkan/triangle.vert b/Resources/Shaders/Vulkan/triangle.vert index 7d450b4c..1da1f020 100644 --- a/Resources/Shaders/Vulkan/triangle.vert +++ b/Resources/Shaders/Vulkan/triangle.vert @@ -1,12 +1,17 @@ -struct World +struct Camera { - float4x4 model; float4x4 view; float4x4 proj; }; - [[vk::binding(0, 0)]] -StructuredBuffer world : register(t0); +StructuredBuffer camera : register(t0); + +struct ModelData +{ + float4x4 model; +}; +[[vk::binding(0, 1)]] +StructuredBuffer model : register(t1); struct Vertex { @@ -18,14 +23,17 @@ struct Vertex float4 bitangent; }; -[[vk::binding(0, 1)]] -StructuredBuffer vertexBuffer : register(t1); +[[vk::binding(0, 2)]] +StructuredBuffer 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; } \ No newline at end of file