From 4f93cb439556b768782419c8f2417f23e93811b1 Mon Sep 17 00:00:00 2001 From: antopilo Date: Fri, 10 Sep 2021 00:04:38 -0400 Subject: [PATCH] Point entity and prefab --- Editor/src/ProjectInterface.cpp | 32 +++++++++++++--- Nuake/src/Rendering/Buffers/UniformBuffer.cpp | 32 ++++++++++++++-- Nuake/src/Rendering/Buffers/UniformBuffer.h | 21 ++++++---- Nuake/src/Rendering/Renderer.cpp | 34 ++++++++--------- Nuake/src/Rendering/Renderer.h | 22 +++++++++++ Nuake/src/Resource/FGD/FDGSerializer.h | 1 + Nuake/src/Resource/FGD/FGDClass.h | 19 +++++++++- Nuake/src/Resource/FGD/FGDFile.cpp | 2 +- Nuake/src/Resource/FGD/FGDFile.h | 33 +++++++++------- Nuake/src/Resource/FGD/FGDSerializer.cpp | 35 +++++++++++++++++ Nuake/src/Resource/Prefab.cpp | 1 + Nuake/src/Resource/Prefab.h | 14 ++++++- Nuake/src/Scene/Components/LightComponent.h | 2 + Nuake/src/Scene/Components/PrefabComponent.h | 7 ++++ Nuake/src/Scene/EditorCamera.h | 6 +++ Nuake/src/Scene/Systems/QuakeMapBuilder.cpp | 38 ++++++++++++++++++- 16 files changed, 245 insertions(+), 54 deletions(-) diff --git a/Editor/src/ProjectInterface.cpp b/Editor/src/ProjectInterface.cpp index 1d3f1f87..726e4a66 100644 --- a/Editor/src/ProjectInterface.cpp +++ b/Editor/src/ProjectInterface.cpp @@ -143,22 +143,44 @@ namespace Nuake { ImGui::TableHeadersRow(); ImGui::TableNextColumn(); + int i = 0; for (auto& pE : file->PointEntities) { - ImGui::Text(pE.Name.c_str()); + ImGuiTextSTD("##PName" + std::to_string(i), pE.Name); + for (int i = 0; i < pE.Name.size(); i++) + { + if (pE.Name[i] == ' ') + pE.Name[i] = '_'; + } ImGui::TableNextColumn(); - ImGui::Text(pE.Description.c_str()); + ImGuiTextSTD("Desc" + std::to_string(i), pE.Description); ImGui::TableNextColumn(); ImGui::Button("Edit"); ImGui::TableNextColumn(); - ImGui::Text(pE.Prefab.c_str()); - ImGui::SameLine(); - ImGui::Button("Browse"); + ImGuiTextSTD("Prefab##" + std::to_string(i), pE.Prefab); + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Prefab")) + { + char* file = (char*)payload->Data; + std::string fullPath = std::string(file, 256); + pE.Prefab = FileSystem::AbsoluteToRelative(fullPath); + } + ImGui::EndDragDropTarget(); + } + ImGui::TableNextColumn(); + i++; } ImGui::EndTable(); } ImGui::EndChild(); + + if (ImGui::Button("Add new")) + { + file->PointEntities.push_back(FGDPointEntity("NewPointEntity")); + } + ImGui::EndTabItem(); } diff --git a/Nuake/src/Rendering/Buffers/UniformBuffer.cpp b/Nuake/src/Rendering/Buffers/UniformBuffer.cpp index ce789a60..4d9804f7 100644 --- a/Nuake/src/Rendering/Buffers/UniformBuffer.cpp +++ b/Nuake/src/Rendering/Buffers/UniformBuffer.cpp @@ -1,7 +1,33 @@ #include "UniformBuffer.h" +#include - -UniformBuffer::UniformBuffer() +namespace Nuake { + UniformBuffer::UniformBuffer(unsigned int size) + { + glGenBuffers(1, &RendererID); + glBindBuffer(GL_UNIFORM_BUFFER, RendererID); + glBufferData(GL_UNIFORM_BUFFER, size, 0, GL_STATIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } -} \ No newline at end of file + void UniformBuffer::Bind() + { + glBindBuffer(GL_UNIFORM_BUFFER, RendererID); + } + + void UniformBuffer::UpdateData(unsigned int size, void* data) + { + glBufferSubData(GL_UNIFORM_BUFFER, 0, size, data); + } + + void UniformBuffer::Push(unsigned int slot) + { + glBindBufferBase(GL_UNIFORM_BUFFER, slot, RendererID); + } + + void UniformBuffer::Unbind() + { + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } +} diff --git a/Nuake/src/Rendering/Buffers/UniformBuffer.h b/Nuake/src/Rendering/Buffers/UniformBuffer.h index 293f613d..d29e8218 100644 --- a/Nuake/src/Rendering/Buffers/UniformBuffer.h +++ b/Nuake/src/Rendering/Buffers/UniformBuffer.h @@ -1,12 +1,17 @@ #pragma once +namespace Nuake +{ + class UniformBuffer { + private: + unsigned int RendererID; + public: + UniformBuffer(unsigned int size); -class UniformBuffer { -private: - unsigned int RendererID; -public: - UniformBuffer(); + void Bind(); + void Unbind(); - void Bind(); - void Unbind(); -}; \ No newline at end of file + void UpdateData(unsigned int size, void* data); + void Push(unsigned int slot = 0); + }; +} \ No newline at end of file diff --git a/Nuake/src/Rendering/Renderer.cpp b/Nuake/src/Rendering/Renderer.cpp index 5e63e933..377b2c15 100644 --- a/Nuake/src/Rendering/Renderer.cpp +++ b/Nuake/src/Rendering/Renderer.cpp @@ -33,9 +33,10 @@ namespace Nuake VertexArray* Renderer::CubeVertexArray; VertexBuffer* Renderer::CubeVertexBuffer; + Ref Renderer::m_LightsUniformBuffer; RenderList Renderer::m_RenderList = RenderList(); - glm::vec3 CubeVertices[36]{ + 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), @@ -66,6 +67,8 @@ namespace Nuake LoadShaders(); + m_LightsUniformBuffer = CreateRef(128); + // Cube buffer CubeVertexArray = new VertexArray(); CubeVertexArray->Bind(); @@ -137,6 +140,8 @@ namespace Nuake Vector3 pos = transform.GlobalTranslation; Matrix4 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) { @@ -163,6 +168,7 @@ namespace Nuake if (m_Lights.size() == 20) return; + Ref deferredShader = ShaderManager::GetShader("resources/Shaders/deferred.shader"); deferredShader->Bind(); m_Lights.push_back({ transform , light }); @@ -175,16 +181,18 @@ namespace Nuake //light.m_Framebuffer->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17); - if (light.CastShadows) + int shadowmapAmount = 0; + if (light.CastShadows && light.Type == Directional) { for (unsigned int i = 0; i < CSM_AMOUNT; i++) { light.m_Framebuffers[i]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17 + i); - deferredShader->SetUniform1i("ShadowMaps[" + std::to_string(i) + "]", 17 + i); - deferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMapsIDs[" + std::to_string(i) + "]", i); + deferredShader->SetUniform1i("ShadowMaps[" + std::to_string(shadowmapAmount + i) + "]", 17 + i); + deferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMapsIDs[" + std::to_string(i) + "]", shadowmapAmount + i); deferredShader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[" + std::to_string(i) + "]", light.mCascadeSplitDepth[i]); deferredShader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[" + std::to_string(i) + "]", light.mViewProjections[i]); } + shadowmapAmount += CSM_AMOUNT; } deferredShader->SetUniform1i("LightCount", idx); @@ -194,6 +202,9 @@ namespace Nuake deferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Direction", direction.x, direction.y, direction.z); deferredShader->SetUniform3f("Lights[" + std::to_string(idx - 1) + "].Color", light.Color.r * light.Strength, light.Color.g * light.Strength, light.Color.b * light.Strength); deferredShader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].Volumetric", light.IsVolumetric); + + m_LightsUniformBuffer->Bind(); + //m_LightsUniformBuffer->UpdateData() } void Renderer::DrawDebugLine(glm::vec3 start, glm::vec3 end, glm::vec4 color) @@ -211,21 +222,6 @@ namespace Nuake CubeVertexArray->Bind(); RenderCommand::DrawArrays(0, 36); - //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 diff --git a/Nuake/src/Rendering/Renderer.h b/Nuake/src/Rendering/Renderer.h index 141ed60b..7e4df1cb 100644 --- a/Nuake/src/Rendering/Renderer.h +++ b/Nuake/src/Rendering/Renderer.h @@ -1,9 +1,11 @@ #pragma once +#include "src/Core/Maths.h" #include "Shaders/Shader.h" #include "src/Scene/Components/Components.h" #include "src/Core/Core.h" #include "Buffers/VertexArray.h" #include "RenderList.h" +#include "Buffers/UniformBuffer.h" namespace Nuake { @@ -13,6 +15,24 @@ namespace Nuake LightComponent light; }; + const int MAX_LIGHT = 64; + //struct LightDataArray + //{ + // LightData Lights[MAX_LIGHT]; + //}; + + struct LightData + { + int ShadowMapsIDs[CSM_AMOUNT]; + float CascadeDepth[CSM_AMOUNT]; + Matrix4 LightTransforms[CSM_AMOUNT]; + int Type; + Vector3 Position; + Vector3 Direction; + Vector3 Color; + int Volumetric; + }; + class Renderer { private: @@ -32,6 +52,8 @@ namespace Nuake static Ref m_ProceduralSkyShader; static Ref m_DebugShader; + static Ref m_LightsUniformBuffer; + static void Init(); static void LoadShaders(); diff --git a/Nuake/src/Resource/FGD/FDGSerializer.h b/Nuake/src/Resource/FGD/FDGSerializer.h index 7e6c7c43..adb97c18 100644 --- a/Nuake/src/Resource/FGD/FDGSerializer.h +++ b/Nuake/src/Resource/FGD/FDGSerializer.h @@ -9,6 +9,7 @@ namespace Nuake { static bool BeginFGDFile(const std::string path); static bool SerializeClass(FGDClass fgdClass); + static bool SerializePoint(FGDPointEntity fgdPoint); static bool SerializeBrush(FGDBrushEntity fgdClass); static bool EndFGDFile(); }; diff --git a/Nuake/src/Resource/FGD/FGDClass.h b/Nuake/src/Resource/FGD/FGDClass.h index 0d7e5f8d..867f51d3 100644 --- a/Nuake/src/Resource/FGD/FGDClass.h +++ b/Nuake/src/Resource/FGD/FGDClass.h @@ -80,6 +80,18 @@ namespace Nuake { std::vector Properties; FGDBaseEntity BaseClass; + FGDPointEntity(const std::string name) + { + Name = name; + Description = ""; + } + + FGDPointEntity() + { + Name = ""; + Description = ""; + } + json Serialize() override { BEGIN_SERIALIZE(); @@ -91,11 +103,16 @@ namespace Nuake { bool Deserialize(const std::string& str) override { + BEGIN_DESERIALIZE(); + Name = j["Name"]; + Description = j["Description"]; + Prefab = j["Prefab"]; return true; } }; - class FGDClass { + class FGDClass + { public: FGDClassType Type; std::string Name; diff --git a/Nuake/src/Resource/FGD/FGDFile.cpp b/Nuake/src/Resource/FGD/FGDFile.cpp index f16a78eb..27f04917 100644 --- a/Nuake/src/Resource/FGD/FGDFile.cpp +++ b/Nuake/src/Resource/FGD/FGDFile.cpp @@ -82,7 +82,7 @@ namespace Nuake { for (auto& p : PointEntities) { - + FGDSerializer::SerializePoint(p); } for (auto& b : BrushEntities) diff --git a/Nuake/src/Resource/FGD/FGDFile.h b/Nuake/src/Resource/FGD/FGDFile.h index 9f5f007d..7d94fcff 100644 --- a/Nuake/src/Resource/FGD/FGDFile.h +++ b/Nuake/src/Resource/FGD/FGDFile.h @@ -31,26 +31,17 @@ namespace Nuake { json Serialize() override { BEGIN_SERIALIZE(); - int i = 0; - for (auto& c : this->BrushEntities) - { - j["BrushEntities"][i] = c.Serialize(); - i++; - } + for (int i = 0; i < BrushEntities.size(); i++) + j["BrushEntities"][i] = BrushEntities[i].Serialize(); - i = 0; - for (auto& c : this->PointEntities) - { - j["PointEntities"][i] = c.Serialize(); - i++; - } + for (int i = 0; i < PointEntities.size(); i++) + j["PointEntities"][i] = PointEntities[i].Serialize(); END_SERIALIZE(); } bool Deserialize(const std::string& str) { BEGIN_DESERIALIZE(); - if (j.contains("BrushEntities")) { for (auto& brush : j["BrushEntities"]) @@ -63,7 +54,12 @@ namespace Nuake { if (j.contains("PointEntities")) { - + for (auto& point : j["PointEntities"]) + { + FGDPointEntity pointEntity = FGDPointEntity(); + pointEntity.Deserialize(point.dump()); + PointEntities.push_back(pointEntity); + } } return true; @@ -78,6 +74,15 @@ namespace Nuake { } } + FGDPointEntity& GetPointEntity(const std::string& name) + { + for (auto& p : PointEntities) + { + if (name == p.Name) + return p; + } + } + EntityType GetTypeOfEntity(const std::string& className) { for (auto& b : BrushEntities) diff --git a/Nuake/src/Resource/FGD/FGDSerializer.cpp b/Nuake/src/Resource/FGD/FGDSerializer.cpp index 4a78cbe5..fbf61c23 100644 --- a/Nuake/src/Resource/FGD/FGDSerializer.cpp +++ b/Nuake/src/Resource/FGD/FGDSerializer.cpp @@ -51,6 +51,41 @@ namespace Nuake { return true; } + bool FGDSerializer::SerializePoint(FGDPointEntity fgdPoint) + { + std::string line = "@"; + line += "PointClass = "; + line += fgdPoint.Name + " : \"" + fgdPoint.Description + "\""; + + // Exit early + if (fgdPoint.Properties.size() == 0) + { + line += " [] \n"; + FileSystem::WriteLine(line); + return true; + } + + // Properties here. + line += "\n [ \n"; + for (auto& p : fgdPoint.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); + } + bool FGDSerializer::SerializeBrush(FGDBrushEntity fgdClass) { std::string line = "@"; diff --git a/Nuake/src/Resource/Prefab.cpp b/Nuake/src/Resource/Prefab.cpp index 96df2f4f..9932d3c6 100644 --- a/Nuake/src/Resource/Prefab.cpp +++ b/Nuake/src/Resource/Prefab.cpp @@ -24,6 +24,7 @@ namespace Nuake { void Prefab::EntityWalker(Entity entity) { + Root = entity; entity.GetComponent().IsPrefab = true; Entities.push_back(entity); diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h index 92264474..7fc7727e 100644 --- a/Nuake/src/Resource/Prefab.h +++ b/Nuake/src/Resource/Prefab.h @@ -12,7 +12,8 @@ namespace Nuake { public: std::string Path; std::vector Entities; - + Entity Root; + static Ref CreatePrefabFromEntity(Entity entity); static Ref New(const std::string& path); @@ -41,10 +42,21 @@ namespace Nuake { { BEGIN_SERIALIZE(); SERIALIZE_VAL(Path); + std::vector entities = std::vector(); for (Entity e : Entities) entities.push_back(e.Serialize()); + SERIALIZE_VAL_LBL("Entities", entities); + + // Manual correction to remove parent if we are prefabing a child. + // We want to get rid of parent link in the prefab itself. + for (auto& e : j["Entities"]) + { + if (e["NameComponent"]["ID"] == Root.GetComponent().ID) + e["ParentComponent"]["HasParent"] = false; + } + END_SERIALIZE(); } diff --git a/Nuake/src/Scene/Components/LightComponent.h b/Nuake/src/Scene/Components/LightComponent.h index 514ad028..b83801d3 100644 --- a/Nuake/src/Scene/Components/LightComponent.h +++ b/Nuake/src/Scene/Components/LightComponent.h @@ -188,6 +188,8 @@ namespace Nuake Type = (LightType)j["Type"]; if (j.contains("IsVolumetric")) IsVolumetric = j["IsVolumetric"]; + if (j.contains("Color")) + Color = Vector3(j["Color"]["x"], j["Color"]["y"], j["Color"]["z"]); if (j.contains("Strength")) Strength = j["Strength"]; if (j.contains("SyncDirectionWithSky")) diff --git a/Nuake/src/Scene/Components/PrefabComponent.h b/Nuake/src/Scene/Components/PrefabComponent.h index 9f717636..182704eb 100644 --- a/Nuake/src/Scene/Components/PrefabComponent.h +++ b/Nuake/src/Scene/Components/PrefabComponent.h @@ -7,5 +7,12 @@ namespace Nuake { { public: Ref PrefabInstance; + + void SetPrefab(Ref prefab) + { + PrefabInstance = prefab; + + + } }; } \ No newline at end of file diff --git a/Nuake/src/Scene/EditorCamera.h b/Nuake/src/Scene/EditorCamera.h index 4b35fb8a..a4033ba9 100644 --- a/Nuake/src/Scene/EditorCamera.h +++ b/Nuake/src/Scene/EditorCamera.h @@ -7,6 +7,12 @@ namespace Nuake class EditorCamera : public Camera { public: + EditorCamera() + { + Translation = Vector3(10, 10, 10); + SetDirection(Vector3(-1, -1, -1)); + } + void Update(Timestep ts); private: bool controlled = false; diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp index f520cf83..b04daf3c 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp @@ -22,6 +22,7 @@ extern "C" { #include "src/Scene/Components/TriggerZone.h" #include "src/Resource/FGD/FGDClass.h" #include "src/Scene/Components/WrenScriptComponent.h" +#include "src/Scene/Components/PrefabComponent.h" namespace Nuake { struct ProcessedMesh @@ -329,6 +330,7 @@ namespace Nuake { return; QuakeMapComponent& quakeMapC = ent.GetComponent(); + ScaleFactor = quakeMapC.ScaleFactor; Scene* m_Scene = ent.GetScene(); // TODO: Tag entities *owned* by the map. @@ -363,8 +365,10 @@ namespace Nuake { std::string target = ""; std::string targetname = ""; FGDBrushEntity fgdBrush; + FGDPointEntity pointEntity; bool isEntity = false; bool isWorldSpawn = false; + bool isPointEntity = false; for (int i = 0; i < entity_inst->property_count; i++) { property* prop = &(entity_inst->properties)[i]; @@ -378,7 +382,7 @@ namespace Nuake { float y = String::ToFloat(splits[2]); float z = String::ToFloat(splits[0]); - Vector3 position = Vector3(x, y, z) * (ScaleFactor * (1.0f / 64.0f)); + Vector3 position = Vector3(x, y, z) * ScaleFactor * (1.0f / 64.0f); newEntity.GetComponent().Translation = position; } @@ -397,6 +401,15 @@ namespace Nuake { else isWorldSpawn = true; } + + if (type == EntityType::Point) + { + if (value != "") + isPointEntity = true; + + pointEntity = file->GetPointEntity(value); + + } } else { @@ -411,6 +424,21 @@ namespace Nuake { } if (!isWorldSpawn) { + if (isPointEntity) + { + Entity newPEntity = Engine::GetCurrentScene()->CreateEntity("New prefab Entity"); + newEntity.AddChild(newPEntity); + PrefabComponent& prefabComponent = newPEntity.AddComponent(); + prefabComponent.SetPrefab(Prefab::New(pointEntity.Prefab)); + for (auto& e : prefabComponent.PrefabInstance->Entities) + { + if (!e.GetComponent().HasParent) + { + newPEntity.AddChild(e); + } + } + } + for (int b = 0; b < entity_inst->brush_count; ++b) { brush* brush_inst = &entity_inst->brushes[b]; @@ -473,7 +501,12 @@ namespace Nuake { for (int i = 0; i < face_geo_inst->vertex_count; ++i) { face_vertex vertex = face_geo_inst->vertices[i]; - vertex_uv vertex_uv = get_valve_uv(vertex.vertex, face, texture->width, texture->height); + vertex_uv vertex_uv; + + if (face->is_valve_uv) + vertex_uv = get_valve_uv(vertex.vertex, face, texture->width, texture->height); + else + vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height); Vector3 vertexPos = Vector3( vertex.vertex.y * quakeMapC.ScaleFactor, @@ -531,6 +564,7 @@ namespace Nuake { } isEntity = false; + isPointEntity = false; } } }