From 0c6ed48bbdcbc4bbd83c8b0a80b16b331e9262d9 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Sun, 11 Jul 2021 18:56:44 -0400 Subject: [PATCH] Major cleanup. Moved to namespace Cleanup includes --- Editor/Editor.cpp | 43 +- Editor/resources/Shaders/deferred.shader | 3 +- Editor/src/EditorInterface.cpp | 2343 +++++++++-------- Editor/src/EditorInterface.h | 78 +- Editor/src/FileSystemUI.cpp | 589 ++--- Editor/src/FileSystemUI.h | 41 +- Editor/src/ProjectInterface.cpp | 404 +-- Editor/src/ProjectInterface.h | 23 +- Nuake/Engine.cpp | 243 +- Nuake/Engine.h | 59 +- Nuake/src/Core/Core.h | 3 + Nuake/src/Core/FileSystem.cpp | 276 +- Nuake/src/Core/FileSystem.h | 84 +- Nuake/src/Core/Input.cpp | 258 +- Nuake/src/Core/Input.h | 52 +- Nuake/src/Core/Logger.cpp | 45 +- Nuake/src/Core/Logger.h | 42 +- Nuake/src/Core/MaterialManager.cpp | 157 +- Nuake/src/Core/MaterialManager.h | 73 +- Nuake/src/Core/Maths.h | 16 +- Nuake/src/Core/OS.h | 18 +- Nuake/src/Core/Physics/BulletDebugDrawer.cpp | 46 +- Nuake/src/Core/Physics/BulletDebugDrawer.h | 20 +- .../src/Core/Physics/CharacterController.cpp | 355 +-- Nuake/src/Core/Physics/CharacterController.h | 97 +- Nuake/src/Core/Physics/DynamicWorld.cpp | 213 +- Nuake/src/Core/Physics/DynamicWorld.h | 43 +- Nuake/src/Core/Physics/GhostObject.cpp | 100 +- Nuake/src/Core/Physics/GhostObject.h | 34 +- Nuake/src/Core/Physics/PhysicsManager.cpp | 100 +- Nuake/src/Core/Physics/PhysicsManager.h | 72 +- Nuake/src/Core/Physics/PhysicsShapes.cpp | 117 +- Nuake/src/Core/Physics/PhysicsShapes.h | 104 +- Nuake/src/Core/Physics/RaycastResult.h | 104 +- Nuake/src/Core/Physics/Rigibody.h | 66 +- Nuake/src/Core/Physics/Rigidbody.cpp | 216 +- Nuake/src/Core/TextureManager.cpp | 47 +- Nuake/src/Core/TextureManager.h | 32 +- Nuake/src/Core/Timestep.h | 33 +- Nuake/src/Rendering/Buffers/Framebuffer.cpp | 128 + Nuake/src/Rendering/Buffers/Framebuffer.h | 42 + Nuake/src/Rendering/{ => Buffers}/GBuffer.cpp | 0 Nuake/src/Rendering/{ => Buffers}/GBuffer.h | 0 .../src/Rendering/Buffers/MSAAFramebuffer.cpp | 124 + Nuake/src/Rendering/Buffers/MSAAFramebuffer.h | 42 + .../Rendering/{ => Buffers}/UniformBuffer.cpp | 0 .../Rendering/{ => Buffers}/UniformBuffer.h | 4 - Nuake/src/Rendering/Camera.cpp | 189 +- Nuake/src/Rendering/Camera.h | 95 +- Nuake/src/Rendering/Framebuffer.cpp | 124 - Nuake/src/Rendering/Framebuffer.h | 37 - Nuake/src/Rendering/MSAAFramebuffer.cpp | 120 - Nuake/src/Rendering/MSAAFramebuffer.h | 38 - Nuake/src/Rendering/Mesh/Mesh.cpp | 141 +- Nuake/src/Rendering/Mesh/Mesh.h | 41 +- Nuake/src/Rendering/ProceduralSky.cpp | 107 - Nuake/src/Rendering/ProceduralSky.h | 27 - Nuake/src/Rendering/RenderList.h | 34 +- Nuake/src/Rendering/Renderer.cpp | 414 +-- Nuake/src/Rendering/Renderer.h | 64 +- Nuake/src/Rendering/Renderer2D.cpp | 231 +- Nuake/src/Rendering/Renderer2D.h | 46 +- Nuake/src/Rendering/Shaders/Shader.cpp | 324 +-- Nuake/src/Rendering/Shaders/Shader.h | 61 +- Nuake/src/Rendering/Shaders/ShaderManager.cpp | 21 +- Nuake/src/Rendering/Shaders/ShaderManager.h | 15 +- Nuake/src/Rendering/Skybox.cpp | 158 -- Nuake/src/Rendering/Skybox.h | 24 - Nuake/src/Rendering/Textures/Cubemap.cpp | 141 +- Nuake/src/Rendering/Textures/Cubemap.h | 39 +- Nuake/src/Rendering/Textures/HDR.cpp | 99 +- Nuake/src/Rendering/Textures/HDR.h | 49 +- Nuake/src/Rendering/Textures/Material.cpp | 336 ++- Nuake/src/Rendering/Textures/Material.h | 167 +- .../Textures/MultiSampledTexture.cpp | 190 +- .../Rendering/Textures/MultiSampledTexture.h | 53 +- Nuake/src/Rendering/Textures/Texture.cpp | 180 +- Nuake/src/Rendering/Textures/Texture.h | 54 +- Nuake/src/Rendering/Transform.h | 12 + Nuake/src/Rendering/Vertex.h | 23 +- Nuake/src/Resource/FGD/BrushClass.h | 1 - Nuake/src/Resource/FGD/FDGSerializer.h | 19 +- Nuake/src/Resource/FGD/FGDClass.cpp | 42 +- Nuake/src/Resource/FGD/FGDClass.h | 143 +- Nuake/src/Resource/FGD/FGDFile.cpp | 152 +- Nuake/src/Resource/FGD/FGDFile.h | 158 +- Nuake/src/Resource/FGD/FGDSerializer.cpp | 156 +- Nuake/src/Resource/Project.cpp | 223 +- Nuake/src/Resource/Project.h | 41 +- .../src/Scene/Components/BSPBrushComponent.h | 37 +- Nuake/src/Scene/Components/BoxCollider.h | 20 +- .../src/Scene/Components/CameraComponent.cpp | 25 +- Nuake/src/Scene/Components/CameraComponent.h | 50 +- .../Components/CharacterControllerComponent.h | 70 +- Nuake/src/Scene/Components/LightComponent.cpp | 255 +- Nuake/src/Scene/Components/LightComponent.h | 357 +-- Nuake/src/Scene/Components/MeshCollider.h | 20 +- Nuake/src/Scene/Components/MeshComponent.cpp | 451 ++-- Nuake/src/Scene/Components/MeshComponent.h | 32 +- Nuake/src/Scene/Components/ModelComponent.cpp | 245 +- Nuake/src/Scene/Components/ModelComponent.h | 40 +- Nuake/src/Scene/Components/NameComponent.h | 47 +- .../Scene/Components/NativeScriptComponent.h | 23 +- Nuake/src/Scene/Components/ParentComponent.h | 80 +- Nuake/src/Scene/Components/QuakeMap.cpp | 40 +- Nuake/src/Scene/Components/QuakeMap.h | 57 +- .../Scene/Components/RigidbodyComponent.cpp | 146 +- .../src/Scene/Components/RigidbodyComponent.h | 56 +- Nuake/src/Scene/Components/SphereCollider.h | 20 +- .../Scene/Components/TransformComponent.cpp | 35 +- .../src/Scene/Components/TransformComponent.h | 55 +- Nuake/src/Scene/Components/TriggerZone.h | 55 +- .../Scene/Components/WrenScriptComponent.h | 56 +- Nuake/src/Scene/EditorCamera.cpp | 161 +- Nuake/src/Scene/EditorCamera.h | 25 +- Nuake/src/Scene/Entities/Entity.cpp | 92 +- Nuake/src/Scene/Entities/Entity.h | 120 +- Nuake/src/Scene/Entities/ScriptableEntity.h | 9 - Nuake/src/Scene/Environment/ProceduralSky.cpp | 114 + Nuake/src/Scene/Environment/ProceduralSky.h | 31 + Nuake/src/Scene/Environment/Skybox.cpp | 171 ++ Nuake/src/Scene/Environment/Skybox.h | 28 + .../Environment}/SkyboxHDR.cpp | 0 .../Environment}/SkyboxHDR.h | 0 Nuake/src/Scene/Lighting/Environment.cpp | 64 +- Nuake/src/Scene/Lighting/Environment.h | 40 +- Nuake/src/Scene/Scene.cpp | 1173 +++++---- Nuake/src/Scene/Scene.h | 120 +- Nuake/src/Scene/Systems/PhysicsSystem.cpp | 230 +- Nuake/src/Scene/Systems/PhysicsSystem.h | 22 +- Nuake/src/Scene/Systems/QuakeMapBuilder.cpp | 693 ++--- Nuake/src/Scene/Systems/QuakeMapBuilder.h | 32 +- Nuake/src/Scene/Systems/ScriptingSystem.cpp | 118 +- Nuake/src/Scene/Systems/ScriptingSystem.h | 24 +- Nuake/src/Scene/Systems/System.h | 25 +- Nuake/src/Scene/Systems/TransformSystem.cpp | 82 +- Nuake/src/Scene/Systems/TransformSystem.h | 26 +- Nuake/src/Scene/Systems/TrenchbroomSystem.cpp | 48 +- Nuake/src/Scene/Systems/TrenchbroomSystem.h | 22 +- Nuake/src/Scripting/Modules/EngineModule.h | 38 +- Nuake/src/Scripting/Modules/EntityModule.h | 47 +- Nuake/src/Scripting/Modules/InputModule.h | 157 +- Nuake/src/Scripting/Modules/MathModule.h | 140 +- Nuake/src/Scripting/Modules/PhysicsModule.h | 90 +- Nuake/src/Scripting/Modules/SceneModule.h | 549 ++-- Nuake/src/Scripting/Modules/ScriptModule.h | 38 +- Nuake/src/Scripting/ScriptLoader.cpp | 18 - Nuake/src/Scripting/ScriptLoader.h | 30 - Nuake/src/Scripting/ScriptingEngine.cpp | 311 +-- Nuake/src/Scripting/ScriptingEngine.h | 60 +- Nuake/src/Scripting/WrenScript.cpp | 190 +- Nuake/src/Scripting/WrenScript.h | 43 +- Nuake/src/UI/Font/Font.h | 183 +- Nuake/src/UI/Font/FontLoader.h | 286 +- Nuake/src/UI/Font/FontManager.cpp | 32 +- Nuake/src/UI/Font/FontManager.h | 17 +- Nuake/src/UI/InterfaceParser.cpp | 520 ++-- Nuake/src/UI/InterfaceParser.h | 32 +- Nuake/src/UI/Nodes/Canvas.cpp | 8 +- Nuake/src/UI/Nodes/Canvas.h | 20 +- Nuake/src/UI/Nodes/Node.cpp | 273 +- Nuake/src/UI/Nodes/Node.h | 792 +++--- Nuake/src/UI/Nodes/Rect.h | 176 +- Nuake/src/UI/Nodes/TextNode.h | 102 +- Nuake/src/UI/Styling/Style.h | 136 +- Nuake/src/UI/Styling/StyleSheetParser.cpp | 77 +- Nuake/src/UI/Styling/StyleSheetParser.h | 11 +- Nuake/src/UI/Styling/Stylesheet.cpp | 17 +- Nuake/src/UI/Styling/Stylesheet.h | 446 ++-- Nuake/src/UI/UserInterface.cpp | 254 +- Nuake/src/UI/UserInterface.h | 62 +- Nuake/src/Window.cpp | 467 ++-- Nuake/src/Window.h | 61 +- nuake.4coder | 65 + 174 files changed, 11772 insertions(+), 11296 deletions(-) create mode 100644 Nuake/src/Rendering/Buffers/Framebuffer.cpp create mode 100644 Nuake/src/Rendering/Buffers/Framebuffer.h rename Nuake/src/Rendering/{ => Buffers}/GBuffer.cpp (100%) rename Nuake/src/Rendering/{ => Buffers}/GBuffer.h (100%) create mode 100644 Nuake/src/Rendering/Buffers/MSAAFramebuffer.cpp create mode 100644 Nuake/src/Rendering/Buffers/MSAAFramebuffer.h rename Nuake/src/Rendering/{ => Buffers}/UniformBuffer.cpp (100%) rename Nuake/src/Rendering/{ => Buffers}/UniformBuffer.h (95%) delete mode 100644 Nuake/src/Rendering/Framebuffer.cpp delete mode 100644 Nuake/src/Rendering/Framebuffer.h delete mode 100644 Nuake/src/Rendering/MSAAFramebuffer.cpp delete mode 100644 Nuake/src/Rendering/MSAAFramebuffer.h delete mode 100644 Nuake/src/Rendering/ProceduralSky.cpp delete mode 100644 Nuake/src/Rendering/ProceduralSky.h delete mode 100644 Nuake/src/Rendering/Skybox.cpp delete mode 100644 Nuake/src/Rendering/Skybox.h create mode 100644 Nuake/src/Rendering/Transform.h create mode 100644 Nuake/src/Scene/Environment/ProceduralSky.cpp create mode 100644 Nuake/src/Scene/Environment/ProceduralSky.h create mode 100644 Nuake/src/Scene/Environment/Skybox.cpp create mode 100644 Nuake/src/Scene/Environment/Skybox.h rename Nuake/src/{Rendering => Scene/Environment}/SkyboxHDR.cpp (100%) rename Nuake/src/{Rendering => Scene/Environment}/SkyboxHDR.h (100%) delete mode 100644 Nuake/src/Scripting/ScriptLoader.cpp delete mode 100644 Nuake/src/Scripting/ScriptLoader.h create mode 100644 nuake.4coder diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index fdd034a2..f2853d71 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -17,39 +17,40 @@ #include #include + int main() { - Engine::Init(); + Nuake::Engine::Init(); - EditorInterface editor; + Nuake::EditorInterface editor; editor.BuildFonts(); // Register Gizmo textures - Ref lightTexture = TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Light.png"); - Ref camTexture = TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Camera.png"); - Ref GuizmoShader = ShaderManager::GetShader("resources/Shaders/gizmo.shader"); + Ref lightTexture = Nuake::TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Light.png"); + Ref camTexture = Nuake::TextureManager::Get()->GetTexture("resources/Icons/Gizmo/Camera.png"); + Ref GuizmoShader = Nuake::ShaderManager::GetShader("resources/Shaders/gizmo.shader"); - while (!Engine::GetCurrentWindow()->ShouldClose()) + while (!Nuake::Engine::GetCurrentWindow()->ShouldClose()) { - Engine::Tick(); - Engine::Draw(); + Nuake::Engine::Tick(); + Nuake::Engine::Draw(); - if (Input::IsKeyPressed(GLFW_KEY_F8)) - Engine::ExitPlayMode(); + if (Nuake::Input::IsKeyPressed(GLFW_KEY_F8)) + Nuake::Engine::ExitPlayMode(); - Ref sceneFramebuffer = Engine::GetCurrentWindow()->GetFrameBuffer(); + Ref sceneFramebuffer = Nuake::Engine::GetCurrentWindow()->GetFrameBuffer(); sceneFramebuffer->Bind(); - Ref currentScene = Engine::GetCurrentScene(); - if (currentScene && !Engine::IsPlayMode) + Ref currentScene = Nuake::Engine::GetCurrentScene(); + if (currentScene && !Nuake::Engine::IsPlayMode) { GuizmoShader->Bind(); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); - auto camView = currentScene->m_Registry.view(); + auto camView = currentScene->m_Registry.view(); for (auto e : camView) { - auto [transformComponent, cam] = camView.get(e); + auto [transformComponent, cam] = camView.get(e); GuizmoShader->SetUniformMat4f("model", transformComponent.GetTransform()); GuizmoShader->SetUniformMat4f("view", currentScene->m_EditorCamera->GetTransform()); @@ -58,12 +59,12 @@ int main() camTexture->Bind(2); GuizmoShader->SetUniform1i("gizmo_texture", 2); - Renderer::DrawQuad(transformComponent.GetTransform()); + Nuake::Renderer::DrawQuad(transformComponent.GetTransform()); } - auto view = currentScene->m_Registry.view(); + auto view = currentScene->m_Registry.view(); for (auto e : view) { - auto [transformComponent, light] = view.get(e); + auto [transformComponent, light] = view.get(e); GuizmoShader->SetUniformMat4f("model", transformComponent.GetTransform()); GuizmoShader->SetUniformMat4f("view", currentScene->m_EditorCamera->GetTransform()); @@ -72,7 +73,7 @@ int main() lightTexture->Bind(2); GuizmoShader->SetUniform1i("gizmo_texture", 2); - Renderer::DrawQuad(transformComponent.GetTransform()); + Nuake::Renderer::DrawQuad(transformComponent.GetTransform()); } glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); @@ -81,9 +82,9 @@ int main() sceneFramebuffer->Unbind(); editor.Draw(); - Engine::EndDraw(); + Nuake::Engine::EndDraw(); } - Engine::Close(); + Nuake::Engine::Close(); } diff --git a/Editor/resources/Shaders/deferred.shader b/Editor/resources/Shaders/deferred.shader index 4f00a7dc..6ad6109e 100644 --- a/Editor/resources/Shaders/deferred.shader +++ b/Editor/resources/Shaders/deferred.shader @@ -240,6 +240,5 @@ void main() // gamma correct color = pow(color, vec3(1.0 / u_Exposure)); - - FragColor = vec4(color, 1.0); // so If i wanted to implement other stuff like SSR and bloom. I would need another render texture? using this same shader? + FragColor = vec4(color, 1.0); } \ No newline at end of file diff --git a/Editor/src/EditorInterface.cpp b/Editor/src/EditorInterface.cpp index 88afb3e9..c96193e4 100644 --- a/Editor/src/EditorInterface.cpp +++ b/Editor/src/EditorInterface.cpp @@ -20,824 +20,826 @@ #include #include #include -#include + #include "ProjectInterface.h" #include -Ref userInterface; -ImFont* normalFont; -ImFont* EditorInterface::bigIconFont; -void EditorInterface::Init() -{ - ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; - static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None; - ImGuiViewport* viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos(viewport->GetWorkPos()); - ImGui::SetNextWindowSize(viewport->GetWorkSize()); - ImGui::SetNextWindowViewport(viewport->ID); - ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); - ImGui::DockSpaceOverViewport(viewport, dockspace_flags); - - //this->filesystem = FileSystemUI(); -} - - -ImVec2 LastSize = ImVec2(); -void EditorInterface::DrawViewport() -{ - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); - - std::string name = ICON_FA_GAMEPAD + std::string(" Scene"); - if(ImGui::Begin(name.c_str())) +namespace Nuake { + Ref userInterface; + ImFont* normalFont; + ImFont* EditorInterface::bigIconFont; + void EditorInterface::Init() { - - ImGui::PopStyleVar(); - Overlay(); - ImGuizmo::BeginFrame(); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; + static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None; + ImGuiViewport* viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(viewport->GetWorkPos()); + ImGui::SetNextWindowSize(viewport->GetWorkSize()); + ImGui::SetNextWindowViewport(viewport->ID); - ImGuizmo::SetOrthographic(false); - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); + ImGui::DockSpaceOverViewport(viewport, dockspace_flags); - if(Engine::GetCurrentWindow()->GetFrameBuffer()->GetSize() != viewportPanelSize) - Engine::GetCurrentWindow()->GetFrameBuffer()->QueueResize(viewportPanelSize); + //this->filesystem = FileSystemUI(); + } - Ref texture = Engine::GetCurrentWindow()->GetFrameBuffer()->GetTexture(); - ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); - ImGuizmo::SetDrawlist(); - ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); + ImVec2 LastSize = ImVec2(); + void EditorInterface::DrawViewport() + { + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); - if (m_DrawGrid && !Engine::IsPlayMode) + std::string name = ICON_FA_GAMEPAD + std::string(" Scene"); + if (ImGui::Begin(name.c_str())) { - ImGuizmo::DrawGrid(glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetTransform()), - glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetPerspective()), - glm::value_ptr(glm::identity()), 100.f); - } - if (m_IsEntitySelected && !Engine::IsPlayMode) - { - TransformComponent& tc = m_SelectedEntity.GetComponent(); - ParentComponent& parent = m_SelectedEntity.GetComponent(); - glm::mat4 oldTransform = tc.GetTransform(); - ImGuizmo::Manipulate( - glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetTransform()), - glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetPerspective()), - CurrentOperation, CurrentMode, glm::value_ptr(oldTransform), 0, 0 - ); - if (ImGuizmo::IsUsing()) + ImGui::PopStyleVar(); + Overlay(); + ImGuizmo::BeginFrame(); + + ImGuizmo::SetOrthographic(false); + ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + + if (Engine::GetCurrentWindow()->GetFrameBuffer()->GetSize() != viewportPanelSize) + Engine::GetCurrentWindow()->GetFrameBuffer()->QueueResize(viewportPanelSize); + + Ref texture = Engine::GetCurrentWindow()->GetFrameBuffer()->GetTexture(); + ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + + ImGuizmo::SetDrawlist(); + ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); + + if (m_DrawGrid && !Engine::IsPlayMode) { - glm::vec3 scale; - glm::quat rotation; - glm::vec3 translation; - glm::vec3 skew; - glm::vec4 perspective; - glm::decompose(oldTransform, scale, rotation, translation, skew, perspective); - //rotation = glm::conjugate(rotation); - if (scale.x < 0 && scale.y < 0 && scale.z < 0) - scale = glm::vec3(0, 0, 0); - rotation = glm::conjugate(rotation); - glm::vec3 euler = glm::eulerAngles(rotation); + ImGuizmo::DrawGrid(glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetTransform()), + glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetPerspective()), + glm::value_ptr(glm::identity()), 100.f); + } - Vector3 globalPos = Vector3(); - Entity currentParent = m_SelectedEntity; - if (parent.HasParent) + if (m_IsEntitySelected && !Engine::IsPlayMode) + { + TransformComponent& tc = m_SelectedEntity.GetComponent(); + ParentComponent& parent = m_SelectedEntity.GetComponent(); + glm::mat4 oldTransform = tc.GetTransform(); + ImGuizmo::Manipulate( + glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetTransform()), + glm::value_ptr(Engine::GetCurrentScene()->GetCurrentCamera()->GetPerspective()), + CurrentOperation, CurrentMode, glm::value_ptr(oldTransform), 0, 0 + ); + if (ImGuizmo::IsUsing()) { - globalPos -= parent.Parent.GetComponent().GlobalTranslation; - translation -= globalPos; - } + glm::vec3 scale; + glm::quat rotation; + glm::vec3 translation; + glm::vec3 skew; + glm::vec4 perspective; + glm::decompose(oldTransform, scale, rotation, translation, skew, perspective); + //rotation = glm::conjugate(rotation); + if (scale.x < 0 && scale.y < 0 && scale.z < 0) + scale = glm::vec3(0, 0, 0); + rotation = glm::conjugate(rotation); + glm::vec3 euler = glm::eulerAngles(rotation); - tc.Translation = translation; - tc.Rotation = glm::vec3(glm::degrees(euler.x), glm::degrees(euler.y), glm::degrees(euler.z)); - tc.Scale = scale; - } - } - } - else - { - ImGui::PopStyleVar(); - } - ImGui::End(); - -} - -static int selected = 0; -Entity QueueDeletion; -void EditorInterface::DrawEntityTree(Entity e) -{ - ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; - - std::string name = e.GetComponent().Name; - ParentComponent& parent = e.GetComponent(); - - if (m_SelectedEntity == e) - base_flags |= ImGuiTreeNodeFlags_Selected; - - // Write in normal font. - ImGui::PushFont(normalFont); - - // If has no childrens draw tree node leaf - if (parent.Children.size() <= 0) - base_flags |= ImGuiTreeNodeFlags_Leaf; - - bool open = ImGui::TreeNodeEx(name.c_str(), base_flags); - - - if (ImGui::BeginDragDropSource()) - { - ImGui::SetDragDropPayload("ENTITY", (void*)&e, sizeof(Entity)); - ImGui::Text(name.c_str()); - ImGui::EndDragDropSource(); - } - - if (ImGui::BeginDragDropTarget()) - { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY")) - { - Entity payload_entity = *(const Entity*)payload->Data; - - // Check if entity is already parent. - ParentComponent& parentPayload = payload_entity.GetComponent(); - if (!EntityContainsItself(payload_entity, e) && parentPayload.Parent != e && std::count(parent.Children.begin(), parent.Children.end(), payload_entity) == 0) - { - if (parentPayload.HasParent) - { - // Erase remove idiom. - ParentComponent& childOfParent = parentPayload.Parent.GetComponent(); - childOfParent.Children.erase(std::remove(childOfParent.Children.begin(), childOfParent.Children.end(), payload_entity), childOfParent.Children.end()); - } - - parentPayload.Parent = e; - parentPayload.HasParent = true; - parent.Children.push_back(payload_entity); - } - } - } - - // Click. - if (ImGui::IsItemClicked()) - { - m_SelectedEntity = e; - m_IsEntitySelected = true; - } - - if (ImGui::BeginPopupContextItem()) - { - if (ImGui::Selectable("Remove")) { - - QueueDeletion = e; - open = false; - } - - if (ImGui::Selectable("Move to root")) - { - auto& p = m_SelectedEntity.GetComponent(); - if (p.HasParent) { - auto& pp = p.Parent.GetComponent(); - pp.RemoveChildren(m_SelectedEntity); - p.HasParent = false; - } - } - ImGui::Selectable("Save as prefab"); - ImGui::EndPopup(); - } - if (open) - { - // Caching list to prevent deletion while iterating. - std::vector childrens = parent.Children; - for (auto c : childrens) - DrawEntityTree(c); - - ImGui::TreePop(); - - } - ImGui::PopFont(); -} - - - - -void EditorInterface::DrawSceneTree() -{ - Ref scene = Engine::GetCurrentScene(); - - if (!scene) - return; - - if (ImGui::Begin(" Environnement")) - { - auto env = Engine::GetCurrentScene()->GetEnvironment(); - if (ImGui::CollapsingHeader("Procedural Sky")) - { - ImGui::DragFloat("Sun Intensity", &env->ProceduralSkybox->SunIntensity, 0.1f, 0.0f); - - glm::vec3 currentDirection = env->ProceduralSkybox->SunDirection; - ImGuiHelper::DrawVec3("Sun Direction", ¤tDirection); - env->ProceduralSkybox->SunDirection = glm::normalize(currentDirection); - - glm::vec3 mieScattering = env->ProceduralSkybox->MieScattering * 10000.0f; - ImGuiHelper::DrawVec3("Mie Scattering", &mieScattering); - env->ProceduralSkybox->MieScattering = mieScattering / 10000.0f; - } - if (ImGui::CollapsingHeader("Fog")) - { - ImGui::DragFloat("Volumetric scattering", &env->VolumetricFog, .01f, 0.0f, 1.0f); - ImGui::DragFloat("Volumetric step count", &env->VolumetricStepCount, 1.f, 0.0f); - } - - } - ImGui::End(); - - std::string title = ICON_FA_TREE + std::string(" Hierarchy"); - if(ImGui::Begin(title.c_str())) - { - // Buttons to add and remove entity. - ImGui::BeginChild("Buttons", ImVec2(300, 20), false); - { - // Add entity. - if (ImGui::Button("Add")) - Engine::GetCurrentScene()->CreateEntity("Entity"); - - ImGui::SameLine(); - - // Remove Entity - if (ImGui::Button("Remove")) - { - scene->DestroyEntity(m_SelectedEntity); - - // Unselect delted entity. - m_SelectedEntity = scene->GetAllEntities().at(0); - } - - } - ImGui::EndChild(); - - ImGui::Separator(); - - // Draw a tree of entities. - std::vector entities = scene->GetAllEntities(); - for (Entity e : entities) - { - ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; - std::string name = e.GetComponent().Name; - // If selected add selected flag. - if (m_SelectedEntity == e) - base_flags |= ImGuiTreeNodeFlags_Selected; - - // Write in normal font. - ImGui::PushFont(normalFont); - - // Small icons + name. - std::string label = ICON_FA_CIRCLE + std::string(" ") + name; - - // Draw all entity without parents. - if (!e.GetComponent().HasParent) - { - // Recursively draw childrens. - DrawEntityTree(e); - - } - - // Pop font. - ImGui::PopFont(); - - // Right click menu - //if (ImGui::BeginPopupContextItem()) - // ImGui::EndPopup(); - } - - // Delete entity - if (QueueDeletion.GetHandle() != 0) - { - Engine::GetCurrentScene()->DestroyEntity(QueueDeletion); - - if(m_SelectedEntity == QueueDeletion) - m_SelectedEntity = scene->GetAllEntities().at(0); - - QueueDeletion = Entity{ (entt::entity)0, scene.get() }; - ImGui::TreePop(); - } - - } - ImGui::End(); -} - - - -void EditorInterface::DrawEntityPropreties() -{ - if(ImGui::Begin("Propreties")) - { - if (!m_IsEntitySelected) - { - ImGui::Text("No entity selected"); - ImGui::End(); - return; - } - - - if(m_SelectedEntity.HasComponent()) { - auto& name = m_SelectedEntity.GetComponent().Name; - - char buffer[256]; - memset(buffer, 0, sizeof(buffer)); - std::strncpy(buffer, name.c_str(), sizeof(buffer)); - ImGui::Text("Name: "); - ImGui::SameLine(); - if (ImGui::InputText("##Name", buffer, sizeof(buffer))) - { - name = std::string(buffer); - } - ImGui::SameLine(); - if (ImGui::Button("Add component")) - { - ImGui::OpenPopup("add_component_popup"); - - } - if (ImGui::BeginPopup("add_component_popup")) - { - if (ImGui::MenuItem("Wren Script") && !m_SelectedEntity.HasComponent()) - m_SelectedEntity.AddComponent(); - ImGui::Separator(); - if (ImGui::MenuItem("Camera Component") && !m_SelectedEntity.HasComponent()) - m_SelectedEntity.AddComponent(); - ImGui::Separator(); - if (ImGui::MenuItem("Light Component") && !m_SelectedEntity.HasComponent()) - m_SelectedEntity.AddComponent(); - ImGui::Separator(); - if (ImGui::MenuItem("Model Component") && !m_SelectedEntity.HasComponent()) - m_SelectedEntity.AddComponent(); - if (ImGui::MenuItem("Quake map Component") && !m_SelectedEntity.HasComponent()) - m_SelectedEntity.AddComponent(); - ImGui::Separator(); - if (ImGui::MenuItem("Character controller") && !m_SelectedEntity.HasComponent()) - m_SelectedEntity.AddComponent(); - if (ImGui::MenuItem("Rigidbody Component") && !m_SelectedEntity.HasComponent()) - { - m_SelectedEntity.AddComponent(); - auto transformComponent = m_SelectedEntity.GetComponent(); - } - if (ImGui::MenuItem("Box collider Component") && !m_SelectedEntity.HasComponent()) - { - m_SelectedEntity.AddComponent(); - } - if (ImGui::MenuItem("Sphere collider Component") && !m_SelectedEntity.HasComponent()) - { - m_SelectedEntity.AddComponent(); - } - if (ImGui::MenuItem("Mesh collider Component") && !m_SelectedEntity.HasComponent()) - { - m_SelectedEntity.AddComponent(); - } - - // your popup code - ImGui::EndPopup(); - } - ImGui::Separator(); - } - - ImGui::PushFont(normalFont); - std::string iconTransform = ICON_FA_MAP_MARKER; - if(ImGui::CollapsingHeader((iconTransform + " Transform").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Transform properties"); - //ImGui::InputText("Name:", selectedEntity->m_Name.data(), 12); - TransformComponent& component = m_SelectedEntity.GetComponent(); - ImGuiHelper::DrawVec3("Translation", &component.Translation); - ImGuiHelper::DrawVec3("Rotation", &component.Rotation); - ImGuiHelper::DrawVec3("Scale", &component.Scale); - ImGui::Separator(); - } - - if (m_SelectedEntity.HasComponent()) { - std::string icon = ICON_FA_MALE; - if (ImGui::CollapsingHeader((icon + " " + "Model").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Model properties"); - auto& component = m_SelectedEntity.GetComponent(); - // Path - std::string path = component.ModelPath; - char pathBuffer[256]; - - memset(pathBuffer, 0, sizeof(pathBuffer)); - std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer)); - - std::string oldPath = component.ModelPath; - ImGui::Text("Model: "); - ImGui::SameLine(); - if (ImGui::InputText("##ModelPath", pathBuffer, sizeof(pathBuffer))) - path = FileSystem::AbsoluteToRelative(std::string(pathBuffer)); - if (ImGui::BeginDragDropTarget()) - { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Model")) + Vector3 globalPos = Vector3(); + Entity currentParent = m_SelectedEntity; + if (parent.HasParent) { - char* file = (char*)payload->Data; - std::string fullPath = std::string(file, 256); - path = FileSystem::AbsoluteToRelative(fullPath); + globalPos -= parent.Parent.GetComponent().GlobalTranslation; + translation -= globalPos; } - ImGui::EndDragDropTarget(); + + tc.Translation = translation; + tc.Rotation = glm::vec3(glm::degrees(euler.x), glm::degrees(euler.y), glm::degrees(euler.z)); + tc.Scale = scale; } - - if (component.ModelPath != path) - { - component.ModelPath = path; - component.LoadModel(); - } - - - if (ImGui::Button("Reimport")) - { - component.LoadModel(); - } - - - ImGui::Separator(); - } - - } - - if (m_SelectedEntity.HasComponent()) { - std::string icon = ICON_FA_LIGHTBULB; - if (ImGui::CollapsingHeader((icon + " " + "Light").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - m_SelectedEntity.GetComponent().DrawEditor(); - ImGui::Separator(); - } - - } - - if (m_SelectedEntity.HasComponent()) { - std::string icon = ICON_FA_FILE; - if (ImGui::CollapsingHeader((icon + " " + "Wren Script").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Script properties"); - auto& component = m_SelectedEntity.GetComponent(); - - // Path - std::string path = component.Script; - char pathBuffer[256]; - - memset(pathBuffer, 0, sizeof(pathBuffer)); - std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer)); - - ImGui::Text("Script: "); - ImGui::SameLine(); - if (ImGui::InputText("##ScriptPath", pathBuffer, sizeof(pathBuffer))) - path = FileSystem::AbsoluteToRelative(std::string(pathBuffer)); - if (ImGui::BeginDragDropTarget()) - { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script")) - { - char* file = (char*)payload->Data; - std::string fullPath = std::string(file, 256); - path = FileSystem::AbsoluteToRelative(fullPath); - } - ImGui::EndDragDropTarget(); - } - - - component.Script = path; - - // Class - std::string module = component.Class; - - char classBuffer[256]; - - memset(classBuffer, 0, sizeof(classBuffer)); - std::strncpy(classBuffer, module.c_str(), sizeof(classBuffer)); - - ImGui::Text("Class: "); - ImGui::SameLine(); - if (ImGui::InputText("##ScriptModule", classBuffer, sizeof(classBuffer))) - module = std::string(classBuffer); - - component.Class = module; - ImGui::Separator(); } } - - if (m_SelectedEntity.HasComponent()) { - - std::string icon = ICON_FA_LIGHTBULB; - if (ImGui::CollapsingHeader((icon + " " + "Camera").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Camera properties"); - m_SelectedEntity.GetComponent().DrawEditor(); - ImGui::Separator(); - } - - } - - if (m_SelectedEntity.HasComponent()) + else { - if (ImGui::CollapsingHeader("Character controller", ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Character controller properties"); - auto& c = m_SelectedEntity.GetComponent(); - ImGui::InputFloat("Height", &c.Height); - ImGui::InputFloat("Radius", &c.Radius); - ImGui::InputFloat("Mass", &c.Mass); - ImGui::Separator(); - } + ImGui::PopStyleVar(); } + ImGui::End(); - if (m_SelectedEntity.HasComponent()) { - - std::string icon = ICON_FA_TREE; - if (ImGui::CollapsingHeader((icon + " " + "Mesh").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Mesh properties"); - ImGui::Button("Drag Material"); - if (ImGui::BeginDragDropTarget()) - { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_DEMO_CELL")) - { - IM_ASSERT(payload->DataSize == sizeof(int)); - int payload_n = *(const int*)payload->Data; - - } - ImGui::EndDragDropTarget(); - } - } - - } - - if (m_SelectedEntity.HasComponent()) - { - std::string icon = ICON_FA_BOWLING_BALL ; - if (ImGui::CollapsingHeader((icon + " Rigidbody").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Rigidbody properties"); - RigidBodyComponent& rbComponent = m_SelectedEntity.GetComponent(); - ImGui::DragFloat("Mass", &rbComponent.mass, 0.1, 0.0); - ImGui::Separator(); - } - } - - if (m_SelectedEntity.HasComponent()) - { - std::string icon = ICON_FA_BOX; - if (ImGui::CollapsingHeader((icon + " Box collider").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Box collider properties"); - BoxColliderComponent& component = m_SelectedEntity.GetComponent(); - ImGuiHelper::DrawVec3("Size", &component.Size); - ImGui::Checkbox("Is trigger", &component.IsTrigger); - - ImGui::Separator(); - } - } - if (m_SelectedEntity.HasComponent()) - { - std::string icon = ICON_FA_CIRCLE; - if (ImGui::CollapsingHeader((icon + " Sphere collider").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Sphere properties"); - SphereColliderComponent& component = m_SelectedEntity.GetComponent(); - ImGui::DragFloat("Radius", &component.Radius, 0.1f, 0.0f, 100.0f); - ImGui::Checkbox("Is trigger", &component.IsTrigger); - - ImGui::Separator(); - } - } - if (m_SelectedEntity.HasComponent()) - { - std::string icon = ICON_FA_BROOM ; - if (ImGui::CollapsingHeader((icon + " " + "Quake map").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Quake map properties"); - auto& component = m_SelectedEntity.GetComponent(); - std::string path = component.Path; - - - char pathBuffer[256]; - memset(pathBuffer, 0, sizeof(pathBuffer)); - std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer)); - ImGui::Text("Map file: "); - ImGui::SameLine(); - if (ImGui::InputText("##MapPath", pathBuffer, sizeof(pathBuffer))) - { - path = std::string(pathBuffer); - } - - if (ImGui::BeginDragDropTarget()) - { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Map")) - { - char* file = (char*)payload->Data; - std::string fullPath = std::string(file, 256); - path = FileSystem::AbsoluteToRelative(fullPath); - } - ImGui::EndDragDropTarget(); - } - - component.Path = path; - - ImGui::Checkbox("Build collisions", &component.HasCollisions); - if (ImGui::Button("Build Geometry")) - { - QuakeMapBuilder mapBuilder; - mapBuilder.BuildQuakeMap(m_SelectedEntity); - } - ImGui::Separator(); - } - } - - ImGui::PopFont(); } - ImGui::End(); -} -void EditorInterface::DrawGizmos() -{ - Ref scene = Engine::GetCurrentScene(); - - if (!m_IsEntitySelected) - return; -} -void EditorInterface::EditorInterfaceDrawFiletree(Ref dir) -{ - for (auto d : dir->Directories) + static int selected = 0; + Entity QueueDeletion; + void EditorInterface::DrawEntityTree(Entity e) { ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; - bool is_selected = m_CurrentDirectory == d; - if (is_selected) + + std::string name = e.GetComponent().Name; + ParentComponent& parent = e.GetComponent(); + + if (m_SelectedEntity == e) base_flags |= ImGuiTreeNodeFlags_Selected; - if (d->Directories.size() == 0) + // Write in normal font. + ImGui::PushFont(normalFont); + + // If has no childrens draw tree node leaf + if (parent.Children.size() <= 0) + base_flags |= ImGuiTreeNodeFlags_Leaf; + + bool open = ImGui::TreeNodeEx(name.c_str(), base_flags); + + + if (ImGui::BeginDragDropSource()) { - base_flags = ImGuiTreeNodeFlags_Leaf; + ImGui::SetDragDropPayload("ENTITY", (void*)&e, sizeof(Entity)); + ImGui::Text(name.c_str()); + ImGui::EndDragDropSource(); } - std::string icon = ICON_FA_FOLDER; - if (is_selected) - icon = ICON_FA_FOLDER_OPEN; - bool open = ImGui::TreeNodeEx((icon + " " + d->name).c_str(), base_flags); - + + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY")) + { + Entity payload_entity = *(const Entity*)payload->Data; + + // Check if entity is already parent. + ParentComponent& parentPayload = payload_entity.GetComponent(); + if (!EntityContainsItself(payload_entity, e) && parentPayload.Parent != e && std::count(parent.Children.begin(), parent.Children.end(), payload_entity) == 0) + { + if (parentPayload.HasParent) + { + // Erase remove idiom. + ParentComponent& childOfParent = parentPayload.Parent.GetComponent(); + childOfParent.Children.erase(std::remove(childOfParent.Children.begin(), childOfParent.Children.end(), payload_entity), childOfParent.Children.end()); + } + + parentPayload.Parent = e; + parentPayload.HasParent = true; + parent.Children.push_back(payload_entity); + } + } + } + + // Click. if (ImGui::IsItemClicked()) - m_CurrentDirectory = d; + { + m_SelectedEntity = e; + m_IsEntitySelected = true; + } + + if (ImGui::BeginPopupContextItem()) + { + if (ImGui::Selectable("Remove")) { + + QueueDeletion = e; + open = false; + } + + if (ImGui::Selectable("Move to root")) + { + auto& p = m_SelectedEntity.GetComponent(); + if (p.HasParent) { + auto& pp = p.Parent.GetComponent(); + pp.RemoveChildren(m_SelectedEntity); + p.HasParent = false; + } + } + ImGui::Selectable("Save as prefab"); + ImGui::EndPopup(); + } if (open) { - if (d->Directories.size() > 0) - EditorInterfaceDrawFiletree(d); + // Caching list to prevent deletion while iterating. + std::vector childrens = parent.Children; + for (auto c : childrens) + DrawEntityTree(c); + ImGui::TreePop(); + } - + ImGui::PopFont(); } -} - -void EditorInterface::DrawFileSystem() -{ - Ref rootDirectory = FileSystem::GetFileTree(); - if (!rootDirectory) - return; -} -void EditorInterface::DrawDirectory(Ref directory) -{ - ImGui::PushFont(bigIconFont); - std::string id = ICON_FA_FOLDER + std::string("##") + directory->name; - if(ImGui::Button(id.c_str(), ImVec2(100, 100))) - m_CurrentDirectory = directory; - ImGui::Text(directory->name.c_str()); - ImGui::PopFont(); -} - -bool EditorInterface::EntityContainsItself(Entity source, Entity target) -{ - ParentComponent& targeParentComponent = target.GetComponent(); - if (!targeParentComponent.HasParent) - return false; - - Entity currentParent = target.GetComponent().Parent; - while (currentParent != source) + void EditorInterface::DrawSceneTree() { - if (currentParent.GetComponent().HasParent) - currentParent = currentParent.GetComponent().Parent; - else - return false; + Ref scene = Engine::GetCurrentScene(); - if (currentParent == source) - return true; - } - return true; -} + if (!scene) + return; -void EditorInterface::DrawFile(Ref file) -{ - ImGui::PushFont(bigIconFont); - if (file->Type == ".png" || file->Type == ".jpg") - { - Ref texture = TextureManager::Get()->GetTexture(file->fullPath); - ImGui::ImageButton((void*)texture->GetID(), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0)); - } - else - { - const char* icon = ICON_FA_FILE; - if (file->Type == ".shader") - icon = ICON_FA_FILE_CODE; - if (file->Type == ".map") - icon = ICON_FA_BROOM; - if (file->Type == ".ogg" || file->Type == ".mp3" || file->Type == ".wav" || file->Type == ".flac") - icon = ICON_FA_FILE_AUDIO; - if(file->Type == ".cpp" || file->Type == ".h" || file->Type == ".cs" || file->Type == ".py" || file->Type == ".lua") - icon = ICON_FA_FILE_CODE; - if (ImGui::Button(icon, ImVec2(100, 100))) + if (ImGui::Begin(" Environnement")) { - if (ImGui::BeginPopupContextItem("item context menu")) + auto env = Engine::GetCurrentScene()->GetEnvironment(); + if (ImGui::CollapsingHeader("Procedural Sky")) { - if (ImGui::Selectable("Set to zero")); - if (ImGui::Selectable("Set to PI")); - ImGui::EndPopup(); + ImGui::DragFloat("Sun Intensity", &env->ProceduralSkybox->SunIntensity, 0.1f, 0.0f); + + glm::vec3 currentDirection = env->ProceduralSkybox->SunDirection; + ImGuiHelper::DrawVec3("Sun Direction", ¤tDirection); + env->ProceduralSkybox->SunDirection = glm::normalize(currentDirection); + + glm::vec3 mieScattering = env->ProceduralSkybox->MieScattering * 10000.0f; + ImGuiHelper::DrawVec3("Mie Scattering", &mieScattering); + env->ProceduralSkybox->MieScattering = mieScattering / 10000.0f; } - } - } - ImGui::Text(file->name.c_str()); - ImGui::PopFont(); - -} - -void EditorInterface::DrawDirectoryExplorer() -{ - if(ImGui::Begin("File browser")) - { - // Wrapping. - int width = ImGui::GetWindowWidth(); - ImVec2 buttonSize = ImVec2(100, 100); - int amount = (width / 100); // -2 because button overflow width + ... button. - int i = 1; // current amount of item per row. - if (ImGui::BeginTable("ssss", amount)) - { - // Button to go up a level. - if (m_CurrentDirectory != FileSystem::RootDirectory) + if (ImGui::CollapsingHeader("Fog")) { - ImGui::TableNextColumn(); - if (ImGui::Button("..", ImVec2(100, 100))) - m_CurrentDirectory = m_CurrentDirectory->Parent; - ImGui::TableNextColumn(); - // Increment item per row tracker. - i++; + ImGui::DragFloat("Volumetric scattering", &env->VolumetricFog, .01f, 0.0f, 1.0f); + ImGui::DragFloat("Volumetric step count", &env->VolumetricStepCount, 1.f, 0.0f); } - // Exit if no current directory. - if (!m_CurrentDirectory) { - ImGui::EndTable(); + } + ImGui::End(); + + std::string title = ICON_FA_TREE + std::string(" Hierarchy"); + if (ImGui::Begin(title.c_str())) + { + // Buttons to add and remove entity. + ImGui::BeginChild("Buttons", ImVec2(300, 20), false); + { + // Add entity. + if (ImGui::Button("Add")) + Engine::GetCurrentScene()->CreateEntity("Entity"); + + ImGui::SameLine(); + + // Remove Entity + if (ImGui::Button("Remove")) + { + scene->DestroyEntity(m_SelectedEntity); + + // Unselect delted entity. + m_SelectedEntity = scene->GetAllEntities().at(0); + } + + } + ImGui::EndChild(); + + ImGui::Separator(); + + // Draw a tree of entities. + std::vector entities = scene->GetAllEntities(); + for (Entity e : entities) + { + ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; + std::string name = e.GetComponent().Name; + // If selected add selected flag. + if (m_SelectedEntity == e) + base_flags |= ImGuiTreeNodeFlags_Selected; + + // Write in normal font. + ImGui::PushFont(normalFont); + + // Small icons + name. + std::string label = ICON_FA_CIRCLE + std::string(" ") + name; + + // Draw all entity without parents. + if (!e.GetComponent().HasParent) + { + // Recursively draw childrens. + DrawEntityTree(e); + + } + + // Pop font. + ImGui::PopFont(); + + // Right click menu + //if (ImGui::BeginPopupContextItem()) + // ImGui::EndPopup(); + } + + // Delete entity + if (QueueDeletion.GetHandle() != 0) + { + Engine::GetCurrentScene()->DestroyEntity(QueueDeletion); + + if (m_SelectedEntity == QueueDeletion) + m_SelectedEntity = scene->GetAllEntities().at(0); + + QueueDeletion = Entity{ (entt::entity)0, scene.get() }; + ImGui::TreePop(); + } + + } + ImGui::End(); + } + + + + void EditorInterface::DrawEntityPropreties() + { + if (ImGui::Begin("Propreties")) + { + if (!m_IsEntitySelected) + { + ImGui::Text("No entity selected"); ImGui::End(); return; } - if (m_CurrentDirectory && m_CurrentDirectory->Directories.size() > 0) - { - for (auto d : m_CurrentDirectory->Directories) + + if (m_SelectedEntity.HasComponent()) { + auto& name = m_SelectedEntity.GetComponent().Name; + + char buffer[256]; + memset(buffer, 0, sizeof(buffer)); + std::strncpy(buffer, name.c_str(), sizeof(buffer)); + ImGui::Text("Name: "); + ImGui::SameLine(); + if (ImGui::InputText("##Name", buffer, sizeof(buffer))) { - DrawDirectory(d); - if (i - 1% amount != 0) - ImGui::TableNextColumn(); - else - ImGui::TableNextRow(); - i++; + name = std::string(buffer); } - } - if (m_CurrentDirectory && m_CurrentDirectory->Files.size() > 0) - { - for (auto f : m_CurrentDirectory->Files) + ImGui::SameLine(); + if (ImGui::Button("Add component")) { - DrawFile(f); - if (i - 1 % amount != 0) - ImGui::TableNextColumn(); - else - ImGui::TableNextRow(); - i++; + ImGui::OpenPopup("add_component_popup"); + + } + if (ImGui::BeginPopup("add_component_popup")) + { + if (ImGui::MenuItem("Wren Script") && !m_SelectedEntity.HasComponent()) + m_SelectedEntity.AddComponent(); + ImGui::Separator(); + if (ImGui::MenuItem("Camera Component") && !m_SelectedEntity.HasComponent()) + m_SelectedEntity.AddComponent(); + ImGui::Separator(); + if (ImGui::MenuItem("Light Component") && !m_SelectedEntity.HasComponent()) + m_SelectedEntity.AddComponent(); + ImGui::Separator(); + if (ImGui::MenuItem("Model Component") && !m_SelectedEntity.HasComponent()) + m_SelectedEntity.AddComponent(); + if (ImGui::MenuItem("Quake map Component") && !m_SelectedEntity.HasComponent()) + m_SelectedEntity.AddComponent(); + ImGui::Separator(); + if (ImGui::MenuItem("Character controller") && !m_SelectedEntity.HasComponent()) + m_SelectedEntity.AddComponent(); + if (ImGui::MenuItem("Rigidbody Component") && !m_SelectedEntity.HasComponent()) + { + m_SelectedEntity.AddComponent(); + auto transformComponent = m_SelectedEntity.GetComponent(); + } + if (ImGui::MenuItem("Box collider Component") && !m_SelectedEntity.HasComponent()) + { + m_SelectedEntity.AddComponent(); + } + if (ImGui::MenuItem("Sphere collider Component") && !m_SelectedEntity.HasComponent()) + { + m_SelectedEntity.AddComponent(); + } + if (ImGui::MenuItem("Mesh collider Component") && !m_SelectedEntity.HasComponent()) + { + m_SelectedEntity.AddComponent(); + } + + // your popup code + ImGui::EndPopup(); + } + ImGui::Separator(); + } + + ImGui::PushFont(normalFont); + std::string iconTransform = ICON_FA_MAP_MARKER; + if (ImGui::CollapsingHeader((iconTransform + " Transform").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Transform properties"); + //ImGui::InputText("Name:", selectedEntity->m_Name.data(), 12); + TransformComponent& component = m_SelectedEntity.GetComponent(); + ImGuiHelper::DrawVec3("Translation", &component.Translation); + ImGuiHelper::DrawVec3("Rotation", &component.Rotation); + ImGuiHelper::DrawVec3("Scale", &component.Scale); + ImGui::Separator(); + } + + if (m_SelectedEntity.HasComponent()) { + std::string icon = ICON_FA_MALE; + if (ImGui::CollapsingHeader((icon + " " + "Model").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Model properties"); + auto& component = m_SelectedEntity.GetComponent(); + // Path + std::string path = component.ModelPath; + char pathBuffer[256]; + + memset(pathBuffer, 0, sizeof(pathBuffer)); + std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer)); + + std::string oldPath = component.ModelPath; + ImGui::Text("Model: "); + ImGui::SameLine(); + if (ImGui::InputText("##ModelPath", pathBuffer, sizeof(pathBuffer))) + path = FileSystem::AbsoluteToRelative(std::string(pathBuffer)); + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Model")) + { + char* file = (char*)payload->Data; + std::string fullPath = std::string(file, 256); + path = FileSystem::AbsoluteToRelative(fullPath); + } + ImGui::EndDragDropTarget(); + } + + if (component.ModelPath != path) + { + component.ModelPath = path; + component.LoadModel(); + } + + + if (ImGui::Button("Reimport")) + { + component.LoadModel(); + } + + + ImGui::Separator(); + } + + } + + if (m_SelectedEntity.HasComponent()) { + std::string icon = ICON_FA_LIGHTBULB; + if (ImGui::CollapsingHeader((icon + " " + "Light").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + m_SelectedEntity.GetComponent().DrawEditor(); + ImGui::Separator(); + } + + } + + if (m_SelectedEntity.HasComponent()) { + std::string icon = ICON_FA_FILE; + if (ImGui::CollapsingHeader((icon + " " + "Wren Script").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Script properties"); + auto& component = m_SelectedEntity.GetComponent(); + + // Path + std::string path = component.Script; + char pathBuffer[256]; + + memset(pathBuffer, 0, sizeof(pathBuffer)); + std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer)); + + ImGui::Text("Script: "); + ImGui::SameLine(); + if (ImGui::InputText("##ScriptPath", pathBuffer, sizeof(pathBuffer))) + path = FileSystem::AbsoluteToRelative(std::string(pathBuffer)); + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script")) + { + char* file = (char*)payload->Data; + std::string fullPath = std::string(file, 256); + path = FileSystem::AbsoluteToRelative(fullPath); + } + ImGui::EndDragDropTarget(); + } + + + component.Script = path; + + // Class + std::string module = component.Class; + + char classBuffer[256]; + + memset(classBuffer, 0, sizeof(classBuffer)); + std::strncpy(classBuffer, module.c_str(), sizeof(classBuffer)); + + ImGui::Text("Class: "); + ImGui::SameLine(); + if (ImGui::InputText("##ScriptModule", classBuffer, sizeof(classBuffer))) + module = std::string(classBuffer); + + component.Class = module; + ImGui::Separator(); } } - + if (m_SelectedEntity.HasComponent()) { + + std::string icon = ICON_FA_LIGHTBULB; + if (ImGui::CollapsingHeader((icon + " " + "Camera").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Camera properties"); + m_SelectedEntity.GetComponent().DrawEditor(); + ImGui::Separator(); + } + + } + + if (m_SelectedEntity.HasComponent()) + { + if (ImGui::CollapsingHeader("Character controller", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Character controller properties"); + auto& c = m_SelectedEntity.GetComponent(); + ImGui::InputFloat("Height", &c.Height); + ImGui::InputFloat("Radius", &c.Radius); + ImGui::InputFloat("Mass", &c.Mass); + ImGui::Separator(); + } + } + + if (m_SelectedEntity.HasComponent()) { + + std::string icon = ICON_FA_TREE; + if (ImGui::CollapsingHeader((icon + " " + "Mesh").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Mesh properties"); + ImGui::Button("Drag Material"); + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_DEMO_CELL")) + { + IM_ASSERT(payload->DataSize == sizeof(int)); + int payload_n = *(const int*)payload->Data; + + } + ImGui::EndDragDropTarget(); + } + } + + } + + if (m_SelectedEntity.HasComponent()) + { + std::string icon = ICON_FA_BOWLING_BALL; + if (ImGui::CollapsingHeader((icon + " Rigidbody").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Rigidbody properties"); + RigidBodyComponent& rbComponent = m_SelectedEntity.GetComponent(); + ImGui::DragFloat("Mass", &rbComponent.mass, 0.1, 0.0); + ImGui::Separator(); + } + } + + if (m_SelectedEntity.HasComponent()) + { + std::string icon = ICON_FA_BOX; + if (ImGui::CollapsingHeader((icon + " Box collider").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Box collider properties"); + BoxColliderComponent& component = m_SelectedEntity.GetComponent(); + ImGuiHelper::DrawVec3("Size", &component.Size); + ImGui::Checkbox("Is trigger", &component.IsTrigger); + + ImGui::Separator(); + } + } + if (m_SelectedEntity.HasComponent()) + { + std::string icon = ICON_FA_CIRCLE; + if (ImGui::CollapsingHeader((icon + " Sphere collider").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Sphere properties"); + SphereColliderComponent& component = m_SelectedEntity.GetComponent(); + ImGui::DragFloat("Radius", &component.Radius, 0.1f, 0.0f, 100.0f); + ImGui::Checkbox("Is trigger", &component.IsTrigger); + + ImGui::Separator(); + } + } + if (m_SelectedEntity.HasComponent()) + { + std::string icon = ICON_FA_BROOM; + if (ImGui::CollapsingHeader((icon + " " + "Quake map").c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Quake map properties"); + auto& component = m_SelectedEntity.GetComponent(); + std::string path = component.Path; + + + char pathBuffer[256]; + memset(pathBuffer, 0, sizeof(pathBuffer)); + std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer)); + ImGui::Text("Map file: "); + ImGui::SameLine(); + if (ImGui::InputText("##MapPath", pathBuffer, sizeof(pathBuffer))) + { + path = std::string(pathBuffer); + } + + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Map")) + { + char* file = (char*)payload->Data; + std::string fullPath = std::string(file, 256); + path = FileSystem::AbsoluteToRelative(fullPath); + } + ImGui::EndDragDropTarget(); + } + + component.Path = path; + + ImGui::Checkbox("Build collisions", &component.HasCollisions); + if (ImGui::Button("Build Geometry")) + { + QuakeMapBuilder mapBuilder; + mapBuilder.BuildQuakeMap(m_SelectedEntity); + } + ImGui::Separator(); + } + } + + ImGui::PopFont(); } - - ImGui::EndTable(); + ImGui::End(); } - ImGui::End(); -} - -bool LogErrors = true; -bool LogWarnings = true; -bool LogDebug = true; -void EditorInterface::DrawLogger() -{ - if (ImGui::Begin("Logger")) + void EditorInterface::DrawGizmos() { - ImGui::Checkbox("Errors", &LogErrors); - ImGui::SameLine(); - ImGui::Checkbox("Warning", &LogWarnings); - ImGui::SameLine(); - ImGui::Checkbox("Debug", &LogDebug); + Ref scene = Engine::GetCurrentScene(); - //ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); - //if (ImGui::BeginChild("Log window", ImGui::GetContentRegionAvail(), false)) - //{ - //ImGui::PopStyleVar(); + if (!m_IsEntitySelected) + return; + } + + void EditorInterface::EditorInterfaceDrawFiletree(Ref dir) + { + for (auto d : dir->Directories) + { + ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; + bool is_selected = m_CurrentDirectory == d; + if (is_selected) + base_flags |= ImGuiTreeNodeFlags_Selected; + + if (d->Directories.size() == 0) + { + base_flags = ImGuiTreeNodeFlags_Leaf; + } + std::string icon = ICON_FA_FOLDER; + if (is_selected) + icon = ICON_FA_FOLDER_OPEN; + bool open = ImGui::TreeNodeEx((icon + " " + d->name).c_str(), base_flags); + + if (ImGui::IsItemClicked()) + m_CurrentDirectory = d; + if (open) + { + if (d->Directories.size() > 0) + EditorInterfaceDrawFiletree(d); + ImGui::TreePop(); + } + + } + } + + void EditorInterface::DrawFileSystem() + { + Ref rootDirectory = FileSystem::GetFileTree(); + if (!rootDirectory) + return; + + + + } + + void EditorInterface::DrawDirectory(Ref directory) + { + ImGui::PushFont(bigIconFont); + std::string id = ICON_FA_FOLDER + std::string("##") + directory->name; + if (ImGui::Button(id.c_str(), ImVec2(100, 100))) + m_CurrentDirectory = directory; + ImGui::Text(directory->name.c_str()); + ImGui::PopFont(); + } + + bool EditorInterface::EntityContainsItself(Entity source, Entity target) + { + ParentComponent& targeParentComponent = target.GetComponent(); + if (!targeParentComponent.HasParent) + return false; + + Entity currentParent = target.GetComponent().Parent; + while (currentParent != source) + { + if (currentParent.GetComponent().HasParent) + currentParent = currentParent.GetComponent().Parent; + else + return false; + + if (currentParent == source) + return true; + } + return true; + } + + void EditorInterface::DrawFile(Ref file) + { + ImGui::PushFont(bigIconFont); + if (file->Type == ".png" || file->Type == ".jpg") + { + Ref texture = TextureManager::Get()->GetTexture(file->fullPath); + ImGui::ImageButton((void*)texture->GetID(), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0)); + } + else + { + const char* icon = ICON_FA_FILE; + if (file->Type == ".shader") + icon = ICON_FA_FILE_CODE; + if (file->Type == ".map") + icon = ICON_FA_BROOM; + if (file->Type == ".ogg" || file->Type == ".mp3" || file->Type == ".wav" || file->Type == ".flac") + icon = ICON_FA_FILE_AUDIO; + if (file->Type == ".cpp" || file->Type == ".h" || file->Type == ".cs" || file->Type == ".py" || file->Type == ".lua") + icon = ICON_FA_FILE_CODE; + if (ImGui::Button(icon, ImVec2(100, 100))) + { + if (ImGui::BeginPopupContextItem("item context menu")) + { + if (ImGui::Selectable("Set to zero")); + if (ImGui::Selectable("Set to PI")); + ImGui::EndPopup(); + } + } + } + ImGui::Text(file->name.c_str()); + ImGui::PopFont(); + + } + + void EditorInterface::DrawDirectoryExplorer() + { + if (ImGui::Begin("File browser")) + { + // Wrapping. + int width = ImGui::GetWindowWidth(); + ImVec2 buttonSize = ImVec2(100, 100); + int amount = (width / 100); // -2 because button overflow width + ... button. + int i = 1; // current amount of item per row. + if (ImGui::BeginTable("ssss", amount)) + { + // Button to go up a level. + if (m_CurrentDirectory != FileSystem::RootDirectory) + { + ImGui::TableNextColumn(); + if (ImGui::Button("..", ImVec2(100, 100))) + m_CurrentDirectory = m_CurrentDirectory->Parent; + ImGui::TableNextColumn(); + // Increment item per row tracker. + i++; + } + + // Exit if no current directory. + if (!m_CurrentDirectory) { + ImGui::EndTable(); + ImGui::End(); + return; + } + + if (m_CurrentDirectory && m_CurrentDirectory->Directories.size() > 0) + { + for (auto d : m_CurrentDirectory->Directories) + { + DrawDirectory(d); + if (i - 1 % amount != 0) + ImGui::TableNextColumn(); + else + ImGui::TableNextRow(); + i++; + } + } + if (m_CurrentDirectory && m_CurrentDirectory->Files.size() > 0) + { + for (auto f : m_CurrentDirectory->Files) + { + DrawFile(f); + if (i - 1 % amount != 0) + ImGui::TableNextColumn(); + else + ImGui::TableNextRow(); + i++; + } + } + + + } + + ImGui::EndTable(); + } + ImGui::End(); + } + + bool LogErrors = true; + bool LogWarnings = true; + bool LogDebug = true; + void EditorInterface::DrawLogger() + { + if (ImGui::Begin("Logger")) + { + ImGui::Checkbox("Errors", &LogErrors); + ImGui::SameLine(); + ImGui::Checkbox("Warning", &LogWarnings); + ImGui::SameLine(); + ImGui::Checkbox("Debug", &LogDebug); + + //ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + //if (ImGui::BeginChild("Log window", ImGui::GetContentRegionAvail(), false)) + //{ + //ImGui::PopStyleVar(); ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; if (ImGui::BeginTable("LogTable", 3, flags)) @@ -867,477 +869,478 @@ void EditorInterface::DrawLogger() ImGui::EndTable(); } - + //ImGui::EndChild(); //} - - - } - ImGui::End(); -} - -void EditorInterface::Overlay() -{ - // FIXME-VIEWPORT: Select a default viewport - const float DISTANCE = 10.0f; - static int corner = 3; - ImGuiIO& io = ImGui::GetIO(); - ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav; - if (corner != -1) - { - window_flags |= ImGuiWindowFlags_NoMove; - ImGuiViewport* viewport = ImGui::GetWindowViewport(); - ImVec2 work_area_pos = ImGui::GetCurrentWindow()->Pos; // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any! - ImVec2 work_area_size = ImGui::GetCurrentWindow()->Size; - ImVec2 window_pos = ImVec2((corner & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE)); - ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); - ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); - ImGui::SetNextWindowViewport(viewport->ID); - } - ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background - if (ImGui::Begin("Example: Simple overlay", &m_ShowOverlay, window_flags)) - { - ImGui::Text("Developpement build 0.1"); - ImGui::Separator(); - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); - if (ImGui::BeginPopupContextWindow()) - { - if (ImGui::MenuItem("Custom", NULL, corner == -1)) corner = -1; - if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0; - if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; - if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; - if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3; - if (m_ShowOverlay && ImGui::MenuItem("Close")) m_ShowOverlay = false; - ImGui::EndPopup(); } - - + ImGui::End(); } - ImGui::End(); -} -void EditorInterface::DrawRessourceWindow() -{ - std::map> materials = MaterialManager::Get()->GetAllMaterials(); - if(ImGui::Begin("Materials")) + void EditorInterface::Overlay() { - int width = ImGui::GetWindowWidth(); - ImVec2 buttonSize = ImVec2(100, 100); - int amount = (width / 100) - 1; - if (amount > 0) + // FIXME-VIEWPORT: Select a default viewport + const float DISTANCE = 10.0f; + static int corner = 3; + ImGuiIO& io = ImGui::GetIO(); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav; + if (corner != -1) { - int i = 1; - for (auto m : materials) + window_flags |= ImGuiWindowFlags_NoMove; + ImGuiViewport* viewport = ImGui::GetWindowViewport(); + ImVec2 work_area_pos = ImGui::GetCurrentWindow()->Pos; // Instead of using viewport->Pos we use GetWorkPos() to avoid menu bars, if any! + ImVec2 work_area_size = ImGui::GetCurrentWindow()->Size; + ImVec2 window_pos = ImVec2((corner & 1) ? (work_area_pos.x + work_area_size.x - DISTANCE) : (work_area_pos.x + DISTANCE), (corner & 2) ? (work_area_pos.y + work_area_size.y - DISTANCE) : (work_area_pos.y + DISTANCE)); + ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); + ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); + ImGui::SetNextWindowViewport(viewport->ID); + } + ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background + if (ImGui::Begin("Example: Simple overlay", &m_ShowOverlay, window_flags)) + { + ImGui::Text("Developpement build 0.1"); + ImGui::Separator(); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); + if (ImGui::BeginPopupContextWindow()) { - unsigned int textureID = 0; - if (m.second->HasAlbedo()) - textureID = m.second->m_Albedo->GetID(); - std::string id = "materialButton" + std::to_string(i); - if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID(id.c_str()), (void*)textureID, ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) - { - m_SelectedMaterial = m.second; - m_IsMaterialSelected = true; - } - if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) - { - // Set payload to carry the index of our item (could be anything) - ImGui::SetDragDropPayload("MaterialName", &m.first, sizeof(int)); + if (ImGui::MenuItem("Custom", NULL, corner == -1)) corner = -1; + if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0; + if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; + if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; + if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3; + if (m_ShowOverlay && ImGui::MenuItem("Close")) m_ShowOverlay = false; + ImGui::EndPopup(); + } - // Display preview (could be anything, e.g. when dragging an image we could decide to display - // the filename and a small preview of the image, etc.) - ImGui::Text("hello"); - ImGui::EndDragDropSource(); + + } + ImGui::End(); + } + + + void EditorInterface::DrawRessourceWindow() + { + std::map> materials = MaterialManager::Get()->GetAllMaterials(); + + if (ImGui::Begin("Materials")) + { + int width = ImGui::GetWindowWidth(); + ImVec2 buttonSize = ImVec2(100, 100); + int amount = (width / 100) - 1; + if (amount > 0) + { + int i = 1; + for (auto m : materials) + { + unsigned int textureID = 0; + if (m.second->HasAlbedo()) + textureID = m.second->m_Albedo->GetID(); + std::string id = "materialButton" + std::to_string(i); + if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID(id.c_str()), (void*)textureID, ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) + { + m_SelectedMaterial = m.second; + m_IsMaterialSelected = true; + } + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) + { + // Set payload to carry the index of our item (could be anything) + ImGui::SetDragDropPayload("MaterialName", &m.first, sizeof(int)); + + // Display preview (could be anything, e.g. when dragging an image we could decide to display + // the filename and a small preview of the image, etc.) + ImGui::Text("hello"); + ImGui::EndDragDropSource(); + } + if (i % amount != 0) + ImGui::SameLine(); + i++; } - if (i % amount != 0) + } + + + } + ImGui::End(); + if (ImGui::Begin("Material property")) + { + if (m_IsMaterialSelected) + { + if (ImGui::CollapsingHeader("Albedo", ImGuiTreeNodeFlags_DefaultOpen)) + { + unsigned int textureID = 0; + if (m_SelectedMaterial->HasAlbedo()) + textureID = m_SelectedMaterial->m_Albedo->GetID(); + if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image1"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) + { + std::string texture = FileDialog::OpenFile("*.png | *.jpg"); + } ImGui::SameLine(); - i++; - } - } - - - } - ImGui::End(); - if(ImGui::Begin("Material property")) - { - if (m_IsMaterialSelected) - { - if (ImGui::CollapsingHeader("Albedo", ImGuiTreeNodeFlags_DefaultOpen)) - { - unsigned int textureID = 0; - if (m_SelectedMaterial->HasAlbedo()) - textureID = m_SelectedMaterial->m_Albedo->GetID(); - if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image1"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) - { - std::string texture = FileDialog::OpenFile("*.png | *.jpg"); + //ImGui::Checkbox("Use##1", &(bool)(m_SelectedMaterial->data.u_HasAlbedo)); + ImGui::SameLine(); + ImGui::ColorPicker3("Color", &m_SelectedMaterial->data.m_AlbedoColor.r); } - ImGui::SameLine(); - //ImGui::Checkbox("Use##1", &(bool)(m_SelectedMaterial->data.u_HasAlbedo)); - ImGui::SameLine(); - ImGui::ColorPicker3("Color", &m_SelectedMaterial->data.m_AlbedoColor.r); - } - if (ImGui::CollapsingHeader("AO", ImGuiTreeNodeFlags_DefaultOpen)) - { - unsigned int textureID = 0; - if (m_SelectedMaterial->HasAO()) - textureID = m_SelectedMaterial->m_AO->GetID(); - if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image2"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(1, 1, 1, 1), ImVec4(1, 1, 1, 1))) + if (ImGui::CollapsingHeader("AO", ImGuiTreeNodeFlags_DefaultOpen)) { - std::string texture = FileDialog::OpenFile("Image files (*.png) | *.png | Image files (*.jpg) | *.jpg"); - if (texture != "") + unsigned int textureID = 0; + if (m_SelectedMaterial->HasAO()) + textureID = m_SelectedMaterial->m_AO->GetID(); + if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image2"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(1, 1, 1, 1), ImVec4(1, 1, 1, 1))) { - m_SelectedMaterial->SetAO(TextureManager::Get()->GetTexture(texture)); + std::string texture = FileDialog::OpenFile("Image files (*.png) | *.png | Image files (*.jpg) | *.jpg"); + if (texture != "") + { + m_SelectedMaterial->SetAO(TextureManager::Get()->GetTexture(texture)); + } } + ImGui::SameLine(); + //ImGui::Checkbox("Use##2", &m_SelectedMaterial->data.u_HasAO); + ImGui::SameLine(); + ImGui::DragFloat("Value##2", &m_SelectedMaterial->data.u_AOValue, 0.01f, 0.0f, 1.0f); } - ImGui::SameLine(); - //ImGui::Checkbox("Use##2", &m_SelectedMaterial->data.u_HasAO); - ImGui::SameLine(); - ImGui::DragFloat("Value##2", &m_SelectedMaterial->data.u_AOValue, 0.01f, 0.0f, 1.0f); - } - if (ImGui::CollapsingHeader("Normal", ImGuiTreeNodeFlags_DefaultOpen)) - { - unsigned int textureID = 0; - if (m_SelectedMaterial->HasNormal()) - textureID = m_SelectedMaterial->m_Normal->GetID(); - if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image3"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2,2), ImVec4(0,0,0,1), ImVec4(1, 1, 1, 1))) + if (ImGui::CollapsingHeader("Normal", ImGuiTreeNodeFlags_DefaultOpen)) { - std::string texture = FileDialog::OpenFile("*.png"); - if (texture != "") + unsigned int textureID = 0; + if (m_SelectedMaterial->HasNormal()) + textureID = m_SelectedMaterial->m_Normal->GetID(); + if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image3"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 1), ImVec4(1, 1, 1, 1))) { - m_SelectedMaterial->SetNormal(TextureManager::Get()->GetTexture(texture)); + std::string texture = FileDialog::OpenFile("*.png"); + if (texture != "") + { + m_SelectedMaterial->SetNormal(TextureManager::Get()->GetTexture(texture)); + } } + //ImGui::SameLine(); + //ImGui::Checkbox("Use##3", &m_SelectedMaterial->data.u_HasNormal); } - //ImGui::SameLine(); - //ImGui::Checkbox("Use##3", &m_SelectedMaterial->data.u_HasNormal); - } - if (ImGui::CollapsingHeader("Metalness", ImGuiTreeNodeFlags_DefaultOpen)) - { - unsigned int textureID = 0; - if (m_SelectedMaterial->HasMetalness()) - textureID = m_SelectedMaterial->m_Metalness->GetID(); - if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image4"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 1), ImVec4(1, 1, 1, 1))) + if (ImGui::CollapsingHeader("Metalness", ImGuiTreeNodeFlags_DefaultOpen)) { - std::string texture = FileDialog::OpenFile("*.png | *.jpg"); + unsigned int textureID = 0; + if (m_SelectedMaterial->HasMetalness()) + textureID = m_SelectedMaterial->m_Metalness->GetID(); + if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image4"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 1), ImVec4(1, 1, 1, 1))) + { + std::string texture = FileDialog::OpenFile("*.png | *.jpg"); + } + ImGui::SameLine(); + //ImGui::Checkbox("Use##4", &m_SelectedMaterial->data.u_HasMetalness); + ImGui::SameLine(); + ImGui::DragFloat("Value##4", &m_SelectedMaterial->data.u_MetalnessValue, 0.01f, 0.0f, 1.0f); } - ImGui::SameLine(); - //ImGui::Checkbox("Use##4", &m_SelectedMaterial->data.u_HasMetalness); - ImGui::SameLine(); - ImGui::DragFloat("Value##4", &m_SelectedMaterial->data.u_MetalnessValue, 0.01f, 0.0f, 1.0f); - } - if (ImGui::CollapsingHeader("Roughness", ImGuiTreeNodeFlags_DefaultOpen)) - { - unsigned int textureID = 0; - if (m_SelectedMaterial->HasRougness()) - textureID = m_SelectedMaterial->m_Roughness->GetID(); - if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image5"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) + if (ImGui::CollapsingHeader("Roughness", ImGuiTreeNodeFlags_DefaultOpen)) { - std::string texture = FileDialog::OpenFile("*.png | *.jpg"); + unsigned int textureID = 0; + if (m_SelectedMaterial->HasRougness()) + textureID = m_SelectedMaterial->m_Roughness->GetID(); + if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image5"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2, 2), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) + { + std::string texture = FileDialog::OpenFile("*.png | *.jpg"); + } + ImGui::SameLine(); + //ImGui::Checkbox("Use##5", &m_SelectedMaterial->data.u_HasRoughness); + ImGui::SameLine(); + ImGui::DragFloat("Value##5", &m_SelectedMaterial->data.u_RoughnessValue, 0.01f, 0.0f, 1.0f); } - ImGui::SameLine(); - //ImGui::Checkbox("Use##5", &m_SelectedMaterial->data.u_HasRoughness); - ImGui::SameLine(); - ImGui::DragFloat("Value##5", &m_SelectedMaterial->data.u_RoughnessValue, 0.01f, 0.0f, 1.0f); } - } - else - { - ImGui::Text("No material selected."); - } - - - } - ImGui::End(); -} - -void NewProject() -{ - if (Engine::GetProject()) - Engine::GetProject()->Save(); - - // Parse the project and load it. - std::string selectedProject = FileDialog::SaveFile(".project") + ".project"; - - - Ref project = Project::New("Unnamed project", "no description", selectedProject); - project->FullPath = selectedProject; - Engine::LoadProject(project); - - Ref scene = Scene::New(); - Engine::LoadScene(scene); -} - - -ProjectInterface pInterface; -void OpenProject() -{ - // Parse the project and load it. - std::string projectPath = FileDialog::OpenFile(".project"); - - FileSystem::SetRootDirectory(projectPath + "/../"); - Ref project = Project::New(); - if (!project->Deserialize(FileSystem::ReadFile(projectPath, true))) - { - Logger::Log("Error loading project: " + projectPath, CRITICAL); - return; - } - - project->FullPath = projectPath; - Engine::LoadProject(project); - - pInterface.m_CurrentProject = project; - // Create new interface named test. - //userInterface = UI::UserInterface::New("test"); - - - // Set current interface running. - //Engine::GetCurrentScene()->AddInterface(userInterface); -} - -void OpenScene() -{ - // Parse the project and load it. - std::string projectPath = FileDialog::OpenFile(".scene"); - - Ref scene = Scene::New(); - if (!scene->Deserialize(FileSystem::ReadFile(projectPath, true))) { - Logger::Log("Error failed loading scene: " + projectPath, CRITICAL); - return; - } - - scene->Path = FileSystem::AbsoluteToRelative(projectPath); - Engine::LoadScene(scene); -} - -void EditorInterface::DrawInit() -{ - -} - -void EditorInterface::Draw() -{ - Init(); - auto flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize; - - if (ImGui::BeginPopupModal("Welcome", NULL, flags)) - { - ImGui::Text("Welcome to"); - ImGui::Text("Nuake engine"); - - ImGui::Text("Would you like to"); - if (ImGui::Button("Start a new project")) - NewProject(); - - ImGui::SameLine(); - if (ImGui::Button("Open a project")) { - OpenProject(); - filesystem.m_CurrentDirectory = FileSystem::RootDirectory; - } - - - ImGui::EndPopup(); - } - if (!Engine::GetProject()) - { - ImGui::OpenPopup("Welcome"); - - return; - } - - if (ImGui::BeginMainMenuBar()) - { - if (ImGui::BeginMenu("File")) - { - if (ImGui::MenuItem("New project", "CTRL+N")) + else { + ImGui::Text("No material selected."); + } + + + } + ImGui::End(); + } + + void NewProject() + { + if (Engine::GetProject()) + Engine::GetProject()->Save(); + + // Parse the project and load it. + std::string selectedProject = FileDialog::SaveFile(".project") + ".project"; + + + Ref project = Project::New("Unnamed project", "no description", selectedProject); + project->FullPath = selectedProject; + Engine::LoadProject(project); + + Ref scene = Scene::New(); + Engine::LoadScene(scene); + } + + + ProjectInterface pInterface; + void OpenProject() + { + // Parse the project and load it. + std::string projectPath = FileDialog::OpenFile(".project"); + + FileSystem::SetRootDirectory(projectPath + "/../"); + Ref project = Project::New(); + if (!project->Deserialize(FileSystem::ReadFile(projectPath, true))) + { + Logger::Log("Error loading project: " + projectPath, CRITICAL); + return; + } + + project->FullPath = projectPath; + Engine::LoadProject(project); + + pInterface.m_CurrentProject = project; + // Create new interface named test. + //userInterface = UI::UserInterface::New("test"); + + + // Set current interface running. + //Engine::GetCurrentScene()->AddInterface(userInterface); + } + + void OpenScene() + { + // Parse the project and load it. + std::string projectPath = FileDialog::OpenFile(".scene"); + + Ref scene = Scene::New(); + if (!scene->Deserialize(FileSystem::ReadFile(projectPath, true))) { + Logger::Log("Error failed loading scene: " + projectPath, CRITICAL); + return; + } + + scene->Path = FileSystem::AbsoluteToRelative(projectPath); + Engine::LoadScene(scene); + } + + void EditorInterface::DrawInit() + { + + } + + void EditorInterface::Draw() + { + Init(); + auto flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize; + + if (ImGui::BeginPopupModal("Welcome", NULL, flags)) + { + ImGui::Text("Welcome to"); + ImGui::Text("Nuake engine"); + + ImGui::Text("Would you like to"); + if (ImGui::Button("Start a new project")) NewProject(); - m_IsEntitySelected = false; - } - if (ImGui::MenuItem("Open...", "CTRL+O")) - { + ImGui::SameLine(); + if (ImGui::Button("Open a project")) { OpenProject(); - - m_IsEntitySelected = false; - } - if (ImGui::MenuItem("Save", "CTRL+S")) - { - Engine::GetProject()->Save(); - Engine::GetCurrentScene()->Save(); - - m_IsEntitySelected = false; - } - if (ImGui::MenuItem("Save as...", "CTRL+SHIFT+S")) - { - std::string savePath = FileDialog::SaveFile("*.project"); - Engine::GetProject()->SaveAs(savePath); - - m_IsEntitySelected = false; - } - ImGui::Separator(); - if (ImGui::MenuItem("Set current scene as default")) { - Engine::GetProject()->DefaultScene = Engine::GetCurrentScene(); - } - ImGui::Separator(); - if (ImGui::MenuItem("Open scene...", "CTRL+O")) - { - OpenScene(); - m_IsEntitySelected = false; - } - if (ImGui::MenuItem("Save scene", "CTRL+S")) - { - Engine::GetCurrentScene()->Save(); - - m_IsEntitySelected = false; - } - if (ImGui::MenuItem("Save scene as...", "CTRL+SHIFT+S")) - { - std::string savePath = FileDialog::SaveFile("*.scene"); - Engine::GetCurrentScene()->SaveAs(savePath); - - m_IsEntitySelected = false; + filesystem.m_CurrentDirectory = FileSystem::RootDirectory; } - ImGui::EndMenu(); + + ImGui::EndPopup(); } - if (ImGui::BeginMenu("Edit")) + if (!Engine::GetProject()) { - if (ImGui::MenuItem("Undo", "CTRL+Z")) {} - if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item - ImGui::Separator(); - if (ImGui::MenuItem("Cut", "CTRL+X")) {} - if (ImGui::MenuItem("Copy", "CTRL+C")) {} - if (ImGui::MenuItem("Paste", "CTRL+V")) {} - ImGui::EndMenu(); + ImGui::OpenPopup("Welcome"); + + return; } - if (ImGui::BeginMenu("View")) + + if (ImGui::BeginMainMenuBar()) { - if (ImGui::MenuItem("Reload Interfaces", NULL)) + if (ImGui::BeginMenu("File")) { - Engine::GetCurrentScene()->ReloadInterfaces(); - } - if (ImGui::MenuItem("Lighting", NULL, true)) {} - if (ImGui::MenuItem("Draw grid", NULL, m_DrawGrid)) - m_DrawGrid = !m_DrawGrid; - if (ImGui::MenuItem("Draw collisions", NULL, m_DebugCollisions)) - { - m_DebugCollisions = !m_DebugCollisions; - PhysicsManager::Get()->SetDrawDebug(m_DebugCollisions); - } - - if (ImGui::MenuItem("Settings", NULL)) {} - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Entity")) - { - if (ImGui::BeginMenu("Create new")) - { - if (ImGui::MenuItem("Empty")) { - auto ent = Engine::GetCurrentScene()->CreateEntity("Empty entity"); - } - if (ImGui::MenuItem("Light")) { - auto ent = Engine::GetCurrentScene()->CreateEntity("Light"); - ent.AddComponent(); - } - if (ImGui::MenuItem("Camera")) { - auto ent = Engine::GetCurrentScene()->CreateEntity("Camera"); - ent.AddComponent(); - } - if (ImGui::MenuItem("Rigidbody")) + if (ImGui::MenuItem("New project", "CTRL+N")) { - auto ent = Engine::GetCurrentScene()->CreateEntity("Rigidbody"); - ent.AddComponent(); + NewProject(); + + m_IsEntitySelected = false; } - if (ImGui::MenuItem("Trenchbroom map")) + if (ImGui::MenuItem("Open...", "CTRL+O")) { - auto ent = Engine::GetCurrentScene()->CreateEntity("Trenchbroom map"); - ent.AddComponent(); + OpenProject(); + + m_IsEntitySelected = false; } - if (ImGui::MenuItem("Mesh")) { - auto ent = Engine::GetCurrentScene()->CreateEntity("Mesh"); - ent.AddComponent(); + if (ImGui::MenuItem("Save", "CTRL+S")) + { + Engine::GetProject()->Save(); + Engine::GetCurrentScene()->Save(); + + m_IsEntitySelected = false; + } + if (ImGui::MenuItem("Save as...", "CTRL+SHIFT+S")) + { + std::string savePath = FileDialog::SaveFile("*.project"); + Engine::GetProject()->SaveAs(savePath); + + m_IsEntitySelected = false; + } + ImGui::Separator(); + if (ImGui::MenuItem("Set current scene as default")) { + Engine::GetProject()->DefaultScene = Engine::GetCurrentScene(); + } + ImGui::Separator(); + if (ImGui::MenuItem("Open scene...", "CTRL+O")) + { + OpenScene(); + m_IsEntitySelected = false; + } + if (ImGui::MenuItem("Save scene", "CTRL+S")) + { + Engine::GetCurrentScene()->Save(); + + m_IsEntitySelected = false; + } + if (ImGui::MenuItem("Save scene as...", "CTRL+SHIFT+S")) + { + std::string savePath = FileDialog::SaveFile("*.scene"); + Engine::GetCurrentScene()->SaveAs(savePath); + + m_IsEntitySelected = false; + } + + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Edit")) + { + if (ImGui::MenuItem("Undo", "CTRL+Z")) {} + if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item + ImGui::Separator(); + if (ImGui::MenuItem("Cut", "CTRL+X")) {} + if (ImGui::MenuItem("Copy", "CTRL+C")) {} + if (ImGui::MenuItem("Paste", "CTRL+V")) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("View")) + { + if (ImGui::MenuItem("Reload Interfaces", NULL)) + { + Engine::GetCurrentScene()->ReloadInterfaces(); + } + if (ImGui::MenuItem("Lighting", NULL, true)) {} + if (ImGui::MenuItem("Draw grid", NULL, m_DrawGrid)) + m_DrawGrid = !m_DrawGrid; + if (ImGui::MenuItem("Draw collisions", NULL, m_DebugCollisions)) + { + m_DebugCollisions = !m_DebugCollisions; + PhysicsManager::Get()->SetDrawDebug(m_DebugCollisions); + } + + if (ImGui::MenuItem("Settings", NULL)) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Entity")) + { + if (ImGui::BeginMenu("Create new")) + { + if (ImGui::MenuItem("Empty")) { + auto ent = Engine::GetCurrentScene()->CreateEntity("Empty entity"); + } + if (ImGui::MenuItem("Light")) { + auto ent = Engine::GetCurrentScene()->CreateEntity("Light"); + ent.AddComponent(); + } + if (ImGui::MenuItem("Camera")) { + auto ent = Engine::GetCurrentScene()->CreateEntity("Camera"); + ent.AddComponent(); + } + if (ImGui::MenuItem("Rigidbody")) + { + auto ent = Engine::GetCurrentScene()->CreateEntity("Rigidbody"); + ent.AddComponent(); + } + if (ImGui::MenuItem("Trenchbroom map")) + { + auto ent = Engine::GetCurrentScene()->CreateEntity("Trenchbroom map"); + ent.AddComponent(); + } + if (ImGui::MenuItem("Mesh")) { + auto ent = Engine::GetCurrentScene()->CreateEntity("Mesh"); + ent.AddComponent(); + } + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Delete selected", NULL)); + + if (ImGui::MenuItem("Duplicate selected", NULL)) {} + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Debug")) + { + if (ImGui::MenuItem("Show ImGui demo", NULL, m_ShowImGuiDemo)) { + m_ShowImGuiDemo = !m_ShowImGuiDemo; } ImGui::EndMenu(); } - if (ImGui::MenuItem("Delete selected", NULL)); - - if (ImGui::MenuItem("Duplicate selected", NULL)) {} - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Debug")) - { - if (ImGui::MenuItem("Show ImGui demo", NULL, m_ShowImGuiDemo)) { - m_ShowImGuiDemo = !m_ShowImGuiDemo; + if (ImGui::BeginMenu("Quit")) + { + ImGui::EndMenu(); } - ImGui::EndMenu(); + ImGui::EndMainMenuBar(); } - if (ImGui::BeginMenu("Quit")) + + DrawGizmos(); + + DrawRessourceWindow(); + DrawViewport(); + DrawSceneTree(); + //DrawDirectoryExplorer(); + DrawEntityPropreties(); + DrawLogger(); + + // new stuff + filesystem.Draw(); + filesystem.DrawDirectoryExplorer(); + + pInterface.DrawEntitySettings(); + + if (m_ShowImGuiDemo) + ImGui::ShowDemoWindow(); + + if (ImGui::Begin("Toolbar")) { - ImGui::EndMenu(); + if (ImGui::Button(ICON_FA_HAND_POINTER)) + CurrentOperation = ImGuizmo::OPERATION::TRANSLATE; + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_ARROWS_ALT)) + CurrentOperation = ImGuizmo::OPERATION::TRANSLATE; + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_SYNC_ALT)) + CurrentOperation = ImGuizmo::OPERATION::ROTATE; + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_EXPAND_ALT)) + CurrentOperation = ImGuizmo::OPERATION::SCALE; + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_PLAY)) + { + Engine::EnterPlayMode(); + } + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_STOP)) + { + Engine::ExitPlayMode(); + } + + } - ImGui::EndMainMenuBar(); + ImGui::End(); } - DrawGizmos(); - - DrawRessourceWindow(); - DrawViewport(); - DrawSceneTree(); - //DrawDirectoryExplorer(); - DrawEntityPropreties(); - DrawLogger(); - // new stuff - filesystem.Draw(); - filesystem.DrawDirectoryExplorer(); - - pInterface.DrawEntitySettings(); - - if(m_ShowImGuiDemo) - ImGui::ShowDemoWindow(); - - if(ImGui::Begin("Toolbar")) + void EditorInterface::BuildFonts() { - if (ImGui::Button(ICON_FA_HAND_POINTER)) - CurrentOperation = ImGuizmo::OPERATION::TRANSLATE; - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_ARROWS_ALT)) - CurrentOperation = ImGuizmo::OPERATION::TRANSLATE; - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_SYNC_ALT)) - CurrentOperation = ImGuizmo::OPERATION::ROTATE; - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_EXPAND_ALT)) - CurrentOperation = ImGuizmo::OPERATION::SCALE; - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_PLAY)) - { - Engine::EnterPlayMode(); - } - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_STOP)) - { - Engine::ExitPlayMode(); - } - - + ImGuiIO& io = ImGui::GetIO(); (void)io; + static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; + ImFontConfig icons_config; icons_config.MergeMode = true; icons_config.PixelSnapH = true; + normalFont = io.Fonts->AddFontFromFileTTF("resources/Fonts/fa-solid-900.ttf", 11.0f, &icons_config, icons_ranges); + + ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.5f, 0.5f)); + ImGui::GetIO().Fonts->AddFontDefault(); + icons_config.MergeMode = true; + bigIconFont = io.Fonts->AddFontFromFileTTF("resources/Fonts/fa-solid-900.ttf", 42.0f, &icons_config, icons_ranges); } - ImGui::End(); } - - -void EditorInterface::BuildFonts() -{ - ImGuiIO& io = ImGui::GetIO(); (void)io; - static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; - ImFontConfig icons_config; icons_config.MergeMode = true; icons_config.PixelSnapH = true; - normalFont = io.Fonts->AddFontFromFileTTF("resources/Fonts/fa-solid-900.ttf", 11.0f, &icons_config, icons_ranges); - - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.5f, 0.5f)); - ImGui::GetIO().Fonts->AddFontDefault(); - icons_config.MergeMode = true; - bigIconFont = io.Fonts->AddFontFromFileTTF("resources/Fonts/fa-solid-900.ttf", 42.0f, &icons_config, icons_ranges); -} \ No newline at end of file diff --git a/Editor/src/EditorInterface.h b/Editor/src/EditorInterface.h index fafe0c1f..ab9a48bd 100644 --- a/Editor/src/EditorInterface.h +++ b/Editor/src/EditorInterface.h @@ -4,43 +4,47 @@ #include #include "src/Core/FileSystem.h" #include "FileSystemUI.h" -class Material; -class EditorInterface -{ -private: - FileSystemUI filesystem = FileSystemUI(); - Entity m_SelectedEntity; - bool m_IsEntitySelected = false; - bool m_DrawGrid = false; - bool m_ShowImGuiDemo = false; - bool m_DebugCollisions = false; - bool m_ShowOverlay = true; - ImGuizmo::OPERATION CurrentOperation = ImGuizmo::TRANSLATE; - ImGuizmo::MODE CurrentMode = ImGuizmo::WORLD; - Ref m_SelectedMaterial; - Ref m_CurrentDirectory; - bool m_IsMaterialSelected = false; -public: - static ImFont* bigIconFont; - void BuildFonts(); - void Init(); - void Draw(); - void DrawViewport(); - void DrawEntityTree(Entity ent); - void DrawSceneTree(); - void DrawEntityPropreties(); - void DrawGizmos(); - void DrawFileSystem(); - void DrawDirectoryExplorer(); - void DrawLogger(); - void DrawDirectory(Ref directory); - bool EntityContainsItself(Entity ent1, Entity ent2); - void DrawFile(Ref file); - void DrawRessourceWindow(); - void DrawInit(); - void EditorInterfaceDrawFiletree(Ref dir); - void Overlay(); -}; \ No newline at end of file +namespace Nuake { + class Material; + class EditorInterface + { + private: + FileSystemUI filesystem = FileSystemUI(); + Entity m_SelectedEntity; + bool m_IsEntitySelected = false; + bool m_DrawGrid = false; + bool m_ShowImGuiDemo = false; + bool m_DebugCollisions = false; + bool m_ShowOverlay = true; + ImGuizmo::OPERATION CurrentOperation = ImGuizmo::TRANSLATE; + ImGuizmo::MODE CurrentMode = ImGuizmo::WORLD; + Ref m_SelectedMaterial; + Ref m_CurrentDirectory; + + bool m_IsMaterialSelected = false; + + public: + static ImFont* bigIconFont; + void BuildFonts(); + void Init(); + void Draw(); + void DrawViewport(); + void DrawEntityTree(Entity ent); + void DrawSceneTree(); + void DrawEntityPropreties(); + void DrawGizmos(); + void DrawFileSystem(); + void DrawDirectoryExplorer(); + void DrawLogger(); + void DrawDirectory(Ref directory); + bool EntityContainsItself(Entity ent1, Entity ent2); + void DrawFile(Ref file); + void DrawRessourceWindow(); + void DrawInit(); + void EditorInterfaceDrawFiletree(Ref dir); + void Overlay(); + }; +} diff --git a/Editor/src/FileSystemUI.cpp b/Editor/src/FileSystemUI.cpp index ad52fd46..7bbd045b 100644 --- a/Editor/src/FileSystemUI.cpp +++ b/Editor/src/FileSystemUI.cpp @@ -8,344 +8,339 @@ #include #include #include "EditorInterface.h" -// TODO: add filetree in same panel -void FileSystemUI::Draw() -{ - -} -void FileSystemUI::DrawDirectoryContent() -{ -} - -void FileSystemUI::DrawFiletree() -{ -} - - -void FileSystemUI::EditorInterfaceDrawFiletree(Ref dir) -{ - for (auto d : dir->Directories) +namespace Nuake { + // TODO: add filetree in same panel + void FileSystemUI::Draw() { - ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; - bool is_selected = m_CurrentDirectory == d; - if (is_selected) - base_flags |= ImGuiTreeNodeFlags_Selected; - - if (d->Directories.size() == 0) - { - base_flags = ImGuiTreeNodeFlags_Leaf; - } - std::string icon = ICON_FA_FOLDER; - if (is_selected) - icon = ICON_FA_FOLDER_OPEN; - bool open = ImGui::TreeNodeEx((icon + " " + d->name).c_str(), base_flags); - - if (ImGui::IsItemClicked()) - m_CurrentDirectory = d; - if (open) - { - if (d->Directories.size() > 0) - EditorInterfaceDrawFiletree(d); - ImGui::TreePop(); - } } -} - - -void FileSystemUI::DrawDirectory(Ref directory) -{ - ImGui::PushFont(EditorInterface::bigIconFont); - std::string id = ICON_FA_FOLDER + std::string("##") + directory->name; - if (ImGui::Button(id.c_str(), ImVec2(100, 100))) - m_CurrentDirectory = directory; - if (ImGui::BeginPopupContextWindow()) + void FileSystemUI::DrawDirectoryContent() { - if (ImGui::MenuItem("Htest")); - - ImGui::EndPopup(); } - ImGui::Text(directory->name.c_str()); - ImGui::PopFont(); -} -bool FileSystemUI::EntityContainsItself(Entity source, Entity target) -{ - ParentComponent& targeParentComponent = target.GetComponent(); - if (!targeParentComponent.HasParent) - return false; - - Entity currentParent = target.GetComponent().Parent; - while (currentParent != source) + void FileSystemUI::DrawFiletree() { - if (currentParent.GetComponent().HasParent) - currentParent = currentParent.GetComponent().Parent; - else - return false; - - if (currentParent == source) - return true; } - return true; -} -void FileSystemUI::DrawFile(Ref file) -{ - ImGui::PushFont(EditorInterface::bigIconFont); - if (file->Type == ".png" || file->Type == ".jpg") - { - Ref texture = TextureManager::Get()->GetTexture(file->fullPath); - ImGui::ImageButton((void*)texture->GetID(), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0)); - } - else - { - const char* icon = ICON_FA_FILE; - if (file->Type == ".shader") - icon = ICON_FA_FILE_CODE; - if (file->Type == ".map") - icon = ICON_FA_BROOM; - if (file->Type == ".ogg" || file->Type == ".mp3" || file->Type == ".wav" || file->Type == ".flac") - icon = ICON_FA_FILE_AUDIO; - if (file->Type == ".wren") - icon = ICON_FA_FILE_CODE; - if (file->Type == ".md3" || file->Type == ".obj") - icon = ICON_FA_FILE_IMAGE; - std::string fullName = icon + std::string("##") + file->fullPath; - if (ImGui::Button(fullName.c_str(), ImVec2(100, 100))) + void FileSystemUI::EditorInterfaceDrawFiletree(Ref dir) + { + for (auto d : dir->Directories) { - - } - - if (ImGui::BeginDragDropSource()) - { - char pathBuffer[256]; - std::strncpy(pathBuffer, file->fullPath.c_str(), sizeof(pathBuffer)); - std::string dragType; - if (file->Type == ".wren") - dragType = "_Script"; - else if (file->Type == ".map") - dragType = "_Map"; - else if (file->Type == ".obj" || file->Type == ".mdl" || file->Type == ".gltf" || file->Type == ".md3" || file->Type == "fbx") - dragType = "_Model"; - - ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer)); - ImGui::Text(file->name.c_str()); - ImGui::EndDragDropSource(); - } - } - ImGui::Text(file->name.c_str()); - ImGui::PopFont(); - -} - -bool Splitter(bool split_vertically, float thickness, float* size1, float* size2, float min_size1, float min_size2, float splitter_long_axis_size = -1.0f) -{ - using namespace ImGui; - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - ImGuiID id = window->GetID("##Splitter"); - ImRect bb; - bb.Min = window->DC.CursorPos + (split_vertically ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1)); - bb.Max = bb.Min + CalcItemSize(split_vertically ? ImVec2(thickness, splitter_long_axis_size) : ImVec2(splitter_long_axis_size, thickness), 0.0f, 0.0f); - return SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, 0.0f); -} -float h = 200; -static float sz1 = 300; -static float sz2 = 300; -void FileSystemUI::DrawDirectoryExplorer() -{ - if (ImGui::Begin("File browser")) - { - Ref rootDirectory = FileSystem::GetFileTree(); - if (!rootDirectory) - return; - - ImVec2 avail = ImGui::GetContentRegionAvail(); - Splitter(true, 4.0f, &sz1, &sz2, 100, 8, avail.y); - - if (ImGui::BeginChild("Tree browser", ImVec2(sz1, avail.y))) - { - if (ImGui::BeginPopupContextItem("item context menu")) - { - if (ImGui::Selectable("Set to zero")); - if (ImGui::Selectable("Set to PI")); - ImGui::SetNextItemWidth(-1); - ImGui::EndPopup(); - } ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; - - bool is_selected = m_CurrentDirectory == FileSystem::RootDirectory; + bool is_selected = m_CurrentDirectory == d; if (is_selected) - base_flags |= ImGuiTreeNodeFlags_Selected | ImGuiTreeNodeFlags_DefaultOpen; - std::string icon = ICON_FA_FOLDER; + base_flags |= ImGuiTreeNodeFlags_Selected; - bool open = ImGui::TreeNodeEx((icon + " " + rootDirectory->name).c_str(), base_flags); - if (ImGui::IsItemClicked()) + if (d->Directories.size() == 0) { - m_CurrentDirectory = FileSystem::RootDirectory; + base_flags = ImGuiTreeNodeFlags_Leaf; } + std::string icon = ICON_FA_FOLDER; + if (is_selected) + icon = ICON_FA_FOLDER_OPEN; + bool open = ImGui::TreeNodeEx((icon + " " + d->name).c_str(), base_flags); + + if (ImGui::IsItemClicked()) + m_CurrentDirectory = d; if (open) { - EditorInterfaceDrawFiletree(rootDirectory); + if (d->Directories.size() > 0) + EditorInterfaceDrawFiletree(d); ImGui::TreePop(); } - - } - ImGui::EndChild(); - ImGui::SameLine(); - - avail = ImGui::GetContentRegionAvail(); - - std::vector> paths = std::vector>(); - - Ref currentParent = m_CurrentDirectory; - paths.push_back(m_CurrentDirectory); - while (currentParent != nullptr) { - paths.push_back(currentParent); - currentParent = currentParent->Parent; + } + } - avail = ImGui::GetContentRegionAvail(); - if (ImGui::BeginChild("Wrapper", avail)) + + void FileSystemUI::DrawDirectory(Ref directory) + { + ImGui::PushFont(EditorInterface::bigIconFont); + std::string id = ICON_FA_FOLDER + std::string("##") + directory->name; + if (ImGui::Button(id.c_str(), ImVec2(100, 100))) + m_CurrentDirectory = directory; + if (ImGui::BeginPopupContextWindow()) { - avail.y = 30; - if (ImGui::BeginChild("ariane", avail)) + if (ImGui::MenuItem("Htest")); + + ImGui::EndPopup(); + } + ImGui::Text(directory->name.c_str()); + ImGui::PopFont(); + } + + bool FileSystemUI::EntityContainsItself(Entity source, Entity target) + { + ParentComponent& targeParentComponent = target.GetComponent(); + if (!targeParentComponent.HasParent) + return false; + + Entity currentParent = target.GetComponent().Parent; + while (currentParent != source) + { + if (currentParent.GetComponent().HasParent) + currentParent = currentParent.GetComponent().Parent; + else + return false; + + if (currentParent == source) + return true; + } + return true; + } + + void FileSystemUI::DrawFile(Ref file) + { + ImGui::PushFont(EditorInterface::bigIconFont); + if (file->Type == ".png" || file->Type == ".jpg") + { + Ref texture = TextureManager::Get()->GetTexture(file->fullPath); + ImGui::ImageButton((void*)texture->GetID(), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0)); + } + else + { + const char* icon = ICON_FA_FILE; + if (file->Type == ".shader") + icon = ICON_FA_FILE_CODE; + if (file->Type == ".map") + icon = ICON_FA_BROOM; + if (file->Type == ".ogg" || file->Type == ".mp3" || file->Type == ".wav" || file->Type == ".flac") + icon = ICON_FA_FILE_AUDIO; + if (file->Type == ".wren") + icon = ICON_FA_FILE_CODE; + if (file->Type == ".md3" || file->Type == ".obj") + icon = ICON_FA_FILE_IMAGE; + + std::string fullName = icon + std::string("##") + file->fullPath; + if (ImGui::Button(fullName.c_str(), ImVec2(100, 100))) { - if (ImGui::Button("Refresh")) - FileSystem::Scan(); - ImGui::SameLine(); - for (int i = paths.size() - 1; i > 0; i--) { - if (i != paths.size()) - ImGui::SameLine(); - if (ImGui::Button(paths[i]->name.c_str())) { - m_CurrentDirectory = paths[i]; - } - - ImGui::SameLine(); - ImGui::Text("/"); + + } + + if (ImGui::BeginDragDropSource()) + { + char pathBuffer[256]; + std::strncpy(pathBuffer, file->fullPath.c_str(), sizeof(pathBuffer)); + std::string dragType; + if (file->Type == ".wren") + dragType = "_Script"; + else if (file->Type == ".map") + dragType = "_Map"; + else if (file->Type == ".obj" || file->Type == ".mdl" || file->Type == ".gltf" || file->Type == ".md3" || file->Type == "fbx") + dragType = "_Model"; + + ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer)); + ImGui::Text(file->name.c_str()); + ImGui::EndDragDropSource(); + } + } + ImGui::Text(file->name.c_str()); + ImGui::PopFont(); + + } + + bool Splitter(bool split_vertically, float thickness, float* size1, float* size2, float min_size1, float min_size2, float splitter_long_axis_size = -1.0f) + { + using namespace ImGui; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiID id = window->GetID("##Splitter"); + ImRect bb; + bb.Min = window->DC.CursorPos + (split_vertically ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1)); + bb.Max = bb.Min + CalcItemSize(split_vertically ? ImVec2(thickness, splitter_long_axis_size) : ImVec2(splitter_long_axis_size, thickness), 0.0f, 0.0f); + return SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, 0.0f); + } + float h = 200; + static float sz1 = 300; + static float sz2 = 300; + void FileSystemUI::DrawDirectoryExplorer() + { + if (ImGui::Begin("File browser")) + { + Ref rootDirectory = FileSystem::GetFileTree(); + if (!rootDirectory) + return; + + ImVec2 avail = ImGui::GetContentRegionAvail(); + Splitter(true, 4.0f, &sz1, &sz2, 100, 8, avail.y); + + if (ImGui::BeginChild("Tree browser", ImVec2(sz1, avail.y))) + { + if (ImGui::BeginPopupContextItem("item context menu")) + { + if (ImGui::Selectable("Set to zero")); + if (ImGui::Selectable("Set to PI")); + ImGui::SetNextItemWidth(-1); + ImGui::EndPopup(); + } + ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; + + bool is_selected = m_CurrentDirectory == FileSystem::RootDirectory; + if (is_selected) + base_flags |= ImGuiTreeNodeFlags_Selected | ImGuiTreeNodeFlags_DefaultOpen; + std::string icon = ICON_FA_FOLDER; + + bool open = ImGui::TreeNodeEx((icon + " " + rootDirectory->name).c_str(), base_flags); + if (ImGui::IsItemClicked()) + { + m_CurrentDirectory = FileSystem::RootDirectory; + } + if (open) + { + EditorInterfaceDrawFiletree(rootDirectory); + ImGui::TreePop(); } - ImGui::EndChild(); } + ImGui::EndChild(); + ImGui::SameLine(); avail = ImGui::GetContentRegionAvail(); - if (ImGui::BeginChild("Content", avail)) + std::vector> paths = std::vector>(); + + Ref currentParent = m_CurrentDirectory; + paths.push_back(m_CurrentDirectory); + while (currentParent != nullptr) { + paths.push_back(currentParent); + currentParent = currentParent->Parent; + } + + + avail = ImGui::GetContentRegionAvail(); + if (ImGui::BeginChild("Wrapper", avail)) { - // Wrapping. - int width = ImGui::GetWindowWidth() * 0.8f; - ImVec2 buttonSize = ImVec2(80, 80); - int amount = (width / 100); // -2 because button overflow width + ... button. - int i = 1; // current amount of item per row. - if (ImGui::BeginTable("ssss", amount)) + avail.y = 30; + if (ImGui::BeginChild("ariane", avail)) { - // Button to go up a level. - if (m_CurrentDirectory != FileSystem::RootDirectory) - { - ImGui::TableNextColumn(); - if (ImGui::Button("..", ImVec2(100, 100))) - m_CurrentDirectory = m_CurrentDirectory->Parent; - ImGui::TableNextColumn(); - // Increment item per row tracker. - i++; + if (ImGui::Button("Refresh")) + FileSystem::Scan(); + ImGui::SameLine(); + for (int i = paths.size() - 1; i > 0; i--) { + if (i != paths.size()) + ImGui::SameLine(); + if (ImGui::Button(paths[i]->name.c_str())) { + m_CurrentDirectory = paths[i]; + } + + ImGui::SameLine(); + ImGui::Text("/"); } - // Exit if no current directory. - if (!m_CurrentDirectory) { - ImGui::EndTable(); - ImGui::End(); - return; - } - - if (m_CurrentDirectory && m_CurrentDirectory->Directories.size() > 0) - { - for (auto d : m_CurrentDirectory->Directories) - { - DrawDirectory(d); - if (i - 1 % amount != 0) - ImGui::TableNextColumn(); - else - ImGui::TableNextRow(); - i++; - } - } - if (m_CurrentDirectory && m_CurrentDirectory->Files.size() > 0) - { - for (auto f : m_CurrentDirectory->Files) - { - DrawFile(f); - if (i - 1 % amount != 0) - ImGui::TableNextColumn(); - else - ImGui::TableNextRow(); - i++; - } - } - if (ImGui::BeginPopupContextItem("item context menu")) - { - float value; - if (ImGui::Selectable("Set to zero")) value = 0.0f; - if (ImGui::Selectable("Set to PI")) value = 3.1415f; - ImGui::SetNextItemWidth(-1); - ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f); - ImGui::EndPopup(); - } - if (ImGui::BeginPopupContextWindow()) - { - if (ImGui::Button("New Wren script")) - { - ImGui::OpenPopup("CreateNewFile"); - - } - if (ImGui::MenuItem("New interface script")) - { - } - if (ImGui::MenuItem("New Scene")) - { - } - if (ImGui::MenuItem("New folder")) - { - } - if (ImGui::MenuItem("New interface")) - { - } - if (ImGui::MenuItem("New stylesheet")) - { - } - if (ImGui::BeginPopup("CreateNewFile")) - { - static char name[32] = "Label1"; - char buf[64]; - sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label - - ImGui::Text("Edit name:"); - ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); - if (ImGui::Button("Close")) - ImGui::CloseCurrentPopup(); - if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter))) - ImGui::CloseCurrentPopup(); - ImGui::EndPopup(); - } - ImGui::EndPopup(); - } - - - ImGui::EndTable(); + ImGui::EndChild(); } - + avail = ImGui::GetContentRegionAvail(); + + if (ImGui::BeginChild("Content", avail)) + { + // Wrapping. + int width = ImGui::GetWindowWidth() * 0.8f; + ImVec2 buttonSize = ImVec2(80, 80); + int amount = (width / 100); // -2 because button overflow width + ... button. + int i = 1; // current amount of item per row. + if (ImGui::BeginTable("ssss", amount)) + { + // Button to go up a level. + if (m_CurrentDirectory != FileSystem::RootDirectory) + { + ImGui::TableNextColumn(); + if (ImGui::Button("..", ImVec2(100, 100))) + m_CurrentDirectory = m_CurrentDirectory->Parent; + ImGui::TableNextColumn(); + // Increment item per row tracker. + i++; + } + + // Exit if no current directory. + if (!m_CurrentDirectory) { + ImGui::EndTable(); + ImGui::End(); + return; + } + + if (m_CurrentDirectory && m_CurrentDirectory->Directories.size() > 0) + { + for (auto d : m_CurrentDirectory->Directories) + { + DrawDirectory(d); + if (i - 1 % amount != 0) + ImGui::TableNextColumn(); + else + ImGui::TableNextRow(); + i++; + } + } + if (m_CurrentDirectory && m_CurrentDirectory->Files.size() > 0) + { + for (auto f : m_CurrentDirectory->Files) + { + DrawFile(f); + if (i - 1 % amount != 0) + ImGui::TableNextColumn(); + else + ImGui::TableNextRow(); + i++; + } + } + if (ImGui::BeginPopupContextItem("item context menu")) + { + float value; + if (ImGui::Selectable("Set to zero")) value = 0.0f; + if (ImGui::Selectable("Set to PI")) value = 3.1415f; + ImGui::SetNextItemWidth(-1); + ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f); + ImGui::EndPopup(); + } + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::Button("New Wren script")) + { + ImGui::OpenPopup("CreateNewFile"); + + } + if (ImGui::MenuItem("New interface script")) + { + } + if (ImGui::MenuItem("New Scene")) + { + } + if (ImGui::MenuItem("New folder")) + { + } + if (ImGui::MenuItem("New interface")) + { + } + if (ImGui::MenuItem("New stylesheet")) + { + } + if (ImGui::BeginPopup("CreateNewFile")) + { + static char name[32] = "Label1"; + char buf[64]; + sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label + + ImGui::Text("Edit name:"); + ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter))) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::EndPopup(); + } + ImGui::EndTable(); + } + } + ImGui::EndChild(); } ImGui::EndChild(); - } - ImGui::EndChild(); - - + ImGui::End(); } - ImGui::End(); } - diff --git a/Editor/src/FileSystemUI.h b/Editor/src/FileSystemUI.h index bacaa188..03a7acee 100644 --- a/Editor/src/FileSystemUI.h +++ b/Editor/src/FileSystemUI.h @@ -1,24 +1,25 @@ #pragma once - #include - #include -class FileSystemUI -{ -private: - -public: - Ref m_CurrentDirectory; - FileSystemUI() { - m_CurrentDirectory = FileSystem::RootDirectory; - } - void Draw(); - void DrawDirectoryContent(); - void DrawFiletree(); - void EditorInterfaceDrawFiletree(Ref dir); - void DrawDirectory(Ref directory); - bool EntityContainsItself(Entity source, Entity target); - void DrawFile(Ref file); - void DrawDirectoryExplorer(); -}; \ No newline at end of file +namespace Nuake { + class FileSystemUI + { + private: + + + public: + Ref m_CurrentDirectory; + FileSystemUI() { + m_CurrentDirectory = FileSystem::RootDirectory; + } + void Draw(); + void DrawDirectoryContent(); + void DrawFiletree(); + void EditorInterfaceDrawFiletree(Ref dir); + void DrawDirectory(Ref directory); + bool EntityContainsItself(Entity source, Entity target); + void DrawFile(Ref file); + void DrawDirectoryExplorer(); + }; +} diff --git a/Editor/src/ProjectInterface.cpp b/Editor/src/ProjectInterface.cpp index 7aaa95e5..1d3f1f87 100644 --- a/Editor/src/ProjectInterface.cpp +++ b/Editor/src/ProjectInterface.cpp @@ -3,11 +3,25 @@ #include "Engine.h" #include "ImGuiTextHelper.h" -void ProjectInterface::DrawProjectSettings() -{ - if (ImGui::Begin("Project settings")) - { - +namespace Nuake { + void ProjectInterface::DrawProjectSettings() + { + if (ImGui::Begin("Project settings")) + { + + char buffer[256]; + memset(buffer, 0, sizeof(buffer)); + std::strncpy(buffer, Engine::GetProject()->Name.c_str(), sizeof(buffer)); + if (ImGui::InputText("##Name", buffer, sizeof(buffer))) + { + Engine::GetProject()->Name = std::string(buffer); + } + } + ImGui::End(); + } + + void ProjectInterface::DrawCreatePointEntity() + { char buffer[256]; memset(buffer, 0, sizeof(buffer)); std::strncpy(buffer, Engine::GetProject()->Name.c_str(), sizeof(buffer)); @@ -15,242 +29,230 @@ void ProjectInterface::DrawProjectSettings() { Engine::GetProject()->Name = std::string(buffer); } - } - ImGui::End(); -} - -void ProjectInterface::DrawCreatePointEntity() -{ - char buffer[256]; - memset(buffer, 0, sizeof(buffer)); - std::strncpy(buffer, Engine::GetProject()->Name.c_str(), sizeof(buffer)); - if (ImGui::InputText("##Name", buffer, sizeof(buffer))) - { - Engine::GetProject()->Name = std::string(buffer); } -} -FGDPointEntity newEntity; + FGDPointEntity newEntity; -const char* items[] = { "String", "Integer", "Float", "Boolean"}; -void ProjectInterface::DrawEntitySettings() -{ - if (!m_CurrentProject) - return; - - if (ImGui::Begin("Entity definitions")) + const char* items[] = { "String", "Integer", "Float", "Boolean" }; + void ProjectInterface::DrawEntitySettings() { - ImGui::Text("This is the entity definition used by trenchbroom. This files allows you to see your entities inside Trenchbroom"); - - ImGui::Text("Trenchbroom path:"); - ImGui::SameLine(); - ImGuiTextSTD("", m_CurrentProject->TrenchbroomPath); - ImGui::SameLine(); - if (ImGui::Button("Browse")) + if (!m_CurrentProject) + return; + + if (ImGui::Begin("Entity definitions")) { - std::string path = FileDialog::OpenFile("*.exe"); - if (path != "") - { - path += "/../"; - m_CurrentProject->TrenchbroomPath = path; - } - } + ImGui::Text("This is the entity definition used by trenchbroom. This files allows you to see your entities inside Trenchbroom"); - Ref file = Engine::GetProject()->EntityDefinitionsFile; - - auto flags = ImGuiWindowFlags_NoTitleBar; - if (ImGui::BeginPopupModal("Create new point entity", NULL, flags)) - { - ImGuiTextSTD("Name", newEntity.Name); - ImGuiTextMultiline("Description", newEntity.Description); - - if (ImGui::BeginTable("DictCreate", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) - { - ImGui::TableSetupColumn("Name"); - ImGui::TableSetupColumn("Type"); - ImGui::TableHeadersRow(); - - ImGui::TableNextColumn(); - int idx = 0; - for (auto& p : newEntity.Properties) - { - ImGuiTextSTD("Name", p.name); - ImGui::TableNextColumn(); - std::string current_item = NULL; - if(ImGui::BeginCombo(("TypeSelection" + std::to_string(idx)).c_str(), current_item.c_str())) - { - for (int n = 0; n < IM_ARRAYSIZE(items); n++) - { - bool is_selected = (p.type == (ClassPropertyType)n); // You can store your selection however you want, outside or inside your objects - if (ImGui::Selectable(items[n], is_selected)) - if (is_selected) - { - p.type = (ClassPropertyType)n; - ImGui::SetItemDefaultFocus(); - } - - } - ImGui::EndCombo(); - } - idx++; - ImGui::TableNextColumn(); - } - if (ImGui::Button("Add new property")) - { - newEntity.Properties.push_back(ClassProperty()); - } - - ImGui::EndTable(); - } - - ImGui::Button("Create"); + ImGui::Text("Trenchbroom path:"); ImGui::SameLine(); - if (ImGui::Button("Cancel")) - ImGui::CloseCurrentPopup(); - - ImGui::EndPopup(); - } - - - if (ImGui::Button("Export")) - { - file->Export(); - } - - ImGui::SameLine(); - - if (ImGui::Button("Save")) - { - file->Save(); - } - - ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 100)); - if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) - { - if (ImGui::BeginTabItem("Point entities")) + ImGuiTextSTD("", m_CurrentProject->TrenchbroomPath); + ImGui::SameLine(); + if (ImGui::Button("Browse")) { - ImVec2 avail = ImGui::GetContentRegionAvail(); - avail.y *= .8; + std::string path = FileDialog::OpenFile("*.exe"); + if (path != "") + { + path += "/../"; + m_CurrentProject->TrenchbroomPath = path; + } + } - ImGui::BeginChild("table_child", avail, false); - if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + Ref file = Engine::GetProject()->EntityDefinitionsFile; + + auto flags = ImGuiWindowFlags_NoTitleBar; + if (ImGui::BeginPopupModal("Create new point entity", NULL, flags)) + { + ImGuiTextSTD("Name", newEntity.Name); + ImGuiTextMultiline("Description", newEntity.Description); + + if (ImGui::BeginTable("DictCreate", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) { ImGui::TableSetupColumn("Name"); - ImGui::TableSetupColumn("Desciption"); - ImGui::TableSetupColumn("Settings"); - ImGui::TableSetupColumn("Prefab"); + ImGui::TableSetupColumn("Type"); ImGui::TableHeadersRow(); ImGui::TableNextColumn(); - for (auto& pE : file->PointEntities) + int idx = 0; + for (auto& p : newEntity.Properties) { - ImGui::Text(pE.Name.c_str()); + ImGuiTextSTD("Name", p.name); ImGui::TableNextColumn(); - ImGui::Text(pE.Description.c_str()); + std::string current_item = NULL; + if (ImGui::BeginCombo(("TypeSelection" + std::to_string(idx)).c_str(), current_item.c_str())) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + bool is_selected = (p.type == (ClassPropertyType)n); // You can store your selection however you want, outside or inside your objects + if (ImGui::Selectable(items[n], is_selected)) + if (is_selected) + { + p.type = (ClassPropertyType)n; + ImGui::SetItemDefaultFocus(); + } + + } + ImGui::EndCombo(); + } + idx++; ImGui::TableNextColumn(); - ImGui::Button("Edit"); - ImGui::TableNextColumn(); - ImGui::Text(pE.Prefab.c_str()); - ImGui::SameLine(); - ImGui::Button("Browse"); + } + if (ImGui::Button("Add new property")) + { + newEntity.Properties.push_back(ClassProperty()); } ImGui::EndTable(); } - ImGui::EndChild(); - ImGui::EndTabItem(); + + ImGui::Button("Create"); + ImGui::SameLine(); + if (ImGui::Button("Cancel")) + ImGui::CloseCurrentPopup(); + + ImGui::EndPopup(); } - if (ImGui::BeginTabItem("Brush entities")) + + if (ImGui::Button("Export")) { - ImVec2 avail = ImGui::GetContentRegionAvail(); - avail.y *= .8; - ImGui::BeginChild("table_child", avail, false); - if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + file->Export(); + } + + ImGui::SameLine(); + + if (ImGui::Button("Save")) + { + file->Save(); + } + + ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 100)); + if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) + { + if (ImGui::BeginTabItem("Point entities")) { - ImGui::TableSetupColumn("Name"); - ImGui::TableSetupColumn("Desciption"); - ImGui::TableSetupColumn("Settings"); - ImGui::TableSetupColumn("Script"); - ImGui::TableHeadersRow(); - ImGui::TableNextColumn(); + ImVec2 avail = ImGui::GetContentRegionAvail(); + avail.y *= .8; - int i = 0; - for (auto& pE : file->BrushEntities) + ImGui::BeginChild("table_child", avail, false); + if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) { - ImGuiTextSTD("##Name" + std::to_string(i), pE.Name); - ImGui::TableNextColumn(); + ImGui::TableSetupColumn("Name"); + ImGui::TableSetupColumn("Desciption"); + ImGui::TableSetupColumn("Settings"); + ImGui::TableSetupColumn("Prefab"); + ImGui::TableHeadersRow(); - ImGuiTextSTD("Desc" + std::to_string(i), pE.Description); ImGui::TableNextColumn(); - - ImGui::Checkbox(std::string("Visible##" + std::to_string(i)).c_str(), &pE.Visible); - ImGui::SameLine(); - ImGui::Checkbox(std::string("Solid##" + std::to_string(i)).c_str(), &pE.Solid); - ImGui::SameLine(); - ImGui::Checkbox(std::string("Trigger##" + std::to_string(i)).c_str(), &pE.IsTrigger); - - ImGui::TableNextColumn(); - - ImGuiTextSTD("Script##" + std::to_string(i), pE.Script); - if (ImGui::BeginDragDropTarget()) + for (auto& pE : file->PointEntities) { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script")) + ImGui::Text(pE.Name.c_str()); + ImGui::TableNextColumn(); + ImGui::Text(pE.Description.c_str()); + ImGui::TableNextColumn(); + ImGui::Button("Edit"); + ImGui::TableNextColumn(); + ImGui::Text(pE.Prefab.c_str()); + ImGui::SameLine(); + ImGui::Button("Browse"); + } + + ImGui::EndTable(); + } + ImGui::EndChild(); + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Brush entities")) + { + ImVec2 avail = ImGui::GetContentRegionAvail(); + avail.y *= .8; + ImGui::BeginChild("table_child", avail, false); + if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("Name"); + ImGui::TableSetupColumn("Desciption"); + ImGui::TableSetupColumn("Settings"); + ImGui::TableSetupColumn("Script"); + ImGui::TableHeadersRow(); + ImGui::TableNextColumn(); + + int i = 0; + for (auto& pE : file->BrushEntities) + { + ImGuiTextSTD("##Name" + std::to_string(i), pE.Name); + ImGui::TableNextColumn(); + + ImGuiTextSTD("Desc" + std::to_string(i), pE.Description); + ImGui::TableNextColumn(); + + ImGui::Checkbox(std::string("Visible##" + std::to_string(i)).c_str(), &pE.Visible); + ImGui::SameLine(); + ImGui::Checkbox(std::string("Solid##" + std::to_string(i)).c_str(), &pE.Solid); + ImGui::SameLine(); + ImGui::Checkbox(std::string("Trigger##" + std::to_string(i)).c_str(), &pE.IsTrigger); + + ImGui::TableNextColumn(); + + ImGuiTextSTD("Script##" + std::to_string(i), pE.Script); + if (ImGui::BeginDragDropTarget()) { - char* file = (char*)payload->Data; - std::string fullPath = std::string(file, 256); - pE.Script = FileSystem::AbsoluteToRelative(fullPath); + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script")) + { + char* file = (char*)payload->Data; + std::string fullPath = std::string(file, 256); + pE.Script = FileSystem::AbsoluteToRelative(fullPath); + } + + ImGui::EndDragDropTarget(); + } + ImGuiTextSTD("Class##" + std::to_string(i), pE.Class); + ImGui::TableNextColumn(); + + i++; + } + + ImGui::TableNextColumn(); + ImGui::EndTable(); + + if (ImGui::BeginPopupModal("CreateBrush", NULL, flags)) + { + ImGuiTextSTD("Name", newEntity.Name); + ImGuiTextMultiline("Description", newEntity.Description); + + bool isSolid = true; + bool isTrigger = false; + bool isVisible = true; + ImGui::Checkbox("Is Solid", &isSolid); + ImGui::Checkbox("Is Trigger", &isTrigger); + ImGui::Checkbox("Is Visible", &isVisible); + + if (ImGui::Button("Create")) + { + } - ImGui::EndDragDropTarget(); + ImGui::SameLine(); + + if (ImGui::Button("Cancel")) + ImGui::CloseCurrentPopup(); + + ImGui::EndPopup(); } - ImGuiTextSTD("Class##" + std::to_string(i), pE.Class); - ImGui::TableNextColumn(); - i++; - } - - ImGui::TableNextColumn(); - ImGui::EndTable(); - - if (ImGui::BeginPopupModal("CreateBrush", NULL, flags)) - { - ImGuiTextSTD("Name", newEntity.Name); - ImGuiTextMultiline("Description", newEntity.Description); - - bool isSolid = true; - bool isTrigger = false; - bool isVisible = true; - ImGui::Checkbox("Is Solid", &isSolid); - ImGui::Checkbox("Is Trigger", &isTrigger); - ImGui::Checkbox("Is Visible", &isVisible); - - if (ImGui::Button("Create")) + if (ImGui::Button("Add new")) { - + file->BrushEntities.push_back(FGDBrushEntity("New brush")); } - ImGui::SameLine(); - - if (ImGui::Button("Cancel")) - ImGui::CloseCurrentPopup(); - - ImGui::EndPopup(); } - - if (ImGui::Button("Add new")) - { - file->BrushEntities.push_back(FGDBrushEntity("New brush")); - } - + ImGui::EndChild(); + ImGui::EndTabItem(); } - ImGui::EndChild(); - ImGui::EndTabItem(); + ImGui::EndTabBar(); } - ImGui::EndTabBar(); + + ImGui::PopStyleVar(); } - - ImGui::PopStyleVar(); + ImGui::End(); } - ImGui::End(); -} \ No newline at end of file +} diff --git a/Editor/src/ProjectInterface.h b/Editor/src/ProjectInterface.h index f42dae82..263da939 100644 --- a/Editor/src/ProjectInterface.h +++ b/Editor/src/ProjectInterface.h @@ -2,17 +2,14 @@ #include "src/Core/Core.h" #include "src/Resource/Project.h" +namespace Nuake { + class ProjectInterface + { + public: + Ref m_CurrentProject; -class ProjectInterface -{ -public: - Ref m_CurrentProject; - - - void DrawProjectSettings(); - - void DrawCreatePointEntity(); - void DrawEntitySettings(); - - -}; \ No newline at end of file + void DrawProjectSettings(); + void DrawCreatePointEntity(); + void DrawEntitySettings(); + }; +} diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index 852039fd..3202b4db 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -12,135 +12,138 @@ #include #include -Ref Engine::CurrentProject; -Ref Engine::CurrentWindow; - -float Engine::m_LastFrameTime = 0.0f; -float Engine::m_FixedUpdateRate = 1.0 / 144.0f; -float Engine::m_FixedUpdateDifference = 0.f; -bool Engine::IsPlayMode = false; - -void Engine::Init() +namespace Nuake { - Logger::Log("Engine initialization..."); + Ref Engine::CurrentProject; + Ref Engine::CurrentWindow; - PhysicsManager::Get()->Init(); - Logger::Log("Physics initialized"); + float Engine::m_LastFrameTime = 0.0f; + float Engine::m_FixedUpdateRate = 1.0 / 144.0f; + float Engine::m_FixedUpdateDifference = 0.f; + bool Engine::IsPlayMode = false; - // Creates the window - CurrentWindow = Window::Get(); - Logger::Log("Window initialized"); - - Renderer2D::Init(); - Logger::Log("2D renderer initialized"); - - Logger::Log("Engine initialized succesfully!"); -} - -void Engine::Tick() -{ - // Dont update if no scene is loaded. - if (!CurrentWindow->GetScene()) - return; - - // Calculate delta time - float time = (float)glfwGetTime(); - Timestep timestep = time - m_LastFrameTime; - m_LastFrameTime = time; - - // Play mode update all the entities, Editor does not. - if (Engine::IsPlayMode) + void Engine::Init() { - CurrentWindow->Update(timestep); - m_FixedUpdateDifference += timestep; + Logger::Log("Engine initialization..."); - // Fixed update - if (m_FixedUpdateDifference >= m_FixedUpdateRate) + PhysicsManager::Get()->Init(); + Logger::Log("Physics initialized"); + + // Creates the window + CurrentWindow = Window::Get(); + Logger::Log("Window initialized"); + + Renderer2D::Init(); + Logger::Log("2D renderer initialized"); + + Logger::Log("Engine initialized succesfully!"); + } + + void Engine::Tick() + { + // Dont update if no scene is loaded. + if (!CurrentWindow->GetScene()) + return; + + // Calculate delta time + float time = (float)glfwGetTime(); + Timestep timestep = time - m_LastFrameTime; + m_LastFrameTime = time; + + // Play mode update all the entities, Editor does not. + if (Engine::IsPlayMode) { - CurrentWindow->FixedUpdate(m_FixedUpdateRate); - m_FixedUpdateDifference = 0.f; + CurrentWindow->Update(timestep); + m_FixedUpdateDifference += timestep; + + // Fixed update + if (m_FixedUpdateDifference >= m_FixedUpdateRate) + { + CurrentWindow->FixedUpdate(m_FixedUpdateRate); + m_FixedUpdateDifference = 0.f; + } } - } - else - { - GetCurrentScene()->EditorUpdate(timestep); - } - - Input::Update(); -} - -void Engine::EnterPlayMode() -{ - // Dont trigger init if already in player mode. - if (!IsPlayMode) - if(GetCurrentScene()->OnInit()) - IsPlayMode = true; else - GetCurrentScene()->OnExit(); -} + { + GetCurrentScene()->EditorUpdate(timestep); + } -void Engine::ExitPlayMode() -{ - // Dont trigger exit if already not in play mode. - if (IsPlayMode) { - GetCurrentScene()->OnExit(); - Input::ShowMouse(); + Input::Update(); } - - Input::ShowMouse(); - IsPlayMode = false; + void Engine::EnterPlayMode() + { + // Dont trigger init if already in player mode. + if (!IsPlayMode) + if (GetCurrentScene()->OnInit()) + IsPlayMode = true; + else + GetCurrentScene()->OnExit(); + } + + void Engine::ExitPlayMode() + { + // Dont trigger exit if already not in play mode. + if (IsPlayMode) { + GetCurrentScene()->OnExit(); + Input::ShowMouse(); + } + + Input::ShowMouse(); + + IsPlayMode = false; + } + + void Engine::Draw() + { + // Start imgui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + // Draw scene + Window::Get()->Draw(); + } + + void Engine::EndDraw() + { + // Swap buffer and draw imgui + Window::Get()->EndDraw(); + } + + void Engine::Close() + { + glfwTerminate(); + } + + Ref Engine::GetCurrentScene() + { + return CurrentWindow->GetScene(); + } + + bool Engine::LoadScene(Ref scene) + { + return CurrentWindow->SetScene(scene); + } + + Ref Engine::GetProject() + { + return CurrentProject; + } + + bool Engine::LoadProject(Ref project) + { + CurrentProject = project; + + if (!Engine::LoadScene(CurrentProject->DefaultScene)) + return false; + + FileSystem::SetRootDirectory(project->FullPath + "/../"); + return true; + } + + Ref Engine::GetCurrentWindow() + { + return CurrentWindow; + } } - -void Engine::Draw() -{ - // Start imgui frame - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - // Draw scene - Window::Get()->Draw(); -} - -void Engine::EndDraw() -{ - // Swap buffer and draw imgui - Window::Get()->EndDraw(); -} - -void Engine::Close() -{ - glfwTerminate(); -} - -Ref Engine::GetCurrentScene() -{ - return CurrentWindow->GetScene(); -} - -bool Engine::LoadScene(Ref scene) -{ - return CurrentWindow->SetScene(scene); -} - -Ref Engine::GetProject() -{ - return CurrentProject; -} - -bool Engine::LoadProject(Ref project) -{ - CurrentProject = project; - - if (!Engine::LoadScene(CurrentProject->DefaultScene)) - return false; - - FileSystem::SetRootDirectory(project->FullPath + "/../"); - return true; -} - -Ref Engine::GetCurrentWindow() -{ - return CurrentWindow; -} \ No newline at end of file diff --git a/Nuake/Engine.h b/Nuake/Engine.h index 481f6c92..e75d4527 100644 --- a/Nuake/Engine.h +++ b/Nuake/Engine.h @@ -1,10 +1,8 @@ #pragma once - #include "src/Core/Core.h" #include "src/Window.h" #include "src/Scene/Scene.h" #include "src/Resource/Project.h" -#include "src/Scripting/ScriptLoader.h" #include "src/Core/Logger.h" /* TODOS: @@ -20,37 +18,40 @@ */ // Welcome to the Nuake source code. This is the entry point for the engine. +namespace Nuake +{ + class Engine { + private: + static Ref CurrentWindow; + static Ref CurrentProject; + static Ref CurrentScene; -class Engine { -private: - static Ref CurrentWindow; - static Ref CurrentProject; - static Ref CurrentScene; + static float m_LastFrameTime; + static float m_FixedUpdateRate; + static float m_FixedUpdateDifference; + public: + static bool IsPlayMode; // True if currently playing the game. - static float m_LastFrameTime; - static float m_FixedUpdateRate; - static float m_FixedUpdateDifference; -public: - static bool IsPlayMode; // True if currently playing the game. + static void Init(); // Initialize the engine. + static void Tick(); // Updates everything, called everyframe. + static void Close(); // Shutdown the engine. - static void Init(); // Initialize the engine. - static void Tick(); // Updates everything, called everyframe. - static void Close(); // Shutdown the engine. - - static void EnterPlayMode(); // Start the game - static void ExitPlayMode(); // Stops the game + static void EnterPlayMode(); // Start the game + static void ExitPlayMode(); // Stops the game - // Custom drawing should happen in between these two - static void Draw(); // Start new frame - static void EndDraw(); // Swap buffer + // Custom drawing should happen in between these two + static void Draw(); // Start new frame + static void EndDraw(); // Swap buffer - static Ref GetCurrentWindow(); + static Ref GetCurrentWindow(); - // Load a specific scene - static bool LoadScene(Ref scene); - static Ref GetCurrentScene(); + // Load a specific scene + static bool LoadScene(Ref scene); + static Ref GetCurrentScene(); + + // Loads a project and the default scene. + static bool LoadProject(Ref project); + static Ref GetProject(); + }; +} - // Loads a project and the default scene. - static bool LoadProject(Ref project); - static Ref GetProject(); -}; diff --git a/Nuake/src/Core/Core.h b/Nuake/src/Core/Core.h index 80769807..f6b9d8aa 100644 --- a/Nuake/src/Core/Core.h +++ b/Nuake/src/Core/Core.h @@ -1,5 +1,8 @@ #pragma once #include +#include +#include +#include template using Scope = std::unique_ptr; diff --git a/Nuake/src/Core/FileSystem.cpp b/Nuake/src/Core/FileSystem.cpp index 8343d46c..4de26519 100644 --- a/Nuake/src/Core/FileSystem.cpp +++ b/Nuake/src/Core/FileSystem.cpp @@ -1,7 +1,7 @@ #include "FileSystem.h" -#include -#include "../../Engine.h" +#include "Engine.h" + #define GLFW_EXPOSE_NATIVE_WIN32 #include @@ -10,150 +10,154 @@ #include #include -namespace fs = std::filesystem; - - -std::string FileDialog::OpenFile(const char* filter) +namespace Nuake { + namespace fs = std::filesystem; - OPENFILENAMEA ofn; - CHAR szFile[260] = { 0 }; - ZeroMemory(&ofn, sizeof(OPENFILENAME)); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle()); - ofn.lpstrFile = szFile; - ofn.nMaxFile = sizeof(szFile); - ofn.lpstrFilter = filter; - ofn.nFilterIndex = 1; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; - if (GetOpenFileNameA(&ofn) == TRUE) + std::string FileDialog::OpenFile(const char* filter) { - return ofn.lpstrFile; - } - return std::string(); - -} -std::string FileDialog::SaveFile(const char* filter) -{ - OPENFILENAMEA ofn; - CHAR szFile[260] = { 0 }; - ZeroMemory(&ofn, sizeof(OPENFILENAME)); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle()); - ofn.lpstrFile = szFile; - ofn.nMaxFile = sizeof(szFile); - ofn.lpstrFilter = filter; - ofn.nFilterIndex = 1; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; - if (GetSaveFileNameA(&ofn) == TRUE) - { - return ofn.lpstrFile; - } - return std::string(); - -} -std::string FileSystem::Root = ""; - -Ref FileSystem::RootDirectory; - -void FileSystem::ScanDirectory(Ref directory) -{ - for (const auto& entry : std::filesystem::directory_iterator(directory->fullPath)) - { - if (entry.is_directory()) + OPENFILENAMEA ofn; + CHAR szFile[260] = { 0 }; + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle()); + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = filter; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; + if (GetOpenFileNameA(&ofn) == TRUE) { - Ref newDir = CreateRef(); - newDir->fullPath = entry.path().string(); - newDir->name = entry.path().filename().string(); - - newDir->Parent = directory; - ScanDirectory(newDir); - - directory->Directories.push_back(newDir); + return ofn.lpstrFile; } - else if (entry.is_regular_file()) + return std::string(); + + } + + std::string FileDialog::SaveFile(const char* filter) + { + OPENFILENAMEA ofn; + CHAR szFile[260] = { 0 }; + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = glfwGetWin32Window(Engine::GetCurrentWindow()->GetHandle()); + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = filter; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; + if (GetSaveFileNameA(&ofn) == TRUE) { - Ref newFile = CreateRef(); - newFile->Type = entry.path().extension().string(); - newFile->name = entry.path().filename().string(); - newFile->Parent = directory; - newFile->fullPath = entry.path().string(); - directory->Files.push_back(newFile); + return ofn.lpstrFile; + } + return std::string(); + + } + + std::string FileSystem::Root = ""; + + Ref FileSystem::RootDirectory; + + void FileSystem::ScanDirectory(Ref directory) + { + for (const auto& entry : std::filesystem::directory_iterator(directory->fullPath)) + { + if (entry.is_directory()) + { + Ref newDir = CreateRef(); + newDir->fullPath = entry.path().string(); + newDir->name = entry.path().filename().string(); + + newDir->Parent = directory; + ScanDirectory(newDir); + + directory->Directories.push_back(newDir); + } + else if (entry.is_regular_file()) + { + Ref newFile = CreateRef(); + newFile->Type = entry.path().extension().string(); + newFile->name = entry.path().filename().string(); + newFile->Parent = directory; + newFile->fullPath = entry.path().string(); + directory->Files.push_back(newFile); + } } } -} -bool FileSystem::DirectoryExists(const std::string path) -{ - return false; -} - -void FileSystem::SetRootDirectory(const std::string path) -{ - Root = path; - Scan(); -} - -void FileSystem::Scan() -{ - RootDirectory = CreateRef(); - RootDirectory->Files = std::vector>(); - RootDirectory->Directories = std::vector>(); - RootDirectory->name = FileSystem::AbsoluteToRelative(Root); - RootDirectory->fullPath = Root; - ScanDirectory(RootDirectory); -} - -std::string FileSystem::AbsoluteToRelative(const std::string& path) -{ - const fs::path rootPath(Root); - const fs::path absolutePath(path); - return fs::relative(absolutePath, rootPath).generic_string(); -} - -std::string FileSystem::ReadFile(const std::string& path, bool absolute) -{ - std::string finalPath = path; - if (!absolute) - finalPath = Root + path; - - std::ifstream MyReadFile(finalPath); - std::string fileContent = ""; - std::string allFile = ""; - - // Use a while loop together with the getline() function to read the file line by line - while (getline(MyReadFile, fileContent)) + bool FileSystem::DirectoryExists(const std::string path) { - allFile.append(fileContent + "\n"); + return false; + } + + void FileSystem::SetRootDirectory(const std::string path) + { + Root = path; + Scan(); + } + + void FileSystem::Scan() + { + RootDirectory = CreateRef(); + RootDirectory->Files = std::vector>(); + RootDirectory->Directories = std::vector>(); + RootDirectory->name = FileSystem::AbsoluteToRelative(Root); + RootDirectory->fullPath = Root; + ScanDirectory(RootDirectory); + } + + std::string FileSystem::AbsoluteToRelative(const std::string& path) + { + const fs::path rootPath(Root); + const fs::path absolutePath(path); + return fs::relative(absolutePath, rootPath).generic_string(); + } + + std::string FileSystem::ReadFile(const std::string& path, bool absolute) + { + std::string finalPath = path; + if (!absolute) + finalPath = Root + path; + + std::ifstream MyReadFile(finalPath); + std::string fileContent = ""; + std::string allFile = ""; + + // Use a while loop together with the getline() function to read the file line by line + while (getline(MyReadFile, fileContent)) + { + allFile.append(fileContent + "\n"); + } + + // Close the file + MyReadFile.close(); + return allFile; + } + + std::ofstream FileSystem::fileWriter; + bool FileSystem::BeginWriteFile(const std::string path) + { + fileWriter = std::ofstream(); + fileWriter.open(path); + + return false; + } + + bool FileSystem::WriteLine(const std::string line) + { + fileWriter << line.c_str(); + + return true; + } + + void FileSystem::EndWriteFile() + { + fileWriter.close(); + } + + Ref FileSystem::GetFileTree() + { + return RootDirectory; } - // Close the file - MyReadFile.close(); - return allFile; -} - -std::ofstream FileSystem::fileWriter; -bool FileSystem::BeginWriteFile(const std::string path) -{ - fileWriter = std::ofstream(); - fileWriter.open(path); - - return false; -} - -bool FileSystem::WriteLine(const std::string line) -{ - fileWriter << line.c_str(); - - return true; -} - -void FileSystem::EndWriteFile() -{ - fileWriter.close(); -} - -Ref FileSystem::GetFileTree() -{ - return RootDirectory; } diff --git a/Nuake/src/Core/FileSystem.h b/Nuake/src/Core/FileSystem.h index 513764c1..4826a627 100644 --- a/Nuake/src/Core/FileSystem.h +++ b/Nuake/src/Core/FileSystem.h @@ -4,54 +4,58 @@ #include "Core.h" #include #include -class FileDialog + +namespace Nuake { -public: - static std::string OpenFile(const char* filter); - static std::string SaveFile(const char* filter); -}; + class FileDialog + { + public: + static std::string OpenFile(const char* filter); + static std::string SaveFile(const char* filter); + }; -struct Directory; -struct File -{ - std::string Type; - std::string name; + struct Directory; + struct File + { + std::string Type; + std::string name; - std::string fullPath; - Ref Parent; -}; + std::string fullPath; + Ref Parent; + }; -struct Directory -{ - std::string name; - std::string fullPath; - Ref Parent; - std::vector> Directories; - std::vector> Files; -}; + struct Directory + { + std::string name; + std::string fullPath; + Ref Parent; + std::vector> Directories; + std::vector> Files; + }; -class FileSystem -{ -public: - static std::string Root; + class FileSystem + { + public: + static std::string Root; - static Ref RootDirectory; + static Ref RootDirectory; - static void SetRootDirectory(const std::string path); + static void SetRootDirectory(const std::string path); - static void Scan(); - static std::string AbsoluteToRelative(const std::string& path); - static Ref GetFileTree(); - static void ScanDirectory(Ref directory); - static void GetDirectories(); + static void Scan(); + static std::string AbsoluteToRelative(const std::string& path); + static Ref GetFileTree(); + static void ScanDirectory(Ref directory); + static void GetDirectories(); - static bool DirectoryExists(const std::string path); - static bool FileExists(const std::string path); + static bool DirectoryExists(const std::string path); + static bool FileExists(const std::string path); - static std::string ReadFile(const std::string& path, bool absolute = false); + static std::string ReadFile(const std::string& path, bool absolute = false); - static std::ofstream fileWriter; - static bool BeginWriteFile(const std::string path); - static bool WriteLine(const std::string line); - static void EndWriteFile(); -}; \ No newline at end of file + static std::ofstream fileWriter; + static bool BeginWriteFile(const std::string path); + static bool WriteLine(const std::string line); + static void EndWriteFile(); + }; +} diff --git a/Nuake/src/Core/Input.cpp b/Nuake/src/Core/Input.cpp index e09665dc..a1ea0144 100644 --- a/Nuake/src/Core/Input.cpp +++ b/Nuake/src/Core/Input.cpp @@ -2,166 +2,170 @@ #include "../Window.h" #include -Input* Input::s_Instance; -std::map Input::m_Keys = std::map(); -bool Input::m_MouseButtons[5] = { false, false, false, false, false }; +namespace Nuake +{ + Input* Input::s_Instance; + std::map Input::m_Keys = std::map(); + bool Input::m_MouseButtons[5] = { false, false, false, false, false }; #pragma region Keys -// Only true if the key is currently being pressed -bool Input::IsKeyDown(int keycode) -{ - auto window = Window::Get()->GetHandle(); - int state = glfwGetKey(window, keycode); - bool result = state == GLFW_PRESS; - - m_Keys[keycode] = state; - - return result; -} - -// Only true if the key is pressed for the first frame. no repeat. -bool Input::IsKeyPressed(int keycode) -{ - auto window = Window::Get()->GetHandle(); - int state = glfwGetKey(window, keycode); - bool result = state == GLFW_PRESS; - - // First time pressed? - if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == true) + // Only true if the key is currently being pressed + bool Input::IsKeyDown(int keycode) { - if (result) - m_Keys[keycode] = true; + auto window = Window::Get()->GetHandle(); + int state = glfwGetKey(window, keycode); + bool result = state == GLFW_PRESS; + + m_Keys[keycode] = state; return result; } - return false; -} - - -bool Input::IsKeyReleased(int keycode) -{ - auto window = Window::Get()->GetHandle(); - int state = glfwGetKey(window, keycode); - bool result = state == GLFW_RELEASE; - - // First time pressed? - if (m_Keys.find(keycode) == m_Keys.end()) - return result; - - if (result && m_Keys[keycode] == true) + // Only true if the key is pressed for the first frame. no repeat. + bool Input::IsKeyPressed(int keycode) { - return true; - } - + auto window = Window::Get()->GetHandle(); + int state = glfwGetKey(window, keycode); + bool result = state == GLFW_PRESS; - return false; -} + // First time pressed? + if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == true) + { + if (result) + m_Keys[keycode] = true; + + return result; + } + + return false; + } + + + bool Input::IsKeyReleased(int keycode) + { + auto window = Window::Get()->GetHandle(); + int state = glfwGetKey(window, keycode); + bool result = state == GLFW_RELEASE; + + // First time pressed? + if (m_Keys.find(keycode) == m_Keys.end()) + return result; + + if (result && m_Keys[keycode] == true) + { + return true; + } + + + return false; + } #pragma endregion #pragma region Mouse -// Visibility -void Input::HideMouse() { - auto window = Window::Get()->GetHandle(); - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); -} - -bool Input::IsMouseHidden() { - auto window = Window::Get()->GetHandle(); - return glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; -} - -void Input::ShowMouse() { - auto window = Window::Get()->GetHandle(); - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); -} - - -// Action -bool Input::IsMouseButtonDown(int button) -{ - auto window = Window::Get()->GetHandle(); - auto state = glfwGetMouseButton(window, button); - - return state == GLFW_PRESS; -} - -bool Input::IsMouseButtonPressed(int button) -{ - auto window = Window::Get()->GetHandle(); - auto state = glfwGetMouseButton(window, button); - - if (m_MouseButtons[button] == false && state == GLFW_PRESS) - { - m_MouseButtons[button] = true; - return true; + // Visibility + void Input::HideMouse() { + auto window = Window::Get()->GetHandle(); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); } - return false; -} + bool Input::IsMouseHidden() { + auto window = Window::Get()->GetHandle(); + return glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; + } -bool Input::IsMouseButtonReleased(int button) -{ - auto window = Window::Get()->GetHandle(); - auto state = glfwGetMouseButton(window, button); + void Input::ShowMouse() { + auto window = Window::Get()->GetHandle(); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } - return state == GLFW_RELEASE && m_MouseButtons[button] == true; -} -// Position -float Input::GetMouseX() -{ - auto window = Window::Get()->GetHandle(); + // Action + bool Input::IsMouseButtonDown(int button) + { + auto window = Window::Get()->GetHandle(); + auto state = glfwGetMouseButton(window, button); - double xpos, ypos; - glfwGetCursorPos(window, &xpos, &ypos); + return state == GLFW_PRESS; + } - return (float)xpos; -} + bool Input::IsMouseButtonPressed(int button) + { + auto window = Window::Get()->GetHandle(); + auto state = glfwGetMouseButton(window, button); -float Input::GetMouseY() -{ - auto window = Window::Get()->GetHandle(); + if (m_MouseButtons[button] == false && state == GLFW_PRESS) + { + m_MouseButtons[button] = true; + return true; + } - double xpos, ypos; - glfwGetCursorPos(window, &xpos, &ypos); + return false; + } - return (float)ypos; -} + bool Input::IsMouseButtonReleased(int button) + { + auto window = Window::Get()->GetHandle(); + auto state = glfwGetMouseButton(window, button); -Vector2 Input::GetMousePosition() -{ - auto window = Window::Get()->GetHandle(); + return state == GLFW_RELEASE && m_MouseButtons[button] == true; + } - double xpos, ypos; - glfwGetCursorPos(window, &xpos, &ypos); + // Position + float Input::GetMouseX() + { + auto window = Window::Get()->GetHandle(); - return Vector2(xpos, ypos); -} + double xpos, ypos; + glfwGetCursorPos(window, &xpos, &ypos); + + return (float)xpos; + } + + float Input::GetMouseY() + { + auto window = Window::Get()->GetHandle(); + + double xpos, ypos; + glfwGetCursorPos(window, &xpos, &ypos); + + return (float)ypos; + } + + Vector2 Input::GetMousePosition() + { + auto window = Window::Get()->GetHandle(); + + double xpos, ypos; + glfwGetCursorPos(window, &xpos, &ypos); + + return Vector2(xpos, ypos); + } #pragma endregion -bool Input::Init() -{ - //auto window = Application::Get().GetWindow()->GetNative(); - //glfwSetKeyCallback(window, Input::HandleInputCallback); - return false; -} - -void Input::Update() -{ - // Reset all input to false. - for (auto& k : m_Keys) + bool Input::Init() { - if(!IsKeyDown(k.first)) - k.second = false; + //auto window = Application::Get().GetWindow()->GetNative(); + //glfwSetKeyCallback(window, Input::HandleInputCallback); + return false; } - for (int i = 0; i < 5; i++) + void Input::Update() { - if(!IsMouseButtonDown(i)) - m_MouseButtons[i] = false; + // Reset all input to false. + for (auto& k : m_Keys) + { + if (!IsKeyDown(k.first)) + k.second = false; + } + + for (int i = 0; i < 5; i++) + { + if (!IsMouseButtonDown(i)) + m_MouseButtons[i] = false; + } } } + diff --git a/Nuake/src/Core/Input.h b/Nuake/src/Core/Input.h index d3dd7c50..35bd5897 100644 --- a/Nuake/src/Core/Input.h +++ b/Nuake/src/Core/Input.h @@ -2,33 +2,37 @@ #include #include "../Core/Maths.h" #include -class Input + +namespace Nuake { -private: - static bool m_MouseButtons[5]; - static std::map m_Keys; -public: - static bool IsKeyPressed(int keycode); - static bool IsKeyDown(int keycode); - static bool IsKeyReleased(int keycode); + class Input + { + private: + static bool m_MouseButtons[5]; + static std::map m_Keys; + public: + static bool IsKeyPressed(int keycode); + static bool IsKeyDown(int keycode); + static bool IsKeyReleased(int keycode); - - static void HideMouse(); - static void ShowMouse(); - static bool IsMouseHidden(); - static bool IsMouseButtonPressed(int button); - static bool IsMouseButtonDown(int button); - static bool IsMouseButtonReleased(int button); - static float GetMouseX(); - static float GetMouseY(); - static Vector2 GetMousePosition(); + static void HideMouse(); + static void ShowMouse(); + static bool IsMouseHidden(); + static bool IsMouseButtonPressed(int button); + static bool IsMouseButtonDown(int button); + static bool IsMouseButtonReleased(int button); - static bool Init(); - static void Update(); + static float GetMouseX(); + static float GetMouseY(); + static Vector2 GetMousePosition(); - Input* Get() { return s_Instance; } + static bool Init(); + static void Update(); -private: - static Input* s_Instance; -}; + Input* Get() { return s_Instance; } + + private: + static Input* s_Instance; + }; +} diff --git a/Nuake/src/Core/Logger.cpp b/Nuake/src/Core/Logger.cpp index 819aab3a..fb8e7fee 100644 --- a/Nuake/src/Core/Logger.cpp +++ b/Nuake/src/Core/Logger.cpp @@ -4,30 +4,33 @@ #include #include -std::vector Logger::m_Logs = std::vector(); - -void Logger::Log(std::string log, LOG_TYPE type) +namespace Nuake { - char buff[100]; - time_t now = time(0); - strftime(buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime(&now)); + std::vector Logger::m_Logs = std::vector(); - LogEntry newLog = { - type, - buff, - log - }; + void Logger::Log(std::string log, LOG_TYPE type) + { + char buff[100]; + time_t now = time(0); + strftime(buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime(&now)); - std::string msg = "[" + std::string(buff) + "]" + std::string(" - ") + log; - printf((msg + "\n").c_str()); + LogEntry newLog = { + type, + buff, + log + }; - if (m_Logs.size() >= MAX_LOG) - m_Logs.erase(m_Logs.begin()); + std::string msg = "[" + std::string(buff) + "]" + std::string(" - ") + log; + printf((msg + "\n").c_str()); - m_Logs.push_back(newLog); + if (m_Logs.size() >= MAX_LOG) + m_Logs.erase(m_Logs.begin()); + + m_Logs.push_back(newLog); + } + + std::vector Logger::GetLogs() + { + return m_Logs; + } } - -std::vector Logger::GetLogs() -{ - return m_Logs; -} \ No newline at end of file diff --git a/Nuake/src/Core/Logger.h b/Nuake/src/Core/Logger.h index 9be0d17d..54686589 100644 --- a/Nuake/src/Core/Logger.h +++ b/Nuake/src/Core/Logger.h @@ -2,25 +2,29 @@ #include #include -enum LOG_TYPE +namespace Nuake { - VERBOSE, - WARNING, - CRITICAL -}; + enum LOG_TYPE + { + VERBOSE, + WARNING, + CRITICAL + }; -struct LogEntry -{ - LOG_TYPE type; - std::string time; - std::string message; -}; + struct LogEntry + { + LOG_TYPE type; + std::string time; + std::string message; + }; -class Logger -{ - static const int MAX_LOG = 64; - static std::vector m_Logs; // TODO: Use log struct. -public: - static void Log(std::string log, LOG_TYPE type = VERBOSE); - static std::vector GetLogs(); -}; \ No newline at end of file + class Logger + { + public: + static void Log(std::string log, LOG_TYPE type = VERBOSE); + static std::vector GetLogs(); + private: + static const int MAX_LOG = 64; + static std::vector m_Logs; // TODO: Use log struct. + }; +} diff --git a/Nuake/src/Core/MaterialManager.cpp b/Nuake/src/Core/MaterialManager.cpp index 95bb05d5..fb891321 100644 --- a/Nuake/src/Core/MaterialManager.cpp +++ b/Nuake/src/Core/MaterialManager.cpp @@ -7,91 +7,100 @@ #include "json/json.hpp" #include "../Rendering/Textures/Material.h" -using json = nlohmann::json; -Ref MaterialManager::s_Instance; - -MaterialManager::MaterialManager() +namespace Nuake { - m_Materials = std::map>(); -} + using json = nlohmann::json; -Ref MaterialManager::GetMaterial(const std::string name) -{ - if (!IsMaterialLoaded(name)) + Ref MaterialManager::s_Instance; + + MaterialManager::MaterialManager() { - Ref newMaterial = CreateRef(name); - RegisterMaterial(newMaterial); + m_Materials = std::map>(); + } + + Ref MaterialManager::GetMaterial(const std::string name) + { + if (!IsMaterialLoaded(name)) + { + Ref newMaterial = CreateRef(name); + RegisterMaterial(newMaterial); + return newMaterial; + } + return m_Materials[name]; + } + + void MaterialManager::RegisterMaterial(Ref material) + { + m_Materials[material->GetName()] = material; + } + + // Gets a material from path and load file if not already loaded. + // + // NOTE: The path passed as param is relative to Res/Materials and + // shouldn't contain the '.material' extension. + Ref MaterialManager::LoadMaterial(const std::string materialPath) + { + if (IsMaterialLoaded(materialPath)) + return (m_Materials)[materialPath]; + + std::string finalPath = "Res/Materials/" + materialPath + ".material"; + std::ifstream i(finalPath); + json j; + i >> j; + + std::string matName; + if (!j.contains("name")) + { + std::string msg = "Error: Cannot load material file: " + materialPath + + " - Material file must have a name. \n"; + printf(msg.c_str()); + return nullptr; + } + else + { + matName = j["name"]; + } + + std::string albedoPath; + std::string normalPath; + std::string aoPath; + std::string metalPath; + std::string roughnessPath; + std::string displacementPath; + + Ref newMaterial = CreateRef(j["albedo"]); + //if (j.contains("albedo")) + // newMaterial = new Material(albedoPath); + //else + // newMaterial = new Material(glm::vec3(1, 1, 1)); + newMaterial->SetName(matName); + + if (j.contains("normal")) + newMaterial->SetNormal(j["normal"]); + if (j.contains("ao")) + newMaterial->SetAO(j["ao"]); + if (j.contains("metal")) + newMaterial->SetMetalness(j["metal"]); + if (j.contains("roughness")) + newMaterial->SetRoughness(j["roughness"]); + if (j.contains("displacement")) + newMaterial->SetDisplacement(j["displacement"]); + return newMaterial; } - return m_Materials[name]; -} -void MaterialManager::RegisterMaterial(Ref material) -{ - m_Materials[material->GetName()] = material; -} -// Gets a material from path and load file if not already loaded. -// -// NOTE: The path passed as param is relative to Res/Materials and -// shouldn't contain the '.material' extension. -Ref MaterialManager::LoadMaterial(const std::string materialPath) { - if (IsMaterialLoaded(materialPath)) - return (m_Materials)[materialPath]; - std::string finalPath = "Res/Materials/" + materialPath + ".material"; - std::ifstream i(finalPath); - json j; - i >> j; - - std::string matName; - if (!j.contains("name")) { - std::string msg = "Error: Cannot load material file: " + materialPath + - " - Material file must have a name. \n"; - printf(msg.c_str()); - return nullptr; + std::map> MaterialManager::GetAllMaterials() + { + return m_Materials; } - else { - matName = j["name"]; + + bool MaterialManager::IsMaterialLoaded(const std::string materialPath) + { + return m_Materials.find(materialPath) != m_Materials.end(); } - - std::string albedoPath; - std::string normalPath; - std::string aoPath; - std::string metalPath; - std::string roughnessPath; - std::string displacementPath; - - Ref newMaterial = CreateRef(j["albedo"]); - //if (j.contains("albedo")) - // newMaterial = new Material(albedoPath); - //else - // newMaterial = new Material(glm::vec3(1, 1, 1)); - newMaterial->SetName(matName); - - if (j.contains("normal")) - newMaterial->SetNormal(j["normal"]); - if (j.contains("ao")) - newMaterial->SetAO(j["ao"]); - if (j.contains("metal")) - newMaterial->SetMetalness(j["metal"]); - if (j.contains("roughness")) - newMaterial->SetRoughness(j["roughness"]); - if (j.contains("displacement")) - newMaterial->SetDisplacement(j["displacement"]); - - return newMaterial; } - -std::map> MaterialManager::GetAllMaterials() -{ - return m_Materials; -} - -bool MaterialManager::IsMaterialLoaded(const std::string materialPath) { - return m_Materials.find(materialPath) != m_Materials.end(); -} - diff --git a/Nuake/src/Core/MaterialManager.h b/Nuake/src/Core/MaterialManager.h index 975810b6..4488ed16 100644 --- a/Nuake/src/Core/MaterialManager.h +++ b/Nuake/src/Core/MaterialManager.h @@ -1,41 +1,46 @@ #pragma once #include #include -#include "../Core/Core.h" +#include "src/Core/Core.h" -class Material; +namespace Nuake +{ + class Material; -// TODO: Should probably be static. -class MaterialManager { -private: - static Ref s_Instance; - - std::map> m_Materials; - - // TODO: Pile of crap - Material* ParseMaterialFile(const std::string path); - void SaveMaterialFile(const std::string path, Material* material); - bool IsMaterialLoaded(const std::string path); - - -public: - std::string CurrentlyBoundedMaterial = ""; - MaterialManager(); - - void LoadMaterials(); - - void RegisterMaterial(Ref material); - - Ref LoadMaterial(const std::string path); - - Ref GetMaterial(const std::string name); - - std::map> GetAllMaterials(); - static Ref Get() + // TODO: Should probably be static. + class MaterialManager { - if (!s_Instance) - s_Instance = CreateRef(); + private: + static Ref s_Instance; - return s_Instance; - } -}; \ No newline at end of file + std::map> m_Materials; + + // TODO: Pile of crap + Material* ParseMaterialFile(const std::string path); + void SaveMaterialFile(const std::string path, Material* material); + bool IsMaterialLoaded(const std::string path); + + + public: + std::string CurrentlyBoundedMaterial = ""; + MaterialManager(); + + void LoadMaterials(); + + void RegisterMaterial(Ref material); + + Ref LoadMaterial(const std::string path); + + Ref GetMaterial(const std::string name); + + std::map> GetAllMaterials(); + + static Ref Get() + { + if (!s_Instance) + s_Instance = CreateRef(); + + return s_Instance; + } + }; +} diff --git a/Nuake/src/Core/Maths.h b/Nuake/src/Core/Maths.h index 09041ee9..0313f1d0 100644 --- a/Nuake/src/Core/Maths.h +++ b/Nuake/src/Core/Maths.h @@ -1,15 +1,17 @@ #pragma once #include #include +#include #include #include -#include - -using Vector3 = glm::vec3; -using Vector2 = glm::vec2; -using Vector4 = glm::vec4; -using Color = glm::vec4; -using Matrix4 = glm::mat4; +namespace Nuake +{ + using Vector3 = glm::vec3; + using Vector2 = glm::vec2; + using Vector4 = glm::vec4; + using Color = glm::vec4; + using Matrix4 = glm::mat4; +} diff --git a/Nuake/src/Core/OS.h b/Nuake/src/Core/OS.h index 4f7aa411..ec0649da 100644 --- a/Nuake/src/Core/OS.h +++ b/Nuake/src/Core/OS.h @@ -1,9 +1,13 @@ #pragma once - -class OS { -public: - static int GetTime() { - return std::chrono::system_clock::now().time_since_epoch().count(); - } -}; \ No newline at end of file +namespace Nuake +{ + class OS + { + public: + static int GetTime() + { + return std::chrono::system_clock::now().time_since_epoch().count(); + } + }; +} diff --git a/Nuake/src/Core/Physics/BulletDebugDrawer.cpp b/Nuake/src/Core/Physics/BulletDebugDrawer.cpp index fdfd21c9..652c777a 100644 --- a/Nuake/src/Core/Physics/BulletDebugDrawer.cpp +++ b/Nuake/src/Core/Physics/BulletDebugDrawer.cpp @@ -2,30 +2,32 @@ #include "../../Rendering/Renderer.h" #include -void BulletDebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color) +namespace Nuake { - TransformComponent tc = TransformComponent(); + void BulletDebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color) + { + TransformComponent tc = TransformComponent(); - tc.Translation = glm::vec3(from.x(), from.y(), from.z()); - tc.Scale = glm::vec3(1.0f); - tc.Rotation = glm::vec3(0.0f); + tc.Translation = glm::vec3(from.x(), from.y(), from.z()); + tc.Scale = glm::vec3(1.0f); + tc.Rotation = glm::vec3(0.0f); - glBegin(GL_LINES); - glColor3f((float)(color.x()), (float)(color.y()), (float)(color.z())); - glVertex3f((float)(from.x()), (float)(from.y()), (float)(from.z())); - glVertex3f((float)(to.x()), (float)(to.y()), (float)(to.z())); - glEnd(); + glBegin(GL_LINES); + glColor3f((float)(color.x()), (float)(color.y()), (float)(color.z())); + glVertex3f((float)(from.x()), (float)(from.y()), (float)(from.z())); + glVertex3f((float)(to.x()), (float)(to.y()), (float)(to.z())); + glEnd(); - //Renderer::DrawCube(tc, glm::vec4(color.x(), color.y(), color.z(), 1.0f)); + //Renderer::DrawCube(tc, glm::vec4(color.x(), color.y(), color.z(), 1.0f)); + } + + void BulletDebugDrawer::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) + { + if (lifeTime > 3.0f) + return; + glBegin(GL_POINTS); + glColor3f(color.x(), color.y(), color.z()); + glVertex3f(PointOnB.x(), PointOnB.y(), PointOnB.z()); + glEnd(); + } } - -void BulletDebugDrawer::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) -{ - if (lifeTime > 3.0f) - return; - glBegin(GL_POINTS); - glColor3f(color.x(), color.y(), color.z()); - glVertex3f(PointOnB.x(), PointOnB.y(), PointOnB.z()); - glEnd(); -} - diff --git a/Nuake/src/Core/Physics/BulletDebugDrawer.h b/Nuake/src/Core/Physics/BulletDebugDrawer.h index 9a90e21e..46218269 100644 --- a/Nuake/src/Core/Physics/BulletDebugDrawer.h +++ b/Nuake/src/Core/Physics/BulletDebugDrawer.h @@ -1,16 +1,20 @@ #pragma once #include "btBulletCollisionCommon.h" -class BulletDebugDrawer : public btIDebugDraw + +namespace Nuake { - void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override; + class BulletDebugDrawer : public btIDebugDraw + { + void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override; - int getDebugMode() const override { return 1; } + int getDebugMode() const override { return 1; } - void draw3dText(const btVector3& location, const char* textString) override {} + void draw3dText(const btVector3& location, const char* textString) override {} - void reportErrorWarning(const char* warningString) override { }; + void reportErrorWarning(const char* warningString) override { }; - void setDebugMode(int debugMode) {}; + void setDebugMode(int debugMode) {}; - void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) override; -}; \ No newline at end of file + void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) override; + }; +} diff --git a/Nuake/src/Core/Physics/CharacterController.cpp b/Nuake/src/Core/Physics/CharacterController.cpp index d169b7af..4262d675 100644 --- a/Nuake/src/Core/Physics/CharacterController.cpp +++ b/Nuake/src/Core/Physics/CharacterController.cpp @@ -1,211 +1,216 @@ #include "CharacterController.h" -#include "../Core/Physics/PhysicsManager.h" -#include "../Core/Physics/RaycastResult.h" -namespace Physics +#include "src/Core/Physics/PhysicsManager.h" +#include "src/Core/Physics/RaycastResult.h" + +namespace Nuake { - CharacterController::CharacterController(float height, float radius, float mass, Vector3 position) + namespace Physics { - m_surfaceHitNormals = std::vector(); - - m_bottomRoundedRegionYOffset = (height + radius) / 2.0f; - m_bottomYOffset = height / 2.0f + radius; - m_CollisionShape = new btCapsuleShape(radius, height); - - btQuaternion quat = btQuaternion(0, 0, 0); - m_Transform = new btTransform(); - m_Transform->setOrigin(btVector3(position.x, position.y, position.z)); - m_Transform->setRotation(quat); - m_MotionState = new btDefaultMotionState(*m_Transform); - - btVector3 inertia; - //m_CollisionShape->calculateLocalInertia(mass, inertia); - - btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, m_MotionState, m_CollisionShape, inertia); - - rigidBodyCI.m_friction = 0.0f; - //rigidBodyCI.m_additionalDamping = true; - //rigidBodyCI.m_additionalLinearDampingThresholdSqr= 1.0f; - //rigidBodyCI.m_additionalLinearDampingThresholdSqr = 0.5f; - rigidBodyCI.m_restitution = 0.0f; - - rigidBodyCI.m_linearDamping = 0.0f; - m_Rigidbody = new btRigidBody(rigidBodyCI); - m_Rigidbody->setGravity(btVector3(0, 0, 0)); - // Keep upright - m_Rigidbody->setAngularFactor(0.0f); - - // No sleeping (or else setLinearVelocity won't work) - m_Rigidbody->setActivationState(DISABLE_DEACTIVATION); - - //m_pPhysicsWorld->m_pDynamicsWorld->addRigidBody(m_pRigidBody); - - // Ghost object that is synchronized with rigid body - m_GhostObject = new btPairCachingGhostObject(); - m_GhostObject->setCollisionShape(m_CollisionShape); - - // Specify filters manually, otherwise ghost doesn't collide with statics for some reason - //m_pPhysicsWorld->m_pDynamicsWorld->addCollisionObject(m_pGhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); - } - - void CharacterController::SetEntity(Entity& ent) - { - m_Rigidbody->setUserIndex(ent.GetHandle()); - m_GhostObject->setUserIndex(ent.GetHandle()); - } - - - - void CharacterController::MoveAndSlide(glm::vec3 velocity) - { - m_Rigidbody->setGravity(btVector3(0, 0, 0)); - m_manualVelocity = velocity; - // Sync ghost with actually object - m_GhostObject->setWorldTransform(m_Rigidbody->getWorldTransform()); - - IsOnGround = false; - ParseGhostContacts(); - UpdatePosition(); - UpdateVelocity(); - m_MotionState->getWorldTransform(m_motionTransform); - } - - void CharacterController::ParseGhostContacts() - { - btManifoldArray manifoldArray; - btBroadphasePairArray& pairArray = m_GhostObject->getOverlappingPairCache()->getOverlappingPairArray(); - int numPairs = pairArray.size(); - - m_hittingWall = false; - - for (int i = 0; i < numPairs; i++) + CharacterController::CharacterController(float height, float radius, float mass, Vector3 position) { - manifoldArray.clear(); + m_surfaceHitNormals = std::vector(); - const btBroadphasePair& pair = pairArray[i]; - - btDiscreteDynamicsWorld* world = PhysicsManager::Get()->GetWorld()->GetDynamicWorld(); - btBroadphasePair* collisionPair = world->getPairCache()->findPair(pair.m_pProxy0, pair.m_pProxy1); + m_bottomRoundedRegionYOffset = (height + radius) / 2.0f; + m_bottomYOffset = height / 2.0f + radius; + m_CollisionShape = new btCapsuleShape(radius, height); - if (collisionPair == NULL) - continue; + btQuaternion quat = btQuaternion(0, 0, 0); + m_Transform = new btTransform(); + m_Transform->setOrigin(btVector3(position.x, position.y, position.z)); + m_Transform->setRotation(quat); + m_MotionState = new btDefaultMotionState(*m_Transform); - if (collisionPair->m_algorithm != NULL) - collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); + btVector3 inertia; + //m_CollisionShape->calculateLocalInertia(mass, inertia); - for (int j = 0; j < manifoldArray.size(); j++) + btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, m_MotionState, m_CollisionShape, inertia); + + rigidBodyCI.m_friction = 0.0f; + //rigidBodyCI.m_additionalDamping = true; + //rigidBodyCI.m_additionalLinearDampingThresholdSqr= 1.0f; + //rigidBodyCI.m_additionalLinearDampingThresholdSqr = 0.5f; + rigidBodyCI.m_restitution = 0.0f; + + rigidBodyCI.m_linearDamping = 0.0f; + m_Rigidbody = new btRigidBody(rigidBodyCI); + m_Rigidbody->setGravity(btVector3(0, 0, 0)); + // Keep upright + m_Rigidbody->setAngularFactor(0.0f); + + // No sleeping (or else setLinearVelocity won't work) + m_Rigidbody->setActivationState(DISABLE_DEACTIVATION); + + //m_pPhysicsWorld->m_pDynamicsWorld->addRigidBody(m_pRigidBody); + + // Ghost object that is synchronized with rigid body + m_GhostObject = new btPairCachingGhostObject(); + m_GhostObject->setCollisionShape(m_CollisionShape); + + // Specify filters manually, otherwise ghost doesn't collide with statics for some reason + //m_pPhysicsWorld->m_pDynamicsWorld->addCollisionObject(m_pGhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); + } + + void CharacterController::SetEntity(Entity& ent) + { + m_Rigidbody->setUserIndex(ent.GetHandle()); + m_GhostObject->setUserIndex(ent.GetHandle()); + } + + + + void CharacterController::MoveAndSlide(glm::vec3 velocity) + { + m_Rigidbody->setGravity(btVector3(0, 0, 0)); + m_manualVelocity = velocity; + // Sync ghost with actually object + m_GhostObject->setWorldTransform(m_Rigidbody->getWorldTransform()); + + IsOnGround = false; + ParseGhostContacts(); + UpdatePosition(); + UpdateVelocity(); + m_MotionState->getWorldTransform(m_motionTransform); + } + + void CharacterController::ParseGhostContacts() + { + btManifoldArray manifoldArray; + btBroadphasePairArray& pairArray = m_GhostObject->getOverlappingPairCache()->getOverlappingPairArray(); + int numPairs = pairArray.size(); + + m_hittingWall = false; + + for (int i = 0; i < numPairs; i++) { - btPersistentManifold* pManifold = manifoldArray[j]; + manifoldArray.clear(); - // Skip the rigid body the ghost monitors - if (pManifold->getBody0() == m_Rigidbody) + const btBroadphasePair& pair = pairArray[i]; + + btDiscreteDynamicsWorld* world = PhysicsManager::Get()->GetWorld()->GetDynamicWorld(); + btBroadphasePair* collisionPair = world->getPairCache()->findPair(pair.m_pProxy0, pair.m_pProxy1); + + if (collisionPair == NULL) continue; - for (int p = 0; p < pManifold->getNumContacts(); p++) + if (collisionPair->m_algorithm != NULL) + collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); + + for (int j = 0; j < manifoldArray.size(); j++) { - const btManifoldPoint& point = pManifold->getContactPoint(p); + btPersistentManifold* pManifold = manifoldArray[j]; - if (point.getDistance() < 0.0f) + // Skip the rigid body the ghost monitors + if (pManifold->getBody0() == m_Rigidbody) + continue; + + for (int p = 0; p < pManifold->getNumContacts(); p++) { - //const btVector3 &ptA = point.getPositionWorldOnA(); - const btVector3& ptB = point.getPositionWorldOnB(); + const btManifoldPoint& point = pManifold->getContactPoint(p); - //const btVector3 &normalOnB = point.m_normalWorldOnB; - - // If point is in rounded bottom region of capsule shape, it is on the ground - if (ptB.getY() < m_motionTransform.getOrigin().getY() - m_bottomRoundedRegionYOffset) - IsOnGround = true; - else + if (point.getDistance() < 0.0f) { - m_hittingWall = true; + //const btVector3 &ptA = point.getPositionWorldOnA(); + const btVector3& ptB = point.getPositionWorldOnB(); - m_surfaceHitNormals.push_back(glm::vec3(point.m_normalWorldOnB.x(), point.m_normalWorldOnB.y(), point.m_normalWorldOnB.z())); + //const btVector3 &normalOnB = point.m_normalWorldOnB; + + // If point is in rounded bottom region of capsule shape, it is on the ground + if (ptB.getY() < m_motionTransform.getOrigin().getY() - m_bottomRoundedRegionYOffset) + IsOnGround = true; + else + { + m_hittingWall = true; + + m_surfaceHitNormals.push_back(glm::vec3(point.m_normalWorldOnB.x(), point.m_normalWorldOnB.y(), point.m_normalWorldOnB.z())); + } } } } } } - } - void CharacterController::UpdatePosition() - { - // Ray cast, ignore rigid body - IgnoreBodyAndGhostCast rayCallBack_bottom(m_Rigidbody, m_GhostObject); - - btVector3 from = m_Rigidbody->getWorldTransform().getOrigin(); - btVector3 toBt = m_Rigidbody->getWorldTransform().getOrigin() - btVector3(0.0f, m_bottomYOffset + m_stepHeight , 0.0f); - PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(from, toBt, rayCallBack_bottom); - - // Bump up if hit - if (rayCallBack_bottom.hasHit()) + void CharacterController::UpdatePosition() { - float previousY = m_Rigidbody->getWorldTransform().getOrigin().getY(); + // Ray cast, ignore rigid body + IgnoreBodyAndGhostCast rayCallBack_bottom(m_Rigidbody, m_GhostObject); + btVector3 from = m_Rigidbody->getWorldTransform().getOrigin(); + btVector3 toBt = m_Rigidbody->getWorldTransform().getOrigin() - btVector3(0.0f, m_bottomYOffset + m_stepHeight, 0.0f); + PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(from, toBt, rayCallBack_bottom); - float t = rayCallBack_bottom.m_closestHitFraction ; - - float clamped = (1.0 - rayCallBack_bottom.m_closestHitFraction); - btVector3 vel(m_Rigidbody->getLinearVelocity()); - - if(vel.getY() < 0) // -magic number is to fix bouncing down a slope. - m_Rigidbody->getWorldTransform().getOrigin().setY(previousY - 0.14f + (m_bottomYOffset + m_stepHeight) * (clamped)); - - vel.setY(0.0f); - - m_Rigidbody->setLinearVelocity(vel); - - IsOnGround = true; - - } - - - - float testOffset = 0.07f; - - // Ray cast, ignore rigid body - IgnoreBodyAndGhostCast rayCallBack_top(m_Rigidbody, m_GhostObject); - - PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(m_Rigidbody->getWorldTransform().getOrigin(), m_Rigidbody->getWorldTransform().getOrigin() + btVector3(0.0f, m_bottomYOffset + testOffset, 0.0f), rayCallBack_top); - - // Bump up if hit - if (rayCallBack_top.hasHit()) - { - m_Rigidbody->getWorldTransform().setOrigin(m_previousPosition); - - btVector3 vel(m_Rigidbody->getLinearVelocity()); - - vel.setY(0.0f); - - m_Rigidbody->setLinearVelocity(vel); - } - - m_previousPosition = m_Rigidbody->getWorldTransform().getOrigin(); - } - - void CharacterController::UpdateVelocity() - { - //m_manualVelocity.y = m_Rigidbody->getLinearVelocity().getY(); - btVector3 grav = m_Rigidbody->getGravity(); - btVector3 finalVel = btVector3(m_manualVelocity.x, m_manualVelocity.y, m_manualVelocity.z); - m_Rigidbody->setLinearVelocity(finalVel); - - // Decelerate - //m_manualVelocity -= m_manualVelocity * m_deceleration * m_pPhysicsWorld->GetScene()->m_frameTimer.GetTimeMultiplier(); - - if (m_hittingWall) - { - for (unsigned int i = 0, size = m_surfaceHitNormals.size(); i < size; i++) + // Bump up if hit + if (rayCallBack_bottom.hasHit()) { - // Cancel velocity across normal - glm::vec3 velInNormalDir(glm::reflect(m_manualVelocity, m_surfaceHitNormals[i])); + float previousY = m_Rigidbody->getWorldTransform().getOrigin().getY(); + + + float t = rayCallBack_bottom.m_closestHitFraction; + + float clamped = (1.0 - rayCallBack_bottom.m_closestHitFraction); + btVector3 vel(m_Rigidbody->getLinearVelocity()); + + if (vel.getY() < 0) // -magic number is to fix bouncing down a slope. + m_Rigidbody->getWorldTransform().getOrigin().setY(previousY - 0.14f + (m_bottomYOffset + m_stepHeight) * (clamped)); + + vel.setY(0.0f); + + m_Rigidbody->setLinearVelocity(vel); + + IsOnGround = true; - // Apply correction - m_manualVelocity -= velInNormalDir * 1.05f; } - // Do not adjust rigid body velocity manually (so bodies can still be pushed by character) - return; + + + float testOffset = 0.07f; + + // Ray cast, ignore rigid body + IgnoreBodyAndGhostCast rayCallBack_top(m_Rigidbody, m_GhostObject); + + PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(m_Rigidbody->getWorldTransform().getOrigin(), m_Rigidbody->getWorldTransform().getOrigin() + btVector3(0.0f, m_bottomYOffset + testOffset, 0.0f), rayCallBack_top); + + // Bump up if hit + if (rayCallBack_top.hasHit()) + { + m_Rigidbody->getWorldTransform().setOrigin(m_previousPosition); + + btVector3 vel(m_Rigidbody->getLinearVelocity()); + + vel.setY(0.0f); + + m_Rigidbody->setLinearVelocity(vel); + } + + m_previousPosition = m_Rigidbody->getWorldTransform().getOrigin(); + } + + void CharacterController::UpdateVelocity() + { + //m_manualVelocity.y = m_Rigidbody->getLinearVelocity().getY(); + btVector3 grav = m_Rigidbody->getGravity(); + btVector3 finalVel = btVector3(m_manualVelocity.x, m_manualVelocity.y, m_manualVelocity.z); + m_Rigidbody->setLinearVelocity(finalVel); + + // Decelerate + //m_manualVelocity -= m_manualVelocity * m_deceleration * m_pPhysicsWorld->GetScene()->m_frameTimer.GetTimeMultiplier(); + + if (m_hittingWall) + { + for (unsigned int i = 0, size = m_surfaceHitNormals.size(); i < size; i++) + { + // Cancel velocity across normal + glm::vec3 velInNormalDir(glm::reflect(m_manualVelocity, m_surfaceHitNormals[i])); + + // Apply correction + m_manualVelocity -= velInNormalDir * 1.05f; + } + + // Do not adjust rigid body velocity manually (so bodies can still be pushed by character) + return; + } } } } + diff --git a/Nuake/src/Core/Physics/CharacterController.h b/Nuake/src/Core/Physics/CharacterController.h index 43c2c2e4..72785e17 100644 --- a/Nuake/src/Core/Physics/CharacterController.h +++ b/Nuake/src/Core/Physics/CharacterController.h @@ -1,56 +1,57 @@ #pragma once -#include -#include "../Core/Core.h" +#include "src/Core/Core.h" +#include "src/Core/Maths.h" + #include - #include -#include -#include "../Core/Maths.h" - -class Entity; -namespace Physics +namespace Nuake { - class CharacterController + class Entity; + + namespace Physics { - public: - bool IsOnGround = false; - bool m_hittingWall; - float m_stepHeight = 0.35f; - float m_MaxSlopeAngle = 45.0f; - - btTransform* m_Transform; - btCollisionShape* m_CollisionShape; - btRigidBody* m_Rigidbody; - btPairCachingGhostObject* m_GhostObject; - btMotionState* m_MotionState; - - //bool m_onJumpableGround; // A bit lower contact than just onGround - - float m_bottomYOffset; - float m_bottomRoundedRegionYOffset ; - - btTransform m_motionTransform; - - glm::vec3 m_manualVelocity; - std::vector m_surfaceHitNormals; - - btVector3 m_previousPosition; - - float m_jumpRechargeTimer; - CharacterController(float height, float radius, float mass, Vector3 position); - - void SetEntity(Entity& ent); - void MoveAndSlide(glm::vec3 velocity); - - bool IsOnFloor() + class CharacterController { - return IsOnGround; - } + public: + bool IsOnGround = false; + bool m_hittingWall; + float m_stepHeight = 0.35f; + float m_MaxSlopeAngle = 45.0f; - private: - void ParseGhostContacts(); - void UpdatePosition(); - void UpdateVelocity(); - }; -} \ No newline at end of file + btTransform* m_Transform; + btCollisionShape* m_CollisionShape; + btRigidBody* m_Rigidbody; + btPairCachingGhostObject* m_GhostObject; + btMotionState* m_MotionState; + + //bool m_onJumpableGround; // A bit lower contact than just onGround + + float m_bottomYOffset; + float m_bottomRoundedRegionYOffset; + + btTransform m_motionTransform; + + glm::vec3 m_manualVelocity; + std::vector m_surfaceHitNormals; + + btVector3 m_previousPosition; + + float m_jumpRechargeTimer; + CharacterController(float height, float radius, float mass, Vector3 position); + + void SetEntity(Entity& ent); + void MoveAndSlide(glm::vec3 velocity); + + bool IsOnFloor() + { + return IsOnGround; + } + + private: + void ParseGhostContacts(); + void UpdatePosition(); + void UpdateVelocity(); + }; + } +} diff --git a/Nuake/src/Core/Physics/DynamicWorld.cpp b/Nuake/src/Core/Physics/DynamicWorld.cpp index e8b47470..a620b631 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -5,128 +5,131 @@ #include #include -namespace Physics +namespace Nuake { - - DynamicWorld::DynamicWorld() { - ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration. - btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); - - ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) - btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); - - ///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep. - btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase(); - - ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) - btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; - - dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration); - dynamicsWorld->setDebugDrawer(new BulletDebugDrawer()); - - m_Bodies = std::map>(); - - SetGravity(Vector3(0, -10000, 0)); - } - - - void DynamicWorld::DrawDebug() + namespace Physics { - dynamicsWorld->debugDrawWorld(); - } + DynamicWorld::DynamicWorld() { + ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration. + btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) + btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); - void DynamicWorld::SetGravity(glm::vec3 g) - { - dynamicsWorld->setGravity(btVector3(g.x, g.y, g.z)); - } + ///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep. + btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase(); + ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) + btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; - void DynamicWorld::AddRigidbody(Ref rb) - { - btRigidBody* bt = rb->GetBulletRigidbody(); - m_Bodies.emplace(std::pair>(bt, rb)); - dynamicsWorld->addRigidBody(rb->GetBulletRigidbody()); - } + dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration); + dynamicsWorld->setDebugDrawer(new BulletDebugDrawer()); - void DynamicWorld::AddGhostbody(Ref gb) - { - dynamicsWorld->addCollisionObject(gb->GetBulletObject(), btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::KinematicFilter); - } + m_Bodies = std::map>(); - void DynamicWorld::AddCharacterController(Ref cc) - { - dynamicsWorld->addRigidBody(cc->m_Rigidbody); - - // Specify filters manually, otherwise ghost doesn't collide with statics for some reason - dynamicsWorld->addCollisionObject(cc->m_GhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::SensorTrigger | btBroadphaseProxy::StaticFilter ); - } - - - RaycastResult DynamicWorld::Raycast(glm::vec3 from, glm::vec3 to) - { - btVector3 btFrom(from.x, from.y, from.z); - btVector3 btTo(to.x, to.y, to.z); - ClosestRayResultCallback res(btFrom, btTo); - - dynamicsWorld->rayTest(btFrom, btTo, res); - btVector3 localNormal; - if(res.m_collisionObject) - { - // TODO: Fix the godammn fucked up normal - localNormal = res.m_hitNormalWorld; + SetGravity(Vector3(0, -10000, 0)); } - - - Vector3 localNorm = glm::vec3(localNormal.x(), localNormal.y(), localNormal.z()); - - //Logger::Log("normal: x:" + std::to_string(localNorm.x) + " y:" + std::to_string(localNorm.y )+ "z: " + std::to_string(localNorm.z)); - res.m_closestHitFraction; - // Map bullet result to dto. - RaycastResult result{ - glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()), - glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()), - localNorm - }; - - return result; - } - void DynamicWorld::StepSimulation(Timestep ts) - { - dynamicsWorld->stepSimulation(ts, 10); - for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) + void DynamicWorld::DrawDebug() { - btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j]; - btRigidBody* body = btRigidBody::upcast(obj); - btTransform trans; - if (body && body->getMotionState()) - { - - body->getMotionState()->getWorldTransform(trans); - if(m_Bodies.find(body) != m_Bodies.end()) - m_Bodies[body]->UpdateTransform(trans); - } - else - { - trans = obj->getWorldTransform(); - if (m_Bodies.find(body) != m_Bodies.end()) - m_Bodies[body]->UpdateTransform(trans); - } - //printf("world pos object %d = %f,%f,%f\n", j, float(trans.getOrigin().getX()), float(trans.getOrigin().getY()), float(trans.getOrigin().getZ())); + dynamicsWorld->debugDrawWorld(); } - } - void DynamicWorld::Clear() - { - for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) + void DynamicWorld::SetGravity(glm::vec3 g) { - btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j]; - dynamicsWorld->removeCollisionObject(obj); + dynamicsWorld->setGravity(btVector3(g.x, g.y, g.z)); } - m_Bodies.clear(); + + void DynamicWorld::AddRigidbody(Ref rb) + { + btRigidBody* bt = rb->GetBulletRigidbody(); + m_Bodies.emplace(std::pair>(bt, rb)); + dynamicsWorld->addRigidBody(rb->GetBulletRigidbody()); + } + + void DynamicWorld::AddGhostbody(Ref gb) + { + dynamicsWorld->addCollisionObject(gb->GetBulletObject(), btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::KinematicFilter); + } + + void DynamicWorld::AddCharacterController(Ref cc) + { + dynamicsWorld->addRigidBody(cc->m_Rigidbody); + + // Specify filters manually, otherwise ghost doesn't collide with statics for some reason + dynamicsWorld->addCollisionObject(cc->m_GhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::SensorTrigger | btBroadphaseProxy::StaticFilter); + } + + + RaycastResult DynamicWorld::Raycast(glm::vec3 from, glm::vec3 to) + { + btVector3 btFrom(from.x, from.y, from.z); + btVector3 btTo(to.x, to.y, to.z); + ClosestRayResultCallback res(btFrom, btTo); + + dynamicsWorld->rayTest(btFrom, btTo, res); + btVector3 localNormal; + if (res.m_collisionObject) + { + // TODO: Fix the godammn fucked up normal + localNormal = res.m_hitNormalWorld; + } + + + Vector3 localNorm = glm::vec3(localNormal.x(), localNormal.y(), localNormal.z()); + + //Logger::Log("normal: x:" + std::to_string(localNorm.x) + " y:" + std::to_string(localNorm.y )+ "z: " + std::to_string(localNorm.z)); + res.m_closestHitFraction; + // Map bullet result to dto. + RaycastResult result{ + glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()), + glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()), + localNorm + }; + + return result; + } + + + void DynamicWorld::StepSimulation(Timestep ts) + { + dynamicsWorld->stepSimulation(ts, 10); + for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) + { + btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j]; + btRigidBody* body = btRigidBody::upcast(obj); + btTransform trans; + if (body && body->getMotionState()) + { + + body->getMotionState()->getWorldTransform(trans); + if (m_Bodies.find(body) != m_Bodies.end()) + m_Bodies[body]->UpdateTransform(trans); + } + else + { + trans = obj->getWorldTransform(); + if (m_Bodies.find(body) != m_Bodies.end()) + m_Bodies[body]->UpdateTransform(trans); + } + //printf("world pos object %d = %f,%f,%f\n", j, float(trans.getOrigin().getX()), float(trans.getOrigin().getY()), float(trans.getOrigin().getZ())); + } + } + + + void DynamicWorld::Clear() + { + for (int j = dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) + { + btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j]; + dynamicsWorld->removeCollisionObject(obj); + } + + m_Bodies.clear(); + } } + } diff --git a/Nuake/src/Core/Physics/DynamicWorld.h b/Nuake/src/Core/Physics/DynamicWorld.h index 04156baf..b5985464 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.h +++ b/Nuake/src/Core/Physics/DynamicWorld.h @@ -2,34 +2,39 @@ #include #include #include "Rigibody.h" -#include "../Timestep.h" -#include "../Core/Core.h" +#include "src/Core/Timestep.h" +#include "src/Core/Core.h" #include #include "RaycastResult.h" #include #include "CharacterController.h" -namespace Physics { - class DynamicWorld { - private: - btDiscreteDynamicsWorld* dynamicsWorld; - std::map> m_Bodies; - public: - DynamicWorld(); - void DrawDebug(); +namespace Nuake +{ + namespace Physics { + class DynamicWorld { + private: + btDiscreteDynamicsWorld* dynamicsWorld; + std::map> m_Bodies; + public: + DynamicWorld(); - void SetGravity(glm::vec3 g); - void AddRigidbody(Ref rb); + void DrawDebug(); - void AddGhostbody(Ref gb); + void SetGravity(glm::vec3 g); + void AddRigidbody(Ref rb); - void AddCharacterController(Ref < CharacterController> cc); + void AddGhostbody(Ref gb); - RaycastResult Raycast(glm::vec3 from, glm::vec3 to); - void StepSimulation(Timestep ts); - void Clear(); + void AddCharacterController(Ref < CharacterController> cc); - btDiscreteDynamicsWorld* GetDynamicWorld() { return dynamicsWorld; } - }; + RaycastResult Raycast(glm::vec3 from, glm::vec3 to); + void StepSimulation(Timestep ts); + void Clear(); + + btDiscreteDynamicsWorld* GetDynamicWorld() { return dynamicsWorld; } + }; + } } + diff --git a/Nuake/src/Core/Physics/GhostObject.cpp b/Nuake/src/Core/Physics/GhostObject.cpp index 54328dd3..17a838e1 100644 --- a/Nuake/src/Core/Physics/GhostObject.cpp +++ b/Nuake/src/Core/Physics/GhostObject.cpp @@ -4,57 +4,59 @@ #include #include - -GhostObject::GhostObject(Vector3 position, Ref shape) +namespace Nuake { - m_OverlappingEntities = std::vector(); - m_BulletObject = new btGhostObject(); - - btTransform transform = btTransform(); - transform.setIdentity(); - transform.setOrigin(btVector3(position.x, position.y, position.z)); - - m_BulletObject->setWorldTransform(transform); - m_BulletObject->setCollisionShape(shape->GetBulletShape()); -} - -int GhostObject::OverlappingCount() -{ - return m_BulletObject->getNumOverlappingObjects(); -} - -void GhostObject::ClearOverlappingList() -{ - m_OverlappingEntities.clear(); -} - -void GhostObject::SetEntityID(Entity ent) -{ - m_BulletObject->setUserIndex(ent.GetHandle()); -} - -void GhostObject::ScanOverlap() -{ - ClearOverlappingList(); - - for (int i = 0; i < OverlappingCount(); i++) + GhostObject::GhostObject(Vector3 position, Ref shape) { - int index = m_BulletObject->getOverlappingObject(i)->getUserIndex(); - if (index == -1) - continue; + m_OverlappingEntities = std::vector(); + m_BulletObject = new btGhostObject(); - Entity handle = Engine::GetCurrentScene()->GetEntity(index); - m_OverlappingEntities.push_back(handle); + btTransform transform = btTransform(); + transform.setIdentity(); + transform.setOrigin(btVector3(position.x, position.y, position.z)); + + m_BulletObject->setWorldTransform(transform); + m_BulletObject->setCollisionShape(shape->GetBulletShape()); + } + + int GhostObject::OverlappingCount() + { + return m_BulletObject->getNumOverlappingObjects(); + } + + void GhostObject::ClearOverlappingList() + { + m_OverlappingEntities.clear(); + } + + void GhostObject::SetEntityID(Entity ent) + { + m_BulletObject->setUserIndex(ent.GetHandle()); + } + + void GhostObject::ScanOverlap() + { + ClearOverlappingList(); + + for (int i = 0; i < OverlappingCount(); i++) + { + int index = m_BulletObject->getOverlappingObject(i)->getUserIndex(); + if (index == -1) + continue; + + Entity handle = Engine::GetCurrentScene()->GetEntity(index); + m_OverlappingEntities.push_back(handle); + } + } + + std::vector GhostObject::GetOverlappingEntities() + { + return m_OverlappingEntities; + } + + // Internal use only. + btGhostObject* GhostObject::GetBulletObject() + { + return m_BulletObject; } } - -std::vector GhostObject::GetOverlappingEntities() -{ - return m_OverlappingEntities; -} - -// Internal use only. -btGhostObject* GhostObject::GetBulletObject() -{ - return m_BulletObject; -} \ No newline at end of file diff --git a/Nuake/src/Core/Physics/GhostObject.h b/Nuake/src/Core/Physics/GhostObject.h index e8e440f8..f1bf3d8a 100644 --- a/Nuake/src/Core/Physics/GhostObject.h +++ b/Nuake/src/Core/Physics/GhostObject.h @@ -1,27 +1,33 @@ #pragma once #include "src/Core/Core.h" +#include "src/Core/Maths.h" #include "PhysicsShapes.h" #include #include + class btGhostObject; -class GhostObject { -private: - btGhostObject* m_BulletObject; - std::vector m_OverlappingEntities; -public: - GhostObject(Vector3 position, Ref shape); +namespace Nuake +{ + class GhostObject { + private: + btGhostObject* m_BulletObject; + std::vector m_OverlappingEntities; - int OverlappingCount(); - void ClearOverlappingList(); - void ScanOverlap(); + public: + GhostObject(Vector3 position, Ref shape); - void SetEntityID(Entity ent); + int OverlappingCount(); + void ClearOverlappingList(); + void ScanOverlap(); - std::vector GetOverlappingEntities(); + void SetEntityID(Entity ent); - // Internal use only. - btGhostObject* GetBulletObject(); -}; \ No newline at end of file + std::vector GetOverlappingEntities(); + + // Internal use only. + btGhostObject* GetBulletObject(); + }; +} diff --git a/Nuake/src/Core/Physics/PhysicsManager.cpp b/Nuake/src/Core/Physics/PhysicsManager.cpp index 9d74c228..f51c49f1 100644 --- a/Nuake/src/Core/Physics/PhysicsManager.cpp +++ b/Nuake/src/Core/Physics/PhysicsManager.cpp @@ -2,54 +2,58 @@ #include "PhysicsShapes.h" #include "btBulletDynamicsCommon.h" #include "../Core/Core.h" -PhysicsManager* PhysicsManager::m_Instance; -void PhysicsManager::RegisterBody(Ref rb) { - m_World->AddRigidbody(rb); -} - -void PhysicsManager::RegisterGhostBody(Ref rb) +namespace Nuake { - m_World->AddGhostbody(rb); - + PhysicsManager* PhysicsManager::m_Instance; + + void PhysicsManager::RegisterBody(Ref rb) { + m_World->AddRigidbody(rb); + } + + void PhysicsManager::RegisterGhostBody(Ref rb) + { + m_World->AddGhostbody(rb); + + } + + void PhysicsManager::RegisterCharacterController(Ref cc) { + m_World->AddCharacterController(cc); + } + + void PhysicsManager::Step(Timestep ts) + { + m_World->StepSimulation(ts); + } + + void PhysicsManager::Reset() + { + m_World->Clear(); + } + + RaycastResult PhysicsManager::Raycast(glm::vec3 from, glm::vec3 to) + { + btVector3 btFrom(from.x, from.y, from.z); + btVector3 btTo(to.x, to.y, to.z); + btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo); + + return m_World->Raycast(from, to); + + } + + void PhysicsManager::DrawDebug() + { + if (m_DrawDebug) + m_World->DrawDebug(); + } + + void PhysicsManager::Init() { + + m_World = new Physics::DynamicWorld(); + m_World->SetGravity(glm::vec3(0, -3, 0)); + + m_World->GetDynamicWorld()->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback()); + + m_IsRunning = false; + } } - -void PhysicsManager::RegisterCharacterController(Ref cc) { - m_World->AddCharacterController(cc); -} - -void PhysicsManager::Step(Timestep ts) -{ - m_World->StepSimulation(ts); -} - -void PhysicsManager::Reset() -{ - m_World->Clear(); -} - -RaycastResult PhysicsManager::Raycast(glm::vec3 from, glm::vec3 to) -{ - btVector3 btFrom(from.x, from.y, from.z); - btVector3 btTo(to.x, to.y, to.z); - btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo); - - return m_World->Raycast(from, to); - -} - -void PhysicsManager::DrawDebug() -{ - if(m_DrawDebug) - m_World->DrawDebug(); -} - -void PhysicsManager::Init() { - - m_World = new Physics::DynamicWorld(); - m_World->SetGravity(glm::vec3(0, -3, 0)); - - m_World->GetDynamicWorld()->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback()); - - m_IsRunning = false; -} \ No newline at end of file diff --git a/Nuake/src/Core/Physics/PhysicsManager.h b/Nuake/src/Core/Physics/PhysicsManager.h index fc03b63a..932c90a9 100644 --- a/Nuake/src/Core/Physics/PhysicsManager.h +++ b/Nuake/src/Core/Physics/PhysicsManager.h @@ -5,48 +5,52 @@ #include "Rigibody.h" #include "RaycastResult.h" -class PhysicsManager + +namespace Nuake { -private: - Physics::DynamicWorld* m_World; - bool m_IsRunning = false; - btAlignedObjectArray collisionShapes; - - bool m_DrawDebug = false; - static PhysicsManager* m_Instance; -public: - static PhysicsManager* Get() + class PhysicsManager { - if (!m_Instance) - m_Instance = new PhysicsManager(); - return m_Instance; - } + private: + Physics::DynamicWorld* m_World; + bool m_IsRunning = false; + btAlignedObjectArray collisionShapes; - Physics::DynamicWorld* GetWorld() { return m_World; } + bool m_DrawDebug = false; + static PhysicsManager* m_Instance; + public: + static PhysicsManager* Get() + { + if (!m_Instance) + m_Instance = new PhysicsManager(); + return m_Instance; + } - PhysicsManager() { if (!m_Instance) m_Instance = this; } + Physics::DynamicWorld* GetWorld() { return m_World; } - void SetDrawDebug(bool value) { - m_DrawDebug = value; - } + PhysicsManager() { if (!m_Instance) m_Instance = this; } - bool GetDrawDebug() { - return m_DrawDebug; - } + void SetDrawDebug(bool value) { + m_DrawDebug = value; + } - void Init(); + bool GetDrawDebug() { + return m_DrawDebug; + } - void Start() { m_IsRunning = true; } - void Stop() { m_IsRunning = false; } - void DrawDebug(); - bool IsRunning() { return m_IsRunning; } - void Step(Timestep ts); + void Init(); - void Reset(); + void Start() { m_IsRunning = true; } + void Stop() { m_IsRunning = false; } + void DrawDebug(); + bool IsRunning() { return m_IsRunning; } + void Step(Timestep ts); - RaycastResult Raycast(glm::vec3 from, glm::vec3 to); + void Reset(); - void RegisterBody(Ref rb); - void RegisterGhostBody(Ref rb); - void RegisterCharacterController(Ref c); -}; \ No newline at end of file + RaycastResult Raycast(glm::vec3 from, glm::vec3 to); + + void RegisterBody(Ref rb); + void RegisterGhostBody(Ref rb); + void RegisterCharacterController(Ref c); + }; +} diff --git a/Nuake/src/Core/Physics/PhysicsShapes.cpp b/Nuake/src/Core/Physics/PhysicsShapes.cpp index 051d7b55..21e6cd0e 100644 --- a/Nuake/src/Core/Physics/PhysicsShapes.cpp +++ b/Nuake/src/Core/Physics/PhysicsShapes.cpp @@ -1,60 +1,67 @@ #include "PhysicsShapes.h" #include "btBulletDynamicsCommon.h" -Physics::Box::Box() + +namespace Nuake { - Size = glm::vec3(1); - bShape = new btBoxShape(btVector3(Size.x, Size.y, Size.z)); - m_Type = BOX; -} -// Sphere -Physics::Box::Box(glm::vec3 size) { - Size = size; - bShape = new btBoxShape(btVector3(size.x, size.y, size.z)); - m_Type = BOX; -} - -Physics::Box::Box(float x, float y, float z) { - Size = glm::vec3(x, y, z); - bShape = new btBoxShape(btVector3(x, y, z)); - m_Type = BOX; -} - -btCollisionShape* Physics::Box::GetBulletShape() -{ - return bShape; -} - -// Sphere -Physics::Sphere::Sphere(float radius) { - Radius = radius; - bShape = new btSphereShape(Radius); - - m_Type = SPHERE; -} - -void Physics::Sphere::SetRadius(float radius) { - ((btSphereShape*)bShape)->setUnscaledRadius(radius); - Radius = radius; -} - -btCollisionShape* Physics::Sphere::GetBulletShape() -{ - return bShape; -} - -Physics::MeshShape::MeshShape(Ref mesh) -{ - m_Mesh = mesh; - btConvexHullShape* trimesh = new btConvexHullShape(); - - for (Vertex i : mesh->m_Vertices) + namespace Physics { - trimesh->addPoint(btVector3(i.position.x, i.position.y, i.position.z)); - } - bShape = trimesh; -} + Box::Box() + { + Size = glm::vec3(1); + bShape = new btBoxShape(btVector3(Size.x, Size.y, Size.z)); + m_Type = BOX; + } + // Sphere + Box::Box(glm::vec3 size) { + Size = size; + bShape = new btBoxShape(btVector3(size.x, size.y, size.z)); + m_Type = BOX; + } -btCollisionShape* Physics::MeshShape::GetBulletShape() -{ - return bShape; -} \ No newline at end of file + Box::Box(float x, float y, float z) { + Size = glm::vec3(x, y, z); + bShape = new btBoxShape(btVector3(x, y, z)); + m_Type = BOX; + } + + btCollisionShape* Box::GetBulletShape() + { + return bShape; + } + + // Sphere + Sphere::Sphere(float radius) { + Radius = radius; + bShape = new btSphereShape(Radius); + + m_Type = SPHERE; + } + + void Sphere::SetRadius(float radius) { + ((btSphereShape*)bShape)->setUnscaledRadius(radius); + Radius = radius; + } + + btCollisionShape* Sphere::GetBulletShape() + { + return bShape; + } + + MeshShape::MeshShape(Ref mesh) + { + m_Mesh = mesh; + btConvexHullShape* trimesh = new btConvexHullShape(); + + for (Vertex i : mesh->m_Vertices) + { + trimesh->addPoint(btVector3(i.position.x, i.position.y, i.position.z)); + } + bShape = trimesh; + } + + btCollisionShape* MeshShape::GetBulletShape() + { + return bShape; + } + } +} diff --git a/Nuake/src/Core/Physics/PhysicsShapes.h b/Nuake/src/Core/Physics/PhysicsShapes.h index 384df63e..99a4d3ca 100644 --- a/Nuake/src/Core/Physics/PhysicsShapes.h +++ b/Nuake/src/Core/Physics/PhysicsShapes.h @@ -1,58 +1,70 @@ #pragma once +#include "src/Core/Maths.h" +#include "src/Rendering/Mesh/Mesh.h" -#include -#include "../../Rendering/Mesh/Mesh.h" class btCollisionShape; -namespace Physics { - enum RigidbodyShapes { - BOX, SPHERE, CAPSULE, MESH - }; - class PhysicShape { - protected: - btCollisionShape* bShape; - RigidbodyShapes m_Type; - public: - virtual btCollisionShape* GetBulletShape() = 0; - RigidbodyShapes GetType() const { return m_Type; } - - }; - class Box : public PhysicShape { - private: - glm::vec3 Size; - btCollisionShape* bShape; - public: - Box(); - Box(glm::vec3 size); - Box(float x, float y, float z); +namespace Nuake +{ + namespace Physics + { + enum RigidbodyShapes + { + BOX, SPHERE, CAPSULE, MESH + }; - glm::vec3 GetSize() const { return Size; } - btCollisionShape* GetBulletShape() override; - }; + class PhysicShape + { + protected: + btCollisionShape* bShape; + RigidbodyShapes m_Type; + public: + virtual btCollisionShape* GetBulletShape() = 0; + RigidbodyShapes GetType() const { return m_Type; } - class Sphere : public PhysicShape { - private: - float Radius; - btCollisionShape* bShape; - public: - Sphere(float radius); + }; - float GetRadius() const { return Radius; } - void SetRadius(float radius); + class Box : public PhysicShape + { + private: + glm::vec3 Size; + btCollisionShape* bShape; + public: + Box(); + Box(glm::vec3 size); + Box(float x, float y, float z); - btCollisionShape* GetBulletShape() override; - }; + glm::vec3 GetSize() const { return Size; } + btCollisionShape* GetBulletShape() override; + }; - class MeshShape : public PhysicShape { - private: - Ref m_Mesh; - btCollisionShape* bShape; - public: - MeshShape(Ref mesh); + class Sphere : public PhysicShape + { + private: + float Radius; + btCollisionShape* bShape; + public: + Sphere(float radius); - void SetMesh(Mesh* mesh); - Mesh* GetMesh(); + float GetRadius() const { return Radius; } + void SetRadius(float radius); + + btCollisionShape* GetBulletShape() override; + }; + + class MeshShape : public PhysicShape + { + private: + Ref m_Mesh; + btCollisionShape* bShape; + public: + MeshShape(Ref mesh); + + void SetMesh(Mesh* mesh); + Mesh* GetMesh(); + + btCollisionShape* GetBulletShape() override; + }; + } - btCollisionShape* GetBulletShape() override; - }; } diff --git a/Nuake/src/Core/Physics/RaycastResult.h b/Nuake/src/Core/Physics/RaycastResult.h index 8e46a155..aae05b18 100644 --- a/Nuake/src/Core/Physics/RaycastResult.h +++ b/Nuake/src/Core/Physics/RaycastResult.h @@ -3,66 +3,70 @@ #include "CharacterController.h" #include -namespace Physics + +namespace Nuake { - struct ClosestRayResultCallback : public btCollisionWorld::RayResultCallback + namespace Physics { - ClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) - : m_rayFromWorld(rayFromWorld), - m_rayToWorld(rayToWorld) + struct ClosestRayResultCallback : public btCollisionWorld::RayResultCallback { - } + ClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) + : m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld) + { + } - btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction - btVector3 m_rayToWorld; + btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; - btVector3 m_hitNormalWorld; - btVector3 m_hitPointWorld; + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; - virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) + { + //caller already does the filter on the m_closestHitFraction + btAssert(rayResult.m_hitFraction <= m_closestHitFraction); + + m_closestHitFraction = rayResult.m_hitFraction; + m_collisionObject = rayResult.m_collisionObject; + + m_hitNormalWorld = rayResult.m_hitNormalLocal; + + + m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); + return rayResult.m_hitFraction; + } + }; + + class IgnoreBodyAndGhostCast : + public Physics::ClosestRayResultCallback { - //caller already does the filter on the m_closestHitFraction - btAssert(rayResult.m_hitFraction <= m_closestHitFraction); + private: + btRigidBody* m_pBody; + btPairCachingGhostObject* m_pGhostObject; - m_closestHitFraction = rayResult.m_hitFraction; - m_collisionObject = rayResult.m_collisionObject; + public: + IgnoreBodyAndGhostCast(btRigidBody* pBody, btPairCachingGhostObject* pGhostObject) + : ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)), + m_pBody(pBody), m_pGhostObject(pGhostObject) + { + } - m_hitNormalWorld = rayResult.m_hitNormalLocal; + btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) + { + if (rayResult.m_collisionObject == m_pBody || rayResult.m_collisionObject == m_pGhostObject) + return 1.0f; + + return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); + } + }; + } - m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); - return rayResult.m_hitFraction; - } - }; - - class IgnoreBodyAndGhostCast : - public Physics::ClosestRayResultCallback - { - private: - btRigidBody* m_pBody; - btPairCachingGhostObject* m_pGhostObject; - - public: - IgnoreBodyAndGhostCast(btRigidBody* pBody, btPairCachingGhostObject* pGhostObject) - : ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)), - m_pBody(pBody), m_pGhostObject(pGhostObject) - { - } - - btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) - { - if (rayResult.m_collisionObject == m_pBody || rayResult.m_collisionObject == m_pGhostObject) - return 1.0f; - - return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); - } + // result object from raycast. + struct RaycastResult { + glm::vec3 WorldPoint; + glm::vec3 LocalPoint; + glm::vec3 Normal; }; } - - -// result object from raycast. -struct RaycastResult { - glm::vec3 WorldPoint; - glm::vec3 LocalPoint; - glm::vec3 Normal; -}; \ No newline at end of file diff --git a/Nuake/src/Core/Physics/Rigibody.h b/Nuake/src/Core/Physics/Rigibody.h index a22cc5b5..d87b1a55 100644 --- a/Nuake/src/Core/Physics/Rigibody.h +++ b/Nuake/src/Core/Physics/Rigibody.h @@ -5,44 +5,48 @@ struct btTransform; struct btRigidBody; struct btVector3; -class Entity; -namespace Physics { - class RigidBody { - private: - bool m_IsDynamic = false; - bool m_IsKinematic = false; - glm::vec3 m_InitialVel; - - btRigidBody* m_Rigidbody; +namespace Nuake +{ + class Entity; + namespace Physics { + class RigidBody { + private: + bool m_IsDynamic = false; + bool m_IsKinematic = false; + glm::vec3 m_InitialVel; - Ref m_CollisionShape; - public: - btTransform* m_Transform; - float m_Mass; + btRigidBody* m_Rigidbody; - RigidBody(); - RigidBody(glm::vec3 position, Entity handle); - RigidBody(float mass, glm::vec3 position, Ref shape, glm::vec3 initialVel = glm::vec3(0, 0, 0)); + Ref m_CollisionShape; + public: + btTransform* m_Transform; + float m_Mass; - btRigidBody* GetBulletRigidbody() const { return m_Rigidbody; } - - void UpdateTransform(btTransform t); - glm::vec3 GetPosition() const; - glm::vec3 GetRotation() const; + RigidBody(); + RigidBody(glm::vec3 position, Entity handle); + RigidBody(float mass, glm::vec3 position, Ref shape, glm::vec3 initialVel = glm::vec3(0, 0, 0)); - void SetEntityID(Entity ent); + btRigidBody* GetBulletRigidbody() const { return m_Rigidbody; } - void SetKinematic(bool value); - bool IsKinematic() const { return m_IsKinematic; } + void UpdateTransform(btTransform t); + glm::vec3 GetPosition() const; + glm::vec3 GetRotation() const; - bool HasShape() { return m_CollisionShape != nullptr; } - void SetShape(Ref shape); - Ref GetShape() const { return m_CollisionShape; } + void SetEntityID(Entity ent); - float GetMass() const { return m_Mass; } - void SetMass(float m); + void SetKinematic(bool value); + bool IsKinematic() const { return m_IsKinematic; } + + bool HasShape() { return m_CollisionShape != nullptr; } + void SetShape(Ref shape); + Ref GetShape() const { return m_CollisionShape; } + + float GetMass() const { return m_Mass; } + void SetMass(float m); + + void MoveAndSlide(glm::vec3 velocity); + }; + } - void MoveAndSlide(glm::vec3 velocity); - }; } diff --git a/Nuake/src/Core/Physics/Rigidbody.cpp b/Nuake/src/Core/Physics/Rigidbody.cpp index bd43408e..8c7a8652 100644 --- a/Nuake/src/Core/Physics/Rigidbody.cpp +++ b/Nuake/src/Core/Physics/Rigidbody.cpp @@ -4,116 +4,120 @@ #include "../Core.h" #include #include -namespace Physics + +namespace Nuake { - RigidBody::RigidBody() + namespace Physics { - m_Transform = new btTransform(); - m_Transform->setIdentity(); - //m_Transform->setOrigin(btVector3(position.x, position.y, position.z)); - } - - RigidBody::RigidBody(glm::vec3 position, Entity handle) - { - Ref shape = CreateRef(); - m_CollisionShape = shape; - - m_Transform = new btTransform(); - m_Transform->setIdentity(); - m_Transform->setOrigin(btVector3(position.x, position.y, position.z)); - - m_Mass = 0.0f; - - //rigidbody is dynamic if and only if mass is non zero, otherwise static - m_IsDynamic = (m_Mass != 0.0f); - - btVector3 localInertia(0, 0, 0); - if (m_IsDynamic) - m_CollisionShape->GetBulletShape()->calculateLocalInertia(m_Mass, localInertia); - - m_InitialVel = glm::vec3(0, 0, 0); - - //using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects - btDefaultMotionState* myMotionState = new btDefaultMotionState(*m_Transform); - btRigidBody::btRigidBodyConstructionInfo rbInfo(m_Mass, myMotionState, m_CollisionShape->GetBulletShape(), localInertia); - - m_Rigidbody = new btRigidBody(rbInfo); - m_Rigidbody->setUserIndex(handle.GetHandle()); - } - - RigidBody::RigidBody(float mass, glm::vec3 position, Ref shape, glm::vec3 initialVel) - { - m_CollisionShape = shape; - - m_Transform = new btTransform(); - m_Transform->setIdentity(); - m_Transform->setOrigin(btVector3(position.x, position.y, position.z)); - - m_Mass = mass; - - //rigidbody is dynamic if and only if mass is non zero, otherwise static - m_IsDynamic = (m_Mass != 0.0f); - - btVector3 localInertia(initialVel.x, initialVel.y, initialVel.z); - m_InitialVel = initialVel; - if (m_IsDynamic) - m_CollisionShape->GetBulletShape()->calculateLocalInertia(m_Mass, localInertia); - - //using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects - btDefaultMotionState* myMotionState = new btDefaultMotionState(*m_Transform); - btRigidBody::btRigidBodyConstructionInfo rbInfo(m_Mass, myMotionState, m_CollisionShape->GetBulletShape(), localInertia); - - m_Rigidbody = new btRigidBody(rbInfo); - } - - void RigidBody::SetShape(Ref shape) - { - m_Rigidbody->setCollisionShape(shape->GetBulletShape()); - m_CollisionShape = shape; - } - - void RigidBody::UpdateTransform(btTransform t) - { - m_Transform->setOrigin(t.getOrigin()); - m_Transform->setRotation(t.getRotation()); - m_Rigidbody->setWorldTransform(t); - } - - glm::vec3 RigidBody::GetRotation() const { - auto q = m_Transform->getRotation(); - btScalar x = 0, y = 0, z = 0; - q.getEulerZYX(z, y, x); - return glm::vec3(glm::degrees(x), glm::degrees(y), glm::degrees(z)); - } - - void RigidBody::SetEntityID(Entity ent) - { - m_Rigidbody->setUserIndex(ent.GetHandle()); - } - - void RigidBody::SetKinematic(bool value) - { - if (value) // Kinematic bodies dont deactivate. + RigidBody::RigidBody() { - m_Rigidbody->setCollisionFlags(m_Rigidbody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - m_Rigidbody->setActivationState(DISABLE_DEACTIVATION); + m_Transform = new btTransform(); + m_Transform->setIdentity(); + //m_Transform->setOrigin(btVector3(position.x, position.y, position.z)); } - else // Reenable deactivation. + + RigidBody::RigidBody(glm::vec3 position, Entity handle) { - m_Rigidbody->setCollisionFlags(m_Rigidbody->getCollisionFlags() ^ ~btCollisionObject::CF_KINEMATIC_OBJECT); - m_Rigidbody->setActivationState(WANTS_DEACTIVATION); + Ref shape = CreateRef(); + m_CollisionShape = shape; + + m_Transform = new btTransform(); + m_Transform->setIdentity(); + m_Transform->setOrigin(btVector3(position.x, position.y, position.z)); + + m_Mass = 0.0f; + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + m_IsDynamic = (m_Mass != 0.0f); + + btVector3 localInertia(0, 0, 0); + if (m_IsDynamic) + m_CollisionShape->GetBulletShape()->calculateLocalInertia(m_Mass, localInertia); + + m_InitialVel = glm::vec3(0, 0, 0); + + //using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(*m_Transform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(m_Mass, myMotionState, m_CollisionShape->GetBulletShape(), localInertia); + + m_Rigidbody = new btRigidBody(rbInfo); + m_Rigidbody->setUserIndex(handle.GetHandle()); + } + + RigidBody::RigidBody(float mass, glm::vec3 position, Ref shape, glm::vec3 initialVel) + { + m_CollisionShape = shape; + + m_Transform = new btTransform(); + m_Transform->setIdentity(); + m_Transform->setOrigin(btVector3(position.x, position.y, position.z)); + + m_Mass = mass; + + //rigidbody is dynamic if and only if mass is non zero, otherwise static + m_IsDynamic = (m_Mass != 0.0f); + + btVector3 localInertia(initialVel.x, initialVel.y, initialVel.z); + m_InitialVel = initialVel; + if (m_IsDynamic) + m_CollisionShape->GetBulletShape()->calculateLocalInertia(m_Mass, localInertia); + + //using motionstate is optional, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(*m_Transform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(m_Mass, myMotionState, m_CollisionShape->GetBulletShape(), localInertia); + + m_Rigidbody = new btRigidBody(rbInfo); + } + + void RigidBody::SetShape(Ref shape) + { + m_Rigidbody->setCollisionShape(shape->GetBulletShape()); + m_CollisionShape = shape; + } + + void RigidBody::UpdateTransform(btTransform t) + { + m_Transform->setOrigin(t.getOrigin()); + m_Transform->setRotation(t.getRotation()); + m_Rigidbody->setWorldTransform(t); + } + + glm::vec3 RigidBody::GetRotation() const { + auto q = m_Transform->getRotation(); + btScalar x = 0, y = 0, z = 0; + q.getEulerZYX(z, y, x); + return glm::vec3(glm::degrees(x), glm::degrees(y), glm::degrees(z)); + } + + void RigidBody::SetEntityID(Entity ent) + { + m_Rigidbody->setUserIndex(ent.GetHandle()); + } + + void RigidBody::SetKinematic(bool value) + { + if (value) // Kinematic bodies dont deactivate. + { + m_Rigidbody->setCollisionFlags(m_Rigidbody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + m_Rigidbody->setActivationState(DISABLE_DEACTIVATION); + } + else // Reenable deactivation. + { + m_Rigidbody->setCollisionFlags(m_Rigidbody->getCollisionFlags() ^ ~btCollisionObject::CF_KINEMATIC_OBJECT); + m_Rigidbody->setActivationState(WANTS_DEACTIVATION); + } + } + + glm::vec3 RigidBody::GetPosition() const { + btVector3 btPos = m_Transform->getOrigin(); + + return glm::vec3(btPos.x(), btPos.y(), btPos.z()); + } + + void RigidBody::SetMass(float m) { m_Rigidbody->setMassProps(m, btVector3(m_InitialVel.x, m_InitialVel.y, m_InitialVel.y)); m_Mass = m; } + void RigidBody::MoveAndSlide(glm::vec3 velocity) + { + } } - - glm::vec3 RigidBody::GetPosition() const { - btVector3 btPos = m_Transform->getOrigin(); - - return glm::vec3(btPos.x(), btPos.y(), btPos.z()); - } - - void RigidBody::SetMass(float m) { m_Rigidbody->setMassProps(m, btVector3(m_InitialVel.x, m_InitialVel.y, m_InitialVel.y)); m_Mass = m; } - void RigidBody::MoveAndSlide(glm::vec3 velocity) - { - - } -} \ No newline at end of file +} diff --git a/Nuake/src/Core/TextureManager.cpp b/Nuake/src/Core/TextureManager.cpp index 2de3d0c2..22e5100d 100644 --- a/Nuake/src/Core/TextureManager.cpp +++ b/Nuake/src/Core/TextureManager.cpp @@ -1,26 +1,29 @@ #include "TextureManager.h" -#include "../Rendering/Textures/Texture.h" +#include "src/Rendering/Textures/Texture.h" -std::map> TextureManager::m_Registry; - -TextureManager* TextureManager::s_Instance = nullptr; - -bool TextureManager::IsTextureLoaded(const std::string path) +namespace Nuake { - return m_Registry.find(path) != m_Registry.end(); -} - -Ref TextureManager::GetTexture(const std::string path) -{ - if (!IsTextureLoaded(path)) - m_Registry.emplace(path, new Texture(path)); - - return m_Registry.at(path); -} - -TextureManager* TextureManager::Get() { return s_Instance; } - -TextureManager::TextureManager() -{ - s_Instance = this; + std::map> TextureManager::m_Registry; + + TextureManager* TextureManager::s_Instance = nullptr; + + bool TextureManager::IsTextureLoaded(const std::string path) + { + return m_Registry.find(path) != m_Registry.end(); + } + + Ref TextureManager::GetTexture(const std::string path) + { + if (!IsTextureLoaded(path)) + m_Registry.emplace(path, new Texture(path)); + + return m_Registry.at(path); + } + + TextureManager* TextureManager::Get() { return s_Instance; } + + TextureManager::TextureManager() + { + s_Instance = this; + } } diff --git a/Nuake/src/Core/TextureManager.h b/Nuake/src/Core/TextureManager.h index e00fc321..c14cd64d 100644 --- a/Nuake/src/Core/TextureManager.h +++ b/Nuake/src/Core/TextureManager.h @@ -1,22 +1,24 @@ #pragma once -#include -#include -#include "../Core/Core.h" -class Texture; +#include "src/Core/Core.h" -// Todo: SHOULD probably be static too. -class TextureManager +namespace Nuake { -private: - static TextureManager* s_Instance; + class Texture; - static std::map> m_Registry; - bool IsTextureLoaded(const std::string path); + // Todo: SHOULD probably be static too. + class TextureManager + { + private: + static TextureManager* s_Instance; -public: - static TextureManager* Get(); + static std::map> m_Registry; + bool IsTextureLoaded(const std::string path); - TextureManager(); + public: + static TextureManager* Get(); - Ref GetTexture(const std::string path); -}; \ No newline at end of file + TextureManager(); + + Ref GetTexture(const std::string path); + }; +} diff --git a/Nuake/src/Core/Timestep.h b/Nuake/src/Core/Timestep.h index 4501ca7e..fe73086a 100644 --- a/Nuake/src/Core/Timestep.h +++ b/Nuake/src/Core/Timestep.h @@ -1,21 +1,24 @@ #pragma once -class Timestep { -private: - float m_Time; +namespace Nuake +{ + class Timestep { + private: + float m_Time; -public: - operator float() const { return m_Time; } + public: + operator float() const { return m_Time; } - Timestep(float time = 0.0f) : m_Time(time) { } + Timestep(float time = 0.0f) : m_Time(time) { } - float GetSeconds() - { - return m_Time; - } + float GetSeconds() + { + return m_Time; + } - float GetMilliseconds() const - { - return m_Time * 1000.0f; - } -}; \ No newline at end of file + float GetMilliseconds() const + { + return m_Time * 1000.0f; + } + }; +} diff --git a/Nuake/src/Rendering/Buffers/Framebuffer.cpp b/Nuake/src/Rendering/Buffers/Framebuffer.cpp new file mode 100644 index 00000000..c18f674d --- /dev/null +++ b/Nuake/src/Rendering/Buffers/Framebuffer.cpp @@ -0,0 +1,128 @@ +#include "Framebuffer.h" +#include + +namespace Nuake +{ + FrameBuffer::FrameBuffer(bool hasRenderBuffer, Vector2 size) + { + m_Textures = std::map>(); + m_Size = size; + + glGenFramebuffers(1, &m_FramebufferID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); + + // Create render buffer and attach to frame buffer. + if (hasRenderBuffer) + { + glGenRenderbuffers(1, &m_RenderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); + } + else + { + m_RenderBuffer = -1; + } + + // Unbind + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } + + void FrameBuffer::SetTexture(Ref texture, GLenum attachment) + { + m_Textures[attachment] = texture; + // Attach texture to the framebuffer. + Bind(); + texture->AttachToFramebuffer(attachment); + + // Set draw buffer with dynamic amount of render target. + // Surely, this can be optimized. + int size = 0; + std::vector keys = std::vector(); + for (auto s : m_Textures) + { + if (s.first != GL_DEPTH_ATTACHMENT) + { + keys.push_back(s.first); + size += 1; + } + } + + if (size > 0) + glDrawBuffers(size, &keys[0]); + + Unbind(); + } + + + void FrameBuffer::Clear() + { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + void FrameBuffer::Bind() + { + if (ResizeQueued) + UpdateSize(m_Size); + + glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferID); + + glViewport(0, 0, m_Size.x, m_Size.y); + } + + void FrameBuffer::Unbind() + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + void FrameBuffer::QueueResize(Vector2 size) + { + ResizeQueued = true; + m_Size = size; + } + + void FrameBuffer::UpdateSize(Vector2 size) + { + m_Size = size; + ResizeQueued = false; + + // Delete frame buffer and render buffer. + glDeleteFramebuffers(1, &m_FramebufferID); + glDeleteRenderbuffers(1, &m_RenderBuffer); + + // Recreate resized texture. + for (auto t : m_Textures) + t.second->Resize(size); + + // New FBO and RBO. + glGenFramebuffers(1, &m_FramebufferID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); + + // Recreate resized texture. + for (auto t : m_Textures) + t.second->AttachToFramebuffer(t.first); + + // Recreate render buffer + glGenRenderbuffers(1, &m_RenderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); + + // Unbind. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } + + void FrameBuffer::SetDrawBuffer(GLenum draw) + { + Bind(); + //glReadBuffer(draw); + Unbind(); + } + + void FrameBuffer::SetReadBuffer(GLenum read) + { + Bind(); + //glReadBuffer(read); + Unbind(); + } +} diff --git a/Nuake/src/Rendering/Buffers/Framebuffer.h b/Nuake/src/Rendering/Buffers/Framebuffer.h new file mode 100644 index 00000000..0307dedd --- /dev/null +++ b/Nuake/src/Rendering/Buffers/Framebuffer.h @@ -0,0 +1,42 @@ +#pragma once +#include "../Core/Maths.h" + +#include +#include "../Core/Core.h" +#include +#include + +namespace Nuake +{ + class FrameBuffer + { + private: + unsigned int m_FramebufferID; + unsigned int m_RenderBuffer; + + Vector2 m_Size; + bool ResizeQueued = false; + + std::map> m_Textures; + Ref m_Texture; + + public: + FrameBuffer(bool hasRenderBuffer, Vector2 size); + ~FrameBuffer() { } + + // 0x8CE0 = color attachment 0. + // TODO: Remove blackbox crap + Ref GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; } + void SetTexture(Ref texture, GLenum attachment = 0x8CE0); + + void Clear(); + void Bind(); + void Unbind(); + void QueueResize(Vector2 size); + Vector2 GetSize() const { return m_Size; } + void UpdateSize(Vector2 size); + + void SetDrawBuffer(GLenum draw); + void SetReadBuffer(GLenum read); + }; +} \ No newline at end of file diff --git a/Nuake/src/Rendering/GBuffer.cpp b/Nuake/src/Rendering/Buffers/GBuffer.cpp similarity index 100% rename from Nuake/src/Rendering/GBuffer.cpp rename to Nuake/src/Rendering/Buffers/GBuffer.cpp diff --git a/Nuake/src/Rendering/GBuffer.h b/Nuake/src/Rendering/Buffers/GBuffer.h similarity index 100% rename from Nuake/src/Rendering/GBuffer.h rename to Nuake/src/Rendering/Buffers/GBuffer.h diff --git a/Nuake/src/Rendering/Buffers/MSAAFramebuffer.cpp b/Nuake/src/Rendering/Buffers/MSAAFramebuffer.cpp new file mode 100644 index 00000000..85ab0aa0 --- /dev/null +++ b/Nuake/src/Rendering/Buffers/MSAAFramebuffer.cpp @@ -0,0 +1,124 @@ +#include "MSAAFramebuffer.h" +#include + +namespace Nuake +{ + MSAAFrameBuffer::MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size) + { + m_Textures = std::map>(); + m_Size = size; + + glGenFramebuffers(1, &m_FramebufferID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); + + // Create render buffer and attach to frame buffer. + if (hasRenderBuffer) + { + glGenRenderbuffers(1, &m_RenderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); + } + else + { + m_RenderBuffer = -1; + } + + // Unbind + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } + + void MSAAFrameBuffer::SetTexture(Ref texture, GLenum attachment) + { + m_Textures[attachment] = texture; + // Attach texture to the framebuffer. + Bind(); + texture->AttachToFramebuffer(attachment); + + // Set draw buffer with dynamic amount of render target. + // Surely, this can be optimized. + int size = 0; + std::vector keys = std::vector(); + for (auto s : m_Textures) + { + if (s.first != GL_DEPTH_ATTACHMENT) + { + keys.push_back(s.first); + size += 1; + } + } + + if (size > 0) + glDrawBuffers(size, &keys[0]); + + Unbind(); + } + + + void MSAAFrameBuffer::Bind() + { + if (ResizeQueued) + UpdateSize(m_Size); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FramebufferID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, m_Size.x, m_Size.y, 0, 0, m_Size.x, m_Size.y, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glViewport(0, 0, m_Size.x, m_Size.y); + } + + void MSAAFrameBuffer::Unbind() + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + void MSAAFrameBuffer::QueueResize(Vector2 size) + { + ResizeQueued = true; + m_Size = size; + } + + void MSAAFrameBuffer::UpdateSize(Vector2 size) + { + m_Size = size; + + // Delete frame buffer and render buffer. + glDeleteFramebuffers(1, &m_FramebufferID); + glDeleteRenderbuffers(1, &m_RenderBuffer); + + // Recreate resized texture. + for (auto t : m_Textures) + t.second->Resize(size); + + // New FBO and RBO. + glGenFramebuffers(1, &m_FramebufferID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); + + // Recreate resized texture. + for (auto t : m_Textures) + t.second->AttachToFramebuffer(t.first); + + // Recreate render buffer + glGenRenderbuffers(1, &m_RenderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); + + // Unbind. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } + + void MSAAFrameBuffer::SetDrawBuffer(GLenum draw) + { + Bind(); + //glReadBuffer(draw); + Unbind(); + } + + void MSAAFrameBuffer::SetReadBuffer(GLenum read) + { + Bind(); + //glReadBuffer(read); + Unbind(); + } +} diff --git a/Nuake/src/Rendering/Buffers/MSAAFramebuffer.h b/Nuake/src/Rendering/Buffers/MSAAFramebuffer.h new file mode 100644 index 00000000..e358d08f --- /dev/null +++ b/Nuake/src/Rendering/Buffers/MSAAFramebuffer.h @@ -0,0 +1,42 @@ +#pragma once +#include "src/Core/Maths.h" +#include +#include "src/Core/Core.h" + +#include +#include + +namespace Nuake +{ + class MSAAFrameBuffer + { + private: + unsigned int m_FramebufferID; + unsigned int m_RenderBuffer; + + Vector2 m_Size; + bool ResizeQueued = false; + + std::map> m_Textures; + Ref m_Texture; + + public: + MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size); + ~MSAAFrameBuffer() { } + + // 0x8CE0 = color attachment 0. + // TODO: Remove blackbox crap + Ref GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; } + void SetTexture(Ref texture, GLenum attachment = 0x8CE0); + + + void Bind(); + void Unbind(); + void QueueResize(Vector2 size); + Vector2 GetSize() const { return m_Size; } + void UpdateSize(Vector2 size); + + void SetDrawBuffer(GLenum draw); + void SetReadBuffer(GLenum read); + }; +} diff --git a/Nuake/src/Rendering/UniformBuffer.cpp b/Nuake/src/Rendering/Buffers/UniformBuffer.cpp similarity index 100% rename from Nuake/src/Rendering/UniformBuffer.cpp rename to Nuake/src/Rendering/Buffers/UniformBuffer.cpp diff --git a/Nuake/src/Rendering/UniformBuffer.h b/Nuake/src/Rendering/Buffers/UniformBuffer.h similarity index 95% rename from Nuake/src/Rendering/UniformBuffer.h rename to Nuake/src/Rendering/Buffers/UniformBuffer.h index bb7d6296..293f613d 100644 --- a/Nuake/src/Rendering/UniformBuffer.h +++ b/Nuake/src/Rendering/Buffers/UniformBuffer.h @@ -5,12 +5,8 @@ class UniformBuffer { private: unsigned int RendererID; public: - UniformBuffer(); - - void Bind(); void Unbind(); - }; \ No newline at end of file diff --git a/Nuake/src/Rendering/Camera.cpp b/Nuake/src/Rendering/Camera.cpp index f16e0023..0d791421 100644 --- a/Nuake/src/Rendering/Camera.cpp +++ b/Nuake/src/Rendering/Camera.cpp @@ -1,4 +1,3 @@ - #include "Camera.h" #include "../Core/Input.h" #include @@ -7,98 +6,100 @@ #include #include -Camera::Camera(CAMERA_TYPE type, glm::vec3 position) { - m_Type = PERSPECTIVE; - Translation = position; - cameraDirection = glm::vec3(0, 0, 1); - up = glm::vec3(0.0f, 1.0f, 0.0f); - cameraRight = glm::normalize(glm::cross(up, cameraDirection)); - cameraUp = glm::cross(cameraDirection, cameraRight); - cameraFront = cameraDirection; -} - -Camera::Camera() { - m_Type = PERSPECTIVE; - Translation = glm::vec3(0, 0, 0); - cameraDirection = glm::vec3(0, 0, 1); - up = glm::vec3(0.0f, 1.0f, 0.0f); - cameraRight = glm::normalize(glm::cross(up, cameraDirection)); - cameraUp = glm::cross(cameraDirection, cameraRight); -} - -void Camera::SetType(CAMERA_TYPE type) +namespace Nuake { - m_Type = type; + Camera::Camera(CAMERA_TYPE type, glm::vec3 position) + { + m_Type = PERSPECTIVE; + Translation = position; + cameraDirection = glm::vec3(0, 0, 1); + up = glm::vec3(0.0f, 1.0f, 0.0f); + cameraRight = glm::normalize(glm::cross(up, cameraDirection)); + cameraUp = glm::cross(cameraDirection, cameraRight); + cameraFront = cameraDirection; + } + + Camera::Camera() + { + m_Type = PERSPECTIVE; + Translation = glm::vec3(0, 0, 0); + cameraDirection = glm::vec3(0, 0, 1); + up = glm::vec3(0.0f, 1.0f, 0.0f); + cameraRight = glm::normalize(glm::cross(up, cameraDirection)); + cameraUp = glm::cross(cameraDirection, cameraRight); + } + + void Camera::SetType(CAMERA_TYPE type) + { + m_Type = type; + } + + void Camera::OnWindowResize(int x, int y) + { + AspectRatio = (float)x / (float)y; + float width = y * (16 * 9); + float height = y; + } + + void Camera::SetDirection(Vector3 direction) + { + //cam->cameraDirection.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); + //cam->cameraDirection.y = sin(glm::radians(Pitch)); + //cam->cameraDirection.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); + //cam->cameraFront = glm::normalize(cam->cameraDirection); + //cam->cameraRight = glm::normalize(glm::cross(cam->up, cam->cameraFront)); + cameraDirection = glm::normalize(direction); + cameraFront = cameraDirection; + cameraRight = glm::normalize(glm::cross(up, cameraFront)); + } + + glm::vec3 Camera::GetTranslation() { + return Translation; + } + + glm::vec3 Camera::GetDirection() { + return cameraDirection; + } + + glm::mat4 Camera::GetPerspective() + { + //TODO: Add perspective options + m_Perspective = glm::perspectiveFov(glm::radians(Fov), 9.0f * AspectRatio, 9.0f, 0.1f, 1000.0f); + //m_Perspective = glm::ortho(-8.0f, 8.0f, -4.5f, 4.5f, -1.0f, 1.0f); + return m_Perspective; + } + + glm::mat4 Camera::GetTransform() + { + glm::mat4 tr = lookAt(Translation, Translation + cameraFront, cameraUp); + return tr; + } + + glm::mat4 Camera::GetTransformRotation() + { + return lookAt(glm::vec3(), cameraFront, cameraUp); + } + + json Camera::Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(m_Type); + SERIALIZE_VAL(AspectRatio); + SERIALIZE_VAL(Fov); + SERIALIZE_VAL(Exposure); + SERIALIZE_VAL(Speed); + END_SERIALIZE(); + } + + bool Camera::Deserialize(const std::string& str) + { + BEGIN_DESERIALIZE(); + j = j["CameraInstance"]; + this->m_Type = (CAMERA_TYPE)j["m_Type"]; + this->AspectRatio = j["AspectRatio"]; + this->Fov = j["Fov"]; + this->Exposure = j["Exposure"]; + this->Speed = j["Speed"]; + return false; + } } - -void Camera::OnWindowResize(int x, int y) -{ - AspectRatio = (float)x / (float)y; - float width = y * (16 * 9); - float height = y; -} - -void Camera::SetDirection(Vector3 direction) -{ - //cam->cameraDirection.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - //cam->cameraDirection.y = sin(glm::radians(Pitch)); - //cam->cameraDirection.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - //cam->cameraFront = glm::normalize(cam->cameraDirection); - //cam->cameraRight = glm::normalize(glm::cross(cam->up, cam->cameraFront)); - cameraDirection = glm::normalize(direction); - cameraFront = cameraDirection; - cameraRight = glm::normalize(glm::cross(up, cameraFront)); -} - -glm::vec3 Camera::GetTranslation() { - return Translation; -} - -glm::vec3 Camera::GetDirection() { - return cameraDirection; -} - -glm::mat4 Camera::GetPerspective() -{ - //TODO: Add perspective options - m_Perspective = glm::perspectiveFov(glm::radians(Fov), 9.0f * AspectRatio, 9.0f, 0.1f, 1000.0f); - //m_Perspective = glm::ortho(-8.0f, 8.0f, -4.5f, 4.5f, -1.0f, 1.0f); - return m_Perspective; -} - -glm::mat4 Camera::GetTransform() -{ - glm::mat4 tr = lookAt(Translation, Translation + cameraFront, cameraUp); - return tr; -} - -glm::mat4 Camera::GetTransformRotation() -{ - return lookAt(glm::vec3(), cameraFront, cameraUp); -} - -json Camera::Serialize() -{ - BEGIN_SERIALIZE(); - SERIALIZE_VAL(m_Type); - SERIALIZE_VAL(AspectRatio); - SERIALIZE_VAL(Fov); - SERIALIZE_VAL(Exposure); - SERIALIZE_VAL(Speed); - END_SERIALIZE(); -} - -bool Camera::Deserialize(const std::string& str) -{ - BEGIN_DESERIALIZE(); - j = j["CameraInstance"]; - this->m_Type = (CAMERA_TYPE)j["m_Type"]; - this->AspectRatio = j["AspectRatio"]; - this->Fov = j["Fov"]; - this->Exposure = j["Exposure"]; - this->Speed = j["Speed"]; - return false; -} - - - diff --git a/Nuake/src/Rendering/Camera.h b/Nuake/src/Rendering/Camera.h index d0bd67fe..ce453b48 100644 --- a/Nuake/src/Rendering/Camera.h +++ b/Nuake/src/Rendering/Camera.h @@ -1,58 +1,63 @@ #pragma once -#include "../Core/Timestep.h" -#include "../Core/Maths.h" -#include "../Resource/Serializable.h" +#include "src/Core/Timestep.h" +#include "src/Core/Maths.h" +#include "src/Resource/Serializable.h" -enum CAMERA_TYPE { - ORTHO, - PERSPECTIVE -}; - -class EditorCamera; - -// TODO: Remove logic from here. -class Camera : public ISerializable +namespace Nuake { -private: - CAMERA_TYPE m_Type; + enum CAMERA_TYPE + { + ORTHO, + PERSPECTIVE + }; - - Vector3 Rotation = { 0.0f, 0.0f, 0.0f }; - Vector3 Scale = { 1.0f, 1.0f, 1.0f }; - Matrix4 m_Perspective; + class EditorCamera; -public: - float AspectRatio = 16.0f / 9.0f; - // TODO: remove duplicate direction and have a proper api. - Vector3 up = Vector3(0.0f, 1.0f, 0.0f); - Vector3 cameraFront = Vector3(0.0f, 0.0f, 1.0f); + // TODO: Remove logic from here. + class Camera : public ISerializable + { + private: + CAMERA_TYPE m_Type; - Vector3 cameraTarget; - Vector3 cameraDirection; - Vector3 Translation = { 0.0f, 0.0f, 0.0f }; - Vector3 cameraRight; - Vector3 cameraUp; - float Fov = 88.0f; - float Exposure = 1.0f; - float Speed = 1.0f; + Vector3 Rotation = { 0.0f, 0.0f, 0.0f }; + Vector3 Scale = { 1.0f, 1.0f, 1.0f }; + Matrix4 m_Perspective; - Camera(); - Camera(CAMERA_TYPE type, Vector3 position); + public: + float AspectRatio = 16.0f / 9.0f; + // TODO: remove duplicate direction and have a proper api. + Vector3 up = Vector3(0.0f, 1.0f, 0.0f); + Vector3 cameraFront = Vector3(0.0f, 0.0f, 1.0f); - void SetType(CAMERA_TYPE type); - void OnWindowResize(int x, int y); + Vector3 cameraTarget; + Vector3 cameraDirection; - void SetDirection(Vector3 direction); + Vector3 Translation = { 0.0f, 0.0f, 0.0f }; + Vector3 cameraRight; + Vector3 cameraUp; + float Fov = 88.0f; + float Exposure = 1.0f; + float Speed = 1.0f; - Vector3 GetTranslation(); - Vector3 GetDirection(); - Matrix4 GetPerspective(); - Matrix4 GetTransform(); - Matrix4 GetTransformRotation(); + Camera(); + Camera(CAMERA_TYPE type, Vector3 position); - json Serialize() override; - bool Deserialize(const std::string& str) override; + void SetType(CAMERA_TYPE type); + void OnWindowResize(int x, int y); + + void SetDirection(Vector3 direction); + + Vector3 GetTranslation(); + Vector3 GetDirection(); + Matrix4 GetPerspective(); + Matrix4 GetTransform(); + Matrix4 GetTransformRotation(); + + json Serialize() override; + bool Deserialize(const std::string& str) override; + + friend EditorCamera; + }; +} - friend EditorCamera; -}; diff --git a/Nuake/src/Rendering/Framebuffer.cpp b/Nuake/src/Rendering/Framebuffer.cpp deleted file mode 100644 index 3d35617d..00000000 --- a/Nuake/src/Rendering/Framebuffer.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "Framebuffer.h" -#include -FrameBuffer::FrameBuffer(bool hasRenderBuffer, Vector2 size) -{ - m_Textures = std::map>(); - m_Size = size; - - glGenFramebuffers(1, &m_FramebufferID); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); - - // Create render buffer and attach to frame buffer. - if (hasRenderBuffer) - { - glGenRenderbuffers(1, &m_RenderBuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); - } - else - { - m_RenderBuffer = -1; - } - - // Unbind - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -void FrameBuffer::SetTexture(Ref texture, GLenum attachment) -{ - m_Textures[attachment] = texture; - // Attach texture to the framebuffer. - Bind(); - texture->AttachToFramebuffer(attachment); - - // Set draw buffer with dynamic amount of render target. - // Surely, this can be optimized. - int size = 0; - std::vector keys = std::vector(); - for (auto s : m_Textures) - { - if (s.first != GL_DEPTH_ATTACHMENT) - { - keys.push_back(s.first); - size += 1; - } - } - - if(size > 0) - glDrawBuffers(size, &keys[0]); - - Unbind(); -} - - -void FrameBuffer::Clear() -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -void FrameBuffer::Bind() -{ - if (ResizeQueued) - UpdateSize(m_Size); - - glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferID); - - glViewport(0, 0, m_Size.x, m_Size.y); -} - -void FrameBuffer::Unbind() -{ - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - -void FrameBuffer::QueueResize(Vector2 size) -{ - ResizeQueued = true; - m_Size = size; -} - -void FrameBuffer::UpdateSize(Vector2 size) -{ - m_Size = size; - ResizeQueued = false; - - // Delete frame buffer and render buffer. - glDeleteFramebuffers(1, &m_FramebufferID); - glDeleteRenderbuffers(1, &m_RenderBuffer); - - // Recreate resized texture. - for (auto t : m_Textures) - t.second->Resize(size); - - // New FBO and RBO. - glGenFramebuffers(1, &m_FramebufferID); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); - - // Recreate resized texture. - for (auto t : m_Textures) - t.second->AttachToFramebuffer(t.first); - - // Recreate render buffer - glGenRenderbuffers(1, &m_RenderBuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); - - // Unbind. - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -void FrameBuffer::SetDrawBuffer(GLenum draw) -{ - Bind(); - //glReadBuffer(draw); - Unbind(); -} - -void FrameBuffer::SetReadBuffer(GLenum read) -{ - Bind(); - //glReadBuffer(read); - Unbind(); -} \ No newline at end of file diff --git a/Nuake/src/Rendering/Framebuffer.h b/Nuake/src/Rendering/Framebuffer.h deleted file mode 100644 index 00446f5d..00000000 --- a/Nuake/src/Rendering/Framebuffer.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "../Core/Maths.h" -#include "Textures/Texture.h" -#include -#include "../Core/Core.h" -#include -class FrameBuffer -{ -private: - unsigned int m_FramebufferID; - unsigned int m_RenderBuffer; - - Vector2 m_Size; - bool ResizeQueued = false; - - std::map> m_Textures; - Ref m_Texture; - -public: - FrameBuffer(bool hasRenderBuffer, Vector2 size); - ~FrameBuffer() { } - - // 0x8CE0 = color attachment 0. - // TODO: Remove blackbox crap - Ref GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; } - void SetTexture(Ref texture, GLenum attachment = 0x8CE0); - - void Clear(); - void Bind(); - void Unbind(); - void QueueResize(Vector2 size); - Vector2 GetSize() const { return m_Size; } - void UpdateSize(Vector2 size); - - void SetDrawBuffer(GLenum draw); - void SetReadBuffer(GLenum read); -}; \ No newline at end of file diff --git a/Nuake/src/Rendering/MSAAFramebuffer.cpp b/Nuake/src/Rendering/MSAAFramebuffer.cpp deleted file mode 100644 index 71de392a..00000000 --- a/Nuake/src/Rendering/MSAAFramebuffer.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "MSAAFramebuffer.h" -#include -MSAAFrameBuffer::MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size) -{ - m_Textures = std::map>(); - m_Size = size; - - glGenFramebuffers(1, &m_FramebufferID); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); - - // Create render buffer and attach to frame buffer. - if (hasRenderBuffer) - { - glGenRenderbuffers(1, &m_RenderBuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); - } - else - { - m_RenderBuffer = -1; - } - - // Unbind - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -void MSAAFrameBuffer::SetTexture(Ref texture, GLenum attachment) -{ - m_Textures[attachment] = texture; - // Attach texture to the framebuffer. - Bind(); - texture->AttachToFramebuffer(attachment); - - // Set draw buffer with dynamic amount of render target. - // Surely, this can be optimized. - int size = 0; - std::vector keys = std::vector(); - for (auto s : m_Textures) - { - if (s.first != GL_DEPTH_ATTACHMENT) - { - keys.push_back(s.first); - size += 1; - } - } - - if (size > 0) - glDrawBuffers(size, &keys[0]); - - Unbind(); -} - - -void MSAAFrameBuffer::Bind() -{ - if (ResizeQueued) - UpdateSize(m_Size); - - glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FramebufferID); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBlitFramebuffer(0, 0, m_Size.x, m_Size.y, 0, 0, m_Size.x, m_Size.y, GL_COLOR_BUFFER_BIT, GL_NEAREST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glViewport(0, 0, m_Size.x, m_Size.y); -} - -void MSAAFrameBuffer::Unbind() -{ - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - -void MSAAFrameBuffer::QueueResize(Vector2 size) -{ - ResizeQueued = true; - m_Size = size; -} - -void MSAAFrameBuffer::UpdateSize(Vector2 size) -{ - m_Size = size; - - // Delete frame buffer and render buffer. - glDeleteFramebuffers(1, &m_FramebufferID); - glDeleteRenderbuffers(1, &m_RenderBuffer); - - // Recreate resized texture. - for (auto t : m_Textures) - t.second->Resize(size); - - // New FBO and RBO. - glGenFramebuffers(1, &m_FramebufferID); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); - - // Recreate resized texture. - for (auto t : m_Textures) - t.second->AttachToFramebuffer(t.first); - - // Recreate render buffer - glGenRenderbuffers(1, &m_RenderBuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); - - // Unbind. - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -void MSAAFrameBuffer::SetDrawBuffer(GLenum draw) -{ - Bind(); - //glReadBuffer(draw); - Unbind(); -} - -void MSAAFrameBuffer::SetReadBuffer(GLenum read) -{ - Bind(); - //glReadBuffer(read); - Unbind(); -} \ No newline at end of file diff --git a/Nuake/src/Rendering/MSAAFramebuffer.h b/Nuake/src/Rendering/MSAAFramebuffer.h deleted file mode 100644 index 5afa9e0e..00000000 --- a/Nuake/src/Rendering/MSAAFramebuffer.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include "../Core/Maths.h" -#include -#include "../Core/Core.h" - -#include -#include -class MSAAFrameBuffer -{ -private: - unsigned int m_FramebufferID; - unsigned int m_RenderBuffer; - - Vector2 m_Size; - bool ResizeQueued = false; - - std::map> m_Textures; - Ref m_Texture; - -public: - MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size); - ~MSAAFrameBuffer() { } - - // 0x8CE0 = color attachment 0. - // TODO: Remove blackbox crap - Ref GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; } - void SetTexture(Ref texture, GLenum attachment = 0x8CE0); - - - void Bind(); - void Unbind(); - void QueueResize(Vector2 size); - Vector2 GetSize() const { return m_Size; } - void UpdateSize(Vector2 size); - - void SetDrawBuffer(GLenum draw); - void SetReadBuffer(GLenum read); -}; \ No newline at end of file diff --git a/Nuake/src/Rendering/Mesh/Mesh.cpp b/Nuake/src/Rendering/Mesh/Mesh.cpp index 83de734f..5b1e97b9 100644 --- a/Nuake/src/Rendering/Mesh/Mesh.cpp +++ b/Nuake/src/Rendering/Mesh/Mesh.cpp @@ -1,76 +1,79 @@ #include "Mesh.h" #include -#include "../Renderer.h" -#include "../../Core/MaterialManager.h" -Mesh::Mesh(std::vector vertices, std::vector indices, Ref material) +#include "src/Rendering/Renderer.h" +#include "src/Core/MaterialManager.h" + +namespace Nuake { - this->m_Vertices = vertices; - this->m_Indices = indices; - this->m_Material = material; + Mesh::Mesh(std::vector vertices, std::vector indices, Ref material) + { + this->m_Vertices = vertices; + this->m_Indices = indices; + this->m_Material = material; - MaterialManager::Get()->RegisterMaterial(material); + MaterialManager::Get()->RegisterMaterial(material); - setupMesh(); + setupMesh(); + } + + void Mesh::setupMesh() + { + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glGenBuffers(1, &EBO); + + glBindVertexArray(VAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + + glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(unsigned int), &m_Indices[0], GL_STATIC_DRAW); + + // vertex positions + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); + glEnableVertexAttribArray(0); + + // UV + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3)); + glEnableVertexAttribArray(1); + + // Normal + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5)); + glEnableVertexAttribArray(2); + + // Tangent + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8)); + glEnableVertexAttribArray(3); + + // Bi tangent + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 11)); + glEnableVertexAttribArray(4); + + // Texture + glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 14)); + glEnableVertexAttribArray(5); + + + glBindVertexArray(0); + } + + void Mesh::Draw(bool drawMaterial) + { + if (drawMaterial) + m_Material->Bind(); + // draw mesh + glBindVertexArray(VAO); + glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0); + //glBindVertexArray(0); + } + + void Mesh::DebugDraw() + { + Renderer::m_DebugShader->Bind(); + Renderer::m_DebugShader->SetUniform4f("u_Color", 1.0f, 0.0f, 0.0f, 1.f); + glBindVertexArray(VAO); + glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0); + } } - -void Mesh::setupMesh() -{ - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - glGenBuffers(1, &EBO); - - glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - - glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(unsigned int), &m_Indices[0], GL_STATIC_DRAW); - - // vertex positions - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); - glEnableVertexAttribArray(0); - - // UV - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3)); - glEnableVertexAttribArray(1); - - // Normal - glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5)); - glEnableVertexAttribArray(2); - - // Tangent - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8)); - glEnableVertexAttribArray(3); - - // Bi tangent - glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 11)); - glEnableVertexAttribArray(4); - - // Texture - glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 14)); - glEnableVertexAttribArray(5); - - - glBindVertexArray(0); -} - -void Mesh::Draw(bool drawMaterial) -{ - if(drawMaterial) - m_Material->Bind(); - // draw mesh - glBindVertexArray(VAO); - glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0); - //glBindVertexArray(0); -} - -void Mesh::DebugDraw() -{ - Renderer::m_DebugShader->Bind(); - Renderer::m_DebugShader->SetUniform4f("u_Color", 1.0f, 0.0f, 0.0f, 1.f); - glBindVertexArray(VAO); - glDrawElements(GL_TRIANGLES, m_Indices.size(), GL_UNSIGNED_INT, 0); -} - diff --git a/Nuake/src/Rendering/Mesh/Mesh.h b/Nuake/src/Rendering/Mesh/Mesh.h index 3be60955..068a8799 100644 --- a/Nuake/src/Rendering/Mesh/Mesh.h +++ b/Nuake/src/Rendering/Mesh/Mesh.h @@ -1,28 +1,27 @@ #pragma once #include -#include "../Textures/Texture.h" -#include "../Vertex.h" +#include "src/Rendering/Textures/Texture.h" +#include "src/Rendering/Vertex.h" #include -#include "../Textures/Material.h" -#include "../Core/Core.h" -struct MeshVertex +#include "src/Rendering/Textures/Material.h" +#include "src/Core/Core.h" + +namespace Nuake { + class Mesh + { + public: + std::vector m_Indices; + std::vector m_Vertices; + Ref m_Material; -}; + Mesh(std::vector vertices, std::vector indices, Ref material); + void Draw(bool bindMaterial = true); + void DebugDraw(); -class Mesh -{ -public: - std::vector m_Indices; - std::vector m_Vertices; - Ref m_Material; - - Mesh(std::vector vertices, std::vector indices, Ref material); - - void Draw(bool bindMaterial = true); - void DebugDraw(); -private: - unsigned int VAO, VBO, EBO; - void setupMesh(); -}; \ No newline at end of file + private: + unsigned int VAO, VBO, EBO; + void setupMesh(); + }; +} diff --git a/Nuake/src/Rendering/ProceduralSky.cpp b/Nuake/src/Rendering/ProceduralSky.cpp deleted file mode 100644 index 6da3d5e7..00000000 --- a/Nuake/src/Rendering/ProceduralSky.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "ProceduralSky.h" -#include "Renderer.h" -#include "Shaders/Shader.h" -#include "Camera.h" -#include -// TODO: move this to primitive -ProceduralSky::ProceduralSky() { - float quadVertices[] = { - // positions // texture Coords - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - - - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f - }; - // setup plane VAO - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); -} - -void ProceduralSky::Draw(Ref cam) { - - glm::vec3 CameraDirection = cam->GetDirection(); - - Renderer::m_ProceduralSkyShader->Bind(); - Renderer::m_ProceduralSkyShader->SetUniform1f("SurfaceRadius", SurfaceRadius); - Renderer::m_ProceduralSkyShader->SetUniform1f("AtmosphereRadius", AtmosphereRadius); - Renderer::m_ProceduralSkyShader->SetUniform1f("SunIntensity", SunIntensity); - - Renderer::m_ProceduralSkyShader->SetUniform3f("RayleighScattering", - RayleighScattering.r, - RayleighScattering.g, - RayleighScattering.b); - - Renderer::m_ProceduralSkyShader->SetUniform3f("MieScattering", - MieScattering.r, - MieScattering.g, - MieScattering.b); - - Renderer::m_ProceduralSkyShader->SetUniform3f("CenterPoint", - CenterPoint.x, - CenterPoint.y, - CenterPoint.z); - - Renderer::m_ProceduralSkyShader->SetUniform3f("SunDirection", - SunDirection.x, - SunDirection.y, - SunDirection.z); - - Renderer::m_ProceduralSkyShader->SetUniform1f("u_Exposure", cam->Exposure); - - //Renderer::m_ProceduralSkyShader->SetUniform3f("CamDirection", - // CameraDirection.x, - // CameraDirection.y, - // CameraDirection.z); - - - Renderer::m_ProceduralSkyShader->SetUniformMat4f("InvProjection", cam->GetPerspective()); - Renderer::m_ProceduralSkyShader->SetUniformMat4f("InvView", cam->GetTransformRotation()); - //glm::vec3 CamRight = cam->cameraRight; - //Renderer::m_ProceduralSkyShader->SetUniform3f("CamRight", - // CamRight.x, - // CamRight.y, - // CamRight.z); - // - //glm::vec3 CamUp = cam->cameraUp;//glm::normalize(glm::cross(CameraDirection, CamRight)); - - //Renderer::m_ProceduralSkyShader->SetUniform3f("CamUp", - // CamUp.x, - // CamUp.y, - // CamUp.z); - - - glBindVertexArray(VAO); - glDrawArrays(GL_TRIANGLES, 0, 6); -} - -glm::vec3 ProceduralSky::GetSunDirection() { - return SunDirection; -} - -json ProceduralSky::Serialize() -{ - BEGIN_SERIALIZE() - SERIALIZE_VAL(SurfaceRadius); - SERIALIZE_VAL(AtmosphereRadius); - SERIALIZE_VEC3(RayleighScattering); - SERIALIZE_VEC3(MieScattering); - SERIALIZE_VAL(SunIntensity); - SERIALIZE_VEC3(SunDirection); - END_SERIALIZE(); -} - -bool ProceduralSky::Deserialize(const std::string& str) -{ - return false; -} diff --git a/Nuake/src/Rendering/ProceduralSky.h b/Nuake/src/Rendering/ProceduralSky.h deleted file mode 100644 index 10582376..00000000 --- a/Nuake/src/Rendering/ProceduralSky.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include -#include "Vertex.h" -#include "../Core/Core.h" -#include "../Resource/Serializable.h" - -class Camera; -class ProceduralSky : ISerializable { -public: - float SurfaceRadius = 6360e3f; - float AtmosphereRadius = 6380e3f; - glm::vec3 RayleighScattering = glm::vec3(58e-7f, 135e-7f, 331e-7f); - glm::vec3 MieScattering = glm::vec3(2e-5f); - float SunIntensity = 100.0; - - glm::vec3 CenterPoint = glm::vec3(0.f, -SurfaceRadius, 0.f); - glm::vec3 SunDirection = glm::vec3(0.20000f, 0.95917f, 0.20000f); - unsigned int VAO; - unsigned int VBO; - ProceduralSky(); - void Draw(Ref cam); - - glm::vec3 GetSunDirection(); - - json Serialize() override; - bool Deserialize(const std::string& str) override; -}; \ No newline at end of file diff --git a/Nuake/src/Rendering/RenderList.h b/Nuake/src/Rendering/RenderList.h index 5b0f4793..b5dae854 100644 --- a/Nuake/src/Rendering/RenderList.h +++ b/Nuake/src/Rendering/RenderList.h @@ -6,19 +6,27 @@ #include "src/Rendering/Textures/Material.h" #include "src/Rendering/Mesh/Mesh.h" -class RenderList +namespace Nuake { -private: - std::map, std::vector>> m_RenderList; - -public: - - RenderList() { - this->m_RenderList = std::map, std::vector>>(); - } - - void AddToRenderList(Ref mesh) + struct RenderMesh { + Ref Mesh; + }; - } -}; \ No newline at end of file + class RenderList + { + public: + RenderList() + { + this->m_RenderList = std::map, std::vector>>(); + } + + void AddToRenderList(Ref mesh) + { + + } + + private: + std::map, std::vector>> m_RenderList; + }; +} diff --git a/Nuake/src/Rendering/Renderer.cpp b/Nuake/src/Rendering/Renderer.cpp index 2eef9012..5bf18e2d 100644 --- a/Nuake/src/Rendering/Renderer.cpp +++ b/Nuake/src/Rendering/Renderer.cpp @@ -6,221 +6,225 @@ #include "../../Engine.h" #include -unsigned int depthTexture; -unsigned int depthFBO; - -Shader* Renderer::m_Shader; -Shader* Renderer::m_SkyboxShader; -Shader* Renderer::m_BRDShader; -Shader* Renderer::m_GBufferShader; -Shader* Renderer::m_DeferredShader; -Shader* Renderer::m_ProceduralSkyShader; -Shader* Renderer::m_DebugShader; - -unsigned int CubeVAO; -unsigned int CubeVBO; -unsigned int QuadVAO; -unsigned int QuadVBO; - - -glm::vec3 CubeVertices[36]{ - glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f), - glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f), - glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f), - glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), - glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f), - glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), - glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), - glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f), - glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, 0.5f), - glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, -0.5f), - glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, 0.5f), - glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, -0.5f) -}; - -float QuadVertices[] = { - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, - -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f -}; - - -void Renderer::Init() +namespace Nuake { - // TODO: Make shader storage somewhere. - m_ShadowmapShader = new Shader("resources/Shaders/shadowMap.shader"); - m_SkyboxShader = new Shader("resources/Shaders/skybox.shader"); - m_BRDShader = new Shader("resources/Shaders/BRD.shader"); - m_GBufferShader = new Shader("resources/Shaders/gbuffer.shader"); - m_DeferredShader = new Shader("resources/Shaders/deferred.shader"); - m_ProceduralSkyShader = new Shader("resources/Shaders/atmospheric_sky.shader"); - m_DebugShader = new Shader("resources/Shaders/debug.shader"); - m_Shader = new Shader("resources/Shaders/basic.shader"); - m_Shader->Bind(); + unsigned int depthTexture; + unsigned int depthFBO; - // TODO: Use buffer abstraction. - // Setup buffers - glGenVertexArrays(1, &CubeVAO); - glBindVertexArray(CubeVAO); + Shader* Renderer::m_Shader; + Shader* Renderer::m_SkyboxShader; + Shader* Renderer::m_BRDShader; + Shader* Renderer::m_GBufferShader; + Shader* Renderer::m_DeferredShader; + Shader* Renderer::m_ProceduralSkyShader; + Shader* Renderer::m_DebugShader; - glGenBuffers(1, &CubeVBO); - glBindBuffer(GL_ARRAY_BUFFER, CubeVBO); - - glBindBuffer(GL_ARRAY_BUFFER, CubeVBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(CubeVertices), CubeVertices, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0); - glEnableVertexAttribArray(0); - - // Quad - glGenVertexArrays(1, &QuadVAO); - glBindVertexArray(QuadVAO); - - glGenBuffers(1, &QuadVBO); - glBindBuffer(GL_ARRAY_BUFFER, QuadVBO); - - glBindBuffer(GL_ARRAY_BUFFER, QuadVBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(QuadVertices), QuadVertices, GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); - -} - -// TODO: Move to shader storage -Shader* Renderer::m_ShadowmapShader; - -void Renderer::BeginDraw(Ref camera) -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - m_Shader->SetUniformMat4f("u_Projection", camera->GetPerspective()); - m_Shader->SetUniformMat4f("u_View", camera->GetTransform()); - m_Shader->SetUniform3f("u_EyePosition", camera->GetTranslation().x, camera->GetTranslation().y, camera->GetTranslation().z); - m_Shader->Bind(); -} - -void Renderer::EndDraw() -{ - m_Lights.clear(); // Clean up lights. -} + unsigned int CubeVAO; + unsigned int CubeVBO; + unsigned int QuadVAO; + unsigned int QuadVBO; -// List of all lights queued to be used for rendering this frame. -std::vector Renderer::m_Lights; + glm::vec3 CubeVertices[36]{ + glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f), + glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f), + glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f), + glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), + glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, -0.5f), + glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), + glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), + glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.5f, 0.5f, 0.5f), + glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.5f, -0.5f, 0.5f), + glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(-0.5f, -0.5f, -0.5f), + glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.5f, 0.5f, 0.5f), + glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(-0.5f, 0.5f, -0.5f) + }; -void Renderer::RegisterLight(TransformComponent transform, LightComponent light, Ref cam) -{ - if (m_Lights.size() == 20) - return; - m_Lights.push_back({ transform , light }); + float QuadVertices[] = { + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f + }; - // What light idx is this? - int idx = m_Lights.size(); - glm::vec3 direction = light.GetDirection(); - glm::vec3 pos = transform.GlobalTranslation; - glm::mat4 lightView = glm::lookAt(pos, pos - direction, glm::vec3(0.0f, 1.0f, 0.0f)); - - //light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17); - - if (light.CastShadows) + void Renderer::Init() { - light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17); - light.m_Framebuffers[1]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(18); - light.m_Framebuffers[2]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(19); - light.m_Framebuffers[3]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(20); + // TODO: Make shader storage somewhere. + m_ShadowmapShader = new Shader("resources/Shaders/shadowMap.shader"); + m_SkyboxShader = new Shader("resources/Shaders/skybox.shader"); + m_BRDShader = new Shader("resources/Shaders/BRD.shader"); + m_GBufferShader = new Shader("resources/Shaders/gbuffer.shader"); + m_DeferredShader = new Shader("resources/Shaders/deferred.shader"); + m_ProceduralSkyShader = new Shader("resources/Shaders/atmospheric_sky.shader"); + m_DebugShader = new Shader("resources/Shaders/debug.shader"); + m_Shader = new Shader("resources/Shaders/basic.shader"); + m_Shader->Bind(); + + // TODO: Use buffer abstraction. + // Setup buffers + glGenVertexArrays(1, &CubeVAO); + glBindVertexArray(CubeVAO); + + glGenBuffers(1, &CubeVBO); + glBindBuffer(GL_ARRAY_BUFFER, CubeVBO); + + glBindBuffer(GL_ARRAY_BUFFER, CubeVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(CubeVertices), CubeVertices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0); + glEnableVertexAttribArray(0); + + // Quad + glGenVertexArrays(1, &QuadVAO); + glBindVertexArray(QuadVAO); + + glGenBuffers(1, &QuadVBO); + glBindBuffer(GL_ARRAY_BUFFER, QuadVBO); + + glBindBuffer(GL_ARRAY_BUFFER, QuadVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(QuadVertices), QuadVertices, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + + } + + // TODO: Move to shader storage + Shader* Renderer::m_ShadowmapShader; + + void Renderer::BeginDraw(Ref camera) + { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + m_Shader->SetUniformMat4f("u_Projection", camera->GetPerspective()); + m_Shader->SetUniformMat4f("u_View", camera->GetTransform()); + m_Shader->SetUniform3f("u_EyePosition", camera->GetTranslation().x, camera->GetTranslation().y, camera->GetTranslation().z); + m_Shader->Bind(); + } + + void Renderer::EndDraw() + { + m_Lights.clear(); // Clean up lights. } - m_Shader->SetUniform1i ("LightCount", idx); - m_Shader->SetUniform1i ("Lights[" + std::to_string(idx - 1) + "].Type" , light.Type); - m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[0]", 17); - m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[1]", 18); - m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[2]", 19); - m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[3]", 20); - m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[0]", light.mViewProjections[0]); - m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[1]", light.mViewProjections[1]); - m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[2]", light.mViewProjections[2]); - m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[3]", light.mViewProjections[3]); - m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[0]", light.mCascadeSplitDepth[0]); - m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[1]", light.mCascadeSplitDepth[1]); - m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[2]", light.mCascadeSplitDepth[2]); - m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[3]", light.mCascadeSplitDepth[3]); - m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView); - m_Shader->SetUniform3f ("Lights[" + std::to_string(idx - 1) + "].Position" , transform.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z); - m_Shader->SetUniform3f ("Lights[" + std::to_string(idx - 1) + "].Direction" , direction.x, direction.y, direction.z); - m_Shader->SetUniform3f ("Lights[" + std::to_string(idx - 1) + "].Color" , light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength); - m_Shader->SetUniform1i ("Lights[" + std::to_string(idx - 1) + "].Volumetric", light.IsVolumetric); -} - -void Renderer::RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam) -{ - m_Lights.push_back({ transform , light }); - - // What light idx is this? - int idx = m_Lights.size(); - - glm::vec3 direction = light.GetDirection(); - glm::vec3 pos = transform.Translation; - glm::mat4 lightView = glm::lookAt(pos, pos - direction, glm::vec3(0.0f, 1.0f, 0.0f)); - - light.m_Framebuffer->GetTexture()->Bind(11); - - m_DeferredShader->SetUniform1i("LightCount", idx); - m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Type", light.Type); - m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMap", 11); - m_DeferredShader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView); - m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Position", transform.Translation.x, transform.Translation.y, transform.Translation.z); - m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z); - m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength); -} - -void Renderer::DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color) { - //m_DebugShader->Bind(); - //m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a); -} - -// TODO: Maybe have a debug primitive draw list -void Renderer::DrawCube(TransformComponent transform, glm::vec4 color) -{ - //glDisable(GL_DEPTH_TEST); - Ref window = Engine::GetCurrentWindow(); - Ref fb = window->GetFrameBuffer(); - - - m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); - m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a); - glBindVertexArray(CubeVAO); - glDrawArrays(GL_TRIANGLES, 0, 36); - - m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, 1.0f); - - glPolygonMode(GL_FRONT, GL_LINE); - glPolygonMode(GL_BACK, GL_LINE); - glLineWidth(4); - glDrawArrays(GL_TRIANGLES, 0, 36); - - // Turn off wireframe mode - glPolygonMode(GL_FRONT, GL_FILL); - glPolygonMode(GL_BACK, GL_FILL); - //glEnable(GL_DEPTH_TEST); - -} - -// TODO: See above -void Renderer::DrawSphere(TransformComponent transform, glm::vec4 color) -{ - -} - -void Renderer::DrawQuad(Matrix4 transform) -{ - glBindVertexArray(QuadVAO); - glDrawArrays(GL_TRIANGLES, 0, 6); + // List of all lights queued to be used for rendering this frame. + std::vector Renderer::m_Lights; + + void Renderer::RegisterLight(TransformComponent transform, LightComponent light, Ref cam) + { + if (m_Lights.size() == 20) + return; + m_Lights.push_back({ transform , light }); + + // What light idx is this? + int idx = m_Lights.size(); + + glm::vec3 direction = light.GetDirection(); + glm::vec3 pos = transform.GlobalTranslation; + glm::mat4 lightView = glm::lookAt(pos, pos - direction, glm::vec3(0.0f, 1.0f, 0.0f)); + + //light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17); + + if (light.CastShadows) + { + light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17); + light.m_Framebuffers[1]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(18); + light.m_Framebuffers[2]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(19); + light.m_Framebuffers[3]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(20); + } + + + m_Shader->SetUniform1i("LightCount", idx); + m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Type", light.Type); + m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[0]", 17); + m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[1]", 18); + m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[2]", 19); + m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[3]", 20); + m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[0]", light.mViewProjections[0]); + m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[1]", light.mViewProjections[1]); + m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[2]", light.mViewProjections[2]); + m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[3]", light.mViewProjections[3]); + m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[0]", light.mCascadeSplitDepth[0]); + m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[1]", light.mCascadeSplitDepth[1]); + m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[2]", light.mCascadeSplitDepth[2]); + m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[3]", light.mCascadeSplitDepth[3]); + m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView); + m_Shader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Position", transform.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z); + m_Shader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z); + m_Shader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength); + m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Volumetric", light.IsVolumetric); + } + + void Renderer::RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam) + { + m_Lights.push_back({ transform , light }); + + // What light idx is this? + int idx = m_Lights.size(); + + glm::vec3 direction = light.GetDirection(); + glm::vec3 pos = transform.Translation; + glm::mat4 lightView = glm::lookAt(pos, pos - direction, glm::vec3(0.0f, 1.0f, 0.0f)); + + light.m_Framebuffer->GetTexture()->Bind(11); + + m_DeferredShader->SetUniform1i("LightCount", idx); + m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Type", light.Type); + m_DeferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMap", 11); + m_DeferredShader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransform", light.GetProjection() * lightView); + m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Position", transform.Translation.x, transform.Translation.y, transform.Translation.z); + m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z); + m_DeferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength); + } + + void Renderer::DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color) + { + //m_DebugShader->Bind(); + //m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a); + } + + // TODO: Maybe have a debug primitive draw list + void Renderer::DrawCube(TransformComponent transform, glm::vec4 color) + { + //glDisable(GL_DEPTH_TEST); + Ref window = Engine::GetCurrentWindow(); + Ref fb = window->GetFrameBuffer(); + + + m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); + m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, color.a); + glBindVertexArray(CubeVAO); + glDrawArrays(GL_TRIANGLES, 0, 36); + + m_DebugShader->SetUniform4f("u_Color", color.r, color.g, color.b, 1.0f); + + glPolygonMode(GL_FRONT, GL_LINE); + glPolygonMode(GL_BACK, GL_LINE); + glLineWidth(4); + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Turn off wireframe mode + glPolygonMode(GL_FRONT, GL_FILL); + glPolygonMode(GL_BACK, GL_FILL); + //glEnable(GL_DEPTH_TEST); + + } + + // TODO: See above + void Renderer::DrawSphere(TransformComponent transform, glm::vec4 color) + { + + } + + void Renderer::DrawQuad(Matrix4 transform) + { + glBindVertexArray(QuadVAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + } } diff --git a/Nuake/src/Rendering/Renderer.h b/Nuake/src/Rendering/Renderer.h index b0447e41..309f164a 100644 --- a/Nuake/src/Rendering/Renderer.h +++ b/Nuake/src/Rendering/Renderer.h @@ -3,36 +3,44 @@ #include "../Scene/Components/Components.h" #include "../Core/Core.h" -struct Light { - TransformComponent transform; - LightComponent light; -}; +namespace Nuake +{ + struct Light + { + TransformComponent transform; + LightComponent light; + }; -class Renderer { -public: - static Shader* m_Shader; - static Shader* m_ShadowmapShader; - static Shader* m_SkyboxShader; - static Shader* m_BRDShader; - static Shader* m_GBufferShader; - static Shader* m_DeferredShader; - static Shader* m_ProceduralSkyShader; - static Shader* m_DebugShader; + class Renderer + { + public: + static Shader* m_Shader; + static Shader* m_ShadowmapShader; + static Shader* m_SkyboxShader; + static Shader* m_BRDShader; + static Shader* m_GBufferShader; + static Shader* m_DeferredShader; + static Shader* m_ProceduralSkyShader; + static Shader* m_DebugShader; - static void Init(); + static void Init(); - // Drawing states - static void BeginDraw(Ref camera); - static void EndDraw(); + // Drawing states + static void BeginDraw(Ref camera); + static void EndDraw(); - // Lights - static std::vector m_Lights; - static void RegisterLight(TransformComponent transform, LightComponent light, Ref cam); - static void RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam); + // Lights + static std::vector m_Lights; + static void RegisterLight(TransformComponent transform, LightComponent light, Ref cam); + static void RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam); - // Debug - static void DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color); - static void DrawCube(TransformComponent transform, glm::vec4 color); - static void DrawSphere(TransformComponent transform, glm::vec4 color); - static void DrawQuad(Matrix4 transform); -}; \ No newline at end of file + + static void SubmitMesh(Ref mesh); + + // Debug + static void DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color); + static void DrawCube(TransformComponent transform, glm::vec4 color); + static void DrawSphere(TransformComponent transform, glm::vec4 color); + static void DrawQuad(Matrix4 transform); + }; +} diff --git a/Nuake/src/Rendering/Renderer2D.cpp b/Nuake/src/Rendering/Renderer2D.cpp index 877db9d8..4f1bec7a 100644 --- a/Nuake/src/Rendering/Renderer2D.cpp +++ b/Nuake/src/Rendering/Renderer2D.cpp @@ -1,137 +1,140 @@ #include "Renderer2D.h" #include "GL/glew.h" -#include "../Core/Maths.h" #include +#include "src/UI/Nodes/TextNode.h" -#include "../UI/Nodes/TextNode.h" -Ref Renderer2D::UIShader; -Ref Renderer2D::TextShader; - -unsigned int Renderer2D::VAO; -unsigned int Renderer2D::VBO; - -Matrix4 Renderer2D::Projection; - -void Renderer2D::Init() +namespace Nuake { - UIShader = CreateRef("resources/Shaders/ui.shader"); - TextShader = CreateRef("resources/Shaders/sdf_text.shader"); + Ref Renderer2D::UIShader; + Ref Renderer2D::TextShader; - float quad_Vertices[] = { - // positions // texture Coords - 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, - 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f - }; - // setup plane VAO - glGenVertexArrays(1, &Renderer2D::VAO); - glGenBuffers(1, &Renderer2D::VBO); - glBindVertexArray(Renderer2D::VAO); - glBindBuffer(GL_ARRAY_BUFFER, Renderer2D::VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(quad_Vertices), &quad_Vertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); -} + unsigned int Renderer2D::VAO; + unsigned int Renderer2D::VBO; -void Renderer2D::BeginDraw(Vector2 size) -{ - glDisable(GL_DEPTH_TEST); - Projection = glm::ortho(0.f, size.x, size.y, 0.f, -0.5f, 1000.0f); - UIShader->Bind(); - UIShader->SetUniformMat4f("projection", Projection); -} + Matrix4 Renderer2D::Projection; -void Renderer2D::DrawRect() -{ - glBindVertexArray(Renderer2D::VAO); - glDrawArrays(GL_TRIANGLES, 0, 6); -} + void Renderer2D::Init() + { + UIShader = CreateRef("resources/Shaders/ui.shader"); + TextShader = CreateRef("resources/Shaders/sdf_text.shader"); -Vector2 Renderer2D::CalculateStringSize(const std::string& str, Ref font, Vector2 position, float fontSize) -{ - float advance = 0.0f; - float Y = 0.0f; - for (char const& c : str) { - Char& letter = font->GetChar((int)c); - advance += letter.Advance * fontSize; - if(letter.PlaneBounds.top - letter.PlaneBounds.bottom > Y) - Y = letter.PlaneBounds.top - letter.PlaneBounds.bottom; - } - return Vector2(advance, Y); -} - -void Renderer2D::DrawString(const std::string& str, TextStyle style, Matrix4 model) -{ - - TextShader->Bind(); - TextShader->SetUniformMat4f("projection", Projection); - float advance = 0.0f; - style.font->FontAtlas->Bind(5); - TextShader->SetUniform1i("msdf", 5); - - - float lineHeight = 0.0f; - for (char const& c : str) { - Char& letter = style.font->GetChar((int)c); - - if (letter.PlaneBounds.top - letter.PlaneBounds.bottom > lineHeight) - lineHeight = letter.PlaneBounds.top - letter.PlaneBounds.bottom ; + float quad_Vertices[] = { + // positions // texture Coords + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f + }; + // setup plane VAO + glGenVertexArrays(1, &Renderer2D::VAO); + glGenBuffers(1, &Renderer2D::VBO); + glBindVertexArray(Renderer2D::VAO); + glBindBuffer(GL_ARRAY_BUFFER, Renderer2D::VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(quad_Vertices), &quad_Vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); } - lineHeight *= style.fontSize; + void Renderer2D::BeginDraw(Vector2 size) + { + glDisable(GL_DEPTH_TEST); + Projection = glm::ortho(0.f, size.x, size.y, 0.f, -0.5f, 1000.0f); + UIShader->Bind(); + UIShader->SetUniformMat4f("projection", Projection); + } - for (char const& c : str) { - Char& letter = style.font->GetChar((int)c); - Matrix4 mat = glm::translate(model, Vector3(advance, -(letter.PlaneBounds.top) + (lineHeight), 0.f)); - float scaleX = letter.PlaneBounds.right - letter.PlaneBounds.left; - float scaleY = letter.PlaneBounds.top - letter.PlaneBounds.bottom; - mat = glm::scale(mat, Vector3(scaleX, scaleY, 0.f)); + void Renderer2D::DrawRect() + { + glBindVertexArray(Renderer2D::VAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + + Vector2 Renderer2D::CalculateStringSize(const std::string& str, Ref font, Vector2 position, float fontSize) + { + float advance = 0.0f; + float Y = 0.0f; + for (char const& c : str) { + Char& letter = font->GetChar((int)c); + advance += letter.Advance * fontSize; + if (letter.PlaneBounds.top - letter.PlaneBounds.bottom > Y) + Y = letter.PlaneBounds.top - letter.PlaneBounds.bottom; + } + return Vector2(advance, Y); + } + + void Renderer2D::DrawString(const std::string& str, TextStyle style, Matrix4 model) + { + + TextShader->Bind(); + TextShader->SetUniformMat4f("projection", Projection); + float advance = 0.0f; + style.font->FontAtlas->Bind(5); + TextShader->SetUniform1i("msdf", 5); + + + float lineHeight = 0.0f; + for (char const& c : str) { + Char& letter = style.font->GetChar((int)c); + + if (letter.PlaneBounds.top - letter.PlaneBounds.bottom > lineHeight) + lineHeight = letter.PlaneBounds.top - letter.PlaneBounds.bottom; + } + + lineHeight *= style.fontSize; + + for (char const& c : str) { + Char& letter = style.font->GetChar((int)c); + Matrix4 mat = glm::translate(model, Vector3(advance, -(letter.PlaneBounds.top) + (lineHeight), 0.f)); + float scaleX = letter.PlaneBounds.right - letter.PlaneBounds.left; + float scaleY = letter.PlaneBounds.top - letter.PlaneBounds.bottom; + mat = glm::scale(mat, Vector3(scaleX, scaleY, 0.f)); + TextShader->SetUniform2f("texPos", letter.AtlasBounds.Pos.x, letter.AtlasBounds.Pos.y); + TextShader->SetUniform2f("texScale", letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y); + TextShader->SetUniformMat4f("model", mat); + //TextShader->SetUniform4f("bgColor", 0, 0, 1, 1); + TextShader->SetUniform4f("bgColor", 1.f, 0.f, 0.f, 0.f); + TextShader->SetUniform4f("fgColor", 1.f, 1.f, 1.f, 1.f); + //TextShader->SetUniform1f("pxRange", 32); + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + advance += letter.Advance; + } + } + + void Renderer2D::DrawChar(Char& letter, Ref font, Vector2 position, Vector2 size) + { + TextShader->Bind(); + TextShader->SetUniformMat4f("projection", Projection); + + Matrix4 mat = Matrix4(1.0f); + mat = glm::translate(mat, Vector3(position.x, position.y, 0.f)); + mat = glm::scale(mat, Vector3(letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y, 0.f)); + + //TextShader->SetUniform1f("u_border_radius", 8.1f); + //TextShader->SetUniform2f("u_size", 100.f, 100.f); + + font->FontAtlas->Bind(5); + // + TextShader->SetUniform1i("msdf", 5); TextShader->SetUniform2f("texPos", letter.AtlasBounds.Pos.x, letter.AtlasBounds.Pos.y); TextShader->SetUniform2f("texScale", letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y); TextShader->SetUniformMat4f("model", mat); //TextShader->SetUniform4f("bgColor", 0, 0, 1, 1); - TextShader->SetUniform4f("bgColor", 1.f, 0.f, 0.f, 0.f); + TextShader->SetUniform4f("bgColor", 0.f, 0.f, 0.f, 0.f); TextShader->SetUniform4f("fgColor", 1.f, 1.f, 1.f, 1.f); //TextShader->SetUniform1f("pxRange", 32); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 6); - advance += letter.Advance; + } + + + void Renderer2D::EndDraw() + { + } } -void Renderer2D::DrawChar(Char& letter, Ref font, Vector2 position, Vector2 size) -{ - TextShader->Bind(); - TextShader->SetUniformMat4f("projection", Projection); - - Matrix4 mat = Matrix4(1.0f); - mat = glm::translate(mat, Vector3(position.x, position.y, 0.f)); - mat = glm::scale(mat, Vector3(letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y, 0.f)); - - //TextShader->SetUniform1f("u_border_radius", 8.1f); - //TextShader->SetUniform2f("u_size", 100.f, 100.f); - - font->FontAtlas->Bind(5); - // - TextShader->SetUniform1i("msdf", 5); - TextShader->SetUniform2f("texPos", letter.AtlasBounds.Pos.x, letter.AtlasBounds.Pos.y); - TextShader->SetUniform2f("texScale", letter.AtlasBounds.Size.x, letter.AtlasBounds.Size.y); - TextShader->SetUniformMat4f("model", mat); - //TextShader->SetUniform4f("bgColor", 0, 0, 1, 1); - TextShader->SetUniform4f("bgColor", 0.f, 0.f, 0.f, 0.f); - TextShader->SetUniform4f("fgColor", 1.f, 1.f, 1.f, 1.f); - //TextShader->SetUniform1f("pxRange", 32); - glBindVertexArray(VAO); - glDrawArrays(GL_TRIANGLES, 0, 6); -} - - -void Renderer2D::EndDraw() -{ - -} diff --git a/Nuake/src/Rendering/Renderer2D.h b/Nuake/src/Rendering/Renderer2D.h index 49855efd..8a221384 100644 --- a/Nuake/src/Rendering/Renderer2D.h +++ b/Nuake/src/Rendering/Renderer2D.h @@ -1,24 +1,28 @@ #pragma once -#include -#include -#include +#include "src/Rendering/Shaders/Shader.h" +#include "src/Core/Core.h" +#include "src/Core/Maths.h" #include "src/UI/Font/Font.h" -class TextStyle; -class Renderer2D -{ -private: - static unsigned int VAO; - static unsigned int VBO; -public: - static Ref UIShader; - static Ref TextShader; - static Matrix4 Projection; - static void Init(); - static void BeginDraw(Vector2 size); - static void DrawRect(); - static Vector2 CalculateStringSize(const std::string& str, Ref font, Vector2 position, float fontSize); - static void DrawString(const std::string& str, TextStyle style, Matrix4 model); - static void DrawChar(Char& letter, Ref font, Vector2 position, Vector2 size); - static void EndDraw(); -}; \ No newline at end of file +namespace Nuake +{ + class TextStyle; + class Renderer2D + { + private: + static unsigned int VAO; + static unsigned int VBO; + public: + static Ref UIShader; + static Ref TextShader; + static Matrix4 Projection; + + static void Init(); + static void BeginDraw(Vector2 size); + static void DrawRect(); + static Vector2 CalculateStringSize(const std::string& str, Ref font, Vector2 position, float fontSize); + static void DrawString(const std::string& str, TextStyle style, Matrix4 model); + static void DrawChar(Char& letter, Ref font, Vector2 position, Vector2 size); + static void EndDraw(); + }; +} diff --git a/Nuake/src/Rendering/Shaders/Shader.cpp b/Nuake/src/Rendering/Shaders/Shader.cpp index d2f09a85..c28293d9 100644 --- a/Nuake/src/Rendering/Shaders/Shader.cpp +++ b/Nuake/src/Rendering/Shaders/Shader.cpp @@ -5,186 +5,200 @@ #define ASSERT(x) if (!(x)) assert(false) -// TODO: Register all uniform when creating shader. -Shader::Shader(const std::string& filePath) { - Source = ParseShader(filePath); - - ProgramId = CreateProgram(); -} - -// Bind the shader -void Shader::Bind() const { - glUseProgram(ProgramId); -} - -// unbind the shader -void Shader::Unbind() const { - glUseProgram(0); -} - -// Prase the shader file and create string source. -ShaderSource Shader::ParseShader(const std::string& filePath) { - std::ifstream stream(filePath); - - enum class ShaderType { - NONE = -1, VERTEX = 0, FRAGMENT = 1 - }; - - ShaderType type = ShaderType::NONE; - - std::string line; - std::stringstream ss[2]; - - while (getline(stream, line)) +namespace Nuake +{ + // TODO: Register all uniform when creating shader. + Shader::Shader(const std::string& filePath) { - // If the current lines contains #shader - if (line.find("#shader") != std::string::npos) + Source = ParseShader(filePath); + + ProgramId = CreateProgram(); + } + + // Bind the shader + void Shader::Bind() const + { + glUseProgram(ProgramId); + } + + // unbind the shader + void Shader::Unbind() const + { + glUseProgram(0); + } + + // Prase the shader file and create string source. + ShaderSource Shader::ParseShader(const std::string& filePath) + { + std::ifstream stream(filePath); + + enum class ShaderType { - // If the current line containes vertex - if (line.find("vertex") != std::string::npos) { - // set mode to vertex - type = ShaderType::VERTEX; + NONE = -1, VERTEX = 0, FRAGMENT = 1 + }; + + ShaderType type = ShaderType::NONE; + + std::string line; + std::stringstream ss[2]; + + while (getline(stream, line)) + { + // If the current lines contains #shader + if (line.find("#shader") != std::string::npos) + { + // If the current line containes vertex + if (line.find("vertex") != std::string::npos) + { + // set mode to vertex + type = ShaderType::VERTEX; + } + else if (line.find("fragment") != std::string::npos) + { + // set mode to fragment + type = ShaderType::FRAGMENT; + } } - else if (line.find("fragment") != std::string::npos) { - // set mode to fragment - type = ShaderType::FRAGMENT; + else + { + ss[(int)type] << line << "\n"; } } - else - { - ss[(int)type] << line << "\n"; - } + + return { ss[0].str(), ss[1].str() }; } - return { ss[0].str(), ss[1].str() }; -} - -// Parse both source and creates a shader program. -// This returns the program id. -unsigned int Shader::CreateProgram() { - unsigned int program = glCreateProgram(); - unsigned int vs = Compile(GL_VERTEX_SHADER); - unsigned int fs = Compile(GL_FRAGMENT_SHADER); - - glAttachShader(program, vs); - glAttachShader(program, fs); - glLinkProgram(program); - glValidateProgram(program); - - glDeleteShader(vs); - glDeleteShader(fs); - - return program; -} - -// Compile a single shader and checks for error. -unsigned int Shader::Compile(unsigned int type) -{ - unsigned int id = glCreateShader(type); - - const char* src; - if (type == GL_FRAGMENT_SHADER) src = Source.FragmentShader.c_str(); - if (type == GL_VERTEX_SHADER) src = Source.VertexShader.c_str(); - - glShaderSource(id, 1, &src, nullptr); - glCompileShader(id); - - //TODO: Error handling - int result; - glGetShaderiv(id, GL_COMPILE_STATUS, &result); - - // Shader error. - if (result == GL_FALSE) + // Parse both source and creates a shader program. + // This returns the program id. + unsigned int Shader::CreateProgram() { - int length; - glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); + unsigned int program = glCreateProgram(); + unsigned int vs = Compile(GL_VERTEX_SHADER); + unsigned int fs = Compile(GL_FRAGMENT_SHADER); - // We allocate the size of the array using - // m alloc. casted as a pointer. - char* message = (char*)malloc(length * sizeof(char)); + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + glValidateProgram(program); - //glGetShaderInfoLog(id, length, &length, message); + glDeleteShader(vs); + glDeleteShader(fs); - std::cout << "Failed to compile " << - (type == GL_VERTEX_SHADER ? "vertex" : "Fragment") << " shader!" << std::endl; - std::cout << message << std::endl; - - // Delete invalid shader - glDeleteShader(id); - return 0; + return program; } - return id; -} + // Compile a single shader and checks for error. + unsigned int Shader::Compile(unsigned int type) + { + unsigned int id = glCreateShader(type); -// Retrieve uniform address and registers it if not already registered. -int Shader::FindUniformLocation(std::string uniform) { - if (UniformCache.count(uniform) == 0) { - int addr = glGetUniformLocation(ProgramId, uniform.c_str()); + const char* src; + if (type == GL_FRAGMENT_SHADER) src = Source.FragmentShader.c_str(); + if (type == GL_VERTEX_SHADER) src = Source.VertexShader.c_str(); - if (addr == -1) - std::cout << "Warning: uniform '" << uniform << "' doesn't exists!" << std::endl; - else { - //std::cout << "Info: uniform '" << uniform << "' registered." << std::endl; - UniformCache[uniform] = addr; + glShaderSource(id, 1, &src, nullptr); + glCompileShader(id); + + //TODO: Error handling + int result; + glGetShaderiv(id, GL_COMPILE_STATUS, &result); + + // Shader error. + if (result == GL_FALSE) + { + int length; + glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); + + // We allocate the size of the array using + // m alloc. casted as a pointer. + char* message = (char*)malloc(length * sizeof(char)); + + //glGetShaderInfoLog(id, length, &length, message); + + std::cout << "Failed to compile " << + (type == GL_VERTEX_SHADER ? "vertex" : "Fragment") << " shader!" << std::endl; + std::cout << message << std::endl; + + // Delete invalid shader + glDeleteShader(id); + return 0; } - - return addr; + return id; } - return UniformCache[uniform]; -} + // Retrieve uniform address and registers it if not already registered. + int Shader::FindUniformLocation(std::string uniform) + { + if (UniformCache.count(uniform) != 0) + { + int addr = glGetUniformLocation(ProgramId, uniform.c_str()); -// Uniforms -void Shader::SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3) { - int addr = FindUniformLocation(name); - ASSERT(addr != -1); - glUniform4f(addr, v0, v1, v2, v3); -} + if (addr == -1) + std::cout << "Warning: uniform '" << uniform << "' doesn't exists!" << std::endl; + else + UniformCache[uniform] = addr; -void Shader::SetUniform3f(const std::string& name, float v0, float v1, float v2) { - int addr = FindUniformLocation(name); - ASSERT(addr != -1); - glUniform3f(addr, v0, v1, v2); -} + return addr; + } -void Shader::SetUniform2f(const std::string& name, float v0, float v1) { - int addr = FindUniformLocation(name); - ASSERT(addr != -1); - glUniform2f(addr, v0, v1); -} + return UniformCache[uniform]; + } -void Shader::SetUniform1i(const std::string& name, int v0) { - int addr = FindUniformLocation(name); - ASSERT(addr != -1); - glUniform1i(addr, v0); -} + // Uniforms + void Shader::SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3) + { + int addr = FindUniformLocation(name); + ASSERT(addr != -1); + glUniform4f(addr, v0, v1, v2, v3); + } -void Shader::SetUniform1iv(const std::string& name, int size, int* value) -{ - int addr = FindUniformLocation(name); - ASSERT(addr != -1); - glUniform1iv(addr, size, value); -} + void Shader::SetUniform3f(const std::string& name, float v0, float v1, float v2) + { + int addr = FindUniformLocation(name); + ASSERT(addr != -1); + glUniform3f(addr, v0, v1, v2); + } -void Shader::SetUniformMat3f(const std::string& name, glm::mat3 mat) -{ - int addr = FindUniformLocation(name); - ASSERT(addr != -1); - glUniformMatrix3fv(addr, 1, GL_FALSE, &mat[0][0]); -} + void Shader::SetUniform2f(const std::string& name, float v0, float v1) + { + int addr = FindUniformLocation(name); + ASSERT(addr != -1); + glUniform2f(addr, v0, v1); + } -void Shader::SetUniformMat4f(const std::string& name, glm::mat4 mat) -{ - int addr = FindUniformLocation(name); - ASSERT(addr != -1); - glUniformMatrix4fv(addr, 1, GL_FALSE, &mat[0][0]); -} + void Shader::SetUniform1i(const std::string& name, int v0) + { + int addr = FindUniformLocation(name); + ASSERT(addr != -1); + glUniform1i(addr, v0); + } -void Shader::SetUniform1f(const std::string& name, float v0) { - int addr = FindUniformLocation(name); - ASSERT(addr != -1); - glUniform1f(addr, v0); -} + void Shader::SetUniform1iv(const std::string& name, int size, int* value) + { + int addr = FindUniformLocation(name); + ASSERT(addr != -1); + glUniform1iv(addr, size, value); + } + void Shader::SetUniformMat3f(const std::string& name, glm::mat3 mat) + { + int addr = FindUniformLocation(name); + ASSERT(addr != -1); + glUniformMatrix3fv(addr, 1, GL_FALSE, &mat[0][0]); + } + + void Shader::SetUniformMat4f(const std::string& name, glm::mat4 mat) + { + int addr = FindUniformLocation(name); + ASSERT(addr != -1); + glUniformMatrix4fv(addr, 1, GL_FALSE, &mat[0][0]); + } + + void Shader::SetUniform1f(const std::string& name, float v0) + { + int addr = FindUniformLocation(name); + ASSERT(addr != -1); + glUniform1f(addr, v0); + } +} diff --git a/Nuake/src/Rendering/Shaders/Shader.h b/Nuake/src/Rendering/Shaders/Shader.h index ccd86f24..1c92d39f 100644 --- a/Nuake/src/Rendering/Shaders/Shader.h +++ b/Nuake/src/Rendering/Shaders/Shader.h @@ -5,40 +5,43 @@ #include #include "glm/gtc/matrix_transform.hpp" -struct ShaderSource { - std::string VertexShader; - std::string FragmentShader; -}; +namespace Nuake +{ + struct ShaderSource + { + std::string VertexShader; + std::string FragmentShader; + }; -class Shader { -public: - ShaderSource Source; - unsigned int ProgramId; + class Shader + { + public: + ShaderSource Source; + unsigned int ProgramId; - std::unordered_map UniformCache; + std::unordered_map UniformCache; - Shader(const std::string& filePath); + Shader(const std::string& filePath); - void Bind() const; - void Unbind() const; + void Bind() const; + void Unbind() const; - // Todo: Other uniform types. - void SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3); - void SetUniform3f(const std::string& name, float v0, float v1, float v2); - void SetUniform2f(const std::string& name, float v0, float v1); - void SetUniform1f(const std::string& name, float v0); - void SetUniform1i(const std::string& name, int v0); - - void SetUniform1iv(const std::string& name, int size, int* value); - void SetUniformMat3f(const std::string& name, glm::mat3 mat); - void SetUniformMat4f(const std::string& name, glm::mat4 mat); - -private: - ShaderSource ParseShader(const std::string& filePath); - unsigned int CreateProgram(); - unsigned int Compile(unsigned int type); - int FindUniformLocation(std::string uniform); -}; + // Todo: Other uniform types. + void SetUniform4f(const std::string& name, float v0, float v1, float v2, float v3); + void SetUniform3f(const std::string& name, float v0, float v1, float v2); + void SetUniform2f(const std::string& name, float v0, float v1); + void SetUniform1f(const std::string& name, float v0); + void SetUniform1i(const std::string& name, int v0); + void SetUniform1iv(const std::string& name, int size, int* value); + void SetUniformMat3f(const std::string& name, glm::mat3 mat); + void SetUniformMat4f(const std::string& name, glm::mat4 mat); + private: + ShaderSource ParseShader(const std::string& filePath); + unsigned int CreateProgram(); + unsigned int Compile(unsigned int type); + int FindUniformLocation(std::string uniform); + }; +} diff --git a/Nuake/src/Rendering/Shaders/ShaderManager.cpp b/Nuake/src/Rendering/Shaders/ShaderManager.cpp index 4cb92e99..e51d591d 100644 --- a/Nuake/src/Rendering/Shaders/ShaderManager.cpp +++ b/Nuake/src/Rendering/Shaders/ShaderManager.cpp @@ -1,14 +1,17 @@ #pragma once #include "ShaderManager.h" -std::map> ShaderManager::m_Shaders = std::map>(); - -Ref ShaderManager::GetShader(const std::string& path) +namespace Nuake { - if (m_Shaders.find(path) == m_Shaders.end()) - { - m_Shaders[path] = CreateRef(path); - } + std::map> ShaderManager::m_Shaders = std::map>(); - return m_Shaders[path]; -} \ No newline at end of file + Ref ShaderManager::GetShader(const std::string& path) + { + if (m_Shaders.find(path) == m_Shaders.end()) + { + m_Shaders[path] = CreateRef(path); + } + + return m_Shaders[path]; + } +} diff --git a/Nuake/src/Rendering/Shaders/ShaderManager.h b/Nuake/src/Rendering/Shaders/ShaderManager.h index 1e2ba336..39d57c8e 100644 --- a/Nuake/src/Rendering/Shaders/ShaderManager.h +++ b/Nuake/src/Rendering/Shaders/ShaderManager.h @@ -5,10 +5,13 @@ #include "src/Core/Core.h" #include "Shader.h" -class ShaderManager { -private: - static std::map> m_Shaders; +namespace Nuake +{ + class ShaderManager { + private: + static std::map> m_Shaders; -public: - static Ref GetShader(const std::string& path); -}; \ No newline at end of file + public: + static Ref GetShader(const std::string& path); + }; +} diff --git a/Nuake/src/Rendering/Skybox.cpp b/Nuake/src/Rendering/Skybox.cpp deleted file mode 100644 index 87c8a99a..00000000 --- a/Nuake/src/Rendering/Skybox.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include "Skybox.h" -#include -#include "Renderer.h" -#include "Textures/Cubemap.h" -glm::vec3 Skybox::vertices[36] { - glm::vec3(-0.5f, -0.5f, -0.5f), - glm::vec3(0.5f, -0.5f, -0.5f), - glm::vec3(0.5f, 0.5f, -0.5f), - glm::vec3(0.5f, 0.5f, -0.5f), - glm::vec3(-0.5f, 0.5f, -0.5f), - glm::vec3(-0.5f, -0.5f, -0.5f), - - glm::vec3(-0.5f, -0.5f, 0.5f), - glm::vec3(0.5f, -0.5f, 0.5f), - glm::vec3(0.5f, 0.5f, 0.5f), - glm::vec3(0.5f, 0.5f, 0.5f), - glm::vec3(-0.5f, 0.5f, 0.5f), - glm::vec3(-0.5f, -0.5f, 0.5f), - - glm::vec3(-0.5f, 0.5f, 0.5f), - glm::vec3(-0.5f, 0.5f, -0.5f), - glm::vec3(-0.5f, -0.5f, -0.5f), - glm::vec3(-0.5f, -0.5f, -0.5f), - glm::vec3(-0.5f, -0.5f, 0.5f), - glm::vec3(-0.5f, 0.5f, 0.5f), - - glm::vec3(0.5f, 0.5f, 0.5f), - glm::vec3(0.5f, 0.5f, -0.5f), - glm::vec3(0.5f, -0.5f, -0.5f), - glm::vec3(0.5f, -0.5f, -0.5f), - glm::vec3(0.5f, -0.5f, 0.5f), - glm::vec3(0.5f, 0.5f, 0.5f), - - glm::vec3(-0.5f, -0.5f, -0.5f), - glm::vec3(0.5f, -0.5f, -0.5f), - glm::vec3(0.5f, -0.5f, 0.5f), - glm::vec3(0.5f, -0.5f, 0.5f), - glm::vec3(-0.5f, -0.5f, 0.5f), - glm::vec3(-0.5f, -0.5f, -0.5f), - - glm::vec3(-0.5f, 0.5f, -0.5f) , - glm::vec3(0.5f, 0.5f, -0.5f) , - glm::vec3(0.5f, 0.5f, 0.5f) , - glm::vec3(0.5f, 0.5f, 0.5f) , - glm::vec3(-0.5f, 0.5f, 0.5f) , - glm::vec3(-0.5f, 0.5f, -0.5f) -}; - -Skybox::Skybox(){ - // Setup buffers - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - - glGenBuffers(1, &VBO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0); - glEnableVertexAttribArray(0); - - // TODO: mem leak. - m_Texture = new CubemapTexture("Res/Textures/Skyboxes/1/japan"); - m_Hdr = new HDRTexture("Res/Textures/Skyboxes/HDR/OldIndustrialHall.jpg"); -} - -void Skybox::Draw(glm::mat4 projection, glm::mat4 view) { - - glDepthMask(GL_FALSE); - m_Texture->Bind(3); - m_Hdr->Bind(4); - Renderer::m_SkyboxShader->Bind(); - m_Hdr->BindCubemap(5); - Renderer::m_SkyboxShader->SetUniformMat4f("projection", projection); - Renderer::m_SkyboxShader->SetUniformMat4f("view", view); - - Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0); - Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 4); - Renderer::m_SkyboxShader->SetUniform1i("skybox", 5); - - // ... set view and projection matrix - glBindVertexArray(VAO); - - glDrawArrays(GL_TRIANGLES, 0, 36); - glDepthMask(GL_TRUE); - //Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f); -} - - -void Skybox::Push() { - m_Hdr->BindCubemap(5); - Renderer::m_Shader->SetUniform1i("u_IrradianceMap", 5); -} - - -void Skybox::CreateHDRCubemap() { - unsigned int captureFBO, captureRBO; - glGenFramebuffers(1, &captureFBO); - glGenRenderbuffers(1, &captureRBO); - - glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); - glBindRenderbuffer(GL_RENDERBUFFER, captureRBO); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO); - - unsigned int envCubemap; - glGenTextures(1, &envCubemap); - glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap); - for (unsigned int i = 0; i < 6; ++i) - { - // note that we store each face with 16 bit floating point values - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, - 512, 512, 0, GL_RGB, GL_FLOAT, nullptr); - } - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f); - glm::mat4 captureViews[] = - { - glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), - glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), - glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)), - glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)), - glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)), - glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)) - }; - m_Hdr->Bind(5); - - // convert HDR equirectangular environment map to cubemap equivalent - Renderer::m_SkyboxShader->Bind(); - Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection); - Renderer::m_SkyboxShader->SetUniform1i("convulate", 0); - Renderer::m_SkyboxShader->SetUniform1i("isHDR", 1); - Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 5); - glActiveTexture(GL_TEXTURE0); - - glViewport(0, 0, 512, 512); // don't forget to configure the viewport to the capture dimensions. - glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); - for (unsigned int i = 0; i < 6; ++i) - { - Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, envCubemap, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindVertexArray(VAO); - - glDrawArrays(GL_TRIANGLES, 0, 36); - } - - m_Hdr->SetCubemapId(envCubemap); - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - diff --git a/Nuake/src/Rendering/Skybox.h b/Nuake/src/Rendering/Skybox.h deleted file mode 100644 index 3db858d8..00000000 --- a/Nuake/src/Rendering/Skybox.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -#include -#include "Textures/HDR.h" -class CubemapTexture; - -class Skybox { - - static glm::vec3 vertices[]; - CubemapTexture* m_Texture; - HDRTexture* m_Hdr; - - - unsigned int VBO; - unsigned int VAO; -public: - Skybox(); - void Draw(glm::mat4 projection, glm::mat4 view); - - void Push(); - - void CreateHDRCubemap(); - -}; \ No newline at end of file diff --git a/Nuake/src/Rendering/Textures/Cubemap.cpp b/Nuake/src/Rendering/Textures/Cubemap.cpp index b2969586..1d491455 100644 --- a/Nuake/src/Rendering/Textures/Cubemap.cpp +++ b/Nuake/src/Rendering/Textures/Cubemap.cpp @@ -3,76 +3,87 @@ #include #include "HDR.h" -bool hasEnding(std::string const& fullString, std::string const& ending) { - if (fullString.length() >= ending.length()) { - return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); +namespace Nuake +{ + bool hasEnding(std::string const& fullString, std::string const& ending) + { + if (fullString.length() >= ending.length()) + return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); + else + return false; } - else { - return false; - } -} -CubemapTexture::CubemapTexture(const std::string& path) { - m_RendererId = 0; - m_FilePath = path; - m_LocalBuffer = nullptr; - m_Width = 0; - m_Height = 0; - m_BPP = 0; + CubemapTexture::CubemapTexture(const std::string& path) + { + m_RendererId = 0; + m_FilePath = path; + m_LocalBuffer = nullptr; + m_Width = 0; + m_Height = 0; + m_BPP = 0; - if (hasEnding(path, ".hdr")) { - CreateFromHDR(); - } - else { - stbi_set_flip_vertically_on_load(0); - - GLvoid* texture_data[6]; - // Load file data. - for (int face = 0; face < 6; face++) - texture_data[face] = stbi_load((path + std::to_string(face) + ".jpg").c_str(), &m_Width, &m_Height, &m_BPP, 4); - - // Create cube map. - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererId); - - // Set each face of the cube with image data. - for (int face = 0; face < 6; face++) { - - GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, - 0, GL_RGBA, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data[face] - ); - - // Clear. - if (texture_data[face]) - stbi_image_free(texture_data[face]); - else - std::cout << "Error: failed to load texture: " << path << std::endl; + if (hasEnding(path, ".hdr")) + { + CreateFromHDR(); + } + else + { + stbi_set_flip_vertically_on_load(0); + + GLvoid* texture_data[6]; + // Load file data. + for (int face = 0; face < 6; face++) + texture_data[face] = stbi_load((path + std::to_string(face) + ".jpg").c_str(), &m_Width, &m_Height, &m_BPP, 4); + + // Create cube map. + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererId); + + // Set each face of the cube with image data. + for (int face = 0; face < 6; face++) + { + + GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, + 0, GL_RGBA, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data[face] + ); + + // Clear. + if (texture_data[face]) + stbi_image_free(texture_data[face]); + else + std::cout << "Error: failed to load texture: " << path << std::endl; + } + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); } - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); } - + + + void CubemapTexture::CreateFromHDR() + { + + } + + CubemapTexture::~CubemapTexture() + { + glDeleteTextures(1, &m_RendererId); + } + + void CubemapTexture::Bind(unsigned int slot) const + { + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererId); + } + + void CubemapTexture::Unbind() const + { + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + } } -void CubemapTexture::CreateFromHDR() { - -} - -CubemapTexture::~CubemapTexture() { - glDeleteTextures(1, &m_RendererId); -} - -void CubemapTexture::Bind(unsigned int slot) const { - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererId); -} - -void CubemapTexture::Unbind() const { - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); -} - diff --git a/Nuake/src/Rendering/Textures/Cubemap.h b/Nuake/src/Rendering/Textures/Cubemap.h index 7e977c68..fb83c722 100644 --- a/Nuake/src/Rendering/Textures/Cubemap.h +++ b/Nuake/src/Rendering/Textures/Cubemap.h @@ -2,28 +2,29 @@ #include "stb_image/stb_image.h" #include - -class CubemapTexture +namespace Nuake { -private: - unsigned int m_RendererId; - std::string m_FilePath; - unsigned char* m_LocalBuffer; - int m_Width; - int m_Height; - int m_BPP; // byte per pixel. + class CubemapTexture + { + public: + CubemapTexture(const std::string& path); + void CreateFromHDR(); + ~CubemapTexture(); -public: - CubemapTexture(const std::string& path); - void CreateFromHDR(); - ~CubemapTexture(); + void Bind(unsigned int slot = 0) const; + void Unbind() const; - void Bind(unsigned int slot = 0) const; - void Unbind() const; - - inline int GetWidth() const { return m_Width; } - inline int GetHeight() const { return m_Height; } -}; + inline int GetWidth() const { return m_Width; } + inline int GetHeight() const { return m_Height; } + private: + std::string m_FilePath; + unsigned int m_RendererId; + unsigned char* m_LocalBuffer; + int m_Width; + int m_Height; + int m_BPP; // byte per pixel. + }; +} diff --git a/Nuake/src/Rendering/Textures/HDR.cpp b/Nuake/src/Rendering/Textures/HDR.cpp index a86ee5e3..8e35acd5 100644 --- a/Nuake/src/Rendering/Textures/HDR.cpp +++ b/Nuake/src/Rendering/Textures/HDR.cpp @@ -1,55 +1,66 @@ #include "HDR.h" #include #include -#include "../Renderer.h" +#include "src/Rendering/Renderer.h" -HDRTexture::HDRTexture(const std::string& path) { - m_RendererId = 0; - m_FilePath = path; - m_LocalBuffer = nullptr; - m_Width = 0; - m_Height = 0; - m_BPP = 0; - - stbi_set_flip_vertically_on_load(1); - float* data = stbi_loadf(path.c_str(), &m_Width, &m_Height, &m_BPP, 0); - - if (data) +namespace Nuake +{ + HDRTexture::HDRTexture(const std::string& path) { - glGenTextures(1, &m_RendererId); + m_RendererId = 0; + m_FilePath = path; + m_LocalBuffer = nullptr; + m_Width = 0; + m_Height = 0; + m_BPP = 0; + + stbi_set_flip_vertically_on_load(1); + float* data = stbi_loadf(path.c_str(), &m_Width, &m_Height, &m_BPP, 0); + + if (data) + { + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Width, m_Height, 0, GL_RGB, GL_FLOAT, data); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + stbi_image_free(data); + } + else + { + std::cout << "Failed to load HDR image." << std::endl; + } + } + + HDRTexture::~HDRTexture() + { + glDeleteTextures(1, &m_RendererId); + } + + void HDRTexture::Bind(unsigned int slot) const + { + glActiveTexture(GL_TEXTURE0 + slot); glBindTexture(GL_TEXTURE_2D, m_RendererId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, m_Width, m_Height, 0, GL_RGB, GL_FLOAT, data); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - stbi_image_free(data); } - else + + void HDRTexture::BindCubemap(unsigned int slot) const { - std::cout << "Failed to load HDR image." << std::endl; + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubemapId); + } + + void HDRTexture::Unbind() const + { + glBindTexture(GL_TEXTURE_2D, 0); + } + + void HDRTexture::GenerateCubeMap() + { + } } -HDRTexture::~HDRTexture() { - glDeleteTextures(1, &m_RendererId); -} - -void HDRTexture::Bind(unsigned int slot) const { - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(GL_TEXTURE_2D, m_RendererId); -} -void HDRTexture::BindCubemap(unsigned int slot) const { - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubemapId); -} - -void HDRTexture::Unbind() const { - glBindTexture(GL_TEXTURE_2D, 0); -} - -void HDRTexture::GenerateCubeMap() { - -} diff --git a/Nuake/src/Rendering/Textures/HDR.h b/Nuake/src/Rendering/Textures/HDR.h index 997f39f6..71910e44 100644 --- a/Nuake/src/Rendering/Textures/HDR.h +++ b/Nuake/src/Rendering/Textures/HDR.h @@ -2,34 +2,33 @@ #include "stb_image/stb_image.h" #include - -class HDRTexture +namespace Nuake { -private: - unsigned int m_RendererId; - std::string m_FilePath; - unsigned char* m_LocalBuffer; - int m_Width; - int m_Height; - int m_BPP; // byte per pixel. - unsigned int m_CubemapId; + class HDRTexture + { + private: + unsigned int m_RendererId; + std::string m_FilePath; + unsigned char* m_LocalBuffer; + int m_Width; + int m_Height; + int m_BPP; // byte per pixel. + unsigned int m_CubemapId; -public: - HDRTexture(const std::string& path); - ~HDRTexture(); + public: + HDRTexture(const std::string& path); + ~HDRTexture(); - void Bind(unsigned int slot = 0) const; - void BindCubemap(unsigned int slot = 0) const; - void Unbind() const; - - inline int GetWidth() const { return m_Width; } - inline int GetHeight() const { return m_Height; } - - void GenerateCubeMap(); - - void SetCubemapId(unsigned int id) { m_CubemapId = id; } - unsigned int GetCubemapId() { return m_CubemapId; } -}; + void Bind(unsigned int slot = 0) const; + void BindCubemap(unsigned int slot = 0) const; + void Unbind() const; + inline int GetWidth() const { return m_Width; } + inline int GetHeight() const { return m_Height; } + void GenerateCubeMap(); + void SetCubemapId(unsigned int id) { m_CubemapId = id; } + unsigned int GetCubemapId() { return m_CubemapId; } + }; +} diff --git a/Nuake/src/Rendering/Textures/Material.cpp b/Nuake/src/Rendering/Textures/Material.cpp index 282d42ec..c16c6f60 100644 --- a/Nuake/src/Rendering/Textures/Material.cpp +++ b/Nuake/src/Rendering/Textures/Material.cpp @@ -1,189 +1,181 @@ - - #include "../Core/MaterialManager.h" #include "Material.h" -#include -#include "../Renderer.h" + +#include "src/Core/Maths.h" +#include "src/Rendering/Renderer.h" + #include #include #include #include -#include -Ref Material::m_DefaultAlbedo; -Ref Material::m_DefaultAO; -Ref Material::m_DefaultNormal; -Ref Material::m_DefaultRoughness; -Ref Material::m_DefaultMetalness; -Ref Material::m_DefaultDisplacement; +#include -Material::Material(const std::string albedo) +namespace Nuake { - glGenBuffers(1, &UBO); - glBindBuffer(GL_UNIFORM_BUFFER, UBO); - glBufferData(GL_UNIFORM_BUFFER, sizeof(UBOStructure), NULL, GL_STATIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); + Ref Material::m_DefaultAlbedo; + Ref Material::m_DefaultAO; + Ref Material::m_DefaultNormal; + Ref Material::m_DefaultRoughness; + Ref Material::m_DefaultMetalness; + Ref Material::m_DefaultDisplacement; - m_Albedo = TextureManager::Get()->GetTexture(albedo); - data.u_HasAlbedo = 1; + Material::Material(const std::string albedo) + { + glGenBuffers(1, &UBO); + glBindBuffer(GL_UNIFORM_BUFFER, UBO); + glBufferData(GL_UNIFORM_BUFFER, sizeof(UBOStructure), NULL, GL_STATIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); - std::stringstream ss(albedo); - std::string item; - std::vector elems; - while (std::getline(ss, item, '/')) { - elems.push_back(item); - // elems.push_back(std::move(item)); // if C++11 (based on comment from @mchiasson) + m_Albedo = TextureManager::Get()->GetTexture(albedo); + + data.u_HasAlbedo = 1; + + std::stringstream ss(albedo); + std::string item; + std::vector elems; + while (std::getline(ss, item, '/')) + { + elems.push_back(item); + } + + m_Name = albedo; + + if (m_DefaultAO == nullptr) + m_DefaultAO = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + if (m_DefaultNormal == nullptr) + m_DefaultNormal = TextureManager::Get()->GetTexture("resources/Textures/default/defaultNormal.png"); + if (m_DefaultDisplacement == nullptr) + m_DefaultDisplacement = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + if (m_DefaultRoughness == nullptr) + m_DefaultRoughness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + if (m_DefaultMetalness == nullptr) + m_DefaultMetalness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); } - m_Name = albedo; - if (m_DefaultAO == nullptr) - m_DefaultAO = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); - if (m_DefaultNormal == nullptr) - m_DefaultNormal = TextureManager::Get()->GetTexture("resources/Textures/default/defaultNormal.png"); - if (m_DefaultDisplacement == nullptr) - m_DefaultDisplacement = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); - if (m_DefaultRoughness == nullptr) - m_DefaultRoughness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); - if (m_DefaultMetalness == nullptr) - m_DefaultMetalness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + Material::Material(const glm::vec3 albedoColor) + { + glGenBuffers(1, &UBO); + glBindBuffer(GL_UNIFORM_BUFFER, UBO); + glBufferData(GL_UNIFORM_BUFFER, 128, NULL, GL_STATIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + + data.m_AlbedoColor = Vector3{ albedoColor.r, albedoColor.g, albedoColor.b }; + + m_Name = "New material"; + + if (m_DefaultAlbedo == nullptr) + m_DefaultAlbedo = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + + m_Albedo = m_DefaultAlbedo; + + if (m_DefaultAO == nullptr) + m_DefaultAO = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + if (m_DefaultNormal == nullptr) + m_DefaultNormal = TextureManager::Get()->GetTexture("resources/Textures/default/defaultNormal.png"); + if (m_DefaultDisplacement == nullptr) + m_DefaultDisplacement = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + if (m_DefaultRoughness == nullptr) + m_DefaultRoughness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + if (m_DefaultMetalness == nullptr) + m_DefaultMetalness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); + } + + Material::~Material() {} + + void Material::Bind() + { + if (MaterialManager::Get()->CurrentlyBoundedMaterial == m_Name) + return; + + MaterialManager::Get()->CurrentlyBoundedMaterial = m_Name; + glBindBuffer(GL_UNIFORM_BUFFER, UBO); + + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UBOStructure), &data); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + glBindBufferBase(GL_UNIFORM_BUFFER, 32, UBO); + + // Albedo + if (m_Albedo != nullptr) + m_Albedo->Bind(4); + else + m_DefaultAlbedo->Bind(4); + Renderer::m_Shader->SetUniform1i("m_Albedo", 4); + + // AO + if (m_AO != nullptr) + m_AO->Bind(5); + else + m_DefaultAO->Bind(5); + Renderer::m_Shader->SetUniform1i("m_AO", 5); + + // Metallic + if (m_Metalness != nullptr) + m_Metalness->Bind(6); + else + m_DefaultMetalness->Bind(6); + Renderer::m_Shader->SetUniform1i("m_Metalness", 6); + + // Roughness + if (m_Roughness != nullptr) + m_Roughness->Bind(7); + else + m_DefaultRoughness->Bind(7); + Renderer::m_Shader->SetUniform1i("m_Roughness", 7); + + // Normal + if (m_Normal != nullptr) + m_Normal->Bind(8); + else + m_DefaultNormal->Bind(8); + Renderer::m_Shader->SetUniform1i("m_Normal", 8); + + // Displacement + if (m_Displacement != nullptr) + m_Displacement->Bind(9); + else + m_DefaultDisplacement->Bind(9); + //Renderer::m_Shader->SetUniform1i("m_Displacement", 9); + //Renderer::m_Shader->SetUniform1i("m_Displacement", 9); + } + + void Material::SetupUniformBuffer() + { + } + + void Material::SetName(const std::string name) + { + m_Name = name; + } + + std::string Material::GetName() { return m_Name; } + + + void Material::SetAO(const std::string ao) + { + m_AO = CreateRef(ao); + } + + void Material::SetMetalness(const std::string metalness) + { + m_Metalness = CreateRef(metalness); + } + + void Material::SetRoughness(const std::string roughness) + { + m_Roughness = CreateRef(roughness); + } + + void Material::SetNormal(const std::string normal) + { + m_Normal = CreateRef(normal); + } + + void Material::SetDisplacement(const std::string displacement) + { + m_Displacement = CreateRef(displacement); + } } -//Material::Material() -//{ -//} - -Material::Material(const glm::vec3 albedoColor) -{ - glGenBuffers(1, &UBO); - glBindBuffer(GL_UNIFORM_BUFFER, UBO); - glBufferData(GL_UNIFORM_BUFFER, 128, NULL, GL_STATIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - - data.m_AlbedoColor = Vector3{ albedoColor.r, albedoColor.g, albedoColor.b}; - - m_Name = "New material"; - - if (m_DefaultAlbedo == nullptr) - m_DefaultAlbedo = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); - - m_Albedo = m_DefaultAlbedo; - - if (m_DefaultAO == nullptr) - m_DefaultAO = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); - if (m_DefaultNormal == nullptr) - m_DefaultNormal = TextureManager::Get()->GetTexture("resources/Textures/default/defaultNormal.png"); - if (m_DefaultDisplacement == nullptr) - m_DefaultDisplacement = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); - if (m_DefaultRoughness == nullptr) - m_DefaultRoughness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); - if (m_DefaultMetalness == nullptr) - m_DefaultMetalness = TextureManager::Get()->GetTexture("resources/Textures/default/Default.png"); -} - -Material::~Material() {} - -void Material::Bind() -{ - if (MaterialManager::Get()->CurrentlyBoundedMaterial == m_Name) - return; - - MaterialManager::Get()->CurrentlyBoundedMaterial = m_Name; - glBindBuffer(GL_UNIFORM_BUFFER, UBO); - - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UBOStructure), &data); - //glBufferSubData(GL_UNIFORM_BUFFER, 0, 4, &data.u_HasAlbedo); - // - //glBufferSubData(GL_UNIFORM_BUFFER, 16, 12, &data.m_AlbedoColor); - // - //glBufferSubData(GL_UNIFORM_BUFFER, 28, 4, &data.u_HasMetalness); - //glBufferSubData(GL_UNIFORM_BUFFER, 32, 4, &data.u_MetalnessValue); - //glBufferSubData(GL_UNIFORM_BUFFER, 36, 4, &data.u_HasRoughness); - //glBufferSubData(GL_UNIFORM_BUFFER, 40, 4, &data.u_RoughnessValue); - // - //glBufferSubData(GL_UNIFORM_BUFFER, 44, 4, &data.u_HasAO); - //glBufferSubData(GL_UNIFORM_BUFFER, 48, 4, &data.u_AOValue); - //glBufferSubData(GL_UNIFORM_BUFFER, 52, 4, &data.u_HasNormal); - //glBufferSubData(GL_UNIFORM_BUFFER, 56, 4, &data.u_HasDisplacement); - - glBindBuffer(GL_UNIFORM_BUFFER, 0); - glBindBufferBase(GL_UNIFORM_BUFFER, 32, UBO); - - // Albedo - if (m_Albedo != nullptr) - m_Albedo->Bind(4); - else - m_DefaultAlbedo->Bind(4); - Renderer::m_Shader->SetUniform1i("m_Albedo", 4); - - // AO - if (m_AO != nullptr) - m_AO->Bind(5); - else - m_DefaultAO->Bind(5); - Renderer::m_Shader->SetUniform1i("m_AO", 5); - - // Metallic - if (m_Metalness != nullptr) - m_Metalness->Bind(6); - else - m_DefaultMetalness->Bind(6); - Renderer::m_Shader->SetUniform1i("m_Metalness", 6); - - // Roughness - if (m_Roughness != nullptr) - m_Roughness->Bind(7); - else - m_DefaultRoughness->Bind(7); - Renderer::m_Shader->SetUniform1i("m_Roughness", 7); - - // Normal - if (m_Normal != nullptr) - m_Normal->Bind(8); - else - m_DefaultNormal->Bind(8); - Renderer::m_Shader->SetUniform1i("m_Normal", 8); - - // Displacement - if (m_Displacement != nullptr) - m_Displacement->Bind(9); - else - m_DefaultDisplacement->Bind(9); - //Renderer::m_Shader->SetUniform1i("m_Displacement", 9); - //Renderer::m_Shader->SetUniform1i("m_Displacement", 9); -} - -void Material::SetupUniformBuffer() -{ -} - -void Material::SetName(const std::string name) -{ - m_Name = name; -} - -std::string Material::GetName() { return m_Name; } - - -void Material::SetAO(const std::string ao) -{ - m_AO = CreateRef(ao); -} -void Material::SetMetalness(const std::string metalness) -{ - m_Metalness = CreateRef(metalness); -} -void Material::SetRoughness(const std::string roughness) -{ - m_Roughness = CreateRef(roughness); -} -void Material::SetNormal(const std::string normal) -{ - m_Normal = CreateRef(normal); -} - -void Material::SetDisplacement(const std::string displacement) -{ - m_Displacement = CreateRef(displacement); -} diff --git a/Nuake/src/Rendering/Textures/Material.h b/Nuake/src/Rendering/Textures/Material.h index fc30b83e..cc3c349e 100644 --- a/Nuake/src/Rendering/Textures/Material.h +++ b/Nuake/src/Rendering/Textures/Material.h @@ -1,103 +1,100 @@ #pragma once -#include "../../Core/TextureManager.h" +#include "src/Core/TextureManager.h" #include "Texture.h" -#include -#include -#include "../Core/Core.h" +#include "src/Core/Core.h" +#include "src/Core/Maths.h" -struct myVec3 { - float r; - float g; - float b; -}; - -struct UBOStructure { - int u_HasAlbedo; - float padding; - float padding2; - float padding3; - glm::vec3 m_AlbedoColor; - int u_HasMetalness; - float u_MetalnessValue; - int u_HasRoughness; - float u_RoughnessValue; - int u_HasAO; - float u_AOValue; - int u_HasNormal; - int u_HasDisplacement; -}; - -class Material +namespace Nuake { -private: - std::string m_Name; - unsigned int UBO; -public: - Ref m_Albedo; - Ref m_AO; - Ref m_Metalness; - Ref m_Roughness; - Ref m_Normal; - Ref m_Displacement; - - UBOStructure data{ - 0, // has labedo - 0, // padding - 0, // padding - 0, // padding - glm::vec3{0.f, 0.f, 0.f}, // m_AlbedoColor - 0, // u_HasMetalness - 0.5f, // u_MetalnessValue - 0, // u_HasRoughness - 0.5f, // u_RoughnessValue - 0, // u_HasAO - 0.5f, // u_AOValue - 0, // u_HasNormal - 0 // u_HasDisplacement + struct UBOStructure { + int u_HasAlbedo; + float padding; + float padding2; + float padding3; + Vector3 m_AlbedoColor; + int u_HasMetalness; + float u_MetalnessValue; + int u_HasRoughness; + float u_RoughnessValue; + int u_HasAO; + float u_AOValue; + int u_HasNormal; + int u_HasDisplacement; }; - static Ref m_DefaultAlbedo; - static Ref m_DefaultAO; - static Ref m_DefaultMetalness; - static Ref m_DefaultRoughness; - static Ref m_DefaultNormal; - static Ref m_DefaultDisplacement; + class Material + { + private: + std::string m_Name; + unsigned int UBO; + public: + Ref m_Albedo; + Ref m_AO; + Ref m_Metalness; + Ref m_Roughness; + Ref m_Normal; + Ref m_Displacement; - Material(const std::string albedo); - Material(Ref texture) { m_Albedo = texture; } - Material(const glm::vec3 albedoColor); + UBOStructure data + { + 0, // Has albedo texture + 0, // Padding byte + 0, // Padding byte + 0, // Padding byte + Vector3(0.f, 0.f, 0.f), // Albedo color + 0, // Has metalness + 0.5f, // Metalness value + 0, // u_HasRoughness + 0.5f, // u_RoughnessValue + 0, // u_HasAO + 0.5f, // u_AOValue + 0, // u_HasNormal + 0 // u_HasDisplacement + }; - ~Material(); + static Ref m_DefaultAlbedo; + static Ref m_DefaultAO; + static Ref m_DefaultMetalness; + static Ref m_DefaultRoughness; + static Ref m_DefaultNormal; + static Ref m_DefaultDisplacement; - void Bind(); + Material(const std::string albedo); + Material(Ref texture) { m_Albedo = texture; } + Material(const glm::vec3 albedoColor); - void SetupUniformBuffer(); + ~Material(); - void SetName(const std::string name); - std::string GetName(); + void Bind(); - bool HasAlbedo() { return m_Albedo != nullptr; } - void SetAlbedo(const std::string path) { m_Albedo = CreateRef(path); } - void SetAlbedo(Ref texture) { m_Albedo = texture; } + void SetupUniformBuffer(); - bool HasAO() { return m_AO != nullptr; } - void SetAO(const std::string albedo); - void SetAO(Ref texture) { m_AO = texture; } + void SetName(const std::string name); + std::string GetName(); - bool HasMetalness() { return m_Metalness != nullptr; } - void SetMetalness(const std::string albedo); - void SetMetalness(Ref texture) { m_Metalness = texture; } + bool HasAlbedo() { return m_Albedo != nullptr; } + void SetAlbedo(const std::string path) { m_Albedo = CreateRef(path); } + void SetAlbedo(Ref texture) { m_Albedo = texture; } - bool HasRougness() { return m_Roughness != nullptr; } - void SetRoughness(const std::string albedo); - void SetRoughness(Ref texture) { m_Roughness = texture; } + bool HasAO() { return m_AO != nullptr; } + void SetAO(const std::string albedo); + void SetAO(Ref texture) { m_AO = texture; } - bool HasNormal() { return m_Normal != nullptr; } - void SetNormal(const std::string albedo); - void SetNormal(Ref texture) { m_Normal = texture; } + bool HasMetalness() { return m_Metalness != nullptr; } + void SetMetalness(const std::string albedo); + void SetMetalness(Ref texture) { m_Metalness = texture; } - bool HasDisplacement() { return m_Displacement != nullptr; } - void SetDisplacement(const std::string displacement); - void SetDisplacement(Ref texture) { m_Displacement = texture; } -}; \ No newline at end of file + bool HasRougness() { return m_Roughness != nullptr; } + void SetRoughness(const std::string albedo); + void SetRoughness(Ref texture) { m_Roughness = texture; } + + bool HasNormal() { return m_Normal != nullptr; } + void SetNormal(const std::string albedo); + void SetNormal(Ref texture) { m_Normal = texture; } + + bool HasDisplacement() { return m_Displacement != nullptr; } + void SetDisplacement(const std::string displacement); + void SetDisplacement(Ref texture) { m_Displacement = texture; } + }; +} diff --git a/Nuake/src/Rendering/Textures/MultiSampledTexture.cpp b/Nuake/src/Rendering/Textures/MultiSampledTexture.cpp index ad314908..6634b608 100644 --- a/Nuake/src/Rendering/Textures/MultiSampledTexture.cpp +++ b/Nuake/src/Rendering/Textures/MultiSampledTexture.cpp @@ -2,100 +2,108 @@ #include #include -MultiSampledTexture::MultiSampledTexture(const std::string& path) { - m_RendererId = 0; - m_FilePath = path; - m_LocalBuffer = nullptr; - m_Width = 0; - m_Height = 0; - m_BPP = 0; - - stbi_set_flip_vertically_on_load(1); - - m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4); - - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId); - glGenerateMipmap(GL_TEXTURE_2D); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f); - //glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE); - glGenerateMipmap(GL_TEXTURE_2D); - if (m_LocalBuffer) - stbi_image_free(m_LocalBuffer); - else - std::cout << "Error: failed to load texture: " << path << std::endl; -} - -// Empty texture not from file. -MultiSampledTexture::MultiSampledTexture(glm::vec2 size, GLenum format) +namespace Nuake { - m_Format = format; + MultiSampledTexture::MultiSampledTexture(const std::string& path) + { + m_RendererId = 0; + m_FilePath = path; + m_LocalBuffer = nullptr; + m_Width = 0; + m_Height = 0; + m_BPP = 0; - m_Width = size.x; - m_Height = size.y; + stbi_set_flip_vertically_on_load(1); - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId); - glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL); - glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glGenerateMipmap(GL_TEXTURE_2D); + m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4); + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId); + glGenerateMipmap(GL_TEXTURE_2D); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f); + //glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE); + glGenerateMipmap(GL_TEXTURE_2D); + if (m_LocalBuffer) + stbi_image_free(m_LocalBuffer); + else + std::cout << "Error: failed to load texture: " << path << std::endl; + } + + // Empty texture not from file. + MultiSampledTexture::MultiSampledTexture(glm::vec2 size, GLenum format) + { + m_Format = format; + + m_Width = size.x; + m_Height = size.y; + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId); + glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL); + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + } + + + MultiSampledTexture::MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t) + { + m_Width = size.x; + m_Height = size.y; + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + + auto pixel = bitmap(0, bitmap.height - 0 - 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels); + } + + void MultiSampledTexture::Resize(glm::vec2 size) + { + glDeleteTextures(1, &m_RendererId); + m_Width = size.x; + m_Height = size.y; + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + MultiSampledTexture::~MultiSampledTexture() + { + glDeleteTextures(1, &m_RendererId); + } + + void MultiSampledTexture::AttachToFramebuffer(GLenum attachment) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE, m_RendererId, 0); + + //glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0); + } + + + void MultiSampledTexture::Bind(unsigned int slot) const + { + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + } + + void MultiSampledTexture::Unbind() const + { + glBindTexture(GL_TEXTURE_2D, 0); + } } -MultiSampledTexture::MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t) -{ - m_Width = size.x; - m_Height = size.y; - - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_2D, m_RendererId); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - - auto pixel = bitmap(0, bitmap.height - 0 - 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels); -} - -void MultiSampledTexture::Resize(glm::vec2 size) -{ - glDeleteTextures(1, &m_RendererId); - m_Width = size.x; - m_Height = size.y; - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_2D, m_RendererId); - glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -} - -MultiSampledTexture::~MultiSampledTexture() { - glDeleteTextures(1, &m_RendererId); -} - -void MultiSampledTexture::AttachToFramebuffer(GLenum attachment) -{ - glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE, m_RendererId, 0); - - //glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0); -} - - -void MultiSampledTexture::Bind(unsigned int slot) const { - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(GL_TEXTURE_2D, m_RendererId); -} - -void MultiSampledTexture::Unbind() const { - glBindTexture(GL_TEXTURE_2D, 0); -} - diff --git a/Nuake/src/Rendering/Textures/MultiSampledTexture.h b/Nuake/src/Rendering/Textures/MultiSampledTexture.h index 0e6e881b..90c93dc9 100644 --- a/Nuake/src/Rendering/Textures/MultiSampledTexture.h +++ b/Nuake/src/Rendering/Textures/MultiSampledTexture.h @@ -4,38 +4,37 @@ #include "glm/vec2.hpp" #include "msdfgen/core/BitmapRef.hpp" - -typedef unsigned int GLenum; -class MultiSampledTexture +namespace Nuake { -private: - unsigned int m_RendererId; - std::string m_FilePath; - unsigned char* m_LocalBuffer; - GLenum m_Format; + typedef unsigned int GLenum; + class MultiSampledTexture + { + private: + unsigned int m_RendererId; + std::string m_FilePath; + unsigned char* m_LocalBuffer; + GLenum m_Format; - int m_Width; - int m_Height; - int m_BPP; // byte per pixel. + int m_Width; + int m_Height; + int m_BPP; // byte per pixel. -public: - MultiSampledTexture(const std::string& path); - MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t); - MultiSampledTexture(glm::vec2 size, GLenum format); + public: + MultiSampledTexture(const std::string& path); + MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t); + MultiSampledTexture(glm::vec2 size, GLenum format); - ~MultiSampledTexture(); + ~MultiSampledTexture(); - void Resize(glm::vec2 size); - void AttachToFramebuffer(GLenum attachment); - - void Bind(unsigned int slot = 0) const; - void Unbind() const; - - unsigned int GetID() const { return m_RendererId; } - - inline int GetWidth() const { return m_Width; } - inline int GetHeight() const { return m_Height; } -}; + void Resize(glm::vec2 size); + void AttachToFramebuffer(GLenum attachment); + void Bind(unsigned int slot = 0) const; + void Unbind() const; + unsigned int GetID() const { return m_RendererId; } + inline int GetWidth() const { return m_Width; } + inline int GetHeight() const { return m_Height; } + }; +} \ No newline at end of file diff --git a/Nuake/src/Rendering/Textures/Texture.cpp b/Nuake/src/Rendering/Textures/Texture.cpp index ede23986..d9b6de70 100644 --- a/Nuake/src/Rendering/Textures/Texture.cpp +++ b/Nuake/src/Rendering/Textures/Texture.cpp @@ -3,94 +3,100 @@ #include #include -Texture::Texture(const std::string& path) { - m_RendererId = 0; - m_FilePath = path; - m_LocalBuffer = nullptr; - m_Width = 0; - m_Height = 0; - m_BPP = 0; - - stbi_set_flip_vertically_on_load(1); - - m_LocalBuffer = stbi_load((path).c_str(), &m_Width, &m_Height, &m_BPP, 4); - - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_2D, m_RendererId); - glGenerateMipmap(GL_TEXTURE_2D); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer); - glGenerateMipmap(GL_TEXTURE_2D); - if (m_LocalBuffer) - stbi_image_free(m_LocalBuffer); - else - std::cout << "Error: failed to load texture: " << path << std::endl; -} - -// Empty texture not from file. -Texture::Texture(glm::vec2 size, GLenum format) +namespace Nuake { - m_Format = format; + Texture::Texture(const std::string& path) + { + m_RendererId = 0; + m_FilePath = path; + m_LocalBuffer = nullptr; + m_Width = 0; + m_Height = 0; + m_BPP = 0; - m_Width = size.x; - m_Height = size.y; + stbi_set_flip_vertically_on_load(1); - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_2D, m_RendererId); - glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - //glGenerateMipmap(GL_TEXTURE_2D); -} - -Texture::Texture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t) -{ - m_Width = size.x; - m_Height = size.y; - - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_2D, m_RendererId); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - - auto pixel = bitmap(0, bitmap.height - 0 - 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels); -} - -void Texture::Resize(glm::vec2 size) -{ - glDeleteTextures(1, &m_RendererId); - m_Width = size.x; - m_Height = size.y; - glGenTextures(1, &m_RendererId); - glBindTexture(GL_TEXTURE_2D, m_RendererId); - glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -} - -Texture::~Texture() { - glDeleteTextures(1, &m_RendererId); -} - -void Texture::AttachToFramebuffer(GLenum attachment) -{ - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0); -} - -void Texture::Bind(unsigned int slot) const { - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(GL_TEXTURE_2D, m_RendererId); -} - -void Texture::Unbind() const { - glBindTexture(GL_TEXTURE_2D, 0); + m_LocalBuffer = stbi_load((path).c_str(), &m_Width, &m_Height, &m_BPP, 4); + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + glGenerateMipmap(GL_TEXTURE_2D); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -1.0f); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer); + glGenerateMipmap(GL_TEXTURE_2D); + if (m_LocalBuffer) + stbi_image_free(m_LocalBuffer); + else + std::cout << "Error: failed to load texture: " << path << std::endl; + } + + Texture::Texture(glm::vec2 size, GLenum format) + { + m_Format = format; + + m_Width = size.x; + m_Height = size.y; + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + //glGenerateMipmap(GL_TEXTURE_2D); + } + + Texture::Texture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t) + { + m_Width = size.x; + m_Height = size.y; + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + + auto pixel = bitmap(0, bitmap.height - 0 - 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels); + } + + void Texture::Resize(glm::vec2 size) + { + glDeleteTextures(1, &m_RendererId); + m_Width = size.x; + m_Height = size.y; + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + Texture::~Texture() + { + glDeleteTextures(1, &m_RendererId); + } + + void Texture::AttachToFramebuffer(GLenum attachment) + { + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0); + } + + void Texture::Bind(unsigned int slot) const + { + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + } + + void Texture::Unbind() const + { + glBindTexture(GL_TEXTURE_2D, 0); + } } diff --git a/Nuake/src/Rendering/Textures/Texture.h b/Nuake/src/Rendering/Textures/Texture.h index 679eda17..c7bf1b44 100644 --- a/Nuake/src/Rendering/Textures/Texture.h +++ b/Nuake/src/Rendering/Textures/Texture.h @@ -1,41 +1,41 @@ #pragma once #include "stb_image/stb_image.h" #include -#include "glm/vec2.hpp" +#include "src/Core/Maths.h" #include "msdfgen/core/BitmapRef.hpp" - -typedef unsigned int GLenum; -class Texture +namespace Nuake { -private: - unsigned int m_RendererId; - std::string m_FilePath; - unsigned char* m_LocalBuffer; - GLenum m_Format; + typedef unsigned int GLenum; - int m_Width; - int m_Height; - int m_BPP; // byte per pixel. + class Texture + { + private: + unsigned int m_RendererId; + std::string m_FilePath; + unsigned char* m_LocalBuffer; + GLenum m_Format; -public: - Texture(const std::string& path); - Texture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t); - Texture(glm::vec2 size, GLenum format); + int m_Width; + int m_Height; + int m_BPP; // byte per pixel. - ~Texture(); + public: + Texture(const std::string& path); + Texture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t); + Texture(glm::vec2 size, GLenum format); - void Resize(glm::vec2 size); - void AttachToFramebuffer(GLenum attachment); + ~Texture(); - void Bind(unsigned int slot = 0) const; - void Unbind() const; - - unsigned int GetID() const { return m_RendererId; } - - inline int GetWidth() const { return m_Width; } - inline int GetHeight() const { return m_Height; } -}; + void Resize(glm::vec2 size); + void AttachToFramebuffer(GLenum attachment); + void Bind(unsigned int slot = 0) const; + void Unbind() const; + unsigned int GetID() const { return m_RendererId; } + inline int GetWidth() const { return m_Width; } + inline int GetHeight() const { return m_Height; } + }; +} diff --git a/Nuake/src/Rendering/Transform.h b/Nuake/src/Rendering/Transform.h new file mode 100644 index 00000000..96c78a42 --- /dev/null +++ b/Nuake/src/Rendering/Transform.h @@ -0,0 +1,12 @@ +#pragma once +#include + +namespace Nuake +{ + struct Transform + { + Vector3 Translation; + Vector3 Rotation; + Vector3 Scale; + }; +} diff --git a/Nuake/src/Rendering/Vertex.h b/Nuake/src/Rendering/Vertex.h index 0795291d..95f2e723 100644 --- a/Nuake/src/Rendering/Vertex.h +++ b/Nuake/src/Rendering/Vertex.h @@ -1,13 +1,16 @@ #pragma once -#include -#include +#include "src/Core/Maths.h" -struct Vertex +namespace Nuake { - glm::vec3 position; - glm::vec2 uv; - glm::vec3 normal; - glm::vec3 tangent; - glm::vec3 bitangent; - float texture; -}; + struct Vertex + { + glm::vec3 position; + glm::vec2 uv; + glm::vec3 normal; + glm::vec3 tangent; + glm::vec3 bitangent; + float texture; + }; +} + diff --git a/Nuake/src/Resource/FGD/BrushClass.h b/Nuake/src/Resource/FGD/BrushClass.h index 14d307c2..45a3599b 100644 --- a/Nuake/src/Resource/FGD/BrushClass.h +++ b/Nuake/src/Resource/FGD/BrushClass.h @@ -1,5 +1,4 @@ #pragma once -#include "BaseClass.h" #include "ClassProperty.h" #include #include diff --git a/Nuake/src/Resource/FGD/FDGSerializer.h b/Nuake/src/Resource/FGD/FDGSerializer.h index 55a2885f..7e6c7c43 100644 --- a/Nuake/src/Resource/FGD/FDGSerializer.h +++ b/Nuake/src/Resource/FGD/FDGSerializer.h @@ -1,12 +1,15 @@ #pragma once #include "FGDClass.h" #include -class FGDSerializer -{ -public: - static bool BeginFGDFile(const std::string path); - static bool SerializeClass(FGDClass fgdClass); - static bool SerializeBrush(FGDBrushEntity fgdClass); - static bool EndFGDFile(); -}; \ No newline at end of file +namespace Nuake { + class FGDSerializer + { + public: + static bool BeginFGDFile(const std::string path); + + static bool SerializeClass(FGDClass fgdClass); + static bool SerializeBrush(FGDBrushEntity fgdClass); + static bool EndFGDFile(); + }; +} diff --git a/Nuake/src/Resource/FGD/FGDClass.cpp b/Nuake/src/Resource/FGD/FGDClass.cpp index 66a9ab94..fc332779 100644 --- a/Nuake/src/Resource/FGD/FGDClass.cpp +++ b/Nuake/src/Resource/FGD/FGDClass.cpp @@ -1,26 +1,28 @@ #include "FGDClass.h" - -FGDClass::FGDClass(FGDClassType type, const std::string& name, const std::string& desc) -{ - Type = type; - Name = name; - Description = desc; -} - -void FGDClass::AddProperty(ClassProperty prop) -{ - Properties.push_back(prop); -} - -void FGDClass::RemoveProperty(const std::string name) -{ - int position = 0; - for (auto& p : Properties) +namespace Nuake { + FGDClass::FGDClass(FGDClassType type, const std::string& name, const std::string& desc) { - if (p.name == name) - Properties.erase(Properties.begin() + position); + Type = type; + Name = name; + Description = desc; + } - position++; + void FGDClass::AddProperty(ClassProperty prop) + { + Properties.push_back(prop); + } + + void FGDClass::RemoveProperty(const std::string name) + { + int position = 0; + for (auto& p : Properties) + { + if (p.name == name) + Properties.erase(Properties.begin() + position); + + position++; + } } } + diff --git a/Nuake/src/Resource/FGD/FGDClass.h b/Nuake/src/Resource/FGD/FGDClass.h index 9f3a402e..157690bc 100644 --- a/Nuake/src/Resource/FGD/FGDClass.h +++ b/Nuake/src/Resource/FGD/FGDClass.h @@ -4,56 +4,56 @@ #include #include - -class FGDBaseEntity -{ -public: - std::string Name; - std::vector Properties; -}; - - -class FGDBrushEntity : ISerializable -{ -public: - std::string Name; - std::string Description; - - bool Visible = false; - bool Solid = false; - bool IsTrigger = false; - std::string Script = ""; - std::string Class = ""; - std::vector Properties; - - FGDBrushEntity() +namespace Nuake { + class FGDBaseEntity { - Name = ""; - Description = ""; - } + public: + std::string Name; + std::vector Properties; + }; - FGDBrushEntity(const std::string& name) - { - Name = name; - Description = ""; - } - json Serialize() override + class FGDBrushEntity : ISerializable { - BEGIN_SERIALIZE(); + public: + std::string Name; + std::string Description; + + bool Visible = false; + bool Solid = false; + bool IsTrigger = false; + std::string Script = ""; + std::string Class = ""; + std::vector Properties; + + FGDBrushEntity() + { + Name = ""; + Description = ""; + } + + FGDBrushEntity(const std::string& name) + { + Name = name; + Description = ""; + } + + json Serialize() override + { + BEGIN_SERIALIZE(); SERIALIZE_VAL(Name); SERIALIZE_VAL(Description); - SERIALIZE_VAL(Visible); + SERIALIZE_VAL(Visible); SERIALIZE_VAL(Solid); SERIALIZE_VAL(IsTrigger); SERIALIZE_VAL(Script); SERIALIZE_VAL(Class); - END_SERIALIZE(); - } + END_SERIALIZE(); + } - bool Deserialize(const std::string& str) override - { - BEGIN_DESERIALIZE(); + bool Deserialize(const std::string& str) override + { + BEGIN_DESERIALIZE(); Name = j["Name"]; Description = j["Description"]; Visible = j["Visible"]; @@ -61,46 +61,47 @@ public: IsTrigger = j["IsTrigger"]; Script = j["Script"]; Class = j["Class"]; - return true; - } + return true; + } - FGDBaseEntity BaseClass; -}; + FGDBaseEntity BaseClass; + }; -class FGDPointEntity : ISerializable -{ -public: - std::string Name; - std::string Description; - std::string Prefab; - std::vector Properties; - FGDBaseEntity BaseClass; - - json Serialize() override + class FGDPointEntity : ISerializable { - BEGIN_SERIALIZE(); + public: + std::string Name; + std::string Description; + std::string Prefab; + std::vector Properties; + FGDBaseEntity BaseClass; + + json Serialize() override + { + BEGIN_SERIALIZE(); SERIALIZE_VAL(Name); SERIALIZE_VAL(Description); SERIALIZE_VAL(Prefab); - END_SERIALIZE(); - } + END_SERIALIZE(); + } - bool Deserialize(const std::string& str) override - { - return true; - } -}; + bool Deserialize(const std::string& str) override + { + return true; + } + }; -class FGDClass { -public: - FGDClassType Type; - std::string Name; - std::string Description; - std::vector Properties; + class FGDClass { + public: + FGDClassType Type; + std::string Name; + std::string Description; + std::vector Properties; - FGDClass(FGDClassType type, const std::string& name, const std::string& desc); + FGDClass(FGDClassType type, const std::string& name, const std::string& desc); - void AddProperty(ClassProperty prop); - void RemoveProperty(const std::string name); -}; \ No newline at end of file + void AddProperty(ClassProperty prop); + void RemoveProperty(const std::string name); + }; +} diff --git a/Nuake/src/Resource/FGD/FGDFile.cpp b/Nuake/src/Resource/FGD/FGDFile.cpp index eae882db..f16a78eb 100644 --- a/Nuake/src/Resource/FGD/FGDFile.cpp +++ b/Nuake/src/Resource/FGD/FGDFile.cpp @@ -3,96 +3,98 @@ #include #include "Engine.h" -FGDFile::FGDFile(const std::string path) -{ - this->Path = path; +namespace Nuake { + FGDFile::FGDFile(const std::string path) + { + this->Path = path; - this->BaseEntities = std::vector(); - this->BrushEntities = std::vector(); - this->PointEntities = std::vector(); -} + this->BaseEntities = std::vector(); + this->BrushEntities = std::vector(); + this->PointEntities = std::vector(); + } -FGDFile::FGDFile() -{ - this->Path = ""; - this->BaseEntities = std::vector(); - this->BrushEntities = std::vector(); - this->PointEntities = std::vector(); + FGDFile::FGDFile() + { + this->Path = ""; + this->BaseEntities = std::vector(); + this->BrushEntities = std::vector(); + this->PointEntities = std::vector(); - // TODO: Remove this, debugging stuff. - FGDPointEntity newEnt; - newEnt.Name = "Light"; - newEnt.Description = "A Nuake PBR light"; - - this->PointEntities.push_back(newEnt); -} + // TODO: Remove this, debugging stuff. + FGDPointEntity newEnt; + newEnt.Name = "Light"; + newEnt.Description = "A Nuake PBR light"; + + this->PointEntities.push_back(newEnt); + } -bool FGDFile::Save() -{ - // Write to file. - FileSystem::BeginWriteFile(FileSystem::Root + Path); + bool FGDFile::Save() + { + // Write to file. + FileSystem::BeginWriteFile(FileSystem::Root + Path); FileSystem::WriteLine(Serialize().dump(4)); - FileSystem::EndWriteFile(); - - return true; -} - -bool FGDFile::SaveAs() -{ - return false; -} - - -void FGDFile::AddClass(FGDClass fgdClass) -{ - //this->Classes.push_back(fgdClass); -} - - -void FGDFile::RemoveClass(const std::string& name) -{ - //int idx = 0; - //for (auto& c : Classes) - //{ - //if (c.Name == name) - //Classes.erase(Classes.begin() + idx); - - //idx++; - //} -} - - -// Exports the FGD data into an fgd file that Trenchbroom can read. -// Should be exported in the Trenchbroom directory directly. /Games/project_name -bool FGDFile::Export() -{ - Ref project = Engine::GetProject(); - std::string path = project->TrenchbroomPath + "games/" + project->Name + "/" + project->Name + ".fgd"; - - - FGDSerializer::BeginFGDFile(path); - - for (auto& b : BaseEntities) - { + FileSystem::EndWriteFile(); + return true; } - for (auto& p : PointEntities) + bool FGDFile::SaveAs() { - + return false; } - for (auto& b : BrushEntities) + + void FGDFile::AddClass(FGDClass fgdClass) { - FGDSerializer::SerializeBrush(b); + //this->Classes.push_back(fgdClass); } - //for(auto& c : Classes) - // FGDSerializer::SerializeClass(c); - FGDSerializer::EndFGDFile(); + void FGDFile::RemoveClass(const std::string& name) + { + //int idx = 0; + //for (auto& c : Classes) + //{ + //if (c.Name == name) + //Classes.erase(Classes.begin() + idx); - return true; -} \ No newline at end of file + //idx++; + //} + } + + + // Exports the FGD data into an fgd file that Trenchbroom can read. + // Should be exported in the Trenchbroom directory directly. /Games/project_name + bool FGDFile::Export() + { + Ref project = Engine::GetProject(); + std::string path = project->TrenchbroomPath + "games/" + project->Name + "/" + project->Name + ".fgd"; + + + FGDSerializer::BeginFGDFile(path); + + for (auto& b : BaseEntities) + { + + } + + for (auto& p : PointEntities) + { + + } + + for (auto& b : BrushEntities) + { + FGDSerializer::SerializeBrush(b); + } + + //for(auto& c : Classes) + // FGDSerializer::SerializeClass(c); + + FGDSerializer::EndFGDFile(); + + return true; + } +} diff --git a/Nuake/src/Resource/FGD/FGDFile.h b/Nuake/src/Resource/FGD/FGDFile.h index a639aecc..5b8ac105 100644 --- a/Nuake/src/Resource/FGD/FGDFile.h +++ b/Nuake/src/Resource/FGD/FGDFile.h @@ -4,93 +4,95 @@ #include #include -enum class EntityType -{ - Brush, Point, Base, None -}; - -class FGDFile : ISerializable{ -public: - std::string Path; - - std::vector PointEntities; - std::vector BrushEntities; - std::vector BaseEntities; - - FGDFile(const std::string path); - FGDFile(); - - bool Export(); - bool Save(); - bool SaveAs(); - - void AddClass(FGDClass fgdClass); - void RemoveClass(const std::string& name); - - json Serialize() override +namespace Nuake { + enum class EntityType { - BEGIN_SERIALIZE(); - int i = 0; - for (auto& c : this->BrushEntities) - { - j["BrushEntities"][i] = c.Serialize(); - i++; - } + Brush, Point, Base, None + }; - i = 0; - for (auto& c : this->PointEntities) - { - j["PointEntities"][i] = c.Serialize(); - i++; - } - END_SERIALIZE(); - } + class FGDFile : ISerializable { + public: + std::string Path; - bool Deserialize(const std::string& str) - { - BEGIN_DESERIALIZE(); + std::vector PointEntities; + std::vector BrushEntities; + std::vector BaseEntities; - if (j.contains("BrushEntities")) + FGDFile(const std::string path); + FGDFile(); + + bool Export(); + bool Save(); + bool SaveAs(); + + void AddClass(FGDClass fgdClass); + void RemoveClass(const std::string& name); + + json Serialize() override { - for (auto& brush : j["BrushEntities"]) + BEGIN_SERIALIZE(); + int i = 0; + for (auto& c : this->BrushEntities) { - FGDBrushEntity brushEntity = FGDBrushEntity(); - brushEntity.Deserialize(brush.dump()); - BrushEntities.push_back(brushEntity); + j["BrushEntities"][i] = c.Serialize(); + i++; + } + + i = 0; + for (auto& c : this->PointEntities) + { + j["PointEntities"][i] = c.Serialize(); + i++; + } + END_SERIALIZE(); + } + + bool Deserialize(const std::string& str) + { + BEGIN_DESERIALIZE(); + + if (j.contains("BrushEntities")) + { + for (auto& brush : j["BrushEntities"]) + { + FGDBrushEntity brushEntity = FGDBrushEntity(); + brushEntity.Deserialize(brush.dump()); + BrushEntities.push_back(brushEntity); + } + } + + if (j.contains("PointEntities")) + { + + } + + return true; + } + + FGDBrushEntity& GetBrushEntity(const std::string& name) + { + for (auto& b : BrushEntities) + { + if (b.Name == name) + return b; } } - if (j.contains("PointEntities")) + EntityType GetTypeOfEntity(const std::string& className) { + for (auto& b : BrushEntities) + { + if (b.Name == className) + return EntityType::Brush; + } + for (auto& p : PointEntities) + { + if (p.Name == className) + return EntityType::Point; + } + + return EntityType::None; } - - return true; - } - - FGDBrushEntity& GetBrushEntity(const std::string& name) - { - for (auto& b : BrushEntities) - { - if (b.Name == name) - return b; - } - } - - EntityType GetTypeOfEntity(const std::string& className) - { - for (auto& b : BrushEntities) - { - if (b.Name == className) - return EntityType::Brush; - } - - for (auto& p : PointEntities) - { - if (p.Name == className) - return EntityType::Point; - } - - return EntityType::None; - } -}; \ No newline at end of file + }; +} diff --git a/Nuake/src/Resource/FGD/FGDSerializer.cpp b/Nuake/src/Resource/FGD/FGDSerializer.cpp index 0f708834..4a78cbe5 100644 --- a/Nuake/src/Resource/FGD/FGDSerializer.cpp +++ b/Nuake/src/Resource/FGD/FGDSerializer.cpp @@ -1,96 +1,96 @@ #include "FDGSerializer.h" #include +namespace Nuake { + bool FGDSerializer::BeginFGDFile(const std::string path) + { + FileSystem::BeginWriteFile(path); + return true; + } -bool FGDSerializer::BeginFGDFile(const std::string path) -{ - FileSystem::BeginWriteFile(path); - return true; -} + bool FGDSerializer::SerializeClass(FGDClass fgdClass) + { + std::string line = "@"; + if (fgdClass.Type == FGDClassType::Point) + line += "PointClass = "; + else if (fgdClass.Type == FGDClassType::Brush) + line += "SolidClass = "; + else // error. + return true; + line += fgdClass.Name + " : \"" + fgdClass.Description + "\""; -bool FGDSerializer::SerializeClass(FGDClass fgdClass) -{ - std::string line = "@"; + // Exit early + if (fgdClass.Properties.size() == 0) + { + line += " [] \n"; + FileSystem::WriteLine(line); + return true; + } - if (fgdClass.Type == FGDClassType::Point) - line += "PointClass = "; - else if (fgdClass.Type == FGDClassType::Brush) + // Properties here. + line += "\n [ \n"; + for (auto& p : fgdClass.Properties) + { + // E.g: myProp(integer) : "description" + line += " "; // Tabulation + line += p.name; + line += "("; + if (p.type == ClassPropertyType::Integer) + line += "integer"; + line += ") : "; + line += "\"" + p.description + "\""; + line += "\n"; + + } + + line += "]"; + + FileSystem::WriteLine(line); + return true; + } + + bool FGDSerializer::SerializeBrush(FGDBrushEntity fgdClass) + { + std::string line = "@"; line += "SolidClass = "; - else // error. - return true; + line += fgdClass.Name + " : \"" + fgdClass.Description + "\""; - line += fgdClass.Name + " : \"" + fgdClass.Description + "\""; + // Exit early + if (fgdClass.Properties.size() == 0) + { + line += " [] \n"; + FileSystem::WriteLine(line); + return true; + } + + // Properties here. + line += "\n [ \n"; + for (auto& p : fgdClass.Properties) + { + // E.g: myProp(integer) : "description" + line += " "; // Tabulation + line += p.name; + line += "("; + if (p.type == ClassPropertyType::Integer) + line += "integer"; + line += ") : "; + line += "\"" + p.description + "\""; + line += "\n"; + + } + + line += "]"; - // Exit early - if (fgdClass.Properties.size() == 0) - { - line += " [] \n"; FileSystem::WriteLine(line); - return true; + return false; } - // Properties here. - line += "\n [ \n"; - for (auto& p : fgdClass.Properties) + bool FGDSerializer::EndFGDFile() { - // E.g: myProp(integer) : "description" - line += " "; // Tabulation - line += p.name; - line += "("; - if (p.type == ClassPropertyType::Integer) - line += "integer"; - line += ") : "; - line += "\"" + p.description + "\""; - line += "\n"; - + FileSystem::EndWriteFile(); + return false; } - - line += "]"; - - FileSystem::WriteLine(line); - return true; } -bool FGDSerializer::SerializeBrush(FGDBrushEntity fgdClass) -{ - std::string line = "@"; - line += "SolidClass = "; - line += fgdClass.Name + " : \"" + fgdClass.Description + "\""; - - // Exit early - if (fgdClass.Properties.size() == 0) - { - line += " [] \n"; - FileSystem::WriteLine(line); - return true; - } - - // Properties here. - line += "\n [ \n"; - for (auto& p : fgdClass.Properties) - { - // E.g: myProp(integer) : "description" - line += " "; // Tabulation - line += p.name; - line += "("; - if (p.type == ClassPropertyType::Integer) - line += "integer"; - line += ") : "; - line += "\"" + p.description + "\""; - line += "\n"; - - } - - line += "]"; - - FileSystem::WriteLine(line); - return false; -} - -bool FGDSerializer::EndFGDFile() -{ - FileSystem::EndWriteFile(); - return false; -} diff --git a/Nuake/src/Resource/Project.cpp b/Nuake/src/Resource/Project.cpp index dd087bca..89d23b63 100644 --- a/Nuake/src/Resource/Project.cpp +++ b/Nuake/src/Resource/Project.cpp @@ -4,138 +4,143 @@ #include #include #include "../Core/Logger.h" -Project::Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath ) -{ - this->Name = Name; - this->Description = Description; - this->FullPath = FullPath; - this->TrenchbroomPath = ""; - if (defaultScenePath != "") +namespace Nuake +{ + Project::Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath) { - Ref scene = CreateRef(); - scene->Deserialize(defaultScenePath); + this->Name = Name; + this->Description = Description; + this->FullPath = FullPath; + this->TrenchbroomPath = ""; + + if (defaultScenePath != "") + { + Ref scene = CreateRef(); + scene->Deserialize(defaultScenePath); + } + + this->EntityDefinitionsFile = CreateRef(); + + SaveAs(FullPath); } - this->EntityDefinitionsFile = CreateRef(); + Project::Project() + { + this->Name = ""; + this->Description = ""; + this->FullPath = ""; + this->TrenchbroomPath = ""; - SaveAs(FullPath); -} + this->EntityDefinitionsFile = CreateRef(); + } -Project::Project() -{ - this->Name = ""; - this->Description = ""; - this->FullPath = ""; - this->TrenchbroomPath = ""; + void Project::Save() + { + SaveAs(this->FullPath); + } - this->EntityDefinitionsFile = CreateRef(); -} + void Project::SaveAs(const std::string FullPath) + { + json j = Serialize(); + std::string serialized_string = j.dump(); -void Project::Save() -{ - SaveAs(this->FullPath); -} - -void Project::SaveAs(const std::string FullPath) -{ - json j = Serialize(); - std::string serialized_string = j.dump(); - - // TODO: Use file interface here... - // Write to file. - std::ofstream projectFile; + // TODO: Use file interface here... + // Write to file. + std::ofstream projectFile; projectFile.open(FullPath); projectFile << serialized_string; - projectFile.close(); -} + projectFile.close(); + } -Ref Project::New(const std::string Name, const std::string Description, const std::string FullPath) -{ - if (Name == "") - return nullptr; + Ref Project::New(const std::string Name, const std::string Description, const std::string FullPath) + { + if (Name == "") + return nullptr; - return CreateRef(Name, Description, FullPath); -} + return CreateRef(Name, Description, FullPath); + } -Ref Project::New() -{ - return CreateRef(); -} + Ref Project::New() + { + return CreateRef(); + } -Ref Project::Load(std::string path) -{ - std::ifstream i(path); - json j; - i >> j; + Ref Project::Load(std::string path) + { + std::ifstream i(path); + json j; + i >> j; - // validation - std::string projectName = ""; - if(!j.contains("ProjectName")) - return nullptr; + // validation + std::string projectName = ""; + if (!j.contains("ProjectName")) + return nullptr; - projectName = j["ProjectName"]; + projectName = j["ProjectName"]; - std::string description = ""; - if (j.contains("Description")) - description = j["Description"]; + std::string description = ""; + if (j.contains("Description")) + description = j["Description"]; - return CreateRef(projectName, description, path); -} + return CreateRef(projectName, description, path); + } -json Project::Serialize() -{ - BEGIN_SERIALIZE(); + json Project::Serialize() + { + BEGIN_SERIALIZE(); SERIALIZE_VAL(Name); SERIALIZE_VAL(Description); SERIALIZE_VAL_LBL("DefaultScene", DefaultScene->Path); SERIALIZE_VAL_LBL("EntityDefinition", EntityDefinitionsFile->Path); SERIALIZE_VAL(TrenchbroomPath); - END_SERIALIZE(); + END_SERIALIZE(); + } + + bool Project::Deserialize(const std::string& str) + { + BEGIN_DESERIALIZE(); + + if (!j.contains("Name") || !j.contains("Description")) + return false; + + Name = j["Name"]; + Description = j["Description"]; + + if (j.contains("EntityDefinition")) + { + std::string path = j["EntityDefinition"]; + EntityDefinitionsFile = CreateRef(path); + std::string content = FileSystem::ReadFile(path, false); + EntityDefinitionsFile->Deserialize(content); + } + + if (j.contains("TrenchbroomPath")) + { + this->TrenchbroomPath = j["TrenchbroomPath"]; + } + + DefaultScene = Scene::New(); + + // Load default scene, a project can have no default scene set. + if (!j.contains("DefaultScene")) + return true; + + std::string scenePath = j["DefaultScene"]; + if (scenePath == "") // Not set correctly. + return true; + + std::string sceneContent = FileSystem::ReadFile(scenePath, false); + if (!DefaultScene->Deserialize(sceneContent)) + { + Logger::Log("Error loading scene: " + scenePath, CRITICAL); + return false; + } + + DefaultScene->Path = scenePath; + Logger::Log("Successfully loaded scene: " + scenePath); + + return true; // Success + } } -bool Project::Deserialize(const std::string& str) -{ - BEGIN_DESERIALIZE(); - - if (!j.contains("Name") || !j.contains("Description")) - return false; - - Name = j["Name"]; - Description = j["Description"]; - - if (j.contains("EntityDefinition")) - { - std::string path = j["EntityDefinition"]; - EntityDefinitionsFile = CreateRef(path); - std::string content = FileSystem::ReadFile(path, false); - EntityDefinitionsFile->Deserialize(content); - } - - if (j.contains("TrenchbroomPath")) - { - this->TrenchbroomPath = j["TrenchbroomPath"]; - } - - DefaultScene = Scene::New(); - - // Load default scene, a project can have no default scene set. - if (!j.contains("DefaultScene")) - return true; - - std::string scenePath = j["DefaultScene"]; - if (scenePath == "") // Not set correctly. - return true; - - std::string sceneContent = FileSystem::ReadFile(scenePath, false); - if (!DefaultScene->Deserialize(sceneContent)) - { - Logger::Log("Error loading scene: " + scenePath, CRITICAL); - return false; - } - - DefaultScene->Path = scenePath; - Logger::Log("Successfully loaded scene: " + scenePath); - - return true; // Success -} diff --git a/Nuake/src/Resource/Project.h b/Nuake/src/Resource/Project.h index 4b5ed6da..f42bba55 100644 --- a/Nuake/src/Resource/Project.h +++ b/Nuake/src/Resource/Project.h @@ -6,29 +6,32 @@ #include "FGD/FGDFile.h" -class Project : public ISerializable +namespace Nuake { -public: - std::string Name; - std::string Description; - std::string FullPath; + class Project : public ISerializable + { + public: + std::string Name; + std::string Description; + std::string FullPath; - // Path of the trenchbroom .exe folder - std::string TrenchbroomPath = ""; + // Path of the trenchbroom .exe folder + std::string TrenchbroomPath = ""; - Ref DefaultScene; - Ref EntityDefinitionsFile; + Ref DefaultScene; + Ref EntityDefinitionsFile; - Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath = ""); - Project(); + Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath = ""); + Project(); - void Save(); - void SaveAs(const std::string FullPath); + void Save(); + void SaveAs(const std::string FullPath); - static Ref New(const std::string Name, const std::string Description, const std::string FullPath); - static Ref New(); - static Ref Load(std::string path); + static Ref New(const std::string Name, const std::string Description, const std::string FullPath); + static Ref New(); + static Ref Load(std::string path); - json Serialize() override; - bool Deserialize(const std::string& str) override; -}; \ No newline at end of file + json Serialize() override; + bool Deserialize(const std::string& str) override; + }; +} diff --git a/Nuake/src/Scene/Components/BSPBrushComponent.h b/Nuake/src/Scene/Components/BSPBrushComponent.h index 83b0490d..5400a555 100644 --- a/Nuake/src/Scene/Components/BSPBrushComponent.h +++ b/Nuake/src/Scene/Components/BSPBrushComponent.h @@ -6,23 +6,26 @@ #include "../Rendering/Mesh/Mesh.h" #include -class BSPBrushComponent { -public: - std::vector> Meshes; - std::vector< Ref> Materials; - std::vector> Rigidbody; +namespace Nuake +{ + class BSPBrushComponent { + public: + std::vector> Meshes; + std::vector< Ref> Materials; + std::vector> Rigidbody; - std::string target = ""; - std::vector Targets; + std::string target = ""; + std::vector Targets; - bool IsSolid = true; - bool IsTrigger = false; - bool IsTransparent = false; - bool IsFunc = false; + bool IsSolid = true; + bool IsTrigger = false; + bool IsTransparent = false; + bool IsFunc = false; - BSPBrushComponent() { - Meshes = std::vector>(); - Materials = std::vector>(); - Rigidbody = std::vector>(); - } -}; \ No newline at end of file + BSPBrushComponent() { + Meshes = std::vector>(); + Materials = std::vector>(); + Rigidbody = std::vector>(); + } + }; +} diff --git a/Nuake/src/Scene/Components/BoxCollider.h b/Nuake/src/Scene/Components/BoxCollider.h index 81883933..68264cd2 100644 --- a/Nuake/src/Scene/Components/BoxCollider.h +++ b/Nuake/src/Scene/Components/BoxCollider.h @@ -1,11 +1,13 @@ #pragma once -#include "../Core/Physics/PhysicsShapes.h" -#include "../Core/Core.h" +#include "src/Core/Physics/PhysicsShapes.h" +#include "src/Core/Core.h" -class BoxColliderComponent -{ -public: - Ref Box; - glm::vec3 Size = glm::vec3(0.5f, 0.5f, 0.5f); - bool IsTrigger; -}; \ No newline at end of file +namespace Nuake { + class BoxColliderComponent + { + public: + Ref Box; + glm::vec3 Size = glm::vec3(0.5f, 0.5f, 0.5f); + bool IsTrigger; + }; +} diff --git a/Nuake/src/Scene/Components/CameraComponent.cpp b/Nuake/src/Scene/Components/CameraComponent.cpp index a29a7600..528dd56d 100644 --- a/Nuake/src/Scene/Components/CameraComponent.cpp +++ b/Nuake/src/Scene/Components/CameraComponent.cpp @@ -1,16 +1,19 @@ #pragma once #include "CameraComponent.h" -#include +#include "src/Rendering/Camera.h" #include "src/Scene/Entities/ImGuiHelper.h" -CameraComponent::CameraComponent() -{ - CameraInstance = CreateRef(); -} +namespace Nuake { + CameraComponent::CameraComponent() + { + CameraInstance = CreateRef(); + } -void CameraComponent::DrawEditor() { - ImGui::Text("Camera"); - ImGui::SliderFloat("Exposure", &CameraInstance->Exposure, 0.0f, 2.0f, "%.2f", 1.0f); - ImGui::SliderFloat("FOV", &CameraInstance->Fov, 1.0f, 180.0f, "%.2f", 1.0f); - ImGui::SliderFloat("Speed", &CameraInstance->Speed, 0.1f, 5.0f, "%.2f", 1.0f); -} \ No newline at end of file + void CameraComponent::DrawEditor() + { + ImGui::Text("Camera"); + ImGui::SliderFloat("Exposure", &CameraInstance->Exposure, 0.0f, 2.0f, "%.2f", 1.0f); + ImGui::SliderFloat("FOV", &CameraInstance->Fov, 1.0f, 180.0f, "%.2f", 1.0f); + ImGui::SliderFloat("Speed", &CameraInstance->Speed, 0.1f, 5.0f, "%.2f", 1.0f); + } +} diff --git a/Nuake/src/Scene/Components/CameraComponent.h b/Nuake/src/Scene/Components/CameraComponent.h index ba50610b..93e1e7d1 100644 --- a/Nuake/src/Scene/Components/CameraComponent.h +++ b/Nuake/src/Scene/Components/CameraComponent.h @@ -1,29 +1,33 @@ #pragma once #include "TransformComponent.h" -#include "../Core/Core.h" -#include "../Resource/Serializable.h" -#include "../Rendering/Camera.h" +#include "src/Core/Core.h" +#include "src/Resource/Serializable.h" +#include "src/Rendering/Camera.h" -class CameraComponent { -public: - Ref CameraInstance; - TransformComponent* transformComponent; - - CameraComponent(); - - void DrawEditor(); - - json Serialize() +namespace Nuake +{ + class CameraComponent { - BEGIN_SERIALIZE(); - SERIALIZE_OBJECT(CameraInstance); - END_SERIALIZE(); - } + public: + Ref CameraInstance; + TransformComponent* transformComponent; - bool Deserialize(std::string str) - { - CameraInstance = CreateRef(); + CameraComponent(); - return CameraInstance->Deserialize(str); - } -}; \ No newline at end of file + void DrawEditor(); + + json Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_OBJECT(CameraInstance); + END_SERIALIZE(); + } + + bool Deserialize(std::string str) + { + CameraInstance = CreateRef(); + + return CameraInstance->Deserialize(str); + } + }; +} \ No newline at end of file diff --git a/Nuake/src/Scene/Components/CharacterControllerComponent.h b/Nuake/src/Scene/Components/CharacterControllerComponent.h index ea90ddd1..21d1cd4f 100644 --- a/Nuake/src/Scene/Components/CharacterControllerComponent.h +++ b/Nuake/src/Scene/Components/CharacterControllerComponent.h @@ -1,40 +1,42 @@ #pragma once +#include "src/Core/Physics/CharacterController.h" -#include "../Core/Physics/CharacterController.h" -class CharacterControllerComponent -{ -public: - Ref < Physics::CharacterController> CharacterController; - - float Height = 1.0f; - float Radius = 0.2f; - float Mass = 25.0f; - - CharacterControllerComponent() +namespace Nuake { + class CharacterControllerComponent { - - } + public: + Ref < Physics::CharacterController> CharacterController; - json Serialize() { - BEGIN_SERIALIZE(); - SERIALIZE_VAL(Height); - SERIALIZE_VAL(Radius); - SERIALIZE_VAL(Mass); - END_SERIALIZE(); - } + float Height = 1.0f; + float Radius = 0.2f; + float Mass = 25.0f; - bool Deserialize(const std::string str) { - BEGIN_DESERIALIZE(); - Height = j["Height"]; - Radius = j["Radius"]; - Mass = j["Mass"]; - return true; - } - void SyncWithTransform(TransformComponent& tc) - { - btVector3 pos = CharacterController->m_motionTransform.getOrigin(); - glm::vec3 finalPos = glm::vec3(pos.x(), pos.y(), pos.z()); + CharacterControllerComponent() + { - tc.Translation = finalPos; - } -}; \ No newline at end of file + } + + json Serialize() { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(Height); + SERIALIZE_VAL(Radius); + SERIALIZE_VAL(Mass); + END_SERIALIZE(); + } + + bool Deserialize(const std::string str) { + BEGIN_DESERIALIZE(); + Height = j["Height"]; + Radius = j["Radius"]; + Mass = j["Mass"]; + return true; + } + void SyncWithTransform(TransformComponent& tc) + { + btVector3 pos = CharacterController->m_motionTransform.getOrigin(); + glm::vec3 finalPos = glm::vec3(pos.x(), pos.y(), pos.z()); + + tc.Translation = finalPos; + } + }; +} diff --git a/Nuake/src/Scene/Components/LightComponent.cpp b/Nuake/src/Scene/Components/LightComponent.cpp index b99214ab..ef24c0a3 100644 --- a/Nuake/src/Scene/Components/LightComponent.cpp +++ b/Nuake/src/Scene/Components/LightComponent.cpp @@ -6,141 +6,144 @@ #include #include "../Core/Core.h" #include -LightComponent::LightComponent() -{ - Color = glm::vec3(1, 1, 1); - Strength = 10.0f; - Direction = glm::vec3(0, -1, 0); - - //m_Framebuffers = std::vector>(); - //mViewProjections = std::vector(); - //mCascadeSplitDepth = std::vector(); - //mCascadeSplits = std::vector(); - // Framebuffer used for shadow mapping. - - //for (int i = 0; i < 4; i++) - //{ - // m_Framebuffers[i] = CreateRef(false, glm::vec2(4096, 4096)); - // m_Framebuffers[i]->SetTexture(CreateRef(glm::vec2(4096, 4096), GL_DEPTH_COMPONENT), GL_DEPTH_ATTACHMENT); - //} - -} - -void LightComponent::SetCastShadows(bool toggle) -{ - CastShadows = toggle; - if (CastShadows) +namespace Nuake { + LightComponent::LightComponent() { - for (int i = 0; i < 4; i++) - { - m_Framebuffers[i] = CreateRef(false, glm::vec2(4096, 4096)); - m_Framebuffers[i]->SetTexture(CreateRef(glm::vec2(4096, 4096), GL_DEPTH_COMPONENT), GL_DEPTH_ATTACHMENT); - } + Color = glm::vec3(1, 1, 1); + Strength = 10.0f; + Direction = glm::vec3(0, -1, 0); + + + //m_Framebuffers = std::vector>(); + //mViewProjections = std::vector(); + //mCascadeSplitDepth = std::vector(); + //mCascadeSplits = std::vector(); + // Framebuffer used for shadow mapping. + + //for (int i = 0; i < 4; i++) + //{ + // m_Framebuffers[i] = CreateRef(false, glm::vec2(4096, 4096)); + // m_Framebuffers[i]->SetTexture(CreateRef(glm::vec2(4096, 4096), GL_DEPTH_COMPONENT), GL_DEPTH_ATTACHMENT); + //} + } - else { - for (int i = 0; i < 4; i++) - { - m_Framebuffers[i] = nullptr; - } - } -} -glm::mat4 LightComponent::GetProjection() -{ - return glm::ortho(-25.0f, 25.0f, -25.0f, 25.0f, -25.0f, 25.0f); -} - -void LightComponent::SetDirection(glm::vec3 dir) -{ - -} - -glm::vec3 LightComponent::GetDirection() -{ - //glm::mat4 start = glm::mat4(1.0f); - //glm::vec3 defaultDirection(0, 0, 1); // forward - // - //start = glm::rotate(start, glm::radians(Direction.x), glm::vec3(1, 0, 0)); - //start = glm::rotate(start, glm::radians(Direction.y), glm::vec3(0, 1, 0)); - //start = glm::rotate(start, glm::radians(Direction.z), glm::vec3(0, 0, 1)); - - //return glm::vec3(start * glm::vec4(defaultDirection, 1.0f)); - return Direction; -} - - -void LightComponent::BeginDrawShadow() -{ - Renderer::m_ShadowmapShader->Bind(); - //m_Framebuffer->Bind(); - - // Render scene... - -} - -void LightComponent::EndDrawShadow() -{ - //m_Framebuffer->Unbind(); -} - -void LightComponent::DrawShadow() -{ - if (Type != Directional) - return; - - Renderer::m_ShadowmapShader->Bind(); -} - -void LightComponent::Draw(TransformComponent transformComponent, Ref cam) -{ - Renderer::RegisterLight(transformComponent, *this, cam); -} - -void LightComponent::DrawDeferred(TransformComponent transformComponent, Camera* cam) -{ - Renderer::RegisterDeferredLight(transformComponent, *this, cam); -} - -void LightComponent::DrawEditor() { - ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Light properties"); - ImGui::ColorEdit3("Light Color", &Color.r); - ImGui::SliderFloat("Strength", &Strength, 0.0f, 50.0f); - bool before = CastShadows; - ImGui::Checkbox("Cast shadows", &CastShadows); - - if (CastShadows && before == false) - SetCastShadows(true); - - const char* types[] = { "Directional", "Point", "Spot" }; - static const char* current_item = types[Type]; - - if (ImGui::BeginCombo("Type", current_item)) // The second parameter is the label previewed before opening the combo. + void LightComponent::SetCastShadows(bool toggle) { - for (int n = 0; n < IM_ARRAYSIZE(types); n++) + CastShadows = toggle; + if (CastShadows) { - bool is_selected = (current_item == types[n]); // You can store your selection however you want, outside or inside your objects - if (ImGui::Selectable(types[n], is_selected)) { - current_item = types[n]; - Type = (LightType)n; + for (int i = 0; i < 4; i++) + { + m_Framebuffers[i] = CreateRef(false, glm::vec2(4096, 4096)); + m_Framebuffers[i]->SetTexture(CreateRef(glm::vec2(4096, 4096), GL_DEPTH_COMPONENT), GL_DEPTH_ATTACHMENT); + } + } + else { + for (int i = 0; i < 4; i++) + { + m_Framebuffers[i] = nullptr; } - if (is_selected) - ImGui::SetItemDefaultFocus(); // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support) } - ImGui::EndCombo(); } - if (Type == Directional) { - ImGui::Checkbox("Sync with sky", &SyncDirectionWithSky); - ImGui::Checkbox("Volumetric?", &IsVolumetric); - ImGuiHelper::DrawVec3("Direction", &Direction); + glm::mat4 LightComponent::GetProjection() + { + return glm::ortho(-25.0f, 25.0f, -25.0f, 25.0f, -25.0f, 25.0f); + } + + void LightComponent::SetDirection(glm::vec3 dir) + { + + } + + glm::vec3 LightComponent::GetDirection() + { + //glm::mat4 start = glm::mat4(1.0f); + //glm::vec3 defaultDirection(0, 0, 1); // forward + // + //start = glm::rotate(start, glm::radians(Direction.x), glm::vec3(1, 0, 0)); + //start = glm::rotate(start, glm::radians(Direction.y), glm::vec3(0, 1, 0)); + //start = glm::rotate(start, glm::radians(Direction.z), glm::vec3(0, 0, 1)); + + //return glm::vec3(start * glm::vec4(defaultDirection, 1.0f)); + return Direction; + } + + + void LightComponent::BeginDrawShadow() + { + Renderer::m_ShadowmapShader->Bind(); + //m_Framebuffer->Bind(); + + // Render scene... + + } + + void LightComponent::EndDrawShadow() + { + //m_Framebuffer->Unbind(); + } + + void LightComponent::DrawShadow() + { + if (Type != Directional) + return; + + Renderer::m_ShadowmapShader->Bind(); + } + + void LightComponent::Draw(TransformComponent transformComponent, Ref cam) + { + Renderer::RegisterLight(transformComponent, *this, cam); + } + + void LightComponent::DrawDeferred(TransformComponent transformComponent, Camera* cam) + { + Renderer::RegisterDeferredLight(transformComponent, *this, cam); + } + + void LightComponent::DrawEditor() { + ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Light properties"); + ImGui::ColorEdit3("Light Color", &Color.r); + ImGui::SliderFloat("Strength", &Strength, 0.0f, 50.0f); + bool before = CastShadows; + ImGui::Checkbox("Cast shadows", &CastShadows); + + if (CastShadows && before == false) + SetCastShadows(true); + + const char* types[] = { "Directional", "Point", "Spot" }; + static const char* current_item = types[Type]; + + if (ImGui::BeginCombo("Type", current_item)) // The second parameter is the label previewed before opening the combo. + { + for (int n = 0; n < IM_ARRAYSIZE(types); n++) + { + bool is_selected = (current_item == types[n]); // You can store your selection however you want, outside or inside your objects + if (ImGui::Selectable(types[n], is_selected)) { + current_item = types[n]; + Type = (LightType)n; + } + if (is_selected) + ImGui::SetItemDefaultFocus(); // You may set the initial focus when opening the combo (scrolling + for keyboard navigation support) + } + ImGui::EndCombo(); + } + + if (Type == Directional) { + ImGui::Checkbox("Sync with sky", &SyncDirectionWithSky); + ImGui::Checkbox("Volumetric?", &IsVolumetric); + ImGuiHelper::DrawVec3("Direction", &Direction); + } + + //if (Type == 1) { + // ImGui::SliderFloat("Attenuation", &Attenuation, 0.0f, 1.0f); + // ImGui::SliderFloat("Linear attenuation", &LinearAttenuation, 0.0f, 1.0f); + // ImGui::SliderFloat("Quadratic attenuation", &QuadraticAttenuation, 0.0f, 1.0f); + //} + + //Direction = glm::normalize(Direction); } - - //if (Type == 1) { - // ImGui::SliderFloat("Attenuation", &Attenuation, 0.0f, 1.0f); - // ImGui::SliderFloat("Linear attenuation", &LinearAttenuation, 0.0f, 1.0f); - // ImGui::SliderFloat("Quadratic attenuation", &QuadraticAttenuation, 0.0f, 1.0f); - //} - - //Direction = glm::normalize(Direction); } diff --git a/Nuake/src/Scene/Components/LightComponent.h b/Nuake/src/Scene/Components/LightComponent.h index 53005c8f..ca3f8469 100644 --- a/Nuake/src/Scene/Components/LightComponent.h +++ b/Nuake/src/Scene/Components/LightComponent.h @@ -3,204 +3,209 @@ #include #include "TransformComponent.h" #include "../Rendering/Camera.h" -#include "../Rendering/Framebuffer.h" +#include "src/Rendering/Buffers/Framebuffer.h" #include "BaseComponent.h" #include "../Resource/Serializable.h" #include -enum LightType { - Directional, Point, Spot -}; - -class LightComponent { -public: - LightType Type = Point; - glm::vec3 Direction = glm::vec3(0, -1, 0); - glm::vec3 Color; - bool IsVolumetric = false; - float Strength; - bool SyncDirectionWithSky = false; - Ref m_Framebuffer; - - bool CastShadows = false; - float Attenuation = 0.0f; - float LinearAttenuation = 0.0f; - float QuadraticAttenuation = 0.0f; - - Ref m_Framebuffers[4]; - glm::mat4 mViewProjections[4]; - float mCascadeSplitDepth[4]; - - LightComponent(); - - void SetCastShadows(bool toggle); - - glm::mat4 GetProjection(); - - glm::mat4 GetLightTransform(); - void SetDirection(glm::vec3 dir); - glm::vec3 GetDirection(); - - void BeginDrawShadow(); - - void EndDrawShadow(); - void DrawShadow(); - - void Draw(TransformComponent transformComponent, Ref cam); - void DrawDeferred(TransformComponent transformComponent, Camera* cam); - void DrawEditor(); - - void SetType(LightType type); - - float mCascadeSplits[4]; - - - void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection) +namespace Nuake +{ + enum LightType { - glm::mat4 viewProjection = projection * view; - glm::mat4 inverseViewProjection = glm::inverse(viewProjection); + Directional, Point, Spot + }; - // TODO: Automate this - const float nearClip = 0.01f; - const float farClip = 1000.0f; - const float clipRange = farClip - nearClip; + class LightComponent + { + public: + LightType Type = Point; + glm::vec3 Direction = glm::vec3(0, -1, 0); + glm::vec3 Color; + bool IsVolumetric = false; + float Strength; + bool SyncDirectionWithSky = false; + Ref m_Framebuffer; - const float mCascadeNearPlaneOffset = 0.0; - const float mCascadeFarPlaneOffset = 0.0; + bool CastShadows = false; + float Attenuation = 0.0f; + float LinearAttenuation = 0.0f; + float QuadraticAttenuation = 0.0f; - // Calculate the optimal cascade distances - const float minZ = nearClip; - const float maxZ = nearClip + clipRange; - const float range = maxZ - minZ; - const float ratio = maxZ / minZ; - for (int i = 0; i < 4; i++) + Ref m_Framebuffers[4]; + glm::mat4 mViewProjections[4]; + float mCascadeSplitDepth[4]; + + LightComponent(); + + void SetCastShadows(bool toggle); + + glm::mat4 GetProjection(); + + glm::mat4 GetLightTransform(); + void SetDirection(glm::vec3 dir); + glm::vec3 GetDirection(); + + void BeginDrawShadow(); + + void EndDrawShadow(); + void DrawShadow(); + + void Draw(TransformComponent transformComponent, Ref cam); + void DrawDeferred(TransformComponent transformComponent, Camera* cam); + void DrawEditor(); + + void SetType(LightType type); + + float mCascadeSplits[4]; + + + void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection) { - const float p = (i + 1) / static_cast(4); - const float log = minZ * glm::pow(ratio, p); - const float uniform = minZ + range * p; - const float d = 0.91f * (log - uniform) + uniform; - mCascadeSplits[i] = (d - nearClip) / clipRange; - } + glm::mat4 viewProjection = projection * view; + glm::mat4 inverseViewProjection = glm::inverse(viewProjection); - //mCascadeSplits[0] = 0.2f; - //mCascadeSplits[1] = 0.45f; - //mCascadeSplits[2] = 1.0f; + // TODO: Automate this + const float nearClip = 0.01f; + const float farClip = 1000.0f; + const float clipRange = farClip - nearClip; - float lastSplitDist = 0.0f; - // Calculate Orthographic Projection matrix for each cascade - for (int cascade = 0; cascade < 4; cascade++) - { - float splitDist = mCascadeSplits[cascade]; - glm::vec4 frustumCorners[8] = - { - //Near face - { 1.0f, 1.0f, -1.0f, 1.0f }, - { -1.0f, 1.0f, -1.0f, 1.0f }, - { 1.0f, -1.0f, -1.0f, 1.0f }, - { -1.0f, -1.0f, -1.0f, 1.0f }, + const float mCascadeNearPlaneOffset = 0.0; + const float mCascadeFarPlaneOffset = 0.0; - //Far face - { 1.0f, 1.0f, 1.0f, 1.0f }, - { -1.0f, 1.0f, 1.0f, 1.0f }, - { 1.0f, -1.0f, 1.0f, 1.0f }, - { -1.0f, -1.0f, 1.0f, 1.0f }, - }; - - // Project frustum corners into world space from clip space - for (int i = 0; i < 8; i++) - { - glm::vec4 invCorner = inverseViewProjection * frustumCorners[i]; - frustumCorners[i] = invCorner / invCorner.w; - } + // Calculate the optimal cascade distances + const float minZ = nearClip; + const float maxZ = nearClip + clipRange; + const float range = maxZ - minZ; + const float ratio = maxZ / minZ; for (int i = 0; i < 4; i++) { - glm::vec4 dist = frustumCorners[i + 4] - frustumCorners[i]; - frustumCorners[i + 4] = frustumCorners[i] + (dist * splitDist); - frustumCorners[i] = frustumCorners[i] + (dist * lastSplitDist); + const float p = (i + 1) / static_cast(4); + const float log = minZ * glm::pow(ratio, p); + const float uniform = minZ + range * p; + const float d = 0.91f * (log - uniform) + uniform; + mCascadeSplits[i] = (d - nearClip) / clipRange; } - // Get frustum center - glm::vec3 frustumCenter = glm::vec3(0.0f); - for (int i = 0; i < 8; i++) - frustumCenter += glm::vec3(frustumCorners[i]); - frustumCenter /= 8.0f; + //mCascadeSplits[0] = 0.2f; + //mCascadeSplits[1] = 0.45f; + //mCascadeSplits[2] = 1.0f; - // Get the minimum and maximum extents - float radius = 0.0f; - for (int i = 0; i < 8; i++) + float lastSplitDist = 0.0f; + // Calculate Orthographic Projection matrix for each cascade + for (int cascade = 0; cascade < 4; cascade++) { - float distance = glm::length(glm::vec3(frustumCorners[i]) - frustumCenter); - radius = glm::max(radius, distance); + float splitDist = mCascadeSplits[cascade]; + glm::vec4 frustumCorners[8] = + { + //Near face + { 1.0f, 1.0f, -1.0f, 1.0f }, + { -1.0f, 1.0f, -1.0f, 1.0f }, + { 1.0f, -1.0f, -1.0f, 1.0f }, + { -1.0f, -1.0f, -1.0f, 1.0f }, + + //Far face + { 1.0f, 1.0f, 1.0f, 1.0f }, + { -1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, -1.0f, 1.0f, 1.0f }, + { -1.0f, -1.0f, 1.0f, 1.0f }, + }; + + // Project frustum corners into world space from clip space + for (int i = 0; i < 8; i++) + { + glm::vec4 invCorner = inverseViewProjection * frustumCorners[i]; + frustumCorners[i] = invCorner / invCorner.w; + } + for (int i = 0; i < 4; i++) + { + glm::vec4 dist = frustumCorners[i + 4] - frustumCorners[i]; + frustumCorners[i + 4] = frustumCorners[i] + (dist * splitDist); + frustumCorners[i] = frustumCorners[i] + (dist * lastSplitDist); + } + + // Get frustum center + glm::vec3 frustumCenter = glm::vec3(0.0f); + for (int i = 0; i < 8; i++) + frustumCenter += glm::vec3(frustumCorners[i]); + frustumCenter /= 8.0f; + + // Get the minimum and maximum extents + float radius = 0.0f; + for (int i = 0; i < 8; i++) + { + float distance = glm::length(glm::vec3(frustumCorners[i]) - frustumCenter); + radius = glm::max(radius, distance); + } + radius = std::ceil(radius * 16.0f) / 16.0f; + glm::vec3 maxExtents = glm::vec3(radius); + glm::vec3 minExtents = -maxExtents; + + // Calculate the view and projection matrix + glm::vec3 lightDir = -this->Direction; + glm::mat4 lightViewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, glm::vec3(0.0f, 0.0f, 1.0f)); + glm::mat4 lightProjectionMatrix = glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f + mCascadeNearPlaneOffset, maxExtents.z - minExtents.z + mCascadeFarPlaneOffset); + + // Offset to texel space to avoid shimmering ->(https://stackoverflow.com/questions/33499053/cascaded-shadow-map-shimmering) + glm::mat4 shadowMatrix = lightProjectionMatrix * lightViewMatrix; + const float ShadowMapResolution = 4096; + glm::vec4 shadowOrigin = (shadowMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) * ShadowMapResolution / 2.0f; + glm::vec4 roundedOrigin = glm::round(shadowOrigin); + glm::vec4 roundOffset = roundedOrigin - shadowOrigin; + roundOffset = roundOffset * 2.0f / ShadowMapResolution; + roundOffset.z = 0.0f; + roundOffset.w = 0.0f; + lightProjectionMatrix[3] += roundOffset; + + // Store SplitDistance and ViewProjection-Matrix + mCascadeSplitDepth[cascade] = (nearClip + splitDist * clipRange) * 1.0f; + mViewProjections[cascade] = lightProjectionMatrix * lightViewMatrix; + lastSplitDist = mCascadeSplits[cascade]; + + // -----------------------Debug only----------------------- + // RendererDebug::BeginScene(viewProjection); + // RendererDebug::SubmitCameraFrustum(frustumCorners, glm::mat4(1.0f), GetColor(cascade)); // Draws the divided camera frustums + // RendererDebug::SubmitLine(glm::vec3(0.0f, 0.0f, 0.0f), frustumCenter, GetColor(cascade)); // Draws the center of the frustum (A line pointing from origin to the center) + // RendererDebug::EndScene(); } - radius = std::ceil(radius * 16.0f) / 16.0f; - glm::vec3 maxExtents = glm::vec3(radius); - glm::vec3 minExtents = -maxExtents; - - // Calculate the view and projection matrix - glm::vec3 lightDir = -this->Direction; - glm::mat4 lightViewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, glm::vec3(0.0f, 0.0f, 1.0f)); - glm::mat4 lightProjectionMatrix = glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f + mCascadeNearPlaneOffset, maxExtents.z - minExtents.z + mCascadeFarPlaneOffset); - - // Offset to texel space to avoid shimmering ->(https://stackoverflow.com/questions/33499053/cascaded-shadow-map-shimmering) - glm::mat4 shadowMatrix = lightProjectionMatrix * lightViewMatrix; - const float ShadowMapResolution = 4096; - glm::vec4 shadowOrigin = (shadowMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) * ShadowMapResolution / 2.0f; - glm::vec4 roundedOrigin = glm::round(shadowOrigin); - glm::vec4 roundOffset = roundedOrigin - shadowOrigin; - roundOffset = roundOffset * 2.0f / ShadowMapResolution; - roundOffset.z = 0.0f; - roundOffset.w = 0.0f; - lightProjectionMatrix[3] += roundOffset; - - // Store SplitDistance and ViewProjection-Matrix - mCascadeSplitDepth[cascade] = (nearClip + splitDist * clipRange) * 1.0f; - mViewProjections[cascade] = lightProjectionMatrix * lightViewMatrix; - lastSplitDist = mCascadeSplits[cascade]; - - // -----------------------Debug only----------------------- - // RendererDebug::BeginScene(viewProjection); - // RendererDebug::SubmitCameraFrustum(frustumCorners, glm::mat4(1.0f), GetColor(cascade)); // Draws the divided camera frustums - // RendererDebug::SubmitLine(glm::vec3(0.0f, 0.0f, 0.0f), frustumCenter, GetColor(cascade)); // Draws the center of the frustum (A line pointing from origin to the center) - // RendererDebug::EndScene(); } - } - json Serialize() - { - BEGIN_SERIALIZE(); - SERIALIZE_VAL(Type); - SERIALIZE_VEC3(Direction); - SERIALIZE_VEC3(Color); - SERIALIZE_VAL(IsVolumetric); - SERIALIZE_VAL(Strength); - SERIALIZE_VAL(SyncDirectionWithSky); - SERIALIZE_VAL(CastShadows); - END_SERIALIZE(); - } + json Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(Type); + SERIALIZE_VEC3(Direction); + SERIALIZE_VEC3(Color); + SERIALIZE_VAL(IsVolumetric); + SERIALIZE_VAL(Strength); + SERIALIZE_VAL(SyncDirectionWithSky); + SERIALIZE_VAL(CastShadows); + END_SERIALIZE(); + } - bool Deserialize(std::string str) - { - BEGIN_DESERIALIZE(); - if (j.contains("Type")) - Type = (LightType)j["Type"]; - if (j.contains("IsVolumetric")) - IsVolumetric = j["IsVolumetric"]; - if (j.contains("Strength")) - Strength = j["Strength"]; - if (j.contains("SyncDirectionWithSky")) - SyncDirectionWithSky = j["SyncDirectionWithSky"]; - if (j.contains("CastShadows")) - SetCastShadows(j["CastShadows"]); - if (j.contains("Direction")) - { - float x = j["Direction"]["x"]; - float y = j["Direction"]["y"]; - float z = j["Direction"]["z"]; - this->Direction = Vector3(x, y, z); - } + bool Deserialize(std::string str) + { + BEGIN_DESERIALIZE(); + if (j.contains("Type")) + Type = (LightType)j["Type"]; + if (j.contains("IsVolumetric")) + IsVolumetric = j["IsVolumetric"]; + if (j.contains("Strength")) + Strength = j["Strength"]; + if (j.contains("SyncDirectionWithSky")) + SyncDirectionWithSky = j["SyncDirectionWithSky"]; + if (j.contains("CastShadows")) + SetCastShadows(j["CastShadows"]); + if (j.contains("Direction")) + { + float x = j["Direction"]["x"]; + float y = j["Direction"]["y"]; + float z = j["Direction"]["z"]; + this->Direction = Vector3(x, y, z); + } - return true; - } -}; \ No newline at end of file + return true; + } + }; +} diff --git a/Nuake/src/Scene/Components/MeshCollider.h b/Nuake/src/Scene/Components/MeshCollider.h index f996164e..7f294583 100644 --- a/Nuake/src/Scene/Components/MeshCollider.h +++ b/Nuake/src/Scene/Components/MeshCollider.h @@ -1,11 +1,13 @@ #pragma once -#include "../Core/Physics/PhysicsShapes.h" -#include "../Core/Core.h" +#include "src/Core/Physics/PhysicsShapes.h" +#include "src/Core/Core.h" -class MeshColliderComponent -{ -public: - Ref MeshShape; - Ref Mesh; - bool IsTrigger; -}; \ No newline at end of file +namespace Nuake { + class MeshColliderComponent + { + public: + Ref MeshShape; + Ref Mesh; + bool IsTrigger; + }; +} diff --git a/Nuake/src/Scene/Components/MeshComponent.cpp b/Nuake/src/Scene/Components/MeshComponent.cpp index 9b099b72..3a619b9c 100644 --- a/Nuake/src/Scene/Components/MeshComponent.cpp +++ b/Nuake/src/Scene/Components/MeshComponent.cpp @@ -1,278 +1,279 @@ #include "MeshComponent.h" #include -#include "../../../Rendering/Renderer.h" -#include "../../../Rendering/Vertex.h" -#include "../../../Core/MaterialManager.h" +#include "src/Rendering/Renderer.h" +#include "src/Rendering/Vertex.h" +#include "src/Core/MaterialManager.h" #include -// TODO: This is a pile of crap. -// TODO: MOVE TO PRIMITIVE -Vertex vertices[] = { - Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, - Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, - Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, - Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, +namespace Nuake{ - Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, - Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, - Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, - Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, - Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, + // TODO: MOVE TO PRIMITIVE + Vertex vertices[] = { + Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, + Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, + Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, + Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, -1), glm::vec3(0, 1, 0), glm::vec3(-1, 0, 0), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, - Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, - Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, - Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, + Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, + Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, + Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, + Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 0, 1), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), 1.0f }, - Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(-1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, -}; + Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, + Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, + Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, + Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(1, 0, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, -1), 1.0f }, -void MeshComponent::LoadModel(const std::string path) { - //Assimp::Importer import; - //const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs); - // - //if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) - //{ - // printf("ERROR::ASSIMP::"); - // return; - //} - // - //ProcessNode(scene->mRootNode, scene); -} -unsigned int sphereVAO = 0; -unsigned int indexCount; -void MeshComponent::RenderSphere() { + Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(0.5f, -0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(0.5f, -0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, -1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, - if (sphereVAO == 0) - { - glGenVertexArrays(1, &sphereVAO); + Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, -0.5f), glm::vec2(1.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(0.5f, 0.5f, 0.5f), glm::vec2(1.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec2(0.0f, 0.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + Vertex{ glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec2(0.0f, 1.0f), glm::vec3(0, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), 1.0f }, + }; - unsigned int vbo, ebo; - glGenBuffers(1, &vbo); - glGenBuffers(1, &ebo); + void MeshComponent::LoadModel(const std::string path) { + //Assimp::Importer import; + //const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs); + // + //if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) + //{ + // printf("ERROR::ASSIMP::"); + // return; + //} + // + //ProcessNode(scene->mRootNode, scene); + } + unsigned int sphereVAO = 0; + unsigned int indexCount; + void MeshComponent::RenderSphere() { - std::vector positions; - std::vector uv; - std::vector normals; - std::vector indices; - - const unsigned int X_SEGMENTS = 64; - const unsigned int Y_SEGMENTS = 64; - const float PI = 3.14159265359; - for (unsigned int y = 0; y <= Y_SEGMENTS; ++y) + if (sphereVAO == 0) { - for (unsigned int x = 0; x <= X_SEGMENTS; ++x) - { - float xSegment = (float)x / (float)X_SEGMENTS; - float ySegment = (float)y / (float)Y_SEGMENTS; - float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI); - float yPos = std::cos(ySegment * PI); - float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI); + glGenVertexArrays(1, &sphereVAO); - positions.push_back(glm::vec3(xPos, yPos, zPos)); - uv.push_back(glm::vec2(xSegment, ySegment)); - normals.push_back(glm::vec3(xPos, yPos, zPos)); - } - } + unsigned int vbo, ebo; + glGenBuffers(1, &vbo); + glGenBuffers(1, &ebo); - bool oddRow = false; - for (unsigned int y = 0; y < Y_SEGMENTS; ++y) - { - if (!oddRow) // even rows: y == 0, y == 2; and so on + std::vector positions; + std::vector uv; + std::vector normals; + std::vector indices; + + const unsigned int X_SEGMENTS = 64; + const unsigned int Y_SEGMENTS = 64; + const float PI = 3.14159265359; + for (unsigned int y = 0; y <= Y_SEGMENTS; ++y) { for (unsigned int x = 0; x <= X_SEGMENTS; ++x) { - indices.push_back(y * (X_SEGMENTS + 1) + x); - indices.push_back((y + 1) * (X_SEGMENTS + 1) + x); + float xSegment = (float)x / (float)X_SEGMENTS; + float ySegment = (float)y / (float)Y_SEGMENTS; + float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI); + float yPos = std::cos(ySegment * PI); + float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI); + + positions.push_back(glm::vec3(xPos, yPos, zPos)); + uv.push_back(glm::vec2(xSegment, ySegment)); + normals.push_back(glm::vec3(xPos, yPos, zPos)); } } - else + + bool oddRow = false; + for (unsigned int y = 0; y < Y_SEGMENTS; ++y) { - for (int x = X_SEGMENTS; x >= 0; --x) + if (!oddRow) // even rows: y == 0, y == 2; and so on { - indices.push_back((y + 1) * (X_SEGMENTS + 1) + x); - indices.push_back(y * (X_SEGMENTS + 1) + x); + for (unsigned int x = 0; x <= X_SEGMENTS; ++x) + { + indices.push_back(y * (X_SEGMENTS + 1) + x); + indices.push_back((y + 1) * (X_SEGMENTS + 1) + x); + } + } + else + { + for (int x = X_SEGMENTS; x >= 0; --x) + { + indices.push_back((y + 1) * (X_SEGMENTS + 1) + x); + indices.push_back(y * (X_SEGMENTS + 1) + x); + } + } + oddRow = !oddRow; + } + indexCount = indices.size(); + + std::vector data; + for (std::size_t i = 0; i < positions.size(); ++i) + { + data.push_back(positions[i].x); + data.push_back(positions[i].y); + data.push_back(positions[i].z); + + if (uv.size() > 0) + { + data.push_back(uv[i].x); + data.push_back(uv[i].y); + } + if (normals.size() > 0) + { + data.push_back(normals[i].x); + data.push_back(normals[i].y); + data.push_back(normals[i].z); } } - oddRow = !oddRow; - } - indexCount = indices.size(); + glBindVertexArray(sphereVAO); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); + float stride = (3 + 2 + 3) * sizeof(float); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); + glEnableVertexAttribArray(0); - std::vector data; - for (std::size_t i = 0; i < positions.size(); ++i) - { - data.push_back(positions[i].x); - data.push_back(positions[i].y); - data.push_back(positions[i].z); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3)); + glEnableVertexAttribArray(1); - if (uv.size() > 0) - { - data.push_back(uv[i].x); - data.push_back(uv[i].y); - } - if (normals.size() > 0) - { - data.push_back(normals[i].x); - data.push_back(normals[i].y); - data.push_back(normals[i].z); - } + glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5)); + glEnableVertexAttribArray(2); + + glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8)); + glEnableVertexAttribArray(3); } + glBindVertexArray(sphereVAO); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); - float stride = (3 + 2 + 3) * sizeof(float); + glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0); + + } + + //void MeshComponent::ProcessNode(aiNode * node, const aiScene* scene) + //{ + /// process all the node's meshes (if any) + //or (unsigned int i = 0; i < node->mNumMeshes; i++) + // + // aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; + // meshes.push_back(ProcessNode(mesh, scene)); + // + /// then do the same for each of its children + //or (unsigned int i = 0; i < node->mNumChildren; i++) + // + // ProcessNode(node->mChildren[i], scene); + // + //} + + MeshComponent::MeshComponent() { + //BuildTangents(); + + // Setup buffers + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + + glGenBuffers(1, &VBO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + // Position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); glEnableVertexAttribArray(0); - + + // UV glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3)); glEnableVertexAttribArray(1); + // Normal glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5)); glEnableVertexAttribArray(2); - glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8)); + // Tangent + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8)); glEnableVertexAttribArray(3); - } - glBindVertexArray(sphereVAO); - glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0); + // Bitangent + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 11)); + glEnableVertexAttribArray(4); -} + // Texture + glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 14)); + glEnableVertexAttribArray(5); -//void MeshComponent::ProcessNode(aiNode * node, const aiScene* scene) -//{ - /// process all the node's meshes (if any) - //or (unsigned int i = 0; i < node->mNumMeshes; i++) - // - // aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; - // meshes.push_back(ProcessNode(mesh, scene)); - // - /// then do the same for each of its children - //or (unsigned int i = 0; i < node->mNumChildren; i++) - // - // ProcessNode(node->mChildren[i], scene); - // -//} + //m_Material = MaterialManager::Get()->LoadMaterial("Planks"); -MeshComponent::MeshComponent() { - //BuildTangents(); + } - // Setup buffers - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); + void MeshComponent::BuildTangents() + { + for (int i = 0; i < 36; i += 3) { + glm::vec3 pos1 = vertices[i].position; + glm::vec3 pos2 = vertices[i + 1].position; + glm::vec3 pos3 = vertices[i + 2].position; - glGenBuffers(1, &VBO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); + glm::vec2 uv1 = vertices[i].uv; + glm::vec2 uv2 = vertices[i + 1].uv; + glm::vec2 uv3 = vertices[i + 2].uv; - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glm::vec3 edge1 = pos2 - pos1; + glm::vec3 edge2 = pos3 - pos1; + glm::vec2 deltaUV1 = uv2 - uv1; + glm::vec2 deltaUV2 = uv3 - uv1; - // Position - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); - glEnableVertexAttribArray(0); - - // UV - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 3)); - glEnableVertexAttribArray(1); + float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); - // Normal - glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 5)); - glEnableVertexAttribArray(2); + for (int j = 0; i < 3; i++) + { + vertices[i + j].tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); + vertices[i + j].tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); + vertices[i + j].tangent.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); - // Tangent - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 8)); - glEnableVertexAttribArray(3); - - // Bitangent - glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 11)); - glEnableVertexAttribArray(4); - - // Texture - glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(sizeof(GL_FLOAT) * 14)); - glEnableVertexAttribArray(5); - - //m_Material = MaterialManager::Get()->LoadMaterial("Planks"); - -} - -void MeshComponent::BuildTangents() -{ - for (int i = 0; i < 36; i += 3) { - glm::vec3 pos1 = vertices[i].position; - glm::vec3 pos2 = vertices[i + 1].position; - glm::vec3 pos3 = vertices[i + 2].position; - - glm::vec2 uv1 = vertices[i].uv; - glm::vec2 uv2 = vertices[i + 1].uv; - glm::vec2 uv3 = vertices[i + 2].uv; - - glm::vec3 edge1 = pos2 - pos1; - glm::vec3 edge2 = pos3 - pos1; - glm::vec2 deltaUV1 = uv2 - uv1; - glm::vec2 deltaUV2 = uv3 - uv1; - - float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); - - for (int j = 0; i < 3; i++) - { - vertices[i + j].tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); - vertices[i + j].tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); - vertices[i + j].tangent.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); - - vertices[i + j].bitangent.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); - vertices[i + j].bitangent.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); - vertices[i + j].bitangent.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); + vertices[i + j].bitangent.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); + vertices[i + j].bitangent.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); + vertices[i + j].bitangent.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); + } } } -} - -void MeshComponent::SetMaterial(const std::string materialName) -{ - m_Material = MaterialManager::Get()->LoadMaterial(materialName); -} - -void MeshComponent::Draw(glm::mat4 projection, glm::mat4 view, glm::mat4 transform) { - - Renderer::m_Shader->SetUniformMat4f("u_Model", transform); - - m_Material->Bind(); - - //RenderSphere(); - glBindVertexArray(VAO); - glDrawArrays(GL_TRIANGLES, 0, 36); -} - -void MeshComponent::DrawEditor() { - int choice = 0; - ImGui::Combo("Material", (int*)&choice, "Marble\0Copper\0Gold\0Paving\0Planks\0Default Material"); - - + + void MeshComponent::SetMaterial(const std::string materialName) + { + m_Material = MaterialManager::Get()->LoadMaterial(materialName); + } + + void MeshComponent::Draw(glm::mat4 projection, glm::mat4 view, glm::mat4 transform) { + + Renderer::m_Shader->SetUniformMat4f("u_Model", transform); + + m_Material->Bind(); + + //RenderSphere(); + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + void MeshComponent::DrawEditor() { + int choice = 0; + ImGui::Combo("Material", (int*)&choice, "Marble\0Copper\0Gold\0Paving\0Planks\0Default Material"); + } } diff --git a/Nuake/src/Scene/Components/MeshComponent.h b/Nuake/src/Scene/Components/MeshComponent.h index 58586084..19853ba1 100644 --- a/Nuake/src/Scene/Components/MeshComponent.h +++ b/Nuake/src/Scene/Components/MeshComponent.h @@ -3,22 +3,24 @@ #include #include "BaseComponent.h" -class MeshComponent { +namespace Nuake { + class MeshComponent { -private: - unsigned int VAO; - unsigned int VBO; - Ref m_Material; + private: + unsigned int VAO; + unsigned int VBO; + Ref m_Material; - void BuildTangents(); -public: - void LoadModel(const std::string path); - //void ProcessNode(aiNode* node, const aiScene* scene); - MeshComponent(); + void BuildTangents(); + public: + void LoadModel(const std::string path); + //void ProcessNode(aiNode* node, const aiScene* scene); + MeshComponent(); - void SetMaterial(const std::string materialName); - void Draw(glm::mat4 projection, glm::mat4 view, glm::mat4 transform); - void DrawEditor(); + void SetMaterial(const std::string materialName); + void Draw(glm::mat4 projection, glm::mat4 view, glm::mat4 transform); + void DrawEditor(); - void RenderSphere(); -}; \ No newline at end of file + void RenderSphere(); + }; +} diff --git a/Nuake/src/Scene/Components/ModelComponent.cpp b/Nuake/src/Scene/Components/ModelComponent.cpp index 45c88dd1..4cbf7b19 100644 --- a/Nuake/src/Scene/Components/ModelComponent.cpp +++ b/Nuake/src/Scene/Components/ModelComponent.cpp @@ -1,136 +1,139 @@ #include "ModelComponent.h" -#include "../../../Rendering/Textures/Material.h" -#include "../../../Rendering/Renderer.h" -#include "../../../Core/TextureManager.h" +#include "src/Rendering/Textures/Material.h" +#include "src/Rendering/Renderer.h" +#include "src/Core/TextureManager.h" -void ModelComponent::Draw() -{ - for (auto m : meshes) { - m.Draw(); - } -} - -void ModelComponent::LoadModel() -{ - this->meshes.clear(); - Assimp::Importer import; - import.SetPropertyFloat("PP_GSN_MAX_SMOOTHING_ANGLE", 90); - const aiScene* scene = import.ReadFile(FileSystem::Root + ModelPath, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace); - - if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) +namespace Nuake { + void ModelComponent::Draw() { - Logger::Log("ASSIMP! Failed to load model" + std::string(import.GetErrorString()), CRITICAL); - return; - } - - ProcessNode(scene->mRootNode, scene); -} - -void ModelComponent::ProcessNode(aiNode* node, const aiScene* scene) -{ - // process all the node's meshes (if any) - for (unsigned int i = 0; i < node->mNumMeshes; i++) - { - aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; - meshes.push_back(ProcessMesh(mesh, scene)); - } - // then do the same for each of its children - for (unsigned int i = 0; i < node->mNumChildren; i++) - { - ProcessNode(node->mChildren[i], scene); - } -} - -Mesh ModelComponent::ProcessMesh(aiMesh* mesh, const aiScene* scene) -{ - std::vector vertices; - std::vector indices; - std::vector textures; - - for (unsigned int i = 0; i < mesh->mNumVertices; i++) - { - Vertex vertex; - vertex.texture = 1.0f; - - glm::vec3 vector; - vector.x = mesh->mVertices[i].x; - vector.y = mesh->mVertices[i].y; - vector.z = mesh->mVertices[i].z; - vertex.position = vector; - - vector.x = mesh->mNormals[i].x; - vector.y = mesh->mNormals[i].y; - vector.z = mesh->mNormals[i].z; - vertex.normal = vector; - - vector.x = mesh->mTangents[i].x; - vector.y = mesh->mTangents[i].y; - vector.z = mesh->mTangents[i].z; - vertex.tangent = vector; - - vector.x = mesh->mBitangents[i].x; - vector.y = mesh->mBitangents[i].y; - vector.z = mesh->mBitangents[i].z; - vertex.bitangent = vector; - - if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates? - { - glm::vec2 vec; - vec.x = mesh->mTextureCoords[0][i].x; - vec.y = mesh->mTextureCoords[0][i].y; - vertex.uv = vec; + for (auto m : meshes) { + m.Draw(); } - else - vertex.uv = glm::vec2(0.0f, 0.0f); - - vertices.push_back(vertex); } - // process indices - for (unsigned int i = 0; i < mesh->mNumFaces; i++) + + void ModelComponent::LoadModel() { - aiFace face = mesh->mFaces[i]; - for (unsigned int j = 0; j < face.mNumIndices; j++) - indices.push_back(face.mIndices[j]); + this->meshes.clear(); + Assimp::Importer import; + import.SetPropertyFloat("PP_GSN_MAX_SMOOTHING_ANGLE", 90); + const aiScene* scene = import.ReadFile(FileSystem::Root + ModelPath, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace); + + if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) + { + Logger::Log("ASSIMP! Failed to load model" + std::string(import.GetErrorString()), CRITICAL); + return; + } + + ProcessNode(scene->mRootNode, scene); } - // process material - if (mesh->mMaterialIndex >= 0) + + void ModelComponent::ProcessNode(aiNode* node, const aiScene* scene) { - aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; - aiString str; - std::string directory = FileSystem::Root + this->ModelPath + "/../"; - material->GetTexture(aiTextureType_DIFFUSE, 0, &str); - Ref newMaterial = CreateRef(TextureManager::Get()->GetTexture(directory + str.C_Str())); + // process all the node's meshes (if any) + for (unsigned int i = 0; i < node->mNumMeshes; i++) + { + aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; + meshes.push_back(ProcessMesh(mesh, scene)); + } + // then do the same for each of its children + for (unsigned int i = 0; i < node->mNumChildren; i++) + { + ProcessNode(node->mChildren[i], scene); + } + } - //material->GetTexture(aiTextureType_NORMALS, 0, &str); - //newMaterial->SetNormal(TextureManager::Get()->GetTexture(directory + str.C_Str())); - // - //material->GetTexture(aiTextureType_METALNESS, 0, &str); - //newMaterial->SetMetalness(TextureManager::Get()->GetTexture(directory + str.C_Str())); - // - //material->GetTexture(aiTextureType_DIFFUSE_ROUGHNESS, 0, &str); - //newMaterial->SetRoughness(TextureManager::Get()->GetTexture(directory + str.C_Str())); + Mesh ModelComponent::ProcessMesh(aiMesh* mesh, const aiScene* scene) + { + std::vector vertices; + std::vector indices; + std::vector textures; - //material->GetTexture(aiTextureType_DISPLACEMENT, 0, &str); - //newMaterial->SetDisplacement(TextureManager::Get()->GetTexture(directory + str.C_Str())); + for (unsigned int i = 0; i < mesh->mNumVertices; i++) + { + Vertex vertex; + vertex.texture = 1.0f; - //material->GetTexture(aiTextureType_AMBIENT_OCCLUSION, 0, &str); - //newMaterial->SetAO(TextureManager::Get()->GetTexture(directory + str.C_Str())); + glm::vec3 vector; + vector.x = mesh->mVertices[i].x; + vector.y = mesh->mVertices[i].y; + vector.z = mesh->mVertices[i].z; + vertex.position = vector; - return Mesh(vertices, indices, newMaterial); + vector.x = mesh->mNormals[i].x; + vector.y = mesh->mNormals[i].y; + vector.z = mesh->mNormals[i].z; + vertex.normal = vector; + + vector.x = mesh->mTangents[i].x; + vector.y = mesh->mTangents[i].y; + vector.z = mesh->mTangents[i].z; + vertex.tangent = vector; + + vector.x = mesh->mBitangents[i].x; + vector.y = mesh->mBitangents[i].y; + vector.z = mesh->mBitangents[i].z; + vertex.bitangent = vector; + + if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates? + { + glm::vec2 vec; + vec.x = mesh->mTextureCoords[0][i].x; + vec.y = mesh->mTextureCoords[0][i].y; + vertex.uv = vec; + } + else + vertex.uv = glm::vec2(0.0f, 0.0f); + + vertices.push_back(vertex); + } + // process indices + for (unsigned int i = 0; i < mesh->mNumFaces; i++) + { + aiFace face = mesh->mFaces[i]; + for (unsigned int j = 0; j < face.mNumIndices; j++) + indices.push_back(face.mIndices[j]); + } + // process material + if (mesh->mMaterialIndex >= 0) + { + aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; + aiString str; + std::string directory = FileSystem::Root + this->ModelPath + "/../"; + material->GetTexture(aiTextureType_DIFFUSE, 0, &str); + Ref newMaterial = CreateRef(TextureManager::Get()->GetTexture(directory + str.C_Str())); + + //material->GetTexture(aiTextureType_NORMALS, 0, &str); + //newMaterial->SetNormal(TextureManager::Get()->GetTexture(directory + str.C_Str())); + // + //material->GetTexture(aiTextureType_METALNESS, 0, &str); + //newMaterial->SetMetalness(TextureManager::Get()->GetTexture(directory + str.C_Str())); + // + //material->GetTexture(aiTextureType_DIFFUSE_ROUGHNESS, 0, &str); + //newMaterial->SetRoughness(TextureManager::Get()->GetTexture(directory + str.C_Str())); + + //material->GetTexture(aiTextureType_DISPLACEMENT, 0, &str); + //newMaterial->SetDisplacement(TextureManager::Get()->GetTexture(directory + str.C_Str())); + + //material->GetTexture(aiTextureType_AMBIENT_OCCLUSION, 0, &str); + //newMaterial->SetAO(TextureManager::Get()->GetTexture(directory + str.C_Str())); + + return Mesh(vertices, indices, newMaterial); + } + } + + std::vector ModelComponent::LoadMaterialTextures(aiMaterial* mat, aiTextureType type) + { + std::vector textures; + for (unsigned int i = 0; i < mat->GetTextureCount(type); i++) + { + aiString str; + mat->GetTexture(type, i, &str); + std::string fixedStr = std::string(str.C_Str()); + + Texture* texture = new Texture(directory + fixedStr); + textures.push_back(texture); + } + return textures; } } -std::vector ModelComponent::LoadMaterialTextures(aiMaterial* mat, aiTextureType type) -{ - std::vector textures; - for (unsigned int i = 0; i < mat->GetTextureCount(type); i++) - { - aiString str; - mat->GetTexture(type, i, &str); - std::string fixedStr = std::string(str.C_Str()); - - Texture* texture = new Texture(directory + fixedStr); - textures.push_back(texture); - } - return textures; -} diff --git a/Nuake/src/Scene/Components/ModelComponent.h b/Nuake/src/Scene/Components/ModelComponent.h index df6d9452..606caad5 100644 --- a/Nuake/src/Scene/Components/ModelComponent.h +++ b/Nuake/src/Scene/Components/ModelComponent.h @@ -1,30 +1,32 @@ #pragma once #include #include -#include "../Rendering/Mesh/Mesh.h" +#include "src/Rendering/Mesh/Mesh.h" #include "assimp/Importer.hpp" #include #include #include -class ModelComponent + +namespace Nuake { -public: - std::string ModelPath; - - ModelComponent() + class ModelComponent { - //loadModel(path); - } - void LoadModel(); - void Draw(); -private: - // model data - std::vector meshes; - std::string directory; + public: + std::string ModelPath; - - void ProcessNode(aiNode* node, const aiScene* scene); - Mesh ProcessMesh(aiMesh* mesh, const aiScene* scene); - std::vector LoadMaterialTextures(aiMaterial* mat, aiTextureType type); -}; \ No newline at end of file + ModelComponent() + { + //loadModel(path); + } + void LoadModel(); + void Draw(); + private: + std::vector meshes; + std::string directory; + + void ProcessNode(aiNode* node, const aiScene* scene); + Mesh ProcessMesh(aiMesh* mesh, const aiScene* scene); + std::vector LoadMaterialTextures(aiMaterial* mat, aiTextureType type); + }; +} diff --git a/Nuake/src/Scene/Components/NameComponent.h b/Nuake/src/Scene/Components/NameComponent.h index 9431fce9..f64a2d68 100644 --- a/Nuake/src/Scene/Components/NameComponent.h +++ b/Nuake/src/Scene/Components/NameComponent.h @@ -1,28 +1,33 @@ #pragma once -#include "../Resource/Serializable.h" -#include "../Core/OS.h" -class NameComponent { -public: - std::string Name = "Entity"; - int ID; +#include "src/Resource/Serializable.h" +#include "src/Core/OS.h" - json Serialize() +namespace Nuake { + class NameComponent { - BEGIN_SERIALIZE(); + public: + std::string Name = "Entity"; + int ID; + + json Serialize() + { + BEGIN_SERIALIZE(); SERIALIZE_VAL(Name); SERIALIZE_VAL(ID); - END_SERIALIZE(); - } + END_SERIALIZE(); + } - bool Deserialize(const std::string& str) - { - BEGIN_DESERIALIZE(); - Name = j["Name"]; - if (j.contains("ID")) - ID = j["ID"]; - else - ID = OS::GetTime(); + bool Deserialize(const std::string& str) + { + BEGIN_DESERIALIZE(); + Name = j["Name"]; - return true; - } -}; \ No newline at end of file + if (j.contains("ID")) + ID = j["ID"]; + else + ID = OS::GetTime(); + + return true; + } + }; +} diff --git a/Nuake/src/Scene/Components/NativeScriptComponent.h b/Nuake/src/Scene/Components/NativeScriptComponent.h index a1fbc8d8..0a7e17c1 100644 --- a/Nuake/src/Scene/Components/NativeScriptComponent.h +++ b/Nuake/src/Scene/Components/NativeScriptComponent.h @@ -2,17 +2,18 @@ #include #include "../Core/Timestep.h" #include "../Entities/ScriptableEntity.h" + struct NativeScriptComponent { - ScriptableEntity* Instance = nullptr; - - ScriptableEntity *(*InstantiateScript)(); - void (*DestroyScript)(NativeScriptComponent*); - - template - void Bind() - { - InstantiateScript = []() { return static_cast(new T()); }; - DestroyScript = [](NativeScriptComponent* nsc) { delete nsc->Instance; nsc->Instance = nullptr; }; - } + //ScriptableEntity* Instance = nullptr; + // + //ScriptableEntity *(*InstantiateScript)(); + //void (*DestroyScript)(NativeScriptComponent*); + // + //template + //void Bind() + //{ + // InstantiateScript = []() { return static_cast(new T()); }; + // DestroyScript = [](NativeScriptComponent* nsc) { delete nsc->Instance; nsc->Instance = nullptr; }; + //} }; \ No newline at end of file diff --git a/Nuake/src/Scene/Components/ParentComponent.h b/Nuake/src/Scene/Components/ParentComponent.h index e2c1d052..514d963b 100644 --- a/Nuake/src/Scene/Components/ParentComponent.h +++ b/Nuake/src/Scene/Components/ParentComponent.h @@ -1,53 +1,55 @@ #pragma once - #include "../Entities/Entity.h" -struct ParentComponent +namespace Nuake { - int ParentID; - Entity Parent; - bool HasParent = false; - std::vector Children = std::vector(); - - bool RemoveChildren(Entity ent) + struct ParentComponent { - for (int i = 0; i < Children.size(); i++) + int ParentID; + Entity Parent; + bool HasParent = false; + std::vector Children = std::vector(); + + bool RemoveChildren(Entity ent) { - if (Children[i].GetHandle() == ent.GetHandle()) + for (int i = 0; i < Children.size(); i++) { - Children.erase(Children.begin() + i); - return true; + if (Children[i].GetHandle() == ent.GetHandle()) + { + Children.erase(Children.begin() + i); + return true; + } } + + return false; } - return false; - } + json Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(HasParent); + if (HasParent) + SERIALIZE_VAL_LBL("ParentID", Parent.GetID()); - json Serialize() - { - BEGIN_SERIALIZE(); - SERIALIZE_VAL(HasParent); - if(HasParent) - SERIALIZE_VAL_LBL("ParentID", Parent.GetID()); + //int i = 0; + //for (auto& c : Children) { + // j["Children"][0] = c.GetHandle(); + // i++; + //} - //int i = 0; - //for (auto& c : Children) { - // j["Children"][0] = c.GetHandle(); - // i++; - //} - - END_SERIALIZE(); - } + END_SERIALIZE(); + } - bool Deserialize(std::string str) - { - BEGIN_DESERIALIZE(); - this->HasParent = j["HasParent"]; - if(HasParent) - this->ParentID = j["ParentID"]; + bool Deserialize(std::string str) + { + BEGIN_DESERIALIZE(); + this->HasParent = j["HasParent"]; + if (HasParent) + this->ParentID = j["ParentID"]; - //this->Parent = Entity{ j["Parent"], Engine::GetCurrentScene().get() }; - - return true; - } -}; \ No newline at end of file + //this->Parent = Entity{ j["Parent"], Engine::GetCurrentScene().get() }; + + return true; + } + }; +} diff --git a/Nuake/src/Scene/Components/QuakeMap.cpp b/Nuake/src/Scene/Components/QuakeMap.cpp index 4e59b237..ff309095 100644 --- a/Nuake/src/Scene/Components/QuakeMap.cpp +++ b/Nuake/src/Scene/Components/QuakeMap.cpp @@ -1,25 +1,25 @@ #include "QuakeMap.h" -#include "../Core/Core.h" -#include "../Core/MaterialManager.h" +#include "src/Core/Core.h" +#include "src/Core/MaterialManager.h" + +namespace Nuake { + void QuakeMapComponent::Draw() + { + for (auto m : m_Meshes) + m->Draw(); + } + + void QuakeMapComponent::Load(std::string path, bool collisions) + { + if (Path == path) + return; + + Path = path; + } -void QuakeMapComponent::Draw() -{ - for (auto m : m_Meshes) { - m->Draw(); - } -} - -void QuakeMapComponent::Load(std::string path, bool collisions) -{ - if (Path == path) - return; - - Path = path; -} - - -void QuakeMapComponent::DrawEditor() -{ + void QuakeMapComponent::DrawEditor() + { + } } \ No newline at end of file diff --git a/Nuake/src/Scene/Components/QuakeMap.h b/Nuake/src/Scene/Components/QuakeMap.h index c6fdffed..ced79ff5 100644 --- a/Nuake/src/Scene/Components/QuakeMap.h +++ b/Nuake/src/Scene/Components/QuakeMap.h @@ -6,33 +6,36 @@ #include "../Resource/Serializable.h" #include -class QuakeMapComponent { -private: - -public: - std::vector> m_Meshes; - Ref Map; - std::string Path; - bool HasCollisions = false; - void Load(std::string path, bool collisions); - - void Draw(); - void DrawEditor(); - - json Serialize() +namespace Nuake { + class QuakeMapComponent { - BEGIN_SERIALIZE(); - SERIALIZE_VAL(HasCollisions); - SERIALIZE_VAL(Path); - END_SERIALIZE(); - } + private: - bool Deserialize(std::string str) - { - BEGIN_DESERIALIZE(); - this->Path = j["Path"]; - this->HasCollisions = j["HasCollisions"]; + public: + std::vector> m_Meshes; + Ref Map; + std::string Path; + bool HasCollisions = false; + void Load(std::string path, bool collisions); - return true; - } -}; \ No newline at end of file + void Draw(); + void DrawEditor(); + + json Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(HasCollisions); + SERIALIZE_VAL(Path); + END_SERIALIZE(); + } + + bool Deserialize(std::string str) + { + BEGIN_DESERIALIZE(); + this->Path = j["Path"]; + this->HasCollisions = j["HasCollisions"]; + + return true; + } + }; +} diff --git a/Nuake/src/Scene/Components/RigidbodyComponent.cpp b/Nuake/src/Scene/Components/RigidbodyComponent.cpp index 9f3d2937..f11bbdb2 100644 --- a/Nuake/src/Scene/Components/RigidbodyComponent.cpp +++ b/Nuake/src/Scene/Components/RigidbodyComponent.cpp @@ -1,77 +1,79 @@ #pragma once #include "RigidbodyComponent.h" -#include "../Core/Physics/Rigibody.h" -#include "../../../Core/Physics/PhysicsManager.h" -#include "../Rendering/Renderer.h" + +#include "src/Core/Physics/Rigibody.h" +#include "src/Core/Physics/PhysicsManager.h" +#include "src/Rendering/Renderer.h" + +namespace Nuake { + RigidBodyComponent::RigidBodyComponent() + { + //m_Rigidbody = CreateRef(); + } + + Ref RigidBodyComponent::GetRigidBody() const + { + return m_Rigidbody; + } + + void RigidBodyComponent::SetRigidBody(Ref rb) + { + m_Rigidbody = rb; + PhysicsManager::Get()->RegisterBody(rb); + } + + bool RigidBodyComponent::HasRigidBody() const + { + return m_Rigidbody != nullptr; + } + + float RigidBodyComponent::GetMass() { + if (m_Rigidbody) + return m_Rigidbody->GetMass(); + return 0.0f; + } + + void RigidBodyComponent::SetMass(float m) + { + if (!m_Rigidbody) + return; + m_Rigidbody->SetMass(m); + } -RigidBodyComponent::RigidBodyComponent() -{ - //m_Rigidbody = CreateRef(); + void RigidBodyComponent::SyncTransformComponent(TransformComponent* tc) + { + if (!m_Rigidbody) + return; + + glm::vec3 newPosition = m_Rigidbody->GetPosition(); + glm::vec3 newRotation = m_Rigidbody->GetRotation(); + tc->Translation = newPosition; + tc->Rotation = newRotation; + } + + void RigidBodyComponent::SyncWithTransform(TransformComponent* tc) + { + if (!m_Rigidbody) + return; + + btTransform newTransform; + newTransform.setIdentity(); + newTransform.setOrigin(btVector3(tc->Translation.x, tc->Translation.t, tc->Translation.z)); + + btQuaternion quat; + quat.setEulerZYX(tc->Rotation.x, tc->Rotation.y, tc->Rotation.z); + newTransform.setRotation(quat); + m_Rigidbody->UpdateTransform(newTransform); + } + + void RigidBodyComponent::DrawShape(TransformComponent* tc) + { + + } + + + void RigidBodyComponent::DrawEditor() { + + } } - -Ref RigidBodyComponent::GetRigidBody() const -{ - return m_Rigidbody; -} - -void RigidBodyComponent::SetRigidBody(Ref rb) -{ - m_Rigidbody = rb; - PhysicsManager::Get()->RegisterBody(rb); -} - -bool RigidBodyComponent::HasRigidBody() const -{ - return m_Rigidbody != nullptr; -} - -float RigidBodyComponent::GetMass() { - if (m_Rigidbody) - return m_Rigidbody->GetMass(); - return 0.0f; -} - -void RigidBodyComponent::SetMass(float m) -{ - if (!m_Rigidbody) - return; - m_Rigidbody->SetMass(m); -} - - -void RigidBodyComponent::SyncTransformComponent(TransformComponent* tc) -{ - if (!m_Rigidbody) - return; - - glm::vec3 newPosition = m_Rigidbody->GetPosition(); - glm::vec3 newRotation = m_Rigidbody->GetRotation(); - tc->Translation = newPosition; - tc->Rotation = newRotation; -} - -void RigidBodyComponent::SyncWithTransform(TransformComponent* tc) -{ - if (!m_Rigidbody) - return; - - btTransform newTransform; - newTransform.setIdentity(); - newTransform.setOrigin(btVector3(tc->Translation.x, tc->Translation.t, tc->Translation.z)); - - btQuaternion quat; - quat.setEulerZYX(tc->Rotation.x, tc->Rotation.y, tc->Rotation.z); - newTransform.setRotation(quat); - m_Rigidbody->UpdateTransform(newTransform); -} - -void RigidBodyComponent::DrawShape(TransformComponent* tc) -{ - -} - - -void RigidBodyComponent::DrawEditor() { - -} \ No newline at end of file diff --git a/Nuake/src/Scene/Components/RigidbodyComponent.h b/Nuake/src/Scene/Components/RigidbodyComponent.h index 3e312bc9..25519fdb 100644 --- a/Nuake/src/Scene/Components/RigidbodyComponent.h +++ b/Nuake/src/Scene/Components/RigidbodyComponent.h @@ -1,32 +1,34 @@ #pragma once - #include "TransformComponent.h" #include "BaseComponent.h" -#include "../Core/Core.h" -namespace Physics{ - class RigidBody; -}; +#include "src/Core/Core.h" + +namespace Nuake { + namespace Physics + { + class RigidBody; + }; + + class RigidBodyComponent + { + public: + float mass = 0.0f; + Ref m_Rigidbody; + bool IsKinematic = false; + + RigidBodyComponent(); + Ref GetRigidBody() const; + void SetRigidBody(Ref rb); + bool HasRigidBody() const; + + void SetMass(float m); + float GetMass(); + + void SyncTransformComponent(TransformComponent* tc); + void SyncWithTransform(TransformComponent* tc); -class RigidBodyComponent -{ -public: - float mass = 0.0f; - Ref m_Rigidbody; - bool IsKinematic = false; - - RigidBodyComponent(); - Ref GetRigidBody() const; - void SetRigidBody(Ref rb); - bool HasRigidBody() const; - - void SetMass(float m); - float GetMass(); - - void SyncTransformComponent(TransformComponent* tc); - void SyncWithTransform(TransformComponent* tc); - - - void DrawShape(TransformComponent* tc); - void DrawEditor(); -}; \ No newline at end of file + void DrawShape(TransformComponent* tc); + void DrawEditor(); + }; +} diff --git a/Nuake/src/Scene/Components/SphereCollider.h b/Nuake/src/Scene/Components/SphereCollider.h index 18b2966e..6af49480 100644 --- a/Nuake/src/Scene/Components/SphereCollider.h +++ b/Nuake/src/Scene/Components/SphereCollider.h @@ -1,11 +1,13 @@ #pragma once -#include "../Core/Physics/PhysicsShapes.h" -#include "../Core/Core.h" +#include "src/Core/Physics/PhysicsShapes.h" +#include "src/Core/Core.h" -class SphereColliderComponent -{ -public: - Ref Sphere; - float Radius = 0.5f; - bool IsTrigger; -}; \ No newline at end of file +namespace Nuake { + class SphereColliderComponent + { + public: + Ref Sphere; + float Radius = 0.5f; + bool IsTrigger; + }; +} diff --git a/Nuake/src/Scene/Components/TransformComponent.cpp b/Nuake/src/Scene/Components/TransformComponent.cpp index 7a904dad..51d1e9c2 100644 --- a/Nuake/src/Scene/Components/TransformComponent.cpp +++ b/Nuake/src/Scene/Components/TransformComponent.cpp @@ -1,21 +1,24 @@ #pragma once #include "TransformComponent.h" -TransformComponent::TransformComponent() +namespace Nuake { - GlobalTranslation = Vector3(0, 0, 0); - Translation = Vector3(0, 0, 0); - Rotation = Vector3(0, 0, 0); - Scale = Vector3(1, 1, 1); -} + TransformComponent::TransformComponent() + { + GlobalTranslation = Vector3(0, 0, 0); + Translation = Vector3(0, 0, 0); + Rotation = Vector3(0, 0, 0); + Scale = Vector3(1, 1, 1); + } -glm::mat4 TransformComponent::GetTransform() -{ - Matrix4 transform = Matrix4(1.0f); - transform = glm::translate(transform, GlobalTranslation); - transform = glm::rotate(transform, glm::radians(Rotation.x), Vector3(1, 0, 0)); - transform = glm::rotate(transform, glm::radians(Rotation.y), Vector3(0, 1, 0)); - transform = glm::rotate(transform, glm::radians(Rotation.z), Vector3(0, 0, 1)); - transform = glm::scale(transform, Scale); - return transform; -} \ No newline at end of file + glm::mat4 TransformComponent::GetTransform() + { + Matrix4 transform = Matrix4(1.0f); + transform = glm::translate(transform, GlobalTranslation); + transform = glm::rotate(transform, glm::radians(Rotation.x), Vector3(1, 0, 0)); + transform = glm::rotate(transform, glm::radians(Rotation.y), Vector3(0, 1, 0)); + transform = glm::rotate(transform, glm::radians(Rotation.z), Vector3(0, 0, 1)); + transform = glm::scale(transform, Scale); + return transform; + } +} diff --git a/Nuake/src/Scene/Components/TransformComponent.h b/Nuake/src/Scene/Components/TransformComponent.h index 957fb58a..ec74df03 100644 --- a/Nuake/src/Scene/Components/TransformComponent.h +++ b/Nuake/src/Scene/Components/TransformComponent.h @@ -2,33 +2,36 @@ #include "../Core/Maths.h" #include "../Resource/Serializable.h" -class TransformComponent { -public: - Vector3 GlobalTranslation; - Vector3 Translation; - Vector3 Rotation; // TODO: Should use quaternions. - Vector3 Scale; +namespace Nuake +{ + class TransformComponent { + public: + Vector3 GlobalTranslation; + Vector3 Translation; + Vector3 Rotation; // TODO: Should use quaternions. + Vector3 Scale; - TransformComponent(); + TransformComponent(); - Matrix4 GetTransform(); + Matrix4 GetTransform(); - json Serialize() - { - BEGIN_SERIALIZE(); - SERIALIZE_VAL_LBL("Type", "TransformComponent"); - SERIALIZE_VEC3(Translation); - SERIALIZE_VEC3(Rotation); - SERIALIZE_VEC3(Scale); - END_SERIALIZE(); - } + json Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL_LBL("Type", "TransformComponent"); + SERIALIZE_VEC3(Translation); + SERIALIZE_VEC3(Rotation); + SERIALIZE_VEC3(Scale); + END_SERIALIZE(); + } - bool Deserialize(std::string str) - { - BEGIN_DESERIALIZE(); - this->Translation = Vector3(j["Translation"]["x"], j["Translation"]["y"], j["Translation"]["z"]); - this->Rotation = Vector3(j["Rotation"]["x"], j["Rotation"]["y"], j["Rotation"]["z"]); - this->Scale = Vector3(j["Scale"]["x"], j["Scale"]["y"], j["Scale"]["z"]); - return true; - } -}; \ No newline at end of file + bool Deserialize(std::string str) + { + BEGIN_DESERIALIZE(); + this->Translation = Vector3(j["Translation"]["x"], j["Translation"]["y"], j["Translation"]["z"]); + this->Rotation = Vector3(j["Rotation"]["x"], j["Rotation"]["y"], j["Rotation"]["z"]); + this->Scale = Vector3(j["Scale"]["x"], j["Scale"]["y"], j["Scale"]["z"]); + return true; + } + }; +} diff --git a/Nuake/src/Scene/Components/TriggerZone.h b/Nuake/src/Scene/Components/TriggerZone.h index e5a5d085..706474b8 100644 --- a/Nuake/src/Scene/Components/TriggerZone.h +++ b/Nuake/src/Scene/Components/TriggerZone.h @@ -1,37 +1,38 @@ #pragma once -#include "src/Core//Physics/GhostObject.h" +#include "src/Core/Physics/GhostObject.h" #include -# -class TriggerZone { -public: - Ref GhostObject; - std::string target = ""; - std::vector Targets; - bool Enabled = true; +namespace Nuake { + class TriggerZone { + public: + Ref GhostObject; + std::string target = ""; - TriggerZone() { - Targets = std::vector(); - } + std::vector Targets; + bool Enabled = true; + TriggerZone() + { + Targets = std::vector(); + } + int GetOverLappingCount() + { + if (!Enabled) return 0; - int GetOverLappingCount() - { - if (!Enabled) return 0; + return GhostObject->OverlappingCount(); + } - return GhostObject->OverlappingCount(); - } + std::vector GetTargets() { + return Targets; + } - std::vector GetTargets() { - return Targets; - } + std::vector GetOverlappingBodies() + { + if (!Enabled) + return std::vector(); - std::vector GetOverlappingBodies() - { - if (!Enabled) - return std::vector(); - - return GhostObject->GetOverlappingEntities(); - } -}; \ No newline at end of file + return GhostObject->GetOverlappingEntities(); + } + }; +} diff --git a/Nuake/src/Scene/Components/WrenScriptComponent.h b/Nuake/src/Scene/Components/WrenScriptComponent.h index e5687cbf..f7f027a8 100644 --- a/Nuake/src/Scene/Components/WrenScriptComponent.h +++ b/Nuake/src/Scene/Components/WrenScriptComponent.h @@ -1,32 +1,34 @@ #pragma once -#include "../Scripting/WrenScript.h" -#include +#include "src/Scripting/WrenScript.h" +#include "src/Resource/Serializable.h" -class WrenScriptComponent -{ -public: - std::string Script; - std::string Class; - - Ref WrenScript; - - json Serialize() +namespace Nuake { + class WrenScriptComponent { - BEGIN_SERIALIZE(); - SERIALIZE_VAL(Script); - SERIALIZE_VAL(Class); - END_SERIALIZE(); - } + public: + std::string Script; + std::string Class; - bool Deserialize(std::string str) - { - BEGIN_DESERIALIZE(); - if (j.contains("Script")) - Script = j["Script"]; - if (j.contains("Class")) - Class = j["Class"]; - + Ref WrenScript; - return true; - } -}; \ No newline at end of file + json Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(Script); + SERIALIZE_VAL(Class); + END_SERIALIZE(); + } + + bool Deserialize(std::string str) + { + BEGIN_DESERIALIZE(); + if (j.contains("Script")) + Script = j["Script"]; + if (j.contains("Class")) + Class = j["Class"]; + + + return true; + } + }; +} \ No newline at end of file diff --git a/Nuake/src/Scene/EditorCamera.cpp b/Nuake/src/Scene/EditorCamera.cpp index 058a8d67..024df6d8 100644 --- a/Nuake/src/Scene/EditorCamera.cpp +++ b/Nuake/src/Scene/EditorCamera.cpp @@ -3,96 +3,99 @@ #include #include -void EditorCamera::Update(Timestep ts) +namespace Nuake { - float x = Input::GetMouseX(); - float y = Input::GetMouseY(); - - if (!controlled && Input::IsMouseButtonDown(1)) + void EditorCamera::Update(Timestep ts) { - mouseLastX = x; - mouseLastY = y; - } + float x = Input::GetMouseX(); + float y = Input::GetMouseY(); - controlled = Input::IsMouseButtonDown(1); + if (!controlled && Input::IsMouseButtonDown(1)) + { + mouseLastX = x; + mouseLastY = y; + } - //if (!controlled) - // Input::ShowMouse(); - //else - // Input::HideMouse(); + controlled = Input::IsMouseButtonDown(1); - // Should probably not have speed binding in here. - if (Input::IsKeyDown(GLFW_KEY_UP)) - Speed += 0.1f; - else if (Input::IsKeyDown(GLFW_KEY_DOWN)) - Speed -= 0.1f; + //if (!controlled) + // Input::ShowMouse(); + //else + // Input::HideMouse(); - if (Speed < 0) - Speed = 0; - - // Keyboard - if (!controlled) { - return; - } - - if (m_Type == CAMERA_TYPE::ORTHO) { - if (Input::IsKeyDown(GLFW_KEY_RIGHT)) - Translation.x += Speed * ts; - if (Input::IsKeyDown(GLFW_KEY_LEFT)) - Translation.x -= Speed * ts; + // Should probably not have speed binding in here. if (Input::IsKeyDown(GLFW_KEY_UP)) - Translation.y += Speed * ts; - if (Input::IsKeyDown(GLFW_KEY_DOWN)) - Translation.y -= Speed * ts; - } - else { - glm::vec3 movement = glm::vec3(0, 0, 0); + Speed += 0.1f; + else if (Input::IsKeyDown(GLFW_KEY_DOWN)) + Speed -= 0.1f; - if (Input::IsKeyDown(GLFW_KEY_D)) - movement -= cameraRight * (Speed * ts); - if (Input::IsKeyDown(GLFW_KEY_A)) - movement += cameraRight * (Speed * ts); + if (Speed < 0) + Speed = 0; - if (Input::IsKeyDown(GLFW_KEY_W)) - movement += cameraDirection * (Speed * ts); - if (Input::IsKeyDown(GLFW_KEY_S)) - movement -= cameraDirection * (Speed * ts); - if (Input::IsKeyDown(GLFW_KEY_LEFT_SHIFT)) - movement -= up * (Speed * ts); - if (Input::IsKeyDown(GLFW_KEY_SPACE)) - movement += up * (Speed * ts); + // Keyboard + if (!controlled) { + return; + } - Translation += Vector3(movement); - } + if (m_Type == CAMERA_TYPE::ORTHO) { + if (Input::IsKeyDown(GLFW_KEY_RIGHT)) + Translation.x += Speed * ts; + if (Input::IsKeyDown(GLFW_KEY_LEFT)) + Translation.x -= Speed * ts; + if (Input::IsKeyDown(GLFW_KEY_UP)) + Translation.y += Speed * ts; + if (Input::IsKeyDown(GLFW_KEY_DOWN)) + Translation.y -= Speed * ts; + } + else { + glm::vec3 movement = glm::vec3(0, 0, 0); - if (firstMouse) - { + if (Input::IsKeyDown(GLFW_KEY_D)) + movement -= cameraRight * (Speed * ts); + if (Input::IsKeyDown(GLFW_KEY_A)) + movement += cameraRight * (Speed * ts); + + if (Input::IsKeyDown(GLFW_KEY_W)) + movement += cameraDirection * (Speed * ts); + if (Input::IsKeyDown(GLFW_KEY_S)) + movement -= cameraDirection * (Speed * ts); + if (Input::IsKeyDown(GLFW_KEY_LEFT_SHIFT)) + movement -= up * (Speed * ts); + if (Input::IsKeyDown(GLFW_KEY_SPACE)) + movement += up * (Speed * ts); + + Translation += Vector3(movement); + } + + if (firstMouse) + { + mouseLastX = x; + mouseLastY = y; + firstMouse = false; + } + + // mouse + float diffx = x - mouseLastX; + float diffy = mouseLastY - y; mouseLastX = x; mouseLastY = y; - firstMouse = false; + + const float sensitivity = 0.1f; + diffx *= sensitivity; + diffy *= sensitivity; + + Yaw += diffx; + Pitch += diffy; + + if (Pitch > 89.0f) + Pitch = 89.0f; + if (Pitch < -89.0f) + Pitch = -89.0f; + + cameraDirection.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); + cameraDirection.y = sin(glm::radians(Pitch)); + cameraDirection.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); + cameraFront = glm::normalize(cameraDirection); + cameraRight = glm::normalize(glm::cross(up, cameraFront)); } - - // mouse - float diffx = x - mouseLastX; - float diffy = mouseLastY - y; - mouseLastX = x; - mouseLastY = y; - - const float sensitivity = 0.1f; - diffx *= sensitivity; - diffy *= sensitivity; - - Yaw += diffx; - Pitch += diffy; - - if (Pitch > 89.0f) - Pitch = 89.0f; - if (Pitch < -89.0f) - Pitch = -89.0f; - - cameraDirection.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - cameraDirection.y = sin(glm::radians(Pitch)); - cameraDirection.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - cameraFront = glm::normalize(cameraDirection); - cameraRight = glm::normalize(glm::cross(up, cameraFront)); -} \ No newline at end of file +} diff --git a/Nuake/src/Scene/EditorCamera.h b/Nuake/src/Scene/EditorCamera.h index b6102e96..4b35fb8a 100644 --- a/Nuake/src/Scene/EditorCamera.h +++ b/Nuake/src/Scene/EditorCamera.h @@ -2,17 +2,20 @@ #include "../Core/Timestep.h" #include "../Rendering/Camera.h" -class EditorCamera : public Camera +namespace Nuake { -private: - bool controlled = false; - bool firstMouse = false; + class EditorCamera : public Camera + { + public: + void Update(Timestep ts); + private: + bool controlled = false; + bool firstMouse = false; - float mouseLastX; - float mouseLastY; + float mouseLastX; + float mouseLastY; - float Yaw = 0.f; - float Pitch = 0.f; -public: - void Update(Timestep ts); -}; \ No newline at end of file + float Yaw = 0.f; + float Pitch = 0.f; + }; +} diff --git a/Nuake/src/Scene/Entities/Entity.cpp b/Nuake/src/Scene/Entities/Entity.cpp index 7719bff2..e8c6ced3 100644 --- a/Nuake/src/Scene/Entities/Entity.cpp +++ b/Nuake/src/Scene/Entities/Entity.cpp @@ -1,5 +1,3 @@ - - #include "../Components/ParentComponent.h" #include "Entity.h" #include "../Components/NameComponent.h" @@ -10,39 +8,42 @@ #include "../Components/QuakeMap.h" #include "../Components/WrenScriptComponent.h" #include "../Components/CharacterControllerComponent.h" -void Entity::AddChild(Entity ent) + +namespace Nuake { - if ((int)m_EntityHandle != ent.GetHandle()) + void Entity::AddChild(Entity ent) { - ent.GetComponent().HasParent = true; - ent.GetComponent().Parent = *this; + if ((int)m_EntityHandle != ent.GetHandle()) + { + ent.GetComponent().HasParent = true; + ent.GetComponent().Parent = *this; - GetComponent().Children.push_back(ent); + GetComponent().Children.push_back(ent); + } } -} -json Entity::Serialize() -{ - BEGIN_SERIALIZE(); - SERIALIZE_OBJECT_REF_LBL("NameComponent", GetComponent()); - SERIALIZE_OBJECT_REF_LBL("ParentComponent", GetComponent()); - SERIALIZE_OBJECT_REF_LBL("TransformComponent", GetComponent()); - if(HasComponent()) - SERIALIZE_OBJECT_REF_LBL("CameraComponent", GetComponent()); - if(HasComponent()) - SERIALIZE_OBJECT_REF_LBL("QuakeMapComponent", GetComponent()); - if (HasComponent()) - SERIALIZE_OBJECT_REF_LBL("LightComponent", GetComponent()); - if (HasComponent()) - SERIALIZE_OBJECT_REF_LBL("WrenScriptComponent", GetComponent()); - if (HasComponent()) - SERIALIZE_OBJECT_REF_LBL("CharacterControllerComponent", GetComponent()); - END_SERIALIZE(); -} + json Entity::Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_OBJECT_REF_LBL("NameComponent", GetComponent()); + SERIALIZE_OBJECT_REF_LBL("ParentComponent", GetComponent()); + SERIALIZE_OBJECT_REF_LBL("TransformComponent", GetComponent()); + if (HasComponent()) + SERIALIZE_OBJECT_REF_LBL("CameraComponent", GetComponent()); + if (HasComponent()) + SERIALIZE_OBJECT_REF_LBL("QuakeMapComponent", GetComponent()); + if (HasComponent()) + SERIALIZE_OBJECT_REF_LBL("LightComponent", GetComponent()); + if (HasComponent()) + SERIALIZE_OBJECT_REF_LBL("WrenScriptComponent", GetComponent()); + if (HasComponent()) + SERIALIZE_OBJECT_REF_LBL("CharacterControllerComponent", GetComponent()); + END_SERIALIZE(); + } -bool Entity::Deserialize(const std::string& str) -{ - BEGIN_DESERIALIZE(); + bool Entity::Deserialize(const std::string& str) + { + BEGIN_DESERIALIZE(); DESERIALIZE_COMPONENT(TransformComponent); DESERIALIZE_COMPONENT(NameComponent); DESERIALIZE_COMPONENT(ParentComponent); @@ -51,20 +52,21 @@ bool Entity::Deserialize(const std::string& str) DESERIALIZE_COMPONENT(LightComponent); DESERIALIZE_COMPONENT(WrenScriptComponent); DESERIALIZE_COMPONENT(CharacterControllerComponent); - return true; + return true; + } + + Entity::Entity(entt::entity handle, Scene* scene) + { + m_EntityHandle = handle; + m_Scene = scene; + } + + Entity::Entity(const Entity& ent) + { + this->m_EntityHandle = ent.m_EntityHandle; + this->m_Scene = ent.m_Scene; + } + + + Entity::Entity() {} } - -Entity::Entity(entt::entity handle, Scene* scene) -{ - m_EntityHandle = handle; - m_Scene = scene; -} - -Entity::Entity(const Entity& ent) -{ - this->m_EntityHandle = ent.m_EntityHandle; - this->m_Scene = ent.m_Scene; -} - - -Entity::Entity(){} \ No newline at end of file diff --git a/Nuake/src/Scene/Entities/Entity.h b/Nuake/src/Scene/Entities/Entity.h index 0ffc6ad2..8715fa6f 100644 --- a/Nuake/src/Scene/Entities/Entity.h +++ b/Nuake/src/Scene/Entities/Entity.h @@ -5,66 +5,70 @@ #include "../Components/BaseComponent.h" #include "../Resource/Serializable.h" #include "../Components/NameComponent.h" -class Entity : public ISerializable + +namespace Nuake { -public: - Entity(entt::entity handle, Scene* scene); - Entity(const Entity& ent); - Entity(); - - void AddChild(Entity ent); - - int GetHandle() { return (int)m_EntityHandle; } - int GetID() { return GetComponent().ID; } - - template - bool HasComponent() { - return m_Scene->m_Registry.all_of(m_EntityHandle); - } - - bool IsValid() { - return m_Scene->m_Registry.valid((entt::entity)GetHandle()); - } - - template - T& AddComponent() { - T& component = m_Scene->m_Registry.emplace(m_EntityHandle); - return component; - } - - template - void RemoveComponent() { - m_Scene->m_Registry.remove(m_EntityHandle); - } - - template - T& GetComponent() { - T& component = m_Scene->m_Registry.get(m_EntityHandle); - return component; - } - - void Destroy() { - Logger::Log("Deleted eneity :" + std::to_string((int)m_EntityHandle)); - m_Scene->m_Registry.destroy(m_EntityHandle); - } - - bool operator==(const Entity& other) const + class Entity : public ISerializable { - return m_EntityHandle == other.m_EntityHandle && m_Scene == other.m_Scene; - } + public: + Entity(entt::entity handle, Scene* scene); + Entity(const Entity& ent); + Entity(); - bool operator!=(const Entity& other) const - { - return !(*this == other); - } + void AddChild(Entity ent); - json Serialize() override; - bool Deserialize(const std::string& str); + int GetHandle() { return (int)m_EntityHandle; } + int GetID() { return GetComponent().ID; } - Scene* GetScene() { - return m_Scene; - } -private: - entt::entity m_EntityHandle; - Scene* m_Scene; -}; \ No newline at end of file + template + bool HasComponent() { + return m_Scene->m_Registry.all_of(m_EntityHandle); + } + + bool IsValid() { + return m_Scene->m_Registry.valid((entt::entity)GetHandle()); + } + + template + T& AddComponent() { + T& component = m_Scene->m_Registry.emplace(m_EntityHandle); + return component; + } + + template + void RemoveComponent() { + m_Scene->m_Registry.remove(m_EntityHandle); + } + + template + T& GetComponent() { + T& component = m_Scene->m_Registry.get(m_EntityHandle); + return component; + } + + void Destroy() { + Logger::Log("Deleted eneity :" + std::to_string((int)m_EntityHandle)); + m_Scene->m_Registry.destroy(m_EntityHandle); + } + + bool operator==(const Entity& other) const + { + return m_EntityHandle == other.m_EntityHandle && m_Scene == other.m_Scene; + } + + bool operator!=(const Entity& other) const + { + return !(*this == other); + } + + json Serialize() override; + bool Deserialize(const std::string& str); + + Scene* GetScene() { + return m_Scene; + } + private: + entt::entity m_EntityHandle; + Scene* m_Scene; + }; +} diff --git a/Nuake/src/Scene/Entities/ScriptableEntity.h b/Nuake/src/Scene/Entities/ScriptableEntity.h index 1877740c..83e16eba 100644 --- a/Nuake/src/Scene/Entities/ScriptableEntity.h +++ b/Nuake/src/Scene/Entities/ScriptableEntity.h @@ -4,12 +4,3 @@ #include "../Components/ParentComponent.h" #include "../Components/NameComponent.h" -class ScriptableEntity -{ -public: - - virtual void OnCreate() {} - virtual void OnDestroy() {} - virtual void OnUpdate(Timestep ts){} - -}; \ No newline at end of file diff --git a/Nuake/src/Scene/Environment/ProceduralSky.cpp b/Nuake/src/Scene/Environment/ProceduralSky.cpp new file mode 100644 index 00000000..4afbdbe9 --- /dev/null +++ b/Nuake/src/Scene/Environment/ProceduralSky.cpp @@ -0,0 +1,114 @@ +#include "ProceduralSky.h" + +#include "src/Rendering/Renderer.h" +#include "src/Rendering/Shaders/Shader.h" +#include "src/Rendering/Camera.h" + +#include + +namespace Nuake +{ + // TODO: move this to primitive + ProceduralSky::ProceduralSky() { + float quadVertices[] = { + // positions // texture Coords + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + + + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f + }; + + // setup plane VAO + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glBindVertexArray(VAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + } + + void ProceduralSky::Draw(Ref cam) { + + glm::vec3 CameraDirection = cam->GetDirection(); + + Renderer::m_ProceduralSkyShader->Bind(); + Renderer::m_ProceduralSkyShader->SetUniform1f("SurfaceRadius", SurfaceRadius); + Renderer::m_ProceduralSkyShader->SetUniform1f("AtmosphereRadius", AtmosphereRadius); + Renderer::m_ProceduralSkyShader->SetUniform1f("SunIntensity", SunIntensity); + + Renderer::m_ProceduralSkyShader->SetUniform3f("RayleighScattering", + RayleighScattering.r, + RayleighScattering.g, + RayleighScattering.b); + + Renderer::m_ProceduralSkyShader->SetUniform3f("MieScattering", + MieScattering.r, + MieScattering.g, + MieScattering.b); + + Renderer::m_ProceduralSkyShader->SetUniform3f("CenterPoint", + CenterPoint.x, + CenterPoint.y, + CenterPoint.z); + + Renderer::m_ProceduralSkyShader->SetUniform3f("SunDirection", + SunDirection.x, + SunDirection.y, + SunDirection.z); + + Renderer::m_ProceduralSkyShader->SetUniform1f("u_Exposure", cam->Exposure); + + //Renderer::m_ProceduralSkyShader->SetUniform3f("CamDirection", + // CameraDirection.x, + // CameraDirection.y, + // CameraDirection.z); + + + Renderer::m_ProceduralSkyShader->SetUniformMat4f("InvProjection", cam->GetPerspective()); + Renderer::m_ProceduralSkyShader->SetUniformMat4f("InvView", cam->GetTransformRotation()); + //glm::vec3 CamRight = cam->cameraRight; + //Renderer::m_ProceduralSkyShader->SetUniform3f("CamRight", + // CamRight.x, + // CamRight.y, + // CamRight.z); + // + //glm::vec3 CamUp = cam->cameraUp;//glm::normalize(glm::cross(CameraDirection, CamRight)); + + //Renderer::m_ProceduralSkyShader->SetUniform3f("CamUp", + // CamUp.x, + // CamUp.y, + // CamUp.z); + + + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + + glm::vec3 ProceduralSky::GetSunDirection() { + return SunDirection; + } + + json ProceduralSky::Serialize() + { + BEGIN_SERIALIZE() + SERIALIZE_VAL(SurfaceRadius); + SERIALIZE_VAL(AtmosphereRadius); + SERIALIZE_VEC3(RayleighScattering); + SERIALIZE_VEC3(MieScattering); + SERIALIZE_VAL(SunIntensity); + SERIALIZE_VEC3(SunDirection); + END_SERIALIZE(); + } + + bool ProceduralSky::Deserialize(const std::string& str) + { + return false; + } +} diff --git a/Nuake/src/Scene/Environment/ProceduralSky.h b/Nuake/src/Scene/Environment/ProceduralSky.h new file mode 100644 index 00000000..4ed8c699 --- /dev/null +++ b/Nuake/src/Scene/Environment/ProceduralSky.h @@ -0,0 +1,31 @@ +#pragma once +#include "src/Core/Core.h" +#include "src/Core/Maths.h" + +#include "src/Rendering/Vertex.h" +#include "src/Resource/Serializable.h" + +namespace Nuake +{ + class Camera; + class ProceduralSky : ISerializable { + public: + float SurfaceRadius = 6360e3f; + float AtmosphereRadius = 6380e3f; + Vector3 RayleighScattering = Vector3(58e-7f, 135e-7f, 331e-7f); + Vector3 MieScattering = Vector3(2e-5f); + float SunIntensity = 100.0; + + Vector3 CenterPoint = Vector3(0.f, -SurfaceRadius, 0.f); + Vector3 SunDirection = Vector3(0.20000f, 0.95917f, 0.20000f); + unsigned int VAO; + unsigned int VBO; + ProceduralSky(); + void Draw(Ref cam); + + Vector3 GetSunDirection(); + + json Serialize() override; + bool Deserialize(const std::string& str) override; + }; +} diff --git a/Nuake/src/Scene/Environment/Skybox.cpp b/Nuake/src/Scene/Environment/Skybox.cpp new file mode 100644 index 00000000..72e79a01 --- /dev/null +++ b/Nuake/src/Scene/Environment/Skybox.cpp @@ -0,0 +1,171 @@ +#include "Skybox.h" +#include + +#include "src/Rendering/Renderer.h" +#include "src/Rendering/Textures/Cubemap.h" + +namespace Nuake +{ + // TODO: Use cube primitive + glm::vec3 Skybox::vertices[36] + { + glm::vec3(-0.5f, -0.5f, -0.5f), + glm::vec3(0.5f, -0.5f, -0.5f), + glm::vec3(0.5f, 0.5f, -0.5f), + glm::vec3(0.5f, 0.5f, -0.5f), + glm::vec3(-0.5f, 0.5f, -0.5f), + glm::vec3(-0.5f, -0.5f, -0.5f), + + glm::vec3(-0.5f, -0.5f, 0.5f), + glm::vec3(0.5f, -0.5f, 0.5f), + glm::vec3(0.5f, 0.5f, 0.5f), + glm::vec3(0.5f, 0.5f, 0.5f), + glm::vec3(-0.5f, 0.5f, 0.5f), + glm::vec3(-0.5f, -0.5f, 0.5f), + + glm::vec3(-0.5f, 0.5f, 0.5f), + glm::vec3(-0.5f, 0.5f, -0.5f), + glm::vec3(-0.5f, -0.5f, -0.5f), + glm::vec3(-0.5f, -0.5f, -0.5f), + glm::vec3(-0.5f, -0.5f, 0.5f), + glm::vec3(-0.5f, 0.5f, 0.5f), + + glm::vec3(0.5f, 0.5f, 0.5f), + glm::vec3(0.5f, 0.5f, -0.5f), + glm::vec3(0.5f, -0.5f, -0.5f), + glm::vec3(0.5f, -0.5f, -0.5f), + glm::vec3(0.5f, -0.5f, 0.5f), + glm::vec3(0.5f, 0.5f, 0.5f), + + glm::vec3(-0.5f, -0.5f, -0.5f), + glm::vec3(0.5f, -0.5f, -0.5f), + glm::vec3(0.5f, -0.5f, 0.5f), + glm::vec3(0.5f, -0.5f, 0.5f), + glm::vec3(-0.5f, -0.5f, 0.5f), + glm::vec3(-0.5f, -0.5f, -0.5f), + + glm::vec3(-0.5f, 0.5f, -0.5f) , + glm::vec3(0.5f, 0.5f, -0.5f) , + glm::vec3(0.5f, 0.5f, 0.5f) , + glm::vec3(0.5f, 0.5f, 0.5f) , + glm::vec3(-0.5f, 0.5f, 0.5f) , + glm::vec3(-0.5f, 0.5f, -0.5f) + }; + + Skybox::Skybox() + { + // Setup buffers + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + + glGenBuffers(1, &VBO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0); + glEnableVertexAttribArray(0); + + // TODO: mem leak. + m_Texture = new CubemapTexture("Res/Textures/Skyboxes/1/japan"); + m_Hdr = new HDRTexture("Res/Textures/Skyboxes/HDR/OldIndustrialHall.jpg"); + } + + void Skybox::Draw(glm::mat4 projection, glm::mat4 view) + { + + glDepthMask(GL_FALSE); + m_Texture->Bind(3); + m_Hdr->Bind(4); + Renderer::m_SkyboxShader->Bind(); + m_Hdr->BindCubemap(5); + Renderer::m_SkyboxShader->SetUniformMat4f("projection", projection); + Renderer::m_SkyboxShader->SetUniformMat4f("view", view); + + Renderer::m_SkyboxShader->SetUniform1i("isHDR", 0); + Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 4); + Renderer::m_SkyboxShader->SetUniform1i("skybox", 5); + + // ... set view and projection matrix + glBindVertexArray(VAO); + + glDrawArrays(GL_TRIANGLES, 0, 36); + glDepthMask(GL_TRUE); + //Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f); + } + + + void Skybox::Push() + { + m_Hdr->BindCubemap(5); + Renderer::m_Shader->SetUniform1i("u_IrradianceMap", 5); + } + + + void Skybox::CreateHDRCubemap() + { + unsigned int captureFBO, captureRBO; + glGenFramebuffers(1, &captureFBO); + glGenRenderbuffers(1, &captureRBO); + + glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); + glBindRenderbuffer(GL_RENDERBUFFER, captureRBO); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO); + + unsigned int envCubemap; + glGenTextures(1, &envCubemap); + glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap); + for (unsigned int i = 0; i < 6; ++i) + { + // note that we store each face with 16 bit floating point values + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, + 512, 512, 0, GL_RGB, GL_FLOAT, nullptr); + } + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f); + glm::mat4 captureViews[] = + { + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)), + glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)) + }; + + m_Hdr->Bind(5); + + // convert HDR equirectangular environment map to cubemap equivalent + Renderer::m_SkyboxShader->Bind(); + Renderer::m_SkyboxShader->SetUniformMat4f("projection", captureProjection); + Renderer::m_SkyboxShader->SetUniform1i("convulate", 0); + Renderer::m_SkyboxShader->SetUniform1i("isHDR", 1); + Renderer::m_SkyboxShader->SetUniform1i("equirectangularMap", 5); + glActiveTexture(GL_TEXTURE0); + + glViewport(0, 0, 512, 512); // don't forget to configure the viewport to the capture dimensions. + glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); + for (unsigned int i = 0; i < 6; ++i) + { + Renderer::m_SkyboxShader->SetUniformMat4f("view", captureViews[i]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, envCubemap, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBindVertexArray(VAO); + + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + m_Hdr->SetCubemapId(envCubemap); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } +} + + diff --git a/Nuake/src/Scene/Environment/Skybox.h b/Nuake/src/Scene/Environment/Skybox.h new file mode 100644 index 00000000..e5bdf99d --- /dev/null +++ b/Nuake/src/Scene/Environment/Skybox.h @@ -0,0 +1,28 @@ +#pragma once +#include "src/Core/Maths.h" +#include "src/Rendering/Textures/HDR.h" + +namespace Nuake +{ + class CubemapTexture; + + class Skybox { + public: + Skybox(); + void CreateHDRCubemap(); + + void Draw(glm::mat4 projection, glm::mat4 view); + void Push(); + + private: + unsigned int VBO; + unsigned int VAO; + + // Always the same buffer. + // TODO: Use primitive. + static glm::vec3 vertices[]; + + CubemapTexture* m_Texture; + HDRTexture* m_Hdr; + }; +} diff --git a/Nuake/src/Rendering/SkyboxHDR.cpp b/Nuake/src/Scene/Environment/SkyboxHDR.cpp similarity index 100% rename from Nuake/src/Rendering/SkyboxHDR.cpp rename to Nuake/src/Scene/Environment/SkyboxHDR.cpp diff --git a/Nuake/src/Rendering/SkyboxHDR.h b/Nuake/src/Scene/Environment/SkyboxHDR.h similarity index 100% rename from Nuake/src/Rendering/SkyboxHDR.h rename to Nuake/src/Scene/Environment/SkyboxHDR.h diff --git a/Nuake/src/Scene/Lighting/Environment.cpp b/Nuake/src/Scene/Lighting/Environment.cpp index 3196d73c..2fa07f28 100644 --- a/Nuake/src/Scene/Lighting/Environment.cpp +++ b/Nuake/src/Scene/Lighting/Environment.cpp @@ -1,42 +1,46 @@ #pragma once #include "Environment.h" -#include "../Rendering/Renderer.h" -#include "../Core/Core.h" -Environment::Environment() -{ - m_AmbientColor = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); - ProceduralSkybox = CreateRef(); -} +#include "src/Rendering/Renderer.h" +#include "src/Core/Core.h" -// Ambient Light -glm::vec4 Environment::GetAmbientColor() -{ - return m_AmbientColor; -} +namespace Nuake { + Environment::Environment() + { + m_AmbientColor = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); + ProceduralSkybox = CreateRef(); + } -void Environment::SetAmbientColor(glm::vec4 color) -{ - m_AmbientColor = color; -} + // Ambient Light + glm::vec4 Environment::GetAmbientColor() + { + return m_AmbientColor; + } -void Environment::Push() { - //Renderer::m_Shader->SetUniform3f("u_AmbientColor", m_AmbientColor.r, m_AmbientColor.g, m_AmbientColor.b); - //Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f); - Renderer::m_Shader->SetUniform1f("u_FogAmount", VolumetricFog); - Renderer::m_Shader->SetUniform1f("u_FogStepCount", VolumetricStepCount); -} + void Environment::SetAmbientColor(glm::vec4 color) + { + m_AmbientColor = color; + } -json Environment::Serialize() -{ - BEGIN_SERIALIZE(); + void Environment::Push() { + //Renderer::m_Shader->SetUniform3f("u_AmbientColor", m_AmbientColor.r, m_AmbientColor.g, m_AmbientColor.b); + //Renderer::m_Shader->SetUniform4f("u_AmbientColor", 1.0f, 1.0f, 1.0f, 1.0f); + Renderer::m_Shader->SetUniform1f("u_FogAmount", VolumetricFog); + Renderer::m_Shader->SetUniform1f("u_FogStepCount", VolumetricStepCount); + } + + json Environment::Serialize() + { + BEGIN_SERIALIZE(); SERIALIZE_VAL(VolumetricFog); SERIALIZE_VAL(VolumetricStepCount); SERIALIZE_VEC4(AmbientColor); SERIALIZE_OBJECT(ProceduralSkybox); - END_SERIALIZE(); + END_SERIALIZE(); + } + + bool Environment::Deserialize(const std::string& str) + { + return false; + } } -bool Environment::Deserialize(const std::string& str) -{ - return false; -} diff --git a/Nuake/src/Scene/Lighting/Environment.h b/Nuake/src/Scene/Lighting/Environment.h index 9db34f22..92db2687 100644 --- a/Nuake/src/Scene/Lighting/Environment.h +++ b/Nuake/src/Scene/Lighting/Environment.h @@ -1,26 +1,28 @@ #pragma once -#include -#include -#include "../Core/Core.h" -#include "../Rendering/ProceduralSky.h" -#include "../Resource/Serializable.h" +#include "src/Core/Maths.h" +#include "src/Core/Core.h" +#include "src/Scene/Environment/ProceduralSky.h" +#include "src/Resource/Serializable.h" -class Environment : public ISerializable +namespace Nuake { -public: - Environment(); + class Environment : public ISerializable + { + public: + Environment(); - float VolumetricFog = 0.95f; - float VolumetricStepCount = 100.f; - glm::vec4 AmbientColor; - Ref ProceduralSkybox; + float VolumetricFog = 0.95f; + float VolumetricStepCount = 100.f; + glm::vec4 AmbientColor; + Ref ProceduralSkybox; - glm::vec4 m_AmbientColor; - glm::vec4 GetAmbientColor(); - void SetAmbientColor(glm::vec4 color); + glm::vec4 m_AmbientColor; + glm::vec4 GetAmbientColor(); + void SetAmbientColor(glm::vec4 color); - void Push(); + void Push(); - json Serialize() override; - bool Deserialize(const std::string& str) override; -}; + json Serialize() override; + bool Deserialize(const std::string& str) override; + }; +} diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index a4940d2a..e8d78fca 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -28,177 +28,281 @@ #include #include -Ref Scene::New() -{ - return CreateRef(); -} - -Scene::Scene() -{ - m_Systems = std::vector>(); - m_EditorCamera = CreateRef(); - m_Environement = CreateRef(); - m_Interfaces = std::vector>(); - - // Adding systems - m_Systems.push_back(CreateRef(this)); - m_Systems.push_back(CreateRef(this)); - m_Systems.push_back(CreateRef(this)); - -} - -Scene::~Scene() {} - -std::string Scene::GetName() -{ - return this->Name; -} - -bool Scene::SetName(std::string& newName) -{ - if (newName == "") - return false; - - this->Name = newName; - return true; -} - -Entity Scene::GetEntity(int handle) -{ - return Entity((entt::entity)handle, this); -} - -Entity Scene::GetEntityByID(int id) -{ - auto idView = m_Registry.view(); - for (auto e : idView) { - NameComponent& nameC = idView.get(e); - if (nameC.ID == id) - return Entity{ e, this }; +namespace Nuake { + Ref Scene::New() + { + return CreateRef(); } -} -bool Scene::OnInit() -{ - for (auto& system : m_Systems) - if(!system->Init()) - { + Scene::Scene() + { + m_Systems = std::vector>(); + m_EditorCamera = CreateRef(); + m_Environement = CreateRef(); + m_Interfaces = std::vector>(); + + // Adding systems + m_Systems.push_back(CreateRef(this)); + m_Systems.push_back(CreateRef(this)); + m_Systems.push_back(CreateRef(this)); + + } + + Scene::~Scene() {} + + std::string Scene::GetName() + { + return this->Name; + } + + bool Scene::SetName(std::string& newName) + { + if (newName == "") return false; + + this->Name = newName; + return true; + } + + Entity Scene::GetEntity(int handle) + { + return Entity((entt::entity)handle, this); + } + + Entity Scene::GetEntityByID(int id) + { + auto idView = m_Registry.view(); + for (auto e : idView) { + NameComponent& nameC = idView.get(e); + if (nameC.ID == id) + return Entity{ e, this }; } + } - return true; -} - -void Scene::OnExit() -{ - for (auto& system : m_Systems) - system->Exit(); - -} - -void Scene::Update(Timestep ts) -{ - for (auto& system : m_Systems) - system->Update(ts); -} - -void Scene::FixedUpdate(Timestep ts) -{ - for (auto& system : m_Systems) - system->FixedUpdate(ts); -} - -void Scene::EditorUpdate(Timestep ts) -{ - UpdatePositions(); - - m_EditorCamera->Update(ts); - - for (auto i : m_Interfaces) - i->Update(ts); -} - -void Scene::UpdatePositions() -{ - auto transformView = m_Registry.view(); - for (auto e : transformView) { - auto [parent, transform] = transformView.get(e); - Entity currentParent = Entity{ e, this }; - Vector3 globalPos = Vector3(); - if (parent.HasParent) - { - while (currentParent.GetComponent().HasParent) { - currentParent = currentParent.GetComponent().Parent; - - globalPos += currentParent.GetComponent().Translation; + bool Scene::OnInit() + { + for (auto& system : m_Systems) + if (!system->Init()) + { + return false; } - transform.GlobalTranslation = globalPos + transform.Translation; - } - else - { - transform.GlobalTranslation = transform.Translation; - } + return true; } -} -struct BSPDrawObject -{ - float distance; - BSPBrushComponent brush; - Matrix4 transform; -}; + void Scene::OnExit() + { + for (auto& system : m_Systems) + system->Exit(); -bool DepthSort(BSPDrawObject& one, BSPDrawObject& two) -{ - return one.distance < two.distance; -} - -void Scene::DrawShadows() -{ - auto modelView = m_Registry.view(); - auto quakeView = m_Registry.view(); - auto view = m_Registry.view(); - - Ref cam = m_EditorCamera; - if (Engine::IsPlayMode) { - auto view = m_Registry.view(); - for (auto e : view) { - auto [transform, camera] = view.get(e); - cam = camera.CameraInstance; - break; - } } - - glm::mat4 perspective = cam->GetPerspective(); - Renderer::m_ShadowmapShader->Bind(); - for (auto l : view) { - auto [lightTransform, light] = view.get(l); - if (light.Type != LightType::Directional || !light.CastShadows) - continue; - - light.CalculateViewProjection(cam->GetTransform(), cam->GetPerspective()); - for (int i = 0; i < 4; i++) - { - light.m_Framebuffers[i]->Bind(); - light.m_Framebuffers[i]->Clear(); - Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]); - for (auto e : modelView) + void Scene::Update(Timestep ts) + { + for (auto& system : m_Systems) + system->Update(ts); + } + + void Scene::FixedUpdate(Timestep ts) + { + for (auto& system : m_Systems) + system->FixedUpdate(ts); + } + + void Scene::EditorUpdate(Timestep ts) + { + UpdatePositions(); + + m_EditorCamera->Update(ts); + + for (auto i : m_Interfaces) + i->Update(ts); + } + + void Scene::UpdatePositions() + { + auto transformView = m_Registry.view(); + for (auto e : transformView) { + auto [parent, transform] = transformView.get(e); + Entity currentParent = Entity{ e, this }; + Vector3 globalPos = Vector3(); + if (parent.HasParent) { - auto [transform, model] = modelView.get(e); + while (currentParent.GetComponent().HasParent) { + currentParent = currentParent.GetComponent().Parent; + + globalPos += currentParent.GetComponent().Translation; + } + + transform.GlobalTranslation = globalPos + transform.Translation; + } + else + { + transform.GlobalTranslation = transform.Translation; + } + } + } + + struct BSPDrawObject + { + float distance; + BSPBrushComponent brush; + Matrix4 transform; + }; + + bool DepthSort(BSPDrawObject& one, BSPDrawObject& two) + { + return one.distance < two.distance; + } + + void Scene::DrawShadows() + { + auto modelView = m_Registry.view(); + auto quakeView = m_Registry.view(); + auto view = m_Registry.view(); + + Ref cam = m_EditorCamera; + if (Engine::IsPlayMode) { + auto view = m_Registry.view(); + for (auto e : view) { + auto [transform, camera] = view.get(e); + cam = camera.CameraInstance; + break; + } + } + + glm::mat4 perspective = cam->GetPerspective(); + Renderer::m_ShadowmapShader->Bind(); + for (auto l : view) { + auto [lightTransform, light] = view.get(l); + if (light.Type != LightType::Directional || !light.CastShadows) + continue; + + light.CalculateViewProjection(cam->GetTransform(), cam->GetPerspective()); + + for (int i = 0; i < 4; i++) + { + light.m_Framebuffers[i]->Bind(); + light.m_Framebuffers[i]->Clear(); + Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]); + for (auto e : modelView) + { + auto [transform, model] = modelView.get(e); + + Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); + model.Draw(); + } + std::vector sortedBrushes = std::vector(); + + Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]); + auto quakeView = m_Registry.view(); + for (auto e : quakeView) { + auto [transform, model] = quakeView.get(e); + Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); + + if (model.IsTransparent) + continue; + + float dist = glm::length(transform.GlobalTranslation - cam->GetTranslation()); + sortedBrushes.push_back({ + dist, + model, + transform.GetTransform() + }); + + //for (auto& e : model.Meshes) { + // e->Draw(false); + //} + } + + std::sort(sortedBrushes.begin(), sortedBrushes.end(), DepthSort); + + for (auto& b : sortedBrushes) + { + Renderer::m_ShadowmapShader->SetUniformMat4f("model", b.transform); + for (auto& e : b.brush.Meshes) { + e->Draw(false); + } + } + } + + } + } + + void Scene::DrawInterface(Vector2 screensize) + { + for (auto i : m_Interfaces) + { + i->Draw(screensize); + } + } + + + + void Scene::Draw() + { + // Find the camera of the scene. + Ref cam = nullptr; + { + auto view = m_Registry.view(); + for (auto e : view) { + auto [transform, camera, parent] = view.get(e); + cam = camera.CameraInstance; + cam->Translation = transform.GlobalTranslation; + break; + } + } + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + Ref env = GetEnvironment(); + + if (env->ProceduralSkybox) + { + env->ProceduralSkybox->Draw(cam); + } + + Renderer::m_Shader->Bind(); + env->Push(); + glEnable(GL_DEPTH_TEST); + + // Push lights + { + auto view = m_Registry.view(); + for (auto l : view) { + auto [transform, light, parent] = view.get(l); + + if (light.SyncDirectionWithSky) + light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection(); + + light.Draw(transform, m_EditorCamera); + } + } + + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + Renderer::m_Shader->Bind(); + Renderer::m_Shader->SetUniform3f("u_EyePosition", cam->GetTranslation().x, cam->GetTranslation().y, cam->GetTranslation().z); + Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0); + + if (cam) + { + Renderer::m_Shader->SetUniform1f("u_Exposure", cam->Exposure); + + auto view = m_Registry.view(); + for (auto e : view) { + auto [transform, model, parent] = view.get(e); + Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform()); + Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective()); + Renderer::m_Shader->SetUniformMat4f("u_Model", transform.GetTransform()); - Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); model.Draw(); } + std::vector sortedBrushes = std::vector(); - Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]); - auto quakeView = m_Registry.view(); + auto quakeView = m_Registry.view(); for (auto e : quakeView) { - auto [transform, model] = quakeView.get(e); - Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); - + auto [transform, model, parent] = quakeView.get(e); if (model.IsTransparent) continue; @@ -207,454 +311,355 @@ void Scene::DrawShadows() dist, model, transform.GetTransform() - }); - - //for (auto& e : model.Meshes) { - // e->Draw(false); - //} + }); } std::sort(sortedBrushes.begin(), sortedBrushes.end(), DepthSort); for (auto& b : sortedBrushes) { - Renderer::m_ShadowmapShader->SetUniformMat4f("model", b.transform); - for (auto& e : b.brush.Meshes) { - e->Draw(false); + Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform()); + Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective()); + Renderer::m_Shader->SetUniformMat4f("u_Model", b.transform); + + for (auto& e : b.brush.Meshes) + e->Draw(); + } + + Renderer::m_DebugShader->SetUniformMat4f("u_View", cam->GetTransform()); + Renderer::m_DebugShader->SetUniformMat4f("u_Projection", cam->GetPerspective()); + + PhysicsManager::Get()->DrawDebug(); + } + } + + void Scene::EditorDraw() + { + glDisable(GL_DEPTH_TEST); + Ref env = GetEnvironment(); + + glDisable(GL_CULL_FACE); + if (env->ProceduralSkybox) + { + env->ProceduralSkybox->Draw(m_EditorCamera); + } + + Renderer::m_Shader->Bind(); + env->Push(); + glEnable(GL_DEPTH_TEST); + + // Push lights + { + auto view = m_Registry.view(); + for (auto l : view) { + auto [transform, light, parent] = view.get(l); + + if (light.SyncDirectionWithSky) + light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection(); + + light.Draw(transform, m_EditorCamera); + } + } + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + Renderer::m_Shader->Bind(); + Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0); + if (m_EditorCamera) + { + Renderer::m_Shader->SetUniform1f("u_Exposure", m_EditorCamera->Exposure); + Renderer::m_Shader->SetUniform3f("u_EyePosition", m_EditorCamera->GetTranslation().x, m_EditorCamera->GetTranslation().y, m_EditorCamera->GetTranslation().z); + auto view = m_Registry.view(); + for (auto e : view) { + auto [transform, model, parent] = view.get(e); + + Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); + Renderer::m_Shader->SetUniformMat4f("u_Model", transform.GetTransform()); + model.Draw(); + } + + std::vector sortedBrushes = std::vector(); + + + auto quakeView = m_Registry.view(); + for (auto e : quakeView) { + auto [transform, model, parent] = quakeView.get(e); + + if (model.IsTransparent) + continue; + + float dist = glm::length(transform.GlobalTranslation - m_EditorCamera->GetTranslation()); + sortedBrushes.push_back({ + dist, + model, + transform.GetTransform() + }); + + Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); + } + + std::sort(sortedBrushes.begin(), sortedBrushes.end(), DepthSort); + + for (auto& b : sortedBrushes) + { + Renderer::m_Shader->SetUniformMat4f("u_Model", b.transform); + + for (auto& d : b.brush.Meshes) + d->Draw(); + } + + Renderer::m_DebugShader->Bind(); + auto boxCollider = m_Registry.view(); + for (auto e : boxCollider) { + auto [transform, box, parent] = boxCollider.get(e); + Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); + + Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); + + TransformComponent t = transform; + t.Scale = (box.Size * 2.f) * transform.Scale; + Renderer::DrawCube(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f)); + } + + auto sphereCollider = m_Registry.view(); + for (auto e : sphereCollider) { + auto [transform, box, parent] = sphereCollider.get(e); + + Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); + Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); + + TransformComponent t = transform; + t.Scale = (box.Radius * 2.f) * transform.Scale; + Renderer::DrawSphere(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f)); + } + + Renderer::m_DebugShader->Bind(); + + auto quakeViewTransparent = m_Registry.view(); + for (auto e : quakeViewTransparent) + { + auto [transform, model, parent] = quakeViewTransparent.get(e); + + if (!model.IsTransparent) + continue; + + Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); + Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); + Renderer::m_DebugShader->SetUniform4f("u_Color", 1.f, 0.0f, 0.1f, 0.5f); + for (auto& e : model.Meshes) { + e->Draw(); + } + } + } + } + + std::vector Scene::GetAllEntities() { + std::vector allEntities; + auto view = m_Registry.view(); + for (auto e : view) { + Entity newEntity(e, this); + + // Check if valid for deleted entities. + if (newEntity.IsValid()) + allEntities.push_back(newEntity); + } + return allEntities; + } + + glm::vec3 Scene::GetGlobalPosition(Entity ent) + { + glm::vec3 globalPos = ent.GetComponent().Translation; + Entity currentParent = ent.AddComponent().Parent; + while (currentParent.GetHandle() != -1) + { + globalPos += currentParent.GetComponent().Translation; + currentParent = currentParent.GetComponent().Parent; + } + + return globalPos; + } + + + Entity Scene::GetEntity(const std::string& name) + { + std::vector allEntities; + auto view = m_Registry.view(); + for (auto e : view) { + auto [transform, namec] = view.get(e); + if (namec.Name == name) + return Entity{ e, this }; + } + } + + Entity Scene::CreateEmptyEntity() { + Entity entity = { m_Registry.create(), this }; + return entity; + } + + Entity Scene::CreateEntity(const std::string& name) { + Entity entity = { m_Registry.create(), this }; + + // Must have transform + entity.AddComponent(); + + NameComponent& nameComponent = entity.AddComponent(); + nameComponent.Name = name; + nameComponent.ID = (int)OS::GetTime(); + + ParentComponent& parentComponent = entity.AddComponent(); + + Logger::Log("Created entity: " + nameComponent.Name + "\n"); + return entity; + } + + void Scene::DestroyEntity(Entity entity) + { + ParentComponent& parentC = entity.GetComponent(); + std::vector copyChildrens = parentC.Children; + if (parentC.HasParent) { // Remove self from parents children lists. + ParentComponent& parent = parentC.Parent.GetComponent(); + parent.RemoveChildren(entity); + } + for (auto& c : copyChildrens) { + Logger::Log("Deleting... entity" + std::to_string(c.GetHandle())); + DestroyEntity(c); + } + + Logger::Log("Deleted entity" + std::to_string(entity.GetHandle()) + " - " + entity.GetComponent().Name); + entity.Destroy(); + m_Registry.shrink_to_fit(); + } + + // Getter + Ref Scene::GetCurrentCamera() + { + if (Engine::IsPlayMode) + { + Ref cam = nullptr; + { + auto view = m_Registry.view(); + for (auto e : view) { + auto [transform, camera] = view.get(e); + cam = camera.CameraInstance; + break; + } + } + if (!cam) + cam = m_EditorCamera; + return cam; + } + + return m_EditorCamera; + } + + Ref Scene::GetEnvironment() { + return m_Environement; + } + + bool Scene::Save() + { + if (Path == "") + Path = FileSystem::AbsoluteToRelative(FileDialog::SaveFile("*.scene") + ".scene"); + + return SaveAs(Path); + } + + bool Scene::SaveAs(const std::string& path) + { + std::ofstream sceneFile; + sceneFile.open(FileSystem::Root + path); + sceneFile << Serialize().dump(4); + sceneFile.close(); + + Logger::Log("Scene saved successfully"); + return true; + } + + + void Scene::ReloadInterfaces() + { + for (auto& i : m_Interfaces) + i->Reload(); + } + + + void Scene::AddInterface(Ref interface) + { + this->m_Interfaces.push_back(interface); + } + + + json Scene::Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(Name); + SERIALIZE_OBJECT(m_Environement) + std::vector entities = std::vector(); + for (Entity e : GetAllEntities()) + entities.push_back(e.Serialize()); + SERIALIZE_VAL_LBL("Entities", entities); + END_SERIALIZE(); + } + + + bool Scene::Deserialize(const std::string& str) + { + if (str == "") + return false; + + BEGIN_DESERIALIZE(); + if (!j.contains("Name")) + return false; + + Name = j["Name"]; + + m_Environement = CreateRef(); + if (j.contains("m_Environement")) + { + m_Environement = CreateRef(); + std::string env = j["m_Environement"].dump(); + m_Environement->Deserialize(env); + } + + // Parse entities + { + if (j.contains("Entities")) + { + for (json e : j["Entities"]) + { + std::string name = e["NameComponent"]["Name"]; + Entity ent = CreateEmptyEntity(); + ent.Deserialize(e.dump()); + } + + auto view = m_Registry.view(); + for (auto e : view) + { + auto parentC = view.get(e); + if (!parentC.HasParent) + continue; + + auto& p = Entity{ e, this }; + auto parent = GetEntityByID(parentC.ParentID); + parent.AddChild(p); } } } + return true; } -} -void Scene::DrawInterface(Vector2 screensize) -{ - for (auto i : m_Interfaces) + void Scene::Snapshot() { - i->Draw(screensize); + } -} - - -void Scene::Draw() -{ - // Find the camera of the scene. - Ref cam = nullptr; + void Scene::LoadSnapshot() { - auto view = m_Registry.view(); - for (auto e : view) { - auto [transform, camera, parent] = view.get(e); - cam = camera.CameraInstance; - cam->Translation = transform.GlobalTranslation; - break; - } - } - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - Ref env = GetEnvironment(); - - if (env->ProceduralSkybox) - { - env->ProceduralSkybox->Draw(cam); } - Renderer::m_Shader->Bind(); - env->Push(); - glEnable(GL_DEPTH_TEST); - - // Push lights - { - auto view = m_Registry.view(); - for (auto l : view) { - auto [transform, light, parent] = view.get(l); - - if (light.SyncDirectionWithSky) - light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection(); - - light.Draw(transform, m_EditorCamera); - } - } - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - Renderer::m_Shader->Bind(); - Renderer::m_Shader->SetUniform3f("u_EyePosition", cam->GetTranslation().x, cam->GetTranslation().y, cam->GetTranslation().z); - Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0); - if (cam) - { - Renderer::m_Shader->SetUniform1f("u_Exposure", cam->Exposure); - - auto view = m_Registry.view(); - for (auto e : view) { - auto [transform, model, parent] = view.get(e); - Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform()); - Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective()); - Renderer::m_Shader->SetUniformMat4f("u_Model", transform.GetTransform()); - model.Draw(); - } - - - std::vector sortedBrushes = std::vector(); - - auto quakeView = m_Registry.view(); - for (auto e : quakeView) { - auto [transform, model, parent] = quakeView.get(e); - if (model.IsTransparent) - continue; - - float dist = glm::length(transform.GlobalTranslation - cam->GetTranslation()); - sortedBrushes.push_back({ - dist, - model, - transform.GetTransform() - }); - } - - std::sort(sortedBrushes.begin(), sortedBrushes.end(), DepthSort); - - for (auto& b : sortedBrushes) - { - Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform()); - Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective()); - Renderer::m_Shader->SetUniformMat4f("u_Model", b.transform); - - for (auto& e : b.brush.Meshes) - e->Draw(); - } - - Renderer::m_DebugShader->SetUniformMat4f("u_View", cam->GetTransform()); - Renderer::m_DebugShader->SetUniformMat4f("u_Projection", cam->GetPerspective()); - - PhysicsManager::Get()->DrawDebug(); - } -} - -void Scene::EditorDraw() -{ - glDisable(GL_DEPTH_TEST); - Ref env = GetEnvironment(); - - glDisable(GL_CULL_FACE); - if (env->ProceduralSkybox) - { - env->ProceduralSkybox->Draw(m_EditorCamera); - } - - Renderer::m_Shader->Bind(); - env->Push(); - glEnable(GL_DEPTH_TEST); - - // Push lights - { - auto view = m_Registry.view(); - for (auto l : view) { - auto [transform, light, parent] = view.get(l); - - if (light.SyncDirectionWithSky) - light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection(); - - light.Draw(transform, m_EditorCamera); - } - } - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - Renderer::m_Shader->Bind(); - Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0); - if (m_EditorCamera) - { - Renderer::m_Shader->SetUniform1f("u_Exposure", m_EditorCamera->Exposure); - Renderer::m_Shader->SetUniform3f("u_EyePosition", m_EditorCamera->GetTranslation().x, m_EditorCamera->GetTranslation().y, m_EditorCamera->GetTranslation().z); - auto view = m_Registry.view(); - for (auto e : view) { - auto [transform, model, parent] = view.get(e); - - Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); - Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); - Renderer::m_Shader->SetUniformMat4f("u_Model", transform.GetTransform()); - model.Draw(); - } - - std::vector sortedBrushes = std::vector(); - - - auto quakeView = m_Registry.view(); - for (auto e : quakeView) { - auto [transform, model, parent] = quakeView.get(e); - - if (model.IsTransparent) - continue; - - float dist = glm::length(transform.GlobalTranslation - m_EditorCamera->GetTranslation()); - sortedBrushes.push_back({ - dist, - model, - transform.GetTransform() - }); - - Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); - Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); - } - - std::sort(sortedBrushes.begin(), sortedBrushes.end(), DepthSort); - - for (auto& b : sortedBrushes) - { - Renderer::m_Shader->SetUniformMat4f("u_Model", b.transform); - - for (auto& d : b.brush.Meshes) - d->Draw(); - } - - Renderer::m_DebugShader->Bind(); - auto boxCollider = m_Registry.view(); - for (auto e : boxCollider) { - auto [transform, box, parent] = boxCollider.get(e); - Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); - Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); - - Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); - - TransformComponent t = transform; - t.Scale = (box.Size * 2.f) * transform.Scale; - Renderer::DrawCube(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f)); - } - - auto sphereCollider = m_Registry.view(); - for (auto e : sphereCollider) { - auto [transform, box, parent] = sphereCollider.get(e); - - Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); - Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); - Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); - - TransformComponent t = transform; - t.Scale = (box.Radius * 2.f) * transform.Scale; - Renderer::DrawSphere(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f)); - } - - Renderer::m_DebugShader->Bind(); - - auto quakeViewTransparent = m_Registry.view(); - for (auto e : quakeViewTransparent) - { - auto [transform, model, parent] = quakeViewTransparent.get(e); - - if (!model.IsTransparent) - continue; - - Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); - Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); - Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); - Renderer::m_DebugShader->SetUniform4f("u_Color", 1.f, 0.0f, 0.1f, 0.5f); - for (auto& e : model.Meshes) { - e->Draw(); - } - } - } -} - -std::vector Scene::GetAllEntities() { - std::vector allEntities; - auto view = m_Registry.view(); - for (auto e : view) { - Entity newEntity(e, this); - - // Check if valid for deleted entities. - if(newEntity.IsValid()) - allEntities.push_back(newEntity); - } - return allEntities; -} - -glm::vec3 Scene::GetGlobalPosition(Entity ent) -{ - glm::vec3 globalPos = ent.GetComponent().Translation; - Entity currentParent = ent.AddComponent().Parent; - while (currentParent.GetHandle() != -1) - { - globalPos += currentParent.GetComponent().Translation; - currentParent = currentParent.GetComponent().Parent; - } - - return globalPos; -} - - -Entity Scene::GetEntity(const std::string& name) -{ - std::vector allEntities; - auto view = m_Registry.view(); - for (auto e : view) { - auto [transform, namec] = view.get(e); - if (namec.Name == name) - return Entity{ e, this }; - } -} - -Entity Scene::CreateEmptyEntity() { - Entity entity = { m_Registry.create(), this }; - return entity; -} - -Entity Scene::CreateEntity(const std::string& name) { - Entity entity = { m_Registry.create(), this }; - - // Must have transform - entity.AddComponent(); - - NameComponent& nameComponent = entity.AddComponent(); - nameComponent.Name = name; - nameComponent.ID = (int)OS::GetTime(); - - ParentComponent& parentComponent = entity.AddComponent(); - - Logger::Log("Created entity: " + nameComponent.Name + "\n"); - return entity; -} - -void Scene::DestroyEntity(Entity entity) -{ - ParentComponent& parentC = entity.GetComponent(); - std::vector copyChildrens = parentC.Children; - if (parentC.HasParent) { // Remove self from parents children lists. - ParentComponent& parent = parentC.Parent.GetComponent(); - parent.RemoveChildren(entity); - } - for (auto& c : copyChildrens) { - Logger::Log("Deleting... entity" + std::to_string(c.GetHandle())); - DestroyEntity(c); - } - - Logger::Log("Deleted entity" + std::to_string(entity.GetHandle()) + " - " + entity.GetComponent().Name); - entity.Destroy(); - m_Registry.shrink_to_fit(); -} - -// Getter -Ref Scene::GetCurrentCamera() -{ - if (Engine::IsPlayMode) - { - Ref cam = nullptr; - { - auto view = m_Registry.view(); - for (auto e : view) { - auto [transform, camera] = view.get(e); - cam = camera.CameraInstance; - break; - } - } - if (!cam) - cam = m_EditorCamera; - return cam; - } - - return m_EditorCamera; -} - -Ref Scene::GetEnvironment() { - return m_Environement; -} - -bool Scene::Save() -{ - if (Path == "") - Path = FileSystem::AbsoluteToRelative(FileDialog::SaveFile("*.scene") + ".scene"); - - return SaveAs(Path); -} - -bool Scene::SaveAs(const std::string& path) -{ - std::ofstream sceneFile; - sceneFile.open(FileSystem::Root + path); - sceneFile << Serialize().dump(4); - sceneFile.close(); - - Logger::Log("Scene saved successfully"); - return true; -} - - -void Scene::ReloadInterfaces() -{ - for (auto& i : m_Interfaces) - i->Reload(); -} - - -void Scene::AddInterface(Ref interface) -{ - this->m_Interfaces.push_back(interface); -} - - -json Scene::Serialize() -{ - BEGIN_SERIALIZE(); - SERIALIZE_VAL(Name); - SERIALIZE_OBJECT(m_Environement) - std::vector entities = std::vector(); - for (Entity e : GetAllEntities()) - entities.push_back(e.Serialize()); - SERIALIZE_VAL_LBL("Entities", entities); - END_SERIALIZE(); -} - - -bool Scene::Deserialize(const std::string& str) -{ - if (str == "") - return false; - - BEGIN_DESERIALIZE(); - if (!j.contains("Name")) - return false; - - Name = j["Name"]; - - m_Environement = CreateRef(); - if (j.contains("m_Environement")) - { - m_Environement = CreateRef(); - std::string env = j["m_Environement"].dump(); - m_Environement->Deserialize(env); - } - - // Parse entities - { - if (j.contains("Entities")) - { - for (json e : j["Entities"]) - { - std::string name = e["NameComponent"]["Name"]; - Entity ent = CreateEmptyEntity(); - ent.Deserialize(e.dump()); - } - - auto view = m_Registry.view(); - for (auto e : view) - { - auto parentC = view.get(e); - if (!parentC.HasParent) - continue; - - auto& p = Entity{ e, this }; - auto parent = GetEntityByID(parentC.ParentID); - parent.AddChild(p); - } - } - } - - return true; -} - -void Scene::Snapshot() -{ - -} - -void Scene::LoadSnapshot() -{ } diff --git a/Nuake/src/Scene/Scene.h b/Nuake/src/Scene/Scene.h index 071db716..e9890e42 100644 --- a/Nuake/src/Scene/Scene.h +++ b/Nuake/src/Scene/Scene.h @@ -3,9 +3,7 @@ #include "Lighting/Environment.h" #include #include "entt/entt.hpp" -#include "../Rendering/SkyboxHDR.h" -#include "../Rendering/GBuffer.h" -#include "../Rendering/ProceduralSky.h" + #include "../Core/Core.h" #include "EditorCamera.h" #include "../Resource/Serializable.h" @@ -13,74 +11,76 @@ #include "../Core/Maths.h" #include -class Entity; +namespace Nuake { + class Entity; -class Scene : public ISerializable -{ - friend Entity; -private: - std::string Name; // Name of the scene - bool has_changed = true; + class Scene : public ISerializable + { + friend Entity; + private: + std::string Name; // Name of the scene + bool has_changed = true; - // The systems are what updates the components. - // You can create a new system(see 'Systems/'.) and register it - // In the scene constructor. - std::vector> m_Systems; - - Ref m_Environement; -public: - Ref m_EditorCamera; - entt::registry m_Registry; - std::vector> m_Interfaces; - std::string Path = ""; - static Ref New(); + // The systems are what updates the components. + // You can create a new system(see 'Systems/'.) and register it + // In the scene constructor. + std::vector> m_Systems; - Scene(); - ~Scene(); + Ref m_Environement; + public: + Ref m_EditorCamera; + entt::registry m_Registry; + std::vector> m_Interfaces; + std::string Path = ""; + static Ref New(); - std::string GetName(); - bool SetName(std::string& newName); - Entity GetEntity(int handle); - Entity GetEntityByID(int id); - void Init(); - bool OnInit(); - void OnExit(); - void Update(Timestep ts); - void FixedUpdate(Timestep ts); - void EditorUpdate(Timestep ts); + Scene(); + ~Scene(); - void UpdatePositions(); + std::string GetName(); + bool SetName(std::string& newName); + Entity GetEntity(int handle); + Entity GetEntityByID(int id); + void Init(); + bool OnInit(); + void OnExit(); + void Update(Timestep ts); + void FixedUpdate(Timestep ts); + void EditorUpdate(Timestep ts); - // TODO: Maybe move this to Renderer::DrawScene() ? - void DrawShadows(); - void DrawInterface(Vector2 screensize); - void Draw(); - void EditorDraw(); + void UpdatePositions(); - std::vector GetAllEntities(); - Entity GetEntity(const std::string& name); + // TODO: Maybe move this to Renderer::DrawScene() ? + void DrawShadows(); + void DrawInterface(Vector2 screensize); + void Draw(); + void EditorDraw(); - // TODO: This shouldnt be allowed - Entity CreateEmptyEntity(); - Entity CreateEntity(const std::string& name); + std::vector GetAllEntities(); + Entity GetEntity(const std::string& name); - // TODO: Could be moved to transform component directly. - glm::vec3 GetGlobalPosition(Entity ent); - void DestroyEntity(Entity entity); // TODO: Could return bool + // TODO: This shouldnt be allowed + Entity CreateEmptyEntity(); + Entity CreateEntity(const std::string& name); - // TODO: Add multiple camera support. - Ref GetCurrentCamera(); - Ref GetEnvironment(); + // TODO: Could be moved to transform component directly. + glm::vec3 GetGlobalPosition(Entity ent); + void DestroyEntity(Entity entity); // TODO: Could return bool - bool Save(); - bool SaveAs(const std::string& path); + // TODO: Add multiple camera support. + Ref GetCurrentCamera(); + Ref GetEnvironment(); - void ReloadInterfaces(); - void AddInterface(Ref interface); + bool Save(); + bool SaveAs(const std::string& path); - json Serialize() override; - bool Deserialize(const std::string& str) override; + void ReloadInterfaces(); + void AddInterface(Ref interface); - void Snapshot(); - void LoadSnapshot(); -}; \ No newline at end of file + json Serialize() override; + bool Deserialize(const std::string& str) override; + + void Snapshot(); + void LoadSnapshot(); + }; +} diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.cpp b/Nuake/src/Scene/Systems/PhysicsSystem.cpp index 5fdf8bb2..7b4097e0 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.cpp +++ b/Nuake/src/Scene/Systems/PhysicsSystem.cpp @@ -10,147 +10,149 @@ #include #include - -PhysicsSystem::PhysicsSystem(Scene* scene) +namespace Nuake { - m_Scene = scene; -} - -bool PhysicsSystem::Init() -{ - // Create physic world. - auto view = m_Scene->m_Registry.view(); - for (auto e : view) + PhysicsSystem::PhysicsSystem(Scene* scene) { - auto [transform, rigidbody] = view.get(e); - Entity ent = Entity({ e, m_Scene }); - - if (ent.HasComponent()) - { - float mass = rigidbody.mass; - - BoxColliderComponent& boxComponent = ent.GetComponent(); - Ref boxShape = CreateRef(boxComponent.Size); - - Ref btRigidbody = CreateRef(mass, transform.Translation, boxShape); - - rigidbody.m_Rigidbody = btRigidbody; - - btRigidbody->SetKinematic(rigidbody.IsKinematic); - - PhysicsManager::Get()->RegisterBody(btRigidbody); - } + m_Scene = scene; } - // character controllers - auto ccview = m_Scene->m_Registry.view(); - for (auto e : ccview) + bool PhysicsSystem::Init() { - auto [transform, cc] = ccview.get(e); - - cc.CharacterController = CreateRef(cc.Height, cc.Radius, cc.Mass, transform.Translation); - Entity ent = Entity({ e, m_Scene }); - cc.CharacterController->SetEntity(ent); - - PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController); - } - - auto bspView = m_Scene->m_Registry.view(); - for (auto e : bspView) - { - auto [transform, brush] = bspView.get(e); - - if (brush.IsSolid) + // Create physic world. + auto view = m_Scene->m_Registry.view(); + for (auto e : view) { - for (auto m : brush.Meshes) + auto [transform, rigidbody] = view.get(e); + Entity ent = Entity({ e, m_Scene }); + + if (ent.HasComponent()) { - Ref meshShape = CreateRef(m); - Ref btRigidbody = CreateRef(0.0f, transform.GlobalTranslation, meshShape); - btRigidbody->SetEntityID(Entity{ e, m_Scene }); - brush.Rigidbody.push_back(btRigidbody); + float mass = rigidbody.mass; + + BoxColliderComponent& boxComponent = ent.GetComponent(); + Ref boxShape = CreateRef(boxComponent.Size); + + Ref btRigidbody = CreateRef(mass, transform.Translation, boxShape); + + rigidbody.m_Rigidbody = btRigidbody; + + btRigidbody->SetKinematic(rigidbody.IsKinematic); + PhysicsManager::Get()->RegisterBody(btRigidbody); } } - } - auto bspTriggerView = m_Scene->m_Registry.view(); - for (auto e : bspTriggerView) { - auto [transform, brush, trigger] = bspTriggerView.get(e); - - Ref meshShape = CreateRef(brush.Meshes[0]); - Ref ghostBody = CreateRef(transform.GlobalTranslation, meshShape); - trigger.GhostObject = ghostBody; + // character controllers + auto ccview = m_Scene->m_Registry.view(); + for (auto e : ccview) + { + auto [transform, cc] = ccview.get(e); - PhysicsManager::Get()->RegisterGhostBody(ghostBody); - } - return true; -} + cc.CharacterController = CreateRef(cc.Height, cc.Radius, cc.Mass, transform.Translation); + Entity ent = Entity({ e, m_Scene }); + cc.CharacterController->SetEntity(ent); -void PhysicsSystem::Update(Timestep ts) -{ - // Update rigidbodies - PhysicsManager::Get()->Step(ts); - - auto brushes = m_Scene->m_Registry.view(); - for (auto e : brushes) { - auto [transform, brush] = brushes.get(e); - - for (auto& r : brush.Rigidbody) { - r->m_Transform->setOrigin(btVector3(transform.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z)); - r->UpdateTransform(*r->m_Transform); + PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController); } - if (!brush.IsFunc) - continue; + auto bspView = m_Scene->m_Registry.view(); + for (auto e : bspView) + { + auto [transform, brush] = bspView.get(e); - brush.Targets.clear(); - auto targetnameView = m_Scene->m_Registry.view(); - for (auto e2 : targetnameView) { - auto [ttransform, name] = targetnameView.get(e2); - - if (name.Name == brush.target) { - brush.Targets.push_back(Entity{ e2, m_Scene }); + if (brush.IsSolid) + { + for (auto m : brush.Meshes) + { + Ref meshShape = CreateRef(m); + Ref btRigidbody = CreateRef(0.0f, transform.GlobalTranslation, meshShape); + btRigidbody->SetEntityID(Entity{ e, m_Scene }); + brush.Rigidbody.push_back(btRigidbody); + PhysicsManager::Get()->RegisterBody(btRigidbody); + } } } + + auto bspTriggerView = m_Scene->m_Registry.view(); + for (auto e : bspTriggerView) { + auto [transform, brush, trigger] = bspTriggerView.get(e); + + Ref meshShape = CreateRef(brush.Meshes[0]); + Ref ghostBody = CreateRef(transform.GlobalTranslation, meshShape); + trigger.GhostObject = ghostBody; + + PhysicsManager::Get()->RegisterGhostBody(ghostBody); + } + return true; } + void PhysicsSystem::Update(Timestep ts) + { + // Update rigidbodies + PhysicsManager::Get()->Step(ts); - auto bspTriggerView = m_Scene->m_Registry.view(); - for (auto e : bspTriggerView) { - auto [transform, brush, trigger] = bspTriggerView.get(e); - trigger.GhostObject->ScanOverlap(); + auto brushes = m_Scene->m_Registry.view(); + for (auto e : brushes) { + auto [transform, brush] = brushes.get(e); - brush.Targets.clear(); - auto targetnameView = m_Scene->m_Registry.view(); - for (auto e2 : targetnameView) { - auto [ttransform, name] = targetnameView.get(e2); - - if (name.Name == brush.target) { - brush.Targets.push_back(Entity{ e2, m_Scene }); + for (auto& r : brush.Rigidbody) { + r->m_Transform->setOrigin(btVector3(transform.GlobalTranslation.x, transform.GlobalTranslation.y, transform.GlobalTranslation.z)); + r->UpdateTransform(*r->m_Transform); } + + if (!brush.IsFunc) + continue; + + brush.Targets.clear(); + auto targetnameView = m_Scene->m_Registry.view(); + for (auto e2 : targetnameView) { + auto [ttransform, name] = targetnameView.get(e2); + + if (name.Name == brush.target) { + brush.Targets.push_back(Entity{ e2, m_Scene }); + } + } + } + + + auto bspTriggerView = m_Scene->m_Registry.view(); + for (auto e : bspTriggerView) { + auto [transform, brush, trigger] = bspTriggerView.get(e); + trigger.GhostObject->ScanOverlap(); + + brush.Targets.clear(); + auto targetnameView = m_Scene->m_Registry.view(); + for (auto e2 : targetnameView) { + auto [ttransform, name] = targetnameView.get(e2); + + if (name.Name == brush.target) { + brush.Targets.push_back(Entity{ e2, m_Scene }); + } + } + } + + auto physicGroup = m_Scene->m_Registry.view(); + for (auto e : physicGroup) { + auto [transform, rb] = physicGroup.get(e); + rb.SyncTransformComponent(&m_Scene->m_Registry.get(e)); + } + + auto ccGroup = m_Scene->m_Registry.view(); + for (auto e : ccGroup) { + auto [transform, rb] = ccGroup.get(e); + rb.SyncWithTransform(m_Scene->m_Registry.get(e)); } } - auto physicGroup = m_Scene->m_Registry.view(); - for (auto e : physicGroup) { - auto [transform, rb] = physicGroup.get(e); - rb.SyncTransformComponent(&m_Scene->m_Registry.get(e)); + void PhysicsSystem::FixedUpdate(Timestep ts) + { + } - auto ccGroup = m_Scene->m_Registry.view(); - for (auto e : ccGroup) { - auto [transform, rb] = ccGroup.get(e); - rb.SyncWithTransform(m_Scene->m_Registry.get(e)); + void PhysicsSystem::Exit() + { + PhysicsManager::Get()->Reset(); + } } - -void PhysicsSystem::FixedUpdate(Timestep ts) -{ - -} - -void PhysicsSystem::Exit() -{ - PhysicsManager::Get()->Reset(); - -} \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.h b/Nuake/src/Scene/Systems/PhysicsSystem.h index 4a405168..a8d4badf 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.h +++ b/Nuake/src/Scene/Systems/PhysicsSystem.h @@ -1,12 +1,16 @@ #pragma once #include -class PhysicsSystem : public System { -public: - PhysicsSystem(Scene* scene); - bool Init() override; - void Update(Timestep ts) override; - void Draw() override {} - void FixedUpdate(Timestep ts) override; - void Exit() override; -}; \ No newline at end of file +namespace Nuake +{ + class PhysicsSystem : public System + { + public: + PhysicsSystem(Scene* scene); + bool Init() override; + void Update(Timestep ts) override; + void Draw() override {} + void FixedUpdate(Timestep ts) override; + void Exit() override; + }; +} diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp index edb0eea1..ca7ede8f 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp @@ -23,276 +23,154 @@ extern "C" { #include #include - -Ref DefaultMaterial; -std::vector split(const std::string& s, char delim) -{ - std::vector result; - std::stringstream ss(s); - std::string item; - - while (getline(ss, item, delim)) +namespace Nuake { + Ref DefaultMaterial; + std::vector split(const std::string& s, char delim) { - result.push_back(item); + std::vector result; + std::stringstream ss(s); + std::string item; + + while (getline(ss, item, delim)) + { + result.push_back(item); + } + + return result; } - return result; -} - -void QuakeMapBuilder::CreateTrigger(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname) -{ - std::vector vertices; - std::vector indices; - - Entity brushEntity = scene->CreateEntity("Trigger"); - TransformComponent& transformComponent = brushEntity.GetComponent(); - TriggerZone& trigger = brushEntity.AddComponent(); - trigger.target = target; - - parent.AddChild(brushEntity); - - transformComponent.Translation = Vector3(brush->center.y * (1.0f / 64), - brush->center.z * (1.0f / 64), - brush->center.x * (1.0f / 64)); - - BSPBrushComponent& bsp = brushEntity.AddComponent(); - bsp.IsSolid = false; - bsp.target = target; - int indexOffset = 0; - for (int f = 0; f < brush->face_count; ++f) + void QuakeMapBuilder::CreateTrigger(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname) { - face* face = &brush->faces[f]; - - face_geometry* face_geo_inst = &brush_inst->faces[f]; + std::vector vertices; + std::vector indices; - for (int i = 0; i < face_geo_inst->vertex_count; ++i) - { - face_vertex vertex = face_geo_inst->vertices[i]; - - Vector3 vertexPos = Vector3( - (vertex.vertex.y - brush->center.y) * (1.0f / 64), - (vertex.vertex.z - brush->center.z) * (1.0f / 64), - (vertex.vertex.x - brush->center.x) * (1.0f / 64) - ); - - Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); - Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); - - vertices.push_back(Vertex{ - vertexPos, - Vector2(0,0), - vertexNormal, - vertexTangent, - glm::vec3(0.0, 1.0, 0.0), 0.0f - }); - } - - for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) - { - unsigned int index = face_geo_inst->indices[i]; - indices.push_back((unsigned int)indexOffset + index); - } - - indexOffset += face_geo_inst->vertex_count; - } - bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); -} - -void QuakeMapBuilder::CreateBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname) -{ - std::vector vertices; - std::vector indices; - Entity brushEntity = scene->CreateEntity(targetname); - TransformComponent& transformComponent = brushEntity.GetComponent(); - BSPBrushComponent& bsp = brushEntity.AddComponent(); - - parent.AddChild(brushEntity); - - transformComponent.Translation = Vector3( - brush->center.y * (1.0f / 64), - brush->center.z * (1.0f / 64), - brush->center.x * (1.0f / 64)); - - int index_offset = 0; - int lastTextureID = -1; - std::string lastTexturePath = ""; - for (int f = 0; f < brush->face_count; ++f) - { - face* face = &brush->faces[f]; - texture_data* texture = &textures[face->texture_idx]; - - if (std::string(texture->name) == "__TB_empty") - { - texture->height = 1; - texture->width = 1; - } - else - { - std::string path = FileSystem::Root + "textures/" + std::string(texture->name) + ".png"; - auto tex = TextureManager::Get()->GetTexture(path); - - texture->height = tex->GetHeight(); - texture->width = tex->GetWidth(); - } - - face_geometry* face_geo_inst = &brush_inst->faces[f]; - - for (int i = 0; i < face_geo_inst->vertex_count; ++i) - { - face_vertex vertex = face_geo_inst->vertices[i]; - vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height); - - Vector3 vertexPos = Vector3( - (vertex.vertex.y - brush->center.y) * (1.0f / 64), - (vertex.vertex.z - brush->center.z) * (1.0f / 64), - (vertex.vertex.x - brush->center.x) * (1.0f / 64) - ); - - Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); - Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); - Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); - - vertices.push_back(Vertex{ - vertexPos, - vertexUV, - vertexNormal, - vertexTangent, - glm::vec3(0.0, 1.0, 0.0), 0.0f - }); - } - - for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) - { - unsigned int index = face_geo_inst->indices[i]; - indices.push_back(index_offset + (unsigned int)index); - } - - if (lastTextureID != face->texture_idx) - { - lastTexturePath = FileSystem::Root + "textures/" + std::string(texture->name) + ".png"; - - if (std::string(texture->name) == "__TB_empty") - bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); - else - bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); - - index_offset = 0; - vertices.clear(); - indices.clear(); - lastTextureID = face->texture_idx; - } - else - { - index_offset += (face_geo_inst->vertex_count); - } - } - - if (vertices.size() > 0) - bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); -} - -void QuakeMapBuilder::CreateFuncBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname, FGDBrushEntity fgdBrush) -{ - std::vector vertices; - std::vector indices; - - std::string name = fgdBrush.Name; - if (targetname != "") - name = targetname; - - Entity brushEntity = scene->CreateEntity(name); - - TransformComponent& transformComponent = brushEntity.GetComponent(); - BSPBrushComponent& bsp = brushEntity.AddComponent(); - - bsp.IsSolid = fgdBrush.Solid; - bsp.IsTransparent = !fgdBrush.Visible; - bsp.IsFunc = true; - bsp.IsTrigger = fgdBrush.IsTrigger; - if (fgdBrush.Script != "" && fgdBrush.Class != "") - { - auto& wrenScript = brushEntity.AddComponent(); - wrenScript.Script = fgdBrush.Script; - wrenScript.Class = fgdBrush.Class; - } - - if (bsp.IsTrigger) - { + Entity brushEntity = scene->CreateEntity("Trigger"); + TransformComponent& transformComponent = brushEntity.GetComponent(); TriggerZone& trigger = brushEntity.AddComponent(); trigger.target = target; + + parent.AddChild(brushEntity); + + transformComponent.Translation = Vector3(brush->center.y * (1.0f / 64), + brush->center.z * (1.0f / 64), + brush->center.x * (1.0f / 64)); + + BSPBrushComponent& bsp = brushEntity.AddComponent(); + bsp.IsSolid = false; + bsp.target = target; + int indexOffset = 0; + for (int f = 0; f < brush->face_count; ++f) + { + face* face = &brush->faces[f]; + + face_geometry* face_geo_inst = &brush_inst->faces[f]; + + for (int i = 0; i < face_geo_inst->vertex_count; ++i) + { + face_vertex vertex = face_geo_inst->vertices[i]; + + Vector3 vertexPos = Vector3( + (vertex.vertex.y - brush->center.y) * (1.0f / 64), + (vertex.vertex.z - brush->center.z) * (1.0f / 64), + (vertex.vertex.x - brush->center.x) * (1.0f / 64) + ); + + Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); + Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); + + vertices.push_back(Vertex{ + vertexPos, + Vector2(0,0), + vertexNormal, + vertexTangent, + glm::vec3(0.0, 1.0, 0.0), 0.0f + }); + } + + for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) + { + unsigned int index = face_geo_inst->indices[i]; + indices.push_back((unsigned int)indexOffset + index); + } + + indexOffset += face_geo_inst->vertex_count; + } + bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); } - bsp.target = target; - - parent.AddChild(brushEntity); - - transformComponent.Translation = Vector3( - brush->center.y * (1.0f / 64), - brush->center.z * (1.0f / 64), - brush->center.x * (1.0f / 64)); - - int index_offset = 0; - int lastTextureID = -1; - std::string lastTexturePath = ""; - - - for (int f = 0; f < brush->face_count; ++f) + void QuakeMapBuilder::CreateBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname) { - face* face = &brush->faces[f]; - texture_data* texture = &textures[face->texture_idx]; - if (std::string(texture->name) == "__TB_empty") + std::vector vertices; + std::vector indices; + Entity brushEntity = scene->CreateEntity(targetname); + TransformComponent& transformComponent = brushEntity.GetComponent(); + BSPBrushComponent& bsp = brushEntity.AddComponent(); + + parent.AddChild(brushEntity); + + transformComponent.Translation = Vector3( + brush->center.y * (1.0f / 64), + brush->center.z * (1.0f / 64), + brush->center.x * (1.0f / 64)); + + int index_offset = 0; + int lastTextureID = -1; + std::string lastTexturePath = ""; + for (int f = 0; f < brush->face_count; ++f) { - texture->height = 1; - texture->width = 1; - } - else - { - std::string path = FileSystem::Root + std::string(texture->name) + ".png"; - auto tex = TextureManager::Get()->GetTexture(path); - texture->height = tex->GetHeight(); - texture->width = tex->GetWidth(); - } + face* face = &brush->faces[f]; + texture_data* texture = &textures[face->texture_idx]; - face_geometry* face_geo_inst = &brush_inst->faces[f]; + if (std::string(texture->name) == "__TB_empty") + { + texture->height = 1; + texture->width = 1; + } + else + { + std::string path = FileSystem::Root + "textures/" + std::string(texture->name) + ".png"; + auto tex = TextureManager::Get()->GetTexture(path); - for (int i = 0; i < face_geo_inst->vertex_count; ++i) - { - face_vertex vertex = face_geo_inst->vertices[i]; - vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height); + texture->height = tex->GetHeight(); + texture->width = tex->GetWidth(); + } - Vector3 vertexPos = Vector3( - (vertex.vertex.y - brush->center.y) * (1.0f / 64), - (vertex.vertex.z - brush->center.z) * (1.0f / 64), - (vertex.vertex.x - brush->center.x) * (1.0f / 64) - ); + face_geometry* face_geo_inst = &brush_inst->faces[f]; - Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); - Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); - Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); + for (int i = 0; i < face_geo_inst->vertex_count; ++i) + { + face_vertex vertex = face_geo_inst->vertices[i]; + vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height); - vertices.push_back(Vertex - { + Vector3 vertexPos = Vector3( + (vertex.vertex.y - brush->center.y) * (1.0f / 64), + (vertex.vertex.z - brush->center.z) * (1.0f / 64), + (vertex.vertex.x - brush->center.x) * (1.0f / 64) + ); + + Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); + Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); + Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); + + vertices.push_back(Vertex{ vertexPos, vertexUV, vertexNormal, vertexTangent, - glm::vec3(0.0, 1.0, 0.0), - 0.0f - } - ); - } + glm::vec3(0.0, 1.0, 0.0), 0.0f + }); + } - for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) - { - unsigned int index = face_geo_inst->indices[i]; - indices.push_back(index_offset + (unsigned int)index); - } + for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) + { + unsigned int index = face_geo_inst->indices[i]; + indices.push_back(index_offset + (unsigned int)index); + } - if(!bsp.IsTrigger) - { if (lastTextureID != face->texture_idx) { lastTexturePath = FileSystem::Root + "textures/" + std::string(texture->name) + ".png"; + if (std::string(texture->name) == "__TB_empty") bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); else @@ -308,118 +186,241 @@ void QuakeMapBuilder::CreateFuncBrush(brush* brush, brush_geometry* brush_inst, index_offset += (face_geo_inst->vertex_count); } } - else + + if (vertices.size() > 0) + bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); + } + + void QuakeMapBuilder::CreateFuncBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname, FGDBrushEntity fgdBrush) + { + std::vector vertices; + std::vector indices; + + std::string name = fgdBrush.Name; + if (targetname != "") + name = targetname; + + Entity brushEntity = scene->CreateEntity(name); + + TransformComponent& transformComponent = brushEntity.GetComponent(); + BSPBrushComponent& bsp = brushEntity.AddComponent(); + + bsp.IsSolid = fgdBrush.Solid; + bsp.IsTransparent = !fgdBrush.Visible; + bsp.IsFunc = true; + bsp.IsTrigger = fgdBrush.IsTrigger; + if (fgdBrush.Script != "" && fgdBrush.Class != "") { - index_offset += (face_geo_inst->vertex_count); + auto& wrenScript = brushEntity.AddComponent(); + wrenScript.Script = fgdBrush.Script; + wrenScript.Class = fgdBrush.Class; } - } - if (bsp.IsTrigger) - { - bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); - vertices.clear(); - } - - if (vertices.size() > 0) - bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); -} - -void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions) -{ - if (!ent.HasComponent()) - return; - - QuakeMapComponent& quakeMapC = ent.GetComponent(); - Scene* m_Scene = ent.GetScene(); - - // TODO: Tag entities *owned* by the map. - ParentComponent& currentParent = ent.GetComponent(); - - // Copy queue, cant delete while iterating. - auto deletionQueue = currentParent.Children; - for (auto& e : deletionQueue) - { - m_Scene->DestroyEntity(e); - } - - map_parser_load(std::string(FileSystem::Root + quakeMapC.Path).c_str()); - geo_generator_run(); - - DefaultMaterial = MaterialManager::Get()->GetMaterial("resources/Textures/default/Default.png"); - for (int e = 0; e < entity_count; ++e) - { - entity* entity_inst = &entities[e]; - entity_geometry* entity_geo_inst = &entity_geo[e]; - - Entity newEntity = m_Scene->CreateEntity("Brush " + std::to_string(e) ); - - if (entity_inst->spawn_type == entity_spawn_type::EST_GROUP) - newEntity.GetComponent().Name = "Group " + std::to_string(e); - - bool isTrigger = false; - bool isFunc = false; - bool isPos = false; - ent.AddChild(newEntity); - - std::string target = ""; - std::string targetname = ""; - FGDBrushEntity fgdBrush; - bool isEntity = false; - for (int i = 0; i < entity_inst->property_count; i++) + if (bsp.IsTrigger) { - property* prop = &(entity_inst->properties)[i]; - std::string key = prop->key; - std::string value = prop->value; - - if (key == "origin") - { - // Positon split with space. - std::vector splits = split(value, ' '); - - float x = std::stof(splits[1]) * (1.f / 64.f); - float y = std::stof(splits[2]) * (1.f / 64.f); - float z = std::stof(splits[0]) * (1.f / 64.f); - - Vector3 position = Vector3(x, y, z); - newEntity.GetComponent().Translation = position; - } - - if (key == "classname") - { - Ref file = Engine::GetProject()->EntityDefinitionsFile; - EntityType type = file->GetTypeOfEntity(value); - if (type != EntityType::None) - { - if (type == EntityType::Brush) - { - fgdBrush = file->GetBrushEntity(value); - isEntity = true; - } - } - } - if (key == "targetname") - { - targetname = value; - } - if (key == "target") - { - target = value; - } + TriggerZone& trigger = brushEntity.AddComponent(); + trigger.target = target; } - for (int b = 0; b < entity_inst->brush_count; ++b) + + bsp.target = target; + + parent.AddChild(brushEntity); + + transformComponent.Translation = Vector3( + brush->center.y * (1.0f / 64), + brush->center.z * (1.0f / 64), + brush->center.x * (1.0f / 64)); + + int index_offset = 0; + int lastTextureID = -1; + std::string lastTexturePath = ""; + + + for (int f = 0; f < brush->face_count; ++f) { - brush* brush_inst = &entity_inst->brushes[b]; - brush_geometry* brush_geo_inst = &entity_geo_inst->brushes[b]; - if (isEntity) + face* face = &brush->faces[f]; + texture_data* texture = &textures[face->texture_idx]; + if (std::string(texture->name) == "__TB_empty") { - CreateFuncBrush(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname, fgdBrush); + texture->height = 1; + texture->width = 1; } else { - CreateBrush(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname); + std::string path = FileSystem::Root + std::string(texture->name) + ".png"; + auto tex = TextureManager::Get()->GetTexture(path); + texture->height = tex->GetHeight(); + texture->width = tex->GetWidth(); + } + + face_geometry* face_geo_inst = &brush_inst->faces[f]; + + for (int i = 0; i < face_geo_inst->vertex_count; ++i) + { + face_vertex vertex = face_geo_inst->vertices[i]; + vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height); + + Vector3 vertexPos = Vector3( + (vertex.vertex.y - brush->center.y) * (1.0f / 64), + (vertex.vertex.z - brush->center.z) * (1.0f / 64), + (vertex.vertex.x - brush->center.x) * (1.0f / 64) + ); + + Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); + Vector3 vertexNormal = Vector3(vertex.normal.y, vertex.normal.z, vertex.normal.x); + Vector3 vertexTangent = Vector3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x); + + vertices.push_back(Vertex + { + vertexPos, + vertexUV, + vertexNormal, + vertexTangent, + glm::vec3(0.0, 1.0, 0.0), + 0.0f + } + ); + } + + for (int i = 0; i < (face_geo_inst->vertex_count - 2) * 3; ++i) + { + unsigned int index = face_geo_inst->indices[i]; + indices.push_back(index_offset + (unsigned int)index); + } + + if (!bsp.IsTrigger) + { + if (lastTextureID != face->texture_idx) + { + lastTexturePath = FileSystem::Root + "textures/" + std::string(texture->name) + ".png"; + if (std::string(texture->name) == "__TB_empty") + bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); + else + bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); + + index_offset = 0; + vertices.clear(); + indices.clear(); + lastTextureID = face->texture_idx; + } + else + { + index_offset += (face_geo_inst->vertex_count); + } + } + else + { + index_offset += (face_geo_inst->vertex_count); } } - isEntity = false; + if (bsp.IsTrigger) + { + bsp.Meshes.push_back(CreateRef(vertices, indices, DefaultMaterial)); + vertices.clear(); + } + + if (vertices.size() > 0) + bsp.Meshes.push_back(CreateRef(vertices, indices, MaterialManager::Get()->GetMaterial(lastTexturePath))); } -} \ No newline at end of file + + void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions) + { + if (!ent.HasComponent()) + return; + + QuakeMapComponent& quakeMapC = ent.GetComponent(); + Scene* m_Scene = ent.GetScene(); + + // TODO: Tag entities *owned* by the map. + ParentComponent& currentParent = ent.GetComponent(); + + // Copy queue, cant delete while iterating. + auto deletionQueue = currentParent.Children; + for (auto& e : deletionQueue) + { + m_Scene->DestroyEntity(e); + } + + map_parser_load(std::string(FileSystem::Root + quakeMapC.Path).c_str()); + geo_generator_run(); + + DefaultMaterial = MaterialManager::Get()->GetMaterial("resources/Textures/default/Default.png"); + for (int e = 0; e < entity_count; ++e) + { + entity* entity_inst = &entities[e]; + entity_geometry* entity_geo_inst = &entity_geo[e]; + + Entity newEntity = m_Scene->CreateEntity("Brush " + std::to_string(e)); + + if (entity_inst->spawn_type == entity_spawn_type::EST_GROUP) + newEntity.GetComponent().Name = "Group " + std::to_string(e); + + bool isTrigger = false; + bool isFunc = false; + bool isPos = false; + ent.AddChild(newEntity); + + std::string target = ""; + std::string targetname = ""; + FGDBrushEntity fgdBrush; + bool isEntity = false; + for (int i = 0; i < entity_inst->property_count; i++) + { + property* prop = &(entity_inst->properties)[i]; + std::string key = prop->key; + std::string value = prop->value; + + if (key == "origin") + { + // Positon split with space. + std::vector splits = split(value, ' '); + + float x = std::stof(splits[1]) * (1.f / 64.f); + float y = std::stof(splits[2]) * (1.f / 64.f); + float z = std::stof(splits[0]) * (1.f / 64.f); + + Vector3 position = Vector3(x, y, z); + newEntity.GetComponent().Translation = position; + } + + if (key == "classname") + { + Ref file = Engine::GetProject()->EntityDefinitionsFile; + EntityType type = file->GetTypeOfEntity(value); + if (type != EntityType::None) + { + if (type == EntityType::Brush) + { + fgdBrush = file->GetBrushEntity(value); + isEntity = true; + } + } + } + if (key == "targetname") + { + targetname = value; + } + if (key == "target") + { + target = value; + } + } + for (int b = 0; b < entity_inst->brush_count; ++b) + { + brush* brush_inst = &entity_inst->brushes[b]; + brush_geometry* brush_geo_inst = &entity_geo_inst->brushes[b]; + if (isEntity) + { + CreateFuncBrush(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname, fgdBrush); + } + else + { + CreateBrush(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname); + } + } + + isEntity = false; + } + } +} diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.h b/Nuake/src/Scene/Systems/QuakeMapBuilder.h index eb74496d..8ee50b80 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.h +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.h @@ -1,20 +1,26 @@ #pragma once #include -class Entity; -class Scene; + struct brush; struct brush_geometry; -class FGDBrushEntity; -class QuakeMapBuilder -{ -private: - void CreateTrigger(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname); - void CreateBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname); - void CreateFuncBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname, FGDBrushEntity fgdBrush); -public: - QuakeMapBuilder(){} - void BuildQuakeMap(Entity& ent, bool Collisions = true); +namespace Nuake { + class Entity; + class Scene; + class FGDBrushEntity; + + class QuakeMapBuilder + { + private: + void CreateTrigger(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname); + void CreateBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname); + void CreateFuncBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, std::string target, std::string targetname, FGDBrushEntity fgdBrush); + public: + QuakeMapBuilder() {} + + void BuildQuakeMap(Entity& ent, bool Collisions = true); + }; +} + -}; \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/ScriptingSystem.cpp b/Nuake/src/Scene/Systems/ScriptingSystem.cpp index 6b5d6358..639bf88d 100644 --- a/Nuake/src/Scene/Systems/ScriptingSystem.cpp +++ b/Nuake/src/Scene/Systems/ScriptingSystem.cpp @@ -1,74 +1,76 @@ #include "ScriptingSystem.h" -#include +#include "src/Scene/Components/WrenScriptComponent.h" #include "src/Scene/Scene.h" -ScriptingSystem::ScriptingSystem(Scene* scene) -{ - m_Scene = scene; -} - -bool ScriptingSystem::Init() -{ - ScriptingEngine::Init(); - - auto entities = m_Scene->m_Registry.view(); - for (auto e : entities) +namespace Nuake { + ScriptingSystem::ScriptingSystem(Scene* scene) { - WrenScriptComponent& wren = entities.get(e); - if (wren.Script != "" && wren.Class != "") + m_Scene = scene; + } + + bool ScriptingSystem::Init() + { + ScriptingEngine::Init(); + + auto entities = m_Scene->m_Registry.view(); + for (auto e : entities) { - wren.WrenScript = CreateRef(wren.Script, wren.Class, true); - if (!wren.WrenScript->CompiledSuccesfully) - return false; + WrenScriptComponent& wren = entities.get(e); + if (wren.Script != "" && wren.Class != "") + { + wren.WrenScript = CreateRef(wren.Script, wren.Class, true); + if (!wren.WrenScript->CompiledSuccesfully) + return false; + } + + if (wren.WrenScript != nullptr) + { + wren.WrenScript->SetScriptableEntityID((int)e); + wren.WrenScript->CallInit(); + } } - if (wren.WrenScript != nullptr) + return true; + } + + + void ScriptingSystem::Update(Timestep ts) + { + auto entities = m_Scene->m_Registry.view(); + for (auto& e : entities) { - wren.WrenScript->SetScriptableEntityID((int)e); - wren.WrenScript->CallInit(); + WrenScriptComponent& wren = entities.get(e); + + if (wren.WrenScript != nullptr) + wren.WrenScript->CallUpdate(ts); } } - return true; -} - -void ScriptingSystem::Update(Timestep ts) -{ - auto entities = m_Scene->m_Registry.view(); - for (auto& e : entities) + void ScriptingSystem::FixedUpdate(Timestep ts) { - WrenScriptComponent& wren = entities.get(e); + auto entities = m_Scene->m_Registry.view(); + for (auto& e : entities) + { + WrenScriptComponent& wren = entities.get(e); - if (wren.WrenScript != nullptr) - wren.WrenScript->CallUpdate(ts); - } -} - - -void ScriptingSystem::FixedUpdate(Timestep ts) -{ - auto entities = m_Scene->m_Registry.view(); - for (auto& e : entities) - { - WrenScriptComponent& wren = entities.get(e); - - if (wren.WrenScript != nullptr) - wren.WrenScript->CallFixedUpdate(ts); - } -} - - -void ScriptingSystem::Exit() -{ - auto entities = m_Scene->m_Registry.view(); - for (auto& e : entities) - { - WrenScriptComponent& wren = entities.get(e); - - if (wren.WrenScript != nullptr) - wren.WrenScript->CallExit(); + if (wren.WrenScript != nullptr) + wren.WrenScript->CallFixedUpdate(ts); + } } - ScriptingEngine::Close(); -} \ No newline at end of file + + void ScriptingSystem::Exit() + { + auto entities = m_Scene->m_Registry.view(); + for (auto& e : entities) + { + WrenScriptComponent& wren = entities.get(e); + + if (wren.WrenScript != nullptr) + wren.WrenScript->CallExit(); + } + + ScriptingEngine::Close(); + } +} diff --git a/Nuake/src/Scene/Systems/ScriptingSystem.h b/Nuake/src/Scene/Systems/ScriptingSystem.h index ceba23ad..6ab630c2 100644 --- a/Nuake/src/Scene/Systems/ScriptingSystem.h +++ b/Nuake/src/Scene/Systems/ScriptingSystem.h @@ -1,13 +1,17 @@ #pragma once #include "System.h" -class Scene; -class ScriptingSystem : public System { -public: - ScriptingSystem(Scene* scene); - bool Init() override; - void Update(Timestep ts) override; - void Draw() override {} - void FixedUpdate(Timestep ts) override; - void Exit() override; -}; \ No newline at end of file +namespace Nuake { + class Scene; + + class ScriptingSystem : public System + { + public: + ScriptingSystem(Scene* scene); + bool Init() override; + void Update(Timestep ts) override; + void Draw() override {} + void FixedUpdate(Timestep ts) override; + void Exit() override; + }; +} diff --git a/Nuake/src/Scene/Systems/System.h b/Nuake/src/Scene/Systems/System.h index b032132b..f167c702 100644 --- a/Nuake/src/Scene/Systems/System.h +++ b/Nuake/src/Scene/Systems/System.h @@ -1,18 +1,21 @@ #pragma once -#include +#include "src/Core/Timestep.h" #include "src/Core/Core.h" -class Scene; -class System { -public: - Scene* m_Scene; +namespace Nuake +{ + class Scene; + class System { + public: + Scene* m_Scene; - virtual bool Init() = 0; + virtual bool Init() = 0; - virtual void Draw() = 0; + virtual void Draw() = 0; - virtual void Update(Timestep ts) = 0; - virtual void FixedUpdate(Timestep ts) = 0; + virtual void Update(Timestep ts) = 0; + virtual void FixedUpdate(Timestep ts) = 0; - virtual void Exit() = 0; -}; \ No newline at end of file + virtual void Exit() = 0; + }; +} diff --git a/Nuake/src/Scene/Systems/TransformSystem.cpp b/Nuake/src/Scene/Systems/TransformSystem.cpp index 9ae10853..5dcbb131 100644 --- a/Nuake/src/Scene/Systems/TransformSystem.cpp +++ b/Nuake/src/Scene/Systems/TransformSystem.cpp @@ -1,54 +1,56 @@ #include "TransformSystem.h" #include "src/Scene/Scene.h" -#include -#include +#include "src/Scene/Components/TransformComponent.h" +#include "src/Scene/Components/ParentComponent.h" -TransformSystem::TransformSystem(Scene* scene) -{ - m_Scene = scene; -} +namespace Nuake { + TransformSystem::TransformSystem(Scene* scene) + { + m_Scene = scene; + } -bool TransformSystem::Init() -{ - UpdateTransform(); - return true; -} + bool TransformSystem::Init() + { + UpdateTransform(); + return true; + } -void TransformSystem::Update(Timestep ts) -{ - UpdateTransform(); -} + void TransformSystem::Update(Timestep ts) + { + UpdateTransform(); + } -void TransformSystem::FixedUpdate(Timestep ts) -{ + void TransformSystem::FixedUpdate(Timestep ts) + { -} + } -void TransformSystem::Exit() -{ + void TransformSystem::Exit() + { -} + } -void TransformSystem::UpdateTransform() -{ - auto transformView = m_Scene->m_Registry.view(); - for (auto e : transformView) { - auto [parent, transform] = transformView.get(e); - Entity currentParent = Entity((entt::entity)e, m_Scene); - Vector3 globalPos = Vector3(); - if (parent.HasParent) - { - while (currentParent.GetComponent().HasParent) + void TransformSystem::UpdateTransform() + { + auto transformView = m_Scene->m_Registry.view(); + for (auto e : transformView) { + auto [parent, transform] = transformView.get(e); + Entity currentParent = Entity((entt::entity)e, m_Scene); + Vector3 globalPos = Vector3(); + if (parent.HasParent) { - currentParent = currentParent.GetComponent().Parent; - globalPos += currentParent.GetComponent().Translation; - } + while (currentParent.GetComponent().HasParent) + { + currentParent = currentParent.GetComponent().Parent; + globalPos += currentParent.GetComponent().Translation; + } - transform.GlobalTranslation = globalPos + transform.Translation; - } - else - { - transform.GlobalTranslation = transform.Translation; + transform.GlobalTranslation = globalPos + transform.Translation; + } + else + { + transform.GlobalTranslation = transform.Translation; + } } } -} \ No newline at end of file +} diff --git a/Nuake/src/Scene/Systems/TransformSystem.h b/Nuake/src/Scene/Systems/TransformSystem.h index fd032143..a6f88596 100644 --- a/Nuake/src/Scene/Systems/TransformSystem.h +++ b/Nuake/src/Scene/Systems/TransformSystem.h @@ -1,15 +1,19 @@ #pragma once #include "System.h" -class Scene; -class TransformSystem : public System { -public: - TransformSystem(Scene* scene); - bool Init() override; - void Update(Timestep ts) override; - void Draw() override {} - void FixedUpdate(Timestep ts) override; - void Exit() override; +namespace Nuake { + class Scene; - void UpdateTransform(); -}; \ No newline at end of file + class TransformSystem : public System + { + public: + TransformSystem(Scene* scene); + bool Init() override; + void Update(Timestep ts) override; + void Draw() override {} + void FixedUpdate(Timestep ts) override; + void Exit() override; + + void UpdateTransform(); + }; +} diff --git a/Nuake/src/Scene/Systems/TrenchbroomSystem.cpp b/Nuake/src/Scene/Systems/TrenchbroomSystem.cpp index dc3f5579..b3eff865 100644 --- a/Nuake/src/Scene/Systems/TrenchbroomSystem.cpp +++ b/Nuake/src/Scene/Systems/TrenchbroomSystem.cpp @@ -1,27 +1,29 @@ #include "TrenchbroomSystem.h" - -TrenchbroomSystem::TrenchbroomSystem(Scene* scene) +namespace Nuake { - m_Scene = scene; + TrenchbroomSystem::TrenchbroomSystem(Scene* scene) + { + m_Scene = scene; + } + + bool TrenchbroomSystem::Init() + { + return true; + } + + void TrenchbroomSystem::Update(Timestep ts) + { + + } + + void TrenchbroomSystem::FixedUpdate(Timestep ts) + { + + } + + void TrenchbroomSystem::Exit() + { + + } } - -bool TrenchbroomSystem::Init() -{ - return true; -} - -void TrenchbroomSystem::Update(Timestep ts) -{ - -} - -void TrenchbroomSystem::FixedUpdate(Timestep ts) -{ - -} - -void TrenchbroomSystem::Exit() -{ - -} \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/TrenchbroomSystem.h b/Nuake/src/Scene/Systems/TrenchbroomSystem.h index e923986d..547a87a0 100644 --- a/Nuake/src/Scene/Systems/TrenchbroomSystem.h +++ b/Nuake/src/Scene/Systems/TrenchbroomSystem.h @@ -1,12 +1,16 @@ #pragma once #include -class TrenchbroomSystem : public System { -public: - TrenchbroomSystem(Scene* scene); - bool Init() override; - void Update(Timestep ts) override; - void Draw() override {} - void FixedUpdate(Timestep ts) override; - void Exit() override; -}; \ No newline at end of file +namespace Nuake +{ + class TrenchbroomSystem : public System + { + public: + TrenchbroomSystem(Scene* scene); + bool Init() override; + void Update(Timestep ts) override; + void Draw() override {} + void FixedUpdate(Timestep ts) override; + void Exit() override; + }; +} diff --git a/Nuake/src/Scripting/Modules/EngineModule.h b/Nuake/src/Scripting/Modules/EngineModule.h index 65f1eec0..b6f082d6 100644 --- a/Nuake/src/Scripting/Modules/EngineModule.h +++ b/Nuake/src/Scripting/Modules/EngineModule.h @@ -5,27 +5,29 @@ #include "ScriptModule.h" #include #include - -namespace ScriptAPI +namespace Nuake { - class EngineModule : public ScriptModule + namespace ScriptAPI { - std::string ModuleName = "Engine"; - - std::string GetModuleName() override + class EngineModule : public ScriptModule { - return "Engine"; - } + std::string ModuleName = "Engine"; - void RegisterModule(WrenVM* vm) override - { - RegisterMethod("Log(_)", (void*)Log); - } + std::string GetModuleName() override + { + return "Engine"; + } - static void Log(WrenVM* vm) - { - std::string msg = wrenGetSlotString(vm, 1); - Logger::Log(msg); - } - }; + void RegisterModule(WrenVM* vm) override + { + RegisterMethod("Log(_)", (void*)Log); + } + + static void Log(WrenVM* vm) + { + std::string msg = wrenGetSlotString(vm, 1); + Logger::Log(msg); + } + }; + } } \ No newline at end of file diff --git a/Nuake/src/Scripting/Modules/EntityModule.h b/Nuake/src/Scripting/Modules/EntityModule.h index 7835d49e..70f51d18 100644 --- a/Nuake/src/Scripting/Modules/EntityModule.h +++ b/Nuake/src/Scripting/Modules/EntityModule.h @@ -6,33 +6,34 @@ #include #include -namespace ScriptAPI +namespace Nuake { - class EngineModule : public ScriptModule + namespace ScriptAPI { - std::string ModuleName = "Engine"; - std::string WrenAPI = "class Engine { \n" - "foreign static Log(msg) \n" - "}" - ""; - - std::string GetModuleName() override + class EngineModule : public ScriptModule { - return "Engine"; - } + std::string ModuleName = "Engine"; + std::string WrenAPI = "class Engine { \n" + "foreign static Log(msg) \n" + "}" + ""; - void RegisterModule(WrenVM* vm) override - { - RegisterMethod("Log(_)", (void*)Log); - WrenInterpretResult result = wrenInterpret(vm, "main", WrenAPI.c_str()); - } - - static void Log(WrenVM* vm) - { - std::string msg = wrenGetSlotString(vm, 1); - Logger::Log(msg); - } - }; + std::string GetModuleName() override + { + return "Engine"; + } + void RegisterModule(WrenVM* vm) override + { + RegisterMethod("Log(_)", (void*)Log); + WrenInterpretResult result = wrenInterpret(vm, "main", WrenAPI.c_str()); + } + static void Log(WrenVM* vm) + { + std::string msg = wrenGetSlotString(vm, 1); + Logger::Log(msg); + } + }; + } } \ No newline at end of file diff --git a/Nuake/src/Scripting/Modules/InputModule.h b/Nuake/src/Scripting/Modules/InputModule.h index 4f5d3cd7..50d1fd84 100644 --- a/Nuake/src/Scripting/Modules/InputModule.h +++ b/Nuake/src/Scripting/Modules/InputModule.h @@ -8,98 +8,99 @@ #include "../Core/Maths.h" #include "../Core/Input.h" -namespace ScriptAPI -{ - class InputModule : public ScriptModule - { - std::string GetModuleName() override +namespace Nuake { + namespace ScriptAPI { + class InputModule : public ScriptModule { - return "Input"; - } + std::string GetModuleName() override + { + return "Input"; + } - void RegisterModule(WrenVM* vm) override - { - RegisterMethod("GetMouseX()", GetMouseX); - RegisterMethod("GetMouseY()", (void*)GetMouseY); + void RegisterModule(WrenVM* vm) override + { + RegisterMethod("GetMouseX()", GetMouseX); + RegisterMethod("GetMouseY()", (void*)GetMouseY); - RegisterMethod("IsKeyDown_(_)", (void*)IsKeyDown); - RegisterMethod("IsKeyPressed_(_)", (void*)IsKeyPressed); - RegisterMethod("IsKeyReleased_(_)", (void*)IsKeyReleased); + RegisterMethod("IsKeyDown_(_)", (void*)IsKeyDown); + RegisterMethod("IsKeyPressed_(_)", (void*)IsKeyPressed); + RegisterMethod("IsKeyReleased_(_)", (void*)IsKeyReleased); - RegisterMethod("IsMouseButtonDown_(_)", (void*)IsMouseButtonDown); - RegisterMethod("IsMouseButtonPressed_(_)", (void*)IsMouseButtonPressed); - RegisterMethod("IsMouseButtonReleased_(_)", (void*)IsMouseButtonReleased); + RegisterMethod("IsMouseButtonDown_(_)", (void*)IsMouseButtonDown); + RegisterMethod("IsMouseButtonPressed_(_)", (void*)IsMouseButtonPressed); + RegisterMethod("IsMouseButtonReleased_(_)", (void*)IsMouseButtonReleased); - RegisterMethod("HideMouse()", (void*)HideMouse); - RegisterMethod("ShowMouse()", (void*)ShowMouse); - RegisterMethod("IsMouseHidden()", (void*)IsMouseHidden); - } + RegisterMethod("HideMouse()", (void*)HideMouse); + RegisterMethod("ShowMouse()", (void*)ShowMouse); + RegisterMethod("IsMouseHidden()", (void*)IsMouseHidden); + } - static void GetMouseX(WrenVM* vm) - { - wrenSetSlotDouble(vm, 0, Input::GetMouseX()); - } + static void GetMouseX(WrenVM* vm) + { + wrenSetSlotDouble(vm, 0, Input::GetMouseX()); + } - static void GetMouseY(WrenVM* vm) - { - wrenSetSlotDouble(vm, 0, Input::GetMouseY()); - } + static void GetMouseY(WrenVM* vm) + { + wrenSetSlotDouble(vm, 0, Input::GetMouseY()); + } - static void IsMouseButtonDown(WrenVM* vm) - { - int key = wrenGetSlotDouble(vm, 1); - bool result = Input::IsMouseButtonDown(key); - wrenSetSlotBool(vm, 0, result); - } + static void IsMouseButtonDown(WrenVM* vm) + { + int key = wrenGetSlotDouble(vm, 1); + bool result = Input::IsMouseButtonDown(key); + wrenSetSlotBool(vm, 0, result); + } - static void IsMouseButtonPressed(WrenVM* vm) - { - int key = (int)wrenGetSlotDouble(vm, 1); - bool result = Input::IsMouseButtonPressed(key); - wrenSetSlotBool(vm, 0, result); - } + static void IsMouseButtonPressed(WrenVM* vm) + { + int key = (int)wrenGetSlotDouble(vm, 1); + bool result = Input::IsMouseButtonPressed(key); + wrenSetSlotBool(vm, 0, result); + } - static void IsMouseButtonReleased(WrenVM* vm) - { - int key = wrenGetSlotDouble(vm, 1); - bool result = Input::IsMouseButtonReleased(key); - wrenSetSlotBool(vm, 0, result); - } + static void IsMouseButtonReleased(WrenVM* vm) + { + int key = wrenGetSlotDouble(vm, 1); + bool result = Input::IsMouseButtonReleased(key); + wrenSetSlotBool(vm, 0, result); + } - static void IsKeyDown(WrenVM* vm) - { - int key = wrenGetSlotDouble(vm, 1); - bool result = Input::IsKeyDown(key); - wrenSetSlotBool(vm, 0, result); - } + static void IsKeyDown(WrenVM* vm) + { + int key = wrenGetSlotDouble(vm, 1); + bool result = Input::IsKeyDown(key); + wrenSetSlotBool(vm, 0, result); + } - static void IsKeyPressed(WrenVM* vm) - { - int key = wrenGetSlotDouble(vm, 1); - bool result = Input::IsKeyPressed(key); - wrenSetSlotBool(vm, 0, result); - } + static void IsKeyPressed(WrenVM* vm) + { + int key = wrenGetSlotDouble(vm, 1); + bool result = Input::IsKeyPressed(key); + wrenSetSlotBool(vm, 0, result); + } - static void IsKeyReleased(WrenVM* vm) - { - int key = wrenGetSlotDouble(vm, 1); - bool result = Input::IsKeyReleased(key); - wrenSetSlotBool(vm, 0, result); - } + static void IsKeyReleased(WrenVM* vm) + { + int key = wrenGetSlotDouble(vm, 1); + bool result = Input::IsKeyReleased(key); + wrenSetSlotBool(vm, 0, result); + } - static void HideMouse(WrenVM* vm) - { - Input::HideMouse(); - } + static void HideMouse(WrenVM* vm) + { + Input::HideMouse(); + } - static void ShowMouse(WrenVM* vm) - { - Input::ShowMouse(); - } + static void ShowMouse(WrenVM* vm) + { + Input::ShowMouse(); + } - static void IsMouseHidden(WrenVM* vm) - { - wrenSetSlotBool(vm, 0, Input::IsMouseHidden()); - } - }; + static void IsMouseHidden(WrenVM* vm) + { + wrenSetSlotBool(vm, 0, Input::IsMouseHidden()); + } + }; + } } \ No newline at end of file diff --git a/Nuake/src/Scripting/Modules/MathModule.h b/Nuake/src/Scripting/Modules/MathModule.h index 8fe284c1..311a1846 100644 --- a/Nuake/src/Scripting/Modules/MathModule.h +++ b/Nuake/src/Scripting/Modules/MathModule.h @@ -7,86 +7,84 @@ #include #include "../Core/Maths.h" -namespace ScriptAPI -{ - class MathModule : public ScriptModule - { - std::string ModuleName = "Math"; - - - std::string GetModuleName() override +namespace Nuake { + namespace ScriptAPI { + class MathModule : public ScriptModule { - return "Math"; - } + std::string ModuleName = "Math"; - void RegisterModule(WrenVM* vm) override - { - RegisterMethod("Sqrt_(_,_,_)", (void*)Sqrt); - RegisterMethod("Sin(_)", (void*)Sin); - RegisterMethod("Cos(_)", (void*)Cos); - RegisterMethod("Radians(_)", (void*)Radians); - RegisterMethod("Degrees(_)", (void*)Degrees); - RegisterMethod("Cross_(_,_,_,_,_,_)", (void*)Cross); - } + std::string GetModuleName() override + { + return "Math"; + } - static void Sqrt(WrenVM* vm) - { - float x = wrenGetSlotDouble(vm, 1); - float y = wrenGetSlotDouble(vm, 2); - float z = wrenGetSlotDouble(vm, 3); - float result = glm::sqrt((x * x) + (y * y) + (z * z)); - wrenSetSlotDouble(vm, 0, result); - } + void RegisterModule(WrenVM* vm) override + { + RegisterMethod("Sqrt_(_,_,_)", (void*)Sqrt); + RegisterMethod("Sin(_)", (void*)Sin); + RegisterMethod("Cos(_)", (void*)Cos); + RegisterMethod("Radians(_)", (void*)Radians); + RegisterMethod("Degrees(_)", (void*)Degrees); + RegisterMethod("Cross_(_,_,_,_,_,_)", (void*)Cross); + } - static void Cos(WrenVM* vm) - { - float d = wrenGetSlotDouble(vm, 1); - float result = glm::cos(d); - wrenSetSlotDouble(vm, 0, result); - } + static void Sqrt(WrenVM* vm) + { + float x = wrenGetSlotDouble(vm, 1); + float y = wrenGetSlotDouble(vm, 2); + float z = wrenGetSlotDouble(vm, 3); + float result = glm::sqrt((x * x) + (y * y) + (z * z)); + wrenSetSlotDouble(vm, 0, result); + } - static void Sin(WrenVM* vm) - { - float d = wrenGetSlotDouble(vm, 1); - float result = glm::sin(d); - wrenSetSlotDouble(vm, 0, result); - } + static void Cos(WrenVM* vm) + { + float d = wrenGetSlotDouble(vm, 1); + float result = glm::cos(d); + wrenSetSlotDouble(vm, 0, result); + } - static void Radians(WrenVM* vm) - { - float d = wrenGetSlotDouble(vm, 1); - float result = glm::radians(d); - wrenSetSlotDouble(vm, 0, result); - } + static void Sin(WrenVM* vm) + { + float d = wrenGetSlotDouble(vm, 1); + float result = glm::sin(d); + wrenSetSlotDouble(vm, 0, result); + } - static void Degrees(WrenVM* vm) - { - float d = wrenGetSlotDouble(vm, 1); - float result = glm::degrees(d); - wrenSetSlotDouble(vm, 0, result); - } + static void Radians(WrenVM* vm) + { + float d = wrenGetSlotDouble(vm, 1); + float result = glm::radians(d); + wrenSetSlotDouble(vm, 0, result); + } - static void Cross(WrenVM* vm) - { - Vector3 v1 = Vector3(wrenGetSlotDouble(vm, 1), - wrenGetSlotDouble(vm, 2), - wrenGetSlotDouble(vm, 3)); - Vector3 v2 = Vector3(wrenGetSlotDouble(vm, 4), - wrenGetSlotDouble(vm, 5), - wrenGetSlotDouble(vm, 6)); - Vector3 cross = glm::cross(v1, v2); + static void Degrees(WrenVM* vm) + { + float d = wrenGetSlotDouble(vm, 1); + float result = glm::degrees(d); + wrenSetSlotDouble(vm, 0, result); + } + + static void Cross(WrenVM* vm) + { + Vector3 v1 = Vector3(wrenGetSlotDouble(vm, 1), + wrenGetSlotDouble(vm, 2), + wrenGetSlotDouble(vm, 3)); + Vector3 v2 = Vector3(wrenGetSlotDouble(vm, 4), + wrenGetSlotDouble(vm, 5), + wrenGetSlotDouble(vm, 6)); + Vector3 cross = glm::cross(v1, v2); - wrenSetSlotNewList(vm, 0); - wrenSetSlotDouble(vm, 1, cross.x); - wrenSetSlotDouble(vm, 2, cross.y); - wrenSetSlotDouble(vm, 3, cross.z); - - wrenInsertInList(vm, 0, -1, 1); - wrenInsertInList(vm, 0, -1, 2); - wrenInsertInList(vm, 0, -1, 3); - } - }; - + wrenSetSlotNewList(vm, 0); + wrenSetSlotDouble(vm, 1, cross.x); + wrenSetSlotDouble(vm, 2, cross.y); + wrenSetSlotDouble(vm, 3, cross.z); + wrenInsertInList(vm, 0, -1, 1); + wrenInsertInList(vm, 0, -1, 2); + wrenInsertInList(vm, 0, -1, 3); + } + }; + } } \ No newline at end of file diff --git a/Nuake/src/Scripting/Modules/PhysicsModule.h b/Nuake/src/Scripting/Modules/PhysicsModule.h index 557484bc..6614f65e 100644 --- a/Nuake/src/Scripting/Modules/PhysicsModule.h +++ b/Nuake/src/Scripting/Modules/PhysicsModule.h @@ -7,57 +7,59 @@ #include #include #include "../Core/Physics/PhysicsManager.h" -namespace ScriptAPI -{ - class PhysicsModule : public ScriptModule - { - std::string ModuleName = "Engine"; - std::string GetModuleName() override +namespace Nuake { + namespace ScriptAPI { + class PhysicsModule : public ScriptModule { - return "Physics"; - } + std::string ModuleName = "Engine"; - void RegisterModule(WrenVM* vm) override - { - RegisterMethod("Raycast_(_,_,_,_,_,_)", (void*)Raycast); - } + std::string GetModuleName() override + { + return "Physics"; + } - static void Raycast(WrenVM* vm) - { - Vector3 v1 = Vector3(wrenGetSlotDouble(vm, 1), - wrenGetSlotDouble(vm, 2), - wrenGetSlotDouble(vm, 3)); - Vector3 v2 = Vector3(wrenGetSlotDouble(vm, 4), - wrenGetSlotDouble(vm, 5), - wrenGetSlotDouble(vm, 6)); + void RegisterModule(WrenVM* vm) override + { + RegisterMethod("Raycast_(_,_,_,_,_,_)", (void*)Raycast); + } - RaycastResult result = PhysicsManager::Get()->Raycast(v1, v2); - wrenSetSlotNewList(vm, 0); + static void Raycast(WrenVM* vm) + { + Vector3 v1 = Vector3(wrenGetSlotDouble(vm, 1), + wrenGetSlotDouble(vm, 2), + wrenGetSlotDouble(vm, 3)); + Vector3 v2 = Vector3(wrenGetSlotDouble(vm, 4), + wrenGetSlotDouble(vm, 5), + wrenGetSlotDouble(vm, 6)); - // Returns a list with 3 vectors placed sequentially - // should be reconstructed in the wren side. - wrenSetSlotDouble(vm, 1, result.LocalPoint.x); - wrenSetSlotDouble(vm, 2, result.LocalPoint.y); - wrenSetSlotDouble(vm, 3, result.LocalPoint.z); + RaycastResult result = PhysicsManager::Get()->Raycast(v1, v2); + wrenSetSlotNewList(vm, 0); - wrenSetSlotDouble(vm, 4, result.WorldPoint.x); - wrenSetSlotDouble(vm, 5, result.WorldPoint.y); - wrenSetSlotDouble(vm, 6, result.WorldPoint.z); + // Returns a list with 3 vectors placed sequentially + // should be reconstructed in the wren side. + wrenSetSlotDouble(vm, 1, result.LocalPoint.x); + wrenSetSlotDouble(vm, 2, result.LocalPoint.y); + wrenSetSlotDouble(vm, 3, result.LocalPoint.z); - wrenSetSlotDouble(vm, 7, result.Normal.x); - wrenSetSlotDouble(vm, 8, result.Normal.y); - wrenSetSlotDouble(vm, 9, result.Normal.z); + wrenSetSlotDouble(vm, 4, result.WorldPoint.x); + wrenSetSlotDouble(vm, 5, result.WorldPoint.y); + wrenSetSlotDouble(vm, 6, result.WorldPoint.z); - wrenInsertInList(vm, 0, -1, 1); - wrenInsertInList(vm, 0, -1, 2); - wrenInsertInList(vm, 0, -1, 3); - wrenInsertInList(vm, 0, -1, 4); - wrenInsertInList(vm, 0, -1, 5); - wrenInsertInList(vm, 0, -1, 6); - wrenInsertInList(vm, 0, -1, 7); - wrenInsertInList(vm, 0, -1, 8); - wrenInsertInList(vm, 0, -1, 9); - } - }; + wrenSetSlotDouble(vm, 7, result.Normal.x); + wrenSetSlotDouble(vm, 8, result.Normal.y); + wrenSetSlotDouble(vm, 9, result.Normal.z); + + wrenInsertInList(vm, 0, -1, 1); + wrenInsertInList(vm, 0, -1, 2); + wrenInsertInList(vm, 0, -1, 3); + wrenInsertInList(vm, 0, -1, 4); + wrenInsertInList(vm, 0, -1, 5); + wrenInsertInList(vm, 0, -1, 6); + wrenInsertInList(vm, 0, -1, 7); + wrenInsertInList(vm, 0, -1, 8); + wrenInsertInList(vm, 0, -1, 9); + } + }; + } } \ No newline at end of file diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index 9f072750..91ff7394 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -17,294 +17,295 @@ #include #include -namespace ScriptAPI -{ - class SceneModule : public ScriptModule - { - std::string GetModuleName() override +namespace Nuake { + namespace ScriptAPI { + class SceneModule : public ScriptModule { - return "Scene"; - } - - void RegisterModule(WrenVM* vm) override - { - RegisterMethod("GetEntityID(_)", (void*)GetEntity); - RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent); - - RegisterMethod("GetTranslation_(_)", (void*)GetTranslation); - RegisterMethod("SetTranslation_(_,_,_,_)", (void*)SetTranslation); - RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity); - RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity); - - RegisterMethod("GetScript_(_)", (void*)GetScript); - - RegisterMethod("SetCameraDirection_(_,_,_,_)", (void*)SetCameraDirection); - RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection); - RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight); - - RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide); - RegisterMethod("IsCharacterControllerOnGround_(_)", (void*)IsCharacterControllerOnGround); - - RegisterMethod("TriggerGetOverlappingBodyCount_(_)", (void*)TriggerGetOverlappingBodyCount); - RegisterMethod("TriggerGetOverlappingBodies_(_)", (void*)TriggerGetOverlappingBodies); - - RegisterMethod("BrushGetTargets_(_)", (void*)BrushGetTargets); - RegisterMethod("BrushGetTargetsCount_(_)", (void*)BrushGetTargetsCount); - } - - static void GetEntity(WrenVM* vm) - { - std::string name = wrenGetSlotString(vm, 1); - int handle = Engine::GetCurrentScene()->GetEntity(name).GetHandle(); - wrenSetSlotDouble(vm, 0, handle); - } - - static void EntityHasComponent(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - std::string name = wrenGetSlotString(vm, 2); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - if (name == "Transform") + std::string GetModuleName() override { - bool result = ent.HasComponent(); + return "Scene"; + } + + void RegisterModule(WrenVM* vm) override + { + RegisterMethod("GetEntityID(_)", (void*)GetEntity); + RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent); + + RegisterMethod("GetTranslation_(_)", (void*)GetTranslation); + RegisterMethod("SetTranslation_(_,_,_,_)", (void*)SetTranslation); + RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity); + RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity); + + RegisterMethod("GetScript_(_)", (void*)GetScript); + + RegisterMethod("SetCameraDirection_(_,_,_,_)", (void*)SetCameraDirection); + RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection); + RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight); + + RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide); + RegisterMethod("IsCharacterControllerOnGround_(_)", (void*)IsCharacterControllerOnGround); + + RegisterMethod("TriggerGetOverlappingBodyCount_(_)", (void*)TriggerGetOverlappingBodyCount); + RegisterMethod("TriggerGetOverlappingBodies_(_)", (void*)TriggerGetOverlappingBodies); + + RegisterMethod("BrushGetTargets_(_)", (void*)BrushGetTargets); + RegisterMethod("BrushGetTargetsCount_(_)", (void*)BrushGetTargetsCount); + } + + static void GetEntity(WrenVM* vm) + { + std::string name = wrenGetSlotString(vm, 1); + int handle = Engine::GetCurrentScene()->GetEntity(name).GetHandle(); + wrenSetSlotDouble(vm, 0, handle); + } + + static void EntityHasComponent(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + std::string name = wrenGetSlotString(vm, 2); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + if (name == "Transform") + { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + if (name == "Light") + { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + if (name == "QuakeMap") + { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + if (name == "CharacterController") + { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + if (name == "Camera") + { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + if (name == "Script") + { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + if (name == "Rigidbody") + { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + if (name == "Script") { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + if (name == "Brush") { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + } + + static void GetScript(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + if (ent.HasComponent()) + { + wrenSetSlotHandle(vm, 0, ent.GetComponent().WrenScript->m_Instance); + } + } + + static void SetLightIntensity(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + float intensity = wrenGetSlotDouble(vm, 2); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + auto& light = ent.GetComponent(); + light.Strength = intensity; + } + + static void GetLightIntensity(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + float intensity = wrenGetSlotDouble(vm, 2); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + auto& light = ent.GetComponent(); + wrenSetSlotDouble(vm, 0, light.Strength); + } + + static void SetCameraDirection(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + float x = wrenGetSlotDouble(vm, 2); + float y = wrenGetSlotDouble(vm, 3); + float z = wrenGetSlotDouble(vm, 4); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + auto& cam = ent.GetComponent(); + cam.CameraInstance->SetDirection(Vector3(x, y, z)); + } + + static void GetCameraDirection(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + auto& cam = ent.GetComponent(); + + Vector3 dir = cam.CameraInstance->GetDirection(); + + wrenEnsureSlots(vm, 4); + + // set the slots + // Fill the list + wrenSetSlotNewList(vm, 0); + wrenSetSlotDouble(vm, 1, dir.x); + wrenSetSlotDouble(vm, 2, dir.y); + wrenSetSlotDouble(vm, 3, dir.z); + + wrenInsertInList(vm, 0, -1, 1); + wrenInsertInList(vm, 0, -1, 2); + wrenInsertInList(vm, 0, -1, 3); + } + + static void GetCameraRight(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + auto& cam = ent.GetComponent(); + + Vector3 right = cam.CameraInstance->cameraRight; + + // set the slots + wrenSetSlotDouble(vm, 1, right.x); + wrenSetSlotDouble(vm, 2, right.y); + wrenSetSlotDouble(vm, 3, right.z); + + // Fill the list + wrenSetSlotNewList(vm, 0); + wrenInsertInList(vm, 0, 0, 1); + wrenInsertInList(vm, 0, 1, 2); + wrenInsertInList(vm, 0, 2, 3); + } + + static void IsCharacterControllerOnGround(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + auto& characterController = ent.GetComponent(); + bool result = characterController.CharacterController->IsOnGround; wrenSetSlotBool(vm, 0, result); } - if (name == "Light") + + static void MoveAndSlide(WrenVM* vm) { - bool result = ent.HasComponent(); - wrenSetSlotBool(vm, 0, result); + int handle = wrenGetSlotDouble(vm, 1); + float x = wrenGetSlotDouble(vm, 2); + float y = wrenGetSlotDouble(vm, 3); + float z = wrenGetSlotDouble(vm, 4); + + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + auto& characterController = ent.GetComponent(); + characterController.CharacterController->MoveAndSlide(Vector3(x, y, z)); } - if (name == "QuakeMap") + + static void GetTranslation(WrenVM* vm) { - bool result = ent.HasComponent(); - wrenSetSlotBool(vm, 0, result); + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + auto& transform = ent.GetComponent(); + // set the slots + wrenSetSlotDouble(vm, 1, transform.Translation.x); + wrenSetSlotDouble(vm, 2, transform.Translation.y); + wrenSetSlotDouble(vm, 3, transform.Translation.z); + + // Fill the list + wrenSetSlotNewList(vm, 0); + wrenInsertInList(vm, 0, 0, 1); + wrenInsertInList(vm, 0, 1, 2); + wrenInsertInList(vm, 0, 2, 3); } - if (name == "CharacterController") + + static void SetTranslation(WrenVM* vm) { - bool result = ent.HasComponent(); - wrenSetSlotBool(vm, 0, result); + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + auto& transform = ent.GetComponent(); + // set the slots + float x = wrenGetSlotDouble(vm, 2); + float y = wrenGetSlotDouble(vm, 3); + float z = wrenGetSlotDouble(vm, 4); + + transform.Translation = Vector3(x, y, z); } - if (name == "Camera") + + static void TriggerGetOverlappingBodyCount(WrenVM* vm) { - bool result = ent.HasComponent(); - wrenSetSlotBool(vm, 0, result); + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + TriggerZone trigger = ent.GetComponent(); + + int count = trigger.GetOverLappingCount(); + + wrenSetSlotDouble(vm, 0, count); } - if (name == "Script") + + static void TriggerGetOverlappingBodies(WrenVM* vm) { - bool result = ent.HasComponent(); - wrenSetSlotBool(vm, 0, result); + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + TriggerZone trigger = ent.GetComponent(); + + std::vector entities = trigger.GetOverlappingBodies(); + + wrenEnsureSlots(vm, entities.size()); + + wrenSetSlotNewList(vm, 0); + int idx = 1; + for (auto& e : entities) + { + wrenSetSlotDouble(vm, idx, e.GetHandle()); + wrenInsertInList(vm, 0, -1, idx); + idx++; + } } - if (name == "Rigidbody") + + static void BrushGetTargets(WrenVM* vm) { - bool result = ent.HasComponent(); - wrenSetSlotBool(vm, 0, result); + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + BSPBrushComponent& brush = ent.GetComponent(); + wrenEnsureSlots(vm, brush.Targets.size()); + wrenSetSlotNewList(vm, 0); + + int idx = 1; + for (auto& e : brush.Targets) + { + wrenSetSlotDouble(vm, idx, e.GetHandle()); + wrenInsertInList(vm, 0, -1, idx); + idx++; + } } - if (name == "Script") { - bool result = ent.HasComponent(); - wrenSetSlotBool(vm, 0, result); + + static void BrushGetTargetsCount(WrenVM* vm) { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + BSPBrushComponent& brush = ent.GetComponent(); + wrenSetSlotDouble(vm, 0, brush.Targets.size()); } - if (name == "Brush") { - bool result = ent.HasComponent(); - wrenSetSlotBool(vm, 0, result); - } - } - - static void GetScript(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - if (ent.HasComponent()) - { - wrenSetSlotHandle(vm, 0, ent.GetComponent().WrenScript->m_Instance); - } - } - - static void SetLightIntensity(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - float intensity = wrenGetSlotDouble(vm, 2); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - auto& light = ent.GetComponent(); - light.Strength = intensity; - } - - static void GetLightIntensity(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - float intensity = wrenGetSlotDouble(vm, 2); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - auto& light = ent.GetComponent(); - wrenSetSlotDouble(vm, 0, light.Strength); - } - - static void SetCameraDirection(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - float x = wrenGetSlotDouble(vm, 2); - float y = wrenGetSlotDouble(vm, 3); - float z = wrenGetSlotDouble(vm, 4); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - auto& cam = ent.GetComponent(); - cam.CameraInstance->SetDirection(Vector3(x, y, z)); - } - - static void GetCameraDirection(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - auto& cam = ent.GetComponent(); - - Vector3 dir = cam.CameraInstance->GetDirection(); - - wrenEnsureSlots(vm, 4); - - // set the slots - // Fill the list - wrenSetSlotNewList(vm, 0); - wrenSetSlotDouble(vm, 1, dir.x); - wrenSetSlotDouble(vm, 2, dir.y); - wrenSetSlotDouble(vm, 3, dir.z); - - wrenInsertInList(vm, 0, -1, 1); - wrenInsertInList(vm, 0, -1, 2); - wrenInsertInList(vm, 0, -1, 3); - } - - static void GetCameraRight(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - auto& cam = ent.GetComponent(); - - Vector3 right = cam.CameraInstance->cameraRight; - - // set the slots - wrenSetSlotDouble(vm, 1, right.x); - wrenSetSlotDouble(vm, 2, right.y); - wrenSetSlotDouble(vm, 3, right.z); - - // Fill the list - wrenSetSlotNewList(vm, 0); - wrenInsertInList(vm, 0, 0, 1); - wrenInsertInList(vm, 0, 1, 2); - wrenInsertInList(vm, 0, 2, 3); - } - - static void IsCharacterControllerOnGround(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - auto& characterController = ent.GetComponent(); - bool result = characterController.CharacterController->IsOnGround; - wrenSetSlotBool(vm, 0, result); - } - - static void MoveAndSlide(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - float x = wrenGetSlotDouble(vm, 2); - float y = wrenGetSlotDouble(vm, 3); - float z = wrenGetSlotDouble(vm, 4); - - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - auto& characterController = ent.GetComponent(); - characterController.CharacterController->MoveAndSlide(Vector3(x, y, z)); - } - - static void GetTranslation(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - auto& transform = ent.GetComponent(); - // set the slots - wrenSetSlotDouble(vm, 1, transform.Translation.x); - wrenSetSlotDouble(vm, 2, transform.Translation.y); - wrenSetSlotDouble(vm, 3, transform.Translation.z); - - // Fill the list - wrenSetSlotNewList(vm, 0); - wrenInsertInList(vm, 0, 0, 1); - wrenInsertInList(vm, 0, 1, 2); - wrenInsertInList(vm, 0, 2, 3); - } - - static void SetTranslation(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - auto& transform = ent.GetComponent(); - // set the slots - float x = wrenGetSlotDouble(vm, 2); - float y = wrenGetSlotDouble(vm, 3); - float z = wrenGetSlotDouble(vm, 4); - - transform.Translation = Vector3(x, y, z); - } - - static void TriggerGetOverlappingBodyCount(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - TriggerZone trigger = ent.GetComponent(); - - int count = trigger.GetOverLappingCount(); - - wrenSetSlotDouble(vm, 0, count); - } - - static void TriggerGetOverlappingBodies(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - TriggerZone trigger = ent.GetComponent(); - - std::vector entities = trigger.GetOverlappingBodies(); - - wrenEnsureSlots(vm, entities.size() ); - - wrenSetSlotNewList(vm, 0); - int idx = 1; - for (auto& e : entities) - { - wrenSetSlotDouble(vm, idx, e.GetHandle()); - wrenInsertInList(vm, 0, -1, idx); - idx++; - } - } - - static void BrushGetTargets(WrenVM* vm) - { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - BSPBrushComponent& brush = ent.GetComponent(); - wrenEnsureSlots(vm, brush.Targets.size()); - wrenSetSlotNewList(vm, 0); - - int idx = 1; - for (auto& e : brush.Targets) - { - wrenSetSlotDouble(vm, idx, e.GetHandle()); - wrenInsertInList(vm, 0, -1, idx); - idx++; - } - } - - static void BrushGetTargetsCount(WrenVM* vm) { - int handle = wrenGetSlotDouble(vm, 1); - Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); - - BSPBrushComponent& brush = ent.GetComponent(); - wrenSetSlotDouble(vm, 0, brush.Targets.size()); - } - }; -} \ No newline at end of file + }; + } +} diff --git a/Nuake/src/Scripting/Modules/ScriptModule.h b/Nuake/src/Scripting/Modules/ScriptModule.h index e8a380d6..d0d65a28 100644 --- a/Nuake/src/Scripting/Modules/ScriptModule.h +++ b/Nuake/src/Scripting/Modules/ScriptModule.h @@ -2,26 +2,26 @@ #include #include struct WrenVM; -class ScriptModule -{ -private: - std::map Methods = std::map(); - std::string WrenAPI; -public: - std::string ModuleName; - virtual void RegisterModule(WrenVM*) = 0; - virtual std::string GetModuleName() = 0; - - void RegisterMethod(const std::string& signature, void* ptr) +namespace Nuake { + class ScriptModule { - Methods[signature] = ptr; - } + public: + std::string ModuleName; + virtual void RegisterModule(WrenVM*) = 0; + virtual std::string GetModuleName() = 0; - void* GetMethodPointer(const std::string& signature) - { - return Methods[signature]; - } + void RegisterMethod(const std::string& signature, void* ptr) + { + Methods[signature] = ptr; + } - -}; \ No newline at end of file + void* GetMethodPointer(const std::string& signature) + { + return Methods[signature]; + } + private: + std::map Methods = std::map(); + std::string WrenAPI; + }; +} diff --git a/Nuake/src/Scripting/ScriptLoader.cpp b/Nuake/src/Scripting/ScriptLoader.cpp deleted file mode 100644 index e8ef5a64..00000000 --- a/Nuake/src/Scripting/ScriptLoader.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "ScriptLoader.h" -#include -#include - -bool ScriptLoader::RegisterScript(ScriptableEntity* script) -{ - return false; -} - -bool ScriptLoader::LoadModule(const std::string& path) -{ - - - return true; - -} - - diff --git a/Nuake/src/Scripting/ScriptLoader.h b/Nuake/src/Scripting/ScriptLoader.h deleted file mode 100644 index cbabad8f..00000000 --- a/Nuake/src/Scripting/ScriptLoader.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include "../Scene/Entities/ScriptableEntity.h" - - -typedef void (ScriptModuleRegister)(); -//#define X_INPUT_GET_STATE(name) DWORD WINAPI name(DWORD dwUserIndex, XINPUT_STATE* pState) -// Now we create a typedef for this function pointer -//typedef X_INPUT_GET_STATE(x_input_get_state); -extern "C" -{ - class ScriptLoader - { - private: - static std::map m_Scripts; - - public: - static bool RegisterScript(ScriptableEntity* script); - - - static ScriptableEntity* GetScript(std::string script) { - return m_Scripts[script]; - } - - static bool LoadModule(const std::string& path); - - }; -} diff --git a/Nuake/src/Scripting/ScriptingEngine.cpp b/Nuake/src/Scripting/ScriptingEngine.cpp index a1b97baa..59916bdf 100644 --- a/Nuake/src/Scripting/ScriptingEngine.cpp +++ b/Nuake/src/Scripting/ScriptingEngine.cpp @@ -8,183 +8,186 @@ #include #include -WrenVM* ScriptingEngine::m_WrenVM; +namespace Nuake { + WrenVM* ScriptingEngine::m_WrenVM; -std::map> ScriptingEngine::m_Scripts; -std::map> ScriptingEngine::Modules; -std::vector ScriptingEngine::m_LoadedScripts; + std::map> ScriptingEngine::m_Scripts; + std::map> ScriptingEngine::Modules; + std::vector ScriptingEngine::m_LoadedScripts; -void errorFn(WrenVM* vm, WrenErrorType errorType, - const char* module, const int line, - const char* msg) -{ - switch (errorType) + void errorFn(WrenVM* vm, WrenErrorType errorType, + const char* module, const int line, + const char* msg) { - case WREN_ERROR_COMPILE: - { - std::string t = std::string(module)+ " line " + std::to_string(line) + ": "+ msg; - Logger::Log(t, CRITICAL); - Engine::ExitPlayMode(); - } break; - case WREN_ERROR_STACK_TRACE: - { - std::string t = "Stack trace: " + std::string(module) + " line " + std::to_string(line) + ": " + msg; - Logger::Log(t, CRITICAL); - } break; - case WREN_ERROR_RUNTIME: - { - std::string t = "Script Runtime Error: " + std::string(msg); - Logger::Log(t, WARNING); - } break; + switch (errorType) + { + case WREN_ERROR_COMPILE: + { + std::string t = std::string(module) + " line " + std::to_string(line) + ": " + msg; + Logger::Log(t, CRITICAL); + Engine::ExitPlayMode(); + } break; + case WREN_ERROR_STACK_TRACE: + { + std::string t = "Stack trace: " + std::string(module) + " line " + std::to_string(line) + ": " + msg; + Logger::Log(t, CRITICAL); + } break; + case WREN_ERROR_RUNTIME: + { + std::string t = "Script Runtime Error: " + std::string(msg); + Logger::Log(t, WARNING); + } break; + } } -} -void writeFn(WrenVM* vm, const char* text) -{ - printf("%s", text); -} - -bool hasEnding(std::string const& fullString, std::string const& ending) -{ - if (fullString.length() >= ending.length()) + void writeFn(WrenVM* vm, const char* text) { - return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); + printf("%s", text); } - else + + bool hasEnding(std::string const& fullString, std::string const& ending) { + if (fullString.length() >= ending.length()) + { + return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); + } + else + { + return false; + } + } + + const std::string NuakeModulePrefix = "Nuake:"; + WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) + { + WrenLoadModuleResult result = { 0 }; + + std::string sname = std::string(name); + std::string path = "resources/" + std::string(name); + + bool isAbsolute = false; + if (sname.rfind(NuakeModulePrefix, 0) == 0) + { + size_t prefixPosition = sname.find(NuakeModulePrefix); + sname.erase(prefixPosition, NuakeModulePrefix.length()); + path = "resources/Scripts/" + std::string(sname); + } + else + { + path = FileSystem::Root + name; + isAbsolute = true; + } + + if (!hasEnding(path, ".wren")) + path += ".wren"; + + std::string str = FileSystem::ReadFile(path, true); + char* c = strcpy(new char[str.length() + 1], str.c_str()); + + result.source = c; + return result; + } + + Ref ScriptingEngine::RegisterScript(const std::string& path, const std::string& mod) + { + // Check if scripts has already been loaded. + // You can't import the same module twice, otherwise, compile error. + if (m_Scripts.find(path) == m_Scripts.end()) + { + std::string query = "import \"" + path + "\" for " + mod; + wrenInterpret(m_WrenVM, "main", query.c_str()); + } + + return CreateRef(path, mod); + } + + // Useful to check if a script has been imported, importing a script + // twice gives a compile error. + bool ScriptingEngine::IsScriptImported(const std::string& path) + { + for (auto& script : m_LoadedScripts) + { + if (script == path) + return true; + } return false; } -} -const std::string NuakeModulePrefix = "Nuake:"; -WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) -{ - WrenLoadModuleResult result = { 0 }; - - std::string sname = std::string(name); - std::string path = "resources/" + std::string(name); - - bool isAbsolute = false; - if (sname.rfind(NuakeModulePrefix, 0) == 0) + void ScriptingEngine::ImportScript(const std::string& path) { - size_t prefixPosition = sname.find(NuakeModulePrefix); - sname.erase(prefixPosition, NuakeModulePrefix.length()); - path = "resources/Scripts/" + std::string(sname); - } - else - { - path = FileSystem::Root + name; - isAbsolute = true; + if (IsScriptImported(path)) + return; + m_LoadedScripts.push_back(path); } - if (!hasEnding(path, ".wren")) - path += ".wren"; - std::string str = FileSystem::ReadFile(path, true); - char* c = strcpy(new char[str.length() + 1], str.c_str()); - result.source = c; - return result; -} - -Ref ScriptingEngine::RegisterScript(const std::string& path, const std::string& mod) -{ - // Check if scripts has already been loaded. - // You can't import the same module twice, otherwise, compile error. - if (m_Scripts.find(path) == m_Scripts.end()) + void ScriptingEngine::RegisterModule(Ref scriptModule) { - std::string query = "import \"" + path + "\" for " + mod; - wrenInterpret(m_WrenVM, "main", query.c_str()); + Modules[scriptModule->GetModuleName()] = scriptModule; + scriptModule->RegisterModule(m_WrenVM); } - return CreateRef(path, mod); -} - -// Useful to check if a script has been imported, importing a script -// twice gives a compile error. -bool ScriptingEngine::IsScriptImported(const std::string& path) -{ - for (auto& script : m_LoadedScripts) + void ScriptingEngine::InitScript(Ref script) { - if (script == path) - return true; + script->CallInit(); } - return false; -} -void ScriptingEngine::ImportScript(const std::string& path) -{ - if (IsScriptImported(path)) - return; - m_LoadedScripts.push_back(path); -} - - - -void ScriptingEngine::RegisterModule(Ref scriptModule) -{ - Modules[scriptModule->GetModuleName()] = scriptModule; - scriptModule->RegisterModule(m_WrenVM); -} - -void ScriptingEngine::InitScript(Ref script) -{ - script->CallInit(); -} - -void ScriptingEngine::UpdateScript(Ref script, Timestep timestep) -{ - script->CallUpdate(timestep); -} - -void ScriptingEngine::ExitScript(Ref script) -{ - script->CallExit(); -} - -void ScriptingEngine::Init() -{ - m_Scripts = std::map>(); - m_LoadedScripts.clear(); - - WrenConfiguration config; - wrenInitConfiguration(&config); - - config.loadModuleFn = &myLoadModule; - config.errorFn = &errorFn; - config.writeFn = &writeFn; - config.bindForeignMethodFn = &bindForeignMethod; - - m_WrenVM = wrenNewVM(&config); - - Ref engineModule = CreateRef(); - RegisterModule(engineModule); - Ref sceneModule = CreateRef(); - RegisterModule(sceneModule); - Ref mathModule = CreateRef(); - RegisterModule(mathModule); - Ref inputModule = CreateRef (); - RegisterModule(inputModule); - Ref physicsModule = CreateRef(); - RegisterModule(physicsModule); -} - -void ScriptingEngine::Close() -{ - wrenFreeVM(m_WrenVM); -} - -WrenForeignMethodFn ScriptingEngine::bindForeignMethod(WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature) -{ - if (Modules.find(className) != Modules.end()) + void ScriptingEngine::UpdateScript(Ref script, Timestep timestep) { - Ref mod = Modules[className]; - void* ptr = mod->GetMethodPointer(signature); - return (WrenForeignMethodFn)ptr; + script->CallUpdate(timestep); + } + + void ScriptingEngine::ExitScript(Ref script) + { + script->CallExit(); + } + + void ScriptingEngine::Init() + { + m_Scripts = std::map>(); + m_LoadedScripts.clear(); + + WrenConfiguration config; + wrenInitConfiguration(&config); + + config.loadModuleFn = &myLoadModule; + config.errorFn = &errorFn; + config.writeFn = &writeFn; + config.bindForeignMethodFn = &bindForeignMethod; + + m_WrenVM = wrenNewVM(&config); + + Ref engineModule = CreateRef(); + RegisterModule(engineModule); + Ref sceneModule = CreateRef(); + RegisterModule(sceneModule); + Ref mathModule = CreateRef(); + RegisterModule(mathModule); + Ref inputModule = CreateRef(); + RegisterModule(inputModule); + Ref physicsModule = CreateRef(); + RegisterModule(physicsModule); + } + + void ScriptingEngine::Close() + { + wrenFreeVM(m_WrenVM); + } + + WrenForeignMethodFn ScriptingEngine::bindForeignMethod(WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature) + { + if (Modules.find(className) != Modules.end()) + { + Ref mod = Modules[className]; + void* ptr = mod->GetMethodPointer(signature); + return (WrenForeignMethodFn)ptr; + } + } + + WrenVM* ScriptingEngine::GetWrenVM() + { + return m_WrenVM; } } -WrenVM* ScriptingEngine::GetWrenVM() -{ - return m_WrenVM; -} diff --git a/Nuake/src/Scripting/ScriptingEngine.h b/Nuake/src/Scripting/ScriptingEngine.h index 2bba223d..5e7fbf92 100644 --- a/Nuake/src/Scripting/ScriptingEngine.h +++ b/Nuake/src/Scripting/ScriptingEngine.h @@ -2,41 +2,43 @@ #include #include #include -#include #include "src/Core/Core.h" #include "src/Vendors/wren/src/include/wren.hpp" -#include +#include "src/Core/Timestep.h" -class WrenScript; -class ScriptModule; -class ScriptingEngine +namespace Nuake { -private: - static WrenVM* m_WrenVM; + class WrenScript; + class ScriptModule; + class ScriptingEngine + { + private: + static WrenVM* m_WrenVM; - static std::vector m_LoadedScripts; - static std::map> m_Scripts; - static std::map> Modules; -public: - static Ref RegisterScript(const std::string& path, const std::string& mod); - static bool IsScriptImported(const std::string& path); - static void ImportScript(const std::string& path); - static void RegisterModule(Ref module); - static void InitScript(Ref script); - static void UpdateScript(Ref script, Timestep timestep); - static void ExitScript(Ref script); - static void Init(); - static void RunCode(const std::string& code); - static void Close(); + static std::vector m_LoadedScripts; + static std::map> m_Scripts; + static std::map> Modules; + public: + static Ref RegisterScript(const std::string& path, const std::string& mod); + static bool IsScriptImported(const std::string& path); + static void ImportScript(const std::string& path); + static void RegisterModule(Ref module); + static void InitScript(Ref script); + static void UpdateScript(Ref script, Timestep timestep); + static void ExitScript(Ref script); + static void Init(); + static void RunCode(const std::string& code); + static void Close(); - static WrenForeignMethodFn bindForeignMethod( - WrenVM* vm, - const char* module, - const char* className, - bool isStatic, - const char* signature); + static WrenForeignMethodFn bindForeignMethod( + WrenVM* vm, + const char* module, + const char* className, + bool isStatic, + const char* signature); - static WrenVM* GetWrenVM(); -}; \ No newline at end of file + static WrenVM* GetWrenVM(); + }; +} diff --git a/Nuake/src/Scripting/WrenScript.cpp b/Nuake/src/Scripting/WrenScript.cpp index 1af0e79a..ffffdbc6 100644 --- a/Nuake/src/Scripting/WrenScript.cpp +++ b/Nuake/src/Scripting/WrenScript.cpp @@ -2,110 +2,112 @@ #include "../Core/FileSystem.h" #include -WrenScript::WrenScript(const std::string& path, const std::string& mod, bool isEntity) -{ - WrenVM* vm = ScriptingEngine::GetWrenVM(); - - CompiledSuccesfully = true; - - // Can't import twice the same script, otherwise gives a compile error. - if (!ScriptingEngine::IsScriptImported(path)) +namespace Nuake { + WrenScript::WrenScript(const std::string& path, const std::string& mod, bool isEntity) { - std::string source = "import \"" + path + "\" for " + mod; - WrenInterpretResult result = wrenInterpret(vm, "main", source.c_str()); + WrenVM* vm = ScriptingEngine::GetWrenVM(); - if (result != WREN_RESULT_SUCCESS) - CompiledSuccesfully = false; + CompiledSuccesfully = true; + // Can't import twice the same script, otherwise gives a compile error. + if (!ScriptingEngine::IsScriptImported(path)) + { + std::string source = "import \"" + path + "\" for " + mod; + WrenInterpretResult result = wrenInterpret(vm, "main", source.c_str()); + + if (result != WREN_RESULT_SUCCESS) + CompiledSuccesfully = false; + + if (!CompiledSuccesfully) + return; + + ScriptingEngine::ImportScript(path); + } + + // Get handle to class + wrenEnsureSlots(vm, 1); + wrenGetVariable(vm, "main", mod.c_str(), 0); + WrenHandle* classHandle = wrenGetSlotHandle(vm, 0); + + // Call the constructor + WrenHandle* constructHandle = wrenMakeCallHandle(vm, "new()"); + wrenCall(vm, constructHandle); + + // Retreive value of constructor + this->m_Instance = wrenGetSlotHandle(vm, 0); + + // Create handles to the instance methods. + this->m_OnInitHandle = wrenMakeCallHandle(vm, "init()"); + this->m_OnUpdateHandle = wrenMakeCallHandle(vm, "update(_)"); + this->m_OnFixedUpdateHandle = wrenMakeCallHandle(vm, "fixedUpdate(_)"); + this->m_OnExitHandle = wrenMakeCallHandle(vm, "exit()"); + + if (isEntity) + this->m_SetEntityIDHandle = wrenMakeCallHandle(vm, "SetEntityId(_)"); + } + + void WrenScript::CallInit() + { + WrenVM* vm = ScriptingEngine::GetWrenVM(); + wrenSetSlotHandle(vm, 0, this->m_Instance); + WrenInterpretResult result = wrenCall(vm, this->m_OnInitHandle); + } + + void WrenScript::CallUpdate(float timestep) + { + WrenVM* vm = ScriptingEngine::GetWrenVM(); + wrenEnsureSlots(vm, 2); + wrenSetSlotHandle(vm, 0, this->m_Instance); + wrenSetSlotDouble(vm, 1, timestep); + WrenInterpretResult result = wrenCall(vm, this->m_OnUpdateHandle); + } + + void WrenScript::CallFixedUpdate(float timestep) + { + WrenVM* vm = ScriptingEngine::GetWrenVM(); + wrenEnsureSlots(vm, 2); + wrenSetSlotHandle(vm, 0, this->m_Instance); + wrenSetSlotDouble(vm, 1, timestep); + WrenInterpretResult result = wrenCall(vm, this->m_OnFixedUpdateHandle); + } + + void WrenScript::CallExit() + { if (!CompiledSuccesfully) return; - ScriptingEngine::ImportScript(path); + WrenVM* vm = ScriptingEngine::GetWrenVM(); + wrenEnsureSlots(vm, 1); + wrenSetSlotHandle(vm, 0, this->m_Instance); + WrenInterpretResult result = wrenCall(vm, this->m_OnExitHandle); } - // Get handle to class - wrenEnsureSlots(vm, 1); - wrenGetVariable(vm, "main", mod.c_str(), 0); - WrenHandle* classHandle = wrenGetSlotHandle(vm, 0); + void WrenScript::RegisterMethod(const std::string& signature) + { + WrenVM* vm = ScriptingEngine::GetWrenVM(); + WrenHandle* handle = wrenMakeCallHandle(vm, signature.c_str()); + methods.emplace(signature, handle); + } - // Call the constructor - WrenHandle* constructHandle = wrenMakeCallHandle(vm, "new()"); - wrenCall(vm, constructHandle); + void WrenScript::CallMethod(const std::string& signature) + { + WrenVM* vm = ScriptingEngine::GetWrenVM(); - // Retreive value of constructor - this->m_Instance = wrenGetSlotHandle(vm, 0); - // Create handles to the instance methods. - this->m_OnInitHandle = wrenMakeCallHandle(vm, "init()"); - this->m_OnUpdateHandle = wrenMakeCallHandle(vm, "update(_)"); - this->m_OnFixedUpdateHandle = wrenMakeCallHandle(vm, "fixedUpdate(_)"); - this->m_OnExitHandle = wrenMakeCallHandle(vm, "exit()"); + // Not found. maybe try to register it? + if (methods.find(signature) == methods.end()) + return; - if (isEntity) - this->m_SetEntityIDHandle = wrenMakeCallHandle(vm, "SetEntityId(_)"); -} - -void WrenScript::CallInit() -{ - WrenVM* vm = ScriptingEngine::GetWrenVM(); - wrenSetSlotHandle(vm, 0, this->m_Instance); - WrenInterpretResult result = wrenCall(vm, this->m_OnInitHandle); -} - -void WrenScript::CallUpdate(float timestep) -{ - WrenVM* vm = ScriptingEngine::GetWrenVM(); - wrenEnsureSlots(vm, 2); - wrenSetSlotHandle(vm, 0, this->m_Instance); - wrenSetSlotDouble(vm, 1, timestep); - WrenInterpretResult result = wrenCall(vm, this->m_OnUpdateHandle); -} - -void WrenScript::CallFixedUpdate(float timestep) -{ - WrenVM* vm = ScriptingEngine::GetWrenVM(); - wrenEnsureSlots(vm, 2); - wrenSetSlotHandle(vm, 0, this->m_Instance); - wrenSetSlotDouble(vm, 1, timestep); - WrenInterpretResult result = wrenCall(vm, this->m_OnFixedUpdateHandle); -} - -void WrenScript::CallExit() -{ - if (!CompiledSuccesfully) - return; - - WrenVM* vm = ScriptingEngine::GetWrenVM(); - wrenEnsureSlots(vm, 1); - wrenSetSlotHandle(vm, 0, this->m_Instance); - WrenInterpretResult result = wrenCall(vm, this->m_OnExitHandle); -} - -void WrenScript::RegisterMethod(const std::string& signature) -{ - WrenVM* vm = ScriptingEngine::GetWrenVM(); - WrenHandle* handle = wrenMakeCallHandle(vm, signature.c_str()); - methods.emplace(signature, handle); -} - -void WrenScript::CallMethod(const std::string& signature) -{ - WrenVM* vm = ScriptingEngine::GetWrenVM(); - - - // Not found. maybe try to register it? - if (methods.find(signature) == methods.end()) - return; - - wrenSetSlotHandle(vm, 0, this->m_Instance); - WrenHandle* handle = methods[signature]; - WrenInterpretResult result = wrenCall(vm, handle); -} - -void WrenScript::SetScriptableEntityID(int id) -{ - WrenVM* vm = ScriptingEngine::GetWrenVM(); - wrenSetSlotHandle(vm, 0, this->m_Instance); - wrenSetSlotDouble(vm, 1, id); - WrenInterpretResult result = wrenCall(vm, this->m_SetEntityIDHandle); + wrenSetSlotHandle(vm, 0, this->m_Instance); + WrenHandle* handle = methods[signature]; + WrenInterpretResult result = wrenCall(vm, handle); + } + + void WrenScript::SetScriptableEntityID(int id) + { + WrenVM* vm = ScriptingEngine::GetWrenVM(); + wrenSetSlotHandle(vm, 0, this->m_Instance); + wrenSetSlotDouble(vm, 1, id); + WrenInterpretResult result = wrenCall(vm, this->m_SetEntityIDHandle); + } } diff --git a/Nuake/src/Scripting/WrenScript.h b/Nuake/src/Scripting/WrenScript.h index 1b24769d..e714b5c2 100644 --- a/Nuake/src/Scripting/WrenScript.h +++ b/Nuake/src/Scripting/WrenScript.h @@ -4,28 +4,31 @@ #include class WrenHandle; -class WrenScript -{ -public: - std::map methods; - WrenHandle* m_Instance; - WrenHandle* m_OnInitHandle; - WrenHandle* m_OnUpdateHandle; - WrenHandle* m_OnFixedUpdateHandle; - WrenHandle* m_OnExitHandle; - WrenHandle* m_SetEntityIDHandle; - bool CompiledSuccesfully; +namespace Nuake { + class WrenScript + { + public: + std::map methods; + WrenHandle* m_Instance; + WrenHandle* m_OnInitHandle; + WrenHandle* m_OnUpdateHandle; + WrenHandle* m_OnFixedUpdateHandle; + WrenHandle* m_OnExitHandle; + WrenHandle* m_SetEntityIDHandle; - WrenScript(const std::string& path, const std::string& mod, bool isEntity = false); + bool CompiledSuccesfully; - void CallInit(); - void CallUpdate(float timestep); - void CallFixedUpdate(float timestep); - void CallExit(); + WrenScript(const std::string& path, const std::string& mod, bool isEntity = false); - void RegisterMethod(const std::string& signature); - void CallMethod(const std::string& signature); + void CallInit(); + void CallUpdate(float timestep); + void CallFixedUpdate(float timestep); + void CallExit(); - void SetScriptableEntityID(int id); -}; \ No newline at end of file + void RegisterMethod(const std::string& signature); + void CallMethod(const std::string& signature); + + void SetScriptableEntityID(int id); + }; +} diff --git a/Nuake/src/UI/Font/Font.h b/Nuake/src/UI/Font/Font.h index f4b1f878..e0f59529 100644 --- a/Nuake/src/UI/Font/Font.h +++ b/Nuake/src/UI/Font/Font.h @@ -1,106 +1,117 @@ #pragma once -#include "../Core/Core.h" +#include "src/Core/Core.h" #include #include #include #include "src/Core/Maths.h" -struct CharPos + +namespace Nuake { - double left; - double right; - double top; - double bottom; -}; - -struct CharUV -{ - Vector2 Pos; - Vector2 Size; -}; - -class Char -{ -private: - unsigned int m_VBO; - unsigned int m_VAO; - -public: - unsigned int Unicode; - float Advance; - CharPos PlaneBounds; - CharUV AtlasBounds; - - Char() {}; - Char(const unsigned int unicode, float advance, CharPos plane, CharUV atlas) + struct CharPos { - Unicode = unicode; - Advance = advance; - PlaneBounds = plane; - AtlasBounds = atlas; - } + double left; + double right; + double top; + double bottom; + }; - CharUV GetAtlasUV(const Vector2& atlasSize) + struct CharUV { - return AtlasBounds; - } -}; + Vector2 Pos; + Vector2 Size; + }; -class Font -{ -private: - msdfgen::FreetypeHandle* ft; - msdfgen::FontHandle* font; - const char* fontFilename; - - std::map Chars; - -public: - Ref FontAtlas; - - Font() : ft(msdfgen::initializeFreetype()), font(nullptr), fontFilename(nullptr) + class Char { - this->Chars = std::map(); - } + private: + unsigned int m_VBO; + unsigned int m_VAO; - ~Font() { - if (ft) { - if (font) - msdfgen::destroyFont(font); - msdfgen::deinitializeFreetype(ft); + public: + unsigned int Unicode; + float Advance; + CharPos PlaneBounds; + CharUV AtlasBounds; + + Char() {}; + Char(const unsigned int unicode, float advance, CharPos plane, CharUV atlas) + { + Unicode = unicode; + Advance = advance; + PlaneBounds = plane; + AtlasBounds = atlas; } - } - bool load(const char* fontFilename) { - if (ft && fontFilename) { - if (this->fontFilename && !strcmp(this->fontFilename, fontFilename)) - return true; - if (font) - msdfgen::destroyFont(font); - if ((font = msdfgen::loadFont(ft, fontFilename))) { - this->fontFilename = fontFilename; - return true; + CharUV GetAtlasUV(const Vector2& atlasSize) + { + return AtlasBounds; + } + }; + + class Font + { + private: + msdfgen::FreetypeHandle* ft; + msdfgen::FontHandle* font; + const char* fontFilename; + + std::map Chars; + + public: + Ref FontAtlas; + + Font() : ft(msdfgen::initializeFreetype()), font(nullptr), fontFilename(nullptr) + { + this->Chars = std::map(); + } + + ~Font() + { + if (ft) + { + if (font) + msdfgen::destroyFont(font); + msdfgen::deinitializeFreetype(ft); } - this->fontFilename = nullptr; } - return false; - } - operator msdfgen::FontHandle* () const { - return font; - } + bool load(const char* fontFilename) + { + if (ft && fontFilename) + { + if (this->fontFilename && !strcmp(this->fontFilename, fontFilename)) + return true; + if (font) + msdfgen::destroyFont(font); + if ((font = msdfgen::loadFont(ft, fontFilename))) + { + this->fontFilename = fontFilename; + return true; + } - msdfgen::FontHandle* GetFontHandle() { return font; } - msdfgen::FreetypeHandle* GetFreetypeHandle() { return ft; } + this->fontFilename = nullptr; + } + return false; + } - void AddChar(const unsigned int unicode, float advance, CharPos plane, CharUV atlas) - { - this->Chars[unicode] = Char(unicode, advance, plane, atlas); - } + operator msdfgen::FontHandle* () const + { + return font; + } - Char GetChar(unsigned int unicode) - { - if (Chars.find(unicode) != Chars.end()) - return Chars[unicode]; - return Char(); - } -}; \ No newline at end of file + msdfgen::FontHandle* GetFontHandle() { return font; } + msdfgen::FreetypeHandle* GetFreetypeHandle() { return ft; } + + void AddChar(const unsigned int unicode, float advance, CharPos plane, CharUV atlas) + { + this->Chars[unicode] = Char(unicode, advance, plane, atlas); + } + + Char GetChar(unsigned int unicode) + { + if (Chars.find(unicode) != Chars.end()) + return Chars[unicode]; + return Char(); + } + }; +} diff --git a/Nuake/src/UI/Font/FontLoader.h b/Nuake/src/UI/Font/FontLoader.h index 2afbe0fe..cfb4033f 100644 --- a/Nuake/src/UI/Font/FontLoader.h +++ b/Nuake/src/UI/Font/FontLoader.h @@ -20,155 +20,159 @@ #include "../Rendering/Textures/Texture.h" #include "msdf-atlas-gen/json-export.h" typedef unsigned char byte; -struct Config + +namespace Nuake { - msdf_atlas::ImageType imageType; - msdf_atlas::ImageFormat imageFormat; - msdf_atlas::YDirection yDirection; - int width, height; - double emSize; - double pxRange; - double angleThreshold; - double miterLimit; - void (*edgeColoring)(msdfgen::Shape&, double, unsigned long long); - bool expensiveColoring; - unsigned long long coloringSeed; - msdf_atlas::GeneratorAttributes generatorAttributes; - bool preprocessGeometry; - bool kerning; - int threadCount = 1; -}; - -class FontLoader -{ -public: - - template GEN_FN> - static bool makeAtlas(const std::vector& glyphs, - const std::vector& fonts, - Config& config, Ref font) { - // Create generator - msdf_atlas::ImmediateAtlasGenerator > generator(config.width, config.height); - - // Setup generator settings - generator.setAttributes(config.generatorAttributes); - generator.setThreadCount(config.threadCount); - generator.generate(glyphs.data(), glyphs.size()); - - // Create bitmap - msdfgen::BitmapConstRef bitmap = (msdfgen::BitmapConstRef) generator.atlasStorage(); - - // Create Texture from bitmap - //msdf_atlas::exportJSON(fonts.data(), fonts.size(), config.emSize, config.pxRange, config.width, config.height, config.imageType, config.yDirection, "yayayayya.json", config.kerning); - font->FontAtlas = CreateRef(Vector2(config.width, config.height), bitmap, true); - - // Create Char structure - return true; - } - static Ref LoadFont(const std::string path) + struct Config { - // create font - Ref font = CreateRef(); + msdf_atlas::ImageType imageType; + msdf_atlas::ImageFormat imageFormat; + msdf_atlas::YDirection yDirection; + int width, height; + double emSize; + double pxRange; + double angleThreshold; + double miterLimit; + void (*edgeColoring)(msdfgen::Shape&, double, unsigned long long); + bool expensiveColoring; + unsigned long long coloringSeed; + msdf_atlas::GeneratorAttributes generatorAttributes; + bool preprocessGeometry; + bool kerning; + int threadCount = 1; + }; - // Create atlas settings - Config config{}; - config.pxRange = 2; - config.emSize = 0.0; - config.coloringSeed = 125155; - config.imageType = msdf_atlas::ImageType::MTSDF; - config.imageFormat = msdf_atlas::ImageFormat::UNSPECIFIED; - config.yDirection = msdf_atlas::YDirection::BOTTOM_UP; - config.edgeColoring = msdfgen::edgeColoringInkTrap; - config.kerning = true; - config.preprocessGeometry = false; - config.angleThreshold = 3.0; - config.miterLimit = 1.0; - config.generatorAttributes.scanlinePass = true; - config.generatorAttributes.config.overlapSupport = true; + class FontLoader + { + public: - // Load file - if (!font->load(path.c_str())) - Logger::Log("Failed to load font", CRITICAL); - - // Load charset ASCII - std::vector glyphs; - std::vector fonts; - msdf_atlas::FontGeometry fontGeometry(&glyphs); - msdf_atlas::Charset charset = msdf_atlas::Charset::ASCII; + template GEN_FN> + static bool makeAtlas(const std::vector& glyphs, + const std::vector& fonts, + Config& config, Ref font) { + // Create generator + msdf_atlas::ImmediateAtlasGenerator > generator(config.width, config.height); - // Load Create charset - float fontScale = 32; - bool preprocess = false; - int loaded = fontGeometry.loadCharset(font->GetFontHandle(), fontScale, charset, config.preprocessGeometry, config.kerning); - - - fonts.push_back(fontGeometry); + // Setup generator settings + generator.setAttributes(config.generatorAttributes); + generator.setThreadCount(config.threadCount); + generator.generate(glyphs.data(), glyphs.size()); - if (glyphs.empty()) - Logger::Log("No glyphs loaded.", CRITICAL); + // Create bitmap + msdfgen::BitmapConstRef bitmap = (msdfgen::BitmapConstRef) generator.atlasStorage(); - // Create atlas params - msdf_atlas::TightAtlasPacker::DimensionsConstraint atlasSizeConstraint = msdf_atlas::TightAtlasPacker::DimensionsConstraint::MULTIPLE_OF_FOUR_SQUARE; - msdf_atlas::TightAtlasPacker atlasPacker; - atlasPacker.setDimensionsConstraint(atlasSizeConstraint); - msdf_atlas::ImageType imageType = msdf_atlas::ImageType::MTSDF; - atlasPacker.setPadding(imageType == msdf_atlas::ImageType::MSDF || imageType == msdf_atlas::ImageType::MTSDF ? 0 : -1); - atlasPacker.setPixelRange(config.pxRange); - atlasPacker.setUnitRange(config.emSize); - atlasPacker.setMiterLimit(config.miterLimit); + // Create Texture from bitmap + //msdf_atlas::exportJSON(fonts.data(), fonts.size(), config.emSize, config.pxRange, config.width, config.height, config.imageType, config.yDirection, "yayayayya.json", config.kerning); + font->FontAtlas = CreateRef(Vector2(config.width, config.height), bitmap, true); - // Pack atlas - if (int remaining = atlasPacker.pack(glyphs.data(), glyphs.size())) { - if (remaining < 0) { - Logger::Log("Failed to pack atlas.", CRITICAL); - } - else { - printf("Error: Could not fit %d out of %d glyphs into the atlas.\n", remaining, (int)glyphs.size()); - - } - } - - // update atlast size - atlasPacker.getDimensions(config.width, config.height); - if (!(config.width > 0 && config.height > 0)) - printf("Unable to determine atlas size."); - - config.emSize = atlasPacker.getScale(); - config.pxRange = atlasPacker.getPixelRange(); - - // Color the glyph - //unsigned long long glyphSeed = config.coloringSeed; - //for (msdf_atlas::GlyphGeometry& glyph : glyphs) { - // glyphSeed *= 6364136223846793005ull; - // glyph.edgeColoring(config.edgeColoring, config.angleThreshold, glyphSeed); - //} - - msdf_atlas::Workload([&glyphs, &config](int i, int threadNo) -> bool { - unsigned long long glyphSeed = (6364136223846793005ull * (config.coloringSeed ^ i) + 1442695040888963407ull) * !!config.coloringSeed; - glyphs[i].edgeColoring(config.edgeColoring, config.angleThreshold, glyphSeed); + // Create Char structure return true; - }, glyphs.size()).finish(config.threadCount); - - // Create bitmap and char structure - auto bitmap = makeAtlas(glyphs, fonts, config, font); - - for (auto& g : glyphs) - { - CharPos plane = {}; - g.getQuadPlaneBounds(plane.left, plane.bottom, plane.right, plane.top); - - CharUV box = {}; - - - double x2, y2, z2, w2; - g.getQuadAtlasBounds(x2, y2, z2, w2); - box.Pos.x = x2; - box.Pos.y = y2; - box.Size.x = z2; - box.Size.y = w2; - font->AddChar(g.getCodepoint(), g.getAdvance(), plane, box); } + static Ref LoadFont(const std::string path) + { + // create font + Ref font = CreateRef(); - return font; - } -}; \ No newline at end of file + // Create atlas settings + Config config{}; + config.pxRange = 2; + config.emSize = 0.0; + config.coloringSeed = 125155; + config.imageType = msdf_atlas::ImageType::MTSDF; + config.imageFormat = msdf_atlas::ImageFormat::UNSPECIFIED; + config.yDirection = msdf_atlas::YDirection::BOTTOM_UP; + config.edgeColoring = msdfgen::edgeColoringInkTrap; + config.kerning = true; + config.preprocessGeometry = false; + config.angleThreshold = 3.0; + config.miterLimit = 1.0; + config.generatorAttributes.scanlinePass = true; + config.generatorAttributes.config.overlapSupport = true; + + // Load file + if (!font->load(path.c_str())) + Logger::Log("Failed to load font", CRITICAL); + + // Load charset ASCII + std::vector glyphs; + std::vector fonts; + msdf_atlas::FontGeometry fontGeometry(&glyphs); + msdf_atlas::Charset charset = msdf_atlas::Charset::ASCII; + + // Load Create charset + float fontScale = 32; + bool preprocess = false; + int loaded = fontGeometry.loadCharset(font->GetFontHandle(), fontScale, charset, config.preprocessGeometry, config.kerning); + + + fonts.push_back(fontGeometry); + + if (glyphs.empty()) + Logger::Log("No glyphs loaded.", CRITICAL); + + // Create atlas params + msdf_atlas::TightAtlasPacker::DimensionsConstraint atlasSizeConstraint = msdf_atlas::TightAtlasPacker::DimensionsConstraint::MULTIPLE_OF_FOUR_SQUARE; + msdf_atlas::TightAtlasPacker atlasPacker; + atlasPacker.setDimensionsConstraint(atlasSizeConstraint); + msdf_atlas::ImageType imageType = msdf_atlas::ImageType::MTSDF; + atlasPacker.setPadding(imageType == msdf_atlas::ImageType::MSDF || imageType == msdf_atlas::ImageType::MTSDF ? 0 : -1); + atlasPacker.setPixelRange(config.pxRange); + atlasPacker.setUnitRange(config.emSize); + atlasPacker.setMiterLimit(config.miterLimit); + + // Pack atlas + if (int remaining = atlasPacker.pack(glyphs.data(), glyphs.size())) { + if (remaining < 0) { + Logger::Log("Failed to pack atlas.", CRITICAL); + } + else { + printf("Error: Could not fit %d out of %d glyphs into the atlas.\n", remaining, (int)glyphs.size()); + + } + } + + // update atlast size + atlasPacker.getDimensions(config.width, config.height); + if (!(config.width > 0 && config.height > 0)) + printf("Unable to determine atlas size."); + + config.emSize = atlasPacker.getScale(); + config.pxRange = atlasPacker.getPixelRange(); + + // Color the glyph + //unsigned long long glyphSeed = config.coloringSeed; + //for (msdf_atlas::GlyphGeometry& glyph : glyphs) { + // glyphSeed *= 6364136223846793005ull; + // glyph.edgeColoring(config.edgeColoring, config.angleThreshold, glyphSeed); + //} + + msdf_atlas::Workload([&glyphs, &config](int i, int threadNo) -> bool { + unsigned long long glyphSeed = (6364136223846793005ull * (config.coloringSeed ^ i) + 1442695040888963407ull) * !!config.coloringSeed; + glyphs[i].edgeColoring(config.edgeColoring, config.angleThreshold, glyphSeed); + return true; + }, glyphs.size()).finish(config.threadCount); + + // Create bitmap and char structure + auto bitmap = makeAtlas(glyphs, fonts, config, font); + + for (auto& g : glyphs) + { + CharPos plane = {}; + g.getQuadPlaneBounds(plane.left, plane.bottom, plane.right, plane.top); + + CharUV box = {}; + + + double x2, y2, z2, w2; + g.getQuadAtlasBounds(x2, y2, z2, w2); + box.Pos.x = x2; + box.Pos.y = y2; + box.Size.x = z2; + box.Size.y = w2; + font->AddChar(g.getCodepoint(), g.getAdvance(), plane, box); + } + + return font; + } + }; +} diff --git a/Nuake/src/UI/Font/FontManager.cpp b/Nuake/src/UI/Font/FontManager.cpp index 69eff7e4..3d4b94f4 100644 --- a/Nuake/src/UI/Font/FontManager.cpp +++ b/Nuake/src/UI/Font/FontManager.cpp @@ -1,20 +1,22 @@ #include "FontManager.h" -std::map > FontManager::m_Fonts = std::map>(); +namespace Nuake { + std::map > FontManager::m_Fonts = std::map>(); -Ref FontManager::GetFont(const std::string& font) -{ - // Fonts exists in memory - if (m_Fonts.find(font) != m_Fonts.end()) + Ref FontManager::GetFont(const std::string& font) { - return m_Fonts[font]; - } - - // Load font - Ref newFont = FontLoader::LoadFont(font); - if (newFont) - return newFont; + // Fonts exists in memory + if (m_Fonts.find(font) != m_Fonts.end()) + { + return m_Fonts[font]; + } - Logger::Log("Error: failed to load font " + font, CRITICAL); - return nullptr; -} \ No newline at end of file + // Load font + Ref newFont = FontLoader::LoadFont(font); + if (newFont) + return newFont; + + Logger::Log("Error: failed to load font " + font, CRITICAL); + return nullptr; + } +} diff --git a/Nuake/src/UI/Font/FontManager.h b/Nuake/src/UI/Font/FontManager.h index 4afb6ac5..580fe81e 100644 --- a/Nuake/src/UI/Font/FontManager.h +++ b/Nuake/src/UI/Font/FontManager.h @@ -2,11 +2,14 @@ #include #include "FontLoader.h" -class FontManager -{ -private: - static std::map > m_Fonts; -public: - static Ref GetFont(const std::string& font); -}; \ No newline at end of file +namespace Nuake { + class FontManager + { + private: + static std::map > m_Fonts; + + public: + static Ref GetFont(const std::string& font); + }; +} diff --git a/Nuake/src/UI/InterfaceParser.cpp b/Nuake/src/UI/InterfaceParser.cpp index c4b2750d..a0b99e56 100644 --- a/Nuake/src/UI/InterfaceParser.cpp +++ b/Nuake/src/UI/InterfaceParser.cpp @@ -1,282 +1,286 @@ #include "InterfaceParser.h" #include "Styling/Stylesheet.h" -Ref InterfaceParser::Root = CreateRef(); -void InterfaceParser::Iterate(const pugi::xml_node& xml_node, Ref node, int depth) +namespace Nuake { - int currentDepth = depth + 1; - for (auto& e : xml_node.children()) + Ref InterfaceParser::Root = CreateRef(); + + void InterfaceParser::Iterate(const pugi::xml_node& xml_node, Ref node, int depth) { - std::string type = e.name(); - Ref newNode; - - if (type == "Canvas") - newNode = CreateCanvas(e); - else if (type == "Rect") - newNode = CreateNode(e); - else if (type == "p") - newNode = CreateTextNode(e); - else - continue; - newNode->Depth = currentDepth; - node->Childrens.push_back(newNode); - Iterate(e, newNode, currentDepth); - } -} - -Ref InterfaceParser::Parse(const std::string path) -{ - pugi::xml_document doc; - pugi::xml_parse_result result = doc.load_file(path.c_str()); - std::string name = doc.first_child().name(); - if (name != "Canvas") - { - Logger::Log("InterfaceParser error: First child should be a canvas - " + path, CRITICAL); - return nullptr; - } - - Root = CreateCanvas(doc.first_child()); - Root->Depth = 0; - Iterate(doc.first_child(), Root, 0); - return Root; -} - -Ref InterfaceParser::CreateTextNode(const pugi::xml_node& xml_node) -{ - Ref node = CreateRef(); - node->content = xml_node.text().as_string(); - node->Type = NodeType::Text; - TextStyle style{ - FontManager::GetFont("resources/Fonts/RobotoMono-Regular.ttf"), - 2.0, - Color(255, 255, 255, 255) - }; - - node->SetTextStyle(style); - for (auto& a : xml_node.attributes()) - { - std::string name = a.name(); - if (name == "groups") + int currentDepth = depth + 1; + for (auto& e : xml_node.children()) { - for (auto& g : split(a.value(), ' ')) - { - node->AddGroup(g); - } - } - if (name == "height") - node->Height = GetUnit(a.value()); - if (name == "width") - node->Width = GetUnit(a.value()); - if (name == "margin") - node->Margin = GetVec4Unit(a.value()); - if (name == "padding") - node->Padding = GetVec4Unit(a.value()); - if (name == "border") - node->Border = GetVec4Unit(a.value()); - if (name == "position") - node->Position = GetVec4Unit(a.value()); - if (name == "color") - node->BackgroundColor = GetColor(a.value()); - } - return node; -} + std::string type = e.name(); + Ref newNode; -Ref InterfaceParser::CreateNode(const pugi::xml_node& xml_node) -{ - Ref node = CreateRef(); - - node->Root = Root; - for (auto& a : xml_node.attributes()) - { - std::string name = a.name(); - if (name == "groups") - { - for (auto& g : split(a.value(), ' ')) - { - node->AddGroup(g); - } - } - if (name == "height") - node->Height = GetUnit(a.value()); - if (name == "width") - node->Width = GetUnit(a.value()); - if (name == "margin") - node->Margin = GetVec4Unit(a.value()); - if (name == "padding") - node->Padding = GetVec4Unit(a.value()); - if (name == "border") - node->Border = GetVec4Unit(a.value()); - if (name == "position") - node->Position = GetVec4Unit(a.value()); - if (name == "color") - node->BackgroundColor = GetColor(a.value()); - if (name == "onclick") - { - std::string signature = a.value(); - Root->Script->RegisterMethod(a.value()); - node->OnClickSignature = a.value(); - } - } - - return node; -} - -Layout::LayoutUnit InterfaceParser::GetUnit(const std::string& value) -{ - std::regex only_number("[0-9]+"); - std::regex not_number("[^0-9]+"); - - // is percentage - std::smatch match_value; - if (std::regex_search(value.begin(), value.end(), match_value, only_number)) - { - std::smatch match_type; - if (std::regex_search(value.begin(), value.end(), match_type, not_number)) - { - float value = std::stof(match_value[0]); - - if (match_type[0] == "%") - { - return Layout::LayoutUnit{ - value, - Layout::Unit::PERCENT - }; - } - else if (match_type[0] == "px") - { - return Layout::LayoutUnit{ - value, - Layout::Unit::PIXEL - }; - } - } - } -} - -std::vector InterfaceParser::split(std::string const& str, const char delim) -{ - std::vector result; - size_t start; - size_t end = 0; - - while ((start = str.find_first_not_of(delim, end)) != std::string::npos) - { - end = str.find(delim, start); - result.push_back(str.substr(start, end - start)); - } - - return result; -} - -Layout::LayoutVec4 InterfaceParser::GetVec4Unit(const std::string& value) -{ - std::regex regex("[0-9]+[^ ]+"); - std::smatch match_value; - Layout::LayoutVec4 result; - - std::vector splits = split(value, ' '); - int idx = 0; - for (auto& s : splits) - { - if (std::regex_search(value.begin(), value.end(), match_value, regex)) - { - if (idx == 0) - { - result.Left = GetUnit(s); - } - else if (idx == 1) - { - result.Right = GetUnit(s); - } - else if (idx == 2) - { - result.Top = GetUnit(s); - } + if (type == "Canvas") + newNode = CreateCanvas(e); + else if (type == "Rect") + newNode = CreateNode(e); + else if (type == "p") + newNode = CreateTextNode(e); else - { - result.Bottom = GetUnit(s); - } - idx++; + continue; + newNode->Depth = currentDepth; + node->Childrens.push_back(newNode); + Iterate(e, newNode, currentDepth); } } - return result; -} -Color InterfaceParser::GetColor(const std::string& value) -{ - std::regex regex("[0-9]+[^ ]+"); - std::smatch match_value; - Color result; - - std::vector splits = split(value, ' '); - int idx = 0; - for (auto& s : splits) + Ref InterfaceParser::Parse(const std::string path) { - if (std::regex_search(value.begin(), value.end(), match_value, regex)) + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_file(path.c_str()); + std::string name = doc.first_child().name(); + if (name != "Canvas") { - if (idx == 0) - { - result.r = std::stof(s); - } - else if (idx == 1) - { - result.g = std::stof(s); - } - else if (idx == 2) - { - result.b = std::stof(s); - } - else - { - result.a = std::stof(s); - } - idx++; + Logger::Log("InterfaceParser error: First child should be a canvas - " + path, CRITICAL); + return nullptr; } - } - return result; -} -Ref InterfaceParser::CreateCanvas(const pugi::xml_node& xml_node) -{ - Ref node = CreateRef(); - node->Root = Root; - for (auto& a : xml_node.attributes()) + Root = CreateCanvas(doc.first_child()); + Root->Depth = 0; + Iterate(doc.first_child(), Root, 0); + return Root; + } + + Ref InterfaceParser::CreateTextNode(const pugi::xml_node& xml_node) { - std::string name = a.name(); - if (name == "groups") + Ref node = CreateRef(); + node->content = xml_node.text().as_string(); + node->Type = NodeType::Text; + TextStyle style{ + FontManager::GetFont("resources/Fonts/RobotoMono-Regular.ttf"), + 2.0, + Color(255, 255, 255, 255) + }; + + node->SetTextStyle(style); + for (auto& a : xml_node.attributes()) { - for (auto& g : split(a.value(), ' ')) + std::string name = a.name(); + if (name == "groups") { - node->AddGroup(g); + for (auto& g : split(a.value(), ' ')) + { + node->AddGroup(g); + } + } + if (name == "height") + node->Height = GetUnit(a.value()); + if (name == "width") + node->Width = GetUnit(a.value()); + if (name == "margin") + node->Margin = GetVec4Unit(a.value()); + if (name == "padding") + node->Padding = GetVec4Unit(a.value()); + if (name == "border") + node->Border = GetVec4Unit(a.value()); + if (name == "position") + node->Position = GetVec4Unit(a.value()); + if (name == "color") + node->BackgroundColor = GetColor(a.value()); + } + return node; + } + + Ref InterfaceParser::CreateNode(const pugi::xml_node& xml_node) + { + Ref node = CreateRef(); + + node->Root = Root; + for (auto& a : xml_node.attributes()) + { + std::string name = a.name(); + if (name == "groups") + { + for (auto& g : split(a.value(), ' ')) + { + node->AddGroup(g); + } + } + if (name == "height") + node->Height = GetUnit(a.value()); + if (name == "width") + node->Width = GetUnit(a.value()); + if (name == "margin") + node->Margin = GetVec4Unit(a.value()); + if (name == "padding") + node->Padding = GetVec4Unit(a.value()); + if (name == "border") + node->Border = GetVec4Unit(a.value()); + if (name == "position") + node->Position = GetVec4Unit(a.value()); + if (name == "color") + node->BackgroundColor = GetColor(a.value()); + if (name == "onclick") + { + std::string signature = a.value(); + Root->Script->RegisterMethod(a.value()); + node->OnClickSignature = a.value(); } } - if (name == "height") - node->Height = GetUnit(a.value()); - if (name == "width") - node->Width = GetUnit(a.value()); - if (name == "margin") - node->Margin = GetVec4Unit(a.value()); - if (name == "padding") - node->Padding = GetVec4Unit(a.value()); - if (name == "border") - node->Border = GetVec4Unit(a.value()); - if (name == "position") - node->Position = GetVec4Unit(a.value()); - if (name == "color") - node->BackgroundColor = GetColor(a.value()); - if (name == "script") + + return node; + } + + Layout::LayoutUnit InterfaceParser::GetUnit(const std::string& value) + { + std::regex only_number("[0-9]+"); + std::regex not_number("[^0-9]+"); + + // is percentage + std::smatch match_value; + if (std::regex_search(value.begin(), value.end(), match_value, only_number)) { - auto s = split(a.value(), ' '); - std::string path = s[0]; - std::string module = s[1]; - node->Script = ScriptingEngine::RegisterScript(path, module); - } - if (name == "stylesheet") - { - std::string path = a.value(); - node->StyleSheet = UI::StyleSheet::New(path); + std::smatch match_type; + if (std::regex_search(value.begin(), value.end(), match_type, not_number)) + { + float value = std::stof(match_value[0]); + + if (match_type[0] == "%") + { + return Layout::LayoutUnit{ + value, + Layout::Unit::PERCENT + }; + } + else if (match_type[0] == "px") + { + return Layout::LayoutUnit{ + value, + Layout::Unit::PIXEL + }; + } + } } } - return node; -} \ No newline at end of file + std::vector InterfaceParser::split(std::string const& str, const char delim) + { + std::vector result; + size_t start; + size_t end = 0; + + while ((start = str.find_first_not_of(delim, end)) != std::string::npos) + { + end = str.find(delim, start); + result.push_back(str.substr(start, end - start)); + } + + return result; + } + + Layout::LayoutVec4 InterfaceParser::GetVec4Unit(const std::string& value) + { + std::regex regex("[0-9]+[^ ]+"); + std::smatch match_value; + Layout::LayoutVec4 result; + + std::vector splits = split(value, ' '); + int idx = 0; + for (auto& s : splits) + { + if (std::regex_search(value.begin(), value.end(), match_value, regex)) + { + if (idx == 0) + { + result.Left = GetUnit(s); + } + else if (idx == 1) + { + result.Right = GetUnit(s); + } + else if (idx == 2) + { + result.Top = GetUnit(s); + } + else + { + result.Bottom = GetUnit(s); + } + idx++; + } + } + return result; + } + + Color InterfaceParser::GetColor(const std::string& value) + { + std::regex regex("[0-9]+[^ ]+"); + std::smatch match_value; + Color result; + + std::vector splits = split(value, ' '); + int idx = 0; + for (auto& s : splits) + { + if (std::regex_search(value.begin(), value.end(), match_value, regex)) + { + if (idx == 0) + { + result.r = std::stof(s); + } + else if (idx == 1) + { + result.g = std::stof(s); + } + else if (idx == 2) + { + result.b = std::stof(s); + } + else + { + result.a = std::stof(s); + } + idx++; + } + } + return result; + } + + Ref InterfaceParser::CreateCanvas(const pugi::xml_node& xml_node) + { + Ref node = CreateRef(); + node->Root = Root; + for (auto& a : xml_node.attributes()) + { + std::string name = a.name(); + if (name == "groups") + { + for (auto& g : split(a.value(), ' ')) + { + node->AddGroup(g); + } + } + if (name == "height") + node->Height = GetUnit(a.value()); + if (name == "width") + node->Width = GetUnit(a.value()); + if (name == "margin") + node->Margin = GetVec4Unit(a.value()); + if (name == "padding") + node->Padding = GetVec4Unit(a.value()); + if (name == "border") + node->Border = GetVec4Unit(a.value()); + if (name == "position") + node->Position = GetVec4Unit(a.value()); + if (name == "color") + node->BackgroundColor = GetColor(a.value()); + if (name == "script") + { + auto s = split(a.value(), ' '); + std::string path = s[0]; + std::string module = s[1]; + node->Script = ScriptingEngine::RegisterScript(path, module); + } + if (name == "stylesheet") + { + std::string path = a.value(); + node->StyleSheet = UI::StyleSheet::New(path); + } + } + + return node; + } +} diff --git a/Nuake/src/UI/InterfaceParser.h b/Nuake/src/UI/InterfaceParser.h index d63c5328..9efe1530 100644 --- a/Nuake/src/UI/InterfaceParser.h +++ b/Nuake/src/UI/InterfaceParser.h @@ -9,22 +9,26 @@ #include "Nodes/TextNode.h" #include "Font/FontManager.h" #include "../Scripting/ScriptingEngine.h" -class InterfaceParser + +namespace Nuake { -private: - static Ref Root; -public: - static Ref Parse(const std::string path); + class InterfaceParser + { + private: + static Ref Root; + public: + static Ref Parse(const std::string path); - static void Iterate(const pugi::xml_node& xml_node, Ref node, int depth); + static void Iterate(const pugi::xml_node& xml_node, Ref node, int depth); - static Ref CreateNode(const pugi::xml_node& xml_node); - static Ref CreateCanvas(const pugi::xml_node& xml_node); - static Ref CreateTextNode(const pugi::xml_node& xml_node); + static Ref CreateNode(const pugi::xml_node& xml_node); + static Ref CreateCanvas(const pugi::xml_node& xml_node); + static Ref CreateTextNode(const pugi::xml_node& xml_node); - static std::vector split(std::string const& str, const char delim); + static std::vector split(std::string const& str, const char delim); - static Layout::LayoutUnit GetUnit(const std::string& value); - static Layout::LayoutVec4 GetVec4Unit(const std::string& value); - static Color GetColor(const std::string& value); -}; \ No newline at end of file + static Layout::LayoutUnit GetUnit(const std::string& value); + static Layout::LayoutVec4 GetVec4Unit(const std::string& value); + static Color GetColor(const std::string& value); + }; +} diff --git a/Nuake/src/UI/Nodes/Canvas.cpp b/Nuake/src/UI/Nodes/Canvas.cpp index 189bf5dc..a2b9425e 100644 --- a/Nuake/src/UI/Nodes/Canvas.cpp +++ b/Nuake/src/UI/Nodes/Canvas.cpp @@ -1,5 +1,9 @@ #include "Canvas.h" -Canvas::Canvas() -{ +namespace Nuake { + Canvas::Canvas() + { + + } } + diff --git a/Nuake/src/UI/Nodes/Canvas.h b/Nuake/src/UI/Nodes/Canvas.h index 9e57c690..826d0a42 100644 --- a/Nuake/src/UI/Nodes/Canvas.h +++ b/Nuake/src/UI/Nodes/Canvas.h @@ -5,15 +5,15 @@ #include #include "../Styling/Stylesheet.h" -// Base container for UI. -class Canvas : public Node -{ -private: - // Script here +namespace Nuake { + class Canvas : public Node + { + private: -public: - Ref Script; - Ref StyleSheet; + public: + Ref Script; + Ref StyleSheet; - Canvas(); -}; \ No newline at end of file + Canvas(); + }; +} diff --git a/Nuake/src/UI/Nodes/Node.cpp b/Nuake/src/UI/Nodes/Node.cpp index daf4bfd0..5cbf0378 100644 --- a/Nuake/src/UI/Nodes/Node.cpp +++ b/Nuake/src/UI/Nodes/Node.cpp @@ -1,141 +1,144 @@ #include "Node.h" -Node::Node() +namespace Nuake { - Childrens = std::vector>(); - Groups = std::vector(); - PositionType = Layout::PositionType::RELATIVE; - Position = Layout::LayoutVec4(); - Height = MaxHeight = MinHeight = Layout::LayoutUnit(); - Margin = Padding = Border = Layout::LayoutVec4(); - Direction = Layout::LayoutDirection::LTR; - FlexDirection = Layout::FlexDirection::ROW; - FlexWrap = Layout::FlexWrap::WRAP; - FlexGrow = 0.f; - FlexShrink = 1.f; - FlexBasis = 10.f; - AspectRatio = 1.f; - AlignItems = Layout::AlignItems::AUTO; - AlignSelf = Layout::AlignItems::AUTO; -} - -void Node::ApplyStyle(Ref stylegroup) -{ - for (auto& s : stylegroup->GetProps()) + Node::Node() { - switch (s.first) - { - case PropType::HEIGHT: - { - Height.Unit = (Layout::Unit)(s.second.type); - float value = s.second.value.Number; - Height.Value = value; - } - break; - case PropType::MIN_HEIGHT: - MinHeight.Unit = (Layout::Unit)s.second.type; - MinHeight.Value = s.second.value.Number; - break; - case PropType::MAX_HEIGHT: - MaxHeight.Unit = (Layout::Unit)s.second.type; - MaxHeight.Value = s.second.value.Number; - break; - case PropType::WIDTH: - Width.Unit = (Layout::Unit)s.second.type; - Width.Value = s.second.value.Number; - break; - case PropType::MIN_WIDTH: - MinWidth.Unit = (Layout::Unit)s.second.type; - MinWidth.Value = s.second.value.Number; - break; - case PropType::MAX_WIDTH: - MaxWidth.Unit = (Layout::Unit)s.second.type; - MaxWidth.Value = s.second.value.Number; - break; - case PropType::MARGIN_RIGHT: - Margin.Right.Unit = (Layout::Unit)s.second.type; - Margin.Right.Value = s.second.value.Number; - break; - case PropType::MARGIN_LEFT: - Margin.Left.Unit = (Layout::Unit)s.second.type; - Margin.Left.Value = s.second.value.Number; - break; - case PropType::MARGIN_TOP: - Margin.Top.Unit = (Layout::Unit)s.second.type; - Margin.Top.Value = s.second.value.Number; - break; - case PropType::MARGIN_BOTTOM: - Margin.Bottom.Unit = (Layout::Unit)s.second.type; - Margin.Bottom.Value = s.second.value.Number; - break; - case PropType::JUSTIFY_CONTENT: - JustifyContent = (Layout::JustifyContent)s.second.value.Enum; - break; - case PropType::FLEX_WRAP: - FlexWrap = (Layout::FlexWrap)s.second.value.Enum; - break; - case PropType::FLEX_DIRECTION: - FlexDirection = (Layout::FlexDirection)s.second.value.Enum; - break; - case PropType::ALIGN_ITEMS: - AlignItems = (Layout::AlignItems)s.second.value.Enum; - break; - case PropType::SELF_ALIGN: - AlignSelf = (Layout::AlignItems)s.second.value.Enum; - break; - case PropType::ALIGN_CONTENT: - AlignContent = (Layout::AlignContent)s.second.value.Enum; - break; - case PropType::POSITION: - PositionType = (Layout::PositionType)s.second.value.Enum; - break; - case PropType::LEFT: - Position.Left.Unit = (Layout::Unit)s.second.type; - Position.Left.Value = s.second.value.Number; - break; - case PropType::RIGHT: - Position.Right.Unit = (Layout::Unit)s.second.type; - Position.Right.Value = s.second.value.Number; - break; - case PropType::TOP: - Position.Top.Unit = (Layout::Unit)s.second.type; - Position.Top.Value = s.second.value.Number; - break; - case PropType::BOTTOM: - Position.Bottom.Unit = (Layout::Unit)s.second.type; - Position.Bottom.Value = s.second.value.Number; - break; - } - } -} - -bool Node::IsPositionInside(Vector2 position) -{ - float width = YGNodeLayoutGetWidth(YogaNode); - float height = YGNodeLayoutGetHeight(YogaNode); - float padding = YGNodeLayoutGetPadding(YogaNode, YGEdgeLeft); - float left = YGNodeLayoutGetLeft(YogaNode); //+ offset.x; - float top = YGNodeLayoutGetTop(YogaNode);// +offset.y; - - float parentLeft = 0.0f; - float parentTop = 0.0f; - auto parent = YGNodeGetParent(YogaNode); - if (parent) - { - parentLeft = YGNodeLayoutGetLeft(YGNodeGetParent(YogaNode)); - parentTop = YGNodeLayoutGetTop(YGNodeGetParent(YogaNode)); - float parentPaddingTop = YGNodeLayoutGetPadding(parent, YGEdgeTop); - float parentPaddingLeft = YGNodeLayoutGetPadding(parent, YGEdgeTop); - // Overflow hidden. - float parentwidth = YGNodeLayoutGetWidth(parent); - if (parentwidth - YGNodeLayoutGetMargin(YogaNode, YGEdgeLeft) < width) - width = parentwidth - parentPaddingLeft; - float parentHeight = YGNodeLayoutGetHeight(parent); - if (parentHeight < height) - height = parentHeight - parentPaddingTop; + Childrens = std::vector>(); + Groups = std::vector(); + PositionType = Layout::PositionType::RELATIVE; + Position = Layout::LayoutVec4(); + Height = MaxHeight = MinHeight = Layout::LayoutUnit(); + Margin = Padding = Border = Layout::LayoutVec4(); + Direction = Layout::LayoutDirection::LTR; + FlexDirection = Layout::FlexDirection::ROW; + FlexWrap = Layout::FlexWrap::WRAP; + FlexGrow = 0.f; + FlexShrink = 1.f; + FlexBasis = 10.f; + AspectRatio = 1.f; + AlignItems = Layout::AlignItems::AUTO; + AlignSelf = Layout::AlignItems::AUTO; } - left += parentLeft; - top += parentTop; - return position.x > left && position.x < left + width && position.y > top && position.y < top + height; -} \ No newline at end of file + void Node::ApplyStyle(Ref stylegroup) + { + for (auto& s : stylegroup->GetProps()) + { + switch (s.first) + { + case PropType::HEIGHT: + { + Height.Unit = (Layout::Unit)(s.second.type); + float value = s.second.value.Number; + Height.Value = value; + } + break; + case PropType::MIN_HEIGHT: + MinHeight.Unit = (Layout::Unit)s.second.type; + MinHeight.Value = s.second.value.Number; + break; + case PropType::MAX_HEIGHT: + MaxHeight.Unit = (Layout::Unit)s.second.type; + MaxHeight.Value = s.second.value.Number; + break; + case PropType::WIDTH: + Width.Unit = (Layout::Unit)s.second.type; + Width.Value = s.second.value.Number; + break; + case PropType::MIN_WIDTH: + MinWidth.Unit = (Layout::Unit)s.second.type; + MinWidth.Value = s.second.value.Number; + break; + case PropType::MAX_WIDTH: + MaxWidth.Unit = (Layout::Unit)s.second.type; + MaxWidth.Value = s.second.value.Number; + break; + case PropType::MARGIN_RIGHT: + Margin.Right.Unit = (Layout::Unit)s.second.type; + Margin.Right.Value = s.second.value.Number; + break; + case PropType::MARGIN_LEFT: + Margin.Left.Unit = (Layout::Unit)s.second.type; + Margin.Left.Value = s.second.value.Number; + break; + case PropType::MARGIN_TOP: + Margin.Top.Unit = (Layout::Unit)s.second.type; + Margin.Top.Value = s.second.value.Number; + break; + case PropType::MARGIN_BOTTOM: + Margin.Bottom.Unit = (Layout::Unit)s.second.type; + Margin.Bottom.Value = s.second.value.Number; + break; + case PropType::JUSTIFY_CONTENT: + JustifyContent = (Layout::JustifyContent)s.second.value.Enum; + break; + case PropType::FLEX_WRAP: + FlexWrap = (Layout::FlexWrap)s.second.value.Enum; + break; + case PropType::FLEX_DIRECTION: + FlexDirection = (Layout::FlexDirection)s.second.value.Enum; + break; + case PropType::ALIGN_ITEMS: + AlignItems = (Layout::AlignItems)s.second.value.Enum; + break; + case PropType::SELF_ALIGN: + AlignSelf = (Layout::AlignItems)s.second.value.Enum; + break; + case PropType::ALIGN_CONTENT: + AlignContent = (Layout::AlignContent)s.second.value.Enum; + break; + case PropType::POSITION: + PositionType = (Layout::PositionType)s.second.value.Enum; + break; + case PropType::LEFT: + Position.Left.Unit = (Layout::Unit)s.second.type; + Position.Left.Value = s.second.value.Number; + break; + case PropType::RIGHT: + Position.Right.Unit = (Layout::Unit)s.second.type; + Position.Right.Value = s.second.value.Number; + break; + case PropType::TOP: + Position.Top.Unit = (Layout::Unit)s.second.type; + Position.Top.Value = s.second.value.Number; + break; + case PropType::BOTTOM: + Position.Bottom.Unit = (Layout::Unit)s.second.type; + Position.Bottom.Value = s.second.value.Number; + break; + } + } + } + + bool Node::IsPositionInside(Vector2 position) + { + float width = YGNodeLayoutGetWidth(YogaNode); + float height = YGNodeLayoutGetHeight(YogaNode); + float padding = YGNodeLayoutGetPadding(YogaNode, YGEdgeLeft); + float left = YGNodeLayoutGetLeft(YogaNode); //+ offset.x; + float top = YGNodeLayoutGetTop(YogaNode);// +offset.y; + + float parentLeft = 0.0f; + float parentTop = 0.0f; + auto parent = YGNodeGetParent(YogaNode); + if (parent) + { + parentLeft = YGNodeLayoutGetLeft(YGNodeGetParent(YogaNode)); + parentTop = YGNodeLayoutGetTop(YGNodeGetParent(YogaNode)); + float parentPaddingTop = YGNodeLayoutGetPadding(parent, YGEdgeTop); + float parentPaddingLeft = YGNodeLayoutGetPadding(parent, YGEdgeTop); + // Overflow hidden. + float parentwidth = YGNodeLayoutGetWidth(parent); + if (parentwidth - YGNodeLayoutGetMargin(YogaNode, YGEdgeLeft) < width) + width = parentwidth - parentPaddingLeft; + float parentHeight = YGNodeLayoutGetHeight(parent); + if (parentHeight < height) + height = parentHeight - parentPaddingTop; + } + + left += parentLeft; + top += parentTop; + return position.x > left && position.x < left + width && position.y > top && position.y < top + height; + } +} diff --git a/Nuake/src/UI/Nodes/Node.h b/Nuake/src/UI/Nodes/Node.h index b658d2fe..edcdf957 100644 --- a/Nuake/src/UI/Nodes/Node.h +++ b/Nuake/src/UI/Nodes/Node.h @@ -6,413 +6,415 @@ #include "../Core/Logger.h" #include - -namespace Layout +namespace Nuake { - enum class LayoutDirection + namespace Layout { - LTR = 2, RTL = 3 + enum class LayoutDirection + { + LTR = 2, RTL = 3 + }; + + enum class FlexWrap + { + NO_WRAP, WRAP, WRAP_REVERSED + }; + + enum class FlexDirection + { + ROW, COLUMN, ROW_REVERSED, COLUMN_REVERSED + }; + + enum class JustifyContent + { + FLEX_START, FLEX_END, CENTER, SPACE_BETWEEN, SPACE_AROUND, SPACE_EVENLY + }; + + enum class AlignItems + { + STRETCH, FLEX_START, FLEX_END, CENTER, BASELINE, AUTO, + }; + + enum class AlignContent + { + FLEX_START, FLEX_END, STRETCH, CENTER, SPACE_BETWEEN, SPACE_AROUND + }; + + enum class PositionType + { + STATIC, RELATIVE, ABSOLUTE + }; + + enum Unit + { + PIXEL, PERCENT, AUTO + }; + + struct LayoutUnit + { + float Value = 0.0f; + Unit Unit = Unit::PIXEL; + }; + + struct LayoutVec4 + { + LayoutUnit Top = LayoutUnit{ 0, PIXEL }; + LayoutUnit Bottom = LayoutUnit{ 0, PIXEL }; + LayoutUnit Left = LayoutUnit{ 0, PIXEL }; + LayoutUnit Right = LayoutUnit{ 0, PIXEL }; + }; + } + + + enum class NodeType + { + Normal, + Text }; - enum class FlexWrap + // Base UI node. + class Node { - NO_WRAP, WRAP, WRAP_REVERSED - }; + public: + int Depth; + Ref Root; + Ref Parent; + std::vector Groups; + std::vector> Childrens = std::vector>(); - enum class FlexDirection - { - ROW, COLUMN, ROW_REVERSED, COLUMN_REVERSED - }; + std::string OnClickSignature = ""; - enum class JustifyContent - { - FLEX_START, FLEX_END, CENTER, SPACE_BETWEEN, SPACE_AROUND, SPACE_EVENLY - }; + NodeType Type = NodeType::Normal; - enum class AlignItems - { - STRETCH, FLEX_START, FLEX_END, CENTER, BASELINE, AUTO, - }; + YGNodeRef YogaNode; - enum class AlignContent - { - FLEX_START, FLEX_END, STRETCH, CENTER, SPACE_BETWEEN, SPACE_AROUND - }; + Ref