diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 496be0a3..3c12aa1d 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -13,145 +13,32 @@ #include #include #include +#include -class FPSCamScript : public ScriptableEntity -{ -public: - float Pitch = 0.0f; - float Yaw = 0.0f; - float Speed = 0.0f; - float mouseLastX = 0.0f; - float mouseLastY = 0.0f; - - void OnCreate() - { - Input::HideMouse(); - } - - void OnDestroy() - { - - } - - void OnUpdate(Timestep ts) - { - float x = Input::GetMouseX(); - float y = Input::GetMouseY(); - - // 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; - - //Ref cam = GetComponent().CameraInstance; - //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)); - } -}; - -class MoveScript : public ScriptableEntity -{ -public: - - glm::vec3 velocity = glm::vec3(0.0f); - float playerHeight = 0.75f; - Ref cam; - - void OnCreate() - { - Entity ent = Engine::GetCurrentScene()->GetEntity("camEntity"); - cam = ent.GetComponent().CameraInstance; - ent.GetComponent().Translation.y = playerHeight; - - } - - void OnDestroy() { } - - void OnUpdate(Timestep ts) - { - if (Input::IsKeyDown(GLFW_KEY_W)) - velocity.z = 5.0f; - else if (Input::IsKeyDown(GLFW_KEY_S)) - velocity.z = -5.0f; - else - velocity.z = 0.0f; - if (Input::IsKeyDown(GLFW_KEY_A)) - velocity.x = 5.0f; - else if (Input::IsKeyDown(GLFW_KEY_D)) - velocity.x = -5.0f; - else - velocity.x = 0.0f; - - glm::vec3 front = cam->cameraFront; - front.y = .0f; - - glm::vec3 right = cam->cameraRight; - right.y = .0f; - glm::vec3 result = velocity.z * glm::normalize(front) + velocity.x * normalize(right); - - - } -}; - -class FlashingLightScript : public ScriptableEntity -{ -public: - bool isOn = false; - float nextFlip = 0.f; - float strength = 10.f; - - float deltaTime = 0.f; - - void OnCreate() { } - - void OnDestroy() { } - - void OnUpdate(Timestep ts) - { - if (nextFlip < deltaTime) - { - //GetComponent().Strength = isOn * strength; - isOn = !isOn; - nextFlip = deltaTime + 1.0f; - } - - deltaTime += ts; - } -}; - -void CreateInterface() -{ - //Ref userInterface = UI::UserInterface::New("test"); - // - //Ref rectangle = UI::Rect::New(16, 16, userInterface->Width - 16, userInterface->Height - 16); - //userInterface->AddRect(rectangle); - -} - int main() { + std::string TrenchbroomPath = "F:/TrenchBroom/"; + + FGDFile file(TrenchbroomPath + "Games/Nuake/Nuake.fgd"); + + FGDClass newClass(FGDClassType::Point, "light", "a nuake light"); + + ClassProperty prop{ + "Intensity", + ClassPropertyType::Integer, + "Changes the light intensity" + }; + + newClass.AddProperty(prop); + file.AddClass(newClass); + + file.Save(); + Engine::Init(); // ScriptingEngine::UpdateScript("test.lua"); - CreateInterface(); EditorInterface editor; editor.BuildFonts(); diff --git a/Editor/resources/Scripts/Cam.wren b/Editor/resources/Scripts/Cam.wren index 2ae7eab0..708d1267 100644 --- a/Editor/resources/Scripts/Cam.wren +++ b/Editor/resources/Scripts/Cam.wren @@ -11,11 +11,13 @@ class CamScript is ScriptableEntity { _mouseLastX = 0 _mouseLastY = 0 - _BobHeight = 0.1 + + _BobHeight = 0.1 _BobSpeed = 5.0 _CamHeight = 0.5 _deltaTime = 0 + Input.HideMouse() } diff --git a/Editor/resources/Scripts/Player.wren b/Editor/resources/Scripts/Player.wren index 2607a01f..2f05f4fb 100644 --- a/Editor/resources/Scripts/Player.wren +++ b/Editor/resources/Scripts/Player.wren @@ -12,13 +12,13 @@ class PlayerScript is ScriptableEntity { construct new() { _InputDir = Vector3.new(0, 0, 0) _Velocity = Vector3.new(0, 0, 0) - _Accel = 25 - _Deccel = 0.92 + _Accel = 150 + _Deccel = 0.85 _AirDeccel = 0.7 - _Gravity = 10 + _Gravity = 20 _MaxSpeed = 20 - _Jump = 200 + _Jump = 400 //Input.HideMouse() } @@ -58,7 +58,6 @@ class PlayerScript is ScriptableEntity { } else { _Velocity.y = -10 - Engine.Log("Grav: %(_Velocity.y)") if(Input.IsKeyPressed(32)) _Velocity.y = _Jump @@ -69,7 +68,6 @@ class PlayerScript is ScriptableEntity { _Velocity.z = _Velocity.z * _Deccel } - Engine.Log("Grav: %(_Velocity.y)") controller.MoveAndSlide(_Velocity * ts) } diff --git a/Editor/resources/Shaders/basic.shader b/Editor/resources/Shaders/basic.shader index 8260f726..6f556afa 100644 --- a/Editor/resources/Shaders/basic.shader +++ b/Editor/resources/Shaders/basic.shader @@ -59,6 +59,9 @@ struct Light { float LinearAttenuation; float QuadraticAttenuation; mat4 LightTransform; + sampler2D ShadowMaps[4]; + float CascadeDepth[4]; + mat4 LightTransforms[4]; sampler2D ShadowMap; sampler2D RSMFlux; sampler2D RSMNormal; @@ -221,6 +224,59 @@ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0); } +float ShadowCalculation(Light light, vec3 FragPos, vec3 normal) +{ + // Get Depth + vec3 startPosition = u_EyePosition; + vec3 rayVector = FragPos - startPosition; + float depth = length(rayVector); + + int shadowmap = -1; + + // Get CSM depth + for (int i = 0; i < 4; i++) + { + float CSMDepth = light.CascadeDepth[i] ; + + if (depth < CSMDepth + 0.0001) + { + shadowmap = i; + break; + } + } + + if (shadowmap == -1) + return 1.0; + + vec4 fragPosLightSpace = light.LightTransforms[shadowmap] * vec4(FragPos, 1.0f); + + //sampler2D shadowmapFB = light.ShadowMaps[shadowmap]; + + // perform perspective divide + vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; + // transform to [0,1] range + projCoords = projCoords * 0.5 + 0.5; + // get closest depth value from light's perspective (using [0,1] range fragPosLight as coords) + float closestDepth = texture(light.ShadowMaps[shadowmap], projCoords.xy).r; + // get depth of current fragment from light's perspective + float currentDepth = projCoords.z; + // check whether current frag pos is in shadow + float bias = max(0.005 * (1.0 - dot(normal, light.Direction)), 0.0005); + + float shadow = 0.0; + vec2 texelSize = 1.0 / textureSize(light.ShadowMaps[shadowmap], 0); + for (int x = -1; x <= 1; ++x) + { + for (int y = -1; y <= 1; ++y) + { + float pcfDepth = texture(light.ShadowMaps[shadowmap], projCoords.xy + vec2(x, y) * texelSize).r; + shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; + } + } + return shadow /= 9; +} + +/* float ShadowCalculation(vec4 fragPosLightSpace, sampler2D shadowMap, vec3 normal, vec3 lightDir) { // perform perspective divide @@ -246,7 +302,7 @@ float ShadowCalculation(vec4 fragPosLightSpace, sampler2D shadowMap, vec3 normal } return shadow /= 9; } - +*/ uniform float u_FogAmount; // Mie scaterring approximated with Henyey-Greenstein phase function. @@ -357,7 +413,8 @@ void main() attenuation = 1.0f; if (Lights[i].Volumetric == 1) Fog += ComputeVolumetric(v_FragPos, Lights[i].LightTransform, Lights[i].Color, Lights[i].ShadowMap, Lights[i].Direction); - shadow += ShadowCalculation(Lights[i].LightTransform * vec4(v_FragPos, 1.0f), Lights[i].ShadowMap, N, Lights[i].Direction); + shadow += ShadowCalculation(Lights[i], v_FragPos, N); + //shadow += ShadowCalculation(Lights[i].LightTransform * vec4(v_FragPos, 1.0f), Lights[i].ShadowMap, N, Lights[i].Direction); } diff --git a/Editor/src/EditorInterface.cpp b/Editor/src/EditorInterface.cpp index 56822da7..a001da46 100644 --- a/Editor/src/EditorInterface.cpp +++ b/Editor/src/EditorInterface.cpp @@ -21,6 +21,7 @@ #include #include #include +#include "ProjectInterface.h" Ref userInterface; ImFont* normalFont; ImFont* EditorInterface::bigIconFont; @@ -37,20 +38,25 @@ void EditorInterface::Init() ImGui::DockSpaceOverViewport(viewport, dockspace_flags); //this->filesystem = FileSystemUI(); + + + + } ImVec2 LastSize = ImVec2(); void EditorInterface::DrawViewport() { - if(ImGui::Begin("ShadowMap")) + /* + if(ImGui::Begin("ShadowMap1")) { ImVec2 regionAvail = ImGui::GetContentRegionAvail(); glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); if (m_IsEntitySelected && m_SelectedEntity.HasComponent()) { auto& light = m_SelectedEntity.GetComponent(); - Ref texture = light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT); + Ref texture = light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT); ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); } else { @@ -58,8 +64,59 @@ void EditorInterface::DrawViewport() } } + ImGui::End(); + if (ImGui::Begin("ShadowMap2")) + { + ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + + if (m_IsEntitySelected && m_SelectedEntity.HasComponent()) { + auto& light = m_SelectedEntity.GetComponent(); + Ref texture = light.m_Framebuffers[1]->GetTexture(GL_DEPTH_ATTACHMENT); + ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + } + else { + ImGui::Text("Please select a light entity"); + } + + } ImGui::End(); + if (ImGui::Begin("ShadowMap3")) + { + ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + + if (m_IsEntitySelected && m_SelectedEntity.HasComponent()) { + auto& light = m_SelectedEntity.GetComponent(); + Ref texture = light.m_Framebuffers[2]->GetTexture(GL_DEPTH_ATTACHMENT); + ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + } + else { + ImGui::Text("Please select a light entity"); + } + + } + + ImGui::End(); + if (ImGui::Begin("ShadowMap4")) + { + ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + + if (m_IsEntitySelected && m_SelectedEntity.HasComponent()) { + auto& light = m_SelectedEntity.GetComponent(); + Ref texture = light.m_Framebuffers[3]->GetTexture(GL_DEPTH_ATTACHMENT); + ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + } + else { + ImGui::Text("Please select a light entity"); + } + + } + + ImGui::End(); + if (ImGui::Begin("SDF FONT")) { ImVec2 regionAvail = ImGui::GetContentRegionAvail(); @@ -72,8 +129,12 @@ void EditorInterface::DrawViewport() } ImGui::End(); + */ + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); if(ImGui::Begin("Viewport")) { + + ImGui::PopStyleVar(); Overlay(); ImGuizmo::BeginFrame(); @@ -129,6 +190,7 @@ void EditorInterface::DrawViewport() } ImGui::End(); + } static int selected = 0; @@ -733,7 +795,7 @@ void EditorInterface::Overlay() { // FIXME-VIEWPORT: Select a default viewport const float DISTANCE = 10.0f; - static int corner = 0; + 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) @@ -988,6 +1050,8 @@ void EditorInterface::Draw() if (!Engine::GetProject()) { ImGui::OpenPopup("Welcome"); + + return; } if (ImGui::BeginMainMenuBar()) @@ -1139,6 +1203,9 @@ void EditorInterface::Draw() filesystem.Draw(); filesystem.DrawDirectoryExplorer(); + ProjectInterface pInterface; + pInterface.DrawEntitySettings(); + if(m_ShowImGuiDemo) ImGui::ShowDemoWindow(); diff --git a/Editor/src/ProjectInterface.cpp b/Editor/src/ProjectInterface.cpp new file mode 100644 index 00000000..4faa6e34 --- /dev/null +++ b/Editor/src/ProjectInterface.cpp @@ -0,0 +1,99 @@ +#include "ProjectInterface.h" +#include +#include "Engine.h" + +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)); + if (ImGui::InputText("##Name", buffer, sizeof(buffer))) + { + Engine::GetProject()->Name = std::string(buffer); + } +} + + +void ProjectInterface::DrawEntitySettings() +{ + if (ImGui::Begin("Entity definitions")) + { + ImGui::Text("This is the entity definition used by trenchbroom. This files allows you to see your entities inside Trenchbroom"); + ImGui::Text("Trenchbroom path:"); + // path here... + Ref file = Engine::GetProject()->EntityDefinitionsFile; + + + + auto flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize; + if (ImGui::BeginPopupModal("Create new point entity", NULL, flags)) + { + + + ImGui::Button("Create"); + ImGui::SameLine(); + ImGui::Button("Cancel"); + + ImGui::EndPopup(); + } + if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) + { + if (ImGui::BeginTabItem("Point entities")) + { + if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("Name"); + ImGui::TableSetupColumn("Desciption"); + ImGui::TableSetupColumn("Settings"); + ImGui::TableSetupColumn("Prefab"); + ImGui::TableHeadersRow(); + + ImGui::TableNextColumn(); + for (auto& pE : file->PointEntities) + { + 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::EndTabItem(); + } + if (ImGui::BeginTabItem("Brush entities")) + { + ImGui::Text("ID: 0123456789"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + + + + } + ImGui::End(); +} \ No newline at end of file diff --git a/Editor/src/ProjectInterface.h b/Editor/src/ProjectInterface.h new file mode 100644 index 00000000..f42dae82 --- /dev/null +++ b/Editor/src/ProjectInterface.h @@ -0,0 +1,18 @@ +#pragma once +#include "src/Core/Core.h" +#include "src/Resource/Project.h" + + +class ProjectInterface +{ +public: + Ref m_CurrentProject; + + + void DrawProjectSettings(); + + void DrawCreatePointEntity(); + void DrawEntitySettings(); + + +}; \ No newline at end of file diff --git a/Nuake/BaseClass.h b/Nuake/BaseClass.h deleted file mode 100644 index 15c3b600..00000000 --- a/Nuake/BaseClass.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include - -class BaseClass { -public: - std::string Name; -}; \ No newline at end of file diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index 43bb0a6f..0169b6d8 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -15,7 +15,7 @@ Ref Engine::CurrentProject; Ref Engine::CurrentWindow; float Engine::m_LastFrameTime = 0.0f; -float Engine::m_FixedUpdateRate = 1.0 / 60.0f; +float Engine::m_FixedUpdateRate = 1.0 / 144.0f; float Engine::m_FixedUpdateDifference = 0.f; bool Engine::IsPlayMode = false; diff --git a/Nuake/FGDSerializer.cpp b/Nuake/FGDSerializer.cpp deleted file mode 100644 index 27bb7a62..00000000 --- a/Nuake/FGDSerializer.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "FDGSerializer.h" -#include - - -bool FGDSerializer::BeginFGDFile(const std::string path) -{ - FileSystem::BeginWriteFile(path + ".fgd"); -} \ No newline at end of file diff --git a/Nuake/PointClass.h b/Nuake/PointClass.h deleted file mode 100644 index 07bde658..00000000 --- a/Nuake/PointClass.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "BaseClass.h" - -class PointClass : public BaseClass { - -}; \ No newline at end of file diff --git a/Nuake/src/Core/FileSystem.cpp b/Nuake/src/Core/FileSystem.cpp index 4b0caa57..c83ab4e6 100644 --- a/Nuake/src/Core/FileSystem.cpp +++ b/Nuake/src/Core/FileSystem.cpp @@ -137,7 +137,7 @@ std::ofstream FileSystem::fileWriter; bool FileSystem::BeginWriteFile(const std::string path) { fileWriter = std::ofstream(); - fileWriter.open("example.txt"); + fileWriter.open(path); return false; } @@ -145,6 +145,8 @@ bool FileSystem::BeginWriteFile(const std::string path) bool FileSystem::WriteLine(const std::string line) { fileWriter << line.c_str(); + + return true; } void FileSystem::EndWriteFile() diff --git a/Nuake/src/Rendering/Camera.cpp b/Nuake/src/Rendering/Camera.cpp index 6b40238d..0b599816 100644 --- a/Nuake/src/Rendering/Camera.cpp +++ b/Nuake/src/Rendering/Camera.cpp @@ -61,7 +61,7 @@ glm::vec3 Camera::GetDirection() { glm::mat4 Camera::GetPerspective() { //TODO: Add perspective options - m_Perspective = glm::perspectiveFov(glm::radians(Fov), 9.0f * AspectRatio, 9.0f, 0.1f, 2000.0f); + 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; } diff --git a/Nuake/src/Rendering/Renderer.cpp b/Nuake/src/Rendering/Renderer.cpp index ac4820d8..ea9ba9ce 100644 --- a/Nuake/src/Rendering/Renderer.cpp +++ b/Nuake/src/Rendering/Renderer.cpp @@ -130,10 +130,27 @@ void Renderer::RegisterLight(TransformComponent transform, LightComponent light, 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(GL_DEPTH_ATTACHMENT)->Bind(17); + //light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17); + + 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) + "].ShadowMap" , 17); + 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.Translation.x, transform.Translation.y, transform.Translation.z); m_Shader->SetUniform3f ("Lights[" + std::to_string(idx - 1) + "].Direction" , direction.x, direction.y, direction.z); diff --git a/Nuake/BrushClass.h b/Nuake/src/Resource/FGD/BrushClass.h similarity index 81% rename from Nuake/BrushClass.h rename to Nuake/src/Resource/FGD/BrushClass.h index e23bd102..14d307c2 100644 --- a/Nuake/BrushClass.h +++ b/Nuake/src/Resource/FGD/BrushClass.h @@ -5,7 +5,8 @@ #include -class BrushClass : public BaseClass { +class BrushClass { +public: std::string name; std::vector Props; std::string Description; diff --git a/Nuake/ClassProperty.h b/Nuake/src/Resource/FGD/ClassProperty.h similarity index 61% rename from Nuake/ClassProperty.h rename to Nuake/src/Resource/FGD/ClassProperty.h index 3ca73569..5810bfcf 100644 --- a/Nuake/ClassProperty.h +++ b/Nuake/src/Resource/FGD/ClassProperty.h @@ -1,15 +1,22 @@ #pragma once #include enum class ClassPropertyType { - AABB, - Float, String, - DropDown, + Integer, + Float, + Boolean, + AABB, + Choices, Color, - Int +}; + +enum class FGDClassType { + Point, + Brush }; struct ClassProperty { std::string name; ClassPropertyType type; + std::string description; }; \ No newline at end of file diff --git a/Nuake/FDGSerializer.h b/Nuake/src/Resource/FGD/FDGSerializer.h similarity index 66% rename from Nuake/FDGSerializer.h rename to Nuake/src/Resource/FGD/FDGSerializer.h index 07cc992c..b7c3f0fc 100644 --- a/Nuake/FDGSerializer.h +++ b/Nuake/src/Resource/FGD/FDGSerializer.h @@ -1,11 +1,12 @@ #pragma once +#include "FGDClass.h" #include class FGDSerializer { public: static bool BeginFGDFile(const std::string path); - static bool RegisterEntity(); + static bool SerializeClass(FGDClass fgdClass); static bool EndFGDFile(); }; \ No newline at end of file diff --git a/Nuake/src/Resource/FGD/FGDClass.cpp b/Nuake/src/Resource/FGD/FGDClass.cpp new file mode 100644 index 00000000..66a9ab94 --- /dev/null +++ b/Nuake/src/Resource/FGD/FGDClass.cpp @@ -0,0 +1,26 @@ +#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) + { + 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 new file mode 100644 index 00000000..37bda367 --- /dev/null +++ b/Nuake/src/Resource/FGD/FGDClass.h @@ -0,0 +1,47 @@ +#pragma once +#include "ClassProperty.h" +#include +#include + +class FGDBaseEntity +{ +public: + std::string Name; + std::vector Properties; +}; + +class FGDBrushEntity +{ +public: + std::string Name; + std::string Description; + bool Transparent = false; + bool Collision = false; + bool IsTrigger = false; + std::string Script = ""; + std::vector Properties; + + FGDBaseEntity BaseClass; +}; + +class FGDPointEntity +{ +public: + std::string Name; + std::string Description; + std::string Prefab; + std::vector Properties; + FGDBaseEntity BaseClass; +}; + +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); + void AddProperty(ClassProperty prop); + void RemoveProperty(const std::string name); +}; \ No newline at end of file diff --git a/Nuake/src/Resource/FGD/FGDFile.cpp b/Nuake/src/Resource/FGD/FGDFile.cpp new file mode 100644 index 00000000..09c5e6b2 --- /dev/null +++ b/Nuake/src/Resource/FGD/FGDFile.cpp @@ -0,0 +1,67 @@ +#include "FGDFile.h" +#include + +FGDFile::FGDFile(const std::string path) +{ + this->path = 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(); + + FGDPointEntity newEnt; + newEnt.Name = "Light"; + newEnt.Description = "A Nuake PBR light"; + + this->PointEntities.push_back(newEnt); +} + +bool FGDFile::Save() +{ + FGDSerializer::BeginFGDFile(this->path); + + for (auto& b : BaseEntities) + { + + } + + for (auto& p : PointEntities) + { + + } + + for (auto& b : BrushEntities) + { + + } + //for(auto& c : Classes) + // FGDSerializer::SerializeClass(c); + + FGDSerializer::EndFGDFile(); + return true; +} + +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++; + //} +} diff --git a/Nuake/src/Resource/FGD/FGDFile.h b/Nuake/src/Resource/FGD/FGDFile.h new file mode 100644 index 00000000..7fd54efa --- /dev/null +++ b/Nuake/src/Resource/FGD/FGDFile.h @@ -0,0 +1,35 @@ +#pragma once +#include "FGDClass.h" +#include "../Serializable.h" +#include +#include + +class FGDFile : ISerializable{ +public: + std::string path; + + std::vector PointEntities; + std::vector BrushEntities; + std::vector BaseEntities; + + FGDFile(const std::string path); + + FGDFile(); + + bool Save(); + + void AddClass(FGDClass fgdClass); + void RemoveClass(const std::string& name); + + json Serialize() override + { + BEGIN_SERIALIZE(); + + END_SERIALIZE(); + } + + bool Deserialize(const std::string& str) + { + return true; + } +}; \ No newline at end of file diff --git a/Nuake/src/Resource/FGD/FGDSerializer.cpp b/Nuake/src/Resource/FGD/FGDSerializer.cpp new file mode 100644 index 00000000..c5d94144 --- /dev/null +++ b/Nuake/src/Resource/FGD/FGDSerializer.cpp @@ -0,0 +1,58 @@ +#include "FDGSerializer.h" +#include + + +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 + "\""; + + // 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 true; +} + +bool FGDSerializer::EndFGDFile() +{ + FileSystem::EndWriteFile(); + return false; +} diff --git a/Nuake/src/Resource/FGD/PointClass.h b/Nuake/src/Resource/FGD/PointClass.h new file mode 100644 index 00000000..285122f2 --- /dev/null +++ b/Nuake/src/Resource/FGD/PointClass.h @@ -0,0 +1,8 @@ +#pragma once +#include "BaseClass.h" + + + +class PointClass { + +}; \ No newline at end of file diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h new file mode 100644 index 00000000..9c648236 --- /dev/null +++ b/Nuake/src/Resource/Prefab.h @@ -0,0 +1,7 @@ +#pragma once + + +class Prefab +{ + +}; \ No newline at end of file diff --git a/Nuake/src/Resource/Project.cpp b/Nuake/src/Resource/Project.cpp index 5b27f535..22989505 100644 --- a/Nuake/src/Resource/Project.cpp +++ b/Nuake/src/Resource/Project.cpp @@ -16,6 +16,8 @@ Project::Project(const std::string Name, const std::string Description, const st scene->Deserialize(defaultScenePath); } + this->EntityDefinitionsFile = CreateRef(); + SaveAs(FullPath); } @@ -24,6 +26,8 @@ Project::Project() this->Name = ""; this->Description = ""; this->FullPath = ""; + + this->EntityDefinitionsFile = CreateRef(); } void Project::Save() diff --git a/Nuake/src/Resource/Project.h b/Nuake/src/Resource/Project.h index e3bd0927..780794ab 100644 --- a/Nuake/src/Resource/Project.h +++ b/Nuake/src/Resource/Project.h @@ -3,6 +3,9 @@ #include "../Core/Core.h" #include "../Scene/Scene.h" #include "Serializable.h" + +#include "FGD/FGDFile.h" + class Project : public ISerializable { public: @@ -11,6 +14,7 @@ public: std::string FullPath; Ref DefaultScene; + Ref EntityDefinitionsFile; Project(const std::string Name, const std::string Description, const std::string& FullPath, const std::string& defaultScenePath = ""); Project(); diff --git a/Nuake/src/Scene/Components/LightComponent.cpp b/Nuake/src/Scene/Components/LightComponent.cpp index 5dff8ed4..f3d471a9 100644 --- a/Nuake/src/Scene/Components/LightComponent.cpp +++ b/Nuake/src/Scene/Components/LightComponent.cpp @@ -12,9 +12,18 @@ LightComponent::LightComponent() 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. - m_Framebuffer = CreateRef(false, glm::vec2(4096, 4096)); - m_Framebuffer->SetTexture(CreateRef(glm::vec2(4096, 4096), GL_DEPTH_COMPONENT), GL_DEPTH_ATTACHMENT); + 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); + } + } glm::mat4 LightComponent::GetProjection() @@ -44,7 +53,7 @@ glm::vec3 LightComponent::GetDirection() void LightComponent::BeginDrawShadow() { Renderer::m_ShadowmapShader->Bind(); - m_Framebuffer->Bind(); + //m_Framebuffer->Bind(); // Render scene... @@ -52,7 +61,7 @@ void LightComponent::BeginDrawShadow() void LightComponent::EndDrawShadow() { - m_Framebuffer->Unbind(); + //m_Framebuffer->Unbind(); } void LightComponent::DrawShadow() diff --git a/Nuake/src/Scene/Components/LightComponent.h b/Nuake/src/Scene/Components/LightComponent.h index a5e25861..b8c71cca 100644 --- a/Nuake/src/Scene/Components/LightComponent.h +++ b/Nuake/src/Scene/Components/LightComponent.h @@ -30,8 +30,9 @@ public: float LinearAttenuation = 0.0f; float QuadraticAttenuation = 0.0f; - std::vector mViewProjections; - std::vector mCascadeSplitDepth; + Ref m_Framebuffers[4]; + glm::mat4 mViewProjections[4]; + float mCascadeSplitDepth[4]; LightComponent(); @@ -52,16 +53,16 @@ public: void SetType(LightType type); - std::vector mCascadeSplits; + float mCascadeSplits[4]; - void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection, const glm::vec3& normalizedDirection) + void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection) { glm::mat4 viewProjection = projection * view; glm::mat4 inverseViewProjection = glm::inverse(viewProjection); // TODO: Automate this - const float nearClip = 0.1f; + const float nearClip = 0.01f; const float farClip = 1000.0f; const float clipRange = farClip - nearClip; @@ -82,9 +83,9 @@ public: mCascadeSplits[i] = (d - nearClip) / clipRange; } - mCascadeSplits[0] = 0.2f; - mCascadeSplits[1] = 0.45f; - mCascadeSplits[2] = 1.0f; + //mCascadeSplits[0] = 0.2f; + //mCascadeSplits[1] = 0.45f; + //mCascadeSplits[2] = 1.0f; float lastSplitDist = 0.0f; // Calculate Orthographic Projection matrix for each cascade @@ -137,7 +138,7 @@ public: glm::vec3 minExtents = -maxExtents; // Calculate the view and projection matrix - glm::vec3 lightDir = -normalizedDirection; + 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); diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 608e2eaa..15feedab 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -71,6 +71,9 @@ void Scene::Update(Timestep ts) { for (auto& system : m_Systems) system->Update(ts); + + + } void Scene::FixedUpdate(Timestep ts) @@ -116,30 +119,42 @@ void Scene::DrawShadows() if (light.Type != LightType::Directional) continue; + light.CalculateViewProjection(cam->GetTransform(), cam->GetPerspective()); + + light.BeginDrawShadow(); - for (auto e : modelView) + for (int i = 0; i < 4; i++) { - auto [transform, model] = modelView.get(e); - - glm::vec3 pos = lightTransform.Translation; - glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f)); - Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.GetProjection() * lightView); - Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); - - model.Draw(); - } - - for (auto e : quakeView) { - auto [transform, model] = quakeView.get(e); - - glm::vec3 pos = lightTransform.Translation; - glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f)); - - Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.GetProjection() * lightView); - Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); - - model.Draw(); + light.m_Framebuffers[i]->Bind(); + + for (auto e : modelView) + { + auto [transform, model] = modelView.get(e); + + glm::vec3 pos = lightTransform.Translation; + glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f)); + Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]); + Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); + + model.Draw(); + } + + for (auto e : quakeView) { + auto [transform, model] = quakeView.get(e); + + glm::vec3 pos = lightTransform.Translation; + glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f)); + + Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]); + Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); + + model.Draw(); + } + + light.m_Framebuffers[i]->Unbind(); } + + light.EndDrawShadow(); } } @@ -182,6 +197,7 @@ void Scene::Draw() break; } } + glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); Ref env = GetEnvironment(); @@ -222,7 +238,8 @@ void Scene::Draw() light.Draw(copyT, 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);