10 Commits

Author SHA1 Message Date
antopilo
4052c14567 Better splash screen 2025-04-17 23:18:11 -04:00
antopilo
5c5289ee73 No more random textures when resizing viewport 2025-04-17 22:50:02 -04:00
antopilo
9a3919d633 Fixed crashen when closing window 2025-04-17 22:33:03 -04:00
antopilo
0c4252be5e Manual GPU resource deletion in desctructor 2025-04-17 22:32:53 -04:00
antopilo
e2fd0644e4 Removed test gizmo drawing 2025-04-17 22:32:40 -04:00
antopilo
54b7c4143f Fixed material being wrongly serialized when baking an asset 2025-04-17 22:23:00 -04:00
antopilo
217a4fbcb6 Fixed weird splash screen when loading a project 2025-04-17 22:22:47 -04:00
antopilo
8125d24926 Fixed crash when resizing viewport 2025-04-17 22:13:57 -04:00
antopilo
d276e875a8 Fixed albedo not working when first importing asset 2025-04-17 20:58:38 -04:00
antopilo
5da09282d0 Added PCF smooth shadows 2025-04-17 20:17:31 -04:00
16 changed files with 138 additions and 49 deletions

BIN
Data/Images/splash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

View File

@@ -193,6 +193,28 @@ int GetCSMSplit(float depth)
return 0;
}
float SampleShadowMap(int textureId, float2 coords, float compare)
{
return compare > textures[textureId].Sample(mySampler, coords.xy).r;
}
float SampleShadowMapLinear(int textureId, float2 coords, float compare, float2 texelSize)
{
float2 pixelPos = coords / texelSize + float2(0.5f, 0.5f);
float2 fracPart = frac(pixelPos);
float2 startTexel = (pixelPos - fracPart) * texelSize;
float blTexel = SampleShadowMap(textureId, startTexel, compare);
float brTexel = SampleShadowMap(textureId, startTexel + float2(texelSize.x, 0.0), compare);
float tlTexel = SampleShadowMap(textureId, startTexel + float2(0.0, texelSize.y), compare);
float trTexel = SampleShadowMap(textureId, startTexel + texelSize, compare);
float mixA = lerp(blTexel, tlTexel, fracPart.y);
float mixB = lerp(brTexel, trTexel, fracPart.y);
return lerp(mixA, mixB, fracPart.x);
}
float ShadowCalculation(Light light, float3 fragPos, float3 normal)
{
// Find correct CSM splits from depth
@@ -214,6 +236,27 @@ float ShadowCalculation(Light light, float3 fragPos, float3 normal)
//projCoords.y = 1.0 - projCoords.y;
float currentDepth = projCoords.z;
float bias = max(0.005 * (1.0 - dot(normal, light.direction)), 0.0005);
if(splitIndex < 2)
{
const float NUM_SAMPLES = 4.0f;
const float SAMPLES_START = (NUM_SAMPLES - 1.0f) / 2.0f;
const float NUM_SAMPLES_SQUARED = NUM_SAMPLES * NUM_SAMPLES;
float2 texelSize = 1.0f / float2(4096, 4096);
float result = 0.0f;
for(float y = -SAMPLES_START; y <= SAMPLES_START; y += 1.0f)
{
for (float x = -SAMPLES_START; x <= SAMPLES_START; x += 1.0f)
{
float2 coordsOffset = float2(x, y) * texelSize;
result += SampleShadowMapLinear(light.shadowMapTextureId[splitIndex], projCoords.xy + coordsOffset, currentDepth, texelSize);
}
}
return result /= NUM_SAMPLES_SQUARED;
}
float shadowMapDepth = textures[light.shadowMapTextureId[splitIndex]].Sample(mySampler, projCoords.xy).r;
return (currentDepth > shadowMapDepth);//> 0.0 ? 1.0 : 0.0;

View File

@@ -64,6 +64,7 @@
#include "Nuake/Rendering/Vulkan/VkShaderManager.h"
#include "../Events/EditorRequests.h"
#include "../../../../Nuake/Thirdparty/glfw/include/GLFW/glfw3.h"
namespace Nuake {
@@ -243,7 +244,7 @@ namespace Nuake {
if (ImGui::InvisibleButton("Minimize", ImVec2(buttonWidth, buttonHeight)))
{
//glfwIconifyWindow(Window::Get()->GetHandle());
glfwIconifyWindow(Window::Get()->GetHandle());
}
auto rect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
@@ -264,11 +265,11 @@ namespace Nuake {
const auto window = Window::Get()->GetHandle();
if (isMaximized)
{
//glfwRestoreWindow(window);
glfwRestoreWindow(window);
}
else
{
//glfwMaximizeWindow(window);
glfwMaximizeWindow(window);
}
}
auto rect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
@@ -282,7 +283,7 @@ namespace Nuake {
int iconHeight = std::max(CloseIconTexture->GetHeight(), 24);
if (ImGui::InvisibleButton("Close", ImVec2(buttonWidth, buttonHeight)))
{
//glfwSetWindowShouldClose(Window::Get()->GetHandle(), true);
glfwSetWindowShouldClose(Window::Get()->GetHandle(), true);
}
UI::DrawButtonImage(CloseIconTexture, UI::TextCol, UI::TextCol, buttonColP);
@@ -2577,11 +2578,7 @@ namespace Nuake {
isLoadingProjectQueue = false;
auto window = Window::Get();
window->SetDecorated(true);
window->ShowTitleBar(false);
window->SetSize({ 1600, 900 });
window->Center();
frameCount = 0;
}
else
@@ -2596,7 +2593,7 @@ namespace Nuake {
if (_WelcomeWindow->IsProjectQueued() && frameCount > 0)
{
// draw splash
LoadingSplash::Get().Draw();
LoadingSplash::Get().Draw(_WelcomeWindow->queuedProjectPath);
frameCount--;
if (frameCount == 0)
@@ -2617,6 +2614,17 @@ namespace Nuake {
m_ProjectSettingsWindow->Init(Engine::GetProject());
}
static bool isDone = false;
if (frameCount == 0 && !isDone)
{
auto window = Window::Get();
window->SetDecorated(true);
window->ShowTitleBar(false);
window->SetSize({ 1600, 900 });
window->Center();
isDone = true;
}
// Shortcuts
if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
{

View File

@@ -4,7 +4,7 @@
#include <Nuake/Core/Maths.h>
#include "Nuake/Window.h"
#include "Nuake/UI/ImUI.h"
#include <imgui/imgui.h>
@@ -16,15 +16,15 @@ using namespace Nuake;
LoadingSplash::LoadingSplash()
{
_NuakeLogo = Nuake::TextureManager::Get()->GetTexture2(NUAKE_LOGO_PATH);
_NuakeSplash = Nuake::TextureManager::Get()->GetTexture2(NUAKE_SPLASH_PATH);
Nuake::Window::Get()->SetDecorated(false);
Nuake::Window::Get()->SetSize({ 640, 480 });
Nuake::Window::Get()->SetSize({ 640, 400 });
Nuake::Window::Get()->Center();
}
void LoadingSplash::Draw()
void LoadingSplash::Draw(const std::string& project)
{
// Make viewport fullscreen
ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->Pos);
@@ -32,17 +32,22 @@ void LoadingSplash::Draw()
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(32.0f, 32.0f));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("Welcome Screen", 0, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
{
// Draw Nuake logo
{
const Vector2 logoSize = _NuakeLogo->GetSize();
const ImVec2 imguiSize = ImVec2(logoSize.x, logoSize.y);
ImGui::Image((ImTextureID)_NuakeLogo->GetImGuiDescriptorSet(), imguiSize);
}
const Vector2 splashSize = _NuakeSplash->GetSize();
const ImVec2 splashImguiSize = ImVec2(splashSize.x, splashSize.y);
ImGui::Image((ImTextureID)_NuakeSplash->GetImGuiDescriptorSet(), splashImguiSize, {0, 1}, {1, 0});
ImGui::Text("LOADING SCENE...");
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 8.0f);
ImGui::SetCursorPosX(8.0f);
{
UIFont font(Fonts::Bold);
ImGui::Text("Loading project... ");
}
ImGui::SetCursorPosX(8.0f);
ImGui::TextColored({ 1.0, 1.0, 1.0, 0.5 }, project.c_str());
//ImGui::Text(project.c_str());
}
ImGui::End();

View File

@@ -14,8 +14,9 @@ class LoadingSplash
{
private:
const std::string NUAKE_LOGO_PATH = "Resources/Images/logo_white.png";
const std::string NUAKE_SPLASH_PATH = "Resources/Images/splash.png";
Ref<Nuake::VulkanImage> _NuakeLogo;
Ref<Nuake::VulkanImage> _NuakeSplash;
public:
static LoadingSplash& Get()
{
@@ -26,5 +27,5 @@ public:
LoadingSplash();
~LoadingSplash() = default;
void Draw();
void Draw(const std::string& projectPath);
};

View File

@@ -77,14 +77,18 @@ void ViewportWidget::Draw()
// This is important for make UI mouse coord relative to viewport
// Nuake::Input::SetViewportDimensions(m_ViewportPos, viewportPanelSize);
VkDescriptorSet textureDesc = sceneViewport->GetRenderTarget()->GetImGuiDescriptorSet();
ImVec2 imagePos = ImGui::GetWindowPos() + ImGui::GetCursorPos();
ImVec2 viewportMin = ImGui::GetCursorScreenPos();
// Input::SetEditorViewportSize(m_ViewportPos, viewportPanelSize);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
//m_ViewportPos = { imagePos.x, imagePos.y };
ImGui::Image(textureDesc, regionAvail, { 0, 1 }, { 1, 0 });
VkDescriptorSet textureDesc = sceneViewport->GetRenderTarget()->GetImGuiDescriptorSet();
if (!needsResize)
{
ImGui::Image(textureDesc, regionAvail, { 0, 1 }, { 1, 0 });
}
ImGui::PopStyleVar();
float title_bar_height = ImGui::GetFontSize() + ImGui::GetStyle().FramePadding.y * 2;
@@ -200,7 +204,7 @@ void ViewportWidget::Draw()
{
Logger::Log("Mouse Picked: " + std::to_string(picked));
constexpr uint32_t INVALID_PICK_ID = 4187593120;
constexpr uint32_t INVALID_PICK_ID = 3863365216;
if (picked != INVALID_PICK_ID)
{
Nuake::Entity entity = Nuake::Entity((entt::entity)picked, editorContext.GetScene().get());
@@ -315,10 +319,6 @@ void ViewportWidget::OnLineDraw(DebugLineCmd& lineCmd)
auto view = cam->GetTransform();
auto proj = cam->GetPerspective();
Matrix4 transform = Matrix4(1.0f);
transform = glm::translate(transform, { 0, 2, 0 });
//lineCmd.DrawLine(proj * view * transform, Color(1, 0, 0, 1), 2.0f);
auto camView = scene->m_Registry.view<TransformComponent, CameraComponent>();
for (auto e : camView)
{
@@ -430,9 +430,6 @@ void ViewportWidget::OnLineDraw(DebugLineCmd& lineCmd)
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)
@@ -472,14 +469,12 @@ void ViewportWidget::OnDebugDraw(DebugCmd& debugCmd)
debugCmd.DrawTexturedQuad(proj * view * gizmoTransform, TextureManager::Get()->GetTexture2(icon), color, entityId);
};
debugCmd.DrawQuad(proj * view * glm::translate(Matrix4(1.0f), { 0, 4, 0 }));
auto lightView = scene->m_Registry.view<TransformComponent, LightComponent>();
for (auto e : lightView)
{
auto [transform, light] = scene->m_Registry.get<TransformComponent, LightComponent>(e);
auto selection = editorContext.GetSelection();
const auto& selection = editorContext.GetSelection();
bool isSelected = selection.Type == EditorSelectionType::Entity && selection.Entity.GetHandle() == (int)e;
std::string texturePath = "Resources/Gizmos/";

View File

@@ -42,10 +42,10 @@ namespace Nuake
int32_t SelectedProject = -1;
std::vector<ProjectPreview> _Projects;
std::string queuedProjectPath;
std::string queuedRemovalPath;
public:
std::string queuedProjectPath;
WelcomeWindow(Nuake::EditorInterface* editor);
~WelcomeWindow() = default;

View File

@@ -83,7 +83,7 @@ Ref<File> GLTFBaker::Bake(const Ref<File>& file)
material = CreateRef<Material>();
if (!materialData.albedo.empty())
{
material->SetAlbedo(absolutePath + "/../" + materialData.albedo);
material->SetAlbedo(FileSystem::AbsoluteToRelative(absolutePath + "/../" + materialData.albedo));
}
if (!materialData.normal.empty())
@@ -117,7 +117,7 @@ Ref<File> GLTFBaker::Bake(const Ref<File>& file)
materialCache[materialPath] = material;
}
mesh->MaterialResource = RID(material->ID);
mesh->SetMaterial(material);
model->AddMesh(std::move(mesh));
}

View File

@@ -100,7 +100,21 @@ namespace Nuake
inline bool GetUnlit() { return data.u_Unlit == 1; }
bool HasAlbedo() { return (m_Albedo != nullptr || AlbedoImage != UUID(0)); }
void SetAlbedo(const std::string path) { m_Albedo = CreateRef<Texture>(path); }
void SetAlbedo(const std::string path)
{
if (FileSystem::FileExists(path))
{
GPUResources& resources = GPUResources::Get();
Ref<VulkanImage> image = CreateRef<VulkanImage>(FileSystem::RelativeToAbsolute(path));
if (resources.AddTexture(image))
{
AlbedoImage = image->GetID();
}
Ref<Texture> albedoTexture = TextureManager::Get()->GetTexture(FileSystem::RelativeToAbsolute(path));
SetAlbedo(albedoTexture);
}
}
void SetAlbedo(Ref<Texture> texture) { m_Albedo = texture; }
bool HasAO() { return m_AO != nullptr; }

View File

@@ -303,9 +303,11 @@ void SceneRenderPipeline::Render(PassRenderContext& ctx)
size_t bufferSize = sizeof(Vector4);
Ref<AllocatedBuffer> stagingBuffer = CreateRef<AllocatedBuffer>(bufferSize, BufferUsage::TRANSFER_DST, MemoryUsage::GPU_TO_CPU);
assert(request.mousePosition.x < GBufferEntityID->GetSize().x && request.mousePosition.y < GBufferEntityID->GetSize().y && "Mouse coord out of bounds");
// Flip Y
request.mousePosition.y = GBufferEntityID->GetSize().y - request.mousePosition.y;
request.mousePosition = glm::clamp(request.mousePosition, { 0, 0 }, GBufferEntityID->GetSize() - Vector2{1, 1});
VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd)
{
Cmd command(cmd);

View File

@@ -29,8 +29,19 @@ bool Viewport::Resize()
{
viewportSize = queuedResize;
renderTarget = CreateRef<VulkanImage>(ImageFormat::RGBA16F, viewportSize);
renderTarget->GetImGuiDescriptorSet();
auto newRenderTarget = CreateRef<VulkanImage>(ImageFormat::RGBA16F, viewportSize);
VkRenderer::Get().ImmediateSubmit([&](VkCommandBuffer cmd)
{
Cmd command(cmd);
command.TransitionImageLayout(renderTarget, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
command.TransitionImageLayout(newRenderTarget, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
command.CopyImageToImage(renderTarget, newRenderTarget);
command.TransitionImageLayout(renderTarget, VK_IMAGE_LAYOUT_GENERAL);
command.TransitionImageLayout(newRenderTarget, VK_IMAGE_LAYOUT_GENERAL);
});
renderTarget = newRenderTarget;
return true;
}

View File

@@ -154,7 +154,7 @@ namespace Nuake
};
GPUResources();
~GPUResources() = default;
~GPUResources();
public:
void Init();

View File

@@ -325,7 +325,6 @@ VulkanImage::VulkanImage(void* inData, size_t inSize) :
VulkanImage::~VulkanImage()
{
Logger::Log("Deleting VulkanImage", "vulkan", VERBOSE);
GPUResources::Get().QueueDeletion(GetGPUCleanUpStack());
}

View File

@@ -722,6 +722,7 @@ bool VkRenderer::Draw()
{
//viewport->Resize();
}
ResizeViewports();
FrameSkipped = false;
@@ -768,6 +769,7 @@ bool VkRenderer::Draw()
void VkRenderer::EndDraw()
{
if (FrameSkipped)
{
return;
@@ -822,10 +824,10 @@ void VkRenderer::EndDraw()
presentInfo.pImageIndices = &swapchainImageIndex;
ResizeViewports();
VK_CALL(vkQueuePresentKHR(GPUQueue, &presentInfo));
auto& io = ImGui::GetIO();
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
//Update and Render additional Platform Windows

View File

@@ -16,6 +16,15 @@ GPUResources::GPUResources()
}
}
GPUResources::~GPUResources()
{
Images.clear();
Buffers.clear();
Meshes.clear();
Light.clear();
Cameras.clear();
}
void GPUResources::Init()
{
CreateBindlessLayout();

View File

@@ -417,7 +417,7 @@ void Window::SetTitlebarHitTestCallback(std::function<void(Window&, int x, int y
void Window::OnWindowFocused(Window& window, bool focused)
{
if (onWindowFocusedCallback)
if (onWindowFocusedCallback && !window.ShouldClose())
{
onWindowFocusedCallback(window, focused);
}