diff --git a/Editor/Source/ApplicationInfoPanel.cpp b/Editor/Source/ApplicationInfoPanel.cpp index e039bae1..d59e7ece 100644 --- a/Editor/Source/ApplicationInfoPanel.cpp +++ b/Editor/Source/ApplicationInfoPanel.cpp @@ -3,6 +3,9 @@ #include #include #include +#include + +#include "Editor.h" #include #include @@ -47,7 +50,7 @@ namespace Lumos ApplicationInfoPanel::ApplicationInfoPanel() { - m_Name = "Application Info##ApplicationInfo"; + m_Name = "Application Info###appinfo"; m_SimpleName = "Application Info"; } @@ -75,7 +78,7 @@ namespace Lumos } static ImPlotAxisFlags rt_axis = ImPlotAxisFlags_NoTickLabels; - static bool PlotFrameTime = true; + static bool PlotFrameTime = false; static bool PlotFramerate = false; ImGui::Checkbox("Plot Frame Time", &PlotFrameTime); @@ -92,6 +95,7 @@ namespace Lumos ImPlot::EndPlot(); } + if(PlotFrameTime && ImPlot::BeginPlot("Frametime", ImVec2(-1, 350), 0)) { ImPlot::SetupAxis(ImAxis_X1, nullptr, rt_axis); @@ -133,27 +137,40 @@ namespace Lumos Application::Get().GetWindow()->GetSwapChain()->SetVSync(VSync); Graphics::Renderer::GetRenderer()->OnResize(Application::Get().GetWindow()->GetWidth(), Application::Get().GetWindow()->GetHeight()); }); } + + QualitySettings& qs = Application::Get().GetQualitySettings(); + int shadowQuality = (int)qs.ShadowQuality; + int shadowRes = (int)qs.ShadowResolution; + + if(ImGuiUtilities::Property("Shadow Quality", shadowQuality, 0, 3)) + qs.ShadowQuality = (ShadowQualitySetting)shadowQuality; + + if(ImGuiUtilities::Property("Shadow Resolution", shadowRes, 0, 3)) + qs.ShadowResolution = (ShadowResolutionSetting)shadowRes; + ImGui::Columns(1); ImGui::Text("FPS : %5.2i", Engine::Get().Statistics().FramesPerSecond); ImGui::Text("UPS : %5.2i", Engine::Get().Statistics().UpdatesPerSecond); ImGui::Text("Frame Time : %5.2f ms", Engine::Get().Statistics().FrameTime); ImGui::Text("Arena Count : %i", GetArenaCount()); - - uint64_t totalAllocated = 0; - for(int i = 0; i < GetArenaCount(); i++) + if(ImGui::TreeNodeEx("Arenas", 0)) { - auto arena = GetArena(i); - totalAllocated += arena->Size; - float percentageFull = (float)arena->Position / (float)arena->Size; - ImGui::ProgressBar((float)arena->Position / (float)arena->Size); - Lumos::ImGuiUtilities::Tooltip((Lumos::StringUtilities::BytesToString(arena->Position) + " / " + Lumos::StringUtilities::BytesToString(arena->Size)).c_str()); + uint64_t totalAllocated = 0; + for(int i = 0; i < GetArenaCount(); i++) + { + auto arena = GetArena(i); + totalAllocated += arena->Size; + float percentageFull = (float)arena->Position / (float)arena->Size; + ImGui::ProgressBar(percentageFull); + Lumos::ImGuiUtilities::Tooltip((Lumos::StringUtilities::BytesToString(arena->Position) + " / " + Lumos::StringUtilities::BytesToString(arena->Size)).c_str()); + } + ImGui::Text("Total %s", Lumos::StringUtilities::BytesToString(totalAllocated).c_str()); + ImGui::TreePop(); } - ImGui::Text("Total %s", Lumos::StringUtilities::BytesToString(totalAllocated).c_str()); - ImGui::NewLine(); ImGui::Text("Scene : %s", Application::Get().GetSceneManager()->GetCurrentScene()->GetSceneName().c_str()); ImGui::TreePop(); - }; + } ImGuiUtilities::PopID(); } diff --git a/Editor/Source/AssetManagerPanel.cpp b/Editor/Source/AssetManagerPanel.cpp new file mode 100644 index 00000000..9ff63b27 --- /dev/null +++ b/Editor/Source/AssetManagerPanel.cpp @@ -0,0 +1,88 @@ +#include "AssetManagerPanel.h" + +#include +#include +#include +#include + +#include "Editor.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace Lumos +{ + AssetManagerPanel::AssetManagerPanel() + { + m_Name = "AssetManagerPanel###AssetManagerPanel"; + m_SimpleName = "Asset Manager"; + } + + void AssetManagerPanel::OnImGui() + { + auto flags = ImGuiWindowFlags_NoCollapse; + if(ImGui::Begin(m_Name.c_str(), &m_Active, flags)) + { + ImGuiUtilities::PushID(); + + enum MyItemColumnID + { + MyItemColumnID_ID, + MyItemColumnID_Name, + MyItemColumnID_Type, + MyItemColumnID_Accessed + }; + + if(ImGui::BeginTable("Asset Registry", 4, ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg)) + { + ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_ID); + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_NoSort, 0.0f, MyItemColumnID_Type); + ImGui::TableSetupColumn("Last Accessed", ImGuiTableColumnFlags_NoSort, 0.0f, MyItemColumnID_Accessed); + + ImGui::TableSetupScrollFreeze(0, 1); + + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); + Lumos::AssetRegistry& registry = m_Editor->GetAssetManager()->GetAssetRegistry(); + + auto DrawEntry = [®istry](AssetMetaData& metaData, uint64_t ID) + { + { + ImGui::TableNextColumn(); + ImGui::TextUnformatted(fmt::format("{0}", ID).c_str()); //"%lld", ID); + + ImGui::TableNextColumn(); + std::string name = "Unnamed"; +#ifndef LUMOS_PRODUCTION + registry.GetName(ID, name); +#endif + ImGui::TextUnformatted(name.c_str()); + + ImGui::TableNextColumn(); + ImGui::TextUnformatted(AssetTypeToString(metaData.Type)); + + ImGui::TableNextColumn(); + ImGui::Text("%.2f", metaData.lastAccessed); + + ImGui::TableNextRow(); + } + }; + + for(auto& current : registry) + { + DrawEntry(current.second, current.first); + } + + ImGui::EndTable(); + } + ImGuiUtilities::PopID(); + } + ImGui::End(); + } +} diff --git a/Editor/Source/AssetManagerPanel.h b/Editor/Source/AssetManagerPanel.h new file mode 100644 index 00000000..7b72f73e --- /dev/null +++ b/Editor/Source/AssetManagerPanel.h @@ -0,0 +1,15 @@ +#pragma once + +#include "EditorPanel.h" + +namespace Lumos +{ + class AssetManagerPanel : public EditorPanel + { + public: + AssetManagerPanel(); + ~AssetManagerPanel() = default; + + void OnImGui() override; + }; +} diff --git a/Editor/Source/ConsolePanel.cpp b/Editor/Source/ConsolePanel.cpp index 5eea20fa..e2324ec5 100644 --- a/Editor/Source/ConsolePanel.cpp +++ b/Editor/Source/ConsolePanel.cpp @@ -33,7 +33,7 @@ namespace Lumos { for(auto messIt = messageStart; messIt != s_MessageBuffer.end(); ++messIt) { - if(message->GetMessageID() == (*messIt)->GetMessageID()) + if((*messIt) && message->GetMessageID() == (*messIt)->GetMessageID()) { (*messIt)->IncreaseCount(); return; diff --git a/Editor/Source/Editor.cpp b/Editor/Source/Editor.cpp index 74825f88..d6a77068 100644 --- a/Editor/Source/Editor.cpp +++ b/Editor/Source/Editor.cpp @@ -5,6 +5,7 @@ #include "HierarchyPanel.h" #include "InspectorPanel.h" #include "ApplicationInfoPanel.h" +#include "AssetManagerPanel.h" #include "GraphicsInfoPanel.h" #include "TextEditPanel.h" #include "ResourcePanel.h" @@ -57,6 +58,7 @@ #include #include #include +#include #include #include @@ -65,6 +67,7 @@ #include #include #include +#include namespace Lumos { @@ -242,6 +245,10 @@ namespace Lumos Application::SetEditorState(EditorState::Preview); Application::Get().GetWindow()->SetEventCallback(BIND_EVENT_FN(Editor::OnEvent)); + String8 pathCopy = PushStr8Copy(m_FrameArena, m_ProjectSettings.m_ProjectRoot.c_str()); + pathCopy = StringUtilities::ResolveRelativePath(m_FrameArena, pathCopy); + m_ProjectSettings.m_ProjectRoot = (const char*)pathCopy.str; + m_EditorCamera = CreateSharedPtr(-20.0f, -40.0f, glm::vec3(-31.0f, 12.0f, 51.0f), @@ -274,6 +281,8 @@ namespace Lumos m_Panels.emplace_back(CreateSharedPtr()); m_Panels.emplace_back(CreateSharedPtr()); m_Panels.emplace_back(CreateSharedPtr()); + m_Panels.emplace_back(CreateSharedPtr()); + m_Panels.back()->SetActive(false); m_Panels.emplace_back(CreateSharedPtr()); m_Panels.emplace_back(CreateSharedPtr()); m_Panels.emplace_back(CreateSharedPtr()); @@ -892,6 +901,7 @@ namespace Lumos Application::Get().GetSystem()->UpdateListener(Application::Get().GetCurrentScene()); Application::Get().GetSystem()->SetPaused(selected); Application::Get().SetEditorState(selected ? EditorState::Preview : EditorState::Play); + ImGui::SetWindowFocus(ICON_MDI_GAMEPAD_VARIANT " Game###game"); m_SelectedEntities.clear(); // m_SelectedEntity = entt::null; @@ -1134,7 +1144,7 @@ namespace Lumos if(defaultSetup) { auto light = scene->GetEntityManager()->Create("Light"); - auto lightComp = light.AddComponent(); + auto& lightComp = light.AddComponent(); glm::mat4 lightView = glm::inverse(glm::lookAt(glm::vec3(30.0f, 9.0f, 50.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f))); light.GetTransform().SetLocalTransform(lightView); @@ -1259,7 +1269,6 @@ namespace Lumos if(ImGui::Button("OK", ImVec2(120, 0))) { - auto scene = new Scene("New Scene"); Application::Get().GetSceneManager()->SwitchScene(Application::Get().GetSceneManager()->GetCurrentSceneIndex()); ImGui::CloseCurrentPopup(); @@ -1611,7 +1620,8 @@ namespace Lumos ImGui::DockBuilderDockWindow("###resources", DockingBottomLeftChild); ImGui::DockBuilderDockWindow("Dear ImGui Demo", DockLeft); ImGui::DockBuilderDockWindow("###GraphicsInfo", DockLeft); - ImGui::DockBuilderDockWindow("###ApplicationInfo", DockLeft); + ImGui::DockBuilderDockWindow("###appinfo", DockLeft); + ImGui::DockBuilderDockWindow("###AssetManagerPanel", DockLeft); ImGui::DockBuilderDockWindow("###hierarchy", DockLeft); ImGui::DockBuilderDockWindow("###textEdit", DockMiddleLeft); ImGui::DockBuilderDockWindow("###scenesettings", DockLeft); @@ -1715,12 +1725,13 @@ namespace Lumos return; } - DebugRenderer::DrawHairLine(glm::vec3(-5000.0f, 0.0f, 0.0f), glm::vec3(5000.0f, 0.0f, 0.0f), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); - DebugRenderer::DrawHairLine(glm::vec3(0.0f, -5000.0f, 0.0f), glm::vec3(0.0f, 5000.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); - DebugRenderer::DrawHairLine(glm::vec3(0.0f, 0.0f, -5000.0f), glm::vec3(0.0f, 0.0f, 5000.0f), glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); + DebugRenderer::DrawHairLine(glm::vec3(-5000.0f, 0.0f, 0.0f), glm::vec3(5000.0f, 0.0f, 0.0f), true, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); + DebugRenderer::DrawHairLine(glm::vec3(0.0f, -5000.0f, 0.0f), glm::vec3(0.0f, 5000.0f, 0.0f), true, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); + DebugRenderer::DrawHairLine(glm::vec3(0.0f, 0.0f, -5000.0f), glm::vec3(0.0f, 0.0f, 5000.0f), true, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); m_GridRenderer->OnImGui(); + m_GridRenderer->SetDepthTarget(m_RenderPasses->GetForwardData().m_DepthTexture); m_GridRenderer->BeginScene(Application::Get().GetSceneManager()->GetCurrentScene(), m_EditorCamera.get(), &m_EditorCameraTransform); m_GridRenderer->RenderScene(); #endif @@ -1943,11 +1954,57 @@ namespace Lumos } } + static float m_SceneSavePopupTimer = -1.0f; + static bool popupopen = false; + + if(m_SceneSavePopupTimer > 0.0f) + { + { + ImGui::OpenPopup("Scene Save"); + ImVec2 size = ImGui::GetMainViewport()->Size; + ImGui::SetNextWindowSize({ size.x * 0.65f, size.y * 0.25f }); + ImGui::SetNextWindowPos({ size.x / 2.0f, size.y / 2.5f }, 0, { 0.5, 0.5 }); + popupopen = true; + } + } + + if(ImGui::BeginPopupModal("Scene Save", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar)) + { + ArenaTemp scratch = ScratchBegin(nullptr, 0); + String8 savedText = PushStr8F(scratch.arena, "Scene Saved - %s/Assets/Scenes", m_ProjectSettings.m_ProjectRoot.c_str()); + ImVec2 textSize = ImGui::CalcTextSize((const char*)savedText.str); + + // Calculate the position to center the text horizontally + ImVec2 windowSize = ImGui::GetWindowSize(); + float posX = (windowSize.x - textSize.x) * 0.5f; + float posY = (windowSize.y - textSize.y) * 0.5f; + + // Set the cursor position to the calculated position + ImGui::SetCursorPosX(posX); + ImGui::SetCursorPosY(posY); + + // Display the centered text + ImGui::TextUnformatted((const char*)savedText.str); + + if(m_SceneSavePopupTimer < 0.0f) + { + popupopen = false; + ImGui::CloseCurrentPopup(); + } + + ScratchEnd(scratch); + ImGui::EndPopup(); + } + + if(m_SceneSavePopupTimer > 0.0f) + m_SceneSavePopupTimer -= Engine::GetTimeStep().GetSeconds(); + if((Input::Get().GetKeyHeld(InputCode::Key::LeftSuper) || (Input::Get().GetKeyHeld(InputCode::Key::LeftControl)))) { if(Input::Get().GetKeyPressed(InputCode::Key::S) && Application::Get().GetSceneActive()) { Application::Get().GetSceneManager()->GetCurrentScene()->Serialise(m_ProjectSettings.m_ProjectRoot + "Assets/scenes/", false); + m_SceneSavePopupTimer = 2.0f; } if(Input::Get().GetKeyPressed(InputCode::Key::O)) @@ -2135,7 +2192,7 @@ namespace Lumos { Entity e = { entity, GetCurrentScene() }; { - DebugRenderer::DrawTextWsNDT(e.GetTransform().GetWorldPosition(), 20.0f, glm::vec4(1.0f), e.GetName()); + DebugRenderer::DrawTextWs(e.GetTransform().GetWorldPosition(), 20.0f, false, glm::vec4(1.0f), 0.0f, e.GetName()); } } } @@ -2362,6 +2419,8 @@ namespace Lumos m_Panels.emplace_back(CreateSharedPtr(physicalPath)); m_Panels.back().As()->SetOnSaveCallback(callback); m_Panels.back()->SetEditor(this); + + ImGui::SetWindowFocus(m_Panels.back()->GetName().c_str()); } EditorPanel* Editor::GetTextEditPanel() @@ -2476,8 +2535,8 @@ namespace Lumos Entity modelEntity = Application::Get().GetSceneManager()->GetCurrentScene()->GetEntityManager()->Create(StringUtilities::GetFileName(path)); modelEntity.AddComponent(path); + m_SelectedEntities.clear(); SetSelected(modelEntity.GetHandle()); - // m_SelectedEntity = modelEntity.GetHandle(); } else if(IsAudioFile(path)) { @@ -2607,6 +2666,20 @@ namespace Lumos LUMOS_PROFILE_FUNCTION(); LUMOS_LOG_INFO("Setting default editor settings"); m_ProjectSettings.m_ProjectRoot = "../../ExampleProject/"; + +#ifdef LUMOS_PLATFORM_MACOS + // Assuming working directory in /bin/Debug-macosx-x86_64/LumosEditor.app/Contents/MacOS + m_ProjectSettings.m_ProjectRoot = StringUtilities::GetFileLocation(OS::Instance()->GetExecutablePath()) + "../../../../../ExampleProject/"; + if(!Lumos::FileSystem::FolderExists(m_ProjectSettings.m_ProjectRoot)) + { + m_ProjectSettings.m_ProjectRoot = StringUtilities::GetFileLocation(OS::Instance()->GetExecutablePath()) + "/ExampleProject/"; + if(!Lumos::FileSystem::FolderExists(m_ProjectSettings.m_ProjectRoot)) + { + m_ProjectSettings.m_ProjectRoot = "../../ExampleProject/"; + } + } +#endif + m_ProjectSettings.m_ProjectName = "Example"; m_IniFile.Add("ShowGrid", m_Settings.m_ShowGrid); @@ -2645,7 +2718,14 @@ namespace Lumos m_ProjectSettings.m_ProjectRoot = m_IniFile.GetOrDefault("ProjectRoot", std::string("../../ExampleProject/")); m_ProjectSettings.m_ProjectName = m_IniFile.GetOrDefault("ProjectName", std::string("Example")); - m_Settings.m_Physics2DDebugFlags = m_IniFile.GetOrDefault("PhysicsDebugDrawFlags2D", 0); + + ArenaTemp arena = ScratchBegin(nullptr, 0); + String8 pathCopy = PushStr8Copy(arena.arena, m_ProjectSettings.m_ProjectRoot.c_str()); + pathCopy = StringUtilities::ResolveRelativePath(arena.arena, pathCopy); + m_ProjectSettings.m_ProjectRoot = (const char*)pathCopy.str; + ScratchEnd(arena); + + m_Settings.m_Physics2DDebugFlags = m_IniFile.GetOrDefault("PhysicsDebugDrawFlags2D", 0); m_Settings.m_Physics3DDebugFlags = m_IniFile.GetOrDefault("PhysicsDebugDrawFlags", 0); m_Settings.m_SleepOutofFocus = m_IniFile.GetOrDefault("SleepOutofFocus", true); m_Settings.m_CameraSpeed = m_IniFile.GetOrDefault("CameraSpeed", 1000.0f); diff --git a/Editor/Source/EditorPanel.h b/Editor/Source/EditorPanel.h index a09ab95f..18fb6178 100644 --- a/Editor/Source/EditorPanel.h +++ b/Editor/Source/EditorPanel.h @@ -57,6 +57,8 @@ namespace Lumos bool m_Active = true; std::string m_Name; std::string m_SimpleName; + std::string m_ChangedName; + Editor* m_Editor = nullptr; }; } diff --git a/Editor/Source/GameViewPanel.cpp b/Editor/Source/GameViewPanel.cpp index 837a9678..19d478ae 100644 --- a/Editor/Source/GameViewPanel.cpp +++ b/Editor/Source/GameViewPanel.cpp @@ -24,12 +24,11 @@ namespace Lumos m_SimpleName = "Game"; m_CurrentScene = nullptr; - m_Width = 1280; - m_Height = 800; + m_Width = 800; + m_Height = 600; - m_RenderPasses = CreateUniquePtr(m_Width, m_Height); - m_RenderPasses->GetSettings().DebugPass = false; - m_RenderPasses->m_DebugRenderEnabled = false; + m_RenderPasses = CreateUniquePtr(m_Width, m_Height); + m_RenderPasses->m_DebugRenderEnabled = false; } static std::string AspectToString(float aspect) @@ -281,6 +280,9 @@ namespace Lumos bool resize = false; LUMOS_ASSERT(width > 0 && height > 0, "Game View Dimensions 0"); + const QualitySettings& qs = Application::Get().GetQualitySettings(); + width *= qs.RendererScale; + height *= qs.RendererScale; if(m_Width != width || m_Height != height) { diff --git a/Editor/Source/GraphicsInfoPanel.cpp b/Editor/Source/GraphicsInfoPanel.cpp index f93bf37a..d3642924 100644 --- a/Editor/Source/GraphicsInfoPanel.cpp +++ b/Editor/Source/GraphicsInfoPanel.cpp @@ -8,7 +8,7 @@ namespace Lumos { GraphicsInfoPanel::GraphicsInfoPanel() { - m_Name = "Graphics Info##GraphicsInfo"; + m_Name = "Graphics Info###GraphicsInfo"; m_SimpleName = "Graphics Info"; } diff --git a/Editor/Source/HierarchyPanel.cpp b/Editor/Source/HierarchyPanel.cpp index 69c530c5..57bdb4ee 100644 --- a/Editor/Source/HierarchyPanel.cpp +++ b/Editor/Source/HierarchyPanel.cpp @@ -149,7 +149,7 @@ namespace Lumos ImGui::PushStyleColor(ImGuiCol_Text, ImGuiUtilities::GetIconColour()); // ImGui::BeginGroup(); - bool nodeOpen = ImGui::TreeNodeEx((void*)(intptr_t)entt::to_integral(node), nodeFlags, (const char*)icon.str); + bool nodeOpen = ImGui::TreeNodeEx((void*)(intptr_t)entt::to_integral(node), nodeFlags, "%s", (const char*)icon.str); { if(ImGui::BeginDragDropSource()) { @@ -265,7 +265,7 @@ namespace Lumos if(ImGui::Selectable("Cut")) { for(auto entity : m_Editor->GetSelected()) - m_Editor->SetCopiedEntity(node, true); + m_Editor->SetCopiedEntity(entity, true); } if(m_Editor->GetCopiedEntity().size() > 0 && registry.valid(m_Editor->GetCopiedEntity().front())) @@ -530,97 +530,102 @@ namespace Lumos auto AddEntity = [scene]() { - if(ImGui::Selectable("Add Empty Entity")) + if(ImGui::BeginMenu("Add")) { - scene->CreateEntity(); - } - - if(ImGui::Selectable("Add Light")) - { - auto entity = scene->CreateEntity("Light"); - entity.AddComponent(); - entity.GetOrAddComponent(); - } - - if(ImGui::Selectable("Add Rigid Body")) - { - auto entity = scene->CreateEntity("RigidBody"); - entity.AddComponent(); - entity.GetOrAddComponent(); - entity.AddComponent(entity, Axes::XZ); - entity.GetComponent().GetRigidBody()->SetCollisionShape(CollisionShapeType::CollisionCuboid); - } - - if(ImGui::Selectable("Add Camera")) - { - auto entity = scene->CreateEntity("Camera"); - entity.AddComponent(); - entity.GetOrAddComponent(); - } - if(ImGui::Selectable("Add Sprite")) - { - auto entity = scene->CreateEntity("Sprite"); - entity.AddComponent(); - entity.GetOrAddComponent(); - } - - if(ImGui::Selectable("Add Lua Script")) - { - auto entity = scene->CreateEntity("LuaScript"); - entity.AddComponent(); - } - - if(ImGui::BeginMenu("Add Primitive")) - { - - if(ImGui::MenuItem("Cube")) + if(ImGui::Selectable("Empty Entity")) { - auto entity = scene->CreateEntity("Cube"); - entity.AddComponent(Graphics::PrimitiveType::Cube); + scene->CreateEntity(); } - if(ImGui::MenuItem("Sphere")) + if(ImGui::Selectable("Light")) { - auto entity = scene->CreateEntity("Sphere"); - entity.AddComponent(Graphics::PrimitiveType::Sphere); + auto entity = scene->CreateEntity("Light"); + entity.AddComponent(); + entity.GetOrAddComponent(); } - if(ImGui::MenuItem("Pyramid")) + if(ImGui::Selectable("Rigid Body")) { - auto entity = scene->CreateEntity("Pyramid"); - entity.AddComponent(Graphics::PrimitiveType::Pyramid); + auto entity = scene->CreateEntity("RigidBody"); + entity.AddComponent(); + entity.GetOrAddComponent(); + entity.AddComponent(entity, Axes::XZ); + entity.GetComponent().GetRigidBody()->SetCollisionShape(CollisionShapeType::CollisionCuboid); } - if(ImGui::MenuItem("Plane")) + if(ImGui::Selectable("Camera")) { - auto entity = scene->CreateEntity("Plane"); - entity.AddComponent(Graphics::PrimitiveType::Plane); + auto entity = scene->CreateEntity("Camera"); + entity.AddComponent(); + entity.GetOrAddComponent(); } - if(ImGui::MenuItem("Cylinder")) + if(ImGui::Selectable("Sprite")) { - auto entity = scene->CreateEntity("Cylinder"); - entity.AddComponent(Graphics::PrimitiveType::Cylinder); + auto entity = scene->CreateEntity("Sprite"); + entity.AddComponent(); + entity.GetOrAddComponent(); } - if(ImGui::MenuItem("Capsule")) + if(ImGui::Selectable("Lua Script")) { - auto entity = scene->CreateEntity("Capsule"); - entity.AddComponent(Graphics::PrimitiveType::Capsule); + auto entity = scene->CreateEntity("LuaScript"); + entity.AddComponent(); } - if(ImGui::MenuItem("Terrain")) + if(ImGui::BeginMenu("Primitive")) { - auto entity = scene->CreateEntity("Terrain"); - entity.AddComponent(Graphics::PrimitiveType::Terrain); - } - if(ImGui::MenuItem("Light Cube")) - { - EntityFactory::AddLightCube(Application::Get().GetSceneManager()->GetCurrentScene(), glm::vec3(0.0f), glm::vec3(0.0f)); - } + if(ImGui::MenuItem("Cube")) + { + auto entity = scene->CreateEntity("Cube"); + entity.AddComponent(Graphics::PrimitiveType::Cube); + } + if(ImGui::MenuItem("Sphere")) + { + auto entity = scene->CreateEntity("Sphere"); + entity.AddComponent(Graphics::PrimitiveType::Sphere); + } + + if(ImGui::MenuItem("Pyramid")) + { + auto entity = scene->CreateEntity("Pyramid"); + entity.AddComponent(Graphics::PrimitiveType::Pyramid); + } + + if(ImGui::MenuItem("Plane")) + { + auto entity = scene->CreateEntity("Plane"); + entity.AddComponent(Graphics::PrimitiveType::Plane); + } + + if(ImGui::MenuItem("Cylinder")) + { + auto entity = scene->CreateEntity("Cylinder"); + entity.AddComponent(Graphics::PrimitiveType::Cylinder); + } + + if(ImGui::MenuItem("Capsule")) + { + auto entity = scene->CreateEntity("Capsule"); + entity.AddComponent(Graphics::PrimitiveType::Capsule); + } + + if(ImGui::MenuItem("Terrain")) + { + auto entity = scene->CreateEntity("Terrain"); + entity.AddComponent(Graphics::PrimitiveType::Terrain); + } + + if(ImGui::MenuItem("Light Cube")) + { + EntityFactory::AddLightCube(Application::Get().GetSceneManager()->GetCurrentScene(), glm::vec3(0.0f), glm::vec3(0.0f)); + } + + ImGui::EndMenu(); + } ImGui::EndMenu(); } }; diff --git a/Editor/Source/InspectorPanel.cpp b/Editor/Source/InspectorPanel.cpp index bb9e9ff9..a0c518c9 100644 --- a/Editor/Source/InspectorPanel.cpp +++ b/Editor/Source/InspectorPanel.cpp @@ -36,6 +36,7 @@ #include #include #include +// #include #include #include @@ -223,6 +224,13 @@ end ImGui::Columns(1); ImGui::Separator(); + + if (ImGui::Button("Copy Editor Camera Transforn", ImVec2(ImGui::GetContentRegionAvail().x, 0.0f))) + { + Lumos::Application* app = &Lumos::Editor::Get(); + glm::mat4 cameraTransform = ((Lumos::Editor*)app)->GetEditorCameraTransform().GetWorldMatrix(); + transform.SetLocalTransform(cameraTransform); + } } static void CuboidCollisionShapeInspector(Lumos::CuboidCollisionShape* shape, const Lumos::RigidBody3DComponent& phys) @@ -310,6 +318,12 @@ end ImGui::TextUnformatted("Hull Collision Shape"); ImGui::NextColumn(); ImGui::PushItemWidth(-1); + + if (ImGui::Button("Generate Collider")) + { + auto test = Lumos::SharedPtr(Lumos::Graphics::CreatePrimative(Lumos::Graphics::PrimitiveType::Cube)); + shape->BuildFromMesh(test.get()); + } } std::string CollisionShape2DTypeToString(Lumos::Shape shape) @@ -387,7 +401,7 @@ end { using namespace Lumos; LUMOS_PROFILE_FUNCTION(); - ImGuiUtilities::ScopedStyle(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); + ImGuiUtilities::ScopedStyle frameStyle(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); ImGui::Columns(2); ImGui::Separator(); @@ -406,6 +420,19 @@ end ImGui::TextUnformatted("Entity"); ImGui::NextColumn(); ImGui::Text("%s", name.c_str()); + + if(ImGui::BeginDragDropTarget()) + { + const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("Drag_Entity"); + if(payload) + { + size_t count = payload->DataSize / sizeof(entt::entity); + entt::entity droppedEntityID = *(((entt::entity*)payload->Data)); + axisConstraintComponent.SetEntity(Entity(droppedEntityID, Application::Get().GetCurrentScene()).GetID()); + } + ImGui::EndDragDropTarget(); + } + ImGui::NextColumn(); std::vector entities; @@ -516,7 +543,7 @@ end int index = 0; for(auto& shape : shapes) { - if(shape == shape_current) + if(strcmp(shape, shape_current) == 0) { selectedIndex = index; break; @@ -800,7 +827,7 @@ end LUMOS_PROFILE_FUNCTION(); auto& camera = reg.get(e); - Lumos::ImGuiUtilities::ScopedStyle(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); + Lumos::ImGuiUtilities::ScopedStyle frameStyle(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); ImGui::Columns(2); ImGui::Separator(); @@ -1101,7 +1128,7 @@ end // Drop directly on to node and append to the end of it's children list. if(ImGui::AcceptDragDropPayload("Font")) { - Application::Get().GetFontLibrary()->Load(filePath, text.FontHandle); + Application::Get().GetAssetManager()->AddAsset(filePath, text.FontHandle); ImGui::EndDragDropTarget(); ImGui::Columns(1); @@ -2042,7 +2069,7 @@ end std::stringstream storage; cereal::JSONOutputArchive output { storage }; - material->save(output); + // Lumos::save(output, *material.get()); FileSystem::WriteTextFile(physicalPath, storage.str()); } @@ -2407,12 +2434,12 @@ end emitter.SetBlendType((Lumos::ParticleEmitter::BlendType)selectedIndex); Lumos::ParticleEmitter::AlignedType alignType = emitter.GetAlignedType(); - static const char* possibleAlignTypes[3] = { "2D", "3D", "Off" }; + static const char* possibleAlignTypes[3] = { "2D", "3D", "Off" }; int selectedIndexAlign = (int)alignType; updated = Lumos::ImGuiUtilities::PropertyDropdown("Align Type", possibleAlignTypes, 3, &selectedIndexAlign); - if (updated) + if(updated) emitter.SetAlignedType((Lumos::ParticleEmitter::AlignedType)selectedIndexAlign); PropertySet("Is Animated", emitter.GetIsAnimated, emitter.SetIsAnimated); diff --git a/Editor/Source/ProjectSettingsPanel.cpp b/Editor/Source/ProjectSettingsPanel.cpp index 9dd2f59e..7b140981 100644 --- a/Editor/Source/ProjectSettingsPanel.cpp +++ b/Editor/Source/ProjectSettingsPanel.cpp @@ -19,7 +19,7 @@ namespace Lumos ImGuiUtilities::PushID(); ImGui::Columns(2); - Lumos::ImGuiUtilities::ScopedStyle(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); + Lumos::ImGuiUtilities::ScopedStyle frameStyle(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); { auto& projectSettings = Application::Get().GetProjectSettings(); diff --git a/Editor/Source/ResourcePanel.cpp b/Editor/Source/ResourcePanel.cpp index 6ac08da7..64667144 100644 --- a/Editor/Source/ResourcePanel.cpp +++ b/Editor/Source/ResourcePanel.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef LUMOS_PLATFORM_WINDOWS #include @@ -99,7 +100,7 @@ namespace Lumos m_Name = ICON_MDI_FOLDER_STAR " Resources###resources"; m_SimpleName = "Resources"; - m_Arena = ArenaAlloc(Kilobytes(64)); + m_Arena = ArenaAlloc(Megabytes(8)); #ifdef LUMOS_PLATFORM_WINDOWS m_Delimiter = Str8Lit("\\"); #else @@ -198,8 +199,8 @@ namespace Lumos directoryInfo->Path = m_BasePath; else directoryInfo->Path = directoryPath; + directoryInfo->Path = directoryPath; - directoryInfo->Path = directoryPath; String8 extension = StringUtilities::Str8PathSkipLastPeriod(directoryInfo->Path); directoryInfo->FileTypeID = GetParsedAssetID(extension); @@ -245,6 +246,9 @@ namespace Lumos directoryInfo->Opened = true; directoryInfo->Leaf = true; + String8 pathCopy = PushStr8Copy(m_Arena, directoryPath); + directoryInfo->AssetPath = StringUtilities::AbsolutePathToRelativeFileSystemPath(m_Arena, pathCopy, m_BasePath, Str8Lit("//Assets")); + ImVec4 fileTypeColor = { 1.0f, 1.0f, 1.0f, 1.0f }; const auto& fileTypeColorIt = s_TypeColors.find(fileType); if(fileTypeColorIt != s_TypeColors.end()) @@ -271,25 +275,6 @@ namespace Lumos const float SmallOffsetX = 6.0f * Application::Get().GetWindowDPI(); ImDrawList* drawList = ImGui::GetWindowDrawList(); - if(ImGui::IsWindowFocused() && (Input::Get().GetKeyHeld(InputCode::Key::LeftSuper) || Input::Get().GetKeyHeld(InputCode::Key::LeftControl))) - { - float mouseScroll = Input::Get().GetScrollOffset(); - - if(m_IsInListView) - { - if(mouseScroll > 0) - m_IsInListView = false; - } - else - { - m_GridSize += mouseScroll; - if(m_GridSize < MinGridSize) - m_IsInListView = true; - } - - m_GridSize = Maths::Clamp(m_GridSize, MinGridSize, MaxGridSize); - } - if(!dirInfo->IsFile) { if(dirInfo->Leaf) @@ -367,7 +352,6 @@ namespace Lumos { LUMOS_PROFILE_FUNCTION(); - m_TextureLibrary.Update((float)Engine::Get().GetTimeStep().GetElapsedSeconds()); if(ImGui::Begin(m_Name.c_str(), &m_Active)) { FileIndex = 0; @@ -614,6 +598,28 @@ namespace Lumos if(ImGui::BeginTable("BodyTable", columnCount, flags)) { + if(ImGui::IsItemHovered() && (Input::Get().GetKeyHeld(InputCode::Key::LeftSuper) || Input::Get().GetKeyHeld(InputCode::Key::LeftControl))) + { + float mouseScroll = Input::Get().GetScrollOffset(); + + if(m_IsInListView) + { + if(mouseScroll > 0) + m_IsInListView = false; + } + else + { + m_GridSize += mouseScroll; + if(m_GridSize < MinGridSize) + m_IsInListView = true; + } + + LUMOS_LOG_INFO("changing icon size {0}", m_GridSize); + + m_GridSize = Maths::Clamp(m_GridSize, MinGridSize, MaxGridSize); + } + + m_GridItemsPerRow = (int)floor(xAvail / (m_GridSize + ImGui::GetStyle().ItemSpacing.x)); m_GridItemsPerRow = Maths::Max(1, m_GridItemsPerRow); @@ -811,9 +817,13 @@ namespace Lumos } else if(!textureCreated) { - textureCreated = true; - CurrentEnty->Thumbnail = m_TextureLibrary.GetResource(std::string((const char*)CurrentEnty->Path.str, CurrentEnty->Path.size)); - textureId = CurrentEnty->Thumbnail ? CurrentEnty->Thumbnail : m_FileIcon; + textureCreated = true; + + if(!m_Editor->GetAssetManager()->AssetExists(std::string((const char*)CurrentEnty->AssetPath.str, CurrentEnty->AssetPath.size))) + CurrentEnty->Thumbnail = m_Editor->GetAssetManager()->LoadTextureAsset(std::string((const char*)CurrentEnty->AssetPath.str, CurrentEnty->AssetPath.size), true); + else + CurrentEnty->Thumbnail = m_Editor->GetAssetManager()->GetAssetData(std::string((const char*)CurrentEnty->AssetPath.str, CurrentEnty->AssetPath.size)).As(); + textureId = CurrentEnty->Thumbnail ? CurrentEnty->Thumbnail : m_FileIcon; } else { @@ -830,13 +840,18 @@ namespace Lumos { ArenaTemp scratch = ArenaTempBegin(m_Arena); - String8 sceneScreenShotPath = PushStr8F(scratch.arena, "%s/Scenes/Cache/%s.png", m_BasePath.str, CurrentEnty->Path); - // auto sceneScreenShotPath = m_BasePath + "/Scenes/Cache/" + CurrentEnty->FilePath.stem().string() + ".png"; + String8 fileName = PushStr8Copy(scratch.arena, StringUtilities::GetFileName(CurrentEnty->Path)); + String8 sceneScreenShotPath = PushStr8F(scratch.arena, "%s/Scenes/Cache/%s.png", m_BasePath.str, fileName.str); if(std::filesystem::exists(std::filesystem::path(std::string((const char*)sceneScreenShotPath.str, sceneScreenShotPath.size)))) { - textureCreated = true; - CurrentEnty->Thumbnail = m_TextureLibrary.GetResource(std::string((const char*)sceneScreenShotPath.str, sceneScreenShotPath.size)); - textureId = CurrentEnty->Thumbnail ? CurrentEnty->Thumbnail : m_FileIcon; + textureCreated = true; + String8 sceneScreenShotAssetPath = PushStr8F(scratch.arena, "%s/Scenes/Cache/%s.png", Str8Lit("//Assets").str, fileName.str); + + if(!m_Editor->GetAssetManager()->AssetExists(std::string((const char*)sceneScreenShotAssetPath.str, sceneScreenShotAssetPath.size))) + CurrentEnty->Thumbnail = m_Editor->GetAssetManager()->LoadTextureAsset(std::string((const char*)sceneScreenShotAssetPath.str, sceneScreenShotAssetPath.size), true); + else + CurrentEnty->Thumbnail = m_Editor->GetAssetManager()->GetAssetData(std::string((const char*)sceneScreenShotAssetPath.str, sceneScreenShotAssetPath.size)).As(); + textureId = CurrentEnty->Thumbnail ? CurrentEnty->Thumbnail : m_FileIcon; } else textureId = m_FileIcon; @@ -909,6 +924,8 @@ namespace Lumos QueueRefresh(); } + ImGui::Separator(); + if(ImGui::Selectable("Open Location")) { auto fullPath = m_CurrentDir->Children[dirIndex]->Path; @@ -921,6 +938,16 @@ namespace Lumos Lumos::OS::Instance()->OpenFileExternal(std::string((const char*)fullPath.str, fullPath.size)); } + if (ImGui::Selectable("Copy Full Path")) + { + ImGui::SetClipboardText((const char*)m_CurrentDir->Children[dirIndex]->Path.str); + } + + if (m_CurrentDir->Children[dirIndex]->IsFile && ImGui::Selectable("Copy Asset Path")) + { + ImGui::SetClipboardText((const char*)ToStdString(m_CurrentDir->Children[dirIndex]->AssetPath).c_str()); + } + ImGui::Separator(); if(ImGui::Selectable("Import New Asset")) @@ -958,11 +985,13 @@ namespace Lumos ImGui::TextUnformatted(m_Editor->GetIconFontIcon(ToStdString(m_CurrentDir->Children[dirIndex]->Path))); ImGui::SameLine(); - m_MovePath = m_CurrentDir->Children[dirIndex]->Path; - ImGui::TextUnformatted((const char*)m_MovePath.str); + m_MovePath = m_CurrentDir->Children[dirIndex]->Path; + String8 resolvedPath = StringUtilities::AbsolutePathToRelativeFileSystemPath(m_Arena, m_MovePath, m_BasePath, Str8Lit("//Assets")); - size_t size = sizeof(const char*) + m_MovePath.size; - ImGui::SetDragDropPayload("AssetFile", m_MovePath.str, size); + ImGui::TextUnformatted((const char*)resolvedPath.str); + + size_t size = sizeof(const char*) + resolvedPath.size; + ImGui::SetDragDropPayload("AssetFile", resolvedPath.str, size); m_IsDragging = true; ImGui::EndDragDropSource(); } @@ -1007,7 +1036,7 @@ namespace Lumos ImGui::TextUnformatted((const char*)(fileTypeString).str); ImGui::Unindent(); cursorPos = ImGui::GetCursorPos(); - ImGui::SetCursorPos({ cursorPos.x + padding * (float)m_Editor->GetWindow()->GetDPIScale(), cursorPos.y - (ImGui::GetIO().Fonts->Fonts[2]->FontSize * 0.6f - padding * (float)m_Editor->GetWindow()->GetDPIScale()) }); + ImGui::SetCursorPos({ cursorPos.x + padding * (float)m_Editor->GetWindow()->GetDPIScale(), cursorPos.y - (ImGui::GetIO().Fonts->Fonts[2]->FontSize * 0.8f - padding * (float)m_Editor->GetWindow()->GetDPIScale()) }); ImGui::Indent(); ImGui::TextUnformatted((const char*)CurrentEnty->FileSizeString.str); ImGui::Unindent(); @@ -1036,7 +1065,7 @@ namespace Lumos ImGui::SameLine(); m_MovePath = m_CurrentDir->Children[dirIndex]->Path; - ImGui::TextUnformatted((const char*)m_MovePath.str); + ImGui::TextUnformatted((const char*)ToStdString(m_MovePath).c_str()); size_t size = sizeof(const char*) + m_MovePath.size; ImGui::SetDragDropPayload("AssetFile", m_MovePath.str, size); @@ -1079,10 +1108,8 @@ namespace Lumos void ResourcePanel::Refresh() { - m_TextureLibrary.Destroy(); - - Arena* temp = ArenaAlloc(256); - String8 currentPath = PushStr8Copy(temp, m_CurrentDir->Path); + ArenaTemp temp = ScratchBegin(&m_Arena, 1); + String8 currentPath = PushStr8Copy(temp.arena, m_CurrentDir->Path); ArenaClear(m_Arena); m_Directories.clear(); @@ -1111,6 +1138,6 @@ namespace Lumos if(!dirFound) ChangeDirectory(m_BaseProjectDir); - ArenaRelease(temp); + ScratchEnd(temp); } } diff --git a/Editor/Source/ResourcePanel.h b/Editor/Source/ResourcePanel.h index b7fca98f..2687e2fe 100644 --- a/Editor/Source/ResourcePanel.h +++ b/Editor/Source/ResourcePanel.h @@ -38,6 +38,7 @@ namespace Lumos bool Opened = false; bool Leaf = true; + String8 AssetPath; String8 Path; SharedPtr Thumbnail = nullptr; FileType Type; @@ -66,7 +67,6 @@ namespace Lumos ResourcePanel(); ~ResourcePanel() { - m_TextureLibrary.Destroy(); ArenaRelease(m_Arena); } @@ -94,7 +94,6 @@ namespace Lumos m_NextDirectory.reset(); m_PreviousDirectory.reset(); m_BreadCrumbData.clear(); - m_TextureLibrary.Destroy(); } int GetParsedAssetID(String8 extension) @@ -187,8 +186,6 @@ namespace Lumos SharedPtr m_CurrentSelected; - Lumos::TextureLibrary m_TextureLibrary; - String8 m_CopiedPath; bool m_CutFile = false; diff --git a/Editor/Source/SceneSettingsPanel.cpp b/Editor/Source/SceneSettingsPanel.cpp index 004d026d..11d7b485 100644 --- a/Editor/Source/SceneSettingsPanel.cpp +++ b/Editor/Source/SceneSettingsPanel.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace Lumos { @@ -23,7 +24,7 @@ namespace Lumos if(ImGui::Begin(m_Name.c_str(), &m_Active, 0)) { - Lumos::ImGuiUtilities::ScopedStyle(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); + Lumos::ImGuiUtilities::ScopedStyle frameStyle(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); Lumos::ImGuiUtilities::PushID(); { const auto& sceneName = m_CurrentScene->GetSceneName(); @@ -133,7 +134,7 @@ namespace Lumos ImGui::TreePop(); } - ImGui::BeginDisabled(); + // ImGui::BeginDisabled(); open = postprocessSetting("SSAO", "##SSAO", sceneSettings.RenderSettings.SSAOEnabled, false); if(open) { @@ -144,7 +145,7 @@ namespace Lumos ImGui::TreePop(); } - ImGui::EndDisabled(); + // ImGui::EndDisabled(); ImGui::Columns(1); ImGui::TreePop(); } @@ -164,6 +165,65 @@ namespace Lumos ImGuiUtilities::Property("Brightness", sceneSettings.RenderSettings.Brightness, -1.0f, 1.0f, 0.01f); ImGuiUtilities::Property("Contrast", sceneSettings.RenderSettings.Contrast, 0.0f, 2.0f, 0.01f); ImGuiUtilities::Property("Saturation", sceneSettings.RenderSettings.Saturation, 0.0f, 1.0f, 0.01f); + + int32_t maxSupportedSampleCount = Lumos::Graphics::Renderer::GetCapabilities().MaxSamples; + uint8_t cachedValue = sceneSettings.RenderSettings.MSAASamples; + static const char* msaaValues[4] = + { + "1", + "2", + "4", + "8" + }; + int index = 0; + switch(cachedValue) + { + case 1: + index = 0; + break; + case 2: + index = 1; + break; + case 4: + index = 2; + break; + case 8: + index = 3; + break; + } + + uint8_t choiceCount = 4; + if (maxSupportedSampleCount < 2) + choiceCount = 1; + else if (maxSupportedSampleCount < 4) + choiceCount = 2; + else if (maxSupportedSampleCount < 8) + choiceCount = 3; + + ImGuiUtilities::PropertyDropdown("MSAA Samples", msaaValues, choiceCount, &index); + switch(index) + { + case 0: + sceneSettings.RenderSettings.MSAASamples = 1; + break; + case 1: + sceneSettings.RenderSettings.MSAASamples = 2; + break; + case 2: + sceneSettings.RenderSettings.MSAASamples = 4; + break; + case 3: + sceneSettings.RenderSettings.MSAASamples = 8; + break; + } + + +// if(sceneSettings.RenderSettings.MSAASamples > cachedValue) +// sceneSettings.RenderSettings.MSAASamples = Maths::NextPowerOfTwo(sceneSettings.RenderSettings.MSAASamples); +// else if (sceneSettings.RenderSettings.MSAASamples < cachedValue) +// sceneSettings.RenderSettings.MSAASamples = sceneSettings.RenderSettings.MSAASamples / 2U; +// sceneSettings.RenderSettings.MSAASamples = Maths::Clamp(sceneSettings.RenderSettings.MSAASamples, (uint8_t)1, (uint8_t)8); + ImGui::Separator(); auto& registry = m_CurrentScene->GetRegistry(); diff --git a/Editor/Source/SceneViewPanel.cpp b/Editor/Source/SceneViewPanel.cpp index 5db69383..58e3486b 100644 --- a/Editor/Source/SceneViewPanel.cpp +++ b/Editor/Source/SceneViewPanel.cpp @@ -38,8 +38,8 @@ namespace Lumos m_ShowComponentGizmoMap[typeid(Camera).hash_code()] = true; m_ShowComponentGizmoMap[typeid(SoundComponent).hash_code()] = true; - m_Width = 1280; - m_Height = 800; + m_Width = 800; + m_Height = 600; Application::Get().GetRenderPasses()->SetDisablePostProcess(false); } @@ -81,7 +81,7 @@ namespace Lumos offset = ImGui::GetCursorPos(); // Usually ImVec2(0.0f, 50.0f); } - if(!camera) + if(!camera || !transform) { ImGui::End(); return; @@ -586,6 +586,10 @@ namespace Lumos LUMOS_ASSERT(width > 0 && height > 0, "Scene View Dimensions 0"); + const QualitySettings& qs = Application::Get().GetQualitySettings(); + width *= qs.RendererScale; + height *= qs.RendererScale; + Application::Get().SetSceneViewDimensions(width, height); if(m_Width != width || m_Height != height) diff --git a/Editor/Source/TextEditPanel.cpp b/Editor/Source/TextEditPanel.cpp index 9dcfdcb1..4eaf2dd3 100644 --- a/Editor/Source/TextEditPanel.cpp +++ b/Editor/Source/TextEditPanel.cpp @@ -9,12 +9,15 @@ namespace Lumos { + static bool JustOpenedFile = false; TextEditPanel::TextEditPanel(const std::string& filePath) : m_FilePath(filePath) { m_Name = "Text Editor###textEdit"; + m_ChangedName = "Text Editor *###textEdit"; m_SimpleName = "TextEdit"; m_OnSaveCallback = NULL; + m_TextUnsaved = false; editor.SetCustomIdentifiers({}); auto extension = StringUtilities::GetFilePathExtension(m_FilePath); @@ -50,27 +53,20 @@ namespace Lumos auto string = FileSystem::ReadTextFile(m_FilePath); editor.SetText(string); editor.SetShowWhitespaces(false); + JustOpenedFile = true; } - void TextEditPanel::SetErrors(const std::map& errors) + void TextEditPanel::SetErrors(const std::unordered_map& errors) { editor.SetErrorMarkers(errors); } void TextEditPanel::OnImGui() { - if((Input::Get().GetKeyHeld(InputCode::Key::LeftSuper) || (Input::Get().GetKeyHeld(InputCode::Key::LeftControl)))) - { - if(Input::Get().GetKeyPressed(InputCode::Key::S)) - { - auto textToSave = editor.GetText(); - FileSystem::WriteTextFile(m_FilePath, textToSave); - } - } - auto cpos = editor.GetCursorPosition(); ImGui::SetWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver); - if(ImGui::Begin(m_Name.c_str(), &m_Active, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_MenuBar)) + std::string& windowName = m_TextUnsaved ? m_ChangedName : m_Name; + if(ImGui::Begin(windowName.c_str(), &m_Active, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_MenuBar)) { if(ImGui::BeginMenuBar()) { @@ -82,6 +78,8 @@ namespace Lumos FileSystem::WriteTextFile(m_FilePath, textToSave); if(m_OnSaveCallback) m_OnSaveCallback(); + + m_TextUnsaved = false; } ImGui::EndMenu(); } @@ -140,16 +138,24 @@ namespace Lumos ImGui::Text("%6d/%-6d %6d lines | %s | %s | %s | %s", cpos.mLine + 1, cpos.mColumn + 1, editor.GetTotalLines(), editor.IsOverwrite() ? "Ovr" : "Ins", editor.CanUndo() ? "*" : " ", editor.GetLanguageDefinition().mName.c_str(), Lumos::StringUtilities::GetFileName(m_FilePath).c_str()); - if(ImGui::IsItemActive()) + if(editor.IsTextChanged() && !JustOpenedFile) + m_TextUnsaved = true; + + editor.Render(m_Name.c_str()); + + if(ImGui::IsWindowFocused(ImGuiHoveredFlags_ChildWindows)) { - if(Input::Get().GetKeyHeld(InputCode::Key::LeftControl) && Input::Get().GetKeyPressed(InputCode::Key::S)) + if((Input::Get().GetKeyHeld(InputCode::Key::LeftSuper) || Input::Get().GetKeyHeld(InputCode::Key::LeftControl)) && Input::Get().GetKeyPressed(InputCode::Key::S)) { auto textToSave = editor.GetText(); FileSystem::WriteTextFile(m_FilePath, textToSave); + if(m_OnSaveCallback) + m_OnSaveCallback(); + + m_TextUnsaved = false; } } - - editor.Render(m_Name.c_str()); + JustOpenedFile = false; } ImGui::End(); } diff --git a/Editor/Source/TextEditPanel.h b/Editor/Source/TextEditPanel.h index 19c2806c..45a6a8db 100644 --- a/Editor/Source/TextEditPanel.h +++ b/Editor/Source/TextEditPanel.h @@ -15,11 +15,15 @@ namespace Lumos void OnClose(); void SetOnSaveCallback(const std::function& callback) { m_OnSaveCallback = callback; } - void SetErrors(const std::map& errors); + void SetErrors(const std::unordered_map& errors); private: std::string m_FilePath; TextEditor editor; std::function m_OnSaveCallback; + + bool m_TextUnsaved = false; + + float m_SavedTimer = -1.0f; }; } diff --git a/ExampleProject/AssetRegistry.lmar b/ExampleProject/AssetRegistry.lmar new file mode 100644 index 00000000..f4d6eae2 --- /dev/null +++ b/ExampleProject/AssetRegistry.lmar @@ -0,0 +1,138 @@ +{ + "value0": { + "Version": 2, + "Count": 44, + "Name": "CreateEnvironmentMap", + "UUID": 498697334553651981, + "AssetType": 6, + "Name": "//Assets/Textures/texture.jpg", + "UUID": 538415633353194237, + "AssetType": 1, + "Name": "Batch2D", + "UUID": 813680964025412095, + "AssetType": 6, + "Name": "EnvironmentIrradiance", + "UUID": 960524816459447479, + "AssetType": 6, + "Name": "SSAO", + "UUID": 1095354547157039442, + "AssetType": 6, + "Name": "//Assets/Textures/particle_dust.png", + "UUID": 1123372390369367885, + "AssetType": 1, + "Name": "//Assets/Textures/icon32.png", + "UUID": 1169913861966067682, + "AssetType": 1, + "Name": "//Assets/Textures/cat.png", + "UUID": 1488776720534277604, + "AssetType": 1, + "Name": "EnvironmentMipFilter", + "UUID": 1675502722393171918, + "AssetType": 6, + "Name": "Batch2DLine", + "UUID": 2094088944344111971, + "AssetType": 6, + "Name": "FXAA", + "UUID": 2145168222577851814, + "AssetType": 6, + "Name": "BRDFLUT", + "UUID": 2216550627408006547, + "AssetType": 6, + "Name": "Debanding", + "UUID": 2495998898540605538, + "AssetType": 6, + "Name": "//Assets/Textures/checkerboard.tga", + "UUID": 2626531592178374404, + "AssetType": 1, + "Name": "//Assets/Textures/PreintegratedFG.tga", + "UUID": 3011559381961549495, + "AssetType": 1, + "Name": "ForwardPBR", + "UUID": 3031085133988255604, + "AssetType": 6, + "Name": "//Assets/Meshes/Scene/scene.gltf", + "UUID": 3853544921239423074, + "AssetType": 9, + "Name": "DepthPrePass", + "UUID": 4415649574143950547, + "AssetType": 6, + "Name": "//Assets/Textures/splash.png", + "UUID": 6567856788857401421, + "AssetType": 1, + "Name": "//Assets/Meshes/lowpoly_bonfire/scene.gltf", + "UUID": 7027018599794543603, + "AssetType": 9, + "Name": "ChromaticAberation", + "UUID": 7375714513771862660, + "AssetType": 6, + "Name": "//Assets/Textures/panda.png", + "UUID": 7920548566536714046, + "AssetType": 1, + "Name": "Shadow", + "UUID": 8301062219737337799, + "AssetType": 6, + "Name": "Bloom", + "UUID": 9292640677943495227, + "AssetType": 6, + "Name": "DepthPrePassAlpha", + "UUID": 9648507851302580497, + "AssetType": 6, + "Name": "Sharpen", + "UUID": 9688744856235066537, + "AssetType": 6, + "Name": "Particle", + "UUID": 10078180836416861066, + "AssetType": 6, + "Name": "//Assets/Textures/icon.png", + "UUID": 10374144327092108136, + "AssetType": 1, + "Name": "DepthOfField", + "UUID": 10557890345575391864, + "AssetType": 6, + "Name": "//Assets/Textures/round_outline.png", + "UUID": 11126978127519170907, + "AssetType": 1, + "Name": "Skybox", + "UUID": 12471848509347416176, + "AssetType": 6, + "Name": "//Assets/Textures/Fire1.png", + "UUID": 12511953359682328681, + "AssetType": 1, + "Name": "Text", + "UUID": 12642754105454942372, + "AssetType": 6, + "Name": "//Assets/Meshes/DamagedHelmet/glTF/DamagedHelmet.gltf", + "UUID": 13579337366301463653, + "AssetType": 9, + "Name": "//Assets/Textures/fire.png", + "UUID": 13831315025881660061, + "AssetType": 1, + "Name": "SSAOBlur", + "UUID": 13910922921860105132, + "AssetType": 6, + "Name": "FinalPass", + "UUID": 14113443814160806123, + "AssetType": 6, + "Name": "Batch2DPoint", + "UUID": 14671482827884459882, + "AssetType": 6, + "Name": "ToneMapping", + "UUID": 15576366496581061081, + "AssetType": 6, + "Name": "FilmicGrain", + "UUID": 15993984468914870617, + "AssetType": 6, + "Name": "//Assets/Textures/backgroundColorGrass.png", + "UUID": 16838368057738779843, + "AssetType": 1, + "Name": "Grid", + "UUID": 17174639512606516617, + "AssetType": 6, + "Name": "//Assets/Textures/Charactervector.png", + "UUID": 17504220957207961491, + "AssetType": 1, + "Name": "ShadowAlpha", + "UUID": 18088774006192505129, + "AssetType": 6 + } +} \ No newline at end of file diff --git a/ExampleProject/Assets/Scenes/Cache/2D.png b/ExampleProject/Assets/Scenes/Cache/2D.png new file mode 100644 index 00000000..1f508687 Binary files /dev/null and b/ExampleProject/Assets/Scenes/Cache/2D.png differ diff --git a/ExampleProject/Assets/Scenes/Cache/Physics.png b/ExampleProject/Assets/Scenes/Cache/Physics.png new file mode 100644 index 00000000..74462b41 Binary files /dev/null and b/ExampleProject/Assets/Scenes/Cache/Physics.png differ diff --git a/ExampleProject/Assets/Scenes/Sandbox.lsn b/ExampleProject/Assets/Scenes/Sandbox.lsn index 10fb03f8..a6a2c23a 100644 --- a/ExampleProject/Assets/Scenes/Sandbox.lsn +++ b/ExampleProject/Assets/Scenes/Sandbox.lsn @@ -1,6 +1,6 @@ { "value0": { - "Version": 17, + "Version": 23, "Scene Name": "Sandbox", "PhysicsEnabled2D": true, "PhysicsEnabled3D": true, @@ -16,12 +16,12 @@ "BloomKnee": 0.10000000149011612, "BloomThreshold": 1.0, "BloomUpsampleScale": 1.0, - "FXAAEnabled": true, - "DebandingEnabled": true, + "FXAAEnabled": false, + "DebandingEnabled": false, "ChromaticAberationEnabled": false, "EyeAdaptation": true, - "SSAOEnabled": true, - "BloomEnabled": true, + "SSAOEnabled": false, + "BloomEnabled": false, "FilmicGrainEnabled": false, "DepthOfFieldEnabled": false, "MotionBlurEnabled": false, @@ -30,36 +30,38 @@ "DepthOfFieldDistance": 100.0, "value0": 0.0, "value1": 1.0, - "value2": 1.0 + "value2": 1.0, + "value3": false }, "value1": 5, - "value2": 2097151, - "value3": 1, - "value4": 2, - "value5": 3, - "value6": 4, - "value7": 2, - "value8": 1, - "value9": { + "value2": 5, + "value3": 0, + "value4": 1, + "value5": 2, + "value6": 3, + "value7": 1048580, + "value8": 3, + "value9": 1048580, + "value10": { "Position": { "value0": 0.0, "value1": 0.0, "value2": 0.0 }, "Rotation": { - "value0": -0.32251736521720889, - "value1": 0.2442595511674881, - "value2": -0.08653092384338379, - "value3": 0.9104021787643433 + "value0": 0.0, + "value1": 0.0, + "value2": 0.0, + "value3": 1.0 }, "Scale": { - "value0": 1.0000011920928956, - "value1": 1.0000061988830567, - "value2": 1.0000035762786866 + "value0": 1.0, + "value1": 1.0, + "value2": 1.0 } }, - "value10": 2, - "value11": { + "value11": 2, + "value12": { "Position": { "value0": 228.4239044189453, "value1": 133.44451904296876, @@ -77,30 +79,49 @@ "value2": 1.0000016689300538 } }, - "value12": 4, "value13": 1, "value14": { - "Name": "Light" + "Position": { + "value0": 0.0, + "value1": 0.0, + "value2": 0.0 + }, + "Rotation": { + "value0": -0.32251736521720889, + "value1": 0.2442595511674881, + "value2": -0.08653092384338379, + "value3": 0.9104021787643433 + }, + "Scale": { + "value0": 1.0000011920928956, + "value1": 1.0000061988830567, + "value2": 1.0000035762786866 + } }, "value15": 4, - "value16": { - "Name": "Environment" + "value16": 1, + "value17": { + "Name": "Light" }, - "value17": 2, - "value18": { + "value18": 3, + "value19": { + "Name": "LuaScript" + }, + "value20": 2, + "value21": { "Name": "Camera" }, - "value19": 3, - "value20": { - "Name": "LuaScript" + "value22": 1048580, + "value23": { + "Name": "Particle" }, - "value21": 0, - "value22": 0, - "value23": 1, - "value24": 2, - "value25": { + "value24": 0, + "value25": 0, + "value26": 1, + "value27": 2, + "value28": { "Scale": 1.0, - "Aspect": 1.1355931758880616, + "Aspect": 0.8066783547401428, "FOV": 79.24700164794922, "Near": 0.27399998903274538, "Far": 831.0960083007813, @@ -108,15 +129,15 @@ "ShutterSpeed": 0.01666666753590107, "Sensitivity": 200.0 }, - "value26": 1, - "value27": 3, - "value28": { + "value29": 1, + "value30": 3, + "value31": { "FilePath": "//Assets/Scripts/Projectile.lua" }, - "value29": 0, - "value30": 1, - "value31": 1, - "value32": { + "value32": 0, + "value33": 1, + "value34": 1, + "value35": { "value0": { "value0": 0.0, "value1": 0.0, @@ -132,7 +153,7 @@ "value2": 0.0, "value3": 0.0, "value4": { - "value0": 0.5005651116371155, + "value0": 0.5005650520324707, "value1": 0.5449714064598084, "value2": 0.6726371645927429, "value3": 1.0 @@ -140,45 +161,77 @@ "value5": 128000.0, "value6": 1.0 }, - "value33": 0, - "value34": 1, - "value35": 4, - "value36": { - "value0": "//Assets/Textures/cubemap/noga", - "value1": 11, - "value2": 3072, - "value3": 4096, - "value4": ".tga", - "value5": 0.03125 - }, + "value36": 0, "value37": 0, "value38": 0, - "value39": 1, - "value40": 2, - "value41": { + "value39": 0, + "value40": 1, + "value41": 2, + "value42": { "ControllerType": 4 }, - "value42": 0, "value43": 0, "value44": 0, - "value45": 4, + "value45": 0, "value46": 4, - "value47": { - "value0": 15908292661079695999 + "value47": 1, + "value48": { + "value0": 7214240436243909756 }, - "value48": 3, - "value49": { + "value49": 3, + "value50": { "value0": 7526643175369553408 }, - "value50": 2, - "value51": { + "value51": 2, + "value52": { "value0": 10876671568568338938 }, - "value52": 1, - "value53": { - "value0": 7214240436243909756 + "value53": 1048580, + "value54": { + "value0": 8659945023637098014 }, - "value54": 0, "value55": 0, - "value56": 0 + "value56": 0, + "value57": 0, + "value58": 1, + "value59": 1048580, + "value60": { + "value0": 65536, + "value1": 5.0, + "value2": 0.5, + "value3": { + "value0": 0.0, + "value1": 0.30000001192092898, + "value2": 0.0 + }, + "value4": { + "value0": 1.0, + "value1": 1.0, + "value2": 1.0, + "value3": 1.0 + }, + "value5": { + "value0": 0.10000000149011612, + "value1": 0.0, + "value2": 0.0 + }, + "value6": { + "value0": 0.10000000149011612, + "value1": 0.0, + "value2": 0.10000000149011612 + }, + "value7": -1.0, + "value8": -1.0, + "value9": 0.06899240612983704, + "value10": 0.10000000149011612, + "value11": 10, + "value12": true, + "value13": { + "value0": 0.0, + "value1": 0.0, + "value2": 0.0 + }, + "value14": 8, + "value15": "//Assets/Textures/fire.png" + } } \ No newline at end of file diff --git a/ExampleProject/Assets/Scenes/Sponza.lsn b/ExampleProject/Assets/Scenes/Sponza.lsn index 305bfab4..47e2330a 100644 --- a/ExampleProject/Assets/Scenes/Sponza.lsn +++ b/ExampleProject/Assets/Scenes/Sponza.lsn @@ -20,7 +20,7 @@ "DebandingEnabled": true, "ChromaticAberationEnabled": false, "EyeAdaptation": true, - "SSAOEnabled": false, + "SSAOEnabled": true, "BloomEnabled": true, "FilmicGrainEnabled": false, "DepthOfFieldEnabled": false, @@ -50,13 +50,13 @@ "Position": { "value0": 0.0, "value1": 0.0, - "value2": 0.857250452041626 + "value2": 1.0328266620635987 }, "Rotation": { "value0": 0.0, "value1": 0.0, "value2": 0.0, - "value3": 0.9999999403953552 + "value3": 1.0 }, "Scale": { "value0": 4.507300853729248, @@ -121,8 +121,27 @@ "value2": 1.000004768371582 } }, - "value21": 2, + "value21": 8, "value22": { + "Position": { + "value0": 0.0, + "value1": 20.91830825805664, + "value2": 0.0 + }, + "Rotation": { + "value0": 0.0, + "value1": 0.0, + "value2": 0.0, + "value3": 1.0 + }, + "Scale": { + "value0": 1.0, + "value1": 1.0, + "value2": 1.0 + } + }, + "value23": 2, + "value24": { "Position": { "value0": 20.89605140686035, "value1": 4.722044944763184, @@ -140,8 +159,8 @@ "value2": 1.0000011920928956 } }, - "value23": 1, - "value24": { + "value25": 1, + "value26": { "Position": { "value0": 0.0, "value1": 0.0, @@ -159,25 +178,6 @@ "value2": 1.000003457069397 } }, - "value25": 8, - "value26": { - "Position": { - "value0": 0.0, - "value1": 0.0, - "value2": 0.0 - }, - "Rotation": { - "value0": 0.0, - "value1": 0.0, - "value2": 0.0, - "value3": 1.0 - }, - "Scale": { - "value0": 1.0, - "value1": 1.0, - "value2": 1.0 - } - }, "value27": 6, "value28": 1, "value29": { @@ -470,7 +470,7 @@ "value98": 1, "value99": 8, "value100": { - "value0": 1024, + "value0": 2048, "value1": 6.0, "value2": 0.20000000298023225, "value3": { @@ -494,11 +494,11 @@ "value1": 0.20000000298023225, "value2": 0.20000000298023225 }, - "value7": 3.0, - "value8": 3.0, - "value9": 0.0017724819481372834, + "value7": 2.0, + "value8": 2.0, + "value9": 0.08911193907260895, "value10": 0.10000000149011612, - "value11": 20, + "value11": 100, "value12": false, "value13": { "value0": 0.0, diff --git a/ExampleProject/Example.lmproj b/ExampleProject/Example.lmproj index 183a8407..517cd3e1 100644 --- a/ExampleProject/Example.lmproj +++ b/ExampleProject/Example.lmproj @@ -19,7 +19,7 @@ ], "SceneIndex": 1, "Borderless": false, - "EngineAssetPath": "/Users/jmorton/Dev/Lumos/Lumos/Assets/", + "EngineAssetPath": "C:/Dev/Lumos-Dev/Lumos/Assets/", "GPUIndex": -1 } } \ No newline at end of file diff --git a/Lumos/Assets/Shaders/CompileShadersWindows.bat b/Lumos/Assets/Shaders/CompileShadersWindows.bat index d10950fe..40444597 100644 --- a/Lumos/Assets/Shaders/CompileShadersWindows.bat +++ b/Lumos/Assets/Shaders/CompileShadersWindows.bat @@ -7,7 +7,7 @@ set mypath=%cd% set COMPILER=C:/VulkanSDK/1.3.216.0/Bin/glslc.exe set DSTDIR=CompiledSPV -set CHECK_FILE_MODIFIED=1 +set CHECK_FILE_MODIFIED=0 if not exist "%DSTDIR%" ( mkdir "%DSTDIR%" diff --git a/Lumos/Assets/Shaders/CompiledSPV/SSAO.frag.spv b/Lumos/Assets/Shaders/CompiledSPV/SSAO.frag.spv index 829b1596..452f670b 100644 Binary files a/Lumos/Assets/Shaders/CompiledSPV/SSAO.frag.spv and b/Lumos/Assets/Shaders/CompiledSPV/SSAO.frag.spv differ diff --git a/Lumos/Assets/Shaders/CompiledSPV/SSAOBlur.frag.spv b/Lumos/Assets/Shaders/CompiledSPV/SSAOBlur.frag.spv index 0dab3dca..5b6d78fa 100644 Binary files a/Lumos/Assets/Shaders/CompiledSPV/SSAOBlur.frag.spv and b/Lumos/Assets/Shaders/CompiledSPV/SSAOBlur.frag.spv differ diff --git a/Lumos/Assets/Shaders/CompiledSPV/Text.frag.spv b/Lumos/Assets/Shaders/CompiledSPV/Text.frag.spv index 4e2c757d..f8f4fd05 100644 Binary files a/Lumos/Assets/Shaders/CompiledSPV/Text.frag.spv and b/Lumos/Assets/Shaders/CompiledSPV/Text.frag.spv differ diff --git a/Lumos/Assets/Shaders/SSAO.frag b/Lumos/Assets/Shaders/SSAO.frag index 4af5e6fd..ec8d1569 100644 --- a/Lumos/Assets/Shaders/SSAO.frag +++ b/Lumos/Assets/Shaders/SSAO.frag @@ -86,7 +86,7 @@ void main() vec4 offset = vec4(samplePos, 1.0f); offset = ubo.projection * offset; offset.xy /= offset.w; - offset.xy = offset.xy * 0.5f + HALF_2; + offset.xy = (offset.xy * 0.5f) + HALF_2; vec3 sampledNormal = normalize(mat3(ubo.view) * (texture(in_Normal, offset.xy).xyz * 2.0f - 1.0f)); vec3 reconstructedPos = reconstructVSPosFromDepth(offset.xy); @@ -104,14 +104,13 @@ void main() float l = length(diff); float rangeCheck = smoothstep(0.0f, 1.0f, ubo.ssaoRadius / abs(reconstructedPos.z - samplePos.z - bias));//abs(diff.z - bias)); - occlusion += (reconstructedPos.z >= samplePos.z + bias ? 1.0f : 0.0f) * rangeCheck; - //occlusion *= smoothstep(MAX_DISTANCE,MAX_DISTANCE * 0.5, l); + occlusion += (reconstructedPos.z <= samplePos.z - bias ? 1.0f : 0.0f) * rangeCheck; ++sampleCount; } } - occlusion = 1.0f - (occlusion * INV_MAX_KERNEL_SIZE_F) / ubo.strength;// / float(max(sampleCount,1))); - //occlusion = pow(occlusion, 2.0f); + occlusion = 1.0f - (occlusion * INV_MAX_KERNEL_SIZE_F); + occlusion = pow(occlusion, ubo.strength); //fragColour = vec4(posVS,1.0); fragColour = occlusion.xxxx; } \ No newline at end of file diff --git a/Lumos/Assets/Shaders/SSAOBlur.frag b/Lumos/Assets/Shaders/SSAOBlur.frag index 274eb379..e388edac 100644 --- a/Lumos/Assets/Shaders/SSAOBlur.frag +++ b/Lumos/Assets/Shaders/SSAOBlur.frag @@ -8,6 +8,7 @@ layout (location = 0) in vec2 outTexCoord; layout (set = 0, binding = 0) uniform UniformBuffer { + mat4 view; vec2 ssaoTexelOffset; int ssaoBlurRadius; int pad; @@ -20,7 +21,7 @@ layout (set = 0,binding = 3) uniform sampler2D in_Normal; void main() { float ourDepth = texture(in_Depth, outTexCoord).r; - vec3 ourNormal = normalize(texture(in_Normal, outTexCoord).rgb * 2.0f - 1.0f); + vec3 ourNormal = normalize(mat3(ubo.view) * (texture(in_Normal, outTexCoord).rgb * 2.0f - 1.0f)); int sampleCount = 0; float sum = 0.0f; @@ -28,7 +29,7 @@ void main() { vec2 offset = ubo.ssaoTexelOffset * float(i); float depth = texture(in_Depth, outTexCoord + offset).r; - vec3 normal = normalize(texture(in_Normal, outTexCoord + offset).rgb * 2.0f - 1.0f); + vec3 normal = normalize(mat3(ubo.view) * (texture(in_Normal, outTexCoord + offset).rgb * 2.0f - 1.0f)); if (abs(ourDepth - depth) < 0.00002f && dot(ourNormal, normal) > 0.85f) { sum += texture(in_SSAO, outTexCoord + offset).r; diff --git a/Lumos/Assets/Shaders/Text.frag b/Lumos/Assets/Shaders/Text.frag index a78d6a43..94bbaac6 100644 --- a/Lumos/Assets/Shaders/Text.frag +++ b/Lumos/Assets/Shaders/Text.frag @@ -30,6 +30,36 @@ float ScreenPxRange() return max(0.5*dot(unitRange, screenTexSize), 1.0); } +vec4 SampleTexture() +{ + vec4 texColour = vec4(0.0); + + if (fs_in.tid > 0.0) + { + switch(int(fs_in.tid - 0.5)) + { + case 0: texColour = texture(textures[0], fs_in.uv); break; + case 1: texColour = texture(textures[1], fs_in.uv); break; + case 2: texColour = texture(textures[2], fs_in.uv); break; + case 3: texColour = texture(textures[3], fs_in.uv); break; + case 4: texColour = texture(textures[4], fs_in.uv); break; + case 5: texColour = texture(textures[5], fs_in.uv); break; + case 6: texColour = texture(textures[6], fs_in.uv); break; + case 7: texColour = texture(textures[7], fs_in.uv); break; + case 8: texColour = texture(textures[8], fs_in.uv); break; + case 9: texColour = texture(textures[9], fs_in.uv); break; + case 10: texColour = texture(textures[10], fs_in.uv); break; + case 11: texColour = texture(textures[11], fs_in.uv); break; + case 12: texColour = texture(textures[12], fs_in.uv); break; + case 13: texColour = texture(textures[13], fs_in.uv); break; + case 14: texColour = texture(textures[14], fs_in.uv); break; + case 15: texColour = texture(textures[15], fs_in.uv); break; + } + } + return texColour; + +} + void main() { vec4 mainColour = fs_in.colour; @@ -38,7 +68,7 @@ void main() float screenPxRange = ScreenPxRange(); float outlineWidth = fs_in.outlineWidth; - vec4 msd = texture(textures[int(fs_in.tid)], fs_in.uv); + vec4 msd = SampleTexture();//texture(textures[int(fs_in.tid)], fs_in.uv); float sd = median(msd.r, msd.g, msd.b); float screenPxDistance = screenPxRange * (sd - 0.5 - (outlineWidth)); diff --git a/Lumos/External/imgui/Plugins/ImTextEditor.h b/Lumos/External/imgui/Plugins/ImTextEditor.h index 079bfce5..639bf69e 100644 --- a/Lumos/External/imgui/Plugins/ImTextEditor.h +++ b/Lumos/External/imgui/Plugins/ImTextEditor.h @@ -128,7 +128,7 @@ class TextEditor typedef std::string String; typedef std::unordered_map Identifiers; typedef std::unordered_set Keywords; - typedef std::map ErrorMarkers; + typedef std::unordered_map ErrorMarkers; typedef std::unordered_set Breakpoints; typedef std::array Palette; typedef uint8_t Char; diff --git a/Lumos/Source/Lumos/Audio/AudioManager.cpp b/Lumos/Source/Lumos/Audio/AudioManager.cpp index efec4c77..0cb641f3 100644 --- a/Lumos/Source/Lumos/Audio/AudioManager.cpp +++ b/Lumos/Source/Lumos/Audio/AudioManager.cpp @@ -3,12 +3,13 @@ #include "Core/Application.h" #include "Scene/Scene.h" #include "Scene/Component/SoundComponent.h" - #ifdef LUMOS_OPENAL #include "Platform/OpenAL/ALManager.h" #endif #include "EmptyAudioManager.h" +#include + namespace Lumos { AudioManager* AudioManager::Create() diff --git a/Lumos/Source/Lumos/Audio/AudioManager.h b/Lumos/Source/Lumos/Audio/AudioManager.h index 393b7ee2..0be7732d 100644 --- a/Lumos/Source/Lumos/Audio/AudioManager.h +++ b/Lumos/Source/Lumos/Audio/AudioManager.h @@ -1,8 +1,8 @@ #pragma once #include "Core/Core.h" #include "Scene/ISystem.h" -#include -#include +#include "Core/DataStructures/Vector.h" + namespace Lumos { class Camera; @@ -11,18 +11,6 @@ namespace Lumos struct Listener { bool m_Enabled = true; - - template - void save(Archive& archive) const - { - archive(cereal::make_nvp("enabled", m_Enabled)); - } - - template - void load(Archive& archive) - { - archive(cereal::make_nvp("enabled", m_Enabled)); - } }; class LUMOS_EXPORT AudioManager : public ISystem @@ -37,20 +25,20 @@ namespace Lumos void AddSoundNode(SoundNode* node) { - m_SoundNodes.emplace_back(node); + m_SoundNodes.EmplaceBack(node); } void OnDebugDraw() override {}; void ClearNodes() { - m_SoundNodes.clear(); + m_SoundNodes.Clear(); } bool GetPaused() const { return m_Paused; } void SetPaused(bool paused); protected: - std::vector m_SoundNodes; + Vector m_SoundNodes; bool m_Paused; }; } diff --git a/Lumos/Source/Lumos/Audio/SoundNode.h b/Lumos/Source/Lumos/Audio/SoundNode.h index d023fecb..843105e5 100644 --- a/Lumos/Source/Lumos/Audio/SoundNode.h +++ b/Lumos/Source/Lumos/Audio/SoundNode.h @@ -1,15 +1,17 @@ #pragma once - #include "Sound.h" -#include "Utilities/StringUtilities.h" -#include "Core/OS/FileSystem.h" -#include #include namespace Lumos { class LUMOS_EXPORT SoundNode { + template + friend void save(Archive& archive, const SoundNode& node); + + template + friend void load(Archive& archive, SoundNode& node); + public: static SoundNode* Create(); SoundNode(); @@ -61,29 +63,6 @@ namespace Lumos virtual void Stop() = 0; virtual void SetSound(SharedPtr s); - template - void save(Archive& archive) const - { - std::string path; - FileSystem::Get().AbsolutePathToFileSystem(m_Sound ? m_Sound->GetFilePath() : "", path); - - archive(cereal::make_nvp("Position", m_Position), cereal::make_nvp("Radius", m_Radius), cereal::make_nvp("Pitch", m_Pitch), cereal::make_nvp("Volume", m_Volume), cereal::make_nvp("Velocity", m_Velocity), cereal::make_nvp("Looping", m_IsLooping), cereal::make_nvp("Paused", m_Paused), cereal::make_nvp("ReferenceDistance", m_ReferenceDistance), cereal::make_nvp("Global", m_IsGlobal), cereal::make_nvp("TimeLeft", m_TimeLeft), cereal::make_nvp("Stationary", m_Stationary), - cereal::make_nvp("SoundNodePath", path), cereal::make_nvp("RollOffFactor", m_RollOffFactor)); - } - - template - void load(Archive& archive) - { - std::string soundFilePath; - archive(cereal::make_nvp("Position", m_Position), cereal::make_nvp("Radius", m_Radius), cereal::make_nvp("Pitch", m_Pitch), cereal::make_nvp("Volume", m_Volume), cereal::make_nvp("Velocity", m_Velocity), cereal::make_nvp("Looping", m_IsLooping), cereal::make_nvp("Paused", m_Paused), cereal::make_nvp("ReferenceDistance", m_ReferenceDistance), cereal::make_nvp("Global", m_IsGlobal), cereal::make_nvp("TimeLeft", 0.0f), cereal::make_nvp("Stationary", m_Stationary), - cereal::make_nvp("SoundNodePath", soundFilePath), cereal::make_nvp("RollOffFactor", m_RollOffFactor)); - - if(!soundFilePath.empty()) - { - SetSound(Sound::Create(soundFilePath, StringUtilities::GetFilePathExtension(soundFilePath))); - } - } - protected: SharedPtr m_Sound; glm::vec3 m_Position; diff --git a/Lumos/Source/Lumos/Core/Application.cpp b/Lumos/Source/Lumos/Core/Application.cpp index fbfcc71a..7c484a86 100644 --- a/Lumos/Source/Lumos/Core/Application.cpp +++ b/Lumos/Source/Lumos/Core/Application.cpp @@ -38,6 +38,9 @@ #include "Physics/B2PhysicsEngine/B2PhysicsEngine.h" #include "Physics/LumosPhysicsEngine/LumosPhysicsEngine.h" +#define SERIALISATION_INCLUDE_ONLY +#include "Scene/SerialisationImplementation.h" + #include "Embedded/splash.inl" #if __has_include() @@ -82,6 +85,10 @@ namespace Lumos #ifndef LUMOS_PLATFORM_IOS auto projectRoot = StringUtilities::GetFileLocation(filePath); m_ProjectSettings.m_ProjectRoot = projectRoot; + + String8 pathCopy = PushStr8Copy(m_FrameArena, projectRoot.c_str()); + pathCopy = StringUtilities::ResolveRelativePath(m_FrameArena, pathCopy); + m_ProjectSettings.m_ProjectRoot = (const char*)pathCopy.str; #endif if(!FileSystem::FolderExists(m_ProjectSettings.m_ProjectRoot + "Assets/Prefabs")) @@ -106,6 +113,10 @@ namespace Lumos m_ProjectSettings.m_ProjectRoot = path + name + "/"; m_ProjectSettings.m_ProjectName = name; + String8 pathCopy = PushStr8Copy(m_FrameArena, m_ProjectSettings.m_ProjectRoot.c_str()); + pathCopy = StringUtilities::ResolveRelativePath(m_FrameArena, pathCopy); + m_ProjectSettings.m_ProjectRoot = (const char*)pathCopy.str; + std::filesystem::create_directory(m_ProjectSettings.m_ProjectRoot); m_SceneManager = CreateUniquePtr(); @@ -191,6 +202,8 @@ namespace Lumos SetMaxImageDimensions(2048, 2048); m_SceneManager = CreateUniquePtr(); + m_AssetManager = CreateSharedPtr(); + Deserialise(); CommandLine* cmdline = Internal::CoreSystem::GetCmdLine(); @@ -235,10 +248,6 @@ namespace Lumos ImPlot::CreateContext(); ImGui::StyleColorsDark(); - m_ShaderLibrary = CreateSharedPtr(); - m_ModelLibrary = CreateSharedPtr(); - m_FontLibrary = CreateSharedPtr(); - bool loadEmbeddedShaders = true; if(FileSystem::FolderExists(m_ProjectSettings.m_EngineAssetPath + "Shaders")) loadEmbeddedShaders = false; @@ -250,7 +259,9 @@ namespace Lumos // Draw Splash Screen { - auto splashTexture = Graphics::Texture2D::CreateFromSource(splashWidth, splashHeight, (void*)splash); + auto desc = Graphics::TextureDesc(Graphics::TextureFilter::LINEAR, Graphics::TextureFilter::LINEAR, Graphics::TextureWrap::REPEAT); + desc.flags = Graphics::TextureFlags::Texture_Sampled; + auto splashTexture = Graphics::Texture2D::CreateFromSource(splashWidth, splashHeight, (void*)splash, desc); Graphics::Renderer::GetRenderer()->Begin(); Graphics::Renderer::GetRenderer()->DrawSplashScreen(splashTexture); Graphics::Renderer::GetRenderer()->Present(); @@ -316,9 +327,7 @@ namespace Lumos Engine::Release(); Input::Release(); - m_ShaderLibrary.reset(); - m_ModelLibrary.reset(); - m_FontLibrary.reset(); + m_AssetManager.reset(); m_SceneManager.reset(); m_RenderPasses.reset(); m_SystemManager.reset(); @@ -368,20 +377,28 @@ namespace Lumos auto& stats = Engine::Get().Statistics(); auto& ts = Engine::GetTimeStep(); + static int s_NumContiguousLargeFrames = 0; + const int maxContiguousLargeFrames = 2; + if(ts.GetSeconds() > 5) { LUMOS_LOG_WARN("Large frame time {0}", ts.GetSeconds()); + + s_NumContiguousLargeFrames++; #ifdef LUMOS_DISABLE_LARGE_FRAME_TIME // Added to stop application locking computer // Exit if frametime exceeds 5 seconds return false; #endif + + if(s_NumContiguousLargeFrames > maxContiguousLargeFrames) + return false; } + else + s_NumContiguousLargeFrames = 0; ExecuteMainThreadQueue(); - ImGui::NewFrame(); - { LUMOS_PROFILE_SCOPE("Application::TimeStepUpdates"); ts.OnUpdate(); @@ -392,8 +409,10 @@ namespace Lumos stats.FrameTime = ts.GetMillis(); } + // Process Input events before ImGui::NewFrame Input::Get().ResetPressed(); m_Window->ProcessInput(); + ImGui::NewFrame(); { std::scoped_lock lock(m_EventQueueMutex); @@ -442,16 +461,15 @@ namespace Lumos m_ImGuiManager->OnRender(m_SceneManager->GetCurrentScene()); // Clears debug line and point lists - DebugRenderer::Reset(); + DebugRenderer::Reset((float)ts.GetSeconds()); OnDebugDraw(); - Graphics::Pipeline::DeleteUnusedCache(); - Graphics::Framebuffer::DeleteUnusedCache(); - Graphics::RenderPass::DeleteUnusedCache(); + // Graphics::Pipeline::DeleteUnusedCache(); + // Graphics::Framebuffer::DeleteUnusedCache(); + // Graphics::RenderPass::DeleteUnusedCache(); // m_ShaderLibrary->Update(ts.GetElapsedSeconds()); - m_ModelLibrary->Update((float)ts.GetElapsedSeconds()); - m_FontLibrary->Update((float)ts.GetElapsedSeconds()); + m_AssetManager->Update((float)ts.GetElapsedSeconds()); m_Frames++; } else @@ -568,19 +586,9 @@ namespace Lumos m_RenderPasses->OnNewScene(scene); } - SharedPtr& Application::GetShaderLibrary() + SharedPtr& Application::GetAssetManager() { - return m_ShaderLibrary; - } - - SharedPtr& Application::GetModelLibrary() - { - return m_ModelLibrary; - } - - SharedPtr& Application::GetFontLibrary() - { - return m_FontLibrary; + return m_AssetManager; } void Application::SubmitToMainThread(const std::function& function) @@ -701,6 +709,12 @@ namespace Lumos LUMOS_LOG_INFO("Serialising Application {0}", fullPath); FileSystem::WriteTextFile(fullPath, storage.str()); } + + // Save Asset Registry + { + String8 path = PushStr8F(m_FrameArena, "%sAssetRegistry.lmar", m_ProjectSettings.m_ProjectRoot.c_str()); // m_ProjectSettings.m_ProjectRoot + std::string("AssetRegistry.lmar"); + SerialialiseAssetRegistry(path, m_AssetManager->GetAssetRegistry()); + } } void Application::Deserialise() @@ -782,6 +796,13 @@ namespace Lumos { cereal::JSONInputArchive input(istr); input(*this); + + // Load Asset Registry + { + String8 path = PushStr8F(m_FrameArena, "%sAssetRegistry.lmar", m_ProjectSettings.m_ProjectRoot.c_str()); + if(FileSystem::FileExists((const char*)path.str)) + DeserialialiseAssetRegistry(path, m_AssetManager->GetAssetRegistry()); + } } catch(...) { diff --git a/Lumos/Source/Lumos/Core/Application.h b/Lumos/Source/Lumos/Core/Application.h index 7823a6d0..98a85c43 100644 --- a/Lumos/Source/Lumos/Core/Application.h +++ b/Lumos/Source/Lumos/Core/Application.h @@ -3,6 +3,7 @@ #include "Scene/SceneManager.h" #include "Scene/SystemManager.h" #include "Core/OS/FileSystem.h" +#include "Core/QualitySettings.h" #include #include @@ -23,10 +24,7 @@ namespace Lumos class WindowCloseEvent; class WindowResizeEvent; class ImGuiManager; - class ModelLibrary; - class TextureLibrary; - class FontLibrary; - class ShaderLibrary; + class AssetManager; namespace Graphics { @@ -99,9 +97,10 @@ namespace Lumos glm::vec2 GetWindowSize() const; float GetWindowDPI() const; - SharedPtr& GetShaderLibrary(); - SharedPtr& GetModelLibrary(); - SharedPtr& GetFontLibrary(); + SharedPtr& GetAssetManager(); + + const QualitySettings& GetQualitySettings() const { return m_QualitySettings; } + QualitySettings& GetQualitySettings() { return m_QualitySettings; } void SubmitToMainThread(const std::function& function); void ExecuteMainThreadQueue(); @@ -328,9 +327,7 @@ namespace Lumos UniquePtr m_RenderPasses; UniquePtr m_ImGuiManager; UniquePtr m_Timer; - SharedPtr m_ShaderLibrary; - SharedPtr m_ModelLibrary; - SharedPtr m_FontLibrary; + SharedPtr m_AssetManager; AppState m_CurrentState = AppState::Loading; EditorState m_EditorState = EditorState::Preview; @@ -346,6 +343,8 @@ namespace Lumos Arena* m_FrameArena; Arena* m_Arena; + QualitySettings m_QualitySettings; + NONCOPYABLE(Application) }; diff --git a/Lumos/Source/Lumos/Core/Asset.h b/Lumos/Source/Lumos/Core/Asset.h index 413da7a0..4c6af335 100644 --- a/Lumos/Source/Lumos/Core/Asset.h +++ b/Lumos/Source/Lumos/Core/Asset.h @@ -25,7 +25,7 @@ namespace Lumos enum class AssetType : uint16_t { - None = 0, + Unkown = 0, Texture = 1, Mesh = 2, Scene = 3, @@ -38,8 +38,46 @@ namespace Lumos Skeleton = 10, Animation = 11, AnimationController = 12, + Prefab = 13, + Script = 14 }; + inline const char* AssetTypeToString(AssetType assetType) + { + switch(assetType) + { + case AssetType::Unkown: + return "Unkown"; + case AssetType::Scene: + return "Scene"; + case AssetType::Prefab: + return "Prefab"; + case AssetType::Mesh: + return "Mesh"; + case AssetType::Model: + return "Model"; + case AssetType::Material: + return "Material"; + case AssetType::Texture: + return "Texture"; + case AssetType::Audio: + return "Audio"; + case AssetType::Font: + return "Font"; + case AssetType::Script: + return "Script"; + case AssetType::Skeleton: + return "Skeleton"; + case AssetType::Animation: + return "Animation"; + case AssetType::Shader: + return "Shader"; + } + + LUMOS_ASSERT(false, "Unknown Asset Type"); + return "None"; + } + class LUMOS_EXPORT Asset { public: @@ -47,8 +85,8 @@ namespace Lumos virtual ~Asset() { } - static AssetType GetStaticType() { return AssetType::None; } - virtual AssetType GetAssetType() const { return AssetType::None; } + static AssetType GetStaticType() { return AssetType::Unkown; } + virtual AssetType GetAssetType() const { return AssetType::Unkown; } bool IsValid() const { return ((Flags & (uint16_t)AssetFlag::Missing) | (Flags & (uint16_t)AssetFlag::Invalid)) == 0; } diff --git a/Lumos/Source/Lumos/Core/CommandLine.cpp b/Lumos/Source/Lumos/Core/CommandLine.cpp index 2e688764..f5f7c8da 100644 --- a/Lumos/Source/Lumos/Core/CommandLine.cpp +++ b/Lumos/Source/Lumos/Core/CommandLine.cpp @@ -10,8 +10,8 @@ namespace Lumos { ArenaTemp scratch = ScratchBegin(&arena, 1); - m_SlotCount = 64; - m_Slots = PushArray(arena, CommandLineOptionSlot, m_SlotCount); + m_SlotCount = 64; + m_Slots = PushArray(arena, CommandLineOptionSlot, m_SlotCount); String8List separatedStrings = { 0 }; for(String8Node* n = strings.first; n != 0; n = n->next) @@ -19,23 +19,23 @@ namespace Lumos String8List stringsFromCurrentNode = { 0 }; uint64_t startIndex = 0; bool quoted = false; - bool seekingNonWS = false; + bool seekingNonWS = false; for(uint64_t index = 0; index <= n->string.size; index += 1) { if(seekingNonWS && index < n->string.size && !CharIsSpace(n->string.str[index])) { - seekingNonWS = false; - startIndex = index; + seekingNonWS = false; + startIndex = index; } if(!seekingNonWS && (index == n->string.size || n->string.str[index] == ' ' || n->string.str[index] == '"')) { String8 string = Substr8(n->string, RangeU64({ startIndex, index })); Str8ListPush(scratch.arena, &stringsFromCurrentNode, string); - startIndex = index + 1; + startIndex = index + 1; if(n->string.str[index] == ' ') { - seekingNonWS = true; + seekingNonWS = true; } } if(index < n->string.size && n->string.str[index] == '"') diff --git a/Lumos/Source/Lumos/Core/CommandLine.h b/Lumos/Source/Lumos/Core/CommandLine.h index a330bfc5..56d60e52 100644 --- a/Lumos/Source/Lumos/Core/CommandLine.h +++ b/Lumos/Source/Lumos/Core/CommandLine.h @@ -19,9 +19,8 @@ namespace Lumos class CommandLine { - public: - - CommandLine() = default; + public: + CommandLine() = default; ~CommandLine() = default; void Init(Arena* arena, String8List strings); @@ -30,11 +29,11 @@ namespace Lumos bool OptionBool(String8 name); double OptionDouble(String8 name); int64_t OptionInt64(String8 name); + private: uint64_t m_SlotCount; CommandLineOptionSlot* m_Slots; String8List m_Inputs; }; - } diff --git a/Lumos/Source/Lumos/Core/DataStructures/Vector.h b/Lumos/Source/Lumos/Core/DataStructures/Vector.h index b27be2ee..1c35788e 100644 --- a/Lumos/Source/Lumos/Core/DataStructures/Vector.h +++ b/Lumos/Source/Lumos/Core/DataStructures/Vector.h @@ -1,5 +1,6 @@ #pragma once #include "Core/OS/Memory.h" +#include // for std::move namespace Lumos { @@ -7,42 +8,41 @@ namespace Lumos class Vector { public: - Vector(Arena* arena = nullptr) - : m_Arena(arena) - { - } - - Vector(const Vector& another_vector); // copy constructor - Vector(size_t size, Arena* arena = nullptr, T initial = T {}); // constructor based on capacity and a default value - Vector(std::initializer_list values, Arena* arena = nullptr); + // Constructors + Vector(Arena* arena = nullptr); + Vector(const Vector& other); Vector(Vector&& other) noexcept; + Vector(size_t size, const T& initial = T {}, Arena* arena = nullptr); + Vector(std::initializer_list values, Arena* arena = nullptr); - ~Vector() - { - if(!m_Arena) - delete[] m_Data; - } - - Vector& operator=(const Vector&); // copy assignment - - size_t Size() const { return m_CurrentIndex; } - size_t Capacity() const { return m_Size; } + // Destructor + ~Vector(); - T& Emplace(const T& element); // pass element by constant reference - T& Emplace(T&& element); + // Copy assignment + Vector& operator=(const Vector& other); + // Element access + T& operator[](size_t index); + const T& operator[](size_t index) const; + T& Front(); + const T& Front() const; + T& Back(); + const T& Back() const; + + // Capacity + bool Empty() const noexcept; + size_t Size() const noexcept; + size_t Capacity() const noexcept; + void Reserve(size_t capacity); + void Resize(size_t size, const T& value = T {}); + + // Modifiers + void Clear() noexcept; + void PushBack(const T& value); + void PushBack(T&& value); template T& EmplaceBack(Args&&... args); - - T& EmplaceBack(); - T& Back(); - void Pop(); - void Clear(bool deleteData = false); - - bool Empty() const { return m_CurrentIndex == 0; } - - bool operator==(const Vector& other) const; - bool operator!=(const Vector& other) const; + void PopBack(); class Iterator { @@ -64,253 +64,265 @@ namespace Lumos T* ptr; }; - Iterator begin() const { return Iterator(m_Data); } - Iterator end() const { return Iterator(m_Data + m_CurrentIndex); } + class ConstIterator + { + public: + ConstIterator(T* ptr) + : ptr(ptr) + { + } + ConstIterator operator++() + { + ++ptr; + return *this; + } + bool operator!=(const Iterator& other) const { return ptr != other.ptr; } + const T& operator*() const { return *ptr; } + Iterator operator+(int offset) const { return Iterator(ptr + offset); } - T& operator[](const size_t index); - const T& operator[](const size_t index) const; - T* Data() { return m_Data; } + private: + const T* ptr; + }; + + Iterator begin() { return Iterator(m_Data); } + Iterator end() { return Iterator(m_Data + m_Size); } - void Reserve(const size_t size); + ConstIterator begin() const { return ConstIterator(m_Data); } + ConstIterator end() const { return ConstIterator(m_Data + m_Size); } + + T* Data() { return m_Data; } private: - T* m_Data = nullptr; - size_t m_Size = 0; - size_t m_CurrentIndex = 0; - Arena* m_Arena = nullptr; + T* m_Data = nullptr; + size_t m_Size = 0; + size_t m_Capacity = 0; + Arena* m_Arena = nullptr; + + // Helper function for copying elements + void CopyElements(const Vector& other); + + // Helper function for deleting allocated memory + void Destroy() noexcept; }; + // Constructor implementations template - Vector::Vector(const Vector& other) + Vector::Vector(Arena* arena) + : m_Arena(arena) { - if(!m_Arena) - delete[] m_Data; // Delete before copying everything from another vector - - // Copy everything from another vector - m_CurrentIndex = other.Size(); - m_Size = other.Capacity(); - if(m_Arena) - m_Data = PushArrayNoZero(m_Arena, T, m_Size); - else - m_Data = new T[m_Size]; + } - for(size_t i = 0; i < m_CurrentIndex; ++i) - m_Data[i] = other[i]; + template + Vector::Vector(const Vector& other) + : m_Arena(other.m_Arena) + { + CopyElements(other); } template Vector::Vector(Vector&& other) noexcept : m_Data(other.m_Data) , m_Size(other.m_Size) - , m_CurrentIndex(other.m_CurrentIndex) + , m_Capacity(other.m_Capacity) + , m_Arena(other.m_Arena) { + other.m_Data = nullptr; + other.m_Size = 0; + other.m_Capacity = 0; } template - Vector::Vector(std::initializer_list values, Arena* arena) - : m_Arena(arena) + Vector::Vector(size_t size, const T& initial, Arena* arena) + : m_Size(0) + , m_Capacity(0) + , m_Arena(arena) { - if(!m_Arena) - delete[] m_Data; // Delete before copying everything from another vector - - // Copy everything from another vector - m_CurrentIndex = values.size(); - m_Size = values.size(); - - if(arena) - m_Data = PushArrayNoZero(m_Arena, T, m_Size); - else - m_Data = new T[m_Size]; + Reserve(size); + for(size_t i = 0; i < size; ++i) + m_Data[i] = initial; + } + template + Vector::Vector(std::initializer_list values, Arena* arena) + : m_Size(values.size()) + , m_Capacity(0) + , m_Arena(arena) + { + Reserve(m_Size); size_t index = 0; for(auto& value : values) m_Data[index++] = value; } + // Destructor implementation template - Vector::Vector(size_t size, Arena* arena, T initial) - : m_Size(size) - , m_CurrentIndex(size) - , m_Arena(arena) + Vector::~Vector() { - if(m_Arena) - m_Data = PushArrayNoZero(m_Arena, T, m_Size); - else - m_Data = new T[size]; - - for(size_t i = 0; i < size; ++i) - m_Data[i] = initial; // initialize + Destroy(); } - // Copy assignment + // Copy assignment implementation template Vector& Vector::operator=(const Vector& other) { - if(!m_Arena) - delete[] m_Data; // Delete before copying everything from another vector - - // Copy everything from another vector - m_CurrentIndex = other.Size(); - m_Size = other.Capacity(); - - if(m_Arena) - m_Data = PushArrayNoZero(m_Arena, T, m_Size); - else - m_Data = new T[m_Size]; - - for(size_t i = 0; i < m_Size; ++i) - m_Data[i] = other[i]; - + if(this != &other) + { + Destroy(); + CopyElements(other); + m_Arena = other.m_Arena; + } return *this; } + // Element access implementations template - T& Vector::operator[](const size_t index) + T& Vector::operator[](size_t index) { - LUMOS_ASSERT(index < m_CurrentIndex, "Index must be less than vector's size"); - + if(index >= m_Size) + LUMOS_ASSERT(index < m_Size, "Index must be less than vector's size"); return m_Data[index]; } template - const T& Vector::operator[](const size_t index) const + const T& Vector::operator[](size_t index) const { - LUMOS_ASSERT(index < m_CurrentIndex, "Index must be less than vector's size"); + if(index >= m_Size) + LUMOS_ASSERT(index < m_Size, "Index must be less than vector's size"); return m_Data[index]; } template - T& Vector::Emplace(const T& element) + T& Vector::Front() { - // If no cacacity, increase capacity - if(m_CurrentIndex == m_Size) - { - if(m_Size == 0) // handing initial when - Reserve(4); - else - Reserve(m_Size * 2); - } + return *begin(); + } - // Append an element to the array - m_Data[m_CurrentIndex] = element; - m_CurrentIndex++; + template + const T& Vector::Front() const + { + return *begin(); + } - return m_Data[m_CurrentIndex - 1]; + template + T& Vector::Back() + { + return m_Data[m_Size - 1]; } template - T& Vector::Emplace(T&& element) + const T& Vector::Back() const { - // If no cacacity, increase capacity - if(m_CurrentIndex == m_Size) - { - if(m_Size == 0) // handing initial when - Reserve(4); - else - Reserve(m_Size * 2); - } + return *(end() - 1); + } - // Append an element to the array - m_Data[m_CurrentIndex] = std::move(element); - m_CurrentIndex++; + // Capacity implementations + template + bool Vector::Empty() const noexcept + { + return m_Size == 0; + } - return m_Data[m_CurrentIndex - 1]; + template + size_t Vector::Size() const noexcept + { + return m_Size; } - template - template - T& Vector::EmplaceBack(Args&&... args) + template + size_t Vector::Capacity() const noexcept { - // If no cacacity, increase capacity - if(m_CurrentIndex == m_Size) - { - if(m_Size == 0) // handing initial when - Reserve(4); - else - Reserve(m_Size * 2); - } + return m_Capacity; + } - // Append an element to the array - m_Data[m_CurrentIndex] = T(std::forward(args)...); - m_CurrentIndex++; + template + void Vector::Reserve(size_t capacity) + { + if(capacity <= m_Capacity) + return; - return m_Data[m_CurrentIndex - 1]; + T* newData = nullptr; + if(m_Arena) + newData = PushArrayNoZero(m_Arena, T, capacity); + else + newData = new T[capacity]; + + for(size_t i = 0; i < m_Size; ++i) + newData[i] = std::move(m_Data[i]); + + if(!m_Arena) + delete[] m_Data; + + m_Data = newData; + m_Capacity = capacity; } template - T& Vector::EmplaceBack() + void Vector::Resize(size_t size, const T& value) { - // If no cacacity, increase capacity - if(m_CurrentIndex == m_Size) - { - if(m_Size == 0) // handing initial when - Reserve(4); - else - Reserve(m_Size * 2); - } + Reserve(size); + for(size_t i = m_Size; i < size; ++i) + m_Data[i] = value; + m_Size = size; + } - // Append an element to the array - auto& element = m_Data[m_CurrentIndex]; - m_CurrentIndex++; + // Modifiers implementations + template + void Vector::Clear() noexcept + { + m_Size = 0; + } - return element; + template + void Vector::PushBack(const T& value) + { + if(m_Size == m_Capacity) + Reserve(m_Capacity == 0 ? 1 : m_Capacity * 2); + m_Data[m_Size++] = value; } template - T& Vector::Back() + void Vector::PushBack(T&& value) + { + if(m_Size == m_Capacity) + Reserve(m_Capacity == 0 ? 1 : m_Capacity * 2); + m_Data[m_Size++] = std::move(value); + } + + template + template + T& Vector::EmplaceBack(Args&&... args) { - return m_Data[m_CurrentIndex - 1]; + if(m_Size == m_Capacity) + Reserve(m_Capacity == 0 ? 1 : m_Capacity * 2); + + m_Data[m_Size] = T(std::forward(args)...); + return m_Data[m_Size++]; } template - void Vector::Pop() + void Vector::PopBack() { - if(m_CurrentIndex > 0) // Nothing to pop otherwise - { - m_CurrentIndex--; - } - else - LUMOS_ASSERT(false, "Nothing to pop"); + if(m_Size > 0) + --m_Size; } + // Helper function implementations template - void Vector::Clear(bool deleteData) + void Vector::CopyElements(const Vector& other) { - if(deleteData) - { - if(!m_Arena) - delete[] m_Data; - m_CurrentIndex = 0; - m_Size = 0; - } - else - { - m_CurrentIndex = 0; - } + Reserve(other.m_Capacity); + for(size_t i = 0; i < other.m_Size; ++i) + m_Data[i] = other.m_Data[i]; + m_Size = other.m_Size; } template - inline void Vector::Reserve(const size_t capacity) + void Vector::Destroy() noexcept { - // Handle case when given capacity is less than equal to size. (No need to reallocate) - if(capacity > m_CurrentIndex) - { - // Reserves memory of size capacity for the vector_ - T* temp; - if(m_Arena) - temp = PushArrayNoZero(m_Arena, T, capacity); - else - temp = new T[capacity]; - - // Move previous elements to this memory - for(size_t i = 0; i < m_Size; ++i) - temp[i] = std::move(m_Data[i]); - - if(!m_Arena) - delete[] m_Data; // Delete old vector - - m_Size = capacity; - m_Data = temp; // Copy assignment - } + if(!m_Arena) + delete[] m_Data; + m_Data = nullptr; + m_Size = 0; + m_Capacity = 0; } -} +} \ No newline at end of file diff --git a/Lumos/Source/Lumos/Core/OS/FileSystem.h b/Lumos/Source/Lumos/Core/OS/FileSystem.h index 83b9f68a..25c9e17f 100644 --- a/Lumos/Source/Lumos/Core/OS/FileSystem.h +++ b/Lumos/Source/Lumos/Core/OS/FileSystem.h @@ -1,7 +1,6 @@ #pragma once #include "Core/DataStructures/Vector.h" #include "Utilities/TSingleton.h" -#include #include "Core/String.h" namespace Lumos diff --git a/Lumos/Source/Lumos/Core/OS/Input.cpp b/Lumos/Source/Lumos/Core/OS/Input.cpp index 316f5363..9c673d7c 100644 --- a/Lumos/Source/Lumos/Core/OS/Input.cpp +++ b/Lumos/Source/Lumos/Core/OS/Input.cpp @@ -18,13 +18,15 @@ namespace Lumos m_MouseOnScreen = true; m_ScrollOffset = 0.0f; + m_ScrollOffsetX = 0.0f; } void Input::ResetPressed() { memset(m_KeyPressed, 0, MAX_KEYS); memset(m_MouseClicked, 0, MAX_BUTTONS); - m_ScrollOffset = 0; + m_ScrollOffset = 0.0f; + m_ScrollOffsetX = 0.0f; } void Input::OnEvent(Event& e) @@ -70,6 +72,7 @@ namespace Lumos bool Input::OnMouseScrolled(MouseScrolledEvent& e) { SetScrollOffset(e.GetYOffset()); + SetScrollOffsetX(e.GetXOffset()); return false; } diff --git a/Lumos/Source/Lumos/Core/OS/Input.h b/Lumos/Source/Lumos/Core/OS/Input.h index dad5c493..a4374768 100644 --- a/Lumos/Source/Lumos/Core/OS/Input.h +++ b/Lumos/Source/Lumos/Core/OS/Input.h @@ -5,6 +5,7 @@ #include "Utilities/TSingleton.h" #include "Core/OS/KeyCodes.h" #include +#include #define MAX_KEYS 1024 #define MAX_BUTTONS 32 @@ -56,6 +57,9 @@ namespace Lumos void SetScrollOffset(float offset) { m_ScrollOffset = offset; } float GetScrollOffset() const { return m_ScrollOffset; } + void SetScrollOffsetX(float offset) { m_ScrollOffsetX = offset; } + float GetScrollOffsetX() const { return m_ScrollOffsetX; } + void Reset(); void ResetPressed(); void OnEvent(Event& e); @@ -93,7 +97,8 @@ namespace Lumos bool m_MouseHeld[MAX_BUTTONS]; bool m_MouseClicked[MAX_BUTTONS]; - float m_ScrollOffset = 0.0f; + float m_ScrollOffset = 0.0f; + float m_ScrollOffsetX = 0.0f; bool m_MouseOnScreen; MouseMode m_MouseMode; diff --git a/Lumos/Source/Lumos/Core/OS/OS.cpp b/Lumos/Source/Lumos/Core/OS/OS.cpp index 8b7457a1..7532fb1f 100644 --- a/Lumos/Source/Lumos/Core/OS/OS.cpp +++ b/Lumos/Source/Lumos/Core/OS/OS.cpp @@ -60,4 +60,13 @@ namespace Lumos break; } } + + std::string OS::GetCurrentWorkingDirectory() + { + return std::string(""); + }; + std::string OS::GetAssetPath() + { + return std::string(""); + }; } diff --git a/Lumos/Source/Lumos/Core/OS/OS.h b/Lumos/Source/Lumos/Core/OS/OS.h index bd59a537..bf031031 100644 --- a/Lumos/Source/Lumos/Core/OS/OS.h +++ b/Lumos/Source/Lumos/Core/OS/OS.h @@ -1,7 +1,6 @@ #pragma once #include "Core/Core.h" -#include #include #if __has_include() @@ -42,12 +41,9 @@ namespace Lumos } static std::string PowerStateToString(PowerState state); - virtual std::string GetCurrentWorkingDirectory() { return std::string(""); }; virtual std::string GetExecutablePath() = 0; - virtual std::string GetAssetPath() - { - return ""; - }; + virtual std::string GetCurrentWorkingDirectory(); + virtual std::string GetAssetPath(); virtual void Vibrate() const {}; virtual void SetTitleBarColour(const glm::vec4& colour, bool dark = true) {}; diff --git a/Lumos/Source/Lumos/Core/Profiler.h b/Lumos/Source/Lumos/Core/Profiler.h index 38eed405..3d1e70c8 100644 --- a/Lumos/Source/Lumos/Core/Profiler.h +++ b/Lumos/Source/Lumos/Core/Profiler.h @@ -9,9 +9,9 @@ #endif #define LUMOS_TRACK_MEMORY 1 -#define LUMOS_PROFILE_LOW 0 -#define LUMOS_PROFILE_GPU_TIMINGS 0 -#define LUMOS_VULKAN_MARKERS 0 // Disable when using OpenGL +#define LUMOS_PROFILE_LOW 1 +#define LUMOS_PROFILE_GPU_TIMINGS 1 +#define LUMOS_VULKAN_MARKERS 1 // Disable when using OpenGL #include #define LUMOS_PROFILE_SCOPE(name) ZoneScopedN(name) diff --git a/Lumos/Source/Lumos/Core/QualitySettings.h b/Lumos/Source/Lumos/Core/QualitySettings.h new file mode 100644 index 00000000..deb6017f --- /dev/null +++ b/Lumos/Source/Lumos/Core/QualitySettings.h @@ -0,0 +1,80 @@ +#pragma once + +namespace Lumos +{ + enum class ShadowQualitySetting + { + None = 0, + Low = 1, + Medium = 2, + High = 2 + }; + + enum class ShadowResolutionSetting + { + None = 0, + Low = 1, + Medium = 2, + High = 3 + }; + + struct QualitySettings + { + float RendererScale = 1.0f; + + // Shadows + bool EnableShadows = true; + ShadowQualitySetting ShadowQuality = ShadowQualitySetting::Low; + ShadowResolutionSetting ShadowResolution = ShadowResolutionSetting::Low; + + // Post-Process + bool EnableBloom = true; + bool EnableDOF = false; + bool EnableSSR = false; + bool EnableSSAO = false; + + void SetGeneralLeve(uint8_t level) + { + switch(level) + { + case 0: + { + EnableShadows = true; + ShadowQuality = ShadowQualitySetting::Low; + ShadowResolution = ShadowResolutionSetting::Low; + + EnableBloom = false; + EnableDOF = false; + EnableSSR = false; + EnableSSAO = false; + break; + } + case 1: + { + EnableShadows = true; + ShadowQuality = ShadowQualitySetting::Medium; + ShadowResolution = ShadowResolutionSetting::Medium; + + EnableBloom = true; + EnableDOF = false; + EnableSSR = false; + EnableSSAO = false; + break; + } + default: + case 2: + { + EnableShadows = true; + ShadowQuality = ShadowQualitySetting::High; + ShadowResolution = ShadowResolutionSetting::High; + + EnableBloom = true; + EnableDOF = true; + EnableSSR = false; + EnableSSAO = true; + break; + } + } + } + }; +} diff --git a/Lumos/Source/Lumos/Core/String.cpp b/Lumos/Source/Lumos/Core/String.cpp index efc8ad6b..857bcc79 100644 --- a/Lumos/Source/Lumos/Core/String.cpp +++ b/Lumos/Source/Lumos/Core/String.cpp @@ -165,7 +165,6 @@ namespace Lumos uint64_t FindSubstr8(String8 haystack, String8 needle, uint64_t start_pos, MatchFlags flags) { - bool found = 0; uint64_t found_idx = haystack.size; for(uint64_t i = start_pos; i < haystack.size; i += 1) { @@ -175,7 +174,6 @@ namespace Lumos if(Str8Match(substr, needle, flags)) { found_idx = i; - found = 1; if(!(flags & MatchFlags::FindLast)) { break; diff --git a/Lumos/Source/Lumos/Core/String.h b/Lumos/Source/Lumos/Core/String.h index 24776c11..6ac9b10b 100644 --- a/Lumos/Source/Lumos/Core/String.h +++ b/Lumos/Source/Lumos/Core/String.h @@ -131,4 +131,5 @@ namespace Lumos #define Str8VArg(s) (int)(s).size, (s).str #define Str8ListFirst(list) ((list)->first != 0 ? (list)->first->string : Str8Lit("")) #define ToStdString(s) std::string((const char*)s.str, s.size) +#define ToCChar(s) (const char*)s.str } diff --git a/Lumos/Source/Lumos/Core/UUID.h b/Lumos/Source/Lumos/Core/UUID.h index 557b7b6c..a52d1347 100644 --- a/Lumos/Source/Lumos/Core/UUID.h +++ b/Lumos/Source/Lumos/Core/UUID.h @@ -6,6 +6,12 @@ namespace Lumos { class UUID { + template + friend void save(Archive& archive, const UUID& ID); + + template + friend void load(Archive& archive, UUID& ID); + public: UUID(); UUID(uint64_t uuid); @@ -32,4 +38,4 @@ namespace std } }; -} \ No newline at end of file +} diff --git a/Lumos/Source/Lumos/Embedded/EmbedAsset.h b/Lumos/Source/Lumos/Embedded/EmbedAsset.h index 5e80ebff..444b111c 100644 --- a/Lumos/Source/Lumos/Embedded/EmbedAsset.h +++ b/Lumos/Source/Lumos/Embedded/EmbedAsset.h @@ -1,5 +1,4 @@ #pragma once -#include namespace Lumos { diff --git a/Lumos/Source/Lumos/Graphics/AnimatedSprite.h b/Lumos/Source/Lumos/Graphics/AnimatedSprite.h index 2f27aab4..c9cc2e72 100644 --- a/Lumos/Source/Lumos/Graphics/AnimatedSprite.h +++ b/Lumos/Source/Lumos/Graphics/AnimatedSprite.h @@ -1,14 +1,17 @@ #pragma once #include "Sprite.h" #include -#include -#include -#include namespace Lumos::Graphics { class AnimatedSprite : public Sprite { + template + friend void save(Archive& archive, const AnimatedSprite& sprite); + + template + friend void load(Archive& archive, AnimatedSprite& sprite); + public: enum class PlayMode { @@ -45,38 +48,6 @@ namespace Lumos::Graphics const std::string& GetState() const { return m_State; } std::unordered_map& GetAnimationStates() { return m_AnimationStates; } - template - void save(Archive& archive) const - { - archive(cereal::make_nvp("TexturePath", m_Texture ? m_Texture->GetFilepath() : ""), - cereal::make_nvp("Position", m_Position), - cereal::make_nvp("Scale", m_Scale), - cereal::make_nvp("Colour", m_Colour), - cereal::make_nvp("AnimationFrames", m_AnimationStates), - cereal::make_nvp("State", m_State)); - archive(SpriteSheetTileSize); - } - - template - void load(Archive& archive) - { - std::string textureFilePath; - archive(cereal::make_nvp("TexturePath", textureFilePath), - cereal::make_nvp("Position", m_Position), - cereal::make_nvp("Scale", m_Scale), - cereal::make_nvp("Colour", m_Colour), - cereal::make_nvp("AnimationFrames", m_AnimationStates), - cereal::make_nvp("State", m_State)); - - if(!textureFilePath.empty()) - m_Texture = SharedPtr(Graphics::Texture2D::CreateFromFile("sprite", textureFilePath)); - - if(Serialisation::CurrentSceneVersion > 21) - archive(SpriteSheetTileSize); - - SetState(m_State); - } - std::unordered_map m_AnimationStates; uint32_t m_CurrentFrame = 0; float m_FrameTimer = 0.0f; diff --git a/Lumos/Source/Lumos/Graphics/Environment.cpp b/Lumos/Source/Lumos/Graphics/Environment.cpp index 4d869e5d..9ff61ea0 100644 --- a/Lumos/Source/Lumos/Graphics/Environment.cpp +++ b/Lumos/Source/Lumos/Graphics/Environment.cpp @@ -67,6 +67,10 @@ namespace Lumos if(m_FileType == ".hdr") { Application::Get().GetRenderPasses()->CreateCubeMap(m_FilePath + "_Env_" + StringUtilities::ToString(0) + "_" + StringUtilities::ToString(currWidth) + "x" + StringUtilities::ToString(currHeight) + m_FileType, m_Parameters, m_Environmnet, m_IrradianceMap); + + delete[] envFiles; + delete[] irrFiles; + return; } else @@ -128,9 +132,6 @@ namespace Lumos { LUMOS_LOG_ERROR("Failed to load environment"); } - - delete[] envFiles; - delete[] irrFiles; } } else // if (m_Mode == 1) @@ -138,6 +139,9 @@ namespace Lumos m_Parameters.w = m_Mode; Application::Get().GetRenderPasses()->CreateCubeMap("", m_Parameters, m_Environmnet, m_IrradianceMap); } + + delete[] envFiles; + delete[] irrFiles; } Environment::~Environment() diff --git a/Lumos/Source/Lumos/Graphics/Font.cpp b/Lumos/Source/Lumos/Graphics/Font.cpp index b1b5920a..50a7b0df 100644 --- a/Lumos/Source/Lumos/Graphics/Font.cpp +++ b/Lumos/Source/Lumos/Graphics/Font.cpp @@ -91,7 +91,10 @@ namespace Lumos if(std::filesystem::exists(filepath)) { storageBuffer.Allocate(uint32_t(FileSystem::GetFileSize(filepath.string()))); - storageBuffer.Write(FileSystem::ReadFile(filepath.string()), storageBuffer.Size); + auto data = FileSystem::ReadFile(filepath.string()); + storageBuffer.Write(data, storageBuffer.Size); + delete[] data; + header = *storageBuffer.As(); pixels = (uint8_t*)storageBuffer.Data + sizeof(AtlasHeader); return true; diff --git a/Lumos/Source/Lumos/Graphics/Material.cpp b/Lumos/Source/Lumos/Graphics/Material.cpp index 785125e3..c7e9969a 100644 --- a/Lumos/Source/Lumos/Graphics/Material.cpp +++ b/Lumos/Source/Lumos/Graphics/Material.cpp @@ -231,7 +231,7 @@ namespace Lumos::Graphics { // If no shader then set it to the default pbr shader // TODO default to forward - m_Shader = Application::Get().GetShaderLibrary()->GetResource("ForwardPBR"); + m_Shader = Application::Get().GetAssetManager()->GetAssetData("ForwardPBR").As(); } Graphics::DescriptorDesc descriptorDesc; @@ -260,7 +260,7 @@ namespace Lumos::Graphics void Material::SetShader(const std::string& filePath) { - m_Shader = Application::Get().GetShaderLibrary()->GetResource(filePath); + m_Shader = Application::Get().GetAssetManager()->GetAssetData("ForwardPBR").As(); } void Material::InitDefaultTexture() diff --git a/Lumos/Source/Lumos/Graphics/Material.h b/Lumos/Source/Lumos/Graphics/Material.h index 09591523..2fcc06b1 100644 --- a/Lumos/Source/Lumos/Graphics/Material.h +++ b/Lumos/Source/Lumos/Graphics/Material.h @@ -2,9 +2,6 @@ #include "RHI/Texture.h" #include "RHI/Shader.h" #include "Core/OS/FileSystem.h" -#include "Scene/Serialisation.h" - -#include "Maths/MathsSerialisation.h" namespace Lumos { @@ -46,6 +43,12 @@ namespace Lumos class LUMOS_EXPORT Material { + template + friend void save(Archive& archive, const Material& material); + + template + friend void load(Archive& archive, Material& material); + public: enum class RenderFlags { @@ -104,130 +107,6 @@ namespace Lumos static void InitDefaultTexture(); static void ReleaseDefaultTexture(); - template - void save(Archive& archive) const - { - std::string shaderPath = ""; - std::string albedoFilePath = m_PBRMaterialTextures.albedo ? FileSystem::Get().AbsolutePathToFileSystem(m_PBRMaterialTextures.albedo->GetFilepath()) : ""; - std::string normalFilePath = m_PBRMaterialTextures.normal ? FileSystem::Get().AbsolutePathToFileSystem(m_PBRMaterialTextures.normal->GetFilepath()) : ""; - std::string metallicFilePath = m_PBRMaterialTextures.metallic ? FileSystem::Get().AbsolutePathToFileSystem(m_PBRMaterialTextures.metallic->GetFilepath()) : ""; - std::string roughnessFilePath = m_PBRMaterialTextures.roughness ? FileSystem::Get().AbsolutePathToFileSystem(m_PBRMaterialTextures.roughness->GetFilepath()) : ""; - std::string emissiveFilePath = m_PBRMaterialTextures.emissive ? FileSystem::Get().AbsolutePathToFileSystem(m_PBRMaterialTextures.emissive->GetFilepath()) : ""; - std::string aoFilePath = m_PBRMaterialTextures.ao ? FileSystem::Get().AbsolutePathToFileSystem(m_PBRMaterialTextures.ao->GetFilepath()) : ""; - - if(m_Shader) - { - std::string path = m_Shader->GetFilePath() + m_Shader->GetName(); - FileSystem::Get().AbsolutePathToFileSystem(path, shaderPath); - } - - archive(cereal::make_nvp("Albedo", albedoFilePath), - cereal::make_nvp("Normal", normalFilePath), - cereal::make_nvp("Metallic", metallicFilePath), - cereal::make_nvp("Roughness", roughnessFilePath), - cereal::make_nvp("Ao", aoFilePath), - cereal::make_nvp("Emissive", emissiveFilePath), - cereal::make_nvp("albedoColour", m_MaterialProperties->albedoColour), - cereal::make_nvp("roughnessValue", m_MaterialProperties->roughness), - cereal::make_nvp("metallicValue", m_MaterialProperties->metallic), - cereal::make_nvp("emissiveValue", m_MaterialProperties->emissive), - cereal::make_nvp("albedoMapFactor", m_MaterialProperties->albedoMapFactor), - cereal::make_nvp("metallicMapFactor", m_MaterialProperties->metallicMapFactor), - cereal::make_nvp("roughnessMapFactor", m_MaterialProperties->roughnessMapFactor), - cereal::make_nvp("normalMapFactor", m_MaterialProperties->normalMapFactor), - cereal::make_nvp("aoMapFactor", m_MaterialProperties->occlusionMapFactor), - cereal::make_nvp("emissiveMapFactor", m_MaterialProperties->emissiveMapFactor), - cereal::make_nvp("alphaCutOff", m_MaterialProperties->alphaCutoff), - cereal::make_nvp("workflow", m_MaterialProperties->workflow), - cereal::make_nvp("shader", shaderPath)); - - archive(cereal::make_nvp("Reflectance", m_MaterialProperties->reflectance)); - } - - template - void load(Archive& archive) - { - std::string albedoFilePath; - std::string normalFilePath; - std::string roughnessFilePath; - std::string metallicFilePath; - std::string emissiveFilePath; - std::string aoFilePath; - std::string shaderFilePath; - - constexpr bool loadOldMaterial = false; - - if constexpr(loadOldMaterial) - { - glm::vec4 roughness, metallic, emissive; - archive(cereal::make_nvp("Albedo", albedoFilePath), - cereal::make_nvp("Normal", normalFilePath), - cereal::make_nvp("Metallic", metallicFilePath), - cereal::make_nvp("Roughness", roughnessFilePath), - cereal::make_nvp("Ao", aoFilePath), - cereal::make_nvp("Emissive", emissiveFilePath), - cereal::make_nvp("albedoColour", m_MaterialProperties->albedoColour), - cereal::make_nvp("roughnessColour", roughness), - cereal::make_nvp("metallicColour", metallic), - cereal::make_nvp("emissiveColour", emissive), - cereal::make_nvp("usingAlbedoMap", m_MaterialProperties->albedoMapFactor), - cereal::make_nvp("usingMetallicMap", m_MaterialProperties->metallicMapFactor), - cereal::make_nvp("usingRoughnessMap", m_MaterialProperties->roughnessMapFactor), - cereal::make_nvp("usingNormalMap", m_MaterialProperties->normalMapFactor), - cereal::make_nvp("usingAOMap", m_MaterialProperties->occlusionMapFactor), - cereal::make_nvp("usingEmissiveMap", m_MaterialProperties->emissiveMapFactor), - cereal::make_nvp("workflow", m_MaterialProperties->workflow), - cereal::make_nvp("shader", shaderFilePath)); - - m_MaterialProperties->emissive = emissive.x; - m_MaterialProperties->metallic = metallic.x; - m_MaterialProperties->roughness = roughness.x; - } - else - { - archive(cereal::make_nvp("Albedo", albedoFilePath), - cereal::make_nvp("Normal", normalFilePath), - cereal::make_nvp("Metallic", metallicFilePath), - cereal::make_nvp("Roughness", roughnessFilePath), - cereal::make_nvp("Ao", aoFilePath), - cereal::make_nvp("Emissive", emissiveFilePath), - cereal::make_nvp("albedoColour", m_MaterialProperties->albedoColour), - cereal::make_nvp("roughnessValue", m_MaterialProperties->roughness), - cereal::make_nvp("metallicValue", m_MaterialProperties->metallic), - cereal::make_nvp("emissiveValue", m_MaterialProperties->emissive), - cereal::make_nvp("albedoMapFactor", m_MaterialProperties->albedoMapFactor), - cereal::make_nvp("metallicMapFactor", m_MaterialProperties->metallicMapFactor), - cereal::make_nvp("roughnessMapFactor", m_MaterialProperties->roughnessMapFactor), - cereal::make_nvp("normalMapFactor", m_MaterialProperties->normalMapFactor), - cereal::make_nvp("aoMapFactor", m_MaterialProperties->occlusionMapFactor), - cereal::make_nvp("emissiveMapFactor", m_MaterialProperties->emissiveMapFactor), - cereal::make_nvp("alphaCutOff", m_MaterialProperties->alphaCutoff), - cereal::make_nvp("workflow", m_MaterialProperties->workflow), - cereal::make_nvp("shader", shaderFilePath)); - - if(Serialisation::CurrentSceneVersion > 19) - archive(cereal::make_nvp("Reflectance", m_MaterialProperties->reflectance)); - } - - // if(!shaderFilePath.empty()) - // SetShader(shaderFilePath); - // TODO: Support Custom Shaders; - m_Shader = nullptr; - - if(!albedoFilePath.empty()) - m_PBRMaterialTextures.albedo = SharedPtr(Graphics::Texture2D::CreateFromFile("albedo", albedoFilePath)); - if(!normalFilePath.empty()) - m_PBRMaterialTextures.normal = SharedPtr(Graphics::Texture2D::CreateFromFile("roughness", normalFilePath)); - if(!metallicFilePath.empty()) - m_PBRMaterialTextures.metallic = SharedPtr(Graphics::Texture2D::CreateFromFile("metallic", metallicFilePath)); - if(!roughnessFilePath.empty()) - m_PBRMaterialTextures.roughness = SharedPtr(Graphics::Texture2D::CreateFromFile("roughness", roughnessFilePath)); - if(!emissiveFilePath.empty()) - m_PBRMaterialTextures.emissive = SharedPtr(Graphics::Texture2D::CreateFromFile("emissive", emissiveFilePath)); - if(!aoFilePath.empty()) - m_PBRMaterialTextures.ao = SharedPtr(Graphics::Texture2D::CreateFromFile("ao", aoFilePath)); - } - uint32_t GetFlags() const { return m_Flags; }; bool GetFlag(RenderFlags flag) const { return (uint32_t)flag & m_Flags; }; void SetFlag(RenderFlags flag, bool value = true) diff --git a/Lumos/Source/Lumos/Graphics/Mesh.cpp b/Lumos/Source/Lumos/Graphics/Mesh.cpp index 417610bb..ddbf9fb4 100644 --- a/Lumos/Source/Lumos/Graphics/Mesh.cpp +++ b/Lumos/Source/Lumos/Graphics/Mesh.cpp @@ -3,6 +3,7 @@ #include "RHI/Renderer.h" #include +#include namespace Lumos { @@ -77,7 +78,43 @@ namespace Lumos m_Stats.OptimiseThreshold = optimiseThreshold; #endif - const bool storeData = false; + const bool storeData = true; + if(!storeData) + { + m_Indices.clear(); + m_Indices.shrink_to_fit(); + + m_Vertices.clear(); + m_Vertices.shrink_to_fit(); + } + } + + Mesh::Mesh(const std::vector& indices, const std::vector& vertices, const std::vector& boneInfluences) + { + // int lod = 2; + // float threshold = powf(0.7f, float(lod)); + m_Indices = indices; + m_Vertices = vertices; + + m_BoundingBox = CreateSharedPtr(); + + for(auto& vertex : m_Vertices) + { + m_BoundingBox->Merge(vertex.Position); + } + + m_IndexBuffer = SharedPtr(Graphics::IndexBuffer::Create(m_Indices.data(), (uint32_t)m_Indices.size())); + m_VertexBuffer = SharedPtr(VertexBuffer::Create((uint32_t)(sizeof(Graphics::Vertex) * m_Vertices.size()), m_Vertices.data(), BufferUsage::STATIC)); + m_BoneInfluenceBuffer = SharedPtr(VertexBuffer::Create((uint32_t)(sizeof(Graphics::BoneInfluence) * boneInfluences.size()), boneInfluences.data(), BufferUsage::STATIC)); + +#ifndef LUMOS_PRODUCTION + m_Stats.VertexCount = (uint32_t)m_Vertices.size(); + m_Stats.TriangleCount = m_Stats.VertexCount / 3; + m_Stats.IndexCount = (uint32_t)m_Indices.size(); + m_Stats.OptimiseThreshold = 1.0f; +#endif + + const bool storeData = true; if(!storeData) { m_Indices.clear(); diff --git a/Lumos/Source/Lumos/Graphics/Mesh.h b/Lumos/Source/Lumos/Graphics/Mesh.h index 4c908235..12bff074 100644 --- a/Lumos/Source/Lumos/Graphics/Mesh.h +++ b/Lumos/Source/Lumos/Graphics/Mesh.h @@ -118,6 +118,7 @@ namespace Lumos Mesh(); Mesh(const Mesh& mesh); Mesh(const std::vector& indices, const std::vector& vertices, bool optimise = false, float optimiseThreshold = 0.95f); + Mesh(const std::vector& indices, const std::vector& vertices, const std::vector& boneInfluences); virtual ~Mesh(); const SharedPtr& GetVertexBuffer() const { return m_VertexBuffer; } @@ -156,6 +157,9 @@ namespace Lumos } #endif + const std::vector& GetIndices() const { return m_Indices; } + const std::vector& GetVertices() const { return m_Vertices; } + protected: static glm::vec3 GenerateTangent(const glm::vec3& a, const glm::vec3& b, const glm::vec3& c, const glm::vec2& ta, const glm::vec2& tb, const glm::vec2& tc); diff --git a/Lumos/Source/Lumos/Graphics/ModelLoader/FBXLoader.cpp b/Lumos/Source/Lumos/Graphics/ModelLoader/FBXLoader.cpp index 49cf55d6..df9e36ce 100644 --- a/Lumos/Source/Lumos/Graphics/ModelLoader/FBXLoader.cpp +++ b/Lumos/Source/Lumos/Graphics/ModelLoader/FBXLoader.cpp @@ -190,8 +190,8 @@ namespace Lumos::Graphics SharedPtr LoadMaterial(const ofbx::Material* material, bool animated) { - // auto shader = animated ? Application::Get().GetShaderLibrary()->GetResource("//CoreShaders/ForwardPBR.shader") : Application::Get().GetShaderLibrary()->GetResource("//CoreShaders/ForwardPBR.shader"); - auto shader = Application::Get().GetShaderLibrary()->GetResource("ForwardPBR"); + // auto shader = animated ? Application::Get().GetShaderLibrary()->GetAsset("//CoreShaders/ForwardPBR.shader") : Application::Get().GetShaderLibrary()->GetAsset("//CoreShaders/ForwardPBR.shader"); + auto shader = Application::Get().GetAssetManager()->GetAssetData("ForwardPBR").As(); SharedPtr pbrMaterial = CreateSharedPtr(shader); diff --git a/Lumos/Source/Lumos/Graphics/ModelLoader/GLTFLoader.cpp b/Lumos/Source/Lumos/Graphics/ModelLoader/GLTFLoader.cpp index ea112370..81c0b8bc 100644 --- a/Lumos/Source/Lumos/Graphics/ModelLoader/GLTFLoader.cpp +++ b/Lumos/Source/Lumos/Graphics/ModelLoader/GLTFLoader.cpp @@ -194,8 +194,8 @@ namespace Lumos::Graphics for(tinygltf::Material& mat : gltfModel.materials) { // TODO : if(isAnimated) Load deferredColourAnimated; - // auto shader = Application::Get().GetShaderLibrary()->GetResource("//CoreShaders/ForwardPBR.shader"); - auto shader = Application::Get().GetShaderLibrary()->GetResource("ForwardPBR"); + // auto shader = Application::Get().GetShaderLibrary()->GetAsset("//CoreShaders/ForwardPBR.shader"); + auto shader = Application::Get().GetAssetManager()->GetAssetData("ForwardPBR").As(); SharedPtr pbrMaterial = CreateSharedPtr(shader); PBRMataterialTextures textures; @@ -313,6 +313,7 @@ namespace Lumos::Graphics std::vector indices; std::vector vertices; + std::vector boneInfluences; uint32_t vertexCount = (uint32_t)(primitive.attributes.empty() ? 0 : model.accessors.at(primitive.attributes["POSITION"]).count); @@ -321,6 +322,20 @@ namespace Lumos::Graphics bool hasTangents = false; bool hasBitangents = false; + bool hasWeights = false; + bool hasJoints = false; + + if(primitive.attributes.find("TANGENT") != primitive.attributes.end()) + hasTangents = true; + if(primitive.attributes.find("JOINTS_0") != primitive.attributes.end()) + hasJoints = true; + if(primitive.attributes.find("WEIGHTS_0") != primitive.attributes.end()) + hasWeights = true; + if(primitive.attributes.find("BITANGENT") != primitive.attributes.end()) + hasBitangents = true; + + if(hasJoints || hasWeights) + boneInfluences.resize(vertexCount); for(auto& attribute : primitive.attributes) { @@ -417,6 +432,37 @@ namespace Lumos::Graphics LUMOS_ASSERT(!glm::isinf(vertices[p].Bitangent.x) && !glm::isinf(vertices[p].Bitangent.y) && !glm::isinf(vertices[p].Bitangent.z) && !glm::isnan(vertices[p].Bitangent.x) && !glm::isnan(vertices[p].Bitangent.y) && !glm::isnan(vertices[p].Bitangent.z)); } } + + // -------- Weights attribute ----------- + + else if(attribute.first == "WEIGHTS_0") + { + hasWeights = true; + + size_t weightCount = accessor.count; + Maths::Vector4Simple* weights = reinterpret_cast(data.data()); + for(auto p = 0; p < weightCount; ++p) + { + boneInfluences[p].AddBoneData(static_cast(weights[p].x), weights[p].w); + } + } + + // -------- Joints attribute ----------- + + else if(attribute.first == "JOINTS_0") + { + hasJoints = true; + + size_t jointCount = accessor.count; + Maths::Vector4Simple* joints = reinterpret_cast(data.data()); + for(auto p = 0; p < jointCount; ++p) + { + boneInfluences[p].BoneInfoIndices[0] = static_cast(joints[p].x); + boneInfluences[p].BoneInfoIndices[0] = static_cast(joints[p].y); + boneInfluences[p].BoneInfoIndices[0] = static_cast(joints[p].z); + boneInfluences[p].BoneInfoIndices[0] = static_cast(joints[p].w); + } + } } // -------- Indices ---------- @@ -470,7 +516,13 @@ namespace Lumos::Graphics if(!hasTangents || !hasBitangents) Graphics::Mesh::GenerateTangentsAndBitangents(vertices.data(), uint32_t(vertices.size()), indices.data(), uint32_t(indices.size())); - auto lMesh = new Graphics::Mesh(indices, vertices); + // Add mesh + Graphics::Mesh* lMesh; + + if(hasJoints || hasWeights) + lMesh = new Graphics::Mesh(indices, vertices, boneInfluences); + else + lMesh = new Graphics::Mesh(indices, vertices); meshes.emplace_back(lMesh); } diff --git a/Lumos/Source/Lumos/Graphics/ModelLoader/OBJLoader.cpp b/Lumos/Source/Lumos/Graphics/ModelLoader/OBJLoader.cpp index cdd99853..531e96f7 100644 --- a/Lumos/Source/Lumos/Graphics/ModelLoader/OBJLoader.cpp +++ b/Lumos/Source/Lumos/Graphics/ModelLoader/OBJLoader.cpp @@ -130,8 +130,8 @@ namespace Lumos Graphics::Mesh::GenerateNormals(vertices.data(), vertexCount, indices.data(), numIndices); // TODO : if(isAnimated) Load deferredColourAnimated; - // auto shader = Application::Get().GetShaderLibrary()->GetResource("//CoreShaders/ForwardPBR.shader"); - auto shader = Application::Get().GetShaderLibrary()->GetResource("ForwardPBR"); + // auto shader = Application::Get().GetShaderLibrary()->GetAsset("//CoreShaders/ForwardPBR.shader"); + auto shader = Application::Get().GetAssetManager()->GetAssetData("ForwardPBR").As(); SharedPtr pbrMaterial = CreateSharedPtr(shader); diff --git a/Lumos/Source/Lumos/Graphics/ParticleManager.h b/Lumos/Source/Lumos/Graphics/ParticleManager.h index 8ee00a83..4b75334c 100644 --- a/Lumos/Source/Lumos/Graphics/ParticleManager.h +++ b/Lumos/Source/Lumos/Graphics/ParticleManager.h @@ -72,11 +72,11 @@ namespace Lumos } archive(newPath); - archive(m_LifeSpread); - archive(m_SortParticles); - archive(m_DepthWrite); - archive(m_BlendType); - archive(m_AlignedType); + archive(m_LifeSpread); + archive(m_SortParticles); + archive(m_DepthWrite); + archive((uint8_t)m_BlendType); + archive((uint8_t)m_AlignedType); } template @@ -112,14 +112,17 @@ namespace Lumos else m_Texture = nullptr; - if(SceneSerialisationVersion > 23) - { - archive(m_LifeSpread); - archive(m_SortParticles); - archive(m_DepthWrite); - archive(m_BlendType); - archive(m_AlignedType); - } + if(SceneSerialisationVersion > 23) + { + archive(m_LifeSpread); + archive(m_SortParticles); + archive(m_DepthWrite); + uint8_t value; + archive(value); + m_BlendType = (BlendType)value; + archive(value); + m_AlignedType = (AlignedType)value; + } Init(); } diff --git a/Lumos/Source/Lumos/Graphics/RHI/Definitions.h b/Lumos/Source/Lumos/Graphics/RHI/Definitions.h index f4c1216b..ee39d6e5 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Definitions.h +++ b/Lumos/Source/Lumos/Graphics/RHI/Definitions.h @@ -1,6 +1,6 @@ #pragma once #include "Core/LMLog.h" -#include +#include "Core/DataStructures/Vector.h" namespace Lumos { @@ -321,7 +321,7 @@ namespace Lumos DescriptorType type = DescriptorType::IMAGE_SAMPLER; ShaderType shaderType; - std::vector m_Members; + Vector m_Members; }; enum class CubeFace : uint8_t @@ -359,6 +359,7 @@ namespace Lumos int mipIndex = 0; int samples = 1; std::string DebugName; + Texture* resolveTexture = nullptr; }; struct TextureDesc @@ -367,7 +368,7 @@ namespace Lumos TextureFilter minFilter; TextureFilter magFilter; TextureWrap wrap; - uint16_t samples = 1; + uint8_t samples = 1; uint16_t flags = TextureFlags::Texture_CreateMips; bool srgb = false; bool generateMipMaps = true; @@ -449,7 +450,7 @@ namespace Lumos uint32_t offset = 0; std::string name; - std::vector m_Members; + Vector m_Members; void SetValue(const std::string& name, void* value) { diff --git a/Lumos/Source/Lumos/Graphics/RHI/DescriptorSet.h b/Lumos/Source/Lumos/Graphics/RHI/DescriptorSet.h index 7c24afb3..f0fa038e 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/DescriptorSet.h +++ b/Lumos/Source/Lumos/Graphics/RHI/DescriptorSet.h @@ -3,9 +3,9 @@ namespace Lumos { + struct Buffer; namespace Graphics { - struct DescriptorSetInfo { std::vector descriptors; @@ -23,12 +23,13 @@ namespace Lumos virtual void SetTexture(const std::string& name, Texture** texture, uint32_t textureCount, TextureType textureType = TextureType(0)) = 0; virtual void SetTexture(const std::string& name, Texture* texture, uint32_t mipIndex = 0, TextureType textureType = TextureType(0)) = 0; virtual void SetBuffer(const std::string& name, UniformBuffer* buffer) = 0; - virtual Graphics::UniformBuffer* GetUnifromBuffer(const std::string& name) = 0; + virtual Graphics::UniformBuffer* GetUniformBuffer(const std::string& name) = 0; virtual void SetUniform(const std::string& bufferName, const std::string& uniformName, void* data) = 0; virtual void SetUniform(const std::string& bufferName, const std::string& uniformName, void* data, uint32_t size) = 0; virtual void SetUniformBufferData(const std::string& bufferName, void* data) = 0; virtual void TransitionImages(CommandBuffer* commandBuffer = nullptr) { } virtual void SetUniformDynamic(const std::string& bufferName, uint32_t size) { } + virtual Buffer* GetUniformBufferLocalData(const std::string& name) { return nullptr; } protected: static DescriptorSet* (*CreateFunc)(const DescriptorDesc&); diff --git a/Lumos/Source/Lumos/Graphics/RHI/Framebuffer.cpp b/Lumos/Source/Lumos/Graphics/RHI/Framebuffer.cpp index c869b0b1..20a34cee 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Framebuffer.cpp +++ b/Lumos/Source/Lumos/Graphics/RHI/Framebuffer.cpp @@ -35,7 +35,7 @@ namespace Lumos { LUMOS_PROFILE_FUNCTION(); uint64_t hash = 0; - HashCombine(hash, framebufferDesc.attachmentCount, framebufferDesc.width, framebufferDesc.height, framebufferDesc.layer, framebufferDesc.screenFBO); + HashCombine(hash, framebufferDesc.attachmentCount, framebufferDesc.width, framebufferDesc.height, framebufferDesc.layer, framebufferDesc.screenFBO, framebufferDesc.samples); for(uint32_t i = 0; i < framebufferDesc.attachmentCount; i++) { diff --git a/Lumos/Source/Lumos/Graphics/RHI/Pipeline.cpp b/Lumos/Source/Lumos/Graphics/RHI/Pipeline.cpp index d7640256..14dab6cd 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Pipeline.cpp +++ b/Lumos/Source/Lumos/Graphics/RHI/Pipeline.cpp @@ -51,6 +51,11 @@ namespace Lumos } } + if(pipelineDesc.resolveTexture) + { + HashCombine(hash, pipelineDesc.resolveTexture->GetUUID()); + } + if(pipelineDesc.depthTarget) { HashCombine(hash, pipelineDesc.depthTarget->GetUUID()); @@ -69,6 +74,7 @@ namespace Lumos HashCombine(hash, pipelineDesc.cubeMapIndex); HashCombine(hash, pipelineDesc.cubeMapTarget); HashCombine(hash, pipelineDesc.mipIndex); + HashCombine(hash, pipelineDesc.samples); if(pipelineDesc.swapchainTarget) { diff --git a/Lumos/Source/Lumos/Graphics/RHI/Pipeline.h b/Lumos/Source/Lumos/Graphics/RHI/Pipeline.h index 9804f3c9..07a7e594 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Pipeline.h +++ b/Lumos/Source/Lumos/Graphics/RHI/Pipeline.h @@ -25,7 +25,7 @@ namespace Lumos bool DepthWrite = true; std::array colourTargets = {}; - + Texture* resolveTexture = nullptr; Texture* cubeMapTarget = nullptr; Texture* depthTarget = nullptr; Texture* depthArrayTarget = nullptr; @@ -35,7 +35,7 @@ namespace Lumos float depthBiasSlopeFactor = 0.0f; int cubeMapIndex = 0; int mipIndex = 0; - int samples = 1; + uint8_t samples = 1; const char* DebugName = nullptr; }; diff --git a/Lumos/Source/Lumos/Graphics/RHI/RenderPass.cpp b/Lumos/Source/Lumos/Graphics/RHI/RenderPass.cpp index 8fe465e0..acfad864 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/RenderPass.cpp +++ b/Lumos/Source/Lumos/Graphics/RHI/RenderPass.cpp @@ -34,7 +34,10 @@ namespace Lumos for(uint32_t i = 0; i < renderPassDesc.attachmentCount; i++) { - HashCombine(hash, renderPassDesc.attachmentTypes[i], renderPassDesc.attachments[i], renderPassDesc.cubeMapIndex, renderPassDesc.mipIndex); + HashCombine(hash, renderPassDesc.attachmentTypes[i], renderPassDesc.attachments[i], renderPassDesc.cubeMapIndex, renderPassDesc.mipIndex, renderPassDesc.samples); + + if(renderPassDesc.resolveTexture) + HashCombine(hash, renderPassDesc.resolveTexture->GetUUID()); if(renderPassDesc.attachments[i]) HashCombine(hash, renderPassDesc.attachments[i]->GetUUID()); @@ -82,5 +85,8 @@ namespace Lumos m_RenderPassCache.erase(keysToDelete[i]); } } + void RenderPass::BeginRenderPass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const + { + } } } diff --git a/Lumos/Source/Lumos/Graphics/RHI/RenderPass.h b/Lumos/Source/Lumos/Graphics/RHI/RenderPass.h index 39f0d7c0..51583cbd 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/RenderPass.h +++ b/Lumos/Source/Lumos/Graphics/RHI/RenderPass.h @@ -15,8 +15,8 @@ namespace Lumos static void ClearCache(); static void DeleteUnusedCache(); - virtual void BeginRenderpass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const = 0; - virtual void EndRenderpass(CommandBuffer* commandBuffer) = 0; + virtual void BeginRenderPass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const = 0; + virtual void EndRenderPass(CommandBuffer* commandBuffer) = 0; virtual int GetAttachmentCount() const = 0; protected: diff --git a/Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp b/Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp index 50258434..137f7e92 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp +++ b/Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp @@ -62,9 +62,9 @@ namespace Lumos { namespace Graphics { -#define LoadShaderEmbedded(name, vertName, fragName) shaderLibrary->AddResource(name, SharedPtr(Graphics::Shader::CreateFromEmbeddedArray(spirv_##vertName##vertspv.data(), spirv_##vertName##vertspv_size, spirv_##fragName##fragspv.data(), spirv_##fragName##fragspv_size))); -#define LoadComputeShaderEmbedded(name, compName) shaderLibrary->AddResource(name, SharedPtr(Graphics::Shader::CreateCompFromEmbeddedArray(spirv_##compName##compspv.data(), spirv_##compName##compspv_size))); -#define LoadShaderFromFile(name, path) shaderLibrary->AddResource(name, SharedPtr(Graphics::Shader::CreateFromFile(engineShaderPath + path))); +#define LoadShaderEmbedded(name, vertName, fragName) shaderLibrary->AddAsset(name, SharedPtr(Graphics::Shader::CreateFromEmbeddedArray(spirv_##vertName##vertspv.data(), spirv_##vertName##vertspv_size, spirv_##fragName##fragspv.data(), spirv_##fragName##fragspv_size)), true); +#define LoadComputeShaderEmbedded(name, compName) shaderLibrary->AddAsset(name, SharedPtr(Graphics::Shader::CreateCompFromEmbeddedArray(spirv_##compName##compspv.data(), spirv_##compName##compspv_size)), true); +#define LoadShaderFromFile(name, path) shaderLibrary->AddAsset(name, SharedPtr(Graphics::Shader::CreateFromFile(engineShaderPath + path)), true); Renderer* (*Renderer::CreateFunc)() = nullptr; @@ -88,7 +88,7 @@ namespace Lumos void Renderer::LoadEngineShaders(bool loadEmbeddedShaders, const std::string& engineShaderPath) { - auto shaderLibrary = Application::Get().GetShaderLibrary(); + auto shaderLibrary = Application::Get().GetAssetManager(); if(loadEmbeddedShaders) { LUMOS_LOG_INFO("Loading shaders - embedded"); diff --git a/Lumos/Source/Lumos/Graphics/RHI/Renderer.h b/Lumos/Source/Lumos/Graphics/RHI/Renderer.h index 7bce2a07..732bd0be 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Renderer.h +++ b/Lumos/Source/Lumos/Graphics/RHI/Renderer.h @@ -17,7 +17,7 @@ namespace Lumos std::string Renderer; std::string Version; - int MaxSamples = 0; + int MaxSamples = 1; float MaxAnisotropy = 0.0f; int MaxTextureUnits = 0; int UniformBufferOffsetAlignment = 0; diff --git a/Lumos/Source/Lumos/Graphics/RHI/Shader.h b/Lumos/Source/Lumos/Graphics/RHI/Shader.h index b479140c..246ab8e9 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Shader.h +++ b/Lumos/Source/Lumos/Graphics/RHI/Shader.h @@ -2,6 +2,7 @@ #include "DescriptorSet.h" #include "Definitions.h" #include "Core/Profiler.h" +#include "Core/Asset.h" namespace spirv_cross { @@ -11,7 +12,7 @@ namespace Lumos { namespace Graphics { - class LUMOS_EXPORT Shader + class LUMOS_EXPORT Shader : public Asset { public: static const Shader* s_CurrentlyBound; @@ -37,6 +38,8 @@ namespace Lumos ShaderDataType SPIRVTypeToLumosDataType(const spirv_cross::SPIRType type); + SET_ASSET_TYPE(AssetType::Shader); + public: static Shader* CreateFromFile(const std::string& filepath); static Shader* CreateFromEmbeddedArray(const uint32_t* vertData, uint32_t vertDataSize, const uint32_t* fragData, uint32_t fragDataSize); diff --git a/Lumos/Source/Lumos/Graphics/RHI/SwapChain.h b/Lumos/Source/Lumos/Graphics/RHI/SwapChain.h index 2e99d34c..eba7401b 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/SwapChain.h +++ b/Lumos/Source/Lumos/Graphics/RHI/SwapChain.h @@ -1,6 +1,7 @@ #pragma once #define MAX_FRAMES_FLIGHT 3 +#define MAX_ELEMENTS_PER_SET 32 namespace Lumos { class Window; diff --git a/Lumos/Source/Lumos/Graphics/RHI/Texture.cpp b/Lumos/Source/Lumos/Graphics/RHI/Texture.cpp index 3f4790f6..426bff75 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Texture.cpp +++ b/Lumos/Source/Lumos/Graphics/RHI/Texture.cpp @@ -11,8 +11,8 @@ namespace Lumos Texture2D* (*Texture2D::CreateFromSourceFunc)(uint32_t, uint32_t, void*, TextureDesc, TextureLoadOptions) = nullptr; Texture2D* (*Texture2D::CreateFromFileFunc)(const std::string&, const std::string&, TextureDesc, TextureLoadOptions) = nullptr; - TextureDepth* (*TextureDepth::CreateFunc)(uint32_t, uint32_t, RHIFormat) = nullptr; - TextureDepthArray* (*TextureDepthArray::CreateFunc)(uint32_t, uint32_t, uint32_t, RHIFormat) = nullptr; + TextureDepth* (*TextureDepth::CreateFunc)(uint32_t, uint32_t, RHIFormat, uint8_t) = nullptr; + TextureDepthArray* (*TextureDepthArray::CreateFunc)(uint32_t, uint32_t, uint32_t, RHIFormat) = nullptr; TextureCube* (*TextureCube::CreateFunc)(uint32_t, void*, bool) = nullptr; TextureCube* (*TextureCube::CreateFromFileFunc)(const std::string&) = nullptr; @@ -179,11 +179,11 @@ namespace Lumos return CreateFromVCrossFunc(files, mips, params, loadOptions); } - TextureDepth* TextureDepth::Create(uint32_t width, uint32_t height, RHIFormat format) + TextureDepth* TextureDepth::Create(uint32_t width, uint32_t height, RHIFormat format, uint8_t samples) { LUMOS_ASSERT(CreateFunc, "No TextureDepth Create Function"); - return CreateFunc(width, height, format); + return CreateFunc(width, height, format, samples); } TextureDepthArray* TextureDepthArray::Create(uint32_t width, uint32_t height, uint32_t count, RHIFormat format) diff --git a/Lumos/Source/Lumos/Graphics/RHI/Texture.h b/Lumos/Source/Lumos/Graphics/RHI/Texture.h index 3e63a01f..56d1832d 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Texture.h +++ b/Lumos/Source/Lumos/Graphics/RHI/Texture.h @@ -24,6 +24,7 @@ namespace Lumos virtual RHIFormat GetFormat() const = 0; virtual void GenerateMipMaps(CommandBuffer* commandBuffer = nullptr) { } virtual void SetName(const std::string& name) {}; + virtual uint8_t GetSamples() const { return 0; } virtual uint32_t GetSize() const { return 0; } virtual uint32_t GetMipMapLevels() const { return 0; } @@ -103,6 +104,8 @@ namespace Lumos static TextureCube* CreateFromFiles(const std::string* files); static TextureCube* CreateFromVCross(const std::string* files, uint32_t mips, TextureDesc params, TextureLoadOptions loadOptions); + virtual void Destroy(bool deletionQueue) { } + protected: static TextureCube* (*CreateFunc)(uint32_t, void*, bool); static TextureCube* (*CreateFromFileFunc)(const std::string&); @@ -113,12 +116,12 @@ namespace Lumos class LUMOS_EXPORT TextureDepth : public Texture { public: - static TextureDepth* Create(uint32_t width, uint32_t height, RHIFormat format = RHIFormat::D24_Unorm_S8_UInt); + static TextureDepth* Create(uint32_t width, uint32_t height, RHIFormat format = RHIFormat::D24_Unorm_S8_UInt, uint8_t samples = 1); virtual void Resize(uint32_t width, uint32_t height) = 0; protected: - static TextureDepth* (*CreateFunc)(uint32_t, uint32_t, RHIFormat); + static TextureDepth* (*CreateFunc)(uint32_t, uint32_t, RHIFormat, uint8_t); }; class LUMOS_EXPORT TextureDepthArray : public Texture diff --git a/Lumos/Source/Lumos/Graphics/Renderers/DebugRenderer.cpp b/Lumos/Source/Lumos/Graphics/Renderers/DebugRenderer.cpp index 5d2ac7c0..af3567a8 100644 --- a/Lumos/Source/Lumos/Graphics/Renderers/DebugRenderer.cpp +++ b/Lumos/Source/Lumos/Graphics/Renderers/DebugRenderer.cpp @@ -79,18 +79,11 @@ namespace Lumos s_Instance = nullptr; } - void DebugRenderer::Reset() + void DebugRenderer::Reset(float dt) { LUMOS_PROFILE_FUNCTION(); - s_Instance->m_DrawList.m_DebugTriangles.clear(); - s_Instance->m_DrawList.m_DebugLines.clear(); - s_Instance->m_DrawList.m_DebugThickLines.clear(); - s_Instance->m_DrawList.m_DebugPoints.clear(); - - s_Instance->m_DrawListNDT.m_DebugTriangles.clear(); - s_Instance->m_DrawListNDT.m_DebugLines.clear(); - s_Instance->m_DrawListNDT.m_DebugThickLines.clear(); - s_Instance->m_DrawListNDT.m_DebugPoints.clear(); + s_Instance->ClearDrawList(s_Instance->m_DrawList, dt); + s_Instance->ClearDrawList(s_Instance->m_DrawListNDT, dt); s_Instance->m_TextList.clear(); s_Instance->m_TextListNDT.clear(); @@ -99,6 +92,33 @@ namespace Lumos s_Instance->m_MaxStatusEntryWidth = 0.0f; } + void DebugRenderer::ClearDrawList(DebugDrawList& drawlist, float dt) + { + drawlist.m_DebugTriangles.erase(std::remove_if(drawlist.m_DebugTriangles.begin(), drawlist.m_DebugTriangles.end(), [dt](TriangleInfo& triangle) + { + triangle.time -= dt; + return triangle.time <= Maths::M_EPSILON; }), + drawlist.m_DebugTriangles.end()); + + drawlist.m_DebugLines.erase(std::remove_if(drawlist.m_DebugLines.begin(), drawlist.m_DebugLines.end(), [dt](LineInfo& line) + { + line.time -= dt; + return line.time <= Maths::M_EPSILON; }), + drawlist.m_DebugLines.end()); + + drawlist.m_DebugThickLines.erase(std::remove_if(drawlist.m_DebugThickLines.begin(), drawlist.m_DebugThickLines.end(), [dt](LineInfo& line) + { + line.time -= dt; + return line.time <= Maths::M_EPSILON; }), + drawlist.m_DebugThickLines.end()); + + drawlist.m_DebugPoints.erase(std::remove_if(drawlist.m_DebugPoints.begin(), drawlist.m_DebugPoints.end(), [dt](PointInfo& point) + { + point.time -= dt; + return point.time <= Maths::M_EPSILON; }), + drawlist.m_DebugPoints.end()); + } + void DebugRenderer::ClearLogEntries() { s_Instance->m_vLogEntries.clear(); @@ -135,162 +155,91 @@ namespace Lumos } // Draw Point (circle) - void DebugRenderer::GenDrawPoint(bool ndt, const glm::vec3& pos, float point_radius, const glm::vec4& colour) + void DebugRenderer::GenDrawPoint(bool ndt, const glm::vec3& pos, float point_radius, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); if(ndt) - s_Instance->m_DrawListNDT.m_DebugPoints.emplace_back(pos, point_radius, colour); + s_Instance->m_DrawListNDT.m_DebugPoints.emplace_back(pos, point_radius, colour, time); else - s_Instance->m_DrawList.m_DebugPoints.emplace_back(pos, point_radius, colour); + s_Instance->m_DrawList.m_DebugPoints.emplace_back(pos, point_radius, colour, time); } - void DebugRenderer::DrawPoint(const glm::vec3& pos, float point_radius, const glm::vec3& colour) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawPoint(false, pos, point_radius, glm::vec4(colour, 1.0f)); - } - void DebugRenderer::DrawPoint(const glm::vec3& pos, float point_radius, const glm::vec4& colour) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawPoint(false, pos, point_radius, colour); - } - void DebugRenderer::DrawPointNDT(const glm::vec3& pos, float point_radius, const glm::vec3& colour) + void DebugRenderer::DrawPoint(const glm::vec3& pos, float point_radius, bool depthTested, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); - GenDrawPoint(true, pos, point_radius, glm::vec4(colour, 1.0f)); - } - void DebugRenderer::DrawPointNDT(const glm::vec3& pos, float point_radius, const glm::vec4& colour) - { - GenDrawPoint(true, pos, point_radius, colour); + GenDrawPoint(!depthTested, pos, point_radius, colour, time); } // Draw Line with a given thickness - void DebugRenderer::GenDrawThickLine(bool ndt, const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec4& colour) + void DebugRenderer::GenDrawThickLine(bool ndt, const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); if(ndt) - s_Instance->m_DrawListNDT.m_DebugThickLines.emplace_back(start, end, colour); + s_Instance->m_DrawListNDT.m_DebugThickLines.emplace_back(start, end, colour, time); else - s_Instance->m_DrawList.m_DebugThickLines.emplace_back(start, end, colour); - } - void DebugRenderer::DrawThickLine(const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec3& colour) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawThickLine(false, start, end, line_width, glm::vec4(colour, 1.0f)); - } - void DebugRenderer::DrawThickLine(const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec4& colour) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawThickLine(false, start, end, line_width, colour); - } - void DebugRenderer::DrawThickLineNDT(const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec3& colour) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawThickLine(true, start, end, line_width, glm::vec4(colour, 1.0f)); + s_Instance->m_DrawList.m_DebugThickLines.emplace_back(start, end, colour, time); } - void DebugRenderer::DrawThickLineNDT(const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec4& colour) + + void DebugRenderer::DrawThickLine(const glm::vec3& start, const glm::vec3& end, float line_width, bool depthTested, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); - GenDrawThickLine(true, start, end, line_width, colour); + GenDrawThickLine(!depthTested, start, end, line_width, colour, time); } // Draw line with thickness of 1 screen pixel regardless of distance from camera - void DebugRenderer::GenDrawHairLine(bool ndt, const glm::vec3& start, const glm::vec3& end, const glm::vec4& colour) + void DebugRenderer::GenDrawHairLine(bool ndt, const glm::vec3& start, const glm::vec3& end, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); if(ndt) - s_Instance->m_DrawListNDT.m_DebugLines.emplace_back(start, end, colour); + s_Instance->m_DrawListNDT.m_DebugLines.emplace_back(start, end, colour, time); else - s_Instance->m_DrawList.m_DebugLines.emplace_back(start, end, colour); - } - void DebugRenderer::DrawHairLine(const glm::vec3& start, const glm::vec3& end, const glm::vec3& colour) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawHairLine(false, start, end, glm::vec4(colour, 1.0f)); - } - void DebugRenderer::DrawHairLine(const glm::vec3& start, const glm::vec3& end, const glm::vec4& colour) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawHairLine(false, start, end, colour); - } - void DebugRenderer::DrawHairLineNDT(const glm::vec3& start, const glm::vec3& end, const glm::vec3& colour) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawHairLine(true, start, end, glm::vec4(colour, 1.0f)); + s_Instance->m_DrawList.m_DebugLines.emplace_back(start, end, colour, time); } - void DebugRenderer::DrawHairLineNDT(const glm::vec3& start, const glm::vec3& end, const glm::vec4& colour) + + void DebugRenderer::DrawHairLine(const glm::vec3& start, const glm::vec3& end, bool depthTested, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); - GenDrawHairLine(true, start, end, colour); + GenDrawHairLine(!depthTested, start, end, colour, time); } // Draw Matrix (x,y,z axis at pos) - void DebugRenderer::DrawMatrix(const glm::mat4& mtx) - { - LUMOS_PROFILE_FUNCTION(); - // glm::vec3 position = mtx[3]; - // GenDrawHairLine(false, position, position + glm::vec3(mtx[0], mtx[1], mtx[2]), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); - // GenDrawHairLine(false, position, position + glm::vec3(mtx[4], mtx[5], mtx[6]), glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); - // GenDrawHairLine(false, position, position + glm::vec3(mtx[8], mtx[9], mtx[10]), glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); - } - void DebugRenderer::DrawMatrix(const glm::mat3& mtx, const glm::vec3& position) + void DebugRenderer::DrawMatrix(const glm::mat4& mtx, bool depthTested, float time) { LUMOS_PROFILE_FUNCTION(); - GenDrawHairLine(false, position, position + mtx[0], glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); - GenDrawHairLine(false, position, position + mtx[1], glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); - GenDrawHairLine(false, position, position + mtx[2], glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); + // glm::vec3 position = glm::vec3(mtx[3].x, mtx[3].y, mtx[3].z); + // GenDrawHairLine(!depthTested, position, position + glm::vec3(mtx[0], mtx[1], mtx[2]), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f), time); + // GenDrawHairLine(!depthTested, position, position + glm::vec3(mtx[4], mtx[5], mtx[6]), glm::vec4(0.0f, 1.0f, 0.0f, 1.0f), time); + // GenDrawHairLine(!depthTested, position, position + glm::vec3(mtx[8], mtx[9], mtx[10]), glm::vec4(0.0f, 0.0f, 1.0f, 1.0f), time); } - void DebugRenderer::DrawMatrixNDT(const glm::mat4& mtx) + void DebugRenderer::DrawMatrix(const glm::mat3& mtx, const glm::vec3& position, bool depthTested, float time) { LUMOS_PROFILE_FUNCTION(); - // glm::vec3 position = mtx[3]; - // GenDrawHairLine(true, position, position + glm::vec3(mtx[0], mtx[1], mtx[2]), glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); - // GenDrawHairLine(true, position, position + glm::vec3(mtx[4], mtx[5], mtx[6]), glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); - // GenDrawHairLine(true, position, position + glm::vec3(mtx[8], mtx[9], mtx[10]), glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); - } - void DebugRenderer::DrawMatrixNDT(const glm::mat3& mtx, const glm::vec3& position) - { - LUMOS_PROFILE_FUNCTION(); - GenDrawHairLine(true, position, position + mtx[0], glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); - GenDrawHairLine(true, position, position + mtx[1], glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); - GenDrawHairLine(true, position, position + mtx[2], glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); + // s } // Draw Triangle - void DebugRenderer::GenDrawTriangle(bool ndt, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, const glm::vec4& colour) - { - LUMOS_PROFILE_FUNCTION(); - s_Instance->m_DrawList.m_DebugTriangles.emplace_back(v0, v1, v2, colour); - } - - void DebugRenderer::DrawTriangle(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, const glm::vec4& colour) + void DebugRenderer::GenDrawTriangle(bool ndt, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); - GenDrawTriangle(false, v0, v1, v2, colour); + if(ndt) + s_Instance->m_DrawListNDT.m_DebugTriangles.emplace_back(v0, v1, v2, colour, time); + else + s_Instance->m_DrawList.m_DebugTriangles.emplace_back(v0, v1, v2, colour, time); } - void DebugRenderer::DrawTriangleNDT(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, const glm::vec4& colour) + void DebugRenderer::DrawTriangle(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, bool depthTested, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); - GenDrawTriangle(true, v0, v1, v2, colour); + GenDrawTriangle(!depthTested, v0, v1, v2, colour, time); } // Draw Polygon (Renders as a triangle fan, so verts must be arranged in order) - void DebugRenderer::DrawPolygon(int n_verts, const glm::vec3* verts, const glm::vec4& colour) + void DebugRenderer::DrawPolygon(int n_verts, const glm::vec3* verts, bool depthTested, const glm::vec4& colour, float time) { LUMOS_PROFILE_FUNCTION(); for(int i = 2; i < n_verts; ++i) { - GenDrawTriangle(false, verts[0], verts[i - 1], verts[i], colour); - } - } - - void DebugRenderer::DrawPolygonNDT(int n_verts, const glm::vec3* verts, const glm::vec4& colour) - { - LUMOS_PROFILE_FUNCTION(); - for(int i = 2; i < n_verts; ++i) - { - GenDrawTriangle(true, verts[0], verts[i - 1], verts[i], colour); + GenDrawTriangle(!depthTested, verts[0], verts[i - 1], verts[i], colour, time); } } @@ -325,32 +274,7 @@ namespace Lumos } // Draw Text WorldSpace - void DebugRenderer::DrawTextWs(const glm::vec3& pos, const float font_size, const glm::vec4& colour, const std::string text, ...) - { - va_list args; - va_start(args, text); - - char buf[1024]; - - int needed = VSNPRINTF(buf, 1023, _TRUNCATE, text.c_str(), args); - - va_end(args); - - int length = (needed < 0) ? 1024 : needed; - - std::string formatted_text = std::string(buf, static_cast(length)); - - // glm::vec4 cs_pos = GetInstance()->m_ProjViewMtx * glm::vec4(pos, 1.0f); - // DrawTextCs(cs_pos, font_size, formatted_text, colour); - - DebugText& dText = GetInstance()->m_TextList.emplace_back(); - dText.text = text; - dText.Position = glm::vec4(pos, 1.0f); - dText.colour = colour; - dText.Size = font_size; - } - - void DebugRenderer::DrawTextWsNDT(const glm::vec3& pos, const float font_size, const glm::vec4& colour, const std::string text, ...) + void DebugRenderer::DrawTextWs(const glm::vec3& pos, const float font_size, bool depthTested, const glm::vec4& colour, float time, const std::string text, ...) { va_list args; va_start(args, text); @@ -366,14 +290,14 @@ namespace Lumos std::string formatted_text = std::string(buf, static_cast(length)); // glm::vec4 cs_pos = GetInstance()->m_ProjViewMtx * glm::vec4(pos, 1.0f); - // cs_pos.z = (1.0f * cs_pos.w); // DrawTextCs(cs_pos, font_size, formatted_text, colour); - DebugText& dText = GetInstance()->m_TextListNDT.emplace_back(); + DebugText& dText = depthTested ? GetInstance()->m_TextList.emplace_back() : GetInstance()->m_TextListNDT.emplace_back(); dText.text = text; dText.Position = glm::vec4(pos, 1.0f); dText.colour = colour; dText.Size = font_size; + dText.time = time; } // Status Entry @@ -496,65 +420,52 @@ namespace Lumos // Draw edges if(!cornersOnly) { - DrawThickLineNDT(luu, uuu, width, edgeColour); - DrawThickLineNDT(lul, uul, width, edgeColour); - DrawThickLineNDT(llu, ulu, width, edgeColour); - DrawThickLineNDT(lll, ull, width, edgeColour); - - DrawThickLineNDT(lul, lll, width, edgeColour); - DrawThickLineNDT(uul, ull, width, edgeColour); - DrawThickLineNDT(luu, llu, width, edgeColour); - DrawThickLineNDT(uuu, ulu, width, edgeColour); - - DrawThickLineNDT(lll, llu, width, edgeColour); - DrawThickLineNDT(ull, ulu, width, edgeColour); - DrawThickLineNDT(lul, luu, width, edgeColour); - DrawThickLineNDT(uul, uuu, width, edgeColour); + DrawThickLine(luu, uuu, width, false, edgeColour); + DrawThickLine(lul, uul, width, false, edgeColour); + DrawThickLine(llu, ulu, width, false, edgeColour); + DrawThickLine(lll, ull, width, false, edgeColour); + DrawThickLine(lul, lll, width, false, edgeColour); + DrawThickLine(uul, ull, width, false, edgeColour); + DrawThickLine(luu, llu, width, false, edgeColour); + DrawThickLine(uuu, ulu, width, false, edgeColour); + DrawThickLine(lll, llu, width, false, edgeColour); + DrawThickLine(ull, ulu, width, false, edgeColour); + DrawThickLine(lul, luu, width, false, edgeColour); + DrawThickLine(uul, uuu, width, false, edgeColour); } else { - DrawThickLineNDT(luu, luu + (uuu - luu) * 0.25f, width, edgeColour); - DrawThickLineNDT(luu + (uuu - luu) * 0.75f, uuu, width, edgeColour); - - DrawThickLineNDT(lul, lul + (uul - lul) * 0.25f, width, edgeColour); - DrawThickLineNDT(lul + (uul - lul) * 0.75f, uul, width, edgeColour); - - DrawThickLineNDT(llu, llu + (ulu - llu) * 0.25f, width, edgeColour); - DrawThickLineNDT(llu + (ulu - llu) * 0.75f, ulu, width, edgeColour); - - DrawThickLineNDT(lll, lll + (ull - lll) * 0.25f, width, edgeColour); - DrawThickLineNDT(lll + (ull - lll) * 0.75f, ull, width, edgeColour); - - DrawThickLineNDT(lul, lul + (lll - lul) * 0.25f, width, edgeColour); - DrawThickLineNDT(lul + (lll - lul) * 0.75f, lll, width, edgeColour); - - DrawThickLineNDT(uul, uul + (ull - uul) * 0.25f, width, edgeColour); - DrawThickLineNDT(uul + (ull - uul) * 0.75f, ull, width, edgeColour); - - DrawThickLineNDT(luu, luu + (llu - luu) * 0.25f, width, edgeColour); - DrawThickLineNDT(luu + (llu - luu) * 0.75f, llu, width, edgeColour); - - DrawThickLineNDT(uuu, uuu + (ulu - uuu) * 0.25f, width, edgeColour); - DrawThickLineNDT(uuu + (ulu - uuu) * 0.75f, ulu, width, edgeColour); - - DrawThickLineNDT(lll, lll + (llu - lll) * 0.25f, width, edgeColour); - DrawThickLineNDT(lll + (llu - lll) * 0.75f, llu, width, edgeColour); - - DrawThickLineNDT(ull, ull + (ulu - ull) * 0.25f, width, edgeColour); - DrawThickLineNDT(ull + (ulu - ull) * 0.75f, ulu, width, edgeColour); - - DrawThickLineNDT(lul, lul + (luu - lul) * 0.25f, width, edgeColour); - DrawThickLineNDT(lul + (luu - lul) * 0.75f, luu, width, edgeColour); - - DrawThickLineNDT(uul, uul + (uuu - uul) * 0.25f, width, edgeColour); - DrawThickLineNDT(uul + (uuu - uul) * 0.75f, uuu, width, edgeColour); + DrawThickLine(luu, luu + (uuu - luu) * 0.25f, width, false, edgeColour); + DrawThickLine(luu + (uuu - luu) * 0.75f, uuu, width, false, edgeColour); + DrawThickLine(lul, lul + (uul - lul) * 0.25f, width, false, edgeColour); + DrawThickLine(lul + (uul - lul) * 0.75f, uul, width, false, edgeColour); + DrawThickLine(llu, llu + (ulu - llu) * 0.25f, width, false, edgeColour); + DrawThickLine(llu + (ulu - llu) * 0.75f, ulu, width, false, edgeColour); + DrawThickLine(lll, lll + (ull - lll) * 0.25f, width, false, edgeColour); + DrawThickLine(lll + (ull - lll) * 0.75f, ull, width, false, edgeColour); + DrawThickLine(lul, lul + (lll - lul) * 0.25f, width, false, edgeColour); + DrawThickLine(lul + (lll - lul) * 0.75f, lll, width, false, edgeColour); + DrawThickLine(uul, uul + (ull - uul) * 0.25f, width, false, edgeColour); + DrawThickLine(uul + (ull - uul) * 0.75f, ull, width, false, edgeColour); + DrawThickLine(luu, luu + (llu - luu) * 0.25f, width, false, edgeColour); + DrawThickLine(luu + (llu - luu) * 0.75f, llu, width, false, edgeColour); + DrawThickLine(uuu, uuu + (ulu - uuu) * 0.25f, width, false, edgeColour); + DrawThickLine(uuu + (ulu - uuu) * 0.75f, ulu, width, false, edgeColour); + DrawThickLine(lll, lll + (llu - lll) * 0.25f, width, false, edgeColour); + DrawThickLine(lll + (llu - lll) * 0.75f, llu, width, false, edgeColour); + DrawThickLine(ull, ull + (ulu - ull) * 0.25f, width, false, edgeColour); + DrawThickLine(ull + (ulu - ull) * 0.75f, ulu, width, false, edgeColour); + DrawThickLine(lul, lul + (luu - lul) * 0.25f, width, false, edgeColour); + DrawThickLine(lul + (luu - lul) * 0.75f, luu, width, false, edgeColour); + DrawThickLine(uul, uul + (uuu - uul) * 0.25f, width, false, edgeColour); + DrawThickLine(uul + (uuu - uul) * 0.75f, uuu, width, false, edgeColour); } } void DebugRenderer::DebugDraw(const Maths::BoundingSphere& sphere, const glm::vec4& colour) { LUMOS_PROFILE_FUNCTION(); - Lumos::DebugRenderer::DrawPointNDT(sphere.GetCenter(), sphere.GetRadius(), colour); + Lumos::DebugRenderer::DrawPoint(sphere.GetCenter(), sphere.GetRadius(), false, colour); } void DebugRenderer::DebugDraw(Maths::Frustum& frustum, const glm::vec4& colour) @@ -562,18 +473,18 @@ namespace Lumos LUMOS_PROFILE_FUNCTION(); auto* vertices = frustum.GetVerticies(); - DebugRenderer::DrawHairLine(vertices[0], vertices[1], colour); - DebugRenderer::DrawHairLine(vertices[1], vertices[2], colour); - DebugRenderer::DrawHairLine(vertices[2], vertices[3], colour); - DebugRenderer::DrawHairLine(vertices[3], vertices[0], colour); - DebugRenderer::DrawHairLine(vertices[4], vertices[5], colour); - DebugRenderer::DrawHairLine(vertices[5], vertices[6], colour); - DebugRenderer::DrawHairLine(vertices[6], vertices[7], colour); - DebugRenderer::DrawHairLine(vertices[7], vertices[4], colour); - DebugRenderer::DrawHairLine(vertices[0], vertices[4], colour); - DebugRenderer::DrawHairLine(vertices[1], vertices[5], colour); - DebugRenderer::DrawHairLine(vertices[2], vertices[6], colour); - DebugRenderer::DrawHairLine(vertices[3], vertices[7], colour); + DebugRenderer::DrawHairLine(vertices[0], vertices[1], false, colour); + DebugRenderer::DrawHairLine(vertices[1], vertices[2], false, colour); + DebugRenderer::DrawHairLine(vertices[2], vertices[3], false, colour); + DebugRenderer::DrawHairLine(vertices[3], vertices[0], false, colour); + DebugRenderer::DrawHairLine(vertices[4], vertices[5], false, colour); + DebugRenderer::DrawHairLine(vertices[5], vertices[6], false, colour); + DebugRenderer::DrawHairLine(vertices[6], vertices[7], false, colour); + DebugRenderer::DrawHairLine(vertices[7], vertices[4], false, colour); + DebugRenderer::DrawHairLine(vertices[0], vertices[4], false, colour); + DebugRenderer::DrawHairLine(vertices[1], vertices[5], false, colour); + DebugRenderer::DrawHairLine(vertices[2], vertices[6], false, colour); + DebugRenderer::DrawHairLine(vertices[3], vertices[7], false, colour); } void DebugRenderer::DebugDraw(Graphics::Light* light, const glm::quat& rotation, const glm::vec4& colour) @@ -583,10 +494,10 @@ namespace Lumos if(light->Type < 0.1f) { glm::vec3 offset(0.0f, 0.1f, 0.0f); - DrawHairLine(glm::vec3(light->Position) + offset, glm::vec3(light->Position + (light->Direction) * 2.0f) + offset, colour); - DrawHairLine(glm::vec3(light->Position) - offset, glm::vec3(light->Position + (light->Direction) * 2.0f) - offset, colour); + DrawHairLine(glm::vec3(light->Position) + offset, glm::vec3(light->Position + (light->Direction) * 2.0f) + offset, false, colour); + DrawHairLine(glm::vec3(light->Position) - offset, glm::vec3(light->Position + (light->Direction) * 2.0f) - offset, false, colour); - DrawHairLine(glm::vec3(light->Position), glm::vec3(light->Position + (light->Direction) * 2.0f), colour); + DrawHairLine(glm::vec3(light->Position), glm::vec3(light->Position + (light->Direction) * 2.0f), false, colour); DebugDrawCone(20, 4, 30.0f, 1.5f, (light->Position - (light->Direction) * 1.5f), rotation, colour); } // Spot @@ -604,7 +515,7 @@ namespace Lumos void DebugRenderer::DebugDraw(SoundNode* sound, const glm::vec4& colour) { LUMOS_PROFILE_FUNCTION(); - DrawPoint(sound->GetPosition(), sound->GetRadius(), colour); + DrawPoint(sound->GetPosition(), sound->GetRadius(), false, colour); } void DebugRenderer::DebugDrawCircle(int numVerts, float radius, const glm::vec3& position, const glm::quat& rotation, const glm::vec4& colour) @@ -622,7 +533,7 @@ namespace Lumos float ny = Maths::Sin(step * (i + 1)) * radius; glm::vec3 next = glm::vec3(nx, ny, 0.0f); - DrawHairLine(position + (rotation * current), position + (rotation * next), colour); + DrawHairLine(position + (rotation * current), position + (rotation * next), false, colour); } } void DebugRenderer::DebugDrawSphere(float radius, const glm::vec3& position, const glm::vec4& colour) @@ -647,7 +558,7 @@ namespace Lumos { float a = i * 90.0f; glm::vec3 point = rotation * glm::vec3(Maths::Cos(a), Maths::Sin(a), 0.0f) * endAngle; - DrawHairLine(position, position + point + forward * length, colour); + DrawHairLine(position, position + point + forward * length, false, colour); } } @@ -669,7 +580,7 @@ namespace Lumos float ny = Maths::Sin(step * (i + 1)) * radius; glm::vec3 next = glm::vec3(nx, ny, 0.0f); - DebugRenderer::DrawHairLine(arcCentre + (rot * current), arcCentre + (rot * next), colour); + DebugRenderer::DrawHairLine(arcCentre + (rot * current), arcCentre + (rot * next), false, colour); } } @@ -693,7 +604,7 @@ namespace Lumos float x = Maths::Sin(step * i) * radius; glm::vec3 offset = rotation * glm::vec4(x, 0.0f, z, 0.0f); - DrawHairLine(bottomSphereCentre + offset, topSphereCentre + offset, colour); + DrawHairLine(bottomSphereCentre + offset, topSphereCentre + offset, false, colour); if(i < 10) { @@ -712,7 +623,7 @@ namespace Lumos void DebugRenderer::DebugDraw(const Maths::Ray& ray, const glm::vec4& colour, float distance) { LUMOS_PROFILE_FUNCTION(); - DrawHairLine(ray.Origin, ray.Origin + ray.Direction * distance, colour); + DrawHairLine(ray.Origin, ray.Origin + ray.Direction * distance, false, colour); } } diff --git a/Lumos/Source/Lumos/Graphics/Renderers/DebugRenderer.h b/Lumos/Source/Lumos/Graphics/Renderers/DebugRenderer.h index 85bdad96..840a4a91 100644 --- a/Lumos/Source/Lumos/Graphics/Renderers/DebugRenderer.h +++ b/Lumos/Source/Lumos/Graphics/Renderers/DebugRenderer.h @@ -22,6 +22,7 @@ namespace Lumos std::string text; float Size; glm::vec4 Position; + float time; }; namespace Graphics @@ -54,11 +55,14 @@ namespace Lumos glm::vec3 p2; glm::vec4 col; - LineInfo(const glm::vec3& pos1, const glm::vec3& pos2, const glm::vec4& colour) + float time = 0.0f; + + LineInfo(const glm::vec3& pos1, const glm::vec3& pos2, const glm::vec4& colour, float t = 0.0f) { - p1 = pos1; - p2 = pos2; - col = colour; + p1 = pos1; + p2 = pos2; + col = colour; + time = t; } }; @@ -67,12 +71,14 @@ namespace Lumos glm::vec3 p1; glm::vec4 col; float size; + float time = 0.0f; - PointInfo(const glm::vec3& pos1, float s, const glm::vec4& colour) + PointInfo(const glm::vec3& pos1, float s, const glm::vec4& colour, float t = 0.0f) { p1 = pos1; size = s; col = colour; + time = t; } }; @@ -82,13 +88,15 @@ namespace Lumos glm::vec3 p2; glm::vec3 p3; glm::vec4 col; + float time = 0.0f; - TriangleInfo(const glm::vec3& pos1, const glm::vec3& pos2, const glm::vec3& pos3, const glm::vec4& colour) + TriangleInfo(const glm::vec3& pos1, const glm::vec3& pos2, const glm::vec3& pos3, const glm::vec4& colour, float t = 0.0f) { - p1 = pos1; - p2 = pos2; - p3 = pos3; - col = colour; + p1 = pos1; + p2 = pos2; + p3 = pos3; + col = colour; + time = t; } }; @@ -111,7 +119,7 @@ namespace Lumos public: static void Init(); static void Release(); - static void Reset(); + static void Reset(float dt); DebugRenderer(); ~DebugRenderer(); @@ -119,40 +127,26 @@ namespace Lumos // Note: Functions appended with 'NDT' (no depth testing) will always be rendered in the foreground. This can be useful for debugging things inside objects. // Draw Point (circle) - static void DrawPoint(const glm::vec3& pos, float point_radius, const glm::vec3& colour); - static void DrawPoint(const glm::vec3& pos, float point_radius, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - static void DrawPointNDT(const glm::vec3& pos, float point_radius, const glm::vec3& colour); - static void DrawPointNDT(const glm::vec3& pos, float point_radius, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + static void DrawPoint(const glm::vec3& pos, float point_radius, bool depthTested = false, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), float time = 0.0f); // Draw Line with a given thickness - static void DrawThickLine(const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec3& colour); - static void DrawThickLine(const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - static void DrawThickLineNDT(const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec3& colour); - static void DrawThickLineNDT(const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + static void DrawThickLine(const glm::vec3& start, const glm::vec3& end, float line_width, bool depthTested = false, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), float time = 0.0f); // Draw line with thickness of 1 screen pixel regardless of distance from camera - static void DrawHairLine(const glm::vec3& start, const glm::vec3& end, const glm::vec3& colour); - static void DrawHairLine(const glm::vec3& start, const glm::vec3& end, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - static void DrawHairLineNDT(const glm::vec3& start, const glm::vec3& end, const glm::vec3& colour); - static void DrawHairLineNDT(const glm::vec3& start, const glm::vec3& end, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + static void DrawHairLine(const glm::vec3& start, const glm::vec3& end, bool depthTested = false, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), float time = 0.0f); // Draw Matrix (x,y,z axis at pos) - static void DrawMatrix(const glm::mat4& transform_mtx); - static void DrawMatrix(const glm::mat3& rotation_mtx, const glm::vec3& position); - static void DrawMatrixNDT(const glm::mat4& transform_mtx); - static void DrawMatrixNDT(const glm::mat3& rotation_mtx, const glm::vec3& position); + static void DrawMatrix(const glm::mat4& transform_mtx, bool depthTested = false, float time = 0.0f); + static void DrawMatrix(const glm::mat3& rotation_mtx, const glm::vec3& position, bool depthTested = false, float time = 0.0f); // Draw Triangle - static void DrawTriangle(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - static void DrawTriangleNDT(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + static void DrawTriangle(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, bool depthTested = false, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), float time = 0.0f); // Draw Polygon (Renders as a triangle fan, so verts must be arranged in order) - static void DrawPolygon(int n_verts, const glm::vec3* verts, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); - static void DrawPolygonNDT(int n_verts, const glm::vec3* verts, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); + static void DrawPolygon(int n_verts, const glm::vec3* verts, bool depthTested = false, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), float time = 0.0f); // Draw Text WorldSpace (pos given here in worldspace) - static void DrawTextWs(const glm::vec3& pos, const float font_size, const glm::vec4& colour, const std::string text, ...); /// See "printf" for usage manual - static void DrawTextWsNDT(const glm::vec3& pos, const float font_size, const glm::vec4& colour, const std::string text, ...); /// See "printf" for usage manual + static void DrawTextWs(const glm::vec3& pos, const float font_size, bool depthTested, const glm::vec4& colour, float time, const std::string text, ...); /// See "printf" for usage manual // Draw Text (pos is assumed to be pre-multiplied by projMtx * viewMtx at this point) static void DrawTextCs(const glm::vec4& pos, const float font_size, const std::string& text, const glm::vec4& colour = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); @@ -205,10 +199,10 @@ namespace Lumos protected: // Actual functions managing data parsing to save code bloat - called by public functions - static void GenDrawPoint(bool ndt, const glm::vec3& pos, float point_radius, const glm::vec4& colour); - static void GenDrawThickLine(bool ndt, const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec4& colour); - static void GenDrawHairLine(bool ndt, const glm::vec3& start, const glm::vec3& end, const glm::vec4& colour); - static void GenDrawTriangle(bool ndt, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, const glm::vec4& colour); + static void GenDrawPoint(bool ndt, const glm::vec3& pos, float point_radius, const glm::vec4& colour, float time); + static void GenDrawThickLine(bool ndt, const glm::vec3& start, const glm::vec3& end, float line_width, const glm::vec4& colour, float time); + static void GenDrawHairLine(bool ndt, const glm::vec3& start, const glm::vec3& end, const glm::vec4& colour, float time); + static void GenDrawTriangle(bool ndt, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, const glm::vec4& colour, float time); static void AddLogEntry(const glm::vec3& colour, const std::string& text); private: @@ -238,6 +232,8 @@ namespace Lumos DebugDrawList m_DrawList; DebugDrawList m_DrawListNDT; + void ClearDrawList(DebugDrawList& drawlist, float dt); + glm::mat4 m_ProjViewMtx = glm::mat4(1.0f); uint32_t m_Width; uint32_t m_Height; diff --git a/Lumos/Source/Lumos/Graphics/Renderers/GridRenderer.cpp b/Lumos/Source/Lumos/Graphics/Renderers/GridRenderer.cpp index 6c8a6052..b8bef898 100644 --- a/Lumos/Source/Lumos/Graphics/Renderers/GridRenderer.cpp +++ b/Lumos/Source/Lumos/Graphics/Renderers/GridRenderer.cpp @@ -20,6 +20,7 @@ #include "Maths/Transform.h" #include "Graphics/Renderers/RenderPasses.h" #include "Utilities/AssetManager.h" +#include #include @@ -84,8 +85,9 @@ namespace Lumos void GridRenderer::Init() { LUMOS_PROFILE_FUNCTION(); - m_Shader = Application::Get().GetShaderLibrary()->GetResource("Grid"); - m_Quad = Graphics::CreateQuad(); // Graphics::CreatePlane(5000.0f, 5000.f, glm::vec3(0.0f, 1.0f, 0.0f)); + m_Shader = Application::Get().GetAssetManager()->GetAssetData("Grid").As(); + + m_Quad = Graphics::CreateQuad(); // Graphics::CreatePlane(5000.0f, 5000.f, glm::vec3(0.0f, 1.0f, 0.0f)); Graphics::DescriptorDesc descriptorDesc {}; descriptorDesc.layoutIndex = 0; @@ -185,6 +187,7 @@ namespace Lumos pipelineDesc.transparencyEnabled = true; pipelineDesc.blendMode = BlendMode::SrcAlphaOneMinusSrcAlpha; + if(m_DepthTexture && m_DepthTexture->GetSamples() == 1) { pipelineDesc.depthTarget = reinterpret_cast(m_DepthTexture); // reinterpret_cast(Application::Get().GetRenderPasses()->GetDepthTexture()); } diff --git a/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.cpp b/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.cpp index 0d8f8ea2..34a6c26f 100644 --- a/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.cpp +++ b/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.cpp @@ -29,7 +29,6 @@ #include "ImGui/ImGuiUtilities.h" #include #include -#include #include #include @@ -43,7 +42,7 @@ static const uint32_t RENDERER_POINT_BUFFER_SIZE = RENDERER_POINT_SIZE * MaxPoin static const uint32_t MaxLines = 1000; static const uint32_t MaxLineVertices = MaxLines * 2; -static const uint32_t MaxLineIndices = MaxLines * 6; +static const uint32_t MaxLineIndices = MaxLines * 2; static const uint32_t MAX_LINE_BATCH_DRAW_CALLS = 100; static const uint32_t RENDERER_LINE_SIZE = sizeof(Lumos::Graphics::LineVertexData) * 4; static const uint32_t RENDERER_LINE_BUFFER_SIZE = RENDERER_LINE_SIZE * MaxLineVertices; @@ -64,17 +63,36 @@ namespace Lumos::Graphics mainRenderTargetDesc.minFilter = TextureFilter::LINEAR; mainRenderTargetDesc.magFilter = TextureFilter::LINEAR; mainRenderTargetDesc.generateMipMaps = false; + mainRenderTargetDesc.samples = m_MainTextureSamples; m_MainTexture = Graphics::Texture2D::Create(mainRenderTargetDesc, width, height); + mainRenderTargetDesc.samples = 1; + m_PostProcessTexture1 = Graphics::Texture2D::Create(mainRenderTargetDesc, width, height); + m_ResolveTexture = Graphics::Texture2D::Create(mainRenderTargetDesc, width, height); // Setup shadow pass data - m_ShadowData.m_ShadowTex = nullptr; - m_ShadowData.m_ShadowMapNum = 4; - m_ShadowData.m_ShadowMapSize = 1024; + m_ShadowData.m_ShadowTex = nullptr; + m_ShadowData.m_ShadowMapNum = 4; + + uint32_t shadowMapResolution = 4096; + switch(Application::Get().GetQualitySettings().ShadowResolution) + { + case ShadowResolutionSetting::Low: + shadowMapResolution = 1024; + break; + case ShadowResolutionSetting::Medium: + shadowMapResolution = 2048; + break; + case ShadowResolutionSetting::High: + shadowMapResolution = 4096; + break; + } + m_ShadowData.m_ShadowMapSize = shadowMapResolution; + m_ShadowData.m_ShadowMapsInvalidated = true; m_ShadowData.m_CascadeSplitLambda = 0.92f; - m_ShadowData.m_Shader = Application::Get().GetShaderLibrary()->GetResource("Shadow"); - m_ShadowData.m_ShaderAlpha = Application::Get().GetShaderLibrary()->GetResource("ShadowAlpha"); + m_ShadowData.m_Shader = Application::Get().GetAssetManager()->GetAssetData("Shadow").As(); + m_ShadowData.m_ShaderAlpha = Application::Get().GetAssetManager()->GetAssetData("ShadowAlpha").As(); m_ShadowData.m_ShadowTex = TextureDepthArray::Create(m_ShadowData.m_ShadowMapSize, m_ShadowData.m_ShadowMapSize, m_ShadowData.m_ShadowMapNum, Renderer::GetRenderer()->GetDepthFormat()); m_ShadowData.m_LightSize = 1.5f; m_ShadowData.m_MaxShadowDistance = 500.0f; @@ -98,8 +116,8 @@ namespace Lumos::Graphics // Setup forward pass data m_ForwardData.m_DepthTest = true; - m_ForwardData.m_Shader = Application::Get().GetShaderLibrary()->GetResource("ForwardPBR"); - m_ForwardData.m_DepthTexture = TextureDepth::Create(width, height, Renderer::GetRenderer()->GetDepthFormat()); + m_ForwardData.m_Shader = Application::Get().GetAssetManager()->GetAssetData("ForwardPBR").As(); + m_ForwardData.m_DepthTexture = TextureDepth::Create(width, height, Renderer::GetRenderer()->GetDepthFormat(), m_MainTextureSamples); m_ForwardData.m_CommandQueue.reserve(1000); const size_t minUboAlignment = size_t(Graphics::Renderer::GetCapabilities().UniformBufferOffsetAlignment); @@ -135,6 +153,7 @@ namespace Lumos::Graphics noiseTextureDesc.wrap = TextureWrap::CLAMP_TO_EDGE; noiseTextureDesc.minFilter = TextureFilter::LINEAR; noiseTextureDesc.magFilter = TextureFilter::LINEAR; + noiseTextureDesc.samples = m_MainTextureSamples; m_NormalTexture = Graphics::Texture2D::Create(noiseTextureDesc, width, height); m_SSAOTexture = Graphics::Texture2D::Create(noiseTextureDesc, width / 2, height / 2); @@ -214,35 +233,35 @@ namespace Lumos::Graphics // Set up skybox pass data m_ScreenQuad = Graphics::CreateQuad(); - m_SkyboxShader = Application::Get().GetShaderLibrary()->GetResource("Skybox"); + m_SkyboxShader = Application::Get().GetAssetManager()->GetAssetData("Skybox").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_SkyboxShader.get(); m_SkyboxDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); // Set up final pass data - m_FinalPassShader = Application::Get().GetShaderLibrary()->GetResource("FinalPass"); + m_FinalPassShader = Application::Get().GetAssetManager()->GetAssetData("FinalPass").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_FinalPassShader.get(); m_FinalPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); // PostProcesses - m_ToneMappingPassShader = Application::Get().GetShaderLibrary()->GetResource("ToneMapping"); + m_ToneMappingPassShader = Application::Get().GetAssetManager()->GetAssetData("ToneMapping").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_ToneMappingPassShader.get(); m_ToneMappingPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_DepthOfFieldShader = Application::Get().GetShaderLibrary()->GetResource("DepthOfField"); + m_DepthOfFieldShader = Application::Get().GetAssetManager()->GetAssetData("DepthOfField").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_DepthOfFieldShader.get(); m_DepthOfFieldPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_SharpenShader = Application::Get().GetShaderLibrary()->GetResource("Sharpen"); + m_SharpenShader = Application::Get().GetAssetManager()->GetAssetData("Sharpen").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_SharpenShader.get(); m_SharpenPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_BloomPassShader = Application::Get().GetShaderLibrary()->GetResource(m_SupportCompute ? "BloomComp" : "Bloom"); + m_BloomPassShader = Application::Get().GetAssetManager()->GetAssetData(m_SupportCompute ? "BloomComp" : "Bloom").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_BloomPassShader.get(); @@ -257,43 +276,43 @@ namespace Lumos::Graphics m_BloomTexture1 = Texture2D::Create(mainRenderTargetDesc, width, height); m_BloomTexture2 = Texture2D::Create(mainRenderTargetDesc, width, height); - m_FXAAShader = Application::Get().GetShaderLibrary()->GetResource(m_SupportCompute ? "FXAAComp" : "FXAA"); + m_FXAAShader = Application::Get().GetAssetManager()->GetAssetData(m_SupportCompute ? "FXAAComp" : "FXAA").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_FXAAShader.get(); m_FXAAPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_DebandingShader = Application::Get().GetShaderLibrary()->GetResource("Debanding"); + m_DebandingShader = Application::Get().GetAssetManager()->GetAssetData("Debanding").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_DebandingShader.get(); m_DebandingPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_ChromaticAberationShader = Application::Get().GetShaderLibrary()->GetResource("ChromaticAberation"); + m_ChromaticAberationShader = Application::Get().GetAssetManager()->GetAssetData("ChromaticAberation").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_ChromaticAberationShader.get(); m_ChromaticAberationPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_DepthPrePassShader = Application::Get().GetShaderLibrary()->GetResource("DepthPrePass"); + m_DepthPrePassShader = Application::Get().GetAssetManager()->GetAssetData("DepthPrePass").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_DepthPrePassShader.get(); m_DepthPrePassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_DepthPrePassAlphaShader = Application::Get().GetShaderLibrary()->GetResource("DepthPrePassAlpha"); + m_DepthPrePassAlphaShader = Application::Get().GetAssetManager()->GetAssetData("DepthPrePassAlpha").As(); descriptorDesc.shader = m_DepthPrePassAlphaShader.get(); m_DepthPrePassAlphaDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_FilmicGrainShader = Application::Get().GetShaderLibrary()->GetResource("FilmicGrain"); + m_FilmicGrainShader = Application::Get().GetAssetManager()->GetAssetData("FilmicGrain").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_FilmicGrainShader.get(); m_FilmicGrainPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_SSAOShader = Application::Get().GetShaderLibrary()->GetResource("SSAO"); + m_SSAOShader = Application::Get().GetAssetManager()->GetAssetData("SSAO").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_SSAOShader.get(); if(m_SSAOShader->IsCompiled()) m_SSAOPassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); - m_SSAOBlurShader = Application::Get().GetShaderLibrary()->GetResource("SSAOBlur"); + m_SSAOBlurShader = Application::Get().GetAssetManager()->GetAssetData("SSAOBlur").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_SSAOBlurShader.get(); if(m_SSAOBlurShader->IsCompiled()) @@ -302,7 +321,7 @@ namespace Lumos::Graphics m_SSAOBlurPassDescriptorSet2 = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); } - // m_OutlineShader = Application::Get().GetShaderLibrary()->GetResource("Outline"); + // m_OutlineShader = Application::Get().GetAssetManager()->GetAssetData("Outline"); // descriptorDesc.layoutIndex = 0; // descriptorDesc.shader = m_OutlineShader.get(); // m_OutlinePassDescriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); @@ -315,7 +334,7 @@ namespace Lumos::Graphics m_Renderer2DData.m_Limits.SetMaxQuads(10000); m_Renderer2DData.m_Limits.MaxTextures = 16; // Renderer::GetCapabilities().MaxTextureUnits; - m_Renderer2DData.m_Shader = Application::Get().GetShaderLibrary()->GetResource("Batch2D"); + m_Renderer2DData.m_Shader = Application::Get().GetAssetManager()->GetAssetData("Batch2D").As(); m_Renderer2DData.m_TransformationStack.emplace_back(glm::mat4(1.0f)); m_Renderer2DData.m_TransformationBack = &m_Renderer2DData.m_TransformationStack.back(); @@ -378,16 +397,6 @@ namespace Lumos::Graphics for(int i = 0; i < Renderer::GetMainSwapChain()->GetSwapChainBufferCount(); i++) { TextVertexBufferBase.push_back(new TextVertexData[m_TextRendererData.m_Limits.MaxQuads * 4]); - - if(m_Settings.DebugPass) // && sceneRenderSettings.DebugRenderEnabled) - { - m_QuadBufferBase.push_back(new VertexData[m_DebugDrawData.m_Renderer2DData.m_Limits.MaxQuads * 4]); - - // m_2DBufferBase.push_back(new VertexData[m_Renderer2DData.m_Limits.MaxQuads * 4]); - m_LineBufferBase.push_back(new LineVertexData[m_DebugDrawData.m_Renderer2DData.m_Limits.MaxQuads * 4]); - m_PointBufferBase.push_back(new PointVertexData[m_DebugDrawData.m_Renderer2DData.m_Limits.MaxQuads * 4]); - DebugTextVertexBufferBase.push_back(new TextVertexData[m_DebugTextRendererData.m_Limits.MaxQuads * 4]); - } } delete[] indices; @@ -403,7 +412,7 @@ namespace Lumos::Graphics m_ParticleData.m_Limits.SetMaxQuads(10000); m_ParticleData.m_Limits.MaxTextures = 16; // Renderer::GetCapabilities().MaxTextureUnits; - m_ParticleData.m_Shader = Application::Get().GetShaderLibrary()->GetResource("Particle"); + m_ParticleData.m_Shader = Application::Get().GetAssetManager()->GetAssetData("Particle").As(); m_ParticleData.m_TransformationStack.emplace_back(glm::mat4(1.0f)); m_ParticleData.m_TransformationBack = &m_ParticleData.m_TransformationStack.back(); @@ -478,7 +487,7 @@ namespace Lumos::Graphics TextVertexBufferPtr = TextVertexBufferBase[0]; - m_TextRendererData.m_Shader = Application::Get().GetShaderLibrary()->GetResource("Text"); + m_TextRendererData.m_Shader = Application::Get().GetAssetManager()->GetAssetData("Text").As(); m_TextRendererData.m_TransformationStack.emplace_back(glm::mat4(1.0f)); m_TextRendererData.m_TransformationBack = &m_Renderer2DData.m_TransformationStack.back(); @@ -540,6 +549,7 @@ namespace Lumos::Graphics { delete m_ForwardData.m_DepthTexture; delete m_MainTexture; + delete m_ResolveTexture; delete m_PostProcessTexture1; delete m_SSAOTexture; delete m_SSAOTexture1; @@ -556,23 +566,30 @@ namespace Lumos::Graphics delete m_Renderer2DData.m_IndexBuffer; delete m_TextRendererData.m_IndexBuffer; - delete m_DebugTextRendererData.m_IndexBuffer; - delete m_DebugDrawData.m_Renderer2DData.m_IndexBuffer; - delete m_DebugDrawData.m_LineIndexBuffer; - delete m_DebugDrawData.m_PointIndexBuffer; delete m_ParticleData.m_IndexBuffer; + if(m_DebugRenderDataInitialised) + { + delete m_DebugTextRendererData.m_IndexBuffer; + delete m_DebugDrawData.m_Renderer2DData.m_IndexBuffer; + delete m_DebugDrawData.m_LineIndexBuffer; + delete m_DebugDrawData.m_PointIndexBuffer; + } + for(auto data : TextVertexBufferBase) delete[] data; for(auto data : DebugTextVertexBufferBase) delete[] data; - for(auto data : m_LineBufferBase) - delete[] data; - for(auto data : m_PointBufferBase) - delete[] data; - for(auto data : m_QuadBufferBase) - delete[] data; + if(!m_LineBufferBase.empty()) + for(auto data : m_LineBufferBase[0]) + delete[] data; + if(!m_PointBufferBase.empty()) + for(auto data : m_PointBufferBase[0]) + delete[] data; + if(!m_QuadBufferBase.empty()) + for(auto data : m_QuadBufferBase[0]) + delete[] data; for(int j = 0; j < Renderer::GetMainSwapChain()->GetSwapChainBufferCount(); j++) { @@ -586,39 +603,43 @@ namespace Lumos::Graphics delete m_TextRendererData.m_VertexBuffers[j][i]; } - for(uint32_t i = 0; i < m_DebugTextRendererData.m_VertexBuffers[j].size(); i++) + for(size_t i = 0; i < m_ParticleData.m_VertexBuffers[j].size(); i++) { - delete m_DebugTextRendererData.m_VertexBuffers[j][i]; + delete m_ParticleData.m_VertexBuffers[j][i]; } - for(size_t i = 0; i < m_DebugDrawData.m_Renderer2DData.m_VertexBuffers[j].size(); i++) - { - delete m_DebugDrawData.m_Renderer2DData.m_VertexBuffers[j][i]; - } + if(m_DebugRenderDataInitialised) + for(uint32_t i = 0; i < m_DebugTextRendererData.m_VertexBuffers[j].size(); i++) + { + delete m_DebugTextRendererData.m_VertexBuffers[j][i]; + } + + if(m_DebugRenderDataInitialised) + for(size_t i = 0; i < m_DebugDrawData.m_Renderer2DData.m_VertexBuffers[j].size(); i++) + { + delete m_DebugDrawData.m_Renderer2DData.m_VertexBuffers[j][i]; + } for(auto data : m_2DBufferBase[j]) delete[] data; - } - - for(int j = 0; j < Renderer::GetMainSwapChain()->GetSwapChainBufferCount(); j++) - { - for(size_t i = 0; i < m_ParticleData.m_VertexBuffers[j].size(); i++) - { - delete m_ParticleData.m_VertexBuffers[j][i]; - } for(auto data : m_ParticleBufferBase[j]) delete[] data; } - for(int i = 0; i < m_DebugDrawData.m_PointVertexBuffers.size(); i++) + if(m_DebugRenderDataInitialised) { - delete m_DebugDrawData.m_PointVertexBuffers[i]; - } + if(!m_DebugDrawData.m_PointVertexBuffers.empty()) + for(int i = 0; i < m_DebugDrawData.m_PointVertexBuffers[0].size(); i++) + { + delete m_DebugDrawData.m_PointVertexBuffers[0][i]; + } - for(int i = 0; i < m_DebugDrawData.m_LineVertexBuffers.size(); i++) - { - delete m_DebugDrawData.m_LineVertexBuffers[i]; + if(!m_DebugDrawData.m_LineVertexBuffers.empty()) + for(int i = 0; i < m_DebugDrawData.m_LineVertexBuffers[0].size(); i++) + { + delete m_DebugDrawData.m_LineVertexBuffers[0][i]; + } } DebugRenderer::Release(); @@ -633,13 +654,13 @@ namespace Lumos::Graphics m_ForwardData.m_DepthTexture->Resize(width, height); m_MainTexture->Resize(width, height); + m_ResolveTexture->Resize(width, height); m_PostProcessTexture1->Resize(width, height); m_SSAOTexture->Resize(width / 2, height / 2); m_SSAOTexture1->Resize(width / 2, height / 2); m_BloomTexture->Resize(width, height); m_BloomTexture1->Resize(width, height); m_BloomTexture2->Resize(width, height); - m_NormalTexture->Resize(width, height); } @@ -648,7 +669,10 @@ namespace Lumos::Graphics m_DebugRenderEnabled = enable; if(m_DebugRenderEnabled) + { DebugRenderer::Init(); + InitDebugRenderData(); + } else DebugRenderer::Release(); } @@ -690,9 +714,42 @@ namespace Lumos::Graphics m_Exposure = m_Camera->GetExposure(); m_ToneMapIndex = scene->GetSettings().RenderSettings.m_ToneMapIndex; - auto view = glm::inverse(m_CameraTransform->GetWorldMatrix()); - auto proj = m_Camera->GetProjectionMatrix(); - auto projView = proj * view; + if (m_MainTextureSamples != scene->GetSettings().RenderSettings.MSAASamples) + { + m_MainTextureSamples = scene->GetSettings().RenderSettings.MSAASamples; + + uint32_t width = m_MainTexture->GetWidth(); + uint32_t height = m_MainTexture->GetHeight(); + + delete m_MainTexture; + delete m_ForwardData.m_DepthTexture; + delete m_NormalTexture; + + Graphics::TextureDesc mainRenderTargetDesc; + mainRenderTargetDesc.format = Graphics::RHIFormat::R11G11B10_Float; + mainRenderTargetDesc.flags = TextureFlags::Texture_RenderTarget; + mainRenderTargetDesc.wrap = TextureWrap::CLAMP_TO_EDGE; + mainRenderTargetDesc.minFilter = TextureFilter::LINEAR; + mainRenderTargetDesc.magFilter = TextureFilter::LINEAR; + mainRenderTargetDesc.generateMipMaps = false; + mainRenderTargetDesc.samples = m_MainTextureSamples; + m_MainTexture = Graphics::Texture2D::Create(mainRenderTargetDesc, width, height); + m_ForwardData.m_DepthTexture = TextureDepth::Create(width, height, Renderer::GetRenderer()->GetDepthFormat(), m_MainTextureSamples); + + mainRenderTargetDesc.generateMipMaps = false; + mainRenderTargetDesc.anisotropicFiltering = false; + mainRenderTargetDesc.flags = TextureFlags::Texture_RenderTarget; + mainRenderTargetDesc.wrap = TextureWrap::CLAMP_TO_EDGE; + mainRenderTargetDesc.minFilter = TextureFilter::LINEAR; + mainRenderTargetDesc.magFilter = TextureFilter::LINEAR; + mainRenderTargetDesc.samples = m_MainTextureSamples; + m_NormalTexture = Graphics::Texture2D::Create(mainRenderTargetDesc, width, height); + + } + + auto view = glm::inverse(m_CameraTransform->GetWorldMatrix()); + const auto& proj = m_Camera->GetProjectionMatrix(); + auto projView = proj * view; if(m_DebugRenderEnabled) { @@ -873,7 +930,7 @@ namespace Lumos::Graphics m_ForwardData.m_DescriptorSet[2]->SetUniform("UBOLight", "Mode", &m_ForwardData.m_RenderMode); m_ForwardData.m_DescriptorSet[2]->SetUniform("UBOLight", "EnvMipCount", &EnvMipCount); m_ForwardData.m_DescriptorSet[2]->SetTexture("uBRDFLUT", m_ForwardData.m_BRDFLUT.get()); - m_ForwardData.m_DescriptorSet[2]->SetTexture("uSSAOMap", Application::Get().GetCurrentScene()->GetSettings().RenderSettings.SSAOEnabled ? m_SSAOTexture : Material::GetDefaultTexture().get()); + m_ForwardData.m_DescriptorSet[2]->SetTexture("uSSAOMap", /*Application::Get().GetCurrentScene()->GetSettings().RenderSettings.SSAOEnabled ?*/ /*m_SSAOTexture :*/ Material::GetDefaultTexture().get()); m_ForwardData.m_DescriptorSet[2]->SetTexture("uEnvMap", m_ForwardData.m_EnvironmentMap, 0, TextureType::CUBE); m_ForwardData.m_DescriptorSet[2]->SetTexture("uIrrMap", m_ForwardData.m_IrradianceMap, 0, TextureType::CUBE); @@ -948,7 +1005,9 @@ namespace Lumos::Graphics pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.cullMode = command.material->GetFlag(Material::RenderFlags::TWOSIDED) ? Graphics::CullMode::NONE : Graphics::CullMode::BACK; pipelineDesc.transparencyEnabled = command.material->GetFlag(Material::RenderFlags::ALPHABLEND); - + pipelineDesc.samples = m_MainTextureSamples; + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; if(m_ForwardData.m_DepthTest && command.material->GetFlag(Material::RenderFlags::DEPTHTEST)) { pipelineDesc.depthTarget = m_ForwardData.m_DepthTexture; @@ -1061,8 +1120,8 @@ namespace Lumos::Graphics LUMOS_PROFILE_FUNCTION(); LUMOS_PROFILE_GPU("Render Passes"); - auto& sceneRenderSettings = Application::Get().GetCurrentScene()->GetSettings().RenderSettings; - sceneRenderSettings.SSAOEnabled = false; // Disabled while broken + auto& sceneRenderSettings = Application::Get().GetCurrentScene()->GetSettings().RenderSettings; + sceneRenderSettings.SSAOEnabled = false; { LUMOS_PROFILE_GPU("Clear Main Texture Pass"); @@ -1094,31 +1153,33 @@ namespace Lumos::Graphics SSAOBlurPass(); } - if(m_Settings.ShadowPass && sceneRenderSettings.ShadowsEnabled) + if(sceneRenderSettings.ShadowsEnabled) ShadowPass(); - - if(m_Settings.GeomPass && sceneRenderSettings.Renderer3DEnabled) + if(sceneRenderSettings.Renderer3DEnabled) ForwardPass(); - if(m_Settings.SkyboxPass && sceneRenderSettings.SkyboxRenderEnabled) + if(sceneRenderSettings.SkyboxRenderEnabled) SkyboxPass(); - if(m_Settings.GeomPass && sceneRenderSettings.Renderer3DEnabled) + if(sceneRenderSettings.Renderer3DEnabled) ParticlePass(); - if(m_Settings.GeomPass && sceneRenderSettings.Renderer2DEnabled) + if(sceneRenderSettings.Renderer2DEnabled) Render2DPass(); TextPass(); - m_LastRenderTarget = m_MainTexture; + if (m_DebugRenderEnabled && sceneRenderSettings.DebugRenderEnabled) + DebugPass(); + + m_LastRenderTarget = m_MainTextureSamples > 1 ? m_ResolveTexture : m_MainTexture; // if (sceneRenderSettings.EyeAdaptation) // EyeAdaptationPass(); + if(sceneRenderSettings.DepthOfFieldEnabled && !m_DisablePostProcess) + DepthOfFieldPass(); + if(sceneRenderSettings.BloomEnabled && !m_DisablePostProcess) BloomPass(); - if(sceneRenderSettings.DepthOfFieldEnabled && !m_DisablePostProcess) - DepthOfFieldPass(); - if(sceneRenderSettings.DebandingEnabled && !m_DisablePostProcess) DebandingPass(); @@ -1139,9 +1200,6 @@ namespace Lumos::Graphics // if(sceneRenderSettings.OutlineEnabled // OutlinePass(); - if(m_Settings.DebugPass && sceneRenderSettings.DebugRenderEnabled) - DebugPass(); - FinalPass(); } @@ -1434,7 +1492,7 @@ namespace Lumos::Graphics m_GenerateBRDFLUT = false; Graphics::PipelineDesc pipelineDesc {}; - pipelineDesc.shader = Application::Get().GetShaderLibrary()->GetResource("BRDFLUT"); + pipelineDesc.shader = Application::Get().GetAssetManager()->GetAssetData("BRDFLUT").As(); pipelineDesc.polygonMode = Graphics::PolygonMode::FILL; pipelineDesc.cullMode = Graphics::CullMode::BACK; @@ -1537,6 +1595,7 @@ namespace Lumos::Graphics pipelineDesc.depthTarget = m_ForwardData.m_DepthTexture; pipelineDesc.colourTargets[0] = m_NormalTexture; pipelineDesc.DebugName = "Depth Prepass"; + pipelineDesc.samples = m_MainTextureSamples; DescriptorSet* sets[2]; sets[0] = m_ForwardData.m_DescriptorSet[0].get(); @@ -1656,7 +1715,9 @@ namespace Lumos::Graphics glm::vec2 ssaoTexelOffset = glm::vec2(0.0f, 2.0f / m_SSAOTexture->GetHeight()); Scene::SceneRenderSettings& renderSettings = m_CurrentScene->GetSettings().RenderSettings; + auto view = glm::inverse(m_CameraTransform->GetWorldMatrix()); + m_SSAOBlurPassDescriptorSet->SetUniform("UniformBuffer", "view", &view); m_SSAOBlurPassDescriptorSet->SetUniform("UniformBuffer", "ssaoTexelOffset", &ssaoTexelOffset); m_SSAOBlurPassDescriptorSet->SetUniform("UniformBuffer", "ssaoBlurRadius", &renderSettings.SSAOBlurRadius); @@ -1668,6 +1729,7 @@ namespace Lumos::Graphics ssaoTexelOffset = glm::vec2(2.0f / m_SSAOTexture->GetWidth(), 0.0f); + m_SSAOBlurPassDescriptorSet2->SetUniform("UniformBuffer", "view", &view); m_SSAOBlurPassDescriptorSet2->SetUniform("UniformBuffer", "ssaoTexelOffset", &ssaoTexelOffset); m_SSAOBlurPassDescriptorSet2->SetUniform("UniformBuffer", "ssaoBlurRadius", &renderSettings.SSAOBlurRadius); @@ -1766,9 +1828,11 @@ namespace Lumos::Graphics pipelineDesc.depthTarget = reinterpret_cast(m_ForwardData.m_DepthTexture); } - pipelineDesc.colourTargets[0] = m_MainTexture; + pipelineDesc.colourTargets[0] = m_MainTexture;//m_MainTexture; pipelineDesc.DebugName = "Skybox"; - + pipelineDesc.samples = m_MainTextureSamples; + if(m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; auto commandBuffer = Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(); auto pipeline = Graphics::Pipeline::Get(pipelineDesc); pipeline->Bind(commandBuffer); @@ -1785,6 +1849,12 @@ namespace Lumos::Graphics LUMOS_PROFILE_FUNCTION(); LUMOS_PROFILE_GPU("Depth Of Field Pass"); + if(m_MainTextureSamples > 1) + { + LUMOS_LOG_WARN("Depth of field pass currently not working with msaa"); + return; + } + if(!m_Camera || !m_DepthOfFieldShader || !m_DepthOfFieldShader->IsCompiled()) return; @@ -1802,7 +1872,7 @@ namespace Lumos::Graphics m_DepthOfFieldPassDescriptorSet->SetUniform("UniformBuffer", "DOFParams", &DOFParams); m_DepthOfFieldPassDescriptorSet->SetUniform("UniformBuffer", "DepthConsts", &DepthConsts); - m_DepthOfFieldPassDescriptorSet->SetTexture("u_Texture", m_MainTexture); + m_DepthOfFieldPassDescriptorSet->SetTexture("u_Texture", m_LastRenderTarget); m_DepthOfFieldPassDescriptorSet->SetTexture("u_DepthTexture", m_ForwardData.m_DepthTexture); m_DepthOfFieldPassDescriptorSet->Update(); @@ -1813,6 +1883,7 @@ namespace Lumos::Graphics pipelineDesc.transparencyEnabled = false; pipelineDesc.colourTargets[0] = m_PostProcessTexture1; pipelineDesc.DebugName = "DepthofField"; + pipelineDesc.samples = m_MainTextureSamples; auto commandBuffer = Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(); auto pipeline = Graphics::Pipeline::Get(pipelineDesc); pipeline->Bind(commandBuffer); @@ -1823,8 +1894,7 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_LastRenderTarget = m_PostProcessTexture1; - std::swap(m_PostProcessTexture1, m_MainTexture); + std::swap(m_LastRenderTarget, m_PostProcessTexture1); } void RenderPasses::SharpenPass() @@ -1837,7 +1907,7 @@ namespace Lumos::Graphics Scene::SceneRenderSettings& renderSettings = m_CurrentScene->GetSettings().RenderSettings; - m_SharpenPassDescriptorSet->SetTexture("u_Texture", m_MainTexture); + m_SharpenPassDescriptorSet->SetTexture("u_Texture", m_LastRenderTarget); m_SharpenPassDescriptorSet->Update(); Graphics::PipelineDesc pipelineDesc {}; @@ -1857,8 +1927,7 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_LastRenderTarget = m_PostProcessTexture1; - std::swap(m_PostProcessTexture1, m_MainTexture); + std::swap(m_PostProcessTexture1, m_LastRenderTarget); } void RenderPasses::ToneMappingPass() @@ -1877,7 +1946,7 @@ namespace Lumos::Graphics m_ToneMappingPassDescriptorSet->SetUniform("UniformBuffer", "Contrast", &Contrast); m_ToneMappingPassDescriptorSet->SetUniform("UniformBuffer", "Saturation", &Saturation); - m_ToneMappingPassDescriptorSet->SetTexture("u_Texture", m_MainTexture); + m_ToneMappingPassDescriptorSet->SetTexture("u_Texture", m_LastRenderTarget); m_ToneMappingPassDescriptorSet->SetTexture("u_BloomTexture", m_BloomTextureLastRenderered); m_ToneMappingPassDescriptorSet->Update(); @@ -1898,8 +1967,7 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_LastRenderTarget = m_PostProcessTexture1; - std::swap(m_PostProcessTexture1, m_MainTexture); + std::swap(m_PostProcessTexture1, m_LastRenderTarget); } void RenderPasses::FinalPass() @@ -1907,7 +1975,7 @@ namespace Lumos::Graphics LUMOS_PROFILE_FUNCTION(); LUMOS_PROFILE_GPU("Final Pass"); - Texture* finalPassTexture = m_MainTexture; + Texture* finalPassTexture = m_LastRenderTarget; #ifndef LUMOS_DIST @@ -1961,6 +2029,9 @@ namespace Lumos::Graphics Renderer::Draw(commandBuffer, DrawType::TRIANGLE, 3); pipeline->End(commandBuffer); + + if(m_LastRenderTarget != m_MainTexture && m_LastRenderTarget != m_ResolveTexture) + std::swap(m_PostProcessTexture1, m_LastRenderTarget); } void RenderPasses::BloomPass() @@ -2011,8 +2082,8 @@ namespace Lumos::Graphics uint32_t workGroupsX = m_BloomTexture->GetWidth() / workGroupSize; uint32_t workGroupsY = m_BloomTexture->GetHeight() / workGroupSize; - m_BloomDescriptorSets[0]->SetTexture("u_Texture", m_MainTexture); - m_BloomDescriptorSets[0]->SetTexture("u_BloomTexture", m_MainTexture); + m_BloomDescriptorSets[0]->SetTexture("u_Texture", m_LastRenderTarget); + m_BloomDescriptorSets[0]->SetTexture("u_BloomTexture", m_LastRenderTarget); if(m_SupportCompute) { @@ -2070,12 +2141,12 @@ namespace Lumos::Graphics if(i % 2 == 0) { m_BloomDescriptorSets[i]->SetTexture("u_Texture", m_BloomTexture1); - m_BloomDescriptorSets[i]->SetTexture("u_BloomTexture", m_MainTexture); + m_BloomDescriptorSets[i]->SetTexture("u_BloomTexture", m_LastRenderTarget); } else { m_BloomDescriptorSets[i]->SetTexture("u_Texture", m_BloomTexture); - m_BloomDescriptorSets[i]->SetTexture("u_BloomTexture", m_MainTexture); + m_BloomDescriptorSets[i]->SetTexture("u_BloomTexture", m_LastRenderTarget); } m_BloomDescriptorSets[i]->Update(); @@ -2187,7 +2258,7 @@ namespace Lumos::Graphics // First Upsample { m_BloomDescriptorSets[passCount]->SetTexture("u_Texture", m_BloomTexture); - m_BloomDescriptorSets[passCount]->SetTexture("u_BloomTexture", m_MainTexture); + m_BloomDescriptorSets[passCount]->SetTexture("u_BloomTexture", m_LastRenderTarget); if(m_SupportCompute) { @@ -2330,7 +2401,7 @@ namespace Lumos::Graphics auto commandBuffer = Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(); - m_FXAAPassDescriptorSet->SetTexture("u_Texture", m_MainTexture); + m_FXAAPassDescriptorSet->SetTexture("u_Texture", m_LastRenderTarget); if(m_SupportCompute) { @@ -2371,8 +2442,7 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_LastRenderTarget = m_PostProcessTexture1; - std::swap(m_PostProcessTexture1, m_MainTexture); + std::swap(m_PostProcessTexture1, m_LastRenderTarget); } void RenderPasses::DebandingPass() @@ -2380,10 +2450,10 @@ namespace Lumos::Graphics LUMOS_PROFILE_FUNCTION(); LUMOS_PROFILE_GPU("Debanding Pass"); - if(!m_MainTexture || !m_DebandingShader->IsCompiled()) + if(!m_LastRenderTarget || !m_DebandingShader->IsCompiled()) return; - m_DebandingPassDescriptorSet->SetTexture("u_Texture", m_MainTexture); + m_DebandingPassDescriptorSet->SetTexture("u_Texture", m_LastRenderTarget); m_DebandingPassDescriptorSet->Update(); Graphics::PipelineDesc pipelineDesc {}; @@ -2403,8 +2473,7 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_LastRenderTarget = m_PostProcessTexture1; - std::swap(m_PostProcessTexture1, m_MainTexture); + std::swap(m_PostProcessTexture1, m_LastRenderTarget); } void RenderPasses::FilmicGrainPass() @@ -2415,7 +2484,7 @@ namespace Lumos::Graphics if(!m_MainTexture || !m_FilmicGrainShader->IsCompiled()) return; - m_FilmicGrainPassDescriptorSet->SetTexture("u_Texture", m_MainTexture); + m_FilmicGrainPassDescriptorSet->SetTexture("u_Texture", m_LastRenderTarget); m_FilmicGrainPassDescriptorSet->Update(); Graphics::PipelineDesc pipelineDesc {}; @@ -2446,8 +2515,7 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_LastRenderTarget = m_PostProcessTexture1; - std::swap(m_PostProcessTexture1, m_MainTexture); + std::swap(m_PostProcessTexture1, m_LastRenderTarget); } void RenderPasses::OutlinePass() @@ -2455,10 +2523,10 @@ namespace Lumos::Graphics LUMOS_PROFILE_FUNCTION(); LUMOS_PROFILE_GPU("Outline Pass"); - if(!m_MainTexture || !m_OutlineShader || !m_OutlineShader->IsCompiled()) + if(!m_LastRenderTarget || !m_OutlineShader || !m_OutlineShader->IsCompiled()) return; - // m_OutlinePassDescriptorSet->SetTexture("u_Texture", m_MainTexture); + // m_OutlinePassDescriptorSet->SetTexture("u_Texture", m_LastRenderTarget); // m_OutlinePassDescriptorSet->Update(); Graphics::PipelineDesc pipelineDesc {}; @@ -2478,8 +2546,7 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_LastRenderTarget = m_PostProcessTexture1; - std::swap(m_PostProcessTexture1, m_MainTexture); + std::swap(m_PostProcessTexture1, m_LastRenderTarget); } void RenderPasses::ChromaticAberationPass() @@ -2487,14 +2554,14 @@ namespace Lumos::Graphics LUMOS_PROFILE_FUNCTION(); LUMOS_PROFILE_GPU("ChromaticAberation Pass"); - if(!m_Camera || !m_MainTexture || !m_ChromaticAberationShader->IsCompiled()) + if(!m_Camera || !m_LastRenderTarget || !m_ChromaticAberationShader->IsCompiled()) return; auto set = m_ChromaticAberationPassDescriptorSet.get(); float cameraAperture = m_Camera->GetAperture(); float intensity = 100.0f; - set->SetTexture("u_Texture", m_MainTexture); + set->SetTexture("u_Texture", m_LastRenderTarget); set->SetUniform("UniformBuffer", "chromaticAberrationIntensity", &intensity); set->SetUniform("UniformBuffer", "cameraAperture", &cameraAperture); set->Update(); @@ -2515,8 +2582,7 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_LastRenderTarget = m_PostProcessTexture1; - std::swap(m_PostProcessTexture1, m_MainTexture); + std::swap(m_PostProcessTexture1, m_LastRenderTarget); } void RenderPasses::EyeAdaptationPass() @@ -2571,6 +2637,9 @@ namespace Lumos::Graphics pipelineDesc.depthTarget = reinterpret_cast(m_ForwardData.m_DepthTexture); pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.DebugName = "2D"; + pipelineDesc.samples = m_MainTextureSamples; + if(m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; m_Renderer2DData.m_Pipeline = Graphics::Pipeline::Get(pipelineDesc); @@ -2645,6 +2714,8 @@ namespace Lumos::Graphics } Render2DFlush(); + + Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()->UnBindPipeline(); } void RenderPasses::Renderer2DBeginBatch() @@ -2669,7 +2740,14 @@ namespace Lumos::Graphics void RenderPasses::Render2DFlush() { LUMOS_PROFILE_FUNCTION(); - uint32_t currentFrame = Renderer::GetMainSwapChain()->GetCurrentBufferIndex(); + uint32_t currentFrame = Renderer::GetMainSwapChain()->GetCurrentBufferIndex(); + Graphics::CommandBuffer* commandBuffer = Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(); + + + uint32_t dataSize = (uint32_t)((uint8_t*)m_Renderer2DData.m_Buffer - (uint8_t*)m_2DBufferBase[currentFrame][m_Renderer2DData.m_BatchDrawCallIndex]); + m_Renderer2DData.m_VertexBuffers[currentFrame][m_Renderer2DData.m_BatchDrawCallIndex]->SetData(dataSize, (void*)m_2DBufferBase[currentFrame][m_Renderer2DData.m_BatchDrawCallIndex], true); + + commandBuffer->BindPipeline(m_Renderer2DData.m_Pipeline); if(m_Renderer2DData.m_DescriptorSet[m_Renderer2DData.m_BatchDrawCallIndex][1] == nullptr || m_Renderer2DData.m_TextureCount != m_Renderer2DData.m_PreviousFrameTextureCount[m_Renderer2DData.m_BatchDrawCallIndex]) { @@ -2685,6 +2763,13 @@ namespace Lumos::Graphics m_Renderer2DData.m_DescriptorSet[m_Renderer2DData.m_BatchDrawCallIndex][1] = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); } + for(int i = m_Renderer2DData.m_TextureCount; i < 16; i++) + { + m_Renderer2DData.m_Textures[i] = Material::GetDefaultTexture(); + } + + m_Renderer2DData.m_TextureCount = 16; + if(m_Renderer2DData.m_TextureCount > 1) m_Renderer2DData.m_DescriptorSet[m_Renderer2DData.m_BatchDrawCallIndex][1]->SetTexture("textures", m_Renderer2DData.m_Textures, m_Renderer2DData.m_TextureCount); else if(m_Renderer2DData.m_TextureCount == 0) @@ -2696,13 +2781,6 @@ namespace Lumos::Graphics m_Renderer2DData.m_PreviousFrameTextureCount[m_Renderer2DData.m_BatchDrawCallIndex] = m_Renderer2DData.m_TextureCount; - Graphics::CommandBuffer* commandBuffer = Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(); - - uint32_t dataSize = (uint32_t)((uint8_t*)m_Renderer2DData.m_Buffer - (uint8_t*)m_2DBufferBase[currentFrame][m_Renderer2DData.m_BatchDrawCallIndex]); - m_Renderer2DData.m_VertexBuffers[currentFrame][m_Renderer2DData.m_BatchDrawCallIndex]->SetData(dataSize, (void*)m_2DBufferBase[currentFrame][m_Renderer2DData.m_BatchDrawCallIndex], true); - - m_Renderer2DData.m_Pipeline->Bind(commandBuffer); - m_Renderer2DData.m_CurrentDescriptorSets[0] = m_Renderer2DData.m_DescriptorSet[0][0].get(); m_Renderer2DData.m_CurrentDescriptorSets[1] = m_Renderer2DData.m_DescriptorSet[m_Renderer2DData.m_BatchDrawCallIndex][1].get(); @@ -2715,8 +2793,6 @@ namespace Lumos::Graphics m_Renderer2DData.m_VertexBuffers[currentFrame][m_Renderer2DData.m_BatchDrawCallIndex]->Unbind(); m_Renderer2DData.m_IndexBuffer->Unbind(); - m_Renderer2DData.m_Pipeline->End(commandBuffer); - m_Renderer2DData.m_BatchDrawCallIndex++; m_Renderer2DData.m_TextureCount = 0; } @@ -2740,6 +2816,13 @@ namespace Lumos::Graphics textRenderData.m_DescriptorSet[textRenderData.m_BatchDrawCallIndex][1] = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); } + for(int i = textRenderData.m_TextureCount; i < 16; i++) + { + textRenderData.m_Textures[i] = Material::GetDefaultTexture(); + } + + textRenderData.m_TextureCount = 16; + if(textRenderData.m_TextureCount > 1) textRenderData.m_DescriptorSet[textRenderData.m_BatchDrawCallIndex][1]->SetTexture("textures", textRenderData.m_Textures, textRenderData.m_TextureCount); else if(textRenderData.m_TextureCount == 0) @@ -2808,6 +2891,10 @@ namespace Lumos::Graphics pipelineDesc.clearTargets = false; pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.DebugName = "Text"; + pipelineDesc.samples = m_MainTextureSamples; + + if(m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; m_TextRendererData.m_Pipeline = Graphics::Pipeline::Get(pipelineDesc); @@ -2859,14 +2946,14 @@ namespace Lumos::Graphics { if(m_TextRendererData.m_Textures[i] == fontAtlas.get()) { - textureIndex = int(i); + textureIndex = int(i + 1); break; } } if(textureIndex == -1) { - textureIndex = (int)m_TextRendererData.m_TextureCount; + textureIndex = (int)m_TextRendererData.m_TextureCount + 1; m_TextRendererData.m_Textures[m_TextRendererData.m_TextureCount] = fontAtlas.get(); m_TextRendererData.m_TextureCount++; } @@ -2983,11 +3070,13 @@ namespace Lumos::Graphics LUMOS_LOG_WARN("Debug Render data not initialised"); return; } - + m_DebugDrawData.m_LineBatchDrawCallIndex = 0; + m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex = 0; + m_DebugDrawData.m_PointBatchDrawCallIndex = 0; // Loop twice for depth test and no depth test for(int i = 0; i < 2; i++) { - bool depthTest = i == 1; + bool depthTest = i == 0; auto& lines = DebugRenderer::GetInstance()->GetLines(depthTest); auto& thickLines = DebugRenderer::GetInstance()->GetThickLines(depthTest); @@ -3013,7 +3102,9 @@ namespace Lumos::Graphics pipelineDesc.drawType = DrawType::LINES; pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.DebugName = "Debug-Lines"; - + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; + pipelineDesc.samples = m_MainTextureSamples; if(depthTest) pipelineDesc.depthTarget = m_ForwardData.m_DepthTexture; @@ -3021,21 +3112,23 @@ namespace Lumos::Graphics pipeline->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()); - if((int)m_DebugDrawData.m_LineVertexBuffers.size() - 1 < (int)m_DebugDrawData.m_LineBatchDrawCallIndex) + if(m_DebugDrawData.m_LineVertexBuffers.empty()) + m_DebugDrawData.m_LineVertexBuffers.emplace_back(); + if((int)m_DebugDrawData.m_LineVertexBuffers[0].size() - 1 < (int)m_DebugDrawData.m_LineBatchDrawCallIndex) { - auto& vertexBuffer = m_DebugDrawData.m_LineVertexBuffers.emplace_back(Graphics::VertexBuffer::Create(RENDERER_LINE_BUFFER_SIZE, nullptr, BufferUsage::DYNAMIC)); + auto& vertexBuffer = m_DebugDrawData.m_LineVertexBuffers[0].emplace_back(Graphics::VertexBuffer::Create(RENDERER_LINE_BUFFER_SIZE, nullptr, BufferUsage::DYNAMIC)); // vertexBuffer->Resize(RENDERER_LINE_BUFFER_SIZE); } - m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), pipeline.get()); - m_DebugDrawData.m_LineBuffer = m_LineBufferBase[0]; + m_DebugDrawData.m_LineVertexBuffers[0][m_DebugDrawData.m_LineBatchDrawCallIndex]->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), pipeline.get()); + m_DebugDrawData.m_LineBuffer = m_LineBufferBase[0][0]; //[m_DebugDrawData.m_LineBatchDrawCallIndex]; // m_DebugDrawData.m_LineBuffer = m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->GetPointer(); for(auto& line : lines) { - if(m_DebugDrawData.LineIndexCount >= m_DebugDrawData.m_Renderer2DData.m_Limits.MaxQuads) - break; + if(m_DebugDrawData.LineIndexCount >= MaxLineIndices) + DebugLineFlush(pipeline); m_DebugDrawData.m_LineBuffer->vertex = line.p1; m_DebugDrawData.m_LineBuffer->colour = line.col; @@ -3052,25 +3145,9 @@ namespace Lumos::Graphics // m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->Unbind(); // m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->Bind(commandBuffer, pipeline.get()); - m_DebugDrawData.m_LineIndexBuffer->SetCount(m_DebugDrawData.LineIndexCount); - m_DebugDrawData.m_LineIndexBuffer->Bind(commandBuffer); - - uint32_t dataSize = (uint32_t)((uint8_t*)m_DebugDrawData.m_LineBuffer - (uint8_t*)m_LineBufferBase[0]); - m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->SetData(dataSize, (void*)m_LineBufferBase[0]); - - auto* desc = m_DebugDrawData.m_LineDescriptorSet[0].get(); - Renderer::BindDescriptorSets(pipeline.get(), commandBuffer, 0, &desc, 1); - Renderer::DrawIndexed(commandBuffer, DrawType::LINES, m_DebugDrawData.LineIndexCount); - - m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->Unbind(); - m_DebugDrawData.m_LineIndexBuffer->Unbind(); - - m_DebugDrawData.m_LineBuffer = m_LineBufferBase[0]; - m_DebugDrawData.LineIndexCount = 0; + DebugLineFlush(pipeline); pipeline->End(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()); - - m_DebugDrawData.m_LineBatchDrawCallIndex++; } if(!thickLines.empty()) @@ -3091,7 +3168,9 @@ namespace Lumos::Graphics pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.lineWidth = 2.0f; pipelineDesc.DebugName = "Debug-ThickLines"; - + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; + pipelineDesc.samples = m_MainTextureSamples; if(depthTest) pipelineDesc.depthTarget = m_ForwardData.m_DepthTexture; @@ -3099,20 +3178,21 @@ namespace Lumos::Graphics pipeline->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()); - if((int)m_DebugDrawData.m_LineVertexBuffers.size() - 1 < (int)m_DebugDrawData.m_LineBatchDrawCallIndex) + if(m_DebugDrawData.m_LineVertexBuffers.empty()) + m_DebugDrawData.m_LineVertexBuffers.emplace_back(); + if((int)m_DebugDrawData.m_LineVertexBuffers[0].size() - 1 < (int)m_DebugDrawData.m_LineBatchDrawCallIndex) { - auto& vertexBuffer = m_DebugDrawData.m_LineVertexBuffers.emplace_back(Graphics::VertexBuffer::Create(RENDERER_LINE_BUFFER_SIZE, nullptr, BufferUsage::DYNAMIC)); + auto& vertexBuffer = m_DebugDrawData.m_LineVertexBuffers[0].emplace_back(Graphics::VertexBuffer::Create(RENDERER_LINE_BUFFER_SIZE, nullptr, BufferUsage::DYNAMIC)); // vertexBuffer->Resize(RENDERER_LINE_BUFFER_SIZE); } - m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), pipeline.get()); - // m_DebugDrawData.m_LineBuffer = m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->GetPointer(); - m_DebugDrawData.m_LineBuffer = m_LineBufferBase[0]; + m_DebugDrawData.m_LineVertexBuffers[0][m_DebugDrawData.m_LineBatchDrawCallIndex]->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), pipeline.get()); + m_DebugDrawData.m_LineBuffer = m_LineBufferBase[0][0]; //[m_DebugDrawData.m_LineBatchDrawCallIndex]; for(auto& line : thickLines) { - if(m_DebugDrawData.LineIndexCount >= m_DebugDrawData.m_Renderer2DData.m_Limits.MaxQuads) - break; + if(m_DebugDrawData.LineIndexCount >= MaxLineIndices) + DebugLineFlush(pipeline); m_DebugDrawData.m_LineBuffer->vertex = line.p1; m_DebugDrawData.m_LineBuffer->colour = line.col; @@ -3125,29 +3205,9 @@ namespace Lumos::Graphics m_DebugDrawData.LineIndexCount += 2; } - // m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->ReleasePointer(); - // m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->Unbind(); - - m_DebugDrawData.m_LineIndexBuffer->SetCount(m_DebugDrawData.LineIndexCount); - - m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->Bind(commandBuffer, pipeline.get()); - uint32_t dataSize = (uint32_t)((uint8_t*)m_DebugDrawData.m_LineBuffer - (uint8_t*)m_LineBufferBase[0]); - m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->SetData(dataSize, (void*)m_LineBufferBase[0]); - - m_DebugDrawData.m_LineIndexBuffer->Bind(commandBuffer); - auto* desc = m_DebugDrawData.m_LineDescriptorSet[0].get(); - Renderer::BindDescriptorSets(pipeline.get(), commandBuffer, 0, &desc, 1); - Renderer::DrawIndexed(commandBuffer, DrawType::LINES, m_DebugDrawData.LineIndexCount); - - m_DebugDrawData.m_LineVertexBuffers[m_DebugDrawData.m_LineBatchDrawCallIndex]->Unbind(); - m_DebugDrawData.m_LineIndexBuffer->Unbind(); - - m_DebugDrawData.m_LineBuffer = m_LineBufferBase[0]; - m_DebugDrawData.LineIndexCount = 0; + DebugLineFlush(pipeline.get()); pipeline->End(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()); - - m_DebugDrawData.m_LineBatchDrawCallIndex++; } if(!points.empty()) @@ -3167,22 +3227,29 @@ namespace Lumos::Graphics pipelineDesc.blendMode = BlendMode::SrcAlphaOneMinusSrcAlpha; pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.DebugName = "Debug-Points"; - + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; + pipelineDesc.samples = m_MainTextureSamples; if(depthTest) pipelineDesc.depthTarget = m_ForwardData.m_DepthTexture; auto pipeline = Graphics::Pipeline::Get(pipelineDesc); - pipeline->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()); + pipeline->Bind(commandBuffer); + + if(m_DebugDrawData.m_PointVertexBuffers.empty()) + m_DebugDrawData.m_PointVertexBuffers.emplace_back(); - if((int)m_DebugDrawData.m_PointVertexBuffers.size() - 1 < (int)m_DebugDrawData.m_PointBatchDrawCallIndex) + int bufferCount = 0; + bufferCount = (int)m_DebugDrawData.m_PointVertexBuffers[0].size(); + if((bufferCount - 1) < (int)m_DebugDrawData.m_PointBatchDrawCallIndex) { - auto& vertexBuffer = m_DebugDrawData.m_PointVertexBuffers.emplace_back(Graphics::VertexBuffer::Create(BufferUsage::DYNAMIC)); + auto& vertexBuffer = m_DebugDrawData.m_PointVertexBuffers[0].emplace_back(Graphics::VertexBuffer::Create(BufferUsage::DYNAMIC)); vertexBuffer->Resize(RENDERER_POINT_BUFFER_SIZE); } - m_DebugDrawData.m_PointVertexBuffers[m_DebugDrawData.m_PointBatchDrawCallIndex]->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), pipeline.get()); - m_DebugDrawData.m_PointBuffer = m_PointBufferBase[0]; // m_DebugDrawData.m_PointVertexBuffers[m_DebugDrawData.m_PointBatchDrawCallIndex]->GetPointer(); + m_DebugDrawData.m_PointVertexBuffers[0][m_DebugDrawData.m_PointBatchDrawCallIndex]->Bind(commandBuffer, pipeline.get()); + m_DebugDrawData.m_PointBuffer = m_PointBufferBase[0][m_DebugDrawData.m_PointBatchDrawCallIndex]; // m_DebugDrawData.m_PointVertexBuffers[m_DebugDrawData.m_PointBatchDrawCallIndex]->GetPointer(); for(auto& pointInfo : points) { @@ -3216,26 +3283,8 @@ namespace Lumos::Graphics m_DebugDrawData.PointIndexCount += 6; } - // m_DebugDrawData.m_PointVertexBuffers[m_DebugDrawData.m_PointBatchDrawCallIndex]->ReleasePointer(); - m_DebugDrawData.m_PointIndexBuffer->SetCount(m_DebugDrawData.PointIndexCount); - m_DebugDrawData.m_PointIndexBuffer->Bind(commandBuffer); - - uint32_t dataSize = (uint32_t)((uint8_t*)m_DebugDrawData.m_PointBuffer - (uint8_t*)m_PointBufferBase[0]); - m_DebugDrawData.m_PointVertexBuffers[m_DebugDrawData.m_PointBatchDrawCallIndex]->SetData(dataSize, (void*)m_PointBufferBase[0]); - - auto* desc = m_DebugDrawData.m_PointDescriptorSet[0].get(); - Renderer::BindDescriptorSets(pipeline.get(), commandBuffer, 0, &desc, 1); - Renderer::DrawIndexed(commandBuffer, DrawType::TRIANGLE, m_DebugDrawData.PointIndexCount); - - m_DebugDrawData.m_PointVertexBuffers[m_DebugDrawData.m_PointBatchDrawCallIndex]->Unbind(); - m_DebugDrawData.m_PointIndexBuffer->Unbind(); - - m_DebugDrawData.m_PointBuffer = m_PointBufferBase[0]; - m_DebugDrawData.PointIndexCount = 0; - - pipeline->End(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()); - - m_DebugDrawData.m_PointBatchDrawCallIndex++; + DebugPointFlush(pipeline.get()); + pipeline->End(commandBuffer); } if(!triangles.empty()) @@ -3254,10 +3303,12 @@ namespace Lumos::Graphics pipelineDesc.clearTargets = false; pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.depthBiasEnabled = true; - pipelineDesc.depthBiasConstantFactor = -1.25f; - pipelineDesc.depthBiasSlopeFactor = -1.75f; + pipelineDesc.depthBiasConstantFactor = 0.0f; + pipelineDesc.depthBiasSlopeFactor = -10.0f; pipelineDesc.DebugName = "Debug-Triangles"; - + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; + pipelineDesc.samples = m_MainTextureSamples; if(depthTest) pipelineDesc.depthTarget = m_ForwardData.m_DepthTexture; @@ -3273,7 +3324,7 @@ namespace Lumos::Graphics m_DebugDrawData.m_Renderer2DData.m_VertexBuffers[currentFrame][m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex]->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), pipeline.get()); // m_DebugDrawData.m_Renderer2DData.m_Buffer = m_DebugDrawData.m_Renderer2DData.m_VertexBuffers[currentFrame][m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex]->GetPointer(); - m_DebugDrawData.m_Renderer2DData.m_Buffer = m_QuadBufferBase[currentFrame]; + m_DebugDrawData.m_Renderer2DData.m_Buffer = m_QuadBufferBase[currentFrame][m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex]; for(auto& triangleInfo : triangles) { @@ -3307,8 +3358,8 @@ namespace Lumos::Graphics m_DebugDrawData.m_Renderer2DData.m_IndexBuffer->SetCount(m_DebugDrawData.m_Renderer2DData.m_IndexCount); m_DebugDrawData.m_Renderer2DData.m_IndexBuffer->Bind(commandBuffer); - uint32_t dataSize = (uint32_t)((uint8_t*)m_DebugDrawData.m_Renderer2DData.m_Buffer - (uint8_t*)m_QuadBufferBase[currentFrame]); - m_DebugDrawData.m_Renderer2DData.m_VertexBuffers[currentFrame][m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex]->SetData(dataSize, (void*)m_QuadBufferBase[currentFrame], true); + uint32_t dataSize = (uint32_t)((uint8_t*)m_DebugDrawData.m_Renderer2DData.m_Buffer - (uint8_t*)m_QuadBufferBase[currentFrame][m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex]); + m_DebugDrawData.m_Renderer2DData.m_VertexBuffers[currentFrame][m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex]->SetData(dataSize, (void*)m_QuadBufferBase[currentFrame][m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex], true); pipeline->Bind(commandBuffer); @@ -3320,7 +3371,8 @@ namespace Lumos::Graphics pipeline->End(commandBuffer); - m_DebugDrawData.m_Renderer2DData.m_Buffer = m_QuadBufferBase[currentFrame]; + // m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex++; + m_DebugDrawData.m_Renderer2DData.m_Buffer = m_QuadBufferBase[currentFrame][m_DebugDrawData.m_Renderer2DData.m_BatchDrawCallIndex]; m_DebugDrawData.m_Renderer2DData.m_IndexCount = 0; } } @@ -3341,7 +3393,10 @@ namespace Lumos::Graphics pipelineDesc.clearTargets = false; pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.DebugName = "Debug-TextDT"; - pipelineDesc.depthTarget = m_ForwardData.m_DepthTexture; + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; + pipelineDesc.samples = m_MainTextureSamples; + //pipelineDesc.depthTarget = m_ForwardData.m_DepthTexture; m_DebugTextRendererData.m_Pipeline = Graphics::Pipeline::Get(pipelineDesc); uint32_t currentFrame = Renderer::GetMainSwapChain()->GetCurrentBufferIndex(); @@ -3507,7 +3562,10 @@ namespace Lumos::Graphics pipelineDesc.blendMode = BlendMode::SrcAlphaOneMinusSrcAlpha; pipelineDesc.clearTargets = false; pipelineDesc.colourTargets[0] = m_MainTexture; - pipelineDesc.DebugName = "Debug-TextNDT"; + pipelineDesc.DebugName = "Debug-TextNDT"; + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; + pipelineDesc.samples = m_MainTextureSamples; m_DebugTextRendererData.m_Pipeline = Graphics::Pipeline::Get(pipelineDesc); uint32_t currentFrame = Renderer::GetMainSwapChain()->GetCurrentBufferIndex(); @@ -3686,6 +3744,9 @@ namespace Lumos::Graphics pipelineDesc.clearTargets = false; pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.DebugName = "Debug-TextCS"; + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; + pipelineDesc.samples = m_MainTextureSamples; m_DebugTextRendererData.m_Pipeline = Graphics::Pipeline::Get(pipelineDesc); uint32_t currentFrame = Renderer::GetMainSwapChain()->GetCurrentBufferIndex(); @@ -3839,6 +3900,72 @@ namespace Lumos::Graphics } } + void RenderPasses::DebugLineFlush(Graphics::Pipeline* pipeline) + { + m_DebugDrawData.m_LineIndexBuffer->SetCount(m_DebugDrawData.LineIndexCount); + m_DebugDrawData.m_LineIndexBuffer->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()); + + uint32_t dataSize = (uint32_t)((uint8_t*)m_DebugDrawData.m_LineBuffer - (uint8_t*)m_LineBufferBase[0][0]); + m_DebugDrawData.m_LineVertexBuffers[0][m_DebugDrawData.m_LineBatchDrawCallIndex]->SetData(dataSize, (void*)m_LineBufferBase[0][0]); + + auto* desc = m_DebugDrawData.m_LineDescriptorSet[0].get(); + Renderer::BindDescriptorSets(pipeline, Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), 0, &desc, 1); + Renderer::DrawIndexed(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), DrawType::LINES, m_DebugDrawData.LineIndexCount); + + m_DebugDrawData.m_LineVertexBuffers[0][m_DebugDrawData.m_LineBatchDrawCallIndex]->Unbind(); + m_DebugDrawData.m_LineIndexBuffer->Unbind(); + + m_DebugDrawData.m_LineBatchDrawCallIndex++; + m_DebugDrawData.m_LineBuffer = m_LineBufferBase[0][0]; //[m_DebugDrawData.m_LineBatchDrawCallIndex]; + m_DebugDrawData.LineIndexCount = 0; + + if(m_DebugDrawData.m_LineVertexBuffers.empty()) + m_DebugDrawData.m_LineVertexBuffers.emplace_back(); + if((int)m_DebugDrawData.m_LineVertexBuffers[0].size() - 1 < (int)m_DebugDrawData.m_LineBatchDrawCallIndex) + { + auto& vertexBuffer = m_DebugDrawData.m_LineVertexBuffers[0].emplace_back(Graphics::VertexBuffer::Create(RENDERER_LINE_BUFFER_SIZE, nullptr, BufferUsage::DYNAMIC)); + // vertexBuffer->Resize(RENDERER_LINE_BUFFER_SIZE); + } + + m_DebugDrawData.m_LineVertexBuffers[0][m_DebugDrawData.m_LineBatchDrawCallIndex]->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), pipeline); + m_DebugDrawData.m_LineBuffer = m_LineBufferBase[0][0]; //[m_DebugDrawData.m_LineBatchDrawCallIndex]; + m_DebugDrawData.LineIndexCount = 0; + } + + void RenderPasses::DebugPointFlush(Graphics::Pipeline* pipeline) + { + // m_DebugDrawData.m_PointVertexBuffers[m_DebugDrawData.m_PointBatchDrawCallIndex]->ReleasePointer(); + m_DebugDrawData.m_PointIndexBuffer->SetCount(m_DebugDrawData.PointIndexCount); + m_DebugDrawData.m_PointIndexBuffer->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer()); + + uint32_t dataSize = (uint32_t)((uint8_t*)m_DebugDrawData.m_PointBuffer - (uint8_t*)m_PointBufferBase[0][m_DebugDrawData.m_PointBatchDrawCallIndex]); + m_DebugDrawData.m_PointVertexBuffers[0][m_DebugDrawData.m_PointBatchDrawCallIndex]->SetData(dataSize, (void*)m_PointBufferBase[0][m_DebugDrawData.m_PointBatchDrawCallIndex]); + + auto* desc = m_DebugDrawData.m_PointDescriptorSet[0].get(); + Renderer::BindDescriptorSets(pipeline, Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), 0, &desc, 1); + Renderer::DrawIndexed(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), DrawType::TRIANGLE, m_DebugDrawData.PointIndexCount); + + m_DebugDrawData.m_PointVertexBuffers[0][m_DebugDrawData.m_PointBatchDrawCallIndex]->Unbind(); + m_DebugDrawData.m_PointIndexBuffer->Unbind(); + + m_DebugDrawData.m_PointBatchDrawCallIndex++; + + if(m_DebugDrawData.m_PointVertexBuffers.empty()) + m_DebugDrawData.m_PointVertexBuffers.emplace_back(); + + int bufferCount = 0; + bufferCount = (int)m_DebugDrawData.m_PointVertexBuffers[0].size(); + if((bufferCount - 1) < (int)m_DebugDrawData.m_PointBatchDrawCallIndex) + { + auto& vertexBuffer = m_DebugDrawData.m_PointVertexBuffers[0].emplace_back(Graphics::VertexBuffer::Create(BufferUsage::DYNAMIC)); + vertexBuffer->Resize(RENDERER_POINT_BUFFER_SIZE); + } + + m_DebugDrawData.m_PointVertexBuffers[0][m_DebugDrawData.m_PointBatchDrawCallIndex]->Bind(Renderer::GetMainSwapChain()->GetCurrentCommandBuffer(), pipeline); + m_DebugDrawData.m_PointBuffer = m_PointBufferBase[0][0]; + m_DebugDrawData.PointIndexCount = 0; + } + void RenderPasses::CreateCubeMap(const std::string& filePath, const glm::vec4& params, SharedPtr& outEnv, SharedPtr& outIrr) { // Create shader and pipeline @@ -3852,7 +3979,7 @@ namespace Lumos::Graphics commandBuffer->BeginRecording(); { - auto shader = Application::Get().GetShaderLibrary()->GetResource("CreateEnvironmentMap"); + auto shader = Application::Get().GetAssetManager()->GetAssetData("CreateEnvironmentMap").As(); Graphics::DescriptorDesc descriptorDesc {}; descriptorDesc.layoutIndex = 0; @@ -3911,8 +4038,7 @@ namespace Lumos::Graphics // Generate Mips { environmentMap->GenerateMipMaps(commandBuffer); - - auto shader = Application::Get().GetShaderLibrary()->GetResource("EnvironmentMipFilter"); + auto shader = Application::Get().GetAssetManager()->GetAssetData("EnvironmentMipFilter").As(); Graphics::DescriptorDesc descriptorDesc {}; descriptorDesc.layoutIndex = 0; @@ -3962,11 +4088,11 @@ namespace Lumos::Graphics } { - auto shader = Application::Get().GetShaderLibrary()->GetResource("EnvironmentIrradiance"); + auto shader = Application::Get().GetAssetManager()->GetAssetData("EnvironmentIrradiance").As(); Graphics::DescriptorDesc descriptorDesc {}; descriptorDesc.layoutIndex = 0; - descriptorDesc.shader = shader.get(); + descriptorDesc.shader = shader; auto descriptorSet = SharedPtr(Graphics::DescriptorSet::Create(descriptorDesc)); descriptorSet->SetTexture("u_Texture", environmentMapFiltered); @@ -4010,6 +4136,8 @@ namespace Lumos::Graphics commandBuffer->EndRecording(); commandBuffer->Submit(); + Graphics::Renderer::GetGraphicsContext()->WaitIdle(); + environmentMap->Destroy(false); delete environmentMap; delete commandBuffer; outEnv = SharedPtr(environmentMapFiltered); @@ -4018,10 +4146,23 @@ namespace Lumos::Graphics void RenderPasses::InitDebugRenderData() { - if(m_DebugRenderDataInitialised) + if(m_DebugRenderDataInitialised || !m_DebugRenderEnabled) return; + + for(int i = 0; i < Renderer::GetMainSwapChain()->GetSwapChainBufferCount(); i++) + { + if(m_DebugRenderEnabled) + { + m_QuadBufferBase.emplace_back().push_back(new VertexData[m_DebugDrawData.m_Renderer2DData.m_Limits.MaxQuads * 4]); + + // m_2DBufferBase.push_back(new VertexData[m_Renderer2DData.m_Limits.MaxQuads * 4]); + m_LineBufferBase.emplace_back().push_back(new LineVertexData[m_DebugDrawData.m_Renderer2DData.m_Limits.MaxQuads * 4]); + m_PointBufferBase.emplace_back().push_back(new PointVertexData[m_DebugDrawData.m_Renderer2DData.m_Limits.MaxQuads * 4]); + DebugTextVertexBufferBase.push_back(new TextVertexData[m_DebugTextRendererData.m_Limits.MaxQuads * 4]); + } + } // Points - m_DebugDrawData.m_PointShader = Application::Get().GetShaderLibrary()->GetResource("Batch2DPoint"); + m_DebugDrawData.m_PointShader = Application::Get().GetAssetManager()->GetAssetData("Batch2DPoint").As(); Graphics::DescriptorDesc descriptorDesc = {}; descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_DebugDrawData.m_PointShader.get(); @@ -4049,7 +4190,7 @@ namespace Lumos::Graphics delete[] indices; // Lines - m_DebugDrawData.m_LineShader = Application::Get().GetShaderLibrary()->GetResource("Batch2DLine"); + m_DebugDrawData.m_LineShader = Application::Get().GetAssetManager()->GetAssetData("Batch2DLine").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_DebugDrawData.m_LineShader.get(); m_DebugDrawData.m_LineDescriptorSet.resize(1); @@ -4071,7 +4212,7 @@ namespace Lumos::Graphics m_DebugDrawData.m_Renderer2DData.m_RenderToDepthTexture = true; m_DebugDrawData.m_Renderer2DData.m_TriangleIndicies = false; m_DebugDrawData.m_Renderer2DData.m_Limits.SetMaxQuads(10000); - m_DebugDrawData.m_Renderer2DData.m_Shader = Application::Get().GetShaderLibrary()->GetResource("Batch2D"); + m_DebugDrawData.m_Renderer2DData.m_Shader = Application::Get().GetAssetManager()->GetAssetData("Batch2D").As(); descriptorDesc.layoutIndex = 0; descriptorDesc.shader = m_DebugDrawData.m_Renderer2DData.m_Shader.get(); @@ -4108,7 +4249,7 @@ namespace Lumos::Graphics DebugTextVertexBufferPtr = DebugTextVertexBufferBase[0]; - m_DebugTextRendererData.m_Shader = Application::Get().GetShaderLibrary()->GetResource("Text"); + m_DebugTextRendererData.m_Shader = Application::Get().GetAssetManager()->GetAssetData("Text").As(); m_DebugTextRendererData.m_TransformationStack.emplace_back(glm::mat4(1.0f)); m_DebugTextRendererData.m_TransformationBack = &m_DebugTextRendererData.m_TransformationStack.back(); @@ -4210,51 +4351,39 @@ namespace Lumos::Graphics return distanceSqA > distanceSqB; } - glm::mat4 CalculateParticleTransform(const glm::vec3& position, const glm::mat4& viewMatrix) - { - glm::mat4 transform = glm::mat4(1.0f); - return transform; - transform = glm::translate(transform, position); - - // Extract the rotation part from the view matrix - glm::mat3 rotationMatrix = glm::mat3(viewMatrix); - - // Set the rotation part of the particle transform matrix - transform[0] = glm::vec4(rotationMatrix[0], 0.0f); - transform[1] = glm::vec4(rotationMatrix[1], 0.0f); - transform[2] = glm::vec4(rotationMatrix[2], 0.0f); - - return transform; - } - void RenderPasses::ParticlePass() { LUMOS_PROFILE_FUNCTION(); LUMOS_PROFILE_GPU("Particle Pass"); + if(!m_Camera || !m_CameraTransform) + return; + auto emitterGroup = m_CurrentScene->GetRegistry().group(entt::get); if(emitterGroup.empty()) return; Graphics::PipelineDesc pipelineDesc; - pipelineDesc.shader = m_ParticleData.m_Shader; - pipelineDesc.polygonMode = Graphics::PolygonMode::FILL; - pipelineDesc.cullMode = Graphics::CullMode::BACK; - pipelineDesc.transparencyEnabled = true; - pipelineDesc.blendMode = BlendMode::SrcAlphaOne; - pipelineDesc.clearTargets = false; - pipelineDesc.depthTarget = reinterpret_cast(m_ForwardData.m_DepthTexture); - pipelineDesc.DepthTest = true; - pipelineDesc.DepthWrite = false; - pipelineDesc.colourTargets[0] = m_MainTexture; - pipelineDesc.DebugName = "Particle"; - + pipelineDesc.shader = m_ParticleData.m_Shader; + pipelineDesc.polygonMode = Graphics::PolygonMode::FILL; + pipelineDesc.cullMode = Graphics::CullMode::BACK; + pipelineDesc.transparencyEnabled = true; + pipelineDesc.blendMode = BlendMode::SrcAlphaOne; + pipelineDesc.clearTargets = false; + pipelineDesc.depthTarget = reinterpret_cast(m_ForwardData.m_DepthTexture); + pipelineDesc.DepthTest = true; + pipelineDesc.DepthWrite = false; + pipelineDesc.colourTargets[0] = m_MainTexture; + if (m_MainTextureSamples > 1) + pipelineDesc.resolveTexture = m_ResolveTexture; + pipelineDesc.DebugName = "Particle"; + pipelineDesc.samples = m_MainTextureSamples; ParticleBeginBatch(); - auto projView = m_Camera->GetProjectionMatrix() * glm::inverse(m_CameraTransform->GetWorldMatrix()); - - auto cameraPos = m_CameraTransform->GetWorldPosition(); + auto projView = m_Camera->GetProjectionMatrix() * glm::inverse(m_CameraTransform->GetWorldMatrix()); + + auto cameraPos = m_CameraTransform->GetWorldPosition(); m_ParticleData.m_DescriptorSet[0][0]->SetUniform("UBO", "projView", &projView); m_ParticleData.m_DescriptorSet[0][0]->Update(); @@ -4273,10 +4402,8 @@ namespace Lumos::Graphics pipelineDesc.blendMode = BlendMode::SrcAlphaOneMinusSrcAlpha; pipelineDesc.clearTargets = false; - pipelineDesc.depthTarget = reinterpret_cast(m_ForwardData.m_DepthTexture); pipelineDesc.DepthTest = true; pipelineDesc.DepthWrite = false; - pipelineDesc.colourTargets[0] = m_MainTexture; pipelineDesc.DebugName = "Particle"; pipelineDesc.depthBiasEnabled = true; pipelineDesc.depthBiasConstantFactor = -1.25f; @@ -4307,23 +4434,23 @@ namespace Lumos::Graphics glm::vec3 v3; glm::vec3 v4; auto alignType = emitter.GetAlignedType(); - if (alignType == ParticleEmitter::Aligned2D) + if(alignType == ParticleEmitter::Aligned2D) { glm::vec3 rightOffset = glm::vec3(1.0f, 0.0f, 0.0f) * particle.Size * 0.5f; - glm::vec3 upOffset = glm::vec3(0.0f, 1.0f, 0.0f) * particle.Size * 0.5f; + glm::vec3 upOffset = glm::vec3(0.0f, 1.0f, 0.0f) * particle.Size * 0.5f; v1 = particle.Position - rightOffset - upOffset; v2 = particle.Position + rightOffset - upOffset; v3 = particle.Position + rightOffset + upOffset; v4 = particle.Position - rightOffset + upOffset; } - else if (alignType == ParticleEmitter::Aligned3D) + else if(alignType == ParticleEmitter::Aligned3D) { glm::vec3 cameraRight = glm::normalize(m_CameraTransform->GetRightDirection()); - glm::vec3 cameraUp = glm::normalize(m_CameraTransform->GetUpDirection()); + glm::vec3 cameraUp = glm::normalize(m_CameraTransform->GetUpDirection()); glm::vec3 rightOffset = cameraRight * particle.Size * 0.5f; - glm::vec3 upOffset = cameraUp * particle.Size * 0.5f; + glm::vec3 upOffset = cameraUp * particle.Size * 0.5f; v1 = particle.Position - rightOffset - upOffset; v2 = particle.Position + rightOffset - upOffset; @@ -4332,8 +4459,8 @@ namespace Lumos::Graphics } else { - glm::vec3 rightOffset = glm::vec3(particle.Size * 0.5f,0.0f, 0.0f); - glm::vec3 upOffset = glm::vec3(0.0f, particle.Size * 0.5f, 0.0f); + glm::vec3 rightOffset = glm::vec3(particle.Size * 0.5f, 0.0f, 0.0f); + glm::vec3 upOffset = glm::vec3(0.0f, particle.Size * 0.5f, 0.0f); v1 = particle.Position - rightOffset - upOffset; v2 = particle.Position + rightOffset - upOffset; @@ -4409,7 +4536,6 @@ namespace Lumos::Graphics m_ParticleData.m_Buffer->colour = colour; m_ParticleData.m_Buffer++; - m_ParticleData.m_Buffer->vertex = v4; if(animated) { @@ -4459,6 +4585,12 @@ namespace Lumos::Graphics { LUMOS_PROFILE_FUNCTION(); uint32_t currentFrame = Renderer::GetMainSwapChain()->GetCurrentBufferIndex(); + for(int i = m_ParticleData.m_TextureCount; i < 16; i++) + { + m_ParticleData.m_Textures[i] = Material::GetDefaultTexture(); + } + + m_ParticleData.m_TextureCount = 16; if(m_ParticleData.m_DescriptorSet[m_ParticleData.m_BatchDrawCallIndex][1] == nullptr || m_ParticleData.m_TextureCount != m_ParticleData.m_PreviousFrameTextureCount[m_ParticleData.m_BatchDrawCallIndex]) { diff --git a/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.h b/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.h index 5173b70f..a3a426b0 100644 --- a/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.h +++ b/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.h @@ -10,6 +10,7 @@ namespace Lumos class TimeStep; class WindowResizeEvent; class Event; + struct SceneRenderSettings; namespace Maths { @@ -53,15 +54,6 @@ namespace Lumos } }; - struct RenderPassesSettings - { - bool DebugPass = true; - bool GeomPass = true; - bool PostProcessPass = false; - bool ShadowPass = true; - bool SkyboxPass = true; - }; - struct RenderPassesStats { uint32_t UpdatesPerSecond; @@ -112,6 +104,8 @@ namespace Lumos void ParticlePass(); void ParticleFlush(); void DebugPass(); + void DebugLineFlush(Graphics::Pipeline* pipeline); + void DebugPointFlush(Graphics::Pipeline* pipeline); void FinalPass(); void TextPass(); @@ -250,11 +244,11 @@ namespace Lumos struct DebugDrawData { - std::vector m_LineVertexBuffers; + std::vector> m_LineVertexBuffers; Graphics::IndexBuffer* m_LineIndexBuffer; Graphics::IndexBuffer* m_PointIndexBuffer = nullptr; - std::vector m_PointVertexBuffers; + std::vector> m_PointVertexBuffers; std::vector> m_LineDescriptorSet; std::vector> m_PointDescriptorSet; @@ -275,7 +269,6 @@ namespace Lumos ForwardData& GetForwardData() { return m_ForwardData; } ShadowData& GetShadowData() { return m_ShadowData; } - RenderPassesSettings& GetSettings() { return m_Settings; } RenderPassesStats& GetRenderPassesStats() { return m_Stats; } void CreateCubeMap(const std::string& filePath, const glm::vec4& params, SharedPtr& outEnv, SharedPtr& outIrr); @@ -289,9 +282,9 @@ namespace Lumos void Init2DRenderData(); bool m_2DRenderDataInitialised = false; - Texture2D* m_MainTexture = nullptr; - Texture2D* m_LastRenderTarget = nullptr; - + Texture2D* m_MainTexture = nullptr; + Texture2D* m_ResolveTexture = nullptr; + Texture2D* m_LastRenderTarget = nullptr; Texture2D* m_PostProcessTexture1 = nullptr; Texture2D* m_PostProcessTexture2 = nullptr; @@ -311,11 +304,12 @@ namespace Lumos TextVertexData* TextVertexBufferPtr = nullptr; + // Vertex data per frame in flight, per batch std::vector> m_ParticleBufferBase; std::vector> m_2DBufferBase; - std::vector m_LineBufferBase; - std::vector m_PointBufferBase; - std::vector m_QuadBufferBase; + std::vector> m_LineBufferBase; + std::vector> m_PointBufferBase; + std::vector> m_QuadBufferBase; std::vector TextVertexBufferBase; std::vector DebugTextVertexBufferBase; TextVertexData* DebugTextVertexBufferPtr = nullptr; @@ -393,13 +387,15 @@ namespace Lumos SharedPtr m_SharpenPassDescriptorSet; SharedPtr m_SharpenShader; - RenderPassesSettings m_Settings; RenderPassesStats m_Stats; + uint8_t m_MainTextureSamples = 4; // Outline pass Graphics::Model* m_SelectedModel = nullptr; Maths::Transform* m_SelectedModelTransform = nullptr; + SceneRenderSettings* m_OverrideSceneRenderSettings = nullptr; //For editor viewport + void TextFlush(Renderer2DData& textRenderData, std::vector& textVertexBufferBase, TextVertexData*& textVertexBufferPtr); }; } diff --git a/Lumos/Source/Lumos/Graphics/Sprite.h b/Lumos/Source/Lumos/Graphics/Sprite.h index ef7dbb71..c1501137 100644 --- a/Lumos/Source/Lumos/Graphics/Sprite.h +++ b/Lumos/Source/Lumos/Graphics/Sprite.h @@ -2,9 +2,6 @@ #include "Renderable2D.h" #include "Core/OS/FileSystem.h" -#include "Scene/Serialisation.h" -#include "Maths/MathsSerialisation.h" - namespace Lumos { namespace Graphics @@ -13,6 +10,12 @@ namespace Lumos class LUMOS_EXPORT Sprite : public Renderable2D { + template + friend void save(Archive& archive, const Sprite& sprite); + + template + friend void load(Archive& archive, Sprite& sprite); + public: Sprite(const glm::vec2& position = glm::vec2(0.0f, 0.0f), const glm::vec2& scale = glm::vec2(1.0f, 1.0f), const glm::vec4& colour = glm::vec4(1.0f)); Sprite(const SharedPtr& texture, const glm::vec2& position, const glm::vec2& scale, const glm::vec4& colour); @@ -29,39 +32,6 @@ namespace Lumos bool UsingSpriteSheet = false; uint32_t SpriteSheetTileSize = 32; - - template - void save(Archive& archive) const - { - std::string newPath = ""; - if(m_Texture) - { - FileSystem::Get().AbsolutePathToFileSystem(m_Texture->GetFilepath(), newPath); - } - - archive(cereal::make_nvp("TexturePath", newPath), - cereal::make_nvp("Position", m_Position), - cereal::make_nvp("Scale", m_Scale), - cereal::make_nvp("Colour", m_Colour)); - - archive(UsingSpriteSheet, SpriteSheetTileSize); - } - - template - void load(Archive& archive) - { - std::string textureFilePath; - archive(cereal::make_nvp("TexturePath", textureFilePath), - cereal::make_nvp("Position", m_Position), - cereal::make_nvp("Scale", m_Scale), - cereal::make_nvp("Colour", m_Colour)); - - if(!textureFilePath.empty()) - m_Texture = SharedPtr(Graphics::Texture2D::CreateFromFile("sprite", textureFilePath)); - - if(Serialisation::CurrentSceneVersion > 21) - archive(UsingSpriteSheet, SpriteSheetTileSize); - } }; } } diff --git a/Lumos/Source/Lumos/ImGui/ImGuiManager.cpp b/Lumos/Source/Lumos/ImGui/ImGuiManager.cpp index 866a858e..9ec92b88 100644 --- a/Lumos/Source/Lumos/ImGui/ImGuiManager.cpp +++ b/Lumos/Source/Lumos/ImGui/ImGuiManager.cpp @@ -71,6 +71,10 @@ namespace Lumos #ifdef LUMOS_PLATFORM_IOS io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen; #endif + +#ifdef LUMOS_PLATFORM_MACOS + io.ConfigMacOSXBehaviors = true; + #endif io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; io.ConfigWindowsMoveFromTitleBarOnly = true; @@ -139,6 +143,7 @@ namespace Lumos void ImGuiManager::OnNewFrame() { + LUMOS_PROFILE_FUNCTION(); m_IMGUIRenderer->NewFrame(); } @@ -188,7 +193,6 @@ namespace Lumos { ImGuiIO& io = ImGui::GetIO(); io.AddMouseWheelEvent((float)e.GetXOffset(), (float)e.GetYOffset()); - return false; } @@ -207,7 +211,7 @@ namespace Lumos io.KeySuper = io.KeysDown[(int)Lumos::InputCode::Key::LeftSuper] || io.KeysDown[(int)Lumos::InputCode::Key::RightSuper]; #endif - return io.WantTextInput; + return io.WantTextInput && !io.KeyCtrl && !io.KeySuper; } bool ImGuiManager::OnKeyReleasedEvent(KeyReleasedEvent& e) diff --git a/Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp b/Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp index 55f17c39..bbac4f57 100644 --- a/Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp +++ b/Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp @@ -237,6 +237,34 @@ namespace Lumos return updated; } + bool ImGuiUtilities::Property(const char* name, uint8_t& value, ImGuiUtilities::PropertyFlag flags) + { + LUMOS_PROFILE_FUNCTION(); + bool updated = false; + + ImGui::AlignTextToFramePadding(); + ImGui::TextUnformatted(name); + ImGui::NextColumn(); + ImGui::PushItemWidth(-1); + + if ((int)flags & (int)PropertyFlag::ReadOnly) + { + ImGui::Text("%d", value); + } + else if ((int)flags & (int)PropertyFlag::DragValue) + { + updated = ImGui::DragScalar(GenerateID(), ImGuiDataType_U8, &value); + } + else + { + updated = ImGui::InputScalar(GenerateID(), ImGuiDataType_U8, &value); + } + ImGui::PopItemWidth(); + ImGui::NextColumn(); + + return updated; + } + bool ImGuiUtilities::Property(const char* name, float& value, float min, float max, float delta, ImGuiUtilities::PropertyFlag flags) { LUMOS_PROFILE_FUNCTION(); @@ -555,7 +583,7 @@ namespace Lumos if(ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - bool flipImage = Graphics::Renderer::GetGraphicsContext()->FlipImGUITexture(); + bool flipImage = false;// Graphics::Renderer::GetGraphicsContext()->FlipImGUITexture(); ImGui::Image(texture ? Application::Get().GetImGuiManager()->GetImGuiRenderer()->AddTexture(texture) : nullptr, ImVec2(size.x, size.y), ImVec2(0.0f, flipImage ? 1.0f : 0.0f), ImVec2(1.0f, flipImage ? 0.0f : 1.0f)); ImGui::TextUnformatted(text); ImGui::EndTooltip(); diff --git a/Lumos/Source/Lumos/ImGui/ImGuiUtilities.h b/Lumos/Source/Lumos/ImGui/ImGuiUtilities.h index 32d51b43..3d99964b 100644 --- a/Lumos/Source/Lumos/ImGui/ImGuiUtilities.h +++ b/Lumos/Source/Lumos/ImGui/ImGuiUtilities.h @@ -6,6 +6,14 @@ #include #include + +static float value1 = 0.0f; +static float value2 = 0.0f; +#define IMGUI_VALUE_WINDOW(windowName, valueName, value) \ +ImGui::Begin(windowName, nullptr); \ +ImGui::DragFloat(valueName, &value);\ +ImGui::End(); + namespace Lumos { namespace Graphics @@ -47,6 +55,7 @@ namespace Lumos bool Property(const char* name, bool& value, PropertyFlag flags = PropertyFlag::None); bool Property(const char* name, int& value, PropertyFlag flags); bool Property(const char* name, uint32_t& value, PropertyFlag flags = PropertyFlag::None); + bool Property(const char* name, uint8_t& value, PropertyFlag flags = PropertyFlag::None); bool PropertyMultiline(const char* label, std::string& value); bool Property(const char* name, double& value, double min = -1.0, double max = 1.0, PropertyFlag flags = PropertyFlag::None); diff --git a/Lumos/Source/Lumos/Maths/BoundingBox.h b/Lumos/Source/Lumos/Maths/BoundingBox.h index c3f368de..356213be 100644 --- a/Lumos/Source/Lumos/Maths/BoundingBox.h +++ b/Lumos/Source/Lumos/Maths/BoundingBox.h @@ -2,8 +2,6 @@ #include "Maths/Rect.h" #include "MathsUtilities.h" #include -#include -#include namespace Lumos { diff --git a/Lumos/Source/Lumos/Maths/MathsUtilities.cpp b/Lumos/Source/Lumos/Maths/MathsUtilities.cpp index c74caf42..da667865 100644 --- a/Lumos/Source/Lumos/Maths/MathsUtilities.cpp +++ b/Lumos/Source/Lumos/Maths/MathsUtilities.cpp @@ -4,6 +4,102 @@ #include namespace Lumos::Maths { + /// Check whether an unsigned integer is a power of two. + bool IsPowerOfTwo(unsigned value) + { + return !(value & (value - 1)); + } + + /// Round up to next power of two. + unsigned NextPowerOfTwo(unsigned value) + { + // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + --value; + value |= value >> 1u; + value |= value >> 2u; + value |= value >> 4u; + value |= value >> 8u; + value |= value >> 16u; + return ++value; + } + + /// Round up or down to the closest power of two. + unsigned ClosestPowerOfTwo(unsigned value) + { + unsigned next = NextPowerOfTwo(value); + unsigned prev = next >> (unsigned)1; + return (value - prev) > (next - value) ? next : prev; + } + + /// Return log base two or the MSB position of the given value. + unsigned LogBaseTwo(unsigned value) + { + // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious + unsigned ret = 0; + while(value >>= 1) // Unroll for more speed... + ++ret; + return ret; + } + + /// Count the number of set bits in a mask. + unsigned CountSetBits(unsigned value) + { + // Brian Kernighan's method + unsigned count = 0; + for(count = 0; value; count++) + value &= value - 1; + return count; + } + + /// Update a hash with the given 8-bit value using the SDBM algorithm. + constexpr unsigned SDBMHash(unsigned hash, unsigned char c) + { + return c + (hash << 6u) + (hash << 16u) - hash; + } + + /// Convert float to half float + unsigned short FloatToHalf(float value) + { + unsigned inu = FloatToRawIntBits(value); + unsigned t1 = inu & 0x7fffffffu; // Non-sign bits + unsigned t2 = inu & 0x80000000u; // Sign bit + unsigned t3 = inu & 0x7f800000u; // Exponent + + t1 >>= 13; // Align mantissa on MSB + t2 >>= 16; // Shift sign bit into position + + t1 -= 0x1c000; // Adjust bias + + t1 = (t3 < 0x38800000) ? 0 : t1; // Flush-to-zero + t1 = (t3 > 0x47000000) ? 0x7bff : t1; // Clamp-to-max + t1 = (t3 == 0 ? 0 : t1); // Denormals-as-zero + + t1 |= t2; // Re-insert sign bit + + return (unsigned short)t1; + } + + /// Convert half float to float + float HalfToFloat(unsigned short value) + { + unsigned t1 = value & 0x7fffu; // Non-sign bits + unsigned t2 = value & 0x8000u; // Sign bit + unsigned t3 = value & 0x7c00u; // Exponent + + t1 <<= 13; // Align mantissa on MSB + t2 <<= 16; // Shift sign bit into position + + t1 += 0x38000000; // Adjust bias + + t1 = (t3 == 0 ? 0 : t1); // Denormals-as-zero + + t1 |= t2; // Re-insert sign bit + + float out; + *((unsigned*)&out) = t1; + return out; + } + void SinCos(float angle, float& sin, float& cos) { float angleRadians = angle * M_DEGTORAD; diff --git a/Lumos/Source/Lumos/Maths/MathsUtilities.h b/Lumos/Source/Lumos/Maths/MathsUtilities.h index 1d8c2424..9c13a6a5 100644 --- a/Lumos/Source/Lumos/Maths/MathsUtilities.h +++ b/Lumos/Source/Lumos/Maths/MathsUtilities.h @@ -6,7 +6,6 @@ #pragma warning(disable : 4702) // unreachable code #endif -#include "Maths/Random.h" #include "Core/Core.h" #include @@ -326,100 +325,28 @@ namespace Lumos } /// Check whether an unsigned integer is a power of two. - inline bool IsPowerOfTwo(unsigned value) - { - return !(value & (value - 1)); - } + bool IsPowerOfTwo(unsigned value); /// Round up to next power of two. - inline unsigned NextPowerOfTwo(unsigned value) - { - // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 - --value; - value |= value >> 1u; - value |= value >> 2u; - value |= value >> 4u; - value |= value >> 8u; - value |= value >> 16u; - return ++value; - } + unsigned NextPowerOfTwo(unsigned value); /// Round up or down to the closest power of two. - inline unsigned ClosestPowerOfTwo(unsigned value) - { - unsigned next = NextPowerOfTwo(value); - unsigned prev = next >> (unsigned)1; - return (value - prev) > (next - value) ? next : prev; - } + unsigned ClosestPowerOfTwo(unsigned value); /// Return log base two or the MSB position of the given value. - inline unsigned LogBaseTwo(unsigned value) - { - // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious - unsigned ret = 0; - while(value >>= 1) // Unroll for more speed... - ++ret; - return ret; - } + unsigned LogBaseTwo(unsigned value); /// Count the number of set bits in a mask. - inline unsigned CountSetBits(unsigned value) - { - // Brian Kernighan's method - unsigned count = 0; - for(count = 0; value; count++) - value &= value - 1; - return count; - } + unsigned CountSetBits(unsigned value); /// Update a hash with the given 8-bit value using the SDBM algorithm. - inline constexpr unsigned SDBMHash(unsigned hash, unsigned char c) - { - return c + (hash << 6u) + (hash << 16u) - hash; - } + constexpr unsigned SDBMHash(unsigned hash, unsigned char c); /// Convert float to half float - inline unsigned short FloatToHalf(float value) - { - unsigned inu = FloatToRawIntBits(value); - unsigned t1 = inu & 0x7fffffffu; // Non-sign bits - unsigned t2 = inu & 0x80000000u; // Sign bit - unsigned t3 = inu & 0x7f800000u; // Exponent - - t1 >>= 13; // Align mantissa on MSB - t2 >>= 16; // Shift sign bit into position - - t1 -= 0x1c000; // Adjust bias - - t1 = (t3 < 0x38800000) ? 0 : t1; // Flush-to-zero - t1 = (t3 > 0x47000000) ? 0x7bff : t1; // Clamp-to-max - t1 = (t3 == 0 ? 0 : t1); // Denormals-as-zero - - t1 |= t2; // Re-insert sign bit - - return (unsigned short)t1; - } + unsigned short FloatToHalf(float value); /// Convert half float to float - inline float HalfToFloat(unsigned short value) - { - unsigned t1 = value & 0x7fffu; // Non-sign bits - unsigned t2 = value & 0x8000u; // Sign bit - unsigned t3 = value & 0x7c00u; // Exponent - - t1 <<= 13; // Align mantissa on MSB - t2 <<= 16; // Shift sign bit into position - - t1 += 0x38000000; // Adjust bias - - t1 = (t3 == 0 ? 0 : t1); // Denormals-as-zero - - t1 |= t2; // Re-insert sign bit - - float out; - *((unsigned*)&out) = t1; - return out; - } + float HalfToFloat(unsigned short value); /// Wrap a value fitting it in the range defined by [min, max) template diff --git a/Lumos/Source/Lumos/Maths/Rect.h b/Lumos/Source/Lumos/Maths/Rect.h index 12598443..07fc8a7b 100644 --- a/Lumos/Source/Lumos/Maths/Rect.h +++ b/Lumos/Source/Lumos/Maths/Rect.h @@ -2,7 +2,6 @@ #include "MathsUtilities.h" #include #include -#include namespace Lumos { diff --git a/Lumos/Source/Lumos/Maths/Transform.cpp b/Lumos/Source/Lumos/Maths/Transform.cpp index d703203b..0d2528b8 100644 --- a/Lumos/Source/Lumos/Maths/Transform.cpp +++ b/Lumos/Source/Lumos/Maths/Transform.cpp @@ -1,7 +1,6 @@ #include "Precompiled.h" #include "Transform.h" #include -#include namespace Lumos { diff --git a/Lumos/Source/Lumos/Maths/Transform.h b/Lumos/Source/Lumos/Maths/Transform.h index 4010b8f7..0040bc8d 100644 --- a/Lumos/Source/Lumos/Maths/Transform.h +++ b/Lumos/Source/Lumos/Maths/Transform.h @@ -1,14 +1,27 @@ #pragma once -#include "Maths/MathsSerialisation.h" -#include +#include +#include +#define GLM_ENABLE_EXPERIMENTAL +#include namespace Lumos { namespace Maths { - class LUMOS_EXPORT Transform + struct WorldTransform { + glm::mat4 WorldMatrix; + }; + + class Transform + { + template + friend void save(Archive& archive, const Transform& transform); + + template + friend void load(Archive& archive, Transform& transform); + public: Transform(); Transform(const glm::mat4& matrix); @@ -60,18 +73,6 @@ namespace Lumos return forward; } - template - void save(Archive& archive) const - { - archive(cereal::make_nvp("Position", m_LocalPosition), cereal::make_nvp("Rotation", m_LocalOrientation), cereal::make_nvp("Scale", m_LocalScale)); - } - - template - void load(Archive& archive) - { - archive(cereal::make_nvp("Position", m_LocalPosition), cereal::make_nvp("Rotation", m_LocalOrientation), cereal::make_nvp("Scale", m_LocalScale)); - } - protected: glm::mat4 m_WorldMatrix; diff --git a/Lumos/Source/Lumos/Physics/B2PhysicsEngine/B2DebugDraw.cpp b/Lumos/Source/Lumos/Physics/B2PhysicsEngine/B2DebugDraw.cpp index e139057c..7a874987 100644 --- a/Lumos/Source/Lumos/Physics/B2PhysicsEngine/B2DebugDraw.cpp +++ b/Lumos/Source/Lumos/Physics/B2PhysicsEngine/B2DebugDraw.cpp @@ -12,7 +12,7 @@ namespace Lumos for(int32 i = 0; i < vertexCount; ++i) { b2Vec2 p2 = vertices[i]; - DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, { colour.r, colour.g, colour.b, colour.a }); + DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, false, { colour.r, colour.g, colour.b, colour.a }); p1 = p2; } } @@ -24,14 +24,14 @@ namespace Lumos for(int32 i = 1; i < vertexCount - 1; ++i) { - DebugRenderer::DrawTriangle({ vertices[0].x, vertices[0].y, 0.0f }, { vertices[2].x, vertices[2].y, 0.0f }, { vertices[1].x, vertices[1].y, 0.0f }, { fillColour.r, fillColour.g, fillColour.b, fillColour.a }); + DebugRenderer::DrawTriangle({ vertices[0].x, vertices[0].y, 0.0f }, { vertices[2].x, vertices[2].y, 0.0f }, { vertices[1].x, vertices[1].y, 0.0f }, false, { fillColour.r, fillColour.g, fillColour.b, fillColour.a }); } b2Vec2 p1 = vertices[vertexCount - 1]; for(int32 i = 0; i < vertexCount; ++i) { b2Vec2 p2 = vertices[i]; - DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, { colour.r, colour.g, colour.b, colour.a }); + DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, false, { colour.r, colour.g, colour.b, colour.a }); p1 = p2; } } @@ -52,7 +52,7 @@ namespace Lumos r2.x = cosInc * r1.x - sinInc * r1.y; r2.y = sinInc * r1.x + cosInc * r1.y; b2Vec2 v2 = center + radius * r2; - DebugRenderer::DrawHairLine({ v1.x, v1.y, 0.0f }, { v2.x, v2.y, 0.0f }, { colour.r, colour.g, colour.b, colour.a }); + DebugRenderer::DrawHairLine({ v1.x, v1.y, 0.0f }, { v2.x, v2.y, 0.0f }, false, { colour.r, colour.g, colour.b, colour.a }); r1 = r2; v1 = v2; } @@ -76,7 +76,7 @@ namespace Lumos r2.x = cosInc * r1.x - sinInc * r1.y; r2.y = sinInc * r1.x + cosInc * r1.y; b2Vec2 v2 = center + radius * r2; - DebugRenderer::DrawTriangle({ v0.x, v0.y, 0.0f }, { v2.x, v2.y, 0.0f }, { v1.x, v1.y, 0.0f }, { fillColour.r, fillColour.g, fillColour.b, fillColour.a }); + DebugRenderer::DrawTriangle({ v0.x, v0.y, 0.0f }, { v2.x, v2.y, 0.0f }, { v1.x, v1.y, 0.0f }, false, { fillColour.r, fillColour.g, fillColour.b, fillColour.a }); r1 = r2; v1 = v2; } @@ -89,7 +89,7 @@ namespace Lumos r2.x = cosInc * r1.x - sinInc * r1.y; r2.y = sinInc * r1.x + cosInc * r1.y; b2Vec2 v2 = center + radius * r2; - DebugRenderer::DrawHairLine({ v1.x, v1.y, 0.0f }, { v2.x, v2.y, 0.0f }, { colour.r, colour.g, colour.b, colour.a }); + DebugRenderer::DrawHairLine({ v1.x, v1.y, 0.0f }, { v2.x, v2.y, 0.0f }, false, { colour.r, colour.g, colour.b, colour.a }); r1 = r2; v1 = v2; @@ -97,13 +97,13 @@ namespace Lumos // Draw a line fixed in the circle to animate rotation. b2Vec2 p = center + radius * axis; - DebugRenderer::DrawHairLine({ p.x, p.y, 0.0f }, { center.x, center.y, 0.0f }, { colour.r, colour.g, colour.b, colour.a }); + DebugRenderer::DrawHairLine({ p.x, p.y, 0.0f }, { center.x, center.y, 0.0f }, false, { colour.r, colour.g, colour.b, colour.a }); } // void B2DebugDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& colour) { - DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, { colour.r, colour.g, colour.b, colour.a }); + DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, false, { colour.r, colour.g, colour.b, colour.a }); } // @@ -115,16 +115,16 @@ namespace Lumos b2Vec2 p1 = xf.p, p2; p2 = p1 + k_axisScale * xf.q.GetXAxis(); - DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, { red.r, red.g, red.b, red.a }); + DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, false, { red.r, red.g, red.b, red.a }); p2 = p1 + k_axisScale * xf.q.GetYAxis(); - DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, { green.r, green.g, green.b, green.a }); + DebugRenderer::DrawHairLine({ p1.x, p1.y, 0.0f }, { p2.x, p2.y, 0.0f }, false, { green.r, green.g, green.b, green.a }); } // void B2DebugDraw::DrawPoint(const b2Vec2& p, float size, const b2Color& colour) { - DebugRenderer::DrawPoint({ p.x, p.y, 0.0f }, size, { colour.r, colour.g, colour.b, colour.a }); + DebugRenderer::DrawPoint({ p.x, p.y, 0.0f }, size, false, { colour.r, colour.g, colour.b, colour.a }); } } diff --git a/Lumos/Source/Lumos/Physics/B2PhysicsEngine/B2PhysicsEngine.cpp b/Lumos/Source/Lumos/Physics/B2PhysicsEngine/B2PhysicsEngine.cpp index 27addd5d..d0ea24ee 100755 --- a/Lumos/Source/Lumos/Physics/B2PhysicsEngine/B2PhysicsEngine.cpp +++ b/Lumos/Source/Lumos/Physics/B2PhysicsEngine/B2PhysicsEngine.cpp @@ -14,6 +14,7 @@ #include #include +#include namespace Lumos { diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/Broadphase.h b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/Broadphase.h index 9c57fa8a..4f19f3f8 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/Broadphase.h +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/Broadphase.h @@ -1,6 +1,7 @@ #pragma once #include "Physics/LumosPhysicsEngine/RigidBody3D.h" +#include "Core/DataStructures/Vector.h" namespace Lumos { @@ -14,8 +15,8 @@ namespace Lumos class LUMOS_EXPORT Broadphase { public: - virtual ~Broadphase() = default; - virtual void FindPotentialCollisionPairs(RigidBody3D* rootObject, std::vector& collisionPairs) = 0; - virtual void DebugDraw() = 0; + virtual ~Broadphase() = default; + virtual void FindPotentialCollisionPairs(RigidBody3D* rootObject, Vector& collisionPairs) = 0; + virtual void DebugDraw() = 0; }; } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/BruteForceBroadphase.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/BruteForceBroadphase.cpp index 12dff65f..073d997c 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/BruteForceBroadphase.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/BruteForceBroadphase.cpp @@ -15,7 +15,7 @@ namespace Lumos } void BruteForceBroadphase::FindPotentialCollisionPairs(RigidBody3D* rootObject, - std::vector& collisionPairs) + Vector& collisionPairs) { LUMOS_PROFILE_FUNCTION(); @@ -62,7 +62,7 @@ namespace Lumos } bool duplicate = false; - for(int i = 0; i < collisionPairs.size(); i++) + for(int i = 0; i < collisionPairs.Size(); i++) { auto& pair2 = collisionPairs[i]; @@ -72,7 +72,7 @@ namespace Lumos } } if(!duplicate) - collisionPairs.push_back(pair); + collisionPairs.EmplaceBack(pair); } } } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/BruteForceBroadphase.h b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/BruteForceBroadphase.h index 0052489b..7d9baf3c 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/BruteForceBroadphase.h +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/BruteForceBroadphase.h @@ -12,7 +12,7 @@ namespace Lumos explicit BruteForceBroadphase(const glm::vec3& axis = glm::vec3(0.0f)); virtual ~BruteForceBroadphase(); - void FindPotentialCollisionPairs(RigidBody3D* rootObject, std::vector& collisionPairs) override; + void FindPotentialCollisionPairs(RigidBody3D* rootObject, Vector& collisionPairs) override; void DebugDraw() override; private: diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/OctreeBroadphase.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/OctreeBroadphase.cpp index 2e2febae..c0e13bfc 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/OctreeBroadphase.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/OctreeBroadphase.cpp @@ -22,7 +22,7 @@ namespace Lumos } void OctreeBroadphase::FindPotentialCollisionPairs(RigidBody3D* rootObject, - std::vector& collisionPairs) + Vector& collisionPairs) { LUMOS_PROFILE_FUNCTION(); m_CurrentPoolIndex = 0; @@ -100,7 +100,7 @@ namespace Lumos } bool duplicate = false; - for(int i = 0; i < collisionPairs.size(); i++) + for(int i = 0; i < collisionPairs.Size(); i++) { auto& pair2 = collisionPairs[i]; @@ -110,7 +110,7 @@ namespace Lumos } } if(!duplicate) - collisionPairs.push_back(pair); + collisionPairs.EmplaceBack(pair); } } } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/OctreeBroadphase.h b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/OctreeBroadphase.h index 087b92d1..90cac7b2 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/OctreeBroadphase.h +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Broadphase/OctreeBroadphase.h @@ -42,7 +42,7 @@ namespace Lumos Maths::BoundingBox boundingBox; }; - void FindPotentialCollisionPairs(RigidBody3D* rootObject, std::vector& collisionPairs) override; + void FindPotentialCollisionPairs(RigidBody3D* rootObject, Vector& collisionPairs) override; void DebugDraw() override; void Divide(OctreeNode& node, size_t iteration); void DebugDrawOctreeNode(const OctreeNode& node); diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/CapsuleCollisionShape.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/CapsuleCollisionShape.cpp index 342166dc..a555ad06 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/CapsuleCollisionShape.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/CapsuleCollisionShape.cpp @@ -55,21 +55,68 @@ namespace Lumos void CapsuleCollisionShape::GetMinMaxVertexOnAxis(const RigidBody3D* currentObject, const glm::vec3& axis, glm::vec3* out_min, glm::vec3* out_max) const { - glm::mat4 transform = currentObject ? currentObject->GetWorldSpaceTransform() * m_LocalTransform : m_LocalTransform; + // glm::mat4 transform = currentObject ? currentObject->GetWorldSpaceTransform() * m_LocalTransform : m_LocalTransform; + // glm::vec3 pos = transform[3]; + // + // glm::vec3 topPosition = glm::vec3(transform * glm::vec4(0.0f, m_Height * 0.5f, 0.0f, 1.0f)); + // glm::vec3 bottomPosition = glm::vec3(transform * glm::vec4(0.0f, -m_Height * 0.5f, 0.0f, 1.0f)); + // + // // Transform the axis into the local coordinate space of the capsule + // glm::mat4 inverseTransform = glm::affineInverse(transform); + // glm::vec3 localAxis = glm::vec3(inverseTransform * glm::vec4(axis, 1.0f)); + // + // float minProj = glm::dot(topPosition, localAxis) - m_Radius; + // float maxProj = glm::dot(bottomPosition, localAxis) + m_Radius; + // + // *out_min = topPosition + minProj * localAxis; + // *out_max = bottomPosition + maxProj * localAxis; + + float minCorrelation = FLT_MAX, maxCorrelation = -FLT_MAX; + + glm::mat4 transform = currentObject ? currentObject->GetWorldSpaceTransform() * m_LocalTransform : m_LocalTransform; + const glm::vec3 localAxis = glm::transpose(transform) * glm::vec4(axis, 1.0f); + glm::vec3 pos = transform[3]; + glm::vec3 minVertex = glm::vec3(0.0f), maxVertex = glm::vec3(0); glm::vec3 topPosition = glm::vec3(transform * glm::vec4(0.0f, m_Height * 0.5f, 0.0f, 1.0f)); glm::vec3 bottomPosition = glm::vec3(transform * glm::vec4(0.0f, -m_Height * 0.5f, 0.0f, 1.0f)); // Transform the axis into the local coordinate space of the capsule - glm::mat4 inverseTransform = glm::affineInverse(transform); - glm::vec3 localAxis = glm::vec3(inverseTransform * glm::vec4(axis, 1.0f)); + // glm::mat4 inverseTransform = glm::affineInverse(transform); + // glm::vec3 localAxis = glm::vec3(inverseTransform * glm::vec4(axis, 1.0f)); float minProj = glm::dot(topPosition, localAxis) - m_Radius; float maxProj = glm::dot(bottomPosition, localAxis) + m_Radius; - *out_min = topPosition + minProj * localAxis; - *out_max = bottomPosition + maxProj * localAxis; + if(out_min) + *out_min = topPosition + minProj; // * localAxis; + if(out_max) + *out_max = bottomPosition + maxProj; // * localAxis; + + // Capsule Collision shape + // for(size_t i = 0; i < m_Vertices.size(); ++i) + // { + // const float cCorrelation = glm::dot(local_axis, m_Vertices[i].pos); + // + // if(cCorrelation > maxCorrelation) + // { + // maxCorrelation = cCorrelation; + // maxVertex = int(i); + // } + // + // if(cCorrelation <= minCorrelation) + // { + // minCorrelation = cCorrelation; + // minVertex = int(i); + // } + // } + + // if(out_min) + // *out_min = pos - axis * m_Radius; + // + // if(out_max) + // *out_max = pos + axis * m_Radius; } void CapsuleCollisionShape::GetIncidentReferencePolygon(const RigidBody3D* currentObject, diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/Hull.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/Hull.cpp index dcc7c6f8..78b3a0aa 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/Hull.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/Hull.cpp @@ -179,7 +179,7 @@ namespace Lumos { glm::vec3 polygon_next = transform * glm::vec4(m_Vertices[face.vert_ids[idx]].pos, 1.0f); - DebugRenderer::DrawTriangle(polygon_start, polygon_last, polygon_next, glm::vec4(0.9f, 0.9f, 0.9f, 0.2f)); + DebugRenderer::DrawTriangle(polygon_start, polygon_last, polygon_next, true, glm::vec4(0.9f, 0.9f, 0.9f, 0.2f)); polygon_last = polygon_next; } } @@ -188,7 +188,7 @@ namespace Lumos // Draw all Hull Edges for(HullEdge& edge : m_Edges) { - DebugRenderer::DrawThickLine(transform * glm::vec4(m_Vertices[edge.vStart].pos, 1.0f), transform * glm::vec4(m_Vertices[edge.vEnd].pos, 1.0f), 0.02f, glm::vec4(0.7f, 0.2f, 0.7f, 1.0f)); + DebugRenderer::DrawThickLine(transform * glm::vec4(m_Vertices[edge.vStart].pos, 1.0f), transform * glm::vec4(m_Vertices[edge.vEnd].pos, 1.0f), 0.02f, true, glm::vec4(0.7f, 0.2f, 0.7f, 1.0f)); } } } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/HullCollisionShape.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/HullCollisionShape.cpp index 30b57e1f..9ad622d1 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/HullCollisionShape.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/CollisionShapes/HullCollisionShape.cpp @@ -4,14 +4,21 @@ #include #include "Graphics/Mesh.h" +#include "Graphics/MeshFactory.h" namespace Lumos { HullCollisionShape::HullCollisionShape() { - m_HalfDimensions = glm::vec3(0.5f, 0.5f, 0.5f); + m_HalfDimensions = glm::vec3(1.0f); m_Type = CollisionShapeType::CollisionHull; m_Axes.resize(3); + + auto test = Lumos::SharedPtr(Lumos::Graphics::CreatePrimative(Lumos::Graphics::PrimitiveType::Cube)); + BuildFromMesh(test.get()); + + m_LocalTransform = glm::scale(glm::mat4(1.0), m_HalfDimensions); + m_Edges.resize(m_Hull->GetNumEdges()); } HullCollisionShape::~HullCollisionShape() @@ -21,21 +28,24 @@ namespace Lumos void HullCollisionShape::BuildFromMesh(Graphics::Mesh* mesh) { m_Hull = CreateSharedPtr(); + const auto& vertices = mesh->GetVertices(); + const auto& indices = mesh->GetIndices(); - auto vertexBuffer = mesh->GetVertexBuffer(); + + /* auto vertexBuffer = mesh->GetVertexBuffer(); Graphics::Vertex* vertices = vertexBuffer->GetPointer(); uint32_t size = vertexBuffer->GetSize(); uint32_t count = size / sizeof(Graphics::Vertex); uint32_t* indices = mesh->GetIndexBuffer()->GetPointer(); - uint32_t indexCount = mesh->GetIndexBuffer()->GetCount(); + uint32_t indexCount = mesh->GetIndexBuffer()->GetCount();*/ - for(size_t i = 0; i < count; i++) + for(size_t i = 0; i < vertices.size(); i++) { m_Hull->AddVertex(vertices[i].Position); } - for(size_t i = 0; i < indexCount; i += 3) + for(size_t i = 0; i < indices.size(); i += 3) { glm::vec3 n1 = vertices[indices[i]].Normal; glm::vec3 n2 = vertices[indices[i + 1]].Normal; @@ -48,9 +58,6 @@ namespace Lumos } m_Edges.resize(m_Hull->GetNumEdges()); - - vertexBuffer->ReleasePointer(); - mesh->GetIndexBuffer()->ReleasePointer(); } // glm::mat3 HullCollisionShape::GetLocalInertiaTensor(float mass) @@ -120,6 +127,16 @@ namespace Lumos int vMin, vMax; + if (!m_Hull) + { + if (out_min) + *out_min = glm::vec3(0.0f); + if (out_max) + *out_max = glm::vec3(0.0f); + + return; + } + m_Hull->GetMinMaxVerticesInAxis(local_axis, &vMin, &vMax); if(out_min) @@ -208,6 +225,8 @@ namespace Lumos void HullCollisionShape::DebugDraw(const RigidBody3D* currentObject) const { + if (!m_Hull) + return; glm::mat4 transform = currentObject->GetWorldSpaceTransform() * m_LocalTransform; m_Hull->DebugDraw(transform); } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Constraints/DistanceConstraint.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Constraints/DistanceConstraint.cpp index b8bf6a43..06f8cb2b 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Constraints/DistanceConstraint.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Constraints/DistanceConstraint.cpp @@ -3,7 +3,7 @@ #include "Physics/LumosPhysicsEngine/LumosPhysicsEngine.h" #include "DistanceConstraint.h" #include "Graphics/Renderers/DebugRenderer.h" -#include + namespace Lumos { @@ -62,8 +62,8 @@ namespace Lumos glm::vec3 globalOnA = glm::toMat3(m_pObj1->GetOrientation()) * m_LocalOnA + m_pObj1->GetPosition(); glm::vec3 globalOnB = glm::toMat3(m_pObj2->GetOrientation()) * m_LocalOnB + m_pObj2->GetPosition(); - DebugRenderer::DrawThickLine(globalOnA, globalOnB, 0.02f, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); - DebugRenderer::DrawPointNDT(globalOnA, 0.05f, glm::vec4(1.0f, 0.8f, 1.0f, 1.0f)); - DebugRenderer::DrawPointNDT(globalOnB, 0.05f, glm::vec4(1.0f, 0.8f, 1.0f, 1.0f)); + DebugRenderer::DrawThickLine(globalOnA, globalOnB, 0.02f, false, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + DebugRenderer::DrawPoint(globalOnA, 0.05f, false, glm::vec4(1.0f, 0.8f, 1.0f, 1.0f)); + DebugRenderer::DrawPoint(globalOnB, 0.05f, false, glm::vec4(1.0f, 0.8f, 1.0f, 1.0f)); } } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Constraints/WeldConstraint.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Constraints/WeldConstraint.cpp index df67546a..6add8614 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Constraints/WeldConstraint.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Constraints/WeldConstraint.cpp @@ -34,8 +34,8 @@ namespace Lumos glm::vec3 posA = m_pObj1->GetPosition(); glm::vec3 posB = m_pObj2->GetPosition(); - DebugRenderer::DrawThickLine(posA, posB, 0.02f, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); - DebugRenderer::DrawPointNDT(posA, 0.05f, glm::vec4(1.0f, 0.8f, 1.0f, 1.0f)); - DebugRenderer::DrawPointNDT(posB, 0.05f, glm::vec4(1.0f, 0.8f, 1.0f, 1.0f)); + DebugRenderer::DrawThickLine(posA, posB, 0.02f, false, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + DebugRenderer::DrawPoint(posA, 0.05f, false, glm::vec4(1.0f, 0.8f, 1.0f, 1.0f)); + DebugRenderer::DrawPoint(posB, 0.05f, false, glm::vec4(1.0f, 0.8f, 1.0f, 1.0f)); } } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.cpp index 2bd9bb28..65fa33f6 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.cpp @@ -11,6 +11,7 @@ #include "Core/JobSystem.h" #include "Core/Application.h" #include "Scene/Component/RigidBody3DComponent.h" +#include "Graphics/Renderers/DebugRenderer.h" #include "Maths/Transform.h" #include "ImGui/ImGuiUtilities.h" @@ -32,7 +33,7 @@ namespace Lumos , m_RootBody(nullptr) { m_DebugName = "Lumos3DPhysicsEngine"; - m_BroadphaseCollisionPairs.reserve(1000); + m_BroadphaseCollisionPairs.Reserve(1000); m_Allocator = new PoolAllocator(); m_Arena = ArenaAlloc(Megabytes(1)); @@ -70,7 +71,7 @@ namespace Lumos auto viewWeld = registry.view(); m_ConstraintCount = (uint32_t)viewSpring.size() + (uint32_t)viewAxis.size() + (uint32_t)viewDis.size() + (uint32_t)viewWeld.size(); - m_Constraints = PushArrayNoZero(m_Arena, Constraint*, m_ConstraintCount); + m_Constraints = PushArray(m_Arena, SharedPtr, m_ConstraintCount); uint32_t constraintIndex = 0; for(auto entity : viewSpring) @@ -85,7 +86,7 @@ namespace Lumos if(constraint.GetEntityID() != Entity(entity, Application::Get().GetCurrentScene()).GetID()) constraint.SetEntity(Entity(entity, Application::Get().GetCurrentScene()).GetID()); if(constraint.GetConstraint()) - m_Constraints[constraintIndex++] = constraint.GetConstraint().get(); + m_Constraints[constraintIndex++] = constraint.GetConstraint(); } for(auto entity : viewDis) @@ -135,7 +136,8 @@ namespace Lumos SolveConstraints(); // Update movement - UpdateRigidBodys(); + for(int i = 0; i < m_PositionIterations; i++) + UpdateRigidBodys(); RigidBody3D* current = m_RootBody; while(current) @@ -246,6 +248,8 @@ namespace Lumos { LUMOS_PROFILE_FUNCTION_LOW(); + s_UpdateTimestep /= m_PositionIterations; + if(!obj->GetIsStatic() && obj->IsAwake()) { const float damping = m_DampingFactor; @@ -363,8 +367,8 @@ namespace Lumos } // Mark cached world transform and AABB as invalid - obj->m_wsTransformInvalidated = true; - obj->m_wsAabbInvalidated = true; + obj->m_WSTransformInvalidated = true; + obj->m_WSAabbInvalidated = true; } s_UpdateTimestep *= m_PositionIterations; @@ -383,7 +387,7 @@ namespace Lumos void LumosPhysicsEngine::BroadPhaseCollisions() { LUMOS_PROFILE_FUNCTION(); - m_BroadphaseCollisionPairs.clear(); + m_BroadphaseCollisionPairs.Clear(); if(m_BroadphaseDetection) m_BroadphaseDetection->FindPotentialCollisionPairs(m_RootBody, m_BroadphaseCollisionPairs); @@ -414,10 +418,10 @@ namespace Lumos void LumosPhysicsEngine::NarrowPhaseCollisions() { LUMOS_PROFILE_FUNCTION(); - if(m_BroadphaseCollisionPairs.empty()) + if(m_BroadphaseCollisionPairs.Empty()) return; - m_Stats.NarrowPhaseCount = (uint32_t)m_BroadphaseCollisionPairs.size(); + m_Stats.NarrowPhaseCount = (uint32_t)m_BroadphaseCollisionPairs.Size(); m_Stats.CollisionCount = 0; for(auto& cp : m_BroadphaseCollisionPairs) @@ -448,6 +452,12 @@ namespace Lumos // Construct contact points that form the perimeter of the collision manifold if(CollisionDetection::Get().BuildCollisionManifold(cp.pObjectA, cp.pObjectB, shapeA.get(), shapeB.get(), colData, &manifold)) { + if(m_DebugDrawFlags & PhysicsDebugFlags::COLLISIONNORMALS) + { + DebugRenderer::DrawPoint(colData.pointOnPlane, 0.1f, false, glm::vec4(0.5f, 0.5f, 1.0f, 1.0f), 3.0f); + DebugRenderer::DrawThickLine(colData.pointOnPlane, colData.pointOnPlane - colData.normal * colData.penetration, 0.05f, false, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f), 3.0f); + } + // Fire callback cp.pObjectA->FireOnCollisionManifoldCallback(cp.pObjectA, cp.pObjectB, &manifold); cp.pObjectB->FireOnCollisionManifoldCallback(cp.pObjectB, cp.pObjectA, &manifold); diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.h b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.h index d2c199d8..0a8bc668 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.h +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.h @@ -89,7 +89,7 @@ namespace Lumos SharedPtr GetBroadphase() const { return m_BroadphaseDetection; } inline void SetBroadphase(const SharedPtr& bp) { m_BroadphaseDetection = bp; } - int GetNumberCollisionPairs() const { return static_cast(m_BroadphaseCollisionPairs.size()); } + int GetNumberCollisionPairs() const { return static_cast(m_BroadphaseCollisionPairs.Size()); } int GetNumberRigidBodys() const { return static_cast(m_Stats.RigidBodyCount); } IntegrationType GetIntegrationType() const { return m_IntegrationType; } void SetIntegrationType(const IntegrationType& type) { m_IntegrationType = type; } @@ -143,13 +143,12 @@ namespace Lumos glm::vec3 m_Gravity; float m_DampingFactor; uint32_t m_MaxUpdatesPerFrame = 5; - uint32_t m_PositionIterations = 1; - uint32_t m_VelocityIterations = 50; + uint32_t m_PositionIterations = 2; + uint32_t m_VelocityIterations = 10; - // Replace with CollisionPair* - std::vector m_BroadphaseCollisionPairs; - Constraint** m_Constraints; // Misc constraints between pairs of objects - Manifold* m_Manifolds; // Contact constraints between pairs of objects + Vector m_BroadphaseCollisionPairs; + SharedPtr* m_Constraints; // Misc constraints between pairs of objects + Manifold* m_Manifolds; // Contact constraints between pairs of objects std::mutex m_ManifoldsMutex; uint32_t m_ManifoldCount = 0; diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/CollisionDetection.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/CollisionDetection.cpp index 1c224100..c5c3490f 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/CollisionDetection.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/CollisionDetection.cpp @@ -664,9 +664,9 @@ namespace Lumos float capsuleTop = capsulePos.y + capsuleHeight * 0.5f; float capsuleBottom = capsulePos.y - capsuleHeight * 0.5f; - for(int i = 0; i < shapeCollisionAxes.size(); i++) + for(int i = 0; i < possibleCollisionAxesCount; i++) { - const glm::vec3& axis = shapeCollisionAxes[i]; + const glm::vec3& axis = possibleCollisionAxes[i]; if(!CheckCollisionAxis(axis, obj1, obj2, shape1, shape2, &cur_colData)) return false; diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/Manifold.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/Manifold.cpp index 1dc5344e..7b992ce6 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/Manifold.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/Manifold.cpp @@ -245,11 +245,11 @@ namespace Lumos glm::vec3 globalOnB = m_pNodeB->GetPosition() + contact.relPosB; // Draw line to form area given by all contact points - DebugRenderer::DrawThickLineNDT(globalOnA1, globalOnA2, 0.02f, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); + DebugRenderer::DrawThickLine(globalOnA1, globalOnA2, 0.02f, false, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f), 3.0f); // Draw descriptors for indivdual contact point - DebugRenderer::DrawPointNDT(globalOnA2, 0.05f, glm::vec4(0.0f, 0.5f, 0.0f, 1.0f)); - DebugRenderer::DrawThickLineNDT(globalOnB, globalOnA2, 0.01f, glm::vec4(1.0f, 0.0f, 1.0f, 1.0f)); + DebugRenderer::DrawPoint(globalOnA2, 0.05f, false, glm::vec4(0.0f, 0.5f, 0.0f, 1.0f), 3.0f); + DebugRenderer::DrawThickLine(globalOnB, globalOnA2, 0.01f, false, glm::vec4(1.0f, 0.0f, 1.0f, 1.0f), 3.0f); globalOnA1 = globalOnA2; } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/RigidBody3D.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/RigidBody3D.cpp index 3a2be8af..99546bf8 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/RigidBody3D.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/RigidBody3D.cpp @@ -13,10 +13,10 @@ namespace Lumos { RigidBody3D::RigidBody3D(const RigidBody3DProperties& properties) - : m_wsTransformInvalidated(true) + : m_WSTransformInvalidated(true) , m_RestVelocityThresholdSquared(0.004f) , m_AverageSummedVelocity(0.0f) - , m_wsAabbInvalidated(true) + , m_WSAabbInvalidated(true) , m_Position(properties.Position) , m_LinearVelocity(properties.LinearVelocity) , m_Force(properties.Force) @@ -26,12 +26,12 @@ namespace Lumos , m_InvInertia(glm::mat3(1.0f)) , m_OnCollisionCallback(nullptr) , m_AngularFactor(1.0f) - , m_wsTransform(glm::mat4(1.0f)) + , m_WSTransform(glm::mat4(1.0f)) { LUMOS_ASSERT(properties.Mass > 0.0f, "Mass <= 0"); m_InvMass = 1.0f / properties.Mass; - m_localBoundingBox.Set(glm::vec3(-0.5f), glm::vec3(0.5f)); + m_LocalBoundingBox.Set(glm::vec3(-0.5f), glm::vec3(0.5f)); if(properties.Shape) SetCollisionShape(properties.Shape); @@ -51,14 +51,14 @@ namespace Lumos const Maths::BoundingBox& RigidBody3D::GetWorldSpaceAABB() { LUMOS_PROFILE_FUNCTION_LOW(); - if(m_wsAabbInvalidated) + if(m_WSAabbInvalidated) { LUMOS_PROFILE_SCOPE_LOW("Calculate BoundingBox"); - m_wsAabb = m_localBoundingBox.Transformed(GetWorldSpaceTransform()); - m_wsAabbInvalidated = false; + m_WSAabb = m_LocalBoundingBox.Transformed(GetWorldSpaceTransform()); + m_WSAabbInvalidated = false; } - return m_wsAabb; + return m_WSAabb; } void RigidBody3D::WakeUp() @@ -74,20 +74,20 @@ namespace Lumos const glm::mat4& RigidBody3D::GetWorldSpaceTransform() const { LUMOS_PROFILE_FUNCTION_LOW(); - if(m_wsTransformInvalidated) + if(m_WSTransformInvalidated) { - m_wsTransform = glm::translate(glm::mat4(1.0), m_Position) * glm::toMat4(m_Orientation); + m_WSTransform = glm::translate(glm::mat4(1.0), m_Position) * glm::toMat4(m_Orientation); - m_wsTransformInvalidated = false; + m_WSTransformInvalidated = false; } - return m_wsTransform; + return m_WSTransform; } void RigidBody3D::AutoResizeBoundingBox() { LUMOS_PROFILE_FUNCTION_LOW(); - m_localBoundingBox.Clear(); + m_LocalBoundingBox.Clear(); const glm::vec3 xAxis(1.0f, 0.0f, 0.0f); const glm::vec3 yAxis(0.0f, 1.0f, 0.0f); @@ -98,19 +98,19 @@ namespace Lumos if(m_CollisionShape) { m_CollisionShape->GetMinMaxVertexOnAxis(nullptr, xAxis, &lower, &upper); - m_localBoundingBox.Merge(lower); - m_localBoundingBox.Merge(upper); + m_LocalBoundingBox.Merge(lower); + m_LocalBoundingBox.Merge(upper); m_CollisionShape->GetMinMaxVertexOnAxis(nullptr, yAxis, &lower, &upper); - m_localBoundingBox.Merge(lower); - m_localBoundingBox.Merge(upper); + m_LocalBoundingBox.Merge(lower); + m_LocalBoundingBox.Merge(upper); m_CollisionShape->GetMinMaxVertexOnAxis(nullptr, zAxis, &lower, &upper); - m_localBoundingBox.Merge(lower); - m_localBoundingBox.Merge(upper); + m_LocalBoundingBox.Merge(lower); + m_LocalBoundingBox.Merge(upper); } - m_wsAabbInvalidated = true; + m_WSAabbInvalidated = true; } void RigidBody3D::RestTest() @@ -142,15 +142,15 @@ namespace Lumos colour = glm::vec4(0.0f, 1.0f, 0.0f, 1.0f); // AABB - Maths::BoundingBox box = m_wsAabb; + Maths::BoundingBox box = m_WSAabb; DebugRenderer::DebugDraw(box, colour, false); } if(flags & PhysicsDebugFlags::LINEARVELOCITY) - DebugRenderer::DrawThickLineNDT(m_wsTransform[3], m_wsTransform * glm::vec4(m_LinearVelocity, 1.0f), 0.02f, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); + DebugRenderer::DrawThickLine(m_WSTransform[3], m_WSTransform * glm::vec4(m_LinearVelocity, 1.0f), 0.02f, false, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); if(flags & PhysicsDebugFlags::LINEARFORCE) - DebugRenderer::DrawThickLineNDT(m_wsTransform[3], m_wsTransform * glm::vec4(m_Force, 1.0f), 0.02f, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); + DebugRenderer::DrawThickLine(m_WSTransform[3], m_WSTransform * glm::vec4(m_Force, 1.0f), 0.02f, false, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); } void RigidBody3D::SetCollisionShape(CollisionShapeType type) @@ -170,6 +170,9 @@ namespace Lumos case CollisionShapeType::CollisionCapsule: SetCollisionShape(CreateSharedPtr()); break; + case CollisionShapeType::CollisionHull: + SetCollisionShape(CreateSharedPtr()); + break; default: LUMOS_LOG_ERROR("Unsupported Collision shape"); break; diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/RigidBody3D.h b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/RigidBody3D.h index 2dd9c733..d74a9dd7 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/RigidBody3D.h +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/RigidBody3D.h @@ -66,7 +66,7 @@ namespace Lumos Maths::BoundingBox GetLocalBoundingBox() const { - return m_localBoundingBox; + return m_LocalBoundingBox; } void SetRestVelocityThreshold(float vel) @@ -79,8 +79,8 @@ namespace Lumos void SetLocalBoundingBox(const Maths::BoundingBox& bb) { - m_localBoundingBox = bb; - m_wsAabbInvalidated = true; + m_LocalBoundingBox = bb; + m_WSAabbInvalidated = true; } //<--------- SETTERS -------------> @@ -88,8 +88,8 @@ namespace Lumos void SetPosition(const glm::vec3& v) { m_Position = v; - m_wsTransformInvalidated = true; - m_wsAabbInvalidated = true; + m_WSTransformInvalidated = true; + m_WSAabbInvalidated = true; // m_AtRest = false; } @@ -111,7 +111,7 @@ namespace Lumos void SetOrientation(const glm::quat& v) { m_Orientation = v; - m_wsTransformInvalidated = true; + m_WSTransformInvalidated = true; m_AtRest = false; } @@ -149,7 +149,7 @@ namespace Lumos void FireOnCollisionManifoldCallback(RigidBody3D* a, RigidBody3D* b, Manifold* manifold) { - for(auto it = m_onCollisionManifoldCallbacks.begin(); it != m_onCollisionManifoldCallbacks.end(); ++it) + for(auto it = m_OnCollisionManifoldCallbacks.begin(); it != m_OnCollisionManifoldCallbacks.end(); ++it) it->operator()(a, b, manifold); } @@ -160,7 +160,7 @@ namespace Lumos typedef std::function OnCollisionManifoldCallback; - void AddOnCollisionManifoldCallback(const OnCollisionManifoldCallback callback) { m_onCollisionManifoldCallbacks.push_back(callback); } + void AddOnCollisionManifoldCallback(const OnCollisionManifoldCallback callback) { m_OnCollisionManifoldCallbacks.push_back(callback); } void SetCollisionShape(const SharedPtr& shape) { @@ -243,7 +243,7 @@ namespace Lumos void SetElasticity(const float elasticity) { m_Elasticity = elasticity; } void SetFriction(const float friction) { m_Friction = friction; } void SetIsStatic(const bool isStatic) { m_Static = isStatic; } - + // void SetIsColliding(const bool colliding) { m_IsColliding = colliding; } UUID GetUUID() const { return m_UUID; } // For iteration @@ -255,20 +255,21 @@ namespace Lumos protected: RigidBody3D(const RigidBody3DProperties& properties = RigidBody3DProperties()); - mutable bool m_wsTransformInvalidated; + mutable bool m_WSTransformInvalidated; float m_RestVelocityThresholdSquared; float m_AverageSummedVelocity; - mutable glm::mat4 m_wsTransform; - Maths::BoundingBox m_localBoundingBox; //!< Model orientated bounding box in model space - mutable bool m_wsAabbInvalidated; //!< Flag indicating if the cached world space transoformed AABB is invalid - mutable Maths::BoundingBox m_wsAabb; //!< Axis aligned bounding box of this object in world space + mutable glm::mat4 m_WSTransform; + Maths::BoundingBox m_LocalBoundingBox; //!< Model orientated bounding box in model space + mutable bool m_WSAabbInvalidated; //!< Flag indicating if the cached world space transoformed AABB is invalid + mutable Maths::BoundingBox m_WSAabb; //!< Axis aligned bounding box of this object in world space bool m_Static; float m_Elasticity; float m_Friction; bool m_AtRest; UUID m_UUID; + // bool m_IsColliding; //<---------LINEAR--------------> glm::vec3 m_Position; @@ -287,6 +288,6 @@ namespace Lumos //<----------COLLISION------------> SharedPtr m_CollisionShape; PhysicsCollisionCallback m_OnCollisionCallback; - std::vector m_onCollisionManifoldCallbacks; //!< Collision callbacks post manifold generation + std::vector m_OnCollisionManifoldCallbacks; //!< Collision callbacks post manifold generation }; } diff --git a/Lumos/Source/Lumos/Platform/OpenAL/ALManager.cpp b/Lumos/Source/Lumos/Platform/OpenAL/ALManager.cpp index baa07e3a..00e10f71 100644 --- a/Lumos/Source/Lumos/Platform/OpenAL/ALManager.cpp +++ b/Lumos/Source/Lumos/Platform/OpenAL/ALManager.cpp @@ -9,6 +9,7 @@ #include "Maths/Transform.h" #include +#include namespace Lumos { @@ -117,7 +118,7 @@ namespace Lumos ImGui::TextUnformatted("Number Of Audio Sources"); ImGui::NextColumn(); ImGui::PushItemWidth(-1); - ImGui::Text("%5.2lu", m_SoundNodes.size()); + ImGui::Text("%5.2lu", m_SoundNodes.Size()); ImGui::PopItemWidth(); ImGui::NextColumn(); diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLDescriptorSet.cpp b/Lumos/Source/Lumos/Platform/OpenGL/GLDescriptorSet.cpp index 48a2a107..54cdfac2 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLDescriptorSet.cpp +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLDescriptorSet.cpp @@ -155,7 +155,7 @@ namespace Lumos LUMOS_LOG_WARN("Uniform not found {0}.{1}", bufferName); } - Graphics::UniformBuffer* GLDescriptorSet::GetUnifromBuffer(const std::string& name) + Graphics::UniformBuffer* GLDescriptorSet::GetUniformBuffer(const std::string& name) { LUMOS_PROFILE_FUNCTION(); for(auto& descriptor : m_Descriptors) diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLDescriptorSet.h b/Lumos/Source/Lumos/Platform/OpenGL/GLDescriptorSet.h index ef8b9990..7984d2ea 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLDescriptorSet.h +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLDescriptorSet.h @@ -24,7 +24,7 @@ namespace Lumos void SetUniform(const std::string& bufferName, const std::string& uniformName, void* data, uint32_t size) override; void SetUniformBufferData(const std::string& bufferName, void* data) override; - Graphics::UniformBuffer* GetUnifromBuffer(const std::string& name) override; + Graphics::UniformBuffer* GetUniformBuffer(const std::string& name) override; void Bind(uint32_t offset = 0); void SetDynamicOffset(uint32_t offset) override { m_DynamicOffset = offset; } @@ -44,7 +44,7 @@ namespace Lumos struct UniformBufferInfo { SharedPtr UB; - std::vector m_Members; + Vector m_Members; Buffer LocalStorage; bool HasUpdated; }; diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLPipeline.cpp b/Lumos/Source/Lumos/Platform/OpenGL/GLPipeline.cpp index fc5c96e6..3d3df8e6 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLPipeline.cpp +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLPipeline.cpp @@ -225,7 +225,7 @@ namespace Lumos framebuffer = m_Framebuffers[0]; } - m_RenderPass->BeginRenderpass(commandBuffer, m_Description.clearColour, framebuffer, Graphics::INLINE, GetWidth(), GetHeight()); + m_RenderPass->BeginRenderPass(commandBuffer, m_Description.clearColour, framebuffer, Graphics::INLINE, GetWidth(), GetHeight()); m_Shader->Bind(); @@ -287,7 +287,7 @@ namespace Lumos void GLPipeline::End(Graphics::CommandBuffer* commandBuffer) { - m_RenderPass->EndRenderpass(commandBuffer); + m_RenderPass->EndRenderPass(commandBuffer); if(m_LineWidth != 1.0f) glLineWidth(1.0f); diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLRenderPass.cpp b/Lumos/Source/Lumos/Platform/OpenGL/GLRenderPass.cpp index c8d272fb..bf5baa2d 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLRenderPass.cpp +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLRenderPass.cpp @@ -25,7 +25,7 @@ namespace Lumos return false; } - void GLRenderPass::BeginRenderpass(CommandBuffer* commandBuffer, float* clearColour, + void GLRenderPass::BeginRenderPass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const { if(frame != nullptr) @@ -45,7 +45,7 @@ namespace Lumos GLRenderer::ClearInternal(RENDERER_BUFFER_COLOUR | RENDERER_BUFFER_DEPTH | RENDERER_BUFFER_STENCIL); } - void GLRenderPass::EndRenderpass(CommandBuffer* commandBuffer) + void GLRenderPass::EndRenderPass(CommandBuffer* commandBuffer) { GLCall(glBindFramebuffer(GL_FRAMEBUFFER, 0)); } diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLRenderPass.h b/Lumos/Source/Lumos/Platform/OpenGL/GLRenderPass.h index 594792e1..606d9815 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLRenderPass.h +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLRenderPass.h @@ -13,8 +13,8 @@ namespace Lumos ~GLRenderPass(); bool Init(const RenderPassDesc& renderPassDesc); - void BeginRenderpass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const override; - void EndRenderpass(CommandBuffer* commandBuffer) override; + void BeginRenderPass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const override; + void EndRenderPass(CommandBuffer* commandBuffer) override; int GetAttachmentCount() const override { return m_ClearCount; }; static void MakeDefault(); diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLShader.cpp b/Lumos/Source/Lumos/Platform/OpenGL/GLShader.cpp index 27508dfe..c3c0d067 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLShader.cpp +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLShader.cpp @@ -858,7 +858,7 @@ namespace Lumos std::string uniformName = uniform_buffer.name + "." + memberName; - auto& member = descriptor.m_Members.emplace_back(); + auto& member = descriptor.m_Members.EmplaceBack(); member.size = (uint32_t)size; member.offset = offset; member.type = SPIRVTypeToLumosDataType(type); @@ -918,7 +918,7 @@ namespace Lumos std::string uniformName = u.name + "." + memberName; - auto& member = m_PushConstants.back().m_Members.emplace_back(); + auto& member = m_PushConstants.back().m_Members.EmplaceBack(); member.size = (uint32_t)size; member.offset = offset; member.type = SPIRVTypeToLumosDataType(type); diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLTexture.cpp b/Lumos/Source/Lumos/Platform/OpenGL/GLTexture.cpp index b50957c5..fef0bef6 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLTexture.cpp +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLTexture.cpp @@ -442,7 +442,7 @@ namespace Lumos glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); } - GLTextureDepth::GLTextureDepth(uint32_t width, uint32_t height, RHIFormat format) + GLTextureDepth::GLTextureDepth(uint32_t width, uint32_t height, RHIFormat format, uint8_t samples) : m_Width(width) , m_Height(height) { @@ -602,9 +602,9 @@ namespace Lumos return new GLTextureCube(files, mips, params, loadOptions); } - TextureDepth* GLTextureDepth::CreateFuncGL(uint32_t width, uint32_t height, RHIFormat format) + TextureDepth* GLTextureDepth::CreateFuncGL(uint32_t width, uint32_t height, RHIFormat format, uint8_t samples) { - return new GLTextureDepth(width, height, format); + return new GLTextureDepth(width, height, format, samples); } TextureDepthArray* GLTextureDepthArray::CreateFuncGL(uint32_t width, uint32_t height, uint32_t count, RHIFormat format) diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLTexture.h b/Lumos/Source/Lumos/Platform/OpenGL/GLTexture.h index b5f9eb33..35afda39 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLTexture.h +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLTexture.h @@ -170,7 +170,7 @@ namespace Lumos class GLTextureDepth : public TextureDepth { public: - GLTextureDepth(uint32_t width, uint32_t height, RHIFormat format); + GLTextureDepth(uint32_t width, uint32_t height, RHIFormat format, uint8_t samples); ~GLTextureDepth(); void Bind(uint32_t slot = 0) const override; @@ -214,7 +214,7 @@ namespace Lumos static void MakeDefault(); protected: - static TextureDepth* CreateFuncGL(uint32_t, uint32_t, RHIFormat); + static TextureDepth* CreateFuncGL(uint32_t, uint32_t, RHIFormat, uint8_t); void Init(); diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VK.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VK.cpp index 243724c1..44d9302e 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VK.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VK.cpp @@ -1,5 +1,5 @@ #include "Precompiled.h" - +#include "VK.h" #ifdef USE_VMA_ALLOCATOR #define VMA_IMPLEMENTATION #define VMA_STATIC_VULKAN_FUNCTIONS 0 diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VK.h b/Lumos/Source/Lumos/Platform/Vulkan/VK.h index ff019c80..b894c6e7 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VK.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VK.h @@ -10,3 +10,36 @@ inline PFN_vkCmdBeginDebugUtilsLabelEXT fpCmdBeginDebugUtilsLabelEXT; inline PFN_vkCmdEndDebugUtilsLabelEXT fpCmdEndDebugUtilsLabelEXT; inline PFN_vkSetDebugUtilsObjectNameEXT fpSetDebugUtilsObjectNameEXT; + +#ifdef USE_VMA_ALLOCATOR +#ifdef LUMOS_DEBUG +#define VMA_DEBUG_MARGIN 16 +#define VMA_DEBUG_DETECT_CORRUPTION 1 +#endif + +#define ENABLE_VMA_LOG 0 + +#if ENABLE_VMA_LOG +static char VMA_LOG_BUFFER[100]; +#define VMA_DEBUG_LOG(...) \ + sprintf(VMA_LOG_BUFFER, __VA_ARGS__); \ + LUMOS_LOG_INFO((const char*)VMA_LOG_BUFFER) +#endif + +#if defined(LUMOS_PLATFORM_MACOS) || defined(LUMOS_PLATFORM_IOS) +#undef VMA_VULKAN_VERSION + +// Cap version to 1.2 for apple devices +// Fixes issue with vma assuming vkGetDeviceBufferMemoryRequirements is available +#if defined(VK_VERSION_1_3) +#define VMA_VULKAN_VERSION 1002000 +#elif defined(VK_VERSION_1_2) +#define VMA_VULKAN_VERSION 1002000 +#elif defined(VK_VERSION_1_1) +#define VMA_VULKAN_VERSION 1001000 +#else +#define VMA_VULKAN_VERSION 1000000 +#endif +#endif +#include +#endif diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKBuffer.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKBuffer.cpp index e0e577ae..7e6d5a35 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKBuffer.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKBuffer.cpp @@ -5,7 +5,7 @@ #include "VKUtilities.h" #ifdef LUMOS_PLATFORM_WINDOWS -#define USE_SMALL_VMA_POOL 1 +#define USE_SMALL_VMA_POOL 0 #else #define USE_SMALL_VMA_POOL 0 #endif @@ -30,36 +30,7 @@ namespace Lumos VKBuffer::~VKBuffer() { LUMOS_PROFILE_FUNCTION(); - if(m_Buffer) - { - if(m_DeleteWithoutQueue) - { -#ifdef USE_VMA_ALLOCATOR - vmaDestroyBuffer(VKDevice::Get().GetAllocator(), m_Buffer, m_Allocation); -#else - vkDestroyBuffer(VKDevice::Device(), m_Buffer, nullptr); - vkFreeMemory(VKDevice::Device(), m_Memory, nullptr); -#endif - } - else - { - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); - - auto buffer = m_Buffer; - -#ifdef USE_VMA_ALLOCATOR - auto alloc = m_Allocation; - deletionQueue.PushFunction([buffer, alloc] - { vmaDestroyBuffer(VKDevice::Get().GetAllocator(), buffer, alloc); }); -#else - auto memory = m_Memory; - deletionQueue.PushFunction([buffer, memory] - { - vkDestroyBuffer(VKDevice::Device(), buffer, nullptr); - vkFreeMemory(VKDevice::Device(), memory, nullptr); }); -#endif - } - } + Destroy(!m_DeleteWithoutQueue); } void VKBuffer::Destroy(bool deletionQueue) @@ -67,7 +38,7 @@ namespace Lumos LUMOS_PROFILE_FUNCTION(); if(m_Buffer) { - VKContext::DeletionQueue& currentDeletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& currentDeletionQueue = VKRenderer::GetCurrentDeletionQueue(); auto buffer = m_Buffer; @@ -261,25 +232,7 @@ namespace Lumos { auto usage = m_UsageFlags; - if(m_Buffer) - { - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); - - auto buffer = m_Buffer; - -#ifdef USE_VMA_ALLOCATOR - auto alloc = m_Allocation; - deletionQueue.PushFunction([buffer, alloc] - { vmaDestroyBuffer(VKDevice::Get().GetAllocator(), buffer, alloc); }); -#else - auto memory = m_Memory; - deletionQueue.PushFunction([buffer, memory] - { - vkDestroyBuffer(VKDevice::Device(), buffer, nullptr); - vkFreeMemory(VKDevice::Device(), memory, nullptr); }); -#endif - } - + Destroy(!m_DeleteWithoutQueue); Init(usage, m_MemoryProperyFlags, size, data); } diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKBuffer.h b/Lumos/Source/Lumos/Platform/Vulkan/VKBuffer.h index a9b8bf41..f03bb790 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKBuffer.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKBuffer.h @@ -2,10 +2,6 @@ #include "VK.h" -#ifdef USE_VMA_ALLOCATOR -#include -#endif - namespace Lumos { namespace Graphics diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKCommandBuffer.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKCommandBuffer.cpp index e14ef964..91be53f8 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKCommandBuffer.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKCommandBuffer.cpp @@ -10,7 +10,7 @@ #if LUMOS_PROFILE #if LUMOS_PROFILE_GPU_TIMINGS -#include +#include #endif #endif diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKContext.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKContext.cpp index 73a31f95..976afbc8 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKContext.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKContext.cpp @@ -8,6 +8,8 @@ #include "Core/Version.h" #include "Utilities/StringUtilities.h" #include "Maths/MathsUtilities.h" +#include "Core/CommandLine.h" +#include "Core/CoreSystem.h" #ifndef VK_API_VERSION_1_2 #error Wrong Vulkan SDK! @@ -19,6 +21,8 @@ #define VK_LAYER_LUNARG_ASSISTENT_LAYER_NAME "VK_LAYER_LUNARG_assistant_layer" #define VK_LAYER_LUNARG_VALIDATION_NAME "VK_LAYER_KHRONOS_validation" +const bool EnableValidationLayers = false; + namespace Lumos { namespace Graphics @@ -26,11 +30,11 @@ namespace Lumos VkInstance VKContext::s_VkInstance = nullptr; uint32_t VKContext::m_VKVersion = 0; - const std::vector VKContext::GetRequiredExtensions() + const std::vector VKContext::GetRequiredExtensions(bool enableValidationLayers) { std::vector extensions; - if(EnableValidationLayers) + if(enableValidationLayers) { LUMOS_LOG_INFO("Vulkan : Enabled Validation Layers"); extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); @@ -69,11 +73,11 @@ namespace Lumos return extensions; } - const std::vector VKContext::GetRequiredLayers() const + const std::vector VKContext::GetRequiredLayers(bool enableValidationLayers) const { std::vector layers; - if(EnableValidationLayers) + if(enableValidationLayers) { layers.emplace_back(VK_LAYER_LUNARG_VALIDATION_NAME); } @@ -126,9 +130,7 @@ namespace Lumos { LUMOS_PROFILE_FUNCTION(); CreateInstance(); - VKDevice::Get().Init(); - - SetupDebugCallback(); + }; void VKContext::Present() @@ -279,9 +281,15 @@ namespace Lumos LUMOS_ASSERT(false, "Could not find loader"); } #endif + bool enableValidation = EnableValidationLayers; + CommandLine* cmdline = Internal::CoreSystem::GetCmdLine(); + if (cmdline->OptionBool(Str8Lit("EnableVulkanValidation"))) + { + enableValidation = true; + } - m_InstanceLayerNames = GetRequiredLayers(); - m_InstanceExtensionNames = GetRequiredExtensions(); + m_InstanceLayerNames = GetRequiredLayers(enableValidation); + m_InstanceExtensionNames = GetRequiredExtensions(enableValidation); if(!CheckValidationLayerSupport(m_InstanceLayerNames)) { @@ -365,13 +373,16 @@ namespace Lumos volkLoadInstance(s_VkInstance); #endif VKUtilities::Init(); + + VKDevice::Get().Init(); + + if(enableValidation) + SetupDebugCallback(); } void VKContext::SetupDebugCallback() { LUMOS_PROFILE_FUNCTION(); - if(!EnableValidationLayers) - return; VkDebugReportCallbackCreateInfoEXT createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKContext.h b/Lumos/Source/Lumos/Platform/Vulkan/VKContext.h index 4bc81a36..d1fc5b1b 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKContext.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKContext.h @@ -5,14 +5,6 @@ #include "VK.h" #include "VKDevice.h" -#include - -#if defined(LUMOS_DEBUG) -const bool EnableValidationLayers = true; -#else -const bool EnableValidationLayers = false; -#endif - namespace Lumos { namespace Graphics @@ -52,29 +44,6 @@ namespace Lumos const std::vector& GetExtensionNames() const { return m_InstanceExtensionNames; } static void MakeDefault(); - - struct DeletionQueue - { - std::deque> m_Deletors; - - template - void PushFunction(F&& function) - { - LUMOS_ASSERT(sizeof(F) < 200, "Lambda too large"); - m_Deletors.push_back(function); - } - - void Flush() - { - for(auto it = m_Deletors.rbegin(); it != m_Deletors.rend(); it++) - { - (*it)(); - } - - m_Deletors.clear(); - } - }; - static uint32_t GetVKVersion() { return m_VKVersion; } protected: @@ -85,8 +54,8 @@ namespace Lumos bool CheckValidationLayerSupport(std::vector& validationLayers); bool CheckExtensionSupport(std::vector& extensions); - static const std::vector GetRequiredExtensions(); - const std::vector GetRequiredLayers() const; + static const std::vector GetRequiredExtensions(bool enableValidationLayers); + const std::vector GetRequiredLayers(bool enableValidationLayers) const; private: static VkInstance s_VkInstance; diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKDescriptorSet.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKDescriptorSet.cpp index 3d445e0b..beb3baa7 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKDescriptorSet.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKDescriptorSet.cpp @@ -71,7 +71,7 @@ namespace Lumos std::map>& buffers = m_UniformBuffers[frame]; buffers.clear(); - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); deletionQueue.PushFunction([descriptorSet, pool, device] { vkFreeDescriptorSets(device, pool, 1, &descriptorSet); });*/ } @@ -327,7 +327,22 @@ namespace Lumos #endif } - Graphics::UniformBuffer* VKDescriptorSet::GetUnifromBuffer(const std::string& name) + Buffer* VKDescriptorSet::GetUniformBufferLocalData(const std::string& name) + { + std::map::iterator itr = m_UniformBuffersData.find(name); + if(itr != m_UniformBuffersData.end()) + { + itr->second.HasUpdated[0] = true; + itr->second.HasUpdated[1] = true; + itr->second.HasUpdated[2] = true; + + return &itr->second.LocalStorage; + } + + return nullptr; + } + + Graphics::UniformBuffer* VKDescriptorSet::GetUniformBuffer(const std::string& name) { LUMOS_PROFILE_FUNCTION(); uint32_t currentFrame = Renderer::GetMainSwapChain()->GetCurrentBufferIndex(); diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKDescriptorSet.h b/Lumos/Source/Lumos/Platform/Vulkan/VKDescriptorSet.h index c6626e01..5eb9eb4b 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKDescriptorSet.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKDescriptorSet.h @@ -29,7 +29,8 @@ namespace Lumos void SetUniformBufferData(const std::string& bufferName, void* data) override; void TransitionImages(CommandBuffer* commandBuffer) override; - Graphics::UniformBuffer* GetUnifromBuffer(const std::string& name) override; + Buffer* GetUniformBufferLocalData(const std::string& name) override; + Graphics::UniformBuffer* GetUniformBuffer(const std::string& name) override; bool GetIsDynamic() const { return m_Dynamic; } void SetDynamicOffset(uint32_t offset) override { m_DynamicOffset = offset; } @@ -53,11 +54,11 @@ namespace Lumos struct UniformBufferInfo { - std::vector m_Members; + Vector m_Members; Buffer LocalStorage; // Per frame in flight - bool HasUpdated[10]; + bool HasUpdated[MAX_FRAMES_FLIGHT]; }; DescriptorSetInfo m_Descriptors; diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKDevice.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKDevice.cpp index 27476c1b..32f90940 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKDevice.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKDevice.cpp @@ -166,7 +166,6 @@ namespace Lumos caps.Renderer = std::string(m_PhysicalDeviceProperties.deviceName); caps.Version = StringUtilities::ToString(m_PhysicalDeviceProperties.driverVersion); caps.MaxAnisotropy = m_PhysicalDeviceProperties.limits.maxSamplerAnisotropy; - caps.MaxSamples = m_PhysicalDeviceProperties.limits.maxSamplerAllocationCount; caps.MaxTextureUnits = m_PhysicalDeviceProperties.limits.maxDescriptorSetSamplers; caps.UniformBufferOffsetAlignment = int(m_PhysicalDeviceProperties.limits.minUniformBufferOffsetAlignment); caps.SupportCompute = false; // true; //Need to sort descriptor set management first @@ -415,6 +414,8 @@ namespace Lumos Renderer::GetCapabilities().WideLines = false; } + Renderer::GetCapabilities().MaxSamples = VKUtilities::GetMaxUsableSampleCount(); + if(supportedFeatures.samplerAnisotropy) m_EnabledFeatures.samplerAnisotropy = true; @@ -528,9 +529,13 @@ namespace Lumos fn.vkGetBufferMemoryRequirements2KHR = 0; fn.vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vkGetInstanceProcAddr; fn.vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)vkGetDeviceProcAddr; - fn.vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)vkGetDeviceBufferMemoryRequirements; - allocatorInfo.pVulkanFunctions = &fn; +#if !defined(LUMOS_PLATFORM_MACOS) && !defined(LUMOS_PLATFORM_IOS) + fn.vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)vkGetDeviceBufferMemoryRequirements; + fn.vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)vkGetDeviceImageMemoryRequirements; +#endif + allocatorInfo.pVulkanFunctions = &fn; + allocatorInfo.preferredLargeHeapBlockSize = 64 * 1024 * 1024; if(vmaCreateAllocator(&allocatorInfo, &m_Allocator) != VK_SUCCESS) { LUMOS_LOG_CRITICAL("[VULKAN] Failed to create VMA allocator"); @@ -597,7 +602,7 @@ namespace Lumos VmaPoolCreateInfo pci; pci.memoryTypeIndex = memTypeIndex; - pci.flags = 0; + pci.flags = VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT; pci.blockSize = 0; pci.minBlockCount = 0; pci.maxBlockCount = SIZE_MAX; diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKDevice.h b/Lumos/Source/Lumos/Platform/Vulkan/VKDevice.h index 23051056..9ae14c91 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKDevice.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKDevice.h @@ -6,14 +6,6 @@ #include "Graphics/RHI/Definitions.h" #include "Utilities/StringUtilities.h" -#ifdef USE_VMA_ALLOCATOR -#ifdef LUMOS_DEBUG -#define VMA_DEBUG_MARGIN 16 -#define VMA_DEBUG_DETECT_CORRUPTION 1 -#endif -#include -#endif - static const uint32_t SMALL_ALLOCATION_MAX_SIZE = 4096; #include diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKFramebuffer.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKFramebuffer.cpp index 18d62c23..7be90092 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKFramebuffer.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKFramebuffer.cpp @@ -57,7 +57,7 @@ namespace Lumos VKFramebuffer::~VKFramebuffer() { - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); auto framebuffer = m_Framebuffer; diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKIMGUIRenderer.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKIMGUIRenderer.cpp index 30db7d48..a9f8d74d 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKIMGUIRenderer.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKIMGUIRenderer.cpp @@ -55,7 +55,7 @@ namespace Lumos delete m_Renderpass; delete m_FontTexture; - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); for(int i = 0; i < Renderer::GetMainSwapChain()->GetSwapChainBufferCount(); i++) { @@ -249,14 +249,14 @@ namespace Lumos ImGui_ImplVulkan_CreateDescriptorSets(ImGui::GetDrawData(), wd->FrameIndex); float clearColour[4] = { 0.1f, 0.1f, 0.1f, 1.0f }; - m_Renderpass->BeginRenderpass(currentCommandBuffer, clearColour, m_Framebuffers[wd->FrameIndex], Graphics::SubPassContents::INLINE, wd->Width, wd->Height); + m_Renderpass->BeginRenderPass(currentCommandBuffer, clearColour, m_Framebuffers[wd->FrameIndex], Graphics::SubPassContents::INLINE, wd->Width, wd->Height); { LUMOS_PROFILE_SCOPE("ImGui Vulkan RenderDrawData"); // Record Imgui Draw Data and draw funcs into command buffer ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), currentCommandBuffer->GetHandle(), VK_NULL_HANDLE, wd->FrameIndex); } - m_Renderpass->EndRenderpass(currentCommandBuffer); + m_Renderpass->EndRenderPass(currentCommandBuffer); } void VKIMGUIRenderer::Render(Lumos::Graphics::CommandBuffer* commandBuffer) @@ -341,7 +341,10 @@ namespace Lumos int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - m_FontTexture = new VKTexture2D(width, height, pixels, TextureDesc(TextureFilter::NEAREST, TextureFilter::NEAREST, TextureWrap::REPEAT)); + auto desc = TextureDesc(TextureFilter::NEAREST, TextureFilter::NEAREST, TextureWrap::REPEAT); + desc.flags = TextureFlags::Texture_Sampled; + + m_FontTexture = new VKTexture2D(width, height, pixels, desc); m_FontTextureID.level = 0; m_FontTextureID.mip = 0; m_FontTextureID.type = TextureType::COLOUR; diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKPipeline.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKPipeline.cpp index fdaf7524..bc00db93 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKPipeline.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKPipeline.cpp @@ -23,7 +23,7 @@ namespace Lumos VKPipeline::~VKPipeline() { LUMOS_PROFILE_FUNCTION_LOW(); - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); auto pipeline = m_Pipeline; @@ -291,7 +291,7 @@ namespace Lumos framebuffer = m_Framebuffers[0]; } - m_RenderPass->BeginRenderpass(commandBuffer, m_Description.clearColour, framebuffer, Graphics::INLINE, GetWidth(), GetHeight()); + m_RenderPass->BeginRenderPass(commandBuffer, m_Description.clearColour, framebuffer, Graphics::INLINE, GetWidth(), GetHeight()); } else { @@ -352,15 +352,21 @@ namespace Lumos attachments.push_back(m_Description.cubeMapTarget); } + if (m_Description.resolveTexture) + { + attachmentTypes.push_back(TextureType::COLOUR); + attachments.push_back(m_Description.resolveTexture); + } + Graphics::RenderPassDesc renderPassDesc = {}; - renderPassDesc.attachmentCount = uint32_t(attachmentTypes.size()); + renderPassDesc.attachmentCount = uint32_t(attachmentTypes.size()) - (m_Description.resolveTexture ? 1 : 0); renderPassDesc.attachmentTypes = attachmentTypes.data(); renderPassDesc.attachments = attachments.data(); renderPassDesc.swapchainTarget = m_Description.swapchainTarget; renderPassDesc.clear = m_Description.clearTargets; renderPassDesc.cubeMapIndex = m_Description.cubeMapIndex; renderPassDesc.mipIndex = m_Description.mipIndex; - + renderPassDesc.resolveTexture = m_Description.resolveTexture; if(m_Description.DebugName != NULL) renderPassDesc.DebugName = m_Description.DebugName; renderPassDesc.samples = m_Description.samples; @@ -426,7 +432,7 @@ namespace Lumos LUMOS_PROFILE_FUNCTION(); if(!m_Compute) { - m_RenderPass->EndRenderpass(commandBuffer); + m_RenderPass->EndRenderPass(commandBuffer); } } @@ -492,6 +498,11 @@ namespace Lumos ((VKTexture2D*)texture)->TransitionImage(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, (VKCommandBuffer*)commandBuffer); } } + + if (m_Description.resolveTexture) + { + ((VKTexture2D*)m_Description.resolveTexture)->TransitionImage(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, (VKCommandBuffer*)commandBuffer); + } } void VKPipeline::MakeDefault() diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKRenderPass.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKRenderPass.cpp index d157842d..1307bd4f 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKRenderPass.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKRenderPass.cpp @@ -30,14 +30,14 @@ namespace Lumos LUMOS_PROFILE_FUNCTION_LOW(); delete[] m_ClearValue; - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); - VkRenderPass renderPass = m_RenderPass; + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + VkRenderPass renderPass = m_RenderPass; deletionQueue.PushFunction([renderPass] { vkDestroyRenderPass(VKDevice::Get().GetDevice(), renderPass, VK_NULL_HANDLE); }); } - VkAttachmentDescription GetAttachmentDescription(TextureType type, Texture* texture, bool clear = true) + VkAttachmentDescription GetAttachmentDescription(TextureType type, Texture* texture, uint8_t samples = 1, bool clear = true) { LUMOS_PROFILE_FUNCTION_LOW(); VkAttachmentDescription attachment = {}; @@ -85,7 +85,7 @@ namespace Lumos attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; } - attachment.samples = VK_SAMPLE_COUNT_1_BIT; + attachment.samples = samples > 1 ? (VkSampleCountFlagBits)samples : VK_SAMPLE_COUNT_1_BIT; attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; @@ -109,7 +109,7 @@ namespace Lumos for(uint32_t i = 0; i < renderPassDesc.attachmentCount; i++) { - attachments.push_back(GetAttachmentDescription(renderPassDesc.attachmentTypes[i], renderPassDesc.attachments[i], renderPassDesc.clear)); + attachments.push_back(GetAttachmentDescription(renderPassDesc.attachmentTypes[i], renderPassDesc.attachments[i], renderPassDesc.samples, renderPassDesc.clear)); if(renderPassDesc.attachmentTypes[i] == TextureType::COLOUR) { @@ -199,16 +199,33 @@ namespace Lumos } } + uint32_t attachmentCount = renderPassDesc.attachmentCount; + + bool resolveTexture = false; + VkAttachmentReference colourAttachmentResolvedRef = {}; + + if(renderPassDesc.resolveTexture != nullptr && renderPassDesc.samples > 1) + { + resolveTexture = true; + VkImageLayout layout = ((VKTexture2D*)renderPassDesc.resolveTexture)->GetImageLayout(); + colourAttachmentResolvedRef.attachment = uint32_t(renderPassDesc.attachmentCount); + colourAttachmentResolvedRef.layout = layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : layout; + attachmentCount++; + + attachments.push_back(GetAttachmentDescription(renderPassDesc.attachmentTypes[0], renderPassDesc.resolveTexture, 1, renderPassDesc.clear)); + } + VkSubpassDescription subpass = {}; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass.colorAttachmentCount = static_cast(colourAttachmentReferences.size()); subpass.pColorAttachments = colourAttachmentReferences.data(); subpass.pDepthStencilAttachment = depthAttachmentReferences.data(); + subpass.pResolveAttachments = resolveTexture ? &colourAttachmentResolvedRef : nullptr; m_ColourAttachmentCount = int(colourAttachmentReferences.size()); VkRenderPassCreateInfo renderPassCreateInfo = VKInitialisers::RenderPassCreateInfo(); - renderPassCreateInfo.attachmentCount = uint32_t(renderPassDesc.attachmentCount); + renderPassCreateInfo.attachmentCount = uint32_t(attachmentCount); renderPassCreateInfo.pAttachments = attachments.data(); renderPassCreateInfo.subpassCount = 1; renderPassCreateInfo.pSubpasses = &subpass; @@ -220,7 +237,7 @@ namespace Lumos if(!renderPassDesc.DebugName.empty()) VKUtilities::SetDebugUtilsObjectName(VKDevice::Get().GetDevice(), VK_OBJECT_TYPE_RENDER_PASS, renderPassDesc.DebugName.c_str(), m_RenderPass); - m_ClearValue = new VkClearValue[renderPassDesc.attachmentCount]; + m_ClearValue = new VkClearValue[attachmentCount]; m_ClearCount = renderPassDesc.attachmentCount; m_SwapchainTarget = renderPassDesc.swapchainTarget; @@ -241,7 +258,7 @@ namespace Lumos } } - void VKRenderPass::BeginRenderpass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const + void VKRenderPass::BeginRenderPass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const { LUMOS_PROFILE_FUNCTION_LOW(); if(!m_DepthOnly) @@ -284,7 +301,7 @@ namespace Lumos commandBuffer->UpdateViewport(width, height, m_SwapchainTarget); } - void VKRenderPass::EndRenderpass(CommandBuffer* commandBuffer) + void VKRenderPass::EndRenderPass(CommandBuffer* commandBuffer) { LUMOS_PROFILE_FUNCTION_LOW(); vkCmdEndRenderPass(static_cast(commandBuffer)->GetHandle()); diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKRenderPass.h b/Lumos/Source/Lumos/Platform/Vulkan/VKRenderPass.h index f70226f6..862dda85 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKRenderPass.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKRenderPass.h @@ -14,8 +14,8 @@ namespace Lumos ~VKRenderPass(); bool Init(const RenderPassDesc& renderPassDesc); - void BeginRenderpass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const override; - void EndRenderpass(CommandBuffer* commandBuffer) override; + void BeginRenderPass(CommandBuffer* commandBuffer, float* clearColour, Framebuffer* frame, SubPassContents contents, uint32_t width, uint32_t height) const override; + void EndRenderPass(CommandBuffer* commandBuffer) override; const VkRenderPass& GetHandle() const { return m_RenderPass; }; int GetAttachmentCount() const override { return m_ClearCount; }; diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKRenderer.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKRenderer.cpp index a547e33b..0b9e5579 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKRenderer.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKRenderer.cpp @@ -20,8 +20,8 @@ namespace Lumos { static VkFence s_ComputeFence = nullptr; - int VKRenderer::s_DeletionQueueIndex = 0; - std::vector VKRenderer::s_DeletionQueue = {}; + int VKRenderer::s_DeletionQueueIndex = 0; + Vector VKRenderer::s_DeletionQueue = {}; void VKRenderer::InitInternal() { @@ -30,7 +30,7 @@ namespace Lumos m_RendererTitle = "Vulkan"; // Deletion queue larger than frames in flight to delay deletion a few frames - s_DeletionQueue.resize(12); + s_DeletionQueue.Resize(12); } VKRenderer::~VKRenderer() @@ -124,7 +124,7 @@ namespace Lumos { LUMOS_PROFILE_FUNCTION_LOW(); s_DeletionQueueIndex++; - s_DeletionQueueIndex = s_DeletionQueueIndex % int(s_DeletionQueue.size()); + s_DeletionQueueIndex = s_DeletionQueueIndex % int(s_DeletionQueue.Size()); s_DeletionQueue[s_DeletionQueueIndex].Flush(); SharedPtr swapChain = Application::Get().GetWindow()->GetSwapChain().As(); @@ -402,6 +402,8 @@ file.close(); LUMOS_ASSERT(vkDesSet->GetHasUpdated(Renderer::GetMainSwapChain()->GetCurrentBufferIndex()), "Descriptor Set has not been updated before"); numDesciptorSets++; } + else + LUMOS_LOG_ERROR("Descriptor null"); } vkCmdBindDescriptorSets(static_cast(commandBuffer)->GetHandle(), static_cast(pipeline)->IsCompute() ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS, static_cast(pipeline)->GetPipelineLayout(), 0, numDesciptorSets, m_CurrentDescriptorSets, numDynamicDescriptorSets, &dynamicOffset); @@ -492,8 +494,8 @@ file.close(); auto frameBuffer = Framebuffer::Get(frameBufferDesc); // To clear screen - renderPass->BeginRenderpass(commandBuffer, clearColour, frameBuffer, SubPassContents::INLINE, width, height); - renderPass->EndRenderpass(commandBuffer); + renderPass->BeginRenderPass(commandBuffer, clearColour, frameBuffer, SubPassContents::INLINE, width, height); + renderPass->EndRenderPass(commandBuffer); float ratio = float(texture->GetWidth() / texture->GetHeight()); VkImageBlit blit {}; @@ -583,7 +585,7 @@ file.close(); if(m_FreeDescriptorPools.Size() > 0) { VkDescriptorPool pool = m_FreeDescriptorPools.Back(); - m_FreeDescriptorPools.Pop(); + m_FreeDescriptorPools.PopBack(); return pool; } else @@ -597,7 +599,7 @@ file.close(); if(m_CurrentPool == VK_NULL_HANDLE) { m_CurrentPool = GetPool(); - m_UsedDescriptorPools.Emplace(m_CurrentPool); + m_UsedDescriptorPools.PushBack(m_CurrentPool); } VkDescriptorSetAllocateInfo allocInfo = {}; @@ -631,7 +633,7 @@ file.close(); { // allocate a new pool and retry m_CurrentPool = GetPool(); - m_UsedDescriptorPools.Emplace(m_CurrentPool); + m_UsedDescriptorPools.PushBack(m_CurrentPool); allocInfo.descriptorPool = m_CurrentPool; allocResult = vkAllocateDescriptorSets(VKDevice::Get().GetDevice(), &allocInfo, set); diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKRenderer.h b/Lumos/Source/Lumos/Platform/Vulkan/VKRenderer.h index 1457d274..b77a0b94 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKRenderer.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKRenderer.h @@ -9,6 +9,7 @@ #include "VKDescriptorSet.h" #include "Graphics/RHI/Renderer.h" #include "Core/DataStructures/Vector.h" +#include "Utilities/DeletionQueue.h" #define NUM_SEMAPHORES 10 @@ -64,13 +65,13 @@ namespace Lumos bool AllocateDescriptorSet(VkDescriptorSet* set, VkDescriptorSetLayout layout, uint32_t descriptorCount); void ReleaseDescriptorPools(); - static VKContext::DeletionQueue& GetDeletionQueue(int frameIndex) + static DeletionQueue& GetDeletionQueue(int frameIndex) { - LUMOS_ASSERT(frameIndex < int(s_DeletionQueue.size()), "Unsupported Frame Index"); + LUMOS_ASSERT(frameIndex < int(s_DeletionQueue.Size()), "Unsupported Frame Index"); return s_DeletionQueue[frameIndex]; } - static VKContext::DeletionQueue& GetCurrentDeletionQueue() + static DeletionQueue& GetCurrentDeletionQueue() { return s_DeletionQueue[s_DeletionQueueIndex]; } @@ -109,7 +110,7 @@ namespace Lumos Vector m_UsedDescriptorPools; Vector m_FreeDescriptorPools; - static std::vector s_DeletionQueue; + static Vector s_DeletionQueue; static int s_DeletionQueueIndex; }; } diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKShader.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKShader.cpp index c8680f9f..b61a3758 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKShader.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKShader.cpp @@ -651,7 +651,7 @@ namespace Lumos std::string uniformName = u.name + "." + memberName; - auto& member = descriptor.m_Members.emplace_back(); + auto& member = descriptor.m_Members.EmplaceBack(); member.name = memberName; member.offset = offset; member.size = (uint32_t)size; @@ -694,7 +694,7 @@ namespace Lumos auto size = comp.get_declared_struct_member_size(bufferType, i); auto offset = comp.type_struct_member_offset(bufferType, i); std::string uniformName = u.name + "." + memberName; - auto& member = m_PushConstants.back().m_Members.emplace_back(); + auto& member = m_PushConstants.back().m_Members.EmplaceBack(); member.size = (uint32_t)size; member.offset = offset; member.type = SPIRVTypeToLumosDataType(type); diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKSwapChain.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKSwapChain.cpp index dd1bfbf7..2602deec 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKSwapChain.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKSwapChain.cpp @@ -247,7 +247,10 @@ namespace Lumos m_Frames[i].MainCommandBuffer = CreateSharedPtr(); m_Frames[i].MainCommandBuffer->Init(true, m_Frames[i].CommandPool->GetHandle()); - VKUtilities::SetDebugUtilsObjectName(VKDevice::Get().GetDevice(), VK_OBJECT_TYPE_COMMAND_BUFFER, "Commandbuffer (frame in flight)", m_Frames[i].MainCommandBuffer->GetHandle()); + ArenaTemp scratch = ScratchBegin(nullptr, 0); + String8 commandBufferName = PushStr8F(scratch.arena, "Commandbuffer - Frame %u", i); + VKUtilities::SetDebugUtilsObjectName(VKDevice::Get().GetDevice(), VK_OBJECT_TYPE_COMMAND_BUFFER, ToCChar(commandBufferName), m_Frames[i].MainCommandBuffer->GetHandle()); + ScratchEnd(scratch); } } } diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKTexture.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKTexture.cpp index 2e1be24a..cc5d491a 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKTexture.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKTexture.cpp @@ -6,6 +6,11 @@ #include "VKRenderer.h" #include "Maths/Random.h" #include "Maths/MathsUtilities.h" +#ifdef LUMOS_PLATFORM_WINDOWS +#define USE_SMALL_VMA_POOL 0 +#else +#define USE_SMALL_VMA_POOL 0 +#endif namespace Lumos { @@ -74,23 +79,26 @@ namespace Lumos void CreateImageVma(const VkImageCreateInfo& imageInfo, VkImage& image, VmaAllocation& allocation, uint32_t imageSize) { LUMOS_PROFILE_FUNCTION(); - VmaAllocationCreateInfo allocInfovma; - allocInfovma.flags = 0; - allocInfovma.usage = VMA_MEMORY_USAGE_AUTO; - allocInfovma.requiredFlags = 0; - allocInfovma.preferredFlags = 0; - allocInfovma.memoryTypeBits = 0; - allocInfovma.pool = nullptr; - allocInfovma.pUserData = nullptr; - + VmaAllocationCreateInfo allocInfovma = {}; + allocInfovma.flags = 0; + allocInfovma.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + allocInfovma.requiredFlags = 0; + allocInfovma.preferredFlags = 0; + allocInfovma.memoryTypeBits = 0; + allocInfovma.pool = nullptr; + allocInfovma.pUserData = nullptr; + +#if USE_SMALL_VMA_POOL if(imageSize <= SMALL_ALLOCATION_MAX_SIZE) { uint32_t mem_type_index = 0; vmaFindMemoryTypeIndexForImageInfo(Graphics::VKDevice::Get().GetAllocator(), &imageInfo, &allocInfovma, &mem_type_index); allocInfovma.pool = Graphics::VKDevice::Get().GetOrCreateSmallAllocPool(mem_type_index); } +#endif - VK_CHECK_RESULT(vmaCreateImage(Graphics::VKDevice::Get().GetAllocator(), &imageInfo, &allocInfovma, &image, &allocation, nullptr)); + VmaAllocationInfo alloc_info = {}; + VK_CHECK_RESULT(vmaCreateImage(Graphics::VKDevice::Get().GetAllocator(), &imageInfo, &allocInfovma, &image, &allocation, &alloc_info)); } #else @@ -138,7 +146,22 @@ namespace Lumos imageInfo.flags = flags; #ifdef USE_VMA_ALLOCATOR - uint32_t imageSize = SMALL_ALLOCATION_MAX_SIZE + 1; // Avoid small pool for now +#if USE_SMALL_VMA_POOL + uint32_t bytesPerPixel = VKUtilities::BytesPerPixel(format); + uint32_t imageSize = imageInfo.extent.width * imageInfo.extent.height * imageInfo.extent.depth * bytesPerPixel; + + // If mipmaps are used, calculate the size for each level and sum them up + for(uint32_t mipLevel = 1; mipLevel < imageInfo.mipLevels; ++mipLevel) + { + imageSize += std::max(1u, imageInfo.extent.width >> mipLevel) * std::max(1u, imageInfo.extent.height >> mipLevel) * imageInfo.extent.depth * bytesPerPixel; + } + + // If there are multiple array layers, multiply by the layer count + imageSize *= imageInfo.arrayLayers; +#else + uint32_t imageSize = SMALL_ALLOCATION_MAX_SIZE + 1; +#endif + CreateImageVma(imageInfo, image, allocation, imageSize); #else CreateImageDefault(imageInfo, image, imageMemory, properties); @@ -160,6 +183,7 @@ namespace Lumos m_MipLevels = 1; m_VKFormat = VKUtilities::FormatToVK(m_Parameters.format, m_Parameters.srgb); m_Flags = m_Parameters.flags; + m_Samples = parameters.samples; BuildTexture(); } @@ -178,7 +202,7 @@ namespace Lumos m_Format = parameters.format; m_VKFormat = VKUtilities::FormatToVK(parameters.format, parameters.srgb); m_Flags = m_Parameters.flags; - + m_Samples = parameters.samples; Load(); m_TextureImageView = CreateImageView(m_TextureImage, VKUtilities::FormatToVK(parameters.format, parameters.srgb), m_MipLevels, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, 1); @@ -200,6 +224,7 @@ namespace Lumos m_Format = parameters.format; m_VKFormat = VKUtilities::FormatToVK(m_Parameters.format, m_Parameters.srgb); m_Flags = m_Parameters.flags; + m_Samples = parameters.samples; m_DeleteImage = Load(); @@ -225,6 +250,7 @@ namespace Lumos , m_ImageLayout(VK_IMAGE_LAYOUT_UNDEFINED) { m_TextureImageMemory = VK_NULL_HANDLE; + m_Samples = 1; m_UUID = Random64::Rand(0, std::numeric_limits::max()); @@ -239,7 +265,7 @@ namespace Lumos void VKTexture2D::DeleteResources() { - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); if(m_TextureSampler) { @@ -475,7 +501,7 @@ namespace Lumos m_MipLevels = static_cast(std::floor(std::log2(Maths::Max(m_Width, m_Height)))) + 1; - if(!(m_Flags & TextureFlags::Texture_CreateMips) || m_Parameters.generateMipMaps == false) + if(!(m_Flags & TextureFlags::Texture_CreateMips) && m_Parameters.generateMipMaps == false) m_MipLevels = 1; VKBuffer* stagingBuffer = new VKBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, static_cast(imageSize), pixels); @@ -484,22 +510,24 @@ namespace Lumos if(m_Data == nullptr) delete[] pixels; #ifdef USE_VMA_ALLOCATOR - Graphics::CreateImage(m_Width, m_Height, m_MipLevels, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0, m_Allocation); + Graphics::CreateImage(m_Width, m_Height, m_MipLevels, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0, m_Allocation, m_Samples); #else Graphics::CreateImage(m_Width, m_Height, m_MipLevels, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0); #endif VKUtilities::TransitionImageLayout(m_TextureImage, m_VKFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, m_MipLevels); VKUtilities::CopyBufferToImage(stagingBuffer->GetBuffer(), m_TextureImage, static_cast(m_Width), static_cast(m_Height)); - m_ImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + m_ImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; delete stagingBuffer; - if(m_Flags & TextureFlags::Texture_CreateMips) + if(m_Flags & TextureFlags::Texture_CreateMips && m_Width > 1 && m_Height > 1) GenerateMipmaps(nullptr, m_TextureImage, m_VKFormat, m_Width, m_Height, m_MipLevels); + m_ImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + m_UUID = Random64::Rand(0, std::numeric_limits::max()); - // TransitionImage(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + TransitionImage(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); return true; } @@ -510,9 +538,11 @@ namespace Lumos { m_MipLevels = static_cast(std::floor(std::log2(Maths::Max(m_Width, m_Height)))) + 1; } + else + m_MipLevels = 1; #ifdef USE_VMA_ALLOCATOR - Graphics::CreateImage(m_Width, m_Height, m_MipLevels, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0, m_Allocation); + Graphics::CreateImage(m_Width, m_Height, m_MipLevels, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0, m_Allocation, m_Samples); #else Graphics::CreateImage(m_Width, m_Height, m_MipLevels, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0); #endif @@ -520,11 +550,6 @@ namespace Lumos m_TextureImageView = CreateImageView(m_TextureImage, m_VKFormat, m_MipLevels, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, 1); m_TextureSampler = CreateTextureSampler(VKUtilities::TextureFilterToVK(m_Parameters.minFilter), VKUtilities::TextureFilterToVK(m_Parameters.magFilter), 0.0f, static_cast(m_MipLevels), false, VKDevice::Get().GetPhysicalDevice()->GetProperties().limits.maxSamplerAnisotropy, VKUtilities::TextureWrapToVK(m_Parameters.wrap), VKUtilities::TextureWrapToVK(m_Parameters.wrap), VKUtilities::TextureWrapToVK(m_Parameters.wrap)); - m_ImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; - TransitionImage(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - UpdateDescriptor(); - if(m_Flags & TextureFlags::Texture_MipViews) { for(uint32_t i = 0; i < m_MipLevels; i++) @@ -533,6 +558,11 @@ namespace Lumos } } + m_ImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + TransitionImage(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + + UpdateDescriptor(); + m_UUID = Random64::Rand(0, std::numeric_limits::max()); } @@ -761,65 +791,7 @@ namespace Lumos VKTextureCube::~VKTextureCube() { - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); - - if(m_TextureSampler) - { - auto sampler = m_TextureSampler; - deletionQueue.PushFunction([sampler] - { vkDestroySampler(VKDevice::GetHandle(), sampler, nullptr); }); - } - - if(m_TextureImageView) - { - auto imageView = m_TextureImageView; - deletionQueue.PushFunction([imageView] - - { vkDestroyImageView(VKDevice::GetHandle(), imageView, nullptr); }); - } - - if(!m_IndividualImageViews.empty()) - { - auto imageViews = m_IndividualImageViews; - deletionQueue.PushFunction([imageViews] - - { - for(uint32_t i = 0; i < (uint32_t)imageViews.size(); i++) - { - vkDestroyImageView(VKDevice::GetHandle(), imageViews[i], nullptr); - } }); - } - - if(!m_ImageViewsPerMip.empty()) - { - auto imageViews = m_ImageViewsPerMip; - deletionQueue.PushFunction([imageViews] - - { - for(uint32_t i = 0; i < (uint32_t)imageViews.size(); i++) - { - vkDestroyImageView(VKDevice::GetHandle(), imageViews[i], nullptr); - } }); - } - - if(m_DeleteImage) - { - auto image = m_TextureImage; -#ifdef USE_VMA_ALLOCATOR - auto alloc = m_Allocation; - deletionQueue.PushFunction([image, alloc] - { vmaDestroyImage(VKDevice::Get().GetAllocator(), image, alloc); }); -#else - deletionQueue.PushFunction([image] - { vkDestroyImage(VKDevice::Get().GetAllocator(), image, nullptr); }); - if(m_TextureImageMemory) - { - auto imageMemory = m_TextureImageMemory; - deletionQueue.PushFunction([imageMemory] - { vkFreeMemory(VKDevice::Get().GetAllocator(), imageMemory, nullptr); }); - } -#endif - } + Destroy(true); } void VKTextureCube::TransitionImage(VkImageLayout newLayout, VKCommandBuffer* commandBuffer) @@ -842,6 +814,126 @@ namespace Lumos VKUtilities::TransitionImageLayout(m_TextureImage, m_VKFormat, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, m_ImageLayout, m_NumMips, 6, ((VKCommandBuffer*)commandBuffer)->GetHandle()); } + void VKTextureCube::Destroy(bool useDeletionQueue) + { + if(useDeletionQueue) + { + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + + if(m_TextureSampler) + { + auto sampler = m_TextureSampler; + deletionQueue.PushFunction([sampler] + { vkDestroySampler(VKDevice::GetHandle(), sampler, nullptr); }); + } + + if(m_TextureImageView) + { + auto imageView = m_TextureImageView; + deletionQueue.PushFunction([imageView] + + { vkDestroyImageView(VKDevice::GetHandle(), imageView, nullptr); }); + } + + if(!m_IndividualImageViews.empty()) + { + auto imageViews = m_IndividualImageViews; + deletionQueue.PushFunction([imageViews] + + { + for (uint32_t i = 0; i < (uint32_t)imageViews.size(); i++) + { + vkDestroyImageView(VKDevice::GetHandle(), imageViews[i], nullptr); + } }); + } + + if(!m_ImageViewsPerMip.empty()) + { + auto imageViews = m_ImageViewsPerMip; + deletionQueue.PushFunction([imageViews] + + { + for (uint32_t i = 0; i < (uint32_t)imageViews.size(); i++) + { + vkDestroyImageView(VKDevice::GetHandle(), imageViews[i], nullptr); + } }); + } + + if(m_DeleteImage && m_TextureImage) + { + auto image = m_TextureImage; +#ifdef USE_VMA_ALLOCATOR + auto alloc = m_Allocation; + deletionQueue.PushFunction([image, alloc] + { vmaDestroyImage(VKDevice::Get().GetAllocator(), image, alloc); }); +#else + deletionQueue.PushFunction([image] + { vkDestroyImage(VKDevice::Get().GetAllocator(), image, nullptr); }); + if(m_TextureImageMemory) + { + auto imageMemory = m_TextureImageMemory; + deletionQueue.PushFunction([imageMemory] + { vkFreeMemory(VKDevice::Get().GetAllocator(), imageMemory, nullptr); }); + } +#endif + } + } + else + { + if(m_TextureSampler) + { + auto sampler = m_TextureSampler; + vkDestroySampler(VKDevice::GetHandle(), sampler, nullptr); + } + + if(m_TextureImageView) + { + auto imageView = m_TextureImageView; + vkDestroyImageView(VKDevice::GetHandle(), imageView, nullptr); + } + + if(!m_IndividualImageViews.empty()) + { + auto imageViews = m_IndividualImageViews; + + for(uint32_t i = 0; i < (uint32_t)imageViews.size(); i++) + { + vkDestroyImageView(VKDevice::GetHandle(), imageViews[i], nullptr); + } + } + + if(!m_ImageViewsPerMip.empty()) + { + auto imageViews = m_ImageViewsPerMip; + for(uint32_t i = 0; i < (uint32_t)imageViews.size(); i++) + { + vkDestroyImageView(VKDevice::GetHandle(), imageViews[i], nullptr); + } + } + + if(m_DeleteImage) + { + auto image = m_TextureImage; +#ifdef USE_VMA_ALLOCATOR + auto alloc = m_Allocation; + vmaDestroyImage(VKDevice::Get().GetAllocator(), image, alloc); +#else + vkDestroyImage(VKDevice::Get().GetAllocator(), image, nullptr); + if(m_TextureImageMemory) + { + auto imageMemory = m_TextureImageMemory; + vkFreeMemory(VKDevice::Get().GetAllocator(), imageMemory, nullptr); + } +#endif + } + } + m_TextureImageView = nullptr; + m_TextureSampler = nullptr; + m_TextureImage = nullptr; + m_ImageViewsPerMip.clear(); + m_IndividualImageViews.clear(); + } + void VKTextureCube::UpdateDescriptor() { m_Descriptor.sampler = m_TextureSampler; @@ -1034,19 +1126,20 @@ namespace Lumos } } - VKTextureDepth::VKTextureDepth(uint32_t width, uint32_t height, RHIFormat format) + VKTextureDepth::VKTextureDepth(uint32_t width, uint32_t height, RHIFormat format, uint8_t samples) : m_Width(width) , m_Height(height) , m_TextureImageView(VK_NULL_HANDLE) , m_TextureSampler(VK_NULL_HANDLE) , m_Format(format) + , m_Samples(samples) { Init(); } VKTextureDepth::~VKTextureDepth() { - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); auto sampler = m_TextureSampler; auto imageView = m_TextureImageView; @@ -1085,7 +1178,7 @@ namespace Lumos m_VKFormat = VKUtilities::FormatToVK(m_Format); #ifdef USE_VMA_ALLOCATOR - Graphics::CreateImage(m_Width, m_Height, 1, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0, m_Allocation); + Graphics::CreateImage(m_Width, m_Height, 1, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0, m_Allocation, m_Samples); #else Graphics::CreateImage(m_Width, m_Height, 1, m_VKFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_TextureImage, m_TextureImageMemory, 1, 0); #endif @@ -1131,7 +1224,7 @@ namespace Lumos m_Height = height; Handle = UUID(); - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); auto sampler = m_TextureSampler; auto imageView = m_TextureImageView; @@ -1175,7 +1268,7 @@ namespace Lumos VKTextureDepthArray::~VKTextureDepthArray() { LUMOS_PROFILE_FUNCTION(); - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); auto sampler = m_TextureSampler; auto imageView = m_TextureImageView; @@ -1214,15 +1307,10 @@ namespace Lumos { LUMOS_PROFILE_FUNCTION(); m_Flags |= TextureFlags::Texture_DepthStencil; - - // VkFormat depthFormat = VKUtilities::FindDepthFormat(); - // m_VKFormat = VK_FORMAT_D32_SFLOAT; // depthFormat; - // m_Format = VKUtilities::VKToFormat(m_VKFormat); - m_VKFormat = VKUtilities::FormatToVK(m_Format); #ifdef LUMOS_PLATFORM_MACOS - VkImageUsageFlags usage = VkImageUsageFlags(0); + VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; #else VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; @@ -1283,7 +1371,7 @@ namespace Lumos m_Count = count; Handle = UUID(); - VKContext::DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); + DeletionQueue& deletionQueue = VKRenderer::GetCurrentDeletionQueue(); auto sampler = m_TextureSampler; auto imageView = m_TextureImageView; @@ -1357,9 +1445,9 @@ namespace Lumos return new VKTextureCube(files, mips, params, loadOptions); } - TextureDepth* VKTextureDepth::CreateFuncVulkan(uint32_t width, uint32_t height, RHIFormat format) + TextureDepth* VKTextureDepth::CreateFuncVulkan(uint32_t width, uint32_t height, RHIFormat format, uint8_t samples) { - return new VKTextureDepth(width, height, format); + return new VKTextureDepth(width, height, format, samples); } TextureDepthArray* VKTextureDepthArray::CreateFuncVulkan(uint32_t width, uint32_t height, uint32_t count, RHIFormat format) diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKTexture.h b/Lumos/Source/Lumos/Platform/Vulkan/VKTexture.h index d124a7a5..6e06b686 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKTexture.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKTexture.h @@ -6,10 +6,6 @@ #include "VKCommandBuffer.h" #include "VKBuffer.h" -#ifdef USE_VMA_ALLOCATOR -#include -#endif - namespace Lumos { namespace Graphics @@ -137,6 +133,11 @@ namespace Lumos return m_VKFormat; } + uint8_t GetSamples() const override + { + return m_Samples; + } + VkImageView GetMipImageView(uint32_t mip); VkImageLayout GetImageLayout() const { return m_ImageLayout; } @@ -156,6 +157,7 @@ namespace Lumos uint32_t m_Width {}, m_Height {}; uint32_t m_MipLevels = 1; uint8_t* m_Data = nullptr; + uint8_t m_Samples = 1; TextureDesc m_Parameters; TextureLoadOptions m_LoadOptions; @@ -296,6 +298,7 @@ namespace Lumos VkImageLayout GetImageLayout() const { return m_ImageLayout; } void GenerateMipMaps(CommandBuffer* commandBuffer) override; + void Destroy(bool useDeletionQueue) override; static void MakeDefault(); @@ -341,7 +344,7 @@ namespace Lumos class VKTextureDepth : public TextureDepth { public: - VKTextureDepth(uint32_t width, uint32_t height, RHIFormat format); + VKTextureDepth(uint32_t width, uint32_t height, RHIFormat format, uint8_t samples); ~VKTextureDepth(); void Bind(uint32_t slot = 0) const override {}; @@ -387,6 +390,11 @@ namespace Lumos return m_Format; } + uint8_t GetSamples() const override + { + return m_Samples; + } + VkImage GetImage() const { return m_TextureImage; @@ -425,13 +433,14 @@ namespace Lumos static void MakeDefault(); protected: - static TextureDepth* CreateFuncVulkan(uint32_t, uint32_t, RHIFormat); + static TextureDepth* CreateFuncVulkan(uint32_t, uint32_t, RHIFormat, uint8_t); void Init(); private: std::string m_Name; uint32_t m_Handle {}; uint32_t m_Width, m_Height; + uint8_t m_Samples; RHIFormat m_Format; VkFormat m_VKFormat; VkImageLayout m_ImageLayout; diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKUniformBuffer.h b/Lumos/Source/Lumos/Platform/Vulkan/VKUniformBuffer.h index 0ca15d83..0286c4ce 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKUniformBuffer.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKUniformBuffer.h @@ -3,10 +3,6 @@ #include "VKBuffer.h" #include "Graphics/RHI/UniformBuffer.h" -#ifdef USE_VMA_ALLOCATOR -#include -#endif - namespace Lumos { namespace Graphics diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKUtilities.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKUtilities.cpp index 4837c932..fba42da9 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKUtilities.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKUtilities.cpp @@ -420,7 +420,7 @@ namespace Lumos { if(imageMemoryBarrier.oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) { - sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + sourceStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; } else if(imageMemoryBarrier.srcAccessMask != 0) { @@ -436,7 +436,7 @@ namespace Lumos { if(imageMemoryBarrier.newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) { - destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; } else if(imageMemoryBarrier.dstAccessMask != 0) { @@ -756,6 +756,57 @@ namespace Lumos } } + uint32_t VKUtilities::BytesPerPixel(VkFormat format) + { + switch(format) + { + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_UINT: + return 1; + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R8G8_SNORM: + case VK_FORMAT_R8G8_UINT: + case VK_FORMAT_R16_UINT: + case VK_FORMAT_D16_UNORM: + return 2; + case VK_FORMAT_D16_UNORM_S8_UINT: + return 3; + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_R16G16_UNORM: + case VK_FORMAT_R16G16_SFLOAT: + case VK_FORMAT_R8G8B8A8_SNORM: + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + case VK_FORMAT_R8G8B8A8_UINT: + case VK_FORMAT_R16G16_UINT: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_B10G11R11_UFLOAT_PACK32: + return 4; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + return 5; + case VK_FORMAT_R16G16B16A16_SFLOAT: + case VK_FORMAT_R16G16B16A16_UNORM: + case VK_FORMAT_R32G32_SFLOAT: + case VK_FORMAT_R16G16B16A16_UINT: + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + return 8; + case VK_FORMAT_R32G32B32A32_SFLOAT: + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC7_UNORM_BLOCK: + return 16; + default: + LUMOS_LOG_ERROR("Unsupported Vulkan format"); + return 4; + } + + return 4; + } + VkShaderStageFlagBits VKUtilities::ShaderTypeToVK(const ShaderType& shaderName) { switch(shaderName) @@ -875,5 +926,21 @@ namespace Lumos VK_CHECK_RESULT(fpSetDebugUtilsObjectNameEXT(device, &nameInfo)); } + + VkSampleCountFlagBits VKUtilities::GetMaxUsableSampleCount() + { + VkPhysicalDeviceProperties physicalDeviceProperties; + vkGetPhysicalDeviceProperties(VKDevice::Get().GetPhysicalDevice()->GetHandle(), &physicalDeviceProperties); + + VkSampleCountFlags counts = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts; + if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; } + if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; } + if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; } + if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; } + if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; } + if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; } + + return VK_SAMPLE_COUNT_1_BIT; + } } } diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKUtilities.h b/Lumos/Source/Lumos/Platform/Vulkan/VKUtilities.h index fd096d77..032f4647 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKUtilities.h +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKUtilities.h @@ -1,7 +1,6 @@ #pragma once #include "VK.h" #include "Graphics/RHI/Definitions.h" -#include #define VK_CHECK_RESULT(f) \ { \ @@ -60,6 +59,8 @@ namespace Lumos VkFormat FormatToVK(const RHIFormat format, bool srgb = false); RHIFormat VKToFormat(VkFormat format); + uint32_t BytesPerPixel(VkFormat format); + VkSamplerAddressMode TextureWrapToVK(const TextureWrap format); VkFilter TextureFilterToVK(const TextureFilter filter); VkShaderStageFlagBits ShaderTypeToVK(const ShaderType& shaderName); @@ -67,6 +68,8 @@ namespace Lumos VkPrimitiveTopology DrawTypeToVk(Lumos::Graphics::DrawType type); void SetDebugUtilsObjectName(const VkDevice device, const VkObjectType objectType, const char* name, const void* handle); + + VkSampleCountFlagBits GetMaxUsableSampleCount(); } } } diff --git a/Lumos/Source/Lumos/Scene/Component/Components.h b/Lumos/Source/Lumos/Scene/Component/Components.h index d991ed8e..0ff5a2e3 100644 --- a/Lumos/Source/Lumos/Scene/Component/Components.h +++ b/Lumos/Source/Lumos/Scene/Component/Components.h @@ -58,7 +58,7 @@ namespace Lumos if(!fontFilePath.empty() && fontFilePath != Graphics::Font::GetDefaultFont()->GetFilePath() && FileSystem::FileExists(fontFilePath)) { - Application::Get().GetFontLibrary()->Load(fontFilePath, FontHandle); + Application::Get().GetAssetManager()->AddAsset(fontFilePath, FontHandle); } else { diff --git a/Lumos/Source/Lumos/Scene/Component/ModelComponent.cpp b/Lumos/Source/Lumos/Scene/Component/ModelComponent.cpp index 0c48e7d3..ddd997aa 100644 --- a/Lumos/Source/Lumos/Scene/Component/ModelComponent.cpp +++ b/Lumos/Source/Lumos/Scene/Component/ModelComponent.cpp @@ -12,7 +12,9 @@ namespace Lumos::Graphics void ModelComponent::LoadFromLibrary(const std::string& path) { - ModelRef = Application::Get().GetModelLibrary()->GetResource(path); + ModelRef = Application::Get().GetAssetManager()->AddAsset(path, CreateSharedPtr(path)).data.As(); + + // ModelRef = Application::Get().GetModelLibrary()->GetAsset(path); } } diff --git a/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.cpp b/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.cpp index c80fd8d0..05590f8d 100644 --- a/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.cpp +++ b/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.cpp @@ -2,7 +2,7 @@ #include "RigidBody3DComponent.h" #include "Scene/Scene.h" #include "Scene/EntityManager.h" - +#include #include namespace Lumos diff --git a/Lumos/Source/Lumos/Scene/Entity.h b/Lumos/Source/Lumos/Scene/Entity.h index c70fb45e..57128832 100644 --- a/Lumos/Source/Lumos/Scene/Entity.h +++ b/Lumos/Source/Lumos/Scene/Entity.h @@ -8,7 +8,7 @@ DISABLE_WARNING_PUSH DISABLE_WARNING_CONVERSION_TO_SMALLER_TYPE -#include +#include DISABLE_WARNING_POP namespace Lumos diff --git a/Lumos/Source/Lumos/Scene/EntityFactory.cpp b/Lumos/Source/Lumos/Scene/EntityFactory.cpp index a87a535f..86a681c2 100644 --- a/Lumos/Source/Lumos/Scene/EntityFactory.cpp +++ b/Lumos/Source/Lumos/Scene/EntityFactory.cpp @@ -58,7 +58,7 @@ namespace Lumos properties.metallicMapFactor = 0.0f; matInstance->SetMaterialProperites(properties); - // auto shader = Application::Get().GetShaderLibrary()->GetResource("//CoreShaders/ForwardPBR.shader"); + // auto shader = Application::Get().GetShaderLibrary()->GetAsset("//CoreShaders/ForwardPBR.shader"); // matInstance->SetShader(nullptr);//shader); model->GetMeshes().front()->SetMaterial(matInstance); @@ -120,7 +120,7 @@ namespace Lumos properties.occlusionMapFactor = 0.0f; matInstance->SetMaterialProperites(properties); - // auto shader = Application::Get().GetShaderLibrary()->GetResource("//CoreShaders/ForwardPBR.shader"); + // auto shader = Application::Get().GetShaderLibrary()->GetAsset("//CoreShaders/ForwardPBR.shader"); // matInstance->SetShader(shader); model->GetMeshes().front()->SetMaterial(matInstance); @@ -177,7 +177,7 @@ namespace Lumos properties.metallicMapFactor = 0.0f; matInstance->SetMaterialProperites(properties); - // auto shader = Application::Get().GetShaderLibrary()->GetResource("//CoreShaders/ForwardPBR.shader"); + // auto shader = Application::Get().GetShaderLibrary()->GetAsset("//CoreShaders/ForwardPBR.shader"); // matInstance->SetShader(shader); pyramidMeshEntity.AddComponent(glm::toMat4(glm::quat(glm::vec3(glm::radians(-90.0f), 0.0f, 0.0f))) * glm::scale(glm::mat4(1.0), halfdims)); diff --git a/Lumos/Source/Lumos/Scene/EntityFactory.h b/Lumos/Source/Lumos/Scene/EntityFactory.h index 9b3f82a9..0b6f9b61 100644 --- a/Lumos/Source/Lumos/Scene/EntityFactory.h +++ b/Lumos/Source/Lumos/Scene/EntityFactory.h @@ -1,6 +1,5 @@ #pragma once -#include "Entity.h" #include #include @@ -8,6 +7,7 @@ namespace Lumos { class RigidBody; class Scene; + class Entity; namespace EntityFactory { diff --git a/Lumos/Source/Lumos/Scene/EntityManager.h b/Lumos/Source/Lumos/Scene/EntityManager.h index 691361de..35a2d038 100644 --- a/Lumos/Source/Lumos/Scene/EntityManager.h +++ b/Lumos/Source/Lumos/Scene/EntityManager.h @@ -4,7 +4,7 @@ DISABLE_WARNING_PUSH DISABLE_WARNING_CONVERSION_TO_SMALLER_TYPE -#include +#include DISABLE_WARNING_POP namespace Lumos diff --git a/Lumos/Source/Lumos/Scene/Scene.cpp b/Lumos/Source/Lumos/Scene/Scene.cpp index 2d7b60cc..7af52c33 100644 --- a/Lumos/Source/Lumos/Scene/Scene.cpp +++ b/Lumos/Source/Lumos/Scene/Scene.cpp @@ -20,6 +20,7 @@ #include "Events/ApplicationEvent.h" #include "Maths/Transform.h" +#include "Maths/Random.h" #include "Core/OS/FileSystem.h" #include "Scene/Component/Components.h" #include "Scripting/Lua/LuaScriptComponent.h" @@ -33,11 +34,13 @@ #include "Scene/Component/SoundComponent.h" #include "Scene/Component/ModelComponent.h" #include "SceneGraph.h" +#include "SerialisationImplementation.h" #include #include #include #include +#include #include CEREAL_REGISTER_TYPE(Lumos::SphereCollisionShape); @@ -217,7 +220,7 @@ namespace Lumos m_EntityManager->AddDependency(); m_EntityManager->AddDependency(); m_EntityManager->AddDependency(); - m_EntityManager->AddDependency(); + m_EntityManager->AddDependency(); m_EntityManager->AddDependency(); m_SceneGraph = CreateUniquePtr(); @@ -237,8 +240,6 @@ namespace Lumos void Scene::OnInit() { LUMOS_PROFILE_FUNCTION(); - LuaManager::Get().GetState().set("registry", &m_EntityManager->GetRegistry()); - LuaManager::Get().GetState().set("scene", this); // Physics setup auto physics3DSytem = Application::Get().GetSystem(); @@ -257,7 +258,7 @@ namespace Lumos LUMOS_PROFILE_FUNCTION(); DeleteAllGameObjects(); - LuaManager::Get().GetState().collect_garbage(); + LuaManager::Get().CollectGarbage(); auto audioManager = Application::Get().GetSystem(); if(audioManager) diff --git a/Lumos/Source/Lumos/Scene/Scene.h b/Lumos/Source/Lumos/Scene/Scene.h index bbaa8994..68ad3146 100644 --- a/Lumos/Source/Lumos/Scene/Scene.h +++ b/Lumos/Source/Lumos/Scene/Scene.h @@ -1,12 +1,9 @@ #pragma once -#include "Serialisation.h" #include #include - -DISABLE_WARNING_PUSH -DISABLE_WARNING_CONVERSION_TO_SMALLER_TYPE -#include -DISABLE_WARNING_POP +#include +#include "Core/DataStructures/Vector.h" +#include "Core/UUID.h" namespace Lumos { @@ -28,6 +25,12 @@ namespace Lumos class LUMOS_EXPORT Scene { + template + friend void save(Archive& archive, const Scene& scene); + + template + friend void load(Archive& archive, Scene& scene); + public: explicit Scene(const std::string& name); virtual ~Scene(); @@ -93,7 +96,6 @@ namespace Lumos entt::registry& GetRegistry(); void UpdateSceneGraph(); - void DuplicateEntity(Entity entity); void DuplicateEntity(Entity entity, Entity parent); Entity CreateEntity(); @@ -158,13 +160,14 @@ namespace Lumos float SkyboxMipLevel = 0.0f; int DebugMode = 0; + uint8_t MSAASamples = 4; }; struct ScenePhysics3DSettings { uint32_t m_MaxUpdatesPerFrame = 5; - uint32_t VelocityIterations = 20; - uint32_t PositionIterations = 1; + uint32_t VelocityIterations = 6; + uint32_t PositionIterations = 2; glm::vec3 Gravity = glm::vec3(0.0f, -9.81f, 0.0f); float Dampening = 0.9995f; @@ -192,68 +195,6 @@ namespace Lumos ScenePhysics2DSettings Physics2DSettings; }; - template - void save(Archive& archive) const - { - archive(cereal::make_nvp("Version", SceneSerialisationVersion)); - archive(cereal::make_nvp("Scene Name", m_SceneName)); - - archive(cereal::make_nvp("PhysicsEnabled2D", m_Settings.PhysicsEnabled2D), cereal::make_nvp("PhysicsEnabled3D", m_Settings.PhysicsEnabled3D), cereal::make_nvp("AudioEnabled", m_Settings.AudioEnabled), cereal::make_nvp("Renderer2DEnabled", m_Settings.RenderSettings.Renderer2DEnabled), - cereal::make_nvp("Renderer3DEnabled", m_Settings.RenderSettings.Renderer3DEnabled), cereal::make_nvp("DebugRenderEnabled", m_Settings.RenderSettings.DebugRenderEnabled), cereal::make_nvp("SkyboxRenderEnabled", m_Settings.RenderSettings.SkyboxRenderEnabled), cereal::make_nvp("ShadowsEnabled", m_Settings.RenderSettings.ShadowsEnabled)); - archive(cereal::make_nvp("Exposure", m_Settings.RenderSettings.m_Exposure), cereal::make_nvp("ToneMap", m_Settings.RenderSettings.m_ToneMapIndex)); - - archive(cereal::make_nvp("BloomIntensity", m_Settings.RenderSettings.m_BloomIntensity), cereal::make_nvp("BloomKnee", m_Settings.RenderSettings.BloomKnee), cereal::make_nvp("BloomThreshold", m_Settings.RenderSettings.BloomThreshold), - cereal::make_nvp("BloomUpsampleScale", m_Settings.RenderSettings.BloomUpsampleScale)); - - archive(cereal::make_nvp("FXAAEnabled", m_Settings.RenderSettings.FXAAEnabled), cereal::make_nvp("DebandingEnabled", m_Settings.RenderSettings.DebandingEnabled), cereal::make_nvp("ChromaticAberationEnabled", m_Settings.RenderSettings.ChromaticAberationEnabled), cereal::make_nvp("EyeAdaptation", m_Settings.RenderSettings.EyeAdaptation), cereal::make_nvp("SSAOEnabled", m_Settings.RenderSettings.SSAOEnabled), cereal::make_nvp("BloomEnabled", m_Settings.RenderSettings.BloomEnabled), cereal::make_nvp("FilmicGrainEnabled", m_Settings.RenderSettings.FilmicGrainEnabled), cereal::make_nvp("DepthOfFieldEnabled", m_Settings.RenderSettings.DepthOfFieldEnabled), cereal::make_nvp("MotionBlurEnabled", m_Settings.RenderSettings.MotionBlurEnabled)); - - archive(cereal::make_nvp("DepthOFFieldEnabled", m_Settings.RenderSettings.DepthOfFieldEnabled), cereal::make_nvp("DepthOfFieldStrength", m_Settings.RenderSettings.DepthOfFieldStrength), cereal::make_nvp("DepthOfFieldDistance", m_Settings.RenderSettings.DepthOfFieldDistance)); - - archive(m_Settings.RenderSettings.Brightness, m_Settings.RenderSettings.Saturation, m_Settings.RenderSettings.Contrast); - - archive(m_Settings.RenderSettings.SharpenEnabled); - } - - template - void load(Archive& archive) - { - archive(cereal::make_nvp("Version", m_SceneSerialisationVersion)); - archive(cereal::make_nvp("Scene Name", m_SceneName)); - - Serialisation::CurrentSceneVersion = m_SceneSerialisationVersion; - - if(m_SceneSerialisationVersion > 7) - { - archive(cereal::make_nvp("PhysicsEnabled2D", m_Settings.PhysicsEnabled2D), cereal::make_nvp("PhysicsEnabled3D", m_Settings.PhysicsEnabled3D), cereal::make_nvp("AudioEnabled", m_Settings.AudioEnabled), cereal::make_nvp("Renderer2DEnabled", m_Settings.RenderSettings.Renderer2DEnabled), - cereal::make_nvp("Renderer3DEnabled", m_Settings.RenderSettings.Renderer3DEnabled), cereal::make_nvp("DebugRenderEnabled", m_Settings.RenderSettings.DebugRenderEnabled), cereal::make_nvp("SkyboxRenderEnabled", m_Settings.RenderSettings.SkyboxRenderEnabled), cereal::make_nvp("ShadowsEnabled", m_Settings.RenderSettings.ShadowsEnabled)); - } - if(m_SceneSerialisationVersion > 9) - { - archive(cereal::make_nvp("Exposure", m_Settings.RenderSettings.m_Exposure), cereal::make_nvp("ToneMap", m_Settings.RenderSettings.m_ToneMapIndex)); - } - - if(Serialisation::CurrentSceneVersion > 11) - { - archive(cereal::make_nvp("BloomIntensity", m_Settings.RenderSettings.m_BloomIntensity), cereal::make_nvp("BloomKnee", m_Settings.RenderSettings.BloomKnee), cereal::make_nvp("BloomThreshold", m_Settings.RenderSettings.BloomThreshold), - cereal::make_nvp("BloomUpsampleScale", m_Settings.RenderSettings.BloomUpsampleScale)); - } - if(Serialisation::CurrentSceneVersion > 12) - { - archive(cereal::make_nvp("FXAAEnabled", m_Settings.RenderSettings.FXAAEnabled), cereal::make_nvp("DebandingEnabled", m_Settings.RenderSettings.DebandingEnabled), cereal::make_nvp("ChromaticAberationEnabled", m_Settings.RenderSettings.ChromaticAberationEnabled), cereal::make_nvp("EyeAdaptation", m_Settings.RenderSettings.EyeAdaptation), cereal::make_nvp("SSAOEnabled", m_Settings.RenderSettings.SSAOEnabled), cereal::make_nvp("BloomEnabled", m_Settings.RenderSettings.BloomEnabled), cereal::make_nvp("FilmicGrainEnabled", m_Settings.RenderSettings.FilmicGrainEnabled), cereal::make_nvp("DepthOfFieldEnabled", m_Settings.RenderSettings.DepthOfFieldEnabled), cereal::make_nvp("MotionBlurEnabled", m_Settings.RenderSettings.MotionBlurEnabled)); - } - - if(Serialisation::CurrentSceneVersion > 15) - { - archive(cereal::make_nvp("DepthOfFieldEnabled", m_Settings.RenderSettings.DepthOfFieldEnabled), cereal::make_nvp("DepthOfFieldStrength", m_Settings.RenderSettings.DepthOfFieldStrength), cereal::make_nvp("DepthOfFieldDistance", m_Settings.RenderSettings.DepthOfFieldDistance)); - } - - if(Serialisation::CurrentSceneVersion > 16) - archive(m_Settings.RenderSettings.Brightness, m_Settings.RenderSettings.Saturation, m_Settings.RenderSettings.Contrast); - - if(Serialisation::CurrentSceneVersion > 18) - archive(m_Settings.RenderSettings.SharpenEnabled); - } - SceneSettings& GetSettings() { return m_Settings; @@ -275,6 +216,9 @@ namespace Lumos uint32_t m_ScreenWidth; uint32_t m_ScreenHeight; + //Load these assets ready to be used during a scene + Vector m_PreLoadAssetsList; + private: NONCOPYABLE(Scene) diff --git a/Lumos/Source/Lumos/Scene/SceneGraph.cpp b/Lumos/Source/Lumos/Scene/SceneGraph.cpp index 135b5f89..144181be 100644 --- a/Lumos/Source/Lumos/Scene/SceneGraph.cpp +++ b/Lumos/Source/Lumos/Scene/SceneGraph.cpp @@ -4,7 +4,7 @@ DISABLE_WARNING_PUSH DISABLE_WARNING_CONVERSION_TO_SMALLER_TYPE -#include +#include DISABLE_WARNING_POP namespace Lumos diff --git a/Lumos/Source/Lumos/Scene/SceneManager.cpp b/Lumos/Source/Lumos/Scene/SceneManager.cpp index 48574acc..4cc33541 100644 --- a/Lumos/Source/Lumos/Scene/SceneManager.cpp +++ b/Lumos/Source/Lumos/Scene/SceneManager.cpp @@ -76,7 +76,7 @@ namespace Lumos return; if(m_vpAllScenes.Empty()) - m_vpAllScenes.Emplace(CreateSharedPtr("NewScene")); + m_vpAllScenes.PushBack(CreateSharedPtr("NewScene")); m_QueuedSceneIndex = 0; } @@ -133,7 +133,7 @@ namespace Lumos for(auto& scene : m_vpAllScenes) { - names.Emplace(scene->GetSceneName()); + names.PushBack(scene->GetSceneName()); } return names; @@ -153,7 +153,7 @@ namespace Lumos } } - m_SceneFilePaths.Emplace(filePath); + m_SceneFilePaths.PushBack(filePath); auto name = StringUtilities::RemoveFilePathExtension(StringUtilities::GetFileName(filePath)); auto scene = new Scene(name); @@ -163,7 +163,7 @@ namespace Lumos void SceneManager::EnqueueScene(Scene* scene) { - m_vpAllScenes.Emplace(SharedPtr(scene)); + m_vpAllScenes.PushBack(SharedPtr(scene)); LUMOS_LOG_INFO("[SceneManager] - Enqueued scene : {0}", scene->GetSceneName().c_str()); } @@ -196,7 +196,7 @@ namespace Lumos { m_SceneFilePaths.Clear(); for(auto scene : m_vpAllScenes) - m_SceneFilePaths.Emplace("//Assets/Scenes/" + scene->GetSceneName()); + m_SceneFilePaths.PushBack("//Assets/Scenes/" + scene->GetSceneName()); return m_SceneFilePaths; } } diff --git a/Lumos/Source/Lumos/Scene/SceneManager.h b/Lumos/Source/Lumos/Scene/SceneManager.h index caa38e18..ac4103a8 100644 --- a/Lumos/Source/Lumos/Scene/SceneManager.h +++ b/Lumos/Source/Lumos/Scene/SceneManager.h @@ -64,7 +64,7 @@ namespace Lumos void EnqueueScene(const std::string& name) { // T* scene = new T(name); - m_vpAllScenes.Emplace(CreateSharedPtr(name)); + m_vpAllScenes.PushBack(CreateSharedPtr(name)); LUMOS_LOG_INFO("[SceneManager] - Enqueued scene : {0}", name.c_str()); } @@ -72,7 +72,7 @@ namespace Lumos void AddFileToLoadList(const std::string& filePath) { - m_SceneFilePathsToLoad.Emplace(filePath); + m_SceneFilePathsToLoad.PushBack(filePath); } void LoadCurrentList(); diff --git a/Lumos/Source/Lumos/Scene/SerialisationImplementation.cpp b/Lumos/Source/Lumos/Scene/SerialisationImplementation.cpp new file mode 100644 index 00000000..6a97e041 --- /dev/null +++ b/Lumos/Source/Lumos/Scene/SerialisationImplementation.cpp @@ -0,0 +1,35 @@ +#include "Precompiled.h" +#include "SerialisationImplementation.h" +#include + +namespace Lumos +{ + void SerialialiseAssetRegistry(const String8& path, const AssetRegistry& registry) + { + std::stringstream storage; + { + // output finishes flushing its contents when it goes out of scope + cereal::JSONOutputArchive output { storage }; + output(registry); + } + + LUMOS_LOG_INFO("Serialising Asset Registry {0}", (const char*)path.str); + FileSystem::WriteTextFile((const char*)path.str, storage.str()); + } + + void DeserialialiseAssetRegistry(const String8& path, AssetRegistry& registry) + { + std::string data = FileSystem::ReadTextFile((const char*)path.str); + std::istringstream istr; + istr.str(data); + try + { + cereal::JSONInputArchive input(istr); + input(registry); + } + catch(...) + { + LUMOS_LOG_WARN("Failed to load asset registry {0}", (const char*)path.str); + } + } +} diff --git a/Lumos/Source/Lumos/Scene/SerialisationImplementation.h b/Lumos/Source/Lumos/Scene/SerialisationImplementation.h new file mode 100644 index 00000000..cafba2c4 --- /dev/null +++ b/Lumos/Source/Lumos/Scene/SerialisationImplementation.h @@ -0,0 +1,388 @@ +#pragma once +#include "Audio/AudioManager.h" +#include "Audio/SoundNode.h" +#include "Scene/Scene.h" +#include "Scene/Serialisation.h" +#include "Maths/MathsSerialisation.h" +#include "Maths/Transform.h" +#include "Graphics/Material.h" +#include "Graphics/Sprite.h" +#include "Graphics/AnimatedSprite.h" +#include "Utilities/AssetManager.h" +#include "Utilities/StringUtilities.h" + +#include +#include + +namespace Lumos +{ +#ifndef SERIALISATION_INCLUDE_ONL + + template + void save(Archive& archive, const Listener& listener) + { + archive(cereal::make_nvp("enabled", listener.m_Enabled)); + } + + template + void load(Archive& archive, Listener& listener) + { + archive(cereal::make_nvp("enabled", listener.m_Enabled)); + } + + template + void save(Archive& archive, const SoundNode& node) + { + std::string path; + FileSystem::Get().AbsolutePathToFileSystem(node.m_Sound ? node.m_Sound->GetFilePath() : "", path); + + archive(cereal::make_nvp("Position", node.m_Position), cereal::make_nvp("Radius", node.m_Radius), cereal::make_nvp("Pitch", node.m_Pitch), cereal::make_nvp("Volume", node.m_Volume), cereal::make_nvp("Velocity", node.m_Velocity), cereal::make_nvp("Looping", node.m_IsLooping), cereal::make_nvp("Paused", node.m_Paused), cereal::make_nvp("ReferenceDistance", node.m_ReferenceDistance), cereal::make_nvp("Global", node.m_IsGlobal), cereal::make_nvp("TimeLeft", node.m_TimeLeft), cereal::make_nvp("Stationary", node.m_Stationary), + cereal::make_nvp("SoundNodePath", path), cereal::make_nvp("RollOffFactor", node.m_RollOffFactor)); + } + + template + void load(Archive& archive, SoundNode& node) + { + std::string soundFilePath; + archive(cereal::make_nvp("Position", node.m_Position), cereal::make_nvp("Radius", node.m_Radius), cereal::make_nvp("Pitch", node.m_Pitch), cereal::make_nvp("Volume", node.m_Volume), cereal::make_nvp("Velocity", node.m_Velocity), cereal::make_nvp("Looping", node.m_IsLooping), cereal::make_nvp("Paused", node.m_Paused), cereal::make_nvp("ReferenceDistance", node.m_ReferenceDistance), cereal::make_nvp("Global", node.m_IsGlobal), cereal::make_nvp("TimeLeft", 0.0f), cereal::make_nvp("Stationary", node.m_Stationary), + cereal::make_nvp("SoundNodePath", soundFilePath), cereal::make_nvp("RollOffFactor", node.m_RollOffFactor)); + + if(!soundFilePath.empty()) + { + node.SetSound(Sound::Create(soundFilePath, StringUtilities::GetFilePathExtension(soundFilePath))); + } + } + + template + void save(Archive& archive, const Scene& scene) + { + archive(cereal::make_nvp("Version", SceneSerialisationVersion)); + archive(cereal::make_nvp("Scene Name", scene.m_SceneName)); + + archive(cereal::make_nvp("PhysicsEnabled2D", scene.m_Settings.PhysicsEnabled2D), cereal::make_nvp("PhysicsEnabled3D", scene.m_Settings.PhysicsEnabled3D), cereal::make_nvp("AudioEnabled", scene.m_Settings.AudioEnabled), cereal::make_nvp("Renderer2DEnabled", scene.m_Settings.RenderSettings.Renderer2DEnabled), + cereal::make_nvp("Renderer3DEnabled", scene.m_Settings.RenderSettings.Renderer3DEnabled), cereal::make_nvp("DebugRenderEnabled", scene.m_Settings.RenderSettings.DebugRenderEnabled), cereal::make_nvp("SkyboxRenderEnabled", scene.m_Settings.RenderSettings.SkyboxRenderEnabled), cereal::make_nvp("ShadowsEnabled", scene.m_Settings.RenderSettings.ShadowsEnabled)); + archive(cereal::make_nvp("Exposure", scene.m_Settings.RenderSettings.m_Exposure), cereal::make_nvp("ToneMap", scene.m_Settings.RenderSettings.m_ToneMapIndex)); + + archive(cereal::make_nvp("BloomIntensity", scene.m_Settings.RenderSettings.m_BloomIntensity), cereal::make_nvp("BloomKnee", scene.m_Settings.RenderSettings.BloomKnee), cereal::make_nvp("BloomThreshold", scene.m_Settings.RenderSettings.BloomThreshold), + cereal::make_nvp("BloomUpsampleScale", scene.m_Settings.RenderSettings.BloomUpsampleScale)); + + archive(cereal::make_nvp("FXAAEnabled", scene.m_Settings.RenderSettings.FXAAEnabled), cereal::make_nvp("DebandingEnabled", scene.m_Settings.RenderSettings.DebandingEnabled), cereal::make_nvp("ChromaticAberationEnabled", scene.m_Settings.RenderSettings.ChromaticAberationEnabled), cereal::make_nvp("EyeAdaptation", scene.m_Settings.RenderSettings.EyeAdaptation), cereal::make_nvp("SSAOEnabled", scene.m_Settings.RenderSettings.SSAOEnabled), cereal::make_nvp("BloomEnabled", scene.m_Settings.RenderSettings.BloomEnabled), cereal::make_nvp("FilmicGrainEnabled", scene.m_Settings.RenderSettings.FilmicGrainEnabled), cereal::make_nvp("DepthOfFieldEnabled", scene.m_Settings.RenderSettings.DepthOfFieldEnabled), cereal::make_nvp("MotionBlurEnabled", scene.m_Settings.RenderSettings.MotionBlurEnabled)); + + archive(cereal::make_nvp("DepthOFFieldEnabled", scene.m_Settings.RenderSettings.DepthOfFieldEnabled), cereal::make_nvp("DepthOfFieldStrength", scene.m_Settings.RenderSettings.DepthOfFieldStrength), cereal::make_nvp("DepthOfFieldDistance", scene.m_Settings.RenderSettings.DepthOfFieldDistance)); + + archive(scene.m_Settings.RenderSettings.Brightness, scene.m_Settings.RenderSettings.Saturation, scene.m_Settings.RenderSettings.Contrast); + + archive(scene.m_Settings.RenderSettings.SharpenEnabled); + } + + template + void load(Archive& archive, Scene& scene) + { + archive(cereal::make_nvp("Version", scene.m_SceneSerialisationVersion)); + archive(cereal::make_nvp("Scene Name", scene.m_SceneName)); + + Serialisation::CurrentSceneVersion = scene.m_SceneSerialisationVersion; + + if(scene.m_SceneSerialisationVersion > 7) + { + archive(cereal::make_nvp("PhysicsEnabled2D", scene.m_Settings.PhysicsEnabled2D), cereal::make_nvp("PhysicsEnabled3D", scene.m_Settings.PhysicsEnabled3D), cereal::make_nvp("AudioEnabled", scene.m_Settings.AudioEnabled), cereal::make_nvp("Renderer2DEnabled", scene.m_Settings.RenderSettings.Renderer2DEnabled), + cereal::make_nvp("Renderer3DEnabled", scene.m_Settings.RenderSettings.Renderer3DEnabled), cereal::make_nvp("DebugRenderEnabled", scene.m_Settings.RenderSettings.DebugRenderEnabled), cereal::make_nvp("SkyboxRenderEnabled", scene.m_Settings.RenderSettings.SkyboxRenderEnabled), cereal::make_nvp("ShadowsEnabled", scene.m_Settings.RenderSettings.ShadowsEnabled)); + } + if(scene.m_SceneSerialisationVersion > 9) + { + archive(cereal::make_nvp("Exposure", scene.m_Settings.RenderSettings.m_Exposure), cereal::make_nvp("ToneMap", scene.m_Settings.RenderSettings.m_ToneMapIndex)); + } + + if(Serialisation::CurrentSceneVersion > 11) + { + archive(cereal::make_nvp("BloomIntensity", scene.m_Settings.RenderSettings.m_BloomIntensity), cereal::make_nvp("BloomKnee", scene.m_Settings.RenderSettings.BloomKnee), cereal::make_nvp("BloomThreshold", scene.m_Settings.RenderSettings.BloomThreshold), + cereal::make_nvp("BloomUpsampleScale", scene.m_Settings.RenderSettings.BloomUpsampleScale)); + } + if(Serialisation::CurrentSceneVersion > 12) + { + archive(cereal::make_nvp("FXAAEnabled", scene.m_Settings.RenderSettings.FXAAEnabled), cereal::make_nvp("DebandingEnabled", scene.m_Settings.RenderSettings.DebandingEnabled), cereal::make_nvp("ChromaticAberationEnabled", scene.m_Settings.RenderSettings.ChromaticAberationEnabled), cereal::make_nvp("EyeAdaptation", scene.m_Settings.RenderSettings.EyeAdaptation), cereal::make_nvp("SSAOEnabled", scene.m_Settings.RenderSettings.SSAOEnabled), cereal::make_nvp("BloomEnabled", scene.m_Settings.RenderSettings.BloomEnabled), cereal::make_nvp("FilmicGrainEnabled", scene.m_Settings.RenderSettings.FilmicGrainEnabled), cereal::make_nvp("DepthOfFieldEnabled", scene.m_Settings.RenderSettings.DepthOfFieldEnabled), cereal::make_nvp("MotionBlurEnabled", scene.m_Settings.RenderSettings.MotionBlurEnabled)); + } + + if(Serialisation::CurrentSceneVersion > 15) + { + archive(cereal::make_nvp("DepthOfFieldEnabled", scene.m_Settings.RenderSettings.DepthOfFieldEnabled), cereal::make_nvp("DepthOfFieldStrength", scene.m_Settings.RenderSettings.DepthOfFieldStrength), cereal::make_nvp("DepthOfFieldDistance", scene.m_Settings.RenderSettings.DepthOfFieldDistance)); + } + + if(Serialisation::CurrentSceneVersion > 16) + archive(scene.m_Settings.RenderSettings.Brightness, scene.m_Settings.RenderSettings.Saturation, scene.m_Settings.RenderSettings.Contrast); + + if(Serialisation::CurrentSceneVersion > 18) + archive(scene.m_Settings.RenderSettings.SharpenEnabled); + } + + template + void save(Archive& archive, const UUID& ID) + { + archive(ID.m_UUID); + } + + template + void load(Archive& archive, UUID& ID) + { + archive(ID.m_UUID); + } + + static const int AssetRegistrySerialisationVersion = 2; + template + void save(Archive& archive, const AssetRegistry& registry) + { + std::vector> elems(registry.m_NameMap.begin(), registry.m_NameMap.end()); + std::sort(elems.begin(), elems.end(), [](std::pair& a, std::pair& b) + { return a.second < b.second; }); + + archive(cereal::make_nvp("Version", AssetRegistrySerialisationVersion)); + archive(cereal::make_nvp("Count", (int)elems.size())); + + for(auto& entry : elems) + archive(cereal::make_nvp("Name", entry.first), cereal::make_nvp("UUID", (uint64_t)entry.second), cereal::make_nvp("AssetType", registry.Contains(entry.second) ? (uint16_t)registry.Get(entry.second).Type : 0)); + } + + template + void load(Archive& archive, AssetRegistry& registry) + { + std::vector> elems; + + int version; + int count; + archive(cereal::make_nvp("Version", version)); + archive(cereal::make_nvp("Count", count)); + + auto& nameMap = registry.m_NameMap; + for(int i = 0; i < count; i++) + { + std::string key; + uint64_t value; + uint16_t type = 0; + if(version <= 1) + archive(cereal::make_nvp("Name", key), cereal::make_nvp("UUID", value)); + else + archive(cereal::make_nvp("Name", key), cereal::make_nvp("UUID", value), cereal::make_nvp("AssetType", type)); + nameMap[key] = (UUID)value; + + if (type) + { + AssetMetaData metaData; + metaData.IsDataLoaded = false; + metaData.Type = (AssetType)type; + registry.m_AssetRegistry[(UUID)value] = metaData; + } + } + } + + namespace Graphics + { + template + void save(Archive& archive, const Graphics::Material& material) + { + std::string shaderPath = ""; + std::string albedoFilePath = material.m_PBRMaterialTextures.albedo ? FileSystem::Get().AbsolutePathToFileSystem(material.m_PBRMaterialTextures.albedo->GetFilepath()) : ""; + std::string normalFilePath = material.m_PBRMaterialTextures.normal ? FileSystem::Get().AbsolutePathToFileSystem(material.m_PBRMaterialTextures.normal->GetFilepath()) : ""; + std::string metallicFilePath = material.m_PBRMaterialTextures.metallic ? FileSystem::Get().AbsolutePathToFileSystem(material.m_PBRMaterialTextures.metallic->GetFilepath()) : ""; + std::string roughnessFilePath = material.m_PBRMaterialTextures.roughness ? FileSystem::Get().AbsolutePathToFileSystem(material.m_PBRMaterialTextures.roughness->GetFilepath()) : ""; + std::string emissiveFilePath = material.m_PBRMaterialTextures.emissive ? FileSystem::Get().AbsolutePathToFileSystem(material.m_PBRMaterialTextures.emissive->GetFilepath()) : ""; + std::string aoFilePath = material.m_PBRMaterialTextures.ao ? FileSystem::Get().AbsolutePathToFileSystem(material.m_PBRMaterialTextures.ao->GetFilepath()) : ""; + + if(material.m_Shader) + { + std::string path = material.m_Shader->GetFilePath() + material.m_Shader->GetName(); + FileSystem::Get().AbsolutePathToFileSystem(path, shaderPath); + } + + archive(cereal::make_nvp("Albedo", albedoFilePath), + cereal::make_nvp("Normal", normalFilePath), + cereal::make_nvp("Metallic", metallicFilePath), + cereal::make_nvp("Roughness", roughnessFilePath), + cereal::make_nvp("Ao", aoFilePath), + cereal::make_nvp("Emissive", emissiveFilePath), + cereal::make_nvp("albedoColour", material.m_MaterialProperties->albedoColour), + cereal::make_nvp("roughnessValue", material.m_MaterialProperties->roughness), + cereal::make_nvp("metallicValue", material.m_MaterialProperties->metallic), + cereal::make_nvp("emissiveValue", material.m_MaterialProperties->emissive), + cereal::make_nvp("albedoMapFactor", material.m_MaterialProperties->albedoMapFactor), + cereal::make_nvp("metallicMapFactor", material.m_MaterialProperties->metallicMapFactor), + cereal::make_nvp("roughnessMapFactor", material.m_MaterialProperties->roughnessMapFactor), + cereal::make_nvp("normalMapFactor", material.m_MaterialProperties->normalMapFactor), + cereal::make_nvp("aoMapFactor", material.m_MaterialProperties->occlusionMapFactor), + cereal::make_nvp("emissiveMapFactor", material.m_MaterialProperties->emissiveMapFactor), + cereal::make_nvp("alphaCutOff", material.m_MaterialProperties->alphaCutoff), + cereal::make_nvp("workflow", material.m_MaterialProperties->workflow), + cereal::make_nvp("shader", shaderPath)); + + archive(cereal::make_nvp("Reflectance", material.m_MaterialProperties->reflectance)); + } + + template + void load(Archive& archive, Graphics::Material& material) + { + std::string albedoFilePath; + std::string normalFilePath; + std::string roughnessFilePath; + std::string metallicFilePath; + std::string emissiveFilePath; + std::string aoFilePath; + std::string shaderFilePath; + + constexpr bool loadOldMaterial = false; + + if constexpr(loadOldMaterial) + { + glm::vec4 roughness, metallic, emissive; + archive(cereal::make_nvp("Albedo", albedoFilePath), + cereal::make_nvp("Normal", normalFilePath), + cereal::make_nvp("Metallic", metallicFilePath), + cereal::make_nvp("Roughness", roughnessFilePath), + cereal::make_nvp("Ao", aoFilePath), + cereal::make_nvp("Emissive", emissiveFilePath), + cereal::make_nvp("albedoColour", material.m_MaterialProperties->albedoColour), + cereal::make_nvp("roughnessColour", roughness), + cereal::make_nvp("metallicColour", metallic), + cereal::make_nvp("emissiveColour", emissive), + cereal::make_nvp("usingAlbedoMap", material.m_MaterialProperties->albedoMapFactor), + cereal::make_nvp("usingMetallicMap", material.m_MaterialProperties->metallicMapFactor), + cereal::make_nvp("usingRoughnessMap", material.m_MaterialProperties->roughnessMapFactor), + cereal::make_nvp("usingNormalMap", material.m_MaterialProperties->normalMapFactor), + cereal::make_nvp("usingAOMap", material.m_MaterialProperties->occlusionMapFactor), + cereal::make_nvp("usingEmissiveMap", material.m_MaterialProperties->emissiveMapFactor), + cereal::make_nvp("workflow", material.m_MaterialProperties->workflow), + cereal::make_nvp("shader", shaderFilePath)); + + material.m_MaterialProperties->emissive = emissive.x; + material.m_MaterialProperties->metallic = metallic.x; + material.m_MaterialProperties->roughness = roughness.x; + } + else + { + archive(cereal::make_nvp("Albedo", albedoFilePath), + cereal::make_nvp("Normal", normalFilePath), + cereal::make_nvp("Metallic", metallicFilePath), + cereal::make_nvp("Roughness", roughnessFilePath), + cereal::make_nvp("Ao", aoFilePath), + cereal::make_nvp("Emissive", emissiveFilePath), + cereal::make_nvp("albedoColour", material.m_MaterialProperties->albedoColour), + cereal::make_nvp("roughnessValue", material.m_MaterialProperties->roughness), + cereal::make_nvp("metallicValue", material.m_MaterialProperties->metallic), + cereal::make_nvp("emissiveValue", material.m_MaterialProperties->emissive), + cereal::make_nvp("albedoMapFactor", material.m_MaterialProperties->albedoMapFactor), + cereal::make_nvp("metallicMapFactor", material.m_MaterialProperties->metallicMapFactor), + cereal::make_nvp("roughnessMapFactor", material.m_MaterialProperties->roughnessMapFactor), + cereal::make_nvp("normalMapFactor", material.m_MaterialProperties->normalMapFactor), + cereal::make_nvp("aoMapFactor", material.m_MaterialProperties->occlusionMapFactor), + cereal::make_nvp("emissiveMapFactor", material.m_MaterialProperties->emissiveMapFactor), + cereal::make_nvp("alphaCutOff", material.m_MaterialProperties->alphaCutoff), + cereal::make_nvp("workflow", material.m_MaterialProperties->workflow), + cereal::make_nvp("shader", shaderFilePath)); + + if(Serialisation::CurrentSceneVersion > 19) + archive(cereal::make_nvp("Reflectance", material.m_MaterialProperties->reflectance)); + } + + // if(!shaderFilePath.empty()) + // SetShader(shaderFilePath); + // TODO: Support Custom Shaders; + material.m_Shader = nullptr; + + if(!albedoFilePath.empty()) + material.m_PBRMaterialTextures.albedo = SharedPtr(Graphics::Texture2D::CreateFromFile("albedo", albedoFilePath)); + if(!normalFilePath.empty()) + material.m_PBRMaterialTextures.normal = SharedPtr(Graphics::Texture2D::CreateFromFile("roughness", normalFilePath)); + if(!metallicFilePath.empty()) + material.m_PBRMaterialTextures.metallic = SharedPtr(Graphics::Texture2D::CreateFromFile("metallic", metallicFilePath)); + if(!roughnessFilePath.empty()) + material.m_PBRMaterialTextures.roughness = SharedPtr(Graphics::Texture2D::CreateFromFile("roughness", roughnessFilePath)); + if(!emissiveFilePath.empty()) + material.m_PBRMaterialTextures.emissive = SharedPtr(Graphics::Texture2D::CreateFromFile("emissive", emissiveFilePath)); + if(!aoFilePath.empty()) + material.m_PBRMaterialTextures.ao = SharedPtr(Graphics::Texture2D::CreateFromFile("ao", aoFilePath)); + } + + template + void save(Archive& archive, const Graphics::Sprite& sprite) + { + std::string newPath = ""; + if(sprite.m_Texture) + { + FileSystem::Get().AbsolutePathToFileSystem(sprite.m_Texture->GetFilepath(), newPath); + } + + archive(cereal::make_nvp("TexturePath", newPath), + cereal::make_nvp("Position", sprite.m_Position), + cereal::make_nvp("Scale", sprite.m_Scale), + cereal::make_nvp("Colour", sprite.m_Colour)); + + archive(sprite.UsingSpriteSheet, sprite.SpriteSheetTileSize); + } + + template + void load(Archive& archive, Graphics::Sprite& sprite) + { + std::string textureFilePath; + archive(cereal::make_nvp("TexturePath", textureFilePath), + cereal::make_nvp("Position", sprite.m_Position), + cereal::make_nvp("Scale", sprite.m_Scale), + cereal::make_nvp("Colour", sprite.m_Colour)); + + if(!textureFilePath.empty()) + sprite.m_Texture = SharedPtr(Graphics::Texture2D::CreateFromFile("sprite", textureFilePath)); + + if(Serialisation::CurrentSceneVersion > 21) + archive(sprite.UsingSpriteSheet, sprite.SpriteSheetTileSize); + } + + template + void save(Archive& archive, const Graphics::AnimatedSprite& sprite) + { + archive(cereal::make_nvp("TexturePath", sprite.m_Texture ? sprite.m_Texture->GetFilepath() : ""), + cereal::make_nvp("Position", sprite.m_Position), + cereal::make_nvp("Scale", sprite.m_Scale), + cereal::make_nvp("Colour", sprite.m_Colour), + cereal::make_nvp("AnimationFrames", sprite.m_AnimationStates), + cereal::make_nvp("State", sprite.m_State)); + archive(sprite.SpriteSheetTileSize); + } + + template + void load(Archive& archive, Graphics::AnimatedSprite& sprite) + { + std::string textureFilePath; + archive(cereal::make_nvp("TexturePath", textureFilePath), + cereal::make_nvp("Position", sprite.m_Position), + cereal::make_nvp("Scale", sprite.m_Scale), + cereal::make_nvp("Colour", sprite.m_Colour), + cereal::make_nvp("AnimationFrames", sprite.m_AnimationStates), + cereal::make_nvp("State", sprite.m_State)); + + if(!textureFilePath.empty()) + sprite.m_Texture = SharedPtr(Graphics::Texture2D::CreateFromFile("sprite", textureFilePath)); + + if(Serialisation::CurrentSceneVersion > 21) + archive(sprite.SpriteSheetTileSize); + + sprite.SetState(sprite.m_State); + } + } + + namespace Maths + { + template + void save(Archive& archive, const Maths::Transform& transform) + { + archive(cereal::make_nvp("Position", transform.m_LocalPosition), cereal::make_nvp("Rotation", transform.m_LocalOrientation), cereal::make_nvp("Scale", transform.m_LocalScale)); + } + + template + void load(Archive& archive, Maths::Transform& transform) + { + archive(cereal::make_nvp("Position", transform.m_LocalPosition), cereal::make_nvp("Rotation", transform.m_LocalOrientation), cereal::make_nvp("Scale", transform.m_LocalScale)); + } + + } +#endif + + void SerialialiseAssetRegistry(const String8& path, const AssetRegistry& registry); + void DeserialialiseAssetRegistry(const String8& path, AssetRegistry& registry); +} diff --git a/Lumos/Source/Lumos/Scripting/Lua/LuaManager.cpp b/Lumos/Source/Lumos/Scripting/Lua/LuaManager.cpp index 5f4fca42..dd7e5278 100644 --- a/Lumos/Source/Lumos/Scripting/Lua/LuaManager.cpp +++ b/Lumos/Source/Lumos/Scripting/Lua/LuaManager.cpp @@ -249,6 +249,9 @@ namespace Lumos // std::string test = state["package"]["path"]; // state["package"]["path"] = std::string(package_path.string()) + test; + m_State->set("registry", ®istry); + m_State->set("scene", scene); + for(auto entity : view) { auto& luaScript = registry.get(entity); @@ -276,6 +279,11 @@ namespace Lumos } } + void LuaManager::CollectGarbage() + { + m_State->collect_garbage(); + } + void LuaManager::OnNewProject(const std::string& projectPath) { auto& state = *m_State; diff --git a/Lumos/Source/Lumos/Scripting/Lua/LuaManager.h b/Lumos/Source/Lumos/Scripting/Lua/LuaManager.h index 82dfa0a7..c4f60bd0 100644 --- a/Lumos/Source/Lumos/Scripting/Lua/LuaManager.h +++ b/Lumos/Source/Lumos/Scripting/Lua/LuaManager.h @@ -23,6 +23,8 @@ namespace Lumos void OnInit(Scene* scene); void OnUpdate(Scene* scene); + void CollectGarbage(); + void OnNewProject(const std::string& projectPath); void BindECSLua(sol::state& state); @@ -38,9 +40,9 @@ namespace Lumos return *m_State; } + private: static std::vector s_Identifiers; - private: sol::state* m_State; }; } diff --git a/Lumos/Source/Lumos/Scripting/Lua/LuaScriptComponent.h b/Lumos/Source/Lumos/Scripting/Lua/LuaScriptComponent.h index b379abfc..0f68e029 100644 --- a/Lumos/Source/Lumos/Scripting/Lua/LuaScriptComponent.h +++ b/Lumos/Source/Lumos/Scripting/Lua/LuaScriptComponent.h @@ -5,6 +5,7 @@ #include #include +#include namespace Lumos { @@ -50,7 +51,7 @@ namespace Lumos m_FileName = path; } - const std::map& GetErrors() const + const std::unordered_map& GetErrors() const { return m_Errors; } @@ -84,7 +85,7 @@ namespace Lumos private: Scene* m_Scene = nullptr; std::string m_FileName; - std::map m_Errors; + std::unordered_map m_Errors; SharedPtr m_Env; SharedPtr m_OnInitFunc; diff --git a/Lumos/Source/Lumos/Utilities/AssetManager.cpp b/Lumos/Source/Lumos/Utilities/AssetManager.cpp index 31feb644..d4c2e97b 100644 --- a/Lumos/Source/Lumos/Utilities/AssetManager.cpp +++ b/Lumos/Source/Lumos/Utilities/AssetManager.cpp @@ -1,6 +1,7 @@ #include "Precompiled.h" #include "AssetManager.h" #include "Core/Application.h" +#include namespace Lumos { @@ -22,40 +23,62 @@ namespace Lumos { tex->Load(imageLoadDesc.outWidth, imageLoadDesc.outHeight, imageLoadDesc.outPixels, desc); }); } - TextureLibrary::~TextureLibrary() + bool AssetManager::LoadTexture(const std::string& filePath, SharedPtr& texture, bool thread) { + texture = SharedPtr(Graphics::Texture2D::Create({}, 1, 1)); + if(thread) + m_Futures.push_back(std::async(std::launch::async, &LoadTexture2D, texture.get(), filePath)); + else + LoadTexture2D(texture.get(), filePath); + + AddAsset(filePath, texture); + return true; } - bool TextureLibrary::Load(const std::string& filePath, SharedPtr& texture) + SharedPtr AssetManager::LoadTextureAsset(const std::string& filePath, bool thread) { - texture = SharedPtr(Graphics::Texture2D::Create({}, 1, 1)); - m_Futures.push_back(std::async(std::launch::async, &LoadTexture2D, texture.get(), filePath)); - return true; + SharedPtr texture; + LoadTexture(filePath, texture, thread); + return texture; + } + + static std::mutex s_AssetRegistryMutex; + + AssetMetaData& AssetRegistry::operator[](UUID handle) + { + std::scoped_lock lock(s_AssetRegistryMutex); + return m_AssetRegistry[handle]; } - void TextureLibrary::Destroy() + const AssetMetaData& AssetRegistry::Get(UUID handle) const { - m_Futures.clear(); - typename MapType::iterator itr = m_NameResourceMap.begin(); + std::scoped_lock lock(s_AssetRegistryMutex); - if(m_ReleaseFunc) - { - while(itr != m_NameResourceMap.end()) - { - m_ReleaseFunc((itr->second.data)); - ++itr; - } - } - m_NameResourceMap.clear(); + LUMOS_ASSERT(m_AssetRegistry.find(handle) != m_AssetRegistry.end()); + return m_AssetRegistry.at(handle); } - ModelLibrary::~ModelLibrary() + AssetMetaData& AssetRegistry::Get(UUID handle) { + std::scoped_lock lock(s_AssetRegistryMutex); + return m_AssetRegistry[handle]; } - bool ModelLibrary::Load(const std::string& filePath, SharedPtr& model) + bool AssetRegistry::Contains(UUID handle) const { - model = CreateSharedPtr(filePath); - return true; + std::scoped_lock lock(s_AssetRegistryMutex); + return m_AssetRegistry.find(handle) != m_AssetRegistry.end(); + } + + size_t AssetRegistry::Remove(UUID handle) + { + std::scoped_lock lock(s_AssetRegistryMutex); + return m_AssetRegistry.erase(handle); + } + + void AssetRegistry::Clear() + { + std::scoped_lock lock(s_AssetRegistryMutex); + m_AssetRegistry.clear(); } } diff --git a/Lumos/Source/Lumos/Utilities/AssetManager.h b/Lumos/Source/Lumos/Utilities/AssetManager.h index f88c5a25..ee7e11a4 100644 --- a/Lumos/Source/Lumos/Utilities/AssetManager.h +++ b/Lumos/Source/Lumos/Utilities/AssetManager.h @@ -6,7 +6,8 @@ #include "Utilities/LoadImage.h" #include "Graphics/Font.h" #include "Graphics/Model.h" -#include +#include "Core/Asset.h" +#include "Utilities/CombineHash.h" namespace Lumos { @@ -15,232 +16,263 @@ namespace Lumos class Model; } - template - class ResourceManager + struct AssetMetaData { + float timeSinceReload = 0.0f; + float lastAccessed = 0.0f; + SharedPtr data = nullptr; + bool onDisk = false; + bool Expire = true; + AssetType Type = AssetType::Unkown; + bool IsDataLoaded = false; + bool IsMemoryAsset = false; + uint64_t ParameterCache; + }; + + class AssetRegistry + { + template + friend void save(Archive& archive, const AssetRegistry& registry); + + template + friend void load(Archive& archive, AssetRegistry& registry); + public: - typedef T Type; - typedef std::string IDType; - typedef SharedPtr ResourceHandle; + AssetMetaData& operator[](const UUID handle); + AssetMetaData& Get(const UUID handle); + const AssetMetaData& Get(const UUID handle) const; - struct Resource + void Update(float elapsedSeconds) { - float timeSinceReload = 0.0f; - float lastAccessed = 0.0f; - ResourceHandle data; - bool onDisk = false; - }; + static UUID keysToDelete[256]; + std::size_t keysToDeleteCount = 0; + + for(auto&& [key, value] : m_AssetRegistry) + { + if(value.Expire && value.IsDataLoaded && value.data.GetCounter()->GetReferenceCount() == 1 && m_ExpirationTime < (elapsedSeconds - value.lastAccessed)) + { + keysToDelete[keysToDeleteCount] = key; + keysToDeleteCount++; + } + } - typedef std::unordered_map MapType; + for(std::size_t i = 0; i < keysToDeleteCount; i++) + { + m_AssetRegistry.erase(keysToDelete[i]); + } + } + size_t Count() const { return m_AssetRegistry.size(); } + bool Contains(const UUID handle) const; + size_t Remove(const UUID handle); + void Clear(); - typedef std::function LoadFunc; - typedef std::function ReleaseFunc; - typedef std::function ReloadFunc; - typedef std::function GetIdFunc; + auto begin() { return m_AssetRegistry.begin(); } + auto end() { return m_AssetRegistry.end(); } + auto begin() const { return m_AssetRegistry.cbegin(); } + auto end() const { return m_AssetRegistry.cend(); } - ResourceHandle GetResource(const IDType& name) + void AddName(const std::string& name, UUID ID) { - typename MapType::iterator itr = m_NameResourceMap.find(name); - if(itr != m_NameResourceMap.end()) + m_NameMap.emplace(name, ID); +#ifndef LUMOS_PRODUCTION + m_UUIDNameMap.emplace(ID, name); +#endif + } + bool GetID(const std::string& name, UUID& ID) + { + if(m_NameMap.find(name) != m_NameMap.end()) { - itr->second.lastAccessed = (float)Engine::GetTimeStep().GetElapsedSeconds(); - return itr->second.data; + ID = m_NameMap[name]; + return true; } - ResourceHandle resourceData; - if(!m_LoadFunc(name, resourceData)) + return false; + } + +#ifndef LUMOS_PRODUCTION + bool GetName(UUID ID, std::string& name) + { + if(m_UUIDNameMap.find(ID) != m_UUIDNameMap.end()) { - LUMOS_LOG_ERROR("Resource Manager could not load resource name {0} of type {1}", name, typeid(T).name()); - return ResourceHandle(nullptr); + name = m_UUIDNameMap[ID]; + return true; } - Resource newResource; - newResource.data = resourceData; - newResource.timeSinceReload = 0; - newResource.onDisk = true; - newResource.lastAccessed = (float)Engine::GetTimeStep().GetElapsedSeconds(); + return false; + } +#endif - m_NameResourceMap.emplace(name, newResource); + private: + std::unordered_map m_AssetRegistry; + std::unordered_map m_NameMap; +#ifndef LUMOS_PRODUCTION + std::unordered_map m_UUIDNameMap; // Debug Only +#endif - return resourceData; + float m_ExpirationTime = 3.0f; + }; + + class AssetManager + { + public: + AssetManager() + { + m_Arena = ArenaAlloc(Megabytes(4)); } - ResourceHandle GetResource(const ResourceHandle& data) + ~AssetManager() { - IDType newId = m_GetIdFunc(data); + ArenaRelease(m_Arena); + } - typename MapType::iterator itr = m_NameResourceMap.find(newId); - if(itr == m_NameResourceMap.end()) + SharedPtr GetAsset(UUID ID) + { + if(m_AssetRegistry.Contains(ID)) { - ResourceHandle resourceData = data; + AssetMetaData& metaData = m_AssetRegistry[ID]; + metaData.lastAccessed = (float)Engine::GetTimeStep().GetElapsedSeconds(); + return metaData.data; + } - Resource newResource; - newResource.data = resourceData; - newResource.timeSinceReload = 0; - newResource.onDisk = false; - m_NameResourceMap.emplace(newId, newResource); + LUMOS_LOG_WARN("Asset not found {0}", ID); + return nullptr; + } - return resourceData; - } + AssetMetaData& AddAsset(const std::string& name, SharedPtr data, bool keepUnreferenced = false) + { + UUID ID = UUID(); + m_AssetRegistry.GetID(name, ID); - return itr->second.data; + AssetMetaData& metaData = AddAsset(ID, data, keepUnreferenced); + m_AssetRegistry.AddName(name, ID); + return metaData; } - void AddResource(const IDType& name, ResourceHandle data) + AssetMetaData& AddAsset(UUID name, SharedPtr data, bool keepUnreferenced = false) { - typename MapType::iterator itr = m_NameResourceMap.find(name); - if(itr != m_NameResourceMap.end()) + if(m_AssetRegistry.Contains(name)) { - itr->second.lastAccessed = (float)Engine::GetTimeStep().GetElapsedSeconds(); - itr->second.data = data; + AssetMetaData& metaData = m_AssetRegistry[name]; + metaData.lastAccessed = (float)Engine::GetTimeStep().GetElapsedSeconds(); + metaData.data = data; + metaData.Expire = !keepUnreferenced; + metaData.Type = data ? data->GetAssetType() : AssetType::Unkown; + metaData.IsDataLoaded = data ? true : false; + return metaData; } - Resource newResource; + AssetMetaData newResource; newResource.data = data; newResource.timeSinceReload = 0; newResource.onDisk = true; newResource.lastAccessed = (float)Engine::GetTimeStep().GetElapsedSeconds(); + newResource.Type = data->GetAssetType(); + newResource.Expire = !keepUnreferenced; + newResource.IsDataLoaded = data ? true : false; - m_NameResourceMap.emplace(name, newResource); - } + m_AssetRegistry[name] = newResource; - virtual void Destroy() - { - typename MapType::iterator itr = m_NameResourceMap.begin(); - - if(m_ReleaseFunc) - { - while(itr != m_NameResourceMap.end()) - { - m_ReleaseFunc((itr->second.data)); - ++itr; - } - } - m_NameResourceMap.clear(); + return m_AssetRegistry[name]; } - void Update(const float elapsedSeconds) + AssetMetaData GetAsset(const std::string& name) { - typename MapType::iterator itr = m_NameResourceMap.begin(); - - static IDType keysToDelete[256]; - std::size_t keysToDeleteCount = 0; - - for(auto&& [key, value] : m_NameResourceMap) + UUID ID; + if(m_AssetRegistry.GetID(name, ID)) { - if(value.data.GetCounter()->GetReferenceCount() == 1 && m_ExpirationTime < (elapsedSeconds - itr->second.lastAccessed)) + if (m_AssetRegistry[ID].IsDataLoaded) + return m_AssetRegistry[ID]; + else { - keysToDelete[keysToDeleteCount] = key; - keysToDeleteCount++; + return AssetMetaData(); } } - for(std::size_t i = 0; i < keysToDeleteCount; i++) - { - m_NameResourceMap.erase(keysToDelete[i]); - } + return AssetMetaData(); } - bool ReloadResources() + SharedPtr GetAssetData(const std::string& name) { - typename MapType::iterator itr = m_NameResourceMap.begin(); - while(itr != m_NameResourceMap.end()) - { - itr->second.timeSinceReload = 0; - if(!m_ReloadFunc(itr->first, (itr->second.data))) - { - LUMOS_LOG_ERROR("Resource Manager could not reload resource name {0} of type {1}", itr->first, typeid(T).name()); - } - ++itr; - } - return true; + return GetAsset(name).data; } - bool ResourceExists(const IDType& name) + virtual void Destroy() { - typename MapType::iterator itr = m_NameResourceMap.find(name); - return itr != m_NameResourceMap.end(); + m_AssetRegistry.Clear(); } - ResourceHandle operator[](const IDType& name) + void Update(float elapsedSeconds) { - return GetResource(name); + m_AssetRegistry.Update(elapsedSeconds); } - LoadFunc& LoadFunction() { return m_LoadFunc; } - ReleaseFunc& ReleaseFunction() { return m_ReleaseFunc; } - ReloadFunc& ReloadFunction() { return m_ReloadFunc; } + bool AssetExists(const std::string& name) + { + UUID ID; + if(m_AssetRegistry.GetID(name, ID)) + return m_AssetRegistry.Contains(ID); - protected: - MapType m_NameResourceMap = {}; - LoadFunc m_LoadFunc; - ReleaseFunc m_ReleaseFunc; - ReloadFunc m_ReloadFunc; - GetIdFunc m_GetIdFunc; - float m_ExpirationTime = 3.0f; - }; + return false; + } - class ShaderLibrary : public ResourceManager - { - public: - ShaderLibrary() + bool AssetExists(UUID name) { - m_LoadFunc = Load; + return m_AssetRegistry.Contains(name); } - ~ShaderLibrary() + SharedPtr operator[](UUID name) { + return GetAsset(name); } - static bool Load(const std::string& filePath, SharedPtr& shader) + bool LoadShader(const std::string& filePath, SharedPtr& shader, bool keepUnreferenced = true) { shader = SharedPtr(Graphics::Shader::CreateFromFile(filePath)); + AddAsset(filePath, shader, keepUnreferenced); return true; } - }; - class TextureLibrary : public ResourceManager - { - public: - TextureLibrary() + bool LoadAsset(const std::string& filePath, SharedPtr& shader, bool keepUnreferenced = true) { - m_LoadFunc = Load; + shader = SharedPtr(Graphics::Shader::CreateFromFile(filePath)); + AddAsset(filePath, shader, keepUnreferenced); + return true; } - ~TextureLibrary(); - static bool Load(const std::string& filePath, SharedPtr& texture); + SharedPtr LoadTextureAsset(const std::string& filePath, bool thread); - void Destroy() override; - }; - - class ModelLibrary : public ResourceManager - { - public: - ModelLibrary() + template + SharedPtr CreateMemoryOnlyAsset(const char* name, TArgs&&... args) { - m_LoadFunc = Load; + static_assert(std::is_base_of::value, "CreateMemoryOnlyAsset only works for types derived from Asset"); + + uint64_t hash = 0; + HashCombine(hash, std::forward(args)...); + SharedPtr asset = SharedPtr::CreateSharedPtr(std::forward(args)...); + AssetMetaData metaData = AddAsset(name, asset); + metaData.IsMemoryAsset = true; + metaData.ParameterCache = hash; + return asset; } - ~ModelLibrary(); - - static bool Load(const std::string& filePath, SharedPtr& model); - }; - class FontLibrary : public ResourceManager - { - public: - FontLibrary() + template + SharedPtr CreateMemoryOnlyAsset(const char* name, TAsset* asset) { - m_LoadFunc = Load; - } + static_assert(std::is_base_of::value, "CreateMemoryOnlyAsset only works for types derived from Asset"); - ~FontLibrary() - { + uint64_t hash = 0; + SharedPtr sharedAsset = SharedPtr::SharedPtr(asset); + AssetMetaData metaData = AddAsset(name, sharedAsset); + metaData.IsMemoryAsset = true; + return asset; } - static bool Load(const std::string& filePath, SharedPtr& font) - { - font = CreateSharedPtr(filePath); - return true; - } + AssetRegistry& GetAssetRegistry() { return m_AssetRegistry; } + + protected: + bool LoadTexture(const std::string& filePath, SharedPtr& texture, bool thread); + + Arena* m_Arena; + AssetRegistry m_AssetRegistry; }; } diff --git a/Lumos/Source/Lumos/Utilities/DeletionQueue.h b/Lumos/Source/Lumos/Utilities/DeletionQueue.h new file mode 100644 index 00000000..773e179c --- /dev/null +++ b/Lumos/Source/Lumos/Utilities/DeletionQueue.h @@ -0,0 +1,26 @@ +#pragma once +#include +namespace Lumos +{ + struct DeletionQueue + { + std::deque> Deletors; + + template + void PushFunction(F&& function) + { + LUMOS_ASSERT(sizeof(F) < 200, "Lambda too large"); + Deletors.push_back(function); + } + + void Flush() + { + for(auto it = Deletors.rbegin(); it != Deletors.rend(); it++) + { + (*it)(); + } + + Deletors.clear(); + } + }; +} \ No newline at end of file diff --git a/Lumos/Source/Lumos/Utilities/StringUtilities.cpp b/Lumos/Source/Lumos/Utilities/StringUtilities.cpp index 7056029c..aa69db73 100644 --- a/Lumos/Source/Lumos/Utilities/StringUtilities.cpp +++ b/Lumos/Source/Lumos/Utilities/StringUtilities.cpp @@ -495,6 +495,15 @@ namespace Lumos return parts; } + String8 ResolveRelativePath(Arena* arena, String8 path) + { + ArenaTemp scratch = ArenaTempBegin(arena); + String8 pathCopy = BackSlashesToSlashes(scratch.arena, path); + String8 resolvedString = NormalizedPathFromStr8(arena, pathCopy, pathCopy); + ArenaTempEnd(scratch); + return resolvedString; + } + String8List DotResolvedPathPartsFromParts(Arena* arena, String8List parts) { ArenaTemp scratch = ArenaTempBegin(arena); @@ -545,7 +554,7 @@ namespace Lumos { join.post = Str8Lit("/"); } - String8 absolute_resolved_path = Str8ListJoin(scratch.arena, absolute_resolved_path_parts, &join); + String8 absolute_resolved_path = Str8ListJoin(arena, absolute_resolved_path_parts, &join); ArenaTempEnd(scratch); return absolute_resolved_path; } @@ -558,6 +567,36 @@ namespace Lumos return Str8PathSkipLastSlash(Str8PathChopLastPeriod(str)); } + String8 AbsolutePathToRelativeFileSystemPath(Arena* arena, String8 path, String8 fileSystemPath, String8 prefix) + { + LUMOS_PROFILE_FUNCTION(); + + ArenaTemp scratch = ScratchBegin(&arena, 1); + String8 pathCopy = BackSlashesToSlashes(scratch.arena, path); + String8 resolvedString = NormalizedPathFromStr8(scratch.arena, pathCopy, pathCopy); + String8 outString; + + uint64_t loc = FindSubstr8(resolvedString, fileSystemPath, 0); + + if(loc != resolvedString.size) + { + resolvedString.str = resolvedString.str + fileSystemPath.size; + resolvedString.size = resolvedString.size - fileSystemPath.size; + + outString = { 0 }; + outString.size = (resolvedString.size + prefix.size); + outString.str = PushArrayNoZero(arena, uint8_t, outString.size + 1); + + MemoryCopy(outString.str, prefix.str, prefix.size); + MemoryCopy(outString.str + prefix.size, resolvedString.str, resolvedString.size); + } + else + outString = PushStr8Copy(arena, resolvedString); + + ScratchEnd(scratch); + return outString; + } + uint64_t BasicHashFromString(String8 string) { uint64_t result = 5381; @@ -567,5 +606,46 @@ namespace Lumos } return result; } + + String8 BackSlashesToSlashes(Arena* arena, String8& string) + { + String8 copy = PushStr8Copy(arena, string); + + ArenaTemp scratch = ArenaTempBegin(arena); + size_t len = string.size; + + for(size_t i = 0; i < len; i++) + { + if(string.str[i] == '\\') + { + copy.str[i] = '/'; + } + else + copy.str[i] = string.str[i]; + } + ArenaTempEnd(scratch); + + return copy; + } + + String8 SlashesToBackSlashes(Arena* arena, String8& string) + { + String8 copy = PushStr8Copy(arena, string); + + ArenaTemp scratch = ArenaTempBegin(arena); + size_t len = string.size; + for(size_t i = 0; i < len; i++) + { + if(string.str[i] == '/') + { + copy.str[i] = '\\'; + } + else + copy.str[i] = string.str[i]; + } + ArenaTempEnd(scratch); + + return copy; + } } } diff --git a/Lumos/Source/Lumos/Utilities/StringUtilities.h b/Lumos/Source/Lumos/Utilities/StringUtilities.h index a53fb0de..5d77d347 100644 --- a/Lumos/Source/Lumos/Utilities/StringUtilities.h +++ b/Lumos/Source/Lumos/Utilities/StringUtilities.h @@ -1,5 +1,5 @@ #pragma once - +#include "Core/String.h" #ifdef LUMOS_PLATFORM_ANDROID template std::string to_string(const T& n) @@ -89,11 +89,15 @@ namespace Lumos PathType PathTypeFromStr8(String8 path); String8List PathPartsFromStr8(Arena* arena, String8 path); String8List AbsolutePathPartsFromSourcePartsType(Arena* arena, String8 source, String8List parts, PathType type); + String8 ResolveRelativePath(Arena* arena, String8 path); String8List DotResolvedPathPartsFromParts(Arena* arena, String8List parts); String8 NormalizedPathFromStr8(Arena* arena, String8 source, String8 path); String8 GetFileName(String8 str, bool directory = false); + String8 AbsolutePathToRelativeFileSystemPath(Arena* arena, String8 path, String8 fileSystemPath, String8 prefix); uint64_t BasicHashFromString(String8 string); + String8 BackSlashesToSlashes(Arena* arena, String8& string); + String8 SlashesToBackSlashes(Arena* arena, String8& string); } } diff --git a/Lumos/Source/Precompiled.h b/Lumos/Source/Precompiled.h index abd0007d..e5bdf5bb 100644 --- a/Lumos/Source/Precompiled.h +++ b/Lumos/Source/Precompiled.h @@ -30,9 +30,14 @@ #include "Core/Thread.h" #include +#include #include #ifdef LUMOS_PLATFORM_WINDOWS #include #endif + +#ifdef LUMOS_RENDER_API_VULKAN +#include "Platform/Vulkan/VK.h" +#endif #endif diff --git a/Resources/AppIcons/Assets.xcassets/AppIcon.appiconset/Contents.json b/Resources/AppIcons/Assets.xcassets/AppIcon.appiconset/Contents.json index 04de9d48..f78687a2 100644 --- a/Resources/AppIcons/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Resources/AppIcons/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -150,6 +150,66 @@ "scale" : "1x", "size" : "1024x1024" }, + { + "filename" : "16.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "filename" : "32.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "filename" : "32.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "filename" : "64.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "filename" : "128.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "filename" : "256.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "filename" : "256.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "filename" : "512.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "filename" : "512.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "filename" : "1024.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + }, { "filename" : "48.png", "idiom" : "watch", @@ -225,6 +285,13 @@ "size" : "51x51", "subtype" : "45mm" }, + { + "idiom" : "watch", + "role" : "appLauncher", + "scale" : "2x", + "size" : "54x54", + "subtype" : "49mm" + }, { "filename" : "172.png", "idiom" : "watch", @@ -257,70 +324,17 @@ "subtype" : "45mm" }, { - "filename" : "1024.png", - "idiom" : "watch-marketing", - "scale" : "1x", - "size" : "1024x1024" - }, - { - "filename" : "16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "32.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "32.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "64.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "256.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "256.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "512.png", - "idiom" : "mac", + "idiom" : "watch", + "role" : "quickLook", "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "512.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" + "size" : "129x129", + "subtype" : "49mm" }, { "filename" : "1024.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" + "idiom" : "watch-marketing", + "scale" : "1x", + "size" : "1024x1024" } ], "info" : {