mirror of
https://github.com/antopilo/Nuake.git
synced 2026-01-06 06:09:52 +03:00
Compare commits
6 Commits
ad581b1d4e
...
1f219ba8bc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f219ba8bc | ||
|
|
e656c01bda | ||
|
|
ef29123dec | ||
|
|
3ceeb3e272 | ||
|
|
54eff5f454 | ||
|
|
b2510a4365 |
@@ -21,9 +21,9 @@ SceneEditorWindow::SceneEditorWindow(Ref<Scene> inScene) :
|
||||
{
|
||||
RegisterWidget<SceneHierarchyWidget>();
|
||||
RegisterWidget<SelectionPropertyWidget>();
|
||||
RegisterWidget<LoggerWidget>();
|
||||
RegisterWidget<ViewportWidget>();
|
||||
RegisterWidget<FileBrowserWidget>();
|
||||
RegisterWidget<ViewportWidget>();
|
||||
RegisterWidget<LoggerWidget>();
|
||||
|
||||
imguiId = editorContext.GetScene()->Path.empty() ? "New Scene" : editorContext.GetScene()->Path;
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <Nuake/Scene/Components/ParticleEmitterComponent.h>
|
||||
#include <Nuake/Scene/Components/RigidbodyComponent.h>
|
||||
|
||||
#include <Nuake/Scene/Components/BoxCollider.h>
|
||||
#include <Nuake/Scene/Components/SphereCollider.h>
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
@@ -34,7 +36,7 @@ void ViewportWidget::Update(float ts)
|
||||
if (!Engine::IsPlayMode())
|
||||
{
|
||||
EditorCamera& editorCam = reinterpret_cast<EditorCamera&>(*editorContext.GetScene()->GetCurrentCamera().get());
|
||||
editorCam.Update(ts, isHoveringViewport);
|
||||
IsControllingCamera = editorCam.Update(ts, isHoveringViewport);
|
||||
}
|
||||
|
||||
const Vector2 viewportSize = sceneViewport->GetViewportSize();
|
||||
@@ -57,6 +59,8 @@ void ViewportWidget::Draw()
|
||||
{
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
DrawOverlay();
|
||||
|
||||
ImGuizmo::BeginFrame();
|
||||
ImGuizmo::SetOrthographic(false);
|
||||
|
||||
@@ -64,6 +68,7 @@ void ViewportWidget::Draw()
|
||||
Vector2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
|
||||
|
||||
bool needsResize = sceneViewport->QueueResize(viewportPanelSize);
|
||||
editorContext.GetScene()->GetCurrentCamera()->OnWindowResize(regionAvail.x, regionAvail.y);
|
||||
|
||||
// This is important for make UI mouse coord relative to viewport
|
||||
// Nuake::Input::SetViewportDimensions(m_ViewportPos, viewportPanelSize);
|
||||
@@ -204,7 +209,7 @@ void ViewportWidget::OnSceneChanged(Ref<Nuake::Scene> scene)
|
||||
}
|
||||
|
||||
// Create new viewport with same reoslution
|
||||
const UUID viewId = editorContext.GetScene()->m_EditorCamera->ID;
|
||||
const UUID viewId = editorContext.GetScene()->GetCurrentCamera()->ID;
|
||||
auto viewport = vkRenderer.CreateViewport(viewId, currentResolution);
|
||||
vkRenderer.RegisterSceneViewport(scene, viewport->GetID());
|
||||
|
||||
@@ -262,7 +267,71 @@ void ViewportWidget::OnLineDraw(DebugLineCmd& lineCmd)
|
||||
|
||||
Matrix4 transform = Matrix4(1.0f);
|
||||
transform = glm::translate(transform, { 0, 2, 0 });
|
||||
lineCmd.DrawLine(proj * view * transform, Color(1, 0, 0, 1), 4.0f);
|
||||
//lineCmd.DrawLine(proj * view * transform, Color(1, 0, 0, 1), 2.0f);
|
||||
|
||||
auto camView = scene->m_Registry.view<TransformComponent, CameraComponent>();
|
||||
for (auto e : camView)
|
||||
{
|
||||
auto [transform, camera] = scene->m_Registry.get<TransformComponent, CameraComponent>(e);
|
||||
const Quat& globalRotation = glm::normalize(transform.GetGlobalRotation());
|
||||
const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation);
|
||||
|
||||
const float aspectRatio = camera.CameraInstance->AspectRatio;
|
||||
const float fov = camera.CameraInstance->Fov;
|
||||
|
||||
Matrix4 clampedProj = glm::perspectiveFov(glm::radians(fov), 9.0f * aspectRatio, 9.0f, 0.05f, 3.0f);
|
||||
Matrix4 boxTransform = glm::translate(scene->m_EditorCamera->GetTransform(), Vector3(transform.GetGlobalTransform()[3])) * rotationMatrix * glm::inverse(clampedProj);
|
||||
lineCmd.DrawBox(proj * boxTransform, Color(1, 0, 0, 1.0f), 1.5f, false);
|
||||
}
|
||||
|
||||
auto boxColliderView = scene->m_Registry.view<TransformComponent, BoxColliderComponent>();
|
||||
for (auto e : boxColliderView)
|
||||
{
|
||||
auto [transform, boxCollider] = scene->m_Registry.get<TransformComponent, BoxColliderComponent>(e);
|
||||
|
||||
Vector3 boxSize = boxCollider.GetSize();
|
||||
Matrix4 boxTransform = Matrix4(1.0f);
|
||||
boxTransform = glm::translate(boxTransform, Vector3(transform.GetGlobalTransform()[3]));
|
||||
boxTransform = glm::scale(boxTransform, boxSize);
|
||||
lineCmd.DrawBox(proj * view * boxTransform, Color(0, 1, 0, 1.0f), 1.5f, boxCollider.IsTrigger);
|
||||
}
|
||||
|
||||
auto sphereColliderView = scene->m_Registry.view<TransformComponent, SphereColliderComponent>();
|
||||
for (auto e : sphereColliderView)
|
||||
{
|
||||
auto [transformComponent, sphereCollider] = scene->m_Registry.get<TransformComponent, SphereColliderComponent>(e);
|
||||
|
||||
float radius = sphereCollider.GetRadius();
|
||||
Matrix4 transform = Matrix4(1.0f);
|
||||
transform = glm::translate(transform, Vector3(transformComponent.GetGlobalTransform()[3]));
|
||||
transform = glm::scale(transform, Vector3(sphereCollider.GetRadius()));
|
||||
lineCmd.DrawSphere(proj * view * transform, Color(1, 0, 0, 1.0f), 1.5f, true);
|
||||
}
|
||||
|
||||
auto capsuleColliderView = scene->m_Registry.view<TransformComponent, CapsuleColliderComponent>();
|
||||
for (auto e : capsuleColliderView)
|
||||
{
|
||||
auto [transformComponent, capsuleCollider] = scene->m_Registry.get<TransformComponent, CapsuleColliderComponent>(e);
|
||||
|
||||
Matrix4 transform = Matrix4(1.0f);
|
||||
transform = glm::translate(transform, Vector3(transformComponent.GetGlobalTransform()[3]));
|
||||
transform = glm::scale(transform, Vector3(capsuleCollider.Radius, capsuleCollider.Height, capsuleCollider.Radius));
|
||||
lineCmd.DrawCapsule(proj * view * transform, Color(1, 0, 0, 1.0f), 1.5f, true);
|
||||
}
|
||||
|
||||
auto cylinderColliderView = scene->m_Registry.view<TransformComponent, CylinderColliderComponent>();
|
||||
for (auto e : cylinderColliderView)
|
||||
{
|
||||
auto [transformComponent, cylinderCollider] = scene->m_Registry.get<TransformComponent, CylinderColliderComponent>(e);
|
||||
|
||||
Matrix4 transform = Matrix4(1.0f);
|
||||
transform = glm::translate(transform, Vector3(transformComponent.GetGlobalTransform()[3]));
|
||||
transform = glm::scale(transform, Vector3(cylinderCollider.Radius, cylinderCollider.Height, cylinderCollider.Radius));
|
||||
lineCmd.DrawCylinder(proj * view * transform, Color(1, 0, 0, 1.0f), 1.5f, true);
|
||||
}
|
||||
|
||||
lineCmd.DrawBox(proj * view * transform, { 0, 1, 0, 1 }, 1.5f, true);
|
||||
//lineCmd.DrawArrow({3, 3, 0}, {7, 3, 0}, proj, view, Color(1, 0, 0, 1), 3.0f);
|
||||
}
|
||||
|
||||
void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd)
|
||||
@@ -319,3 +388,203 @@ void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd)
|
||||
DrawIconGizmo<RigidBodyComponent>(debugCmd, "Resources/Gizmos/rigidbody.png");
|
||||
DrawIconGizmo<ParticleEmitterComponent>(debugCmd, "Resources/Gizmos/particles.png");
|
||||
}
|
||||
|
||||
|
||||
void ViewportWidget::DrawOverlay()
|
||||
{
|
||||
if (Engine::GetGameState() == GameState::Playing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
const float DISTANCE = 10.0f;
|
||||
int corner = 0;
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
|
||||
|
||||
window_flags |= ImGuiWindowFlags_NoMove;
|
||||
ImGuiViewport* viewport = ImGui::GetWindowViewport();
|
||||
float title_bar_height = ImGui::GetFontSize() + ImGui::GetStyle().FramePadding.y * 2;
|
||||
ImVec2 work_area_pos = ImGui::GetCurrentWindow()->Pos + ImVec2(0, title_bar_height); // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any!
|
||||
ImVec2 work_area_size = ImGui::GetCurrentWindow()->Size;
|
||||
ImVec2 window_pos = ImVec2((corner & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE));
|
||||
ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 32.0f);
|
||||
|
||||
bool showOverlay = true;
|
||||
if (ImGui::Begin("ActionBar", &showOverlay, window_flags))
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 2));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 100);
|
||||
|
||||
bool selectedMode = CurrentOperation == ImGuizmo::OPERATION::TRANSLATE;
|
||||
if (selectedMode)
|
||||
{
|
||||
Color color = Engine::GetProject()->Settings.PrimaryColor;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
|
||||
}
|
||||
|
||||
if (ImGui::Button(ICON_FA_ARROWS_ALT, ImVec2(30, 28)) || (ImGui::Shortcut(ImGuiKey_W, 0, ImGuiInputFlags_RouteGlobalLow) && !ImGui::IsAnyItemActive() && !IsControllingCamera))
|
||||
{
|
||||
CurrentOperation = ImGuizmo::OPERATION::TRANSLATE;
|
||||
}
|
||||
|
||||
|
||||
UI::Tooltip("Translate");
|
||||
if (selectedMode)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
selectedMode = CurrentOperation == ImGuizmo::OPERATION::ROTATE;
|
||||
if (selectedMode)
|
||||
{
|
||||
Color color = Engine::GetProject()->Settings.PrimaryColor;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
|
||||
}
|
||||
|
||||
if (ImGui::Button(ICON_FA_SYNC_ALT, ImVec2(30, 28)) || (ImGui::Shortcut(ImGuiKey_E, 0, ImGuiInputFlags_RouteGlobalLow) && !ImGui::IsAnyItemActive() && !IsControllingCamera))
|
||||
{
|
||||
CurrentOperation = ImGuizmo::OPERATION::ROTATE;
|
||||
}
|
||||
|
||||
UI::Tooltip("Rotate");
|
||||
|
||||
if (selectedMode)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
selectedMode = CurrentOperation == ImGuizmo::OPERATION::SCALE;
|
||||
if (selectedMode)
|
||||
{
|
||||
Color color = Engine::GetProject()->Settings.PrimaryColor;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
|
||||
}
|
||||
|
||||
if (ImGui::Button(ICON_FA_EXPAND_ALT, ImVec2(30, 28)) || (ImGui::Shortcut(ImGuiKey_R, 0, ImGuiInputFlags_RouteGlobalLow) && !ImGui::IsAnyItemActive() && !IsControllingCamera))
|
||||
{
|
||||
CurrentOperation = ImGuizmo::OPERATION::SCALE;
|
||||
}
|
||||
|
||||
UI::Tooltip("Scale");
|
||||
|
||||
if (selectedMode)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
selectedMode = CurrentMode == ImGuizmo::MODE::WORLD;
|
||||
if (selectedMode)
|
||||
{
|
||||
Color color = Engine::GetProject()->Settings.PrimaryColor;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
|
||||
}
|
||||
|
||||
if (ImGui::Button(ICON_FA_GLOBE, ImVec2(30, 28)))
|
||||
{
|
||||
CurrentMode = ImGuizmo::MODE::WORLD;
|
||||
}
|
||||
|
||||
UI::Tooltip("Global Transformation");
|
||||
|
||||
if (selectedMode)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
selectedMode = CurrentMode == ImGuizmo::MODE::LOCAL;
|
||||
if (selectedMode)
|
||||
{
|
||||
Color color = Engine::GetProject()->Settings.PrimaryColor;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { color.r, color.g, color.b, 1.0f });
|
||||
}
|
||||
|
||||
if (ImGui::Button(ICON_FA_CUBE, ImVec2(30, 28)))
|
||||
{
|
||||
CurrentMode = ImGuizmo::MODE::LOCAL;
|
||||
}
|
||||
|
||||
UI::Tooltip("Local Transformation");
|
||||
|
||||
if (selectedMode)
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(75);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 6, 6 });
|
||||
ImGui::DragFloat("##snapping", &CurrentSnapping.x, 0.01f, 0.0f, 100.0f);
|
||||
CurrentSnapping = { CurrentSnapping.x, CurrentSnapping.x, CurrentSnapping.x };
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
UI::Tooltip("Snapping");
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::End();
|
||||
|
||||
corner = 1;
|
||||
window_flags |= ImGuiWindowFlags_NoMove;
|
||||
viewport = ImGui::GetWindowViewport();
|
||||
work_area_pos = ImGui::GetCurrentWindow()->Pos; // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any!
|
||||
work_area_size = ImGui::GetCurrentWindow()->Size;
|
||||
window_pos = ImVec2((corner & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE));
|
||||
window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
|
||||
int corner2 = 1;
|
||||
work_area_pos = ImGui::GetCurrentWindow()->Pos; // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any!
|
||||
work_area_size = ImGui::GetCurrentWindow()->Size;
|
||||
window_pos = ImVec2((corner2 & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner2 & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE));
|
||||
window_pos_pivot = ImVec2((corner2 & 1) ? 1.0f : 0.0f, (corner2 & 2) ? 1.0f : 0.0f);
|
||||
ImGui::SetNextWindowPos(window_pos + ImVec2(0, 40), ImGuiCond_Always, window_pos_pivot);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 32.0f);
|
||||
ImGui::SetNextWindowSize(ImVec2(16, ImGui::GetContentRegionAvail().y - DISTANCE * 2.0 - 40.0));
|
||||
if (IsControllingCamera)
|
||||
{
|
||||
if (ImGui::Begin("Controls", &showOverlay, window_flags))
|
||||
{
|
||||
const auto& editorCam = Engine::GetCurrentScene()->m_EditorCamera;
|
||||
const float camSpeed = editorCam->Speed;
|
||||
|
||||
const float maxSpeed = 50.0f;
|
||||
const float minSpeed = 0.05f;
|
||||
const float normalizedSpeed = glm::clamp((camSpeed / maxSpeed), 0.0f, 1.0f);
|
||||
|
||||
ImVec2 start = ImGui::GetWindowPos() - ImVec2(0.0, 4.0);
|
||||
ImVec2 end = start + ImGui::GetWindowSize() - ImVec2(0, 16.0);
|
||||
ImVec2 startOffset = ImVec2(start.x, end.y - (normalizedSpeed * (ImGui::GetWindowHeight() - 20.0)));
|
||||
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(startOffset + ImVec2(0, 10.0), end + ImVec2(0.0, 20.0), IM_COL32(255, 255, 255, 180), 8.0f, ImDrawFlags_RoundCornersAll);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 100);
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
@@ -22,7 +22,7 @@ private:
|
||||
ImGuizmo::MODE CurrentMode = ImGuizmo::WORLD;
|
||||
bool UseSnapping = true;
|
||||
Nuake::Vector3 CurrentSnapping = { 0.05f, 0.05f, 0.05f };
|
||||
|
||||
bool IsControllingCamera = false;
|
||||
bool isHoveringViewport;
|
||||
public:
|
||||
ViewportWidget(EditorContext& context);
|
||||
@@ -35,4 +35,7 @@ public:
|
||||
|
||||
void OnLineDraw(Nuake::DebugLineCmd& lineCmd);
|
||||
void OnDebugDraw(Nuake::DebugCmd& debugCmd);
|
||||
|
||||
private:
|
||||
void DrawOverlay();
|
||||
};
|
||||
@@ -41,6 +41,8 @@ void DebugCmd::DrawTexturedQuad(const Matrix4& transform, Ref<VulkanImage> textu
|
||||
cmd.DrawIndexed(6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DebugLineCmd::DebugLineCmd(Cmd& inCmd, PassRenderContext& inCtx) :
|
||||
cmd(inCmd), ctx(inCtx), lineConstant({})
|
||||
{
|
||||
@@ -69,3 +71,147 @@ void DebugLineCmd::DrawLine(const Matrix4& transform, const Color& inColor, floa
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
}
|
||||
|
||||
void DebugLineCmd::DrawBox(const Matrix4& transform, const Color& inColor, float lineWidth, bool stippled)
|
||||
{
|
||||
cmd.SetPolygonMode(VK_POLYGON_MODE_LINE);
|
||||
cmd.SetLineRasterizationMode(VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH);
|
||||
cmd.SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
|
||||
|
||||
cmd.SetLineStippleEnabled(stippled);
|
||||
if (stippled)
|
||||
{
|
||||
cmd.SetLineStipple(2, 0b1111111100000000);
|
||||
}
|
||||
|
||||
cmd.SetLineWidth(lineWidth);
|
||||
|
||||
lineConstant.LineColor = inColor;
|
||||
lineConstant.Transform = transform;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(LineConstant), &lineConstant);
|
||||
|
||||
auto& boxMesh = VkSceneRenderer::BoxMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, boxMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(boxMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(24);
|
||||
}
|
||||
|
||||
void DebugLineCmd::DrawCapsule(const Matrix4& transform, const Color& inColor, float lineWidth, bool stippled)
|
||||
{
|
||||
cmd.SetPolygonMode(VK_POLYGON_MODE_LINE);
|
||||
cmd.SetLineRasterizationMode(VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH);
|
||||
cmd.SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
|
||||
|
||||
cmd.SetLineStippleEnabled(stippled);
|
||||
if (stippled)
|
||||
{
|
||||
cmd.SetLineStipple(2, 0b1111111100000000);
|
||||
}
|
||||
|
||||
cmd.SetLineWidth(lineWidth);
|
||||
|
||||
lineConstant.LineColor = inColor;
|
||||
lineConstant.Transform = transform;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(LineConstant), &lineConstant);
|
||||
|
||||
auto& capsuleMesh = VkSceneRenderer::CapsuleMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, capsuleMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(capsuleMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(capsuleMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void DebugLineCmd::DrawSphere(const Matrix4& transform, const Color& inColor, float lineWidth, bool stippled)
|
||||
{
|
||||
cmd.SetPolygonMode(VK_POLYGON_MODE_LINE);
|
||||
cmd.SetLineRasterizationMode(VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH);
|
||||
cmd.SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
|
||||
|
||||
cmd.SetLineStippleEnabled(stippled);
|
||||
if (stippled)
|
||||
{
|
||||
cmd.SetLineStipple(2, 0b1111111100000000);
|
||||
}
|
||||
|
||||
cmd.SetLineWidth(lineWidth);
|
||||
|
||||
lineConstant.LineColor = inColor;
|
||||
lineConstant.Transform = transform;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(LineConstant), &lineConstant);
|
||||
|
||||
auto& sphereMesh = VkSceneRenderer::SphereMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, sphereMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(sphereMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(sphereMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void DebugLineCmd::DrawCylinder(const Matrix4& transform, const Color& inColor, float lineWidth, bool stippled)
|
||||
{
|
||||
cmd.SetPolygonMode(VK_POLYGON_MODE_LINE);
|
||||
cmd.SetLineRasterizationMode(VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH);
|
||||
cmd.SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
|
||||
|
||||
cmd.SetLineStippleEnabled(stippled);
|
||||
if (stippled)
|
||||
{
|
||||
cmd.SetLineStipple(2, 0b1111111100000000);
|
||||
}
|
||||
|
||||
cmd.SetLineWidth(lineWidth);
|
||||
|
||||
lineConstant.LineColor = inColor;
|
||||
lineConstant.Transform = transform;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(LineConstant), &lineConstant);
|
||||
|
||||
auto& sphereMesh = VkSceneRenderer::CylinderMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, sphereMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(sphereMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(sphereMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void DebugLineCmd::DrawArrow(const Vector3& from, const Vector3& to, const Matrix4& view, const Matrix4& proj, const Color& inColor, float lineWidth, bool stippled)
|
||||
{
|
||||
cmd.SetPolygonMode(VK_POLYGON_MODE_LINE);
|
||||
cmd.SetLineRasterizationMode(VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH);
|
||||
cmd.SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
|
||||
|
||||
cmd.SetLineStippleEnabled(stippled);
|
||||
if (stippled)
|
||||
{
|
||||
cmd.SetLineStipple(2, 0b1111111100000000);
|
||||
}
|
||||
|
||||
cmd.SetLineWidth(lineWidth);
|
||||
|
||||
// Shaft direction (normalized)
|
||||
glm::vec3 dir = glm::normalize(to - from);
|
||||
|
||||
// Get camera position from inverse of view
|
||||
glm::vec3 cameraPos = glm::vec3(glm::inverse(view)[3]);
|
||||
glm::vec3 toCamera = glm::normalize(cameraPos - to);
|
||||
|
||||
// Billboard basis
|
||||
glm::vec3 right = glm::normalize(glm::cross(dir, toCamera));
|
||||
glm::vec3 up = glm::normalize(glm::cross(right, dir));
|
||||
|
||||
//// Build arrowhead transform
|
||||
//glm::mat4 arrowTransform(1.0f);
|
||||
//arrowTransform[0] = glm::vec4(right, 0.0f); // X axis
|
||||
//arrowTransform[1] = glm::vec4(up, 0.0f); // Y axis
|
||||
//arrowTransform[2] = glm::vec4(dir, 0.0f); // Z axis (forward)
|
||||
//arrowTransform[3] = glm::vec4(to, 1.0f); // Position
|
||||
|
||||
// Optional: scale arrowhead size
|
||||
//float arrowScale = 0.2f; // You can tweak this
|
||||
//arrowTransform = arrowTransform * glm::scale(glm::mat4(1.0f), glm::vec3(arrowScale));
|
||||
|
||||
// Final matrix
|
||||
lineConstant.Transform = proj * view;
|
||||
|
||||
lineConstant.LineColor = inColor;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(LineConstant), &lineConstant);
|
||||
|
||||
auto& sphereMesh = VkSceneRenderer::ArrowMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, sphereMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(sphereMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(sphereMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t));
|
||||
}
|
||||
@@ -33,6 +33,13 @@ namespace Nuake
|
||||
void DrawAABB(const Vector3& min, const Vector3& max, const Color& color) const;
|
||||
};
|
||||
|
||||
struct DrawLineRequest
|
||||
{
|
||||
Vector3 Start;
|
||||
Vector3 End;
|
||||
Color Color;
|
||||
};
|
||||
|
||||
class DebugLineCmd
|
||||
{
|
||||
private:
|
||||
@@ -47,5 +54,10 @@ namespace Nuake
|
||||
Ref<Scene> GetScene() const;
|
||||
|
||||
void DrawLine(const Matrix4& transform, const Color& color, float lineWidth = 1.0f);
|
||||
void DrawBox(const Matrix4& transform, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
void DrawCapsule(const Matrix4& transform, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
void DrawSphere(const Matrix4& transform, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
void DrawCylinder(const Matrix4& transform, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
void DrawArrow(const Vector3& from, const Vector3& to, const Matrix4& view, const Matrix4& proj, const Color& color, float lineWidth = 1.0f, bool stippled = false);
|
||||
};
|
||||
}
|
||||
@@ -158,23 +158,17 @@ SceneRenderPipeline::SceneRenderPipeline()
|
||||
vkUpdateDescriptorSets(VkRenderer::Get().GetDevice(), 1, &bufferWriteModel, 0, nullptr);
|
||||
|
||||
// Generate noise texture
|
||||
struct Vector2H
|
||||
{
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
};
|
||||
|
||||
std::vector<Vector2H> noiseData;
|
||||
std::vector<Vector2> noiseData;
|
||||
for (unsigned int i = 0; i < 16; i++)
|
||||
{
|
||||
Vector2H noise(
|
||||
glm::packHalf1x16(randomFloats(generator) * 2.0 - 1.0),
|
||||
glm::packHalf1x16(randomFloats(generator) * 2.0 - 1.0 )
|
||||
Vector2 noise(
|
||||
randomFloats(generator),
|
||||
randomFloats(generator)
|
||||
);
|
||||
noiseData.push_back(noise);
|
||||
}
|
||||
|
||||
ssaoNoiseTexture = CreateRef<VulkanImage>(noiseData.data(), ImageFormat::RG16F, Vector2{4, 4});
|
||||
ssaoNoiseTexture = CreateRef<VulkanImage>(noiseData.data(), ImageFormat::RG32F, Vector2{4, 4});
|
||||
resources.AddTexture(ssaoNoiseTexture);
|
||||
|
||||
initKernels = true;
|
||||
@@ -215,6 +209,9 @@ SceneRenderPipeline::SceneRenderPipeline()
|
||||
SSAOOutput = CreateRef<VulkanImage>(ImageFormat::RGBA8, defaultSize);
|
||||
SSAOOutput->SetDebugName("SSAOOutput");
|
||||
|
||||
SSAOBlurOutput = CreateRef<VulkanImage>(ImageFormat::RGBA8, defaultSize);
|
||||
SSAOBlurOutput->SetDebugName("SSAOBlurOutput");
|
||||
|
||||
GizmoOutput = CreateRef<VulkanImage>(ImageFormat::RGBA8, defaultSize);
|
||||
GizmoOutput->SetDebugName("GizmoOutput");
|
||||
|
||||
@@ -252,6 +249,7 @@ void SceneRenderPipeline::Render(PassRenderContext& ctx)
|
||||
LineCombineOutput = ResizeImage(ctx, LineCombineOutput, ctx.resolution);
|
||||
|
||||
SSAOOutput = ResizeImage(ctx, SSAOOutput, ctx.resolution);
|
||||
SSAOBlurOutput = ResizeImage(ctx, SSAOBlurOutput, ctx.resolution);
|
||||
|
||||
OutlineOutput = ResizeImage(ctx, OutlineOutput, ctx.resolution);
|
||||
|
||||
@@ -262,9 +260,10 @@ void SceneRenderPipeline::Render(PassRenderContext& ctx)
|
||||
{
|
||||
{ GBufferAlbedo, GBufferDepth, GBufferNormal, GBufferMaterial, GBufferEntityID }, // GBuffer
|
||||
{ SSAOOutput },
|
||||
{ SSAOBlurOutput },
|
||||
{ ShadingOutput }, // Shading
|
||||
{ TonemappedOutput }, // Tonemap
|
||||
{ LineOutput },
|
||||
{ LineOutput, GBufferDepth },
|
||||
{ LineCombineOutput },
|
||||
{ GizmoOutput, GBufferDepth }, // Reusing depth from gBuffer
|
||||
{ GizmoCombineOutput },
|
||||
@@ -287,7 +286,8 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
gBufferPass.AddAttachment("EntityID", GBufferEntityID->GetFormat());
|
||||
gBufferPass.AddAttachment("Depth", GBufferDepth->GetFormat(), ImageUsage::Depth);
|
||||
gBufferPass.SetPushConstant<GBufferConstant>(gbufferConstant);
|
||||
gBufferPass.SetPreRender([&](PassRenderContext& ctx) {
|
||||
gBufferPass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
|
||||
@@ -298,8 +298,9 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
gBufferPass.SetRender([&](PassRenderContext& ctx) {
|
||||
});
|
||||
gBufferPass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
|
||||
Ref<Scene> scene = ctx.scene;
|
||||
@@ -334,7 +335,7 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
cmd.DrawIndexed(vkMesh->GetIndexBuffer()->GetSize() / sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
auto& ssaoPass = GBufferPipeline.AddPass("SSAOPass");
|
||||
ssaoPass.SetShaders(shaderMgr.GetShader("ssao_vert"), shaderMgr.GetShader("ssao_frag"));
|
||||
@@ -343,41 +344,111 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
ssaoPass.AddInput("Depth");
|
||||
ssaoPass.AddInput("Normal");
|
||||
ssaoPass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
|
||||
// Bind noise kernel
|
||||
cmd.BindDescriptorSet(layout, res.SSAOKernelDescriptor, 7);
|
||||
// Bind noise kernel
|
||||
cmd.BindDescriptorSet(layout, res.SSAOKernelDescriptor, 7);
|
||||
|
||||
// Use noise texture
|
||||
ssaoConstant.noiseTextureID = res.GetBindlessTextureID(ssaoNoiseTexture->GetID());
|
||||
ssaoConstant.normalTextureID = res.GetBindlessTextureID(GBufferNormal->GetID());
|
||||
ssaoConstant.depthTextureID = res.GetBindlessTextureID(GBufferDepth->GetID());
|
||||
ssaoConstant.camViewID = ctx.cameraID;
|
||||
ssaoConstant.radius = ctx.scene->GetEnvironment()->mSSAO->Radius;
|
||||
ssaoConstant.bias = ctx.scene->GetEnvironment()->mSSAO->Bias;
|
||||
ssaoConstant.noiseScale = ctx.resolution / 4.0f;
|
||||
ssaoConstant.power = ctx.scene->GetEnvironment()->mSSAO->Strength;
|
||||
// Use noise texture
|
||||
ssaoConstant.noiseTextureID = res.GetBindlessTextureID(ssaoNoiseTexture->GetID());
|
||||
ssaoConstant.normalTextureID = res.GetBindlessTextureID(GBufferNormal->GetID());
|
||||
ssaoConstant.depthTextureID = res.GetBindlessTextureID(GBufferDepth->GetID());
|
||||
ssaoConstant.camViewID = ctx.cameraID;
|
||||
ssaoConstant.radius = ctx.scene->GetEnvironment()->mSSAO->Radius;
|
||||
ssaoConstant.bias = ctx.scene->GetEnvironment()->mSSAO->Bias;
|
||||
ssaoConstant.noiseScale = ctx.resolution / 4.0f;
|
||||
ssaoConstant.power = ctx.scene->GetEnvironment()->mSSAO->Strength;
|
||||
|
||||
cmd.PushConstants(layout, sizeof(SSAOConstant), &ssaoConstant);
|
||||
});
|
||||
cmd.PushConstants(layout, sizeof(SSAOConstant), &ssaoConstant);
|
||||
});
|
||||
ssaoPass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
|
||||
auto& ssaoBlurPass = GBufferPipeline.AddPass("SSAOBlurPass");
|
||||
ssaoBlurPass.SetShaders(shaderMgr.GetShader("blur_vert"), shaderMgr.GetShader("blur_frag"));
|
||||
ssaoBlurPass.SetPushConstant<BlurConstant>(blurConstant);
|
||||
ssaoBlurPass.AddAttachment("SSAOBlurOutput", SSAOBlurOutput->GetFormat());
|
||||
ssaoBlurPass.AddInput("Input");
|
||||
ssaoBlurPass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
|
||||
blurConstant.sourceTextureID = res.GetBindlessTextureID(SSAOOutput->GetID());
|
||||
blurConstant.sourceSize = SSAOOutput->GetSize();
|
||||
|
||||
cmd.PushConstants(layout, sizeof(BlurConstant), &blurConstant);
|
||||
});
|
||||
ssaoBlurPass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
|
||||
//auto& skyPass = GBufferPipeline.AddPass("SkyPass");
|
||||
//skyPass.SetShaders(shaderMgr.GetShader("sky_vert"), shaderMgr.GetShader("sky_frag"));
|
||||
//skyPass.SetPushConstant<SkyConstant>(skyConstant);
|
||||
//skyPass.AddAttachment("SkyOutput", ShadingOutput->GetFormat());
|
||||
//skyPass.SetDepthTest(false);
|
||||
//skyPass.SetPreRender([&](PassRenderContext& ctx)
|
||||
//{
|
||||
// Cmd& cmd = ctx.commandBuffer;
|
||||
// auto& layout = ctx.renderPass->PipelineLayout;
|
||||
// auto& res = GPUResources::Get();
|
||||
// cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
// cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
// cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
// cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
// cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
// cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
//
|
||||
// skyConstant.cameraID = ctx.cameraID;
|
||||
// auto camera = res.GetCamera(ctx.cameraID);
|
||||
//
|
||||
//
|
||||
//
|
||||
// skyConstant.ambientColor = ctx.scene->GetEnvironment()->AmbientColor;
|
||||
// skyConstant.ambientTerm = ctx.scene->GetEnvironment()->AmbientTerm;
|
||||
//
|
||||
// cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(SkyConstant), &skyConstant);
|
||||
//});
|
||||
//skyPass.SetRender([&](PassRenderContext& ctx)
|
||||
// {
|
||||
// Cmd& cmd = ctx.commandBuffer;
|
||||
// auto& layout = ctx.renderPass->PipelineLayout;
|
||||
// auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
// cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
// cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
// cmd.DrawIndexed(6);
|
||||
// });
|
||||
// skyPass.SetShaders("shaderMgr")
|
||||
|
||||
auto& shadingPass = GBufferPipeline.AddPass("Shading");
|
||||
shadingPass.SetShaders(shaderMgr.GetShader("shading_vert"), shaderMgr.GetShader("shading_frag"));
|
||||
@@ -388,7 +459,8 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
shadingPass.AddInput("Normal");
|
||||
shadingPass.AddInput("Depth");
|
||||
shadingPass.AddInput("Material");
|
||||
shadingPass.SetPreRender([&](PassRenderContext& ctx) {
|
||||
shadingPass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
@@ -407,7 +479,7 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
shadingConstant.NormalTextureID = res.GetBindlessTextureID(GBufferNormal->GetID());
|
||||
shadingConstant.MaterialTextureID = res.GetBindlessTextureID(GBufferMaterial->GetID());
|
||||
shadingConstant.AmbientTerm = ctx.scene->GetEnvironment()->AmbientTerm;
|
||||
shadingConstant.SSAOTextureID = res.GetBindlessTextureID(SSAOOutput->GetID());
|
||||
shadingConstant.SSAOTextureID = res.GetBindlessTextureID(SSAOBlurOutput->GetID());
|
||||
|
||||
// Camera
|
||||
shadingConstant.CameraID = ctx.cameraID;
|
||||
@@ -418,8 +490,9 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
{
|
||||
shadingConstant.CascadeSplits[i] = LightComponent::mCascadeSplitDepth[i];
|
||||
}
|
||||
});
|
||||
shadingPass.SetRender([&](PassRenderContext& ctx) {
|
||||
});
|
||||
shadingPass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(ShadingConstant), &shadingConstant);
|
||||
|
||||
@@ -430,7 +503,7 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
});
|
||||
|
||||
auto& tonemapPass = GBufferPipeline.AddPass("Tonemap");
|
||||
tonemapPass.SetShaders(shaderMgr.GetShader("tonemap_vert"), shaderMgr.GetShader("tonemap_frag"));
|
||||
@@ -438,7 +511,8 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
tonemapPass.AddAttachment("TonemapOutput", TonemappedOutput->GetFormat());
|
||||
tonemapPass.SetDepthTest(false);
|
||||
tonemapPass.AddInput("ShadingOutput");
|
||||
tonemapPass.SetPreRender([&](PassRenderContext& ctx) {
|
||||
tonemapPass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
@@ -455,49 +529,48 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
tonemapConstant.Exposure = ctx.scene->GetEnvironment()->Exposure;
|
||||
tonemapConstant.SourceTextureID = res.GetBindlessTextureID(ShadingOutput->GetID());
|
||||
tonemapConstant.Gamma = ctx.scene->GetEnvironment()->Gamma;
|
||||
});
|
||||
});
|
||||
tonemapPass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(TonemapConstant), &tonemapConstant);
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(TonemapConstant), &tonemapConstant);
|
||||
|
||||
ctx.renderPass->SetClearColor(ctx.scene->GetEnvironment()->AmbientColor);
|
||||
ctx.renderPass->SetClearColor(ctx.scene->GetEnvironment()->AmbientColor);
|
||||
|
||||
// Draw full screen quad
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
|
||||
RenderPass& linePass = GBufferPipeline.AddPass("Line");
|
||||
linePass.SetIsLinePass(true);
|
||||
linePass.SetTopology(PolygonTopology::LINE_LIST);
|
||||
linePass.SetShaders(shaderMgr.GetShader("line_vert"), shaderMgr.GetShader("line_frag"));
|
||||
linePass.AddAttachment("LineOutput", LineOutput->GetFormat());
|
||||
linePass.AddAttachment("LineDepth", GBufferDepth->GetFormat(), ImageUsage::Depth, false);
|
||||
linePass.SetPushConstant(lineConstant);
|
||||
linePass.SetDepthTest(false);
|
||||
linePass.SetDepthTest(true);
|
||||
linePass.SetIsLinePass(true);
|
||||
linePass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
|
||||
// Bindless
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
linePass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
DebugLineCmd debugCmd = DebugLineCmd(cmd, ctx);
|
||||
OnLineDraw().Broadcast(debugCmd);
|
||||
});
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
DebugLineCmd debugCmd = DebugLineCmd(cmd, ctx);
|
||||
OnLineDraw().Broadcast(debugCmd);
|
||||
});
|
||||
|
||||
auto& lineCombinePass = GBufferPipeline.AddPass("LineCombine");
|
||||
lineCombinePass.SetPushConstant(copyConstant);
|
||||
@@ -505,33 +578,31 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
lineCombinePass.AddAttachment("LineCombineOutput", LineCombineOutput->GetFormat());
|
||||
lineCombinePass.AddInput("lineCombinePassOutput");
|
||||
lineCombinePass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
|
||||
// Bindless
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
lineCombinePass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
|
||||
copyConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(LineOutput->GetID());
|
||||
copyConstant.Source2TextureID = GPUResources::Get().GetBindlessTextureID(TonemappedOutput->GetID());
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(copyConstant), ©Constant);
|
||||
copyConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(LineOutput->GetID());
|
||||
copyConstant.Source2TextureID = GPUResources::Get().GetBindlessTextureID(TonemappedOutput->GetID());
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(copyConstant), ©Constant);
|
||||
|
||||
// Draw full screen quad
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
|
||||
auto& gizmoPass = GBufferPipeline.AddPass("Gizmo");
|
||||
gizmoPass.SetShaders(shaderMgr.GetShader("gizmo_vert"), shaderMgr.GetShader("gizmo_frag"));
|
||||
@@ -541,25 +612,24 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
gizmoPass.AddAttachment("GizmoDepth", GBufferDepth->GetFormat(), ImageUsage::Depth, false);
|
||||
gizmoPass.SetDepthTest(true);
|
||||
gizmoPass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
|
||||
// Bindless
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
gizmoPass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
DebugCmd debugCmd = DebugCmd(cmd, ctx);
|
||||
OnDebugDraw().Broadcast(debugCmd);
|
||||
});
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
DebugCmd debugCmd = DebugCmd(cmd, ctx);
|
||||
OnDebugDraw().Broadcast(debugCmd);
|
||||
});
|
||||
|
||||
auto& gizmoCombinePass = GBufferPipeline.AddPass("GizmoCombine");
|
||||
gizmoCombinePass.SetPushConstant(copyConstant);
|
||||
@@ -567,33 +637,31 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
gizmoCombinePass.AddAttachment("GizmoCombineOutput", GizmoCombineOutput->GetFormat());
|
||||
gizmoCombinePass.AddInput("GizmoCombineOutput");
|
||||
gizmoCombinePass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
|
||||
// Bindless
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
cmd.BindDescriptorSet(layout, res.ModelDescriptor, 0);
|
||||
cmd.BindDescriptorSet(layout, res.SamplerDescriptor, 2);
|
||||
cmd.BindDescriptorSet(layout, res.MaterialDescriptor, 3);
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
gizmoCombinePass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
{
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
|
||||
copyConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(GizmoOutput->GetID());
|
||||
copyConstant.Source2TextureID = GPUResources::Get().GetBindlessTextureID(LineCombineOutput->GetID());
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(copyConstant), ©Constant);
|
||||
copyConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(GizmoOutput->GetID());
|
||||
copyConstant.Source2TextureID = GPUResources::Get().GetBindlessTextureID(LineCombineOutput->GetID());
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(copyConstant), ©Constant);
|
||||
|
||||
// Draw full screen quad
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
|
||||
auto& outlinePass = GBufferPipeline.AddPass("Outline");
|
||||
outlinePass.SetShaders(shaderMgr.GetShader("outline_vert"), shaderMgr.GetShader("outline_frag"));
|
||||
@@ -602,7 +670,8 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
outlinePass.SetDepthTest(false);
|
||||
outlinePass.AddInput("ShadingOutput");
|
||||
outlinePass.AddInput("EntityID");
|
||||
outlinePass.SetPreRender([&](PassRenderContext& ctx) {
|
||||
outlinePass.SetPreRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
Cmd& cmd = ctx.commandBuffer;
|
||||
auto& layout = ctx.renderPass->PipelineLayout;
|
||||
auto& res = GPUResources::Get();
|
||||
@@ -614,25 +683,25 @@ void SceneRenderPipeline::RecreatePipeline()
|
||||
cmd.BindDescriptorSet(layout, res.TexturesDescriptor, 4);
|
||||
cmd.BindDescriptorSet(layout, res.LightsDescriptor, 5);
|
||||
cmd.BindDescriptorSet(layout, res.CamerasDescriptor, 6);
|
||||
});
|
||||
});
|
||||
outlinePass.SetRender([&](PassRenderContext& ctx)
|
||||
{
|
||||
outlineConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(ShadingOutput->GetID());
|
||||
outlineConstant.EntityIDTextureID = GPUResources::Get().GetBindlessTextureID(GBufferEntityID->GetID());
|
||||
outlineConstant.DepthTextureID = GPUResources::Get().GetBindlessTextureID(GBufferDepth->GetID());
|
||||
outlineConstant.SelectedEntityID = ctx.selectedEntity;
|
||||
outlineConstant.Color = Vector4(1, 0, 0, 1);
|
||||
outlineConstant.Thickness = 4.0f;
|
||||
{
|
||||
outlineConstant.SourceTextureID = GPUResources::Get().GetBindlessTextureID(ShadingOutput->GetID());
|
||||
outlineConstant.EntityIDTextureID = GPUResources::Get().GetBindlessTextureID(GBufferEntityID->GetID());
|
||||
outlineConstant.DepthTextureID = GPUResources::Get().GetBindlessTextureID(GBufferDepth->GetID());
|
||||
outlineConstant.SelectedEntityID = ctx.selectedEntity;
|
||||
outlineConstant.Color = Vector4(1, 0, 0, 1);
|
||||
outlineConstant.Thickness = 4.0f;
|
||||
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(OutlineConstant), &outlineConstant);
|
||||
auto& cmd = ctx.commandBuffer;
|
||||
cmd.PushConstants(ctx.renderPass->PipelineLayout, sizeof(OutlineConstant), &outlineConstant);
|
||||
|
||||
// Draw full screen quad
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
// Draw full screen quad
|
||||
auto& quadMesh = VkSceneRenderer::QuadMesh;
|
||||
cmd.BindDescriptorSet(ctx.renderPass->PipelineLayout, quadMesh->GetDescriptorSet(), 1);
|
||||
cmd.BindIndexBuffer(quadMesh->GetIndexBuffer()->GetBuffer());
|
||||
cmd.DrawIndexed(6);
|
||||
});
|
||||
|
||||
GBufferPipeline.Build();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,28 @@ namespace Nuake
|
||||
float bias;
|
||||
Vector2 noiseScale;
|
||||
float power;
|
||||
};
|
||||
|
||||
struct SkyConstant
|
||||
{
|
||||
int cameraID;
|
||||
float surfaceRadius;
|
||||
float atmosphereRadius;
|
||||
Vector3 RayleighScattering;
|
||||
Vector3 MieScattering;
|
||||
float SunIntensity;
|
||||
Vector3 CenterPoint;
|
||||
Vector3 SunDirection;
|
||||
Vector3 CamDirection;
|
||||
Vector3 CamUp;
|
||||
Vector3 CamRight;
|
||||
float Exposure;
|
||||
};
|
||||
|
||||
struct BlurConstant
|
||||
{
|
||||
int sourceTextureID;
|
||||
Vector2 sourceSize;
|
||||
};
|
||||
|
||||
struct ShadingConstant
|
||||
@@ -116,6 +137,7 @@ namespace Nuake
|
||||
// Attachments Shading
|
||||
Ref<VulkanImage> ShadingOutput;
|
||||
Ref<VulkanImage> SSAOOutput;
|
||||
Ref<VulkanImage> SSAOBlurOutput;
|
||||
|
||||
Ref<VulkanImage> LineOutput;
|
||||
Ref<VulkanImage> LineCombineOutput;
|
||||
@@ -141,6 +163,8 @@ namespace Nuake
|
||||
GBufferConstant gbufferConstant;
|
||||
ShadingConstant shadingConstant;
|
||||
SSAOConstant ssaoConstant;
|
||||
BlurConstant blurConstant;
|
||||
SkyConstant skyConstant;
|
||||
TonemapConstant tonemapConstant;
|
||||
DebugConstant debugConstant;
|
||||
LineConstant lineConstant;
|
||||
|
||||
@@ -177,6 +177,10 @@ VulkanImage::VulkanImage(void* inData, ImageFormat inFormat, Vector2 inSize) : V
|
||||
{
|
||||
data_size *= 4;
|
||||
}
|
||||
else if (inFormat == ImageFormat::RG32F)
|
||||
{
|
||||
data_size *= 8;
|
||||
}
|
||||
else if (inFormat != ImageFormat::A8)
|
||||
{
|
||||
data_size *= 4;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Nuake
|
||||
RGBA16F = 97,
|
||||
RGB16F = 90,
|
||||
RG16F = 83,
|
||||
RG32F = 103,
|
||||
RGBA32F = 109,
|
||||
D32F = 126,
|
||||
R32UINT = 98,
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
using namespace Nuake;
|
||||
|
||||
Ref<VkMesh> VkSceneRenderer::QuadMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::BoxMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::CapsuleMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::SphereMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::CylinderMesh;
|
||||
Ref<VkMesh> VkSceneRenderer::ArrowMesh;
|
||||
|
||||
void VkSceneRenderer::Init()
|
||||
{
|
||||
@@ -47,6 +52,295 @@ void VkSceneRenderer::Init()
|
||||
};
|
||||
|
||||
QuadMesh = CreateRef<VkMesh>(quadVertices, quadIndices);
|
||||
|
||||
const std::vector<Vertex> boxVertices
|
||||
{
|
||||
// Front face
|
||||
{ Vector3(-1.0f, -1.0f, 1.0f), 0.0f, Vector3(0, 0, 1), 0.0f },
|
||||
{ Vector3(1.0f, -1.0f, 1.0f), 1.0f, Vector3(0, 0, 1), 0.0f },
|
||||
{ Vector3(1.0f, 1.0f, 1.0f), 1.0f, Vector3(0, 0, 1), 1.0f },
|
||||
{ Vector3(-1.0f, 1.0f, 1.0f), 0.0f, Vector3(0, 0, 1), 1.0f },
|
||||
|
||||
// Back face
|
||||
{ Vector3(1.0f, -1.0f, -1.0f), 0.0f, Vector3(0, 0, -1), 0.0f },
|
||||
{ Vector3(-1.0f, -1.0f, -1.0f), 1.0f, Vector3(0, 0, -1), 0.0f },
|
||||
{ Vector3(-1.0f, 1.0f, -1.0f), 1.0f, Vector3(0, 0, -1), 1.0f },
|
||||
{ Vector3(1.0f, 1.0f, -1.0f), 0.0f, Vector3(0, 0, -1), 1.0f },
|
||||
|
||||
// Left face
|
||||
{ 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, 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), 0.0f, Vector3(-1, 0, 0), 1.0f },
|
||||
|
||||
// Right face
|
||||
{ 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, 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), 0.0f, Vector3(1, 0, 0), 1.0f },
|
||||
|
||||
// Top face
|
||||
{ Vector3(-1.0f, 1.0f, 1.0f), 0.0f, Vector3(0, 1, 0), 0.0f },
|
||||
{ Vector3(1.0f, 1.0f, 1.0f), 1.0f, Vector3(0, 1, 0), 0.0f },
|
||||
{ Vector3(1.0f, 1.0f, -1.0f), 1.0f, Vector3(0, 1, 0), 1.0f },
|
||||
{ Vector3(-1.0f, 1.0f, -1.0f), 0.0f, Vector3(0, 1, 0), 1.0f },
|
||||
|
||||
// Bottom face
|
||||
{ Vector3(-1.0f, -1.0f, -1.0f), 0.0f, Vector3(0, -1, 0), 0.0f },
|
||||
{ Vector3(1.0f, -1.0f, -1.0f), 1.0f, Vector3(0, -1, 0), 0.0f },
|
||||
{ Vector3(1.0f, -1.0f, 1.0f), 1.0f, Vector3(0, -1, 0), 1.0f },
|
||||
{ Vector3(-1.0f, -1.0f, 1.0f), 0.0f, Vector3(0, -1, 0), 1.0f },
|
||||
};
|
||||
|
||||
const std::vector<uint32_t> boxIndices
|
||||
{
|
||||
// Front face
|
||||
0, 1, 1, 2, 2, 3, 3, 0,
|
||||
|
||||
// Back face
|
||||
4, 5, 5, 6, 6, 7, 7, 4,
|
||||
|
||||
// Side edges
|
||||
0, 5, 1, 4, 2, 7, 3, 6
|
||||
};
|
||||
|
||||
BoxMesh = CreateRef<VkMesh>(boxVertices, boxIndices);
|
||||
|
||||
{
|
||||
std::vector<Vertex> arrowVertices;
|
||||
std::vector<uint32_t> arrowIndices;
|
||||
|
||||
Vector3 base = Vector3(0.0f, 0.0f, 0.0f); // Start of arrow
|
||||
Vector3 tip = Vector3(0.0f, 1.0f, 0.0f); // Tip of arrow
|
||||
float headSize = 0.2f;
|
||||
float shaftLength = 0.8f;
|
||||
Vector3 shaftEnd = Vector3(0.0f, shaftLength, 0.0f);
|
||||
|
||||
// Shaft line
|
||||
arrowVertices.push_back({ base, 0.0f, Vector3(), 0.0f }); // 0
|
||||
arrowVertices.push_back({ shaftEnd, 0.0f, Vector3(), 0.0f }); // 1
|
||||
arrowIndices.push_back(0);
|
||||
arrowIndices.push_back(1);
|
||||
|
||||
// Arrowhead lines (simple triangle)
|
||||
Vector3 left = shaftEnd + Vector3(-headSize, headSize, 0.0f); // 2
|
||||
Vector3 right = shaftEnd + Vector3(headSize, headSize, 0.0f); // 3
|
||||
Vector3 back = shaftEnd + Vector3(0.0f, headSize, headSize); // 4
|
||||
|
||||
arrowVertices.push_back({ left, 0.0f, Vector3(), 0.0f });
|
||||
arrowVertices.push_back({ right, 0.0f, Vector3(), 0.0f });
|
||||
arrowVertices.push_back({ back, 0.0f, Vector3(), 0.0f });
|
||||
|
||||
// Arrowhead edges
|
||||
arrowIndices.push_back(1); arrowIndices.push_back(2); // shaftEnd -> left
|
||||
arrowIndices.push_back(1); arrowIndices.push_back(3); // shaftEnd -> right
|
||||
arrowIndices.push_back(1); arrowIndices.push_back(4); // shaftEnd -> back
|
||||
|
||||
ArrowMesh = CreateRef<VkMesh>(arrowVertices, arrowIndices);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<Vertex> capsuleVertices;
|
||||
std::vector<uint32_t> capsuleIndices;
|
||||
|
||||
const int segments = 16;
|
||||
const int hemisphereSegments = 8;
|
||||
const float radius = 1.0f;
|
||||
const float cylinderHeight = 2.0f;
|
||||
const float halfHeight = cylinderHeight * 0.5f;
|
||||
|
||||
// =====
|
||||
// Circle rings (top and bottom of cylinder)
|
||||
for (int i = 0; i < segments; ++i)
|
||||
{
|
||||
float angle = (2.0f * glm::pi<float>() * i) / segments;
|
||||
float x = cos(angle) * radius;
|
||||
float z = sin(angle) * radius;
|
||||
|
||||
// Top ring
|
||||
capsuleVertices.push_back({ Vector3(x, +halfHeight, z), 0.0f, Vector3(), 0.0f });
|
||||
|
||||
// Bottom ring
|
||||
capsuleVertices.push_back({ Vector3(x, -halfHeight, z), 0.0f, Vector3(), 0.0f });
|
||||
}
|
||||
|
||||
// Top/bottom circle outline
|
||||
for (int i = 0; i < segments; ++i)
|
||||
{
|
||||
uint32_t top = i * 2;
|
||||
uint32_t topNext = ((i + 1) % segments) * 2;
|
||||
uint32_t bot = i * 2 + 1;
|
||||
uint32_t botNext = ((i + 1) % segments) * 2 + 1;
|
||||
|
||||
capsuleIndices.push_back(top);
|
||||
capsuleIndices.push_back(topNext);
|
||||
|
||||
capsuleIndices.push_back(bot);
|
||||
capsuleIndices.push_back(botNext);
|
||||
}
|
||||
|
||||
// =====
|
||||
// 4 vertical lines at 0<>, 90<39>, 180<38>, 270<37>
|
||||
for (int i : { 0, segments / 4, segments / 2, (3 * segments) / 4 })
|
||||
{
|
||||
uint32_t top = i * 2;
|
||||
uint32_t bot = i * 2 + 1;
|
||||
|
||||
capsuleIndices.push_back(top);
|
||||
capsuleIndices.push_back(bot);
|
||||
}
|
||||
|
||||
// =====
|
||||
// Hemisphere arcs (vertical arcs at 4 directions)
|
||||
for (int i : { 0, segments / 4, segments / 2, (3 * segments) / 4 })
|
||||
{
|
||||
float angle = (2.0f * glm::pi<float>() * i) / segments;
|
||||
float x = cos(angle);
|
||||
float z = sin(angle);
|
||||
|
||||
// Top hemisphere arc
|
||||
uint32_t last = capsuleVertices.size();
|
||||
for (int j = 0; j <= hemisphereSegments; ++j)
|
||||
{
|
||||
float theta = (0.5f * glm::pi<float>() * j) / hemisphereSegments; // from 0 to pi/2
|
||||
float y = sin(theta) * radius + halfHeight;
|
||||
float r = cos(theta) * radius;
|
||||
|
||||
capsuleVertices.push_back({ Vector3(x * r, y, z * r), 0.0f, Vector3(), 0.0f });
|
||||
|
||||
if (j > 0)
|
||||
{
|
||||
capsuleIndices.push_back(last + j - 1);
|
||||
capsuleIndices.push_back(last + j);
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom hemisphere arc
|
||||
last = capsuleVertices.size();
|
||||
for (int j = 0; j <= hemisphereSegments; ++j)
|
||||
{
|
||||
float theta = (0.5f * glm::pi<float>() * j) / hemisphereSegments; // from 0 to pi/2
|
||||
float y = -sin(theta) * radius - halfHeight;
|
||||
float r = cos(theta) * radius;
|
||||
|
||||
capsuleVertices.push_back({ Vector3(x * r, y, z * r), 0.0f, Vector3(), 0.0f });
|
||||
|
||||
if (j > 0)
|
||||
{
|
||||
capsuleIndices.push_back(last + j - 1);
|
||||
capsuleIndices.push_back(last + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
CapsuleMesh = CreateRef<VkMesh>(capsuleVertices, capsuleIndices);
|
||||
}
|
||||
{
|
||||
std::vector<Vertex> sphereVertices;
|
||||
std::vector<uint32_t> sphereIndices;
|
||||
|
||||
const int ringSegments = 16;
|
||||
const float sphereRadius = 0.5f;
|
||||
|
||||
// XY Ring
|
||||
for (int i = 0; i < ringSegments; ++i)
|
||||
{
|
||||
float angle = (2.0f * glm::pi<float>() * i) / ringSegments;
|
||||
float x = cos(angle) * sphereRadius;
|
||||
float y = sin(angle) * sphereRadius;
|
||||
sphereVertices.push_back({ Vector3(x, y, 0.0f), 0.0f, Vector3(), 0.0f });
|
||||
|
||||
uint32_t curr = i;
|
||||
uint32_t next = (i + 1) % ringSegments;
|
||||
sphereIndices.push_back(curr);
|
||||
sphereIndices.push_back(next);
|
||||
}
|
||||
|
||||
// XZ Ring
|
||||
uint32_t baseXZ = sphereVertices.size();
|
||||
for (int i = 0; i < ringSegments; ++i)
|
||||
{
|
||||
float angle = (2.0f * glm::pi<float>() * i) / ringSegments;
|
||||
float x = cos(angle) * sphereRadius;
|
||||
float z = sin(angle) * sphereRadius;
|
||||
sphereVertices.push_back({ Vector3(x, 0.0f, z), 0.0f, Vector3(), 0.0f });
|
||||
|
||||
uint32_t curr = baseXZ + i;
|
||||
uint32_t next = baseXZ + ((i + 1) % ringSegments);
|
||||
sphereIndices.push_back(curr);
|
||||
sphereIndices.push_back(next);
|
||||
}
|
||||
|
||||
// YZ Ring
|
||||
uint32_t baseYZ = sphereVertices.size();
|
||||
for (int i = 0; i < ringSegments; ++i)
|
||||
{
|
||||
float angle = (2.0f * glm::pi<float>() * i) / ringSegments;
|
||||
float y = cos(angle) * sphereRadius;
|
||||
float z = sin(angle) * sphereRadius;
|
||||
sphereVertices.push_back({ Vector3(0.0f, y, z), 0.0f, Vector3(), 0.0f });
|
||||
|
||||
uint32_t curr = baseYZ + i;
|
||||
uint32_t next = baseYZ + ((i + 1) % ringSegments);
|
||||
sphereIndices.push_back(curr);
|
||||
sphereIndices.push_back(next);
|
||||
}
|
||||
|
||||
SphereMesh = CreateRef<VkMesh>(sphereVertices, sphereIndices);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<Vertex> cylinderVertices;
|
||||
std::vector<uint32_t> cylinderIndices;
|
||||
|
||||
const int segments = 16;
|
||||
const float radius = 0.5f;
|
||||
const float halfHeight = 1.0f;
|
||||
|
||||
// Vertex pairs: top and bottom
|
||||
for (int i = 0; i < segments; ++i)
|
||||
{
|
||||
float angle = (2.0f * glm::pi<float>() * i) / segments;
|
||||
float x = cos(angle) * radius;
|
||||
float z = sin(angle) * radius;
|
||||
|
||||
// Top ring
|
||||
cylinderVertices.push_back({ Vector3(x, +halfHeight, z), 0.0f, Vector3(), 0.0f });
|
||||
|
||||
// Bottom ring
|
||||
cylinderVertices.push_back({ Vector3(x, -halfHeight, z), 0.0f, Vector3(), 0.0f });
|
||||
}
|
||||
|
||||
// Circle edges (top and bottom)
|
||||
for (int i = 0; i < segments; ++i)
|
||||
{
|
||||
uint32_t topIdx = i * 2;
|
||||
uint32_t nextTopIdx = ((i + 1) % segments) * 2;
|
||||
uint32_t botIdx = i * 2 + 1;
|
||||
uint32_t nextBotIdx = ((i + 1) % segments) * 2 + 1;
|
||||
|
||||
// Top circle
|
||||
cylinderIndices.push_back(topIdx);
|
||||
cylinderIndices.push_back(nextTopIdx);
|
||||
|
||||
// Bottom circle
|
||||
cylinderIndices.push_back(botIdx);
|
||||
cylinderIndices.push_back(nextBotIdx);
|
||||
}
|
||||
|
||||
// 4 vertical edges at 0, 90, 180, 270 degrees
|
||||
for (int i : { 0, segments / 4, segments / 2, (3 * segments) / 4 })
|
||||
{
|
||||
uint32_t topIdx = i * 2;
|
||||
uint32_t botIdx = i * 2 + 1;
|
||||
|
||||
cylinderIndices.push_back(topIdx);
|
||||
cylinderIndices.push_back(botIdx);
|
||||
}
|
||||
|
||||
// Final creation of the cylinder outline mesh
|
||||
CylinderMesh = CreateRef<VkMesh>(cylinderVertices, cylinderIndices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VkSceneRenderer::LoadShaders()
|
||||
@@ -72,6 +366,8 @@ void VkSceneRenderer::LoadShaders()
|
||||
shaderMgr.AddShader("line_vert", shaderCompiler.CompileShader("Resources/Shaders/Vulkan/line.vert"));
|
||||
shaderMgr.AddShader("ssao_frag", shaderCompiler.CompileShader("Resources/Shaders/Vulkan/ssao.frag"));
|
||||
shaderMgr.AddShader("ssao_vert", shaderCompiler.CompileShader("Resources/Shaders/Vulkan/ssao.vert"));
|
||||
shaderMgr.AddShader("blur_frag", shaderCompiler.CompileShader("Resources/Shaders/Vulkan/blur.frag"));
|
||||
shaderMgr.AddShader("blur_vert", shaderCompiler.CompileShader("Resources/Shaders/Vulkan/blur.vert"));
|
||||
}
|
||||
|
||||
void VkSceneRenderer::PrepareScenes(const std::vector<Ref<Scene>>& scenes, RenderContext inContext)
|
||||
|
||||
@@ -25,6 +25,11 @@ namespace Nuake
|
||||
{
|
||||
public:
|
||||
static Ref<VkMesh> QuadMesh;
|
||||
static Ref<VkMesh> BoxMesh;
|
||||
static Ref<VkMesh> CapsuleMesh;
|
||||
static Ref<VkMesh> SphereMesh;
|
||||
static Ref<VkMesh> CylinderMesh;
|
||||
static Ref<VkMesh> ArrowMesh;
|
||||
|
||||
public:
|
||||
//RenderContext Context;
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Nuake
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ButtonPadding);
|
||||
|
||||
//UIFont boldFont(Bold);
|
||||
UIFont boldFont(Bold);
|
||||
const bool buttonPressed = ImGui::Button(name.c_str(), ImVec2(size.x, size.y));
|
||||
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
Reference in New Issue
Block a user