diff --git a/Editor/resources/Shaders/debug.shader b/Editor/resources/Shaders/flat.shader similarity index 100% rename from Editor/resources/Shaders/debug.shader rename to Editor/resources/Shaders/flat.shader diff --git a/Editor/resources/Shaders/basic.shader b/Editor/resources/Shaders/pbr.shader similarity index 99% rename from Editor/resources/Shaders/basic.shader rename to Editor/resources/Shaders/pbr.shader index 27325761..34360c42 100644 --- a/Editor/resources/Shaders/basic.shader +++ b/Editor/resources/Shaders/pbr.shader @@ -212,7 +212,7 @@ float ShadowCalculation(Light light, vec3 FragPos, vec3 normal) int shadowmap = -1; // Get CSM depth - for (int i = 0; i < 4; i++) + for (int i = 0; i < 2; i++) { float CSMDepth = light.CascadeDepth[i] ; diff --git a/Editor/resources/Shaders/shadowMap.shader b/Editor/resources/Shaders/shadowMap.shader index 8ab18c95..28526c2d 100644 --- a/Editor/resources/Shaders/shadowMap.shader +++ b/Editor/resources/Shaders/shadowMap.shader @@ -1,20 +1,17 @@ #shader vertex #version 460 core + layout(location = 0) in vec3 Position; -uniform mat4 lightSpaceMatrix; -uniform mat4 model; + +uniform mat4 u_LightTransform; +uniform mat4 u_Model; void main() { - - gl_Position = lightSpaceMatrix * model * vec4(Position, 1.0); + gl_Position = u_LightTransform * u_Model * vec4(Position, 1.0); } #shader fragment #version 460 core - -void main() -{ - -} +void main() { } \ No newline at end of file diff --git a/Editor/src/EditorInterface.cpp b/Editor/src/EditorInterface.cpp index d9ee3377..363337ac 100644 --- a/Editor/src/EditorInterface.cpp +++ b/Editor/src/EditorInterface.cpp @@ -28,6 +28,7 @@ #include "src/Scene/Components/WrenScriptComponent.h" #include "src/Scene/Systems/QuakeMapBuilder.h" #include "src/Scene/Components/LightComponent.h" +#include "UIComponents/Viewport.h" namespace Nuake { Ref userInterface; @@ -53,7 +54,6 @@ namespace Nuake { 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())) { @@ -125,7 +125,6 @@ namespace Nuake { ImGui::PopStyleVar(); } ImGui::End(); - } static int selected = 0; diff --git a/Editor/src/UIComponents/Viewport.cpp b/Editor/src/UIComponents/Viewport.cpp new file mode 100644 index 00000000..85a6ca51 --- /dev/null +++ b/Editor/src/UIComponents/Viewport.cpp @@ -0,0 +1,21 @@ +#include "Viewport.h" +#include + +Viewport::Viewport(const std::string& name, Ref texture) +{ + Name = name; + Texture = texture; +} + +void Viewport::Draw() +{ + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + + if (ImGui::Begin(Name.c_str())) + { + ImGui::Image((void*)Texture->GetID(), ImGui::GetContentRegionAvail(), ImVec2(0, 1), ImVec2(1, 0)); + } + ImGui::PopStyleVar(); + + ImGui::End(); +} \ No newline at end of file diff --git a/Editor/src/UIComponents/Viewport.h b/Editor/src/UIComponents/Viewport.h new file mode 100644 index 00000000..ce34adbf --- /dev/null +++ b/Editor/src/UIComponents/Viewport.h @@ -0,0 +1,13 @@ +#pragma once +#include "Engine.h" +#include "src/Rendering/Textures/Texture.h" + +class Viewport +{ +public: + std::string Name = ""; + Ref Texture; + + Viewport(const std::string& name, Ref texture); + void Draw(); +}; \ No newline at end of file diff --git a/Nuake/src/Rendering/Platforms/OGLRendererAPI.cpp b/Nuake/src/Rendering/Platforms/OGLRendererAPI.cpp index b79907fc..558d00f3 100644 --- a/Nuake/src/Rendering/Platforms/OGLRendererAPI.cpp +++ b/Nuake/src/Rendering/Platforms/OGLRendererAPI.cpp @@ -58,6 +58,11 @@ namespace Nuake { glVertexAttribPointer(index, size, glType, normalized, stride, pointer); } + void OGLRendererAPI::DrawMultiElements(const RendererEnum mode, const int count, const RendererEnum type, const void* const* indices, unsigned int drawCount) + { + glMultiDrawElements(GetType(mode), &count, GetType(type), indices, drawCount); + } + void OGLRendererAPI::DrawElements(const RendererEnum mode, const int count, const RendererEnum type, const void* indices) { glDrawElements(GetType(mode), count, GetType(type), indices); diff --git a/Nuake/src/Rendering/Platforms/OGLRendererAPI.h b/Nuake/src/Rendering/Platforms/OGLRendererAPI.h index 694ab163..1ad89a80 100644 --- a/Nuake/src/Rendering/Platforms/OGLRendererAPI.h +++ b/Nuake/src/Rendering/Platforms/OGLRendererAPI.h @@ -22,6 +22,7 @@ namespace Nuake { void EnableVertexAttribArray(unsigned int& index) override; void VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer) override; + void DrawMultiElements(const RendererEnum mode, const int count, const RendererEnum type, const void* const* indices, unsigned int drawCount) override; void DrawElements(const RendererEnum mode, const int count, const RendererEnum type, const void* indices) override; void DrawArrays(int from, int count) override; private: diff --git a/Nuake/src/Rendering/Platforms/RendererAPI.h b/Nuake/src/Rendering/Platforms/RendererAPI.h index 893ddbad..8c0e49af 100644 --- a/Nuake/src/Rendering/Platforms/RendererAPI.h +++ b/Nuake/src/Rendering/Platforms/RendererAPI.h @@ -27,6 +27,7 @@ namespace Nuake { virtual void EnableVertexAttribArray(unsigned int& index) = 0; virtual void VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer) = 0; + virtual void DrawMultiElements(const RendererEnum mode, const int count, const RendererEnum type, const void* const* indices, unsigned int drawCount) = 0; virtual void DrawElements(const RendererEnum mode, const int count, const RendererEnum type, const void* indices) = 0; virtual void DrawArrays(int from, int count) = 0; }; diff --git a/Nuake/src/Rendering/RenderCommand.cpp b/Nuake/src/Rendering/RenderCommand.cpp index 4357bafd..a0e3b20c 100644 --- a/Nuake/src/Rendering/RenderCommand.cpp +++ b/Nuake/src/Rendering/RenderCommand.cpp @@ -64,6 +64,11 @@ namespace Nuake { sRendererAPI->VertexAttribPointer(index, size, type, normalized, stride, pointer); } + void RenderCommand::DrawMultiElements(const RendererEnum mode, const int count, const RendererEnum type, const void* const* indices, unsigned int drawCount) + { + sRendererAPI->DrawMultiElements(mode, count, type, indices, drawCount); + } + void RenderCommand::DrawElements(const RendererEnum mode, const int count, const RendererEnum type, const void* indices) { sRendererAPI->DrawElements(mode, count, type, indices); diff --git a/Nuake/src/Rendering/RenderCommand.h b/Nuake/src/Rendering/RenderCommand.h index 84471bb7..ed4670c6 100644 --- a/Nuake/src/Rendering/RenderCommand.h +++ b/Nuake/src/Rendering/RenderCommand.h @@ -26,7 +26,7 @@ namespace Nuake { static void BindVertexArray(const unsigned int& rendererID); static void VertexAttribPointer(const unsigned int index, const int size, const RendererEnum type, bool normalized, int stride, const void* pointer); - + static void DrawMultiElements(const RendererEnum mode, const int count, const RendererEnum type, const void* const* indices, unsigned int drawCount); static void DrawElements(const RendererEnum mode, const int count, const RendererEnum type, const void* indices); static void DrawArrays(int first, int count); private: diff --git a/Nuake/src/Rendering/RenderList.h b/Nuake/src/Rendering/RenderList.h index 8e8b2deb..c1b467b1 100644 --- a/Nuake/src/Rendering/RenderList.h +++ b/Nuake/src/Rendering/RenderList.h @@ -30,17 +30,17 @@ namespace Nuake m_RenderList[mesh->m_Material].push_back({mesh, transform}); } - void Flush() + void Flush(Ref shader, bool depthOnly = false) { - Ref pbrShader = ShaderManager::GetShader("resources/Shaders/basic.shader"); - pbrShader->Bind(); + shader->Bind(); for (auto& i : m_RenderList) { - i.first->Bind(); + if(!depthOnly) + i.first->Bind(); for (auto& m : i.second) { - pbrShader->SetUniformMat4f("u_Model", m.transform); + shader->SetUniformMat4f("u_Model", m.transform); m.Mesh->Draw(false); } } diff --git a/Nuake/src/Rendering/Renderer.cpp b/Nuake/src/Rendering/Renderer.cpp index 9f576937..16298eb3 100644 --- a/Nuake/src/Rendering/Renderer.cpp +++ b/Nuake/src/Rendering/Renderer.cpp @@ -95,7 +95,7 @@ namespace Nuake m_DeferredShader = ShaderManager::GetShader("resources/Shaders/deferred.shader"); m_ProceduralSkyShader = ShaderManager::GetShader("resources/Shaders/atmospheric_sky.shader"); m_DebugShader = ShaderManager::GetShader("resources/Shaders/debug.shader"); - m_Shader = ShaderManager::GetShader("resources/Shaders/basic.shader"); + m_Shader = ShaderManager::GetShader("resources/Shaders/pbr.shader"); } void Renderer::SubmitMesh(Ref mesh, Matrix4 transform) @@ -103,15 +103,13 @@ namespace Nuake m_RenderList.AddToRenderList(mesh, transform); } - void Renderer::Flush() + void Renderer::Flush(Ref shader, bool depthOnly) { - m_RenderList.Flush(); + m_RenderList.Flush(shader, depthOnly); } void Renderer::BeginDraw(Ref camera) { - RenderCommand::Clear(); - m_Shader->Bind(); m_Shader->SetUniformMat4f("u_Projection", camera->GetPerspective()); m_Shader->SetUniformMat4f("u_View", camera->GetTransform()); @@ -126,7 +124,7 @@ namespace Nuake // 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) + void Renderer::RegisterLight(TransformComponent transform, LightComponent light) { if (m_Lights.size() == 20) return; @@ -143,26 +141,17 @@ namespace Nuake 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); + for (unsigned int i = 0; i < CSM_AMOUNT; i++) + { + light.m_Framebuffers[i]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17 + i); + m_Shader->SetUniform1i("Lights[" + std::to_string(idx - 1) + "].ShadowMaps[" + std::to_string(i) + "]", 17 + i); + m_Shader->SetUniform1f("Lights[" + std::to_string(idx - 1) + "].CascadeDepth[" + std::to_string(i) + "]", light.mCascadeSplitDepth[i]); + m_Shader->SetUniformMat4f("Lights[" + std::to_string(idx - 1) + "].LightTransforms[" + std::to_string(i) + "]", light.mViewProjections[i]); + } } 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); diff --git a/Nuake/src/Rendering/Renderer.h b/Nuake/src/Rendering/Renderer.h index 5e1ec312..42d9144b 100644 --- a/Nuake/src/Rendering/Renderer.h +++ b/Nuake/src/Rendering/Renderer.h @@ -37,7 +37,7 @@ namespace Nuake static void BeginScene(); static void SubmitMesh(Ref mesh, Matrix4 transform); - static void Flush(); + static void Flush(Ref shader, bool depthOnly = false); // Drawing states static void BeginDraw(Ref camera); @@ -45,7 +45,7 @@ namespace Nuake // Lights static std::vector m_Lights; - static void RegisterLight(TransformComponent transform, LightComponent light, Ref cam); + static void RegisterLight(TransformComponent transform, LightComponent light); static void RegisterDeferredLight(TransformComponent transform, LightComponent light, Camera* cam); diff --git a/Nuake/src/Rendering/Shaders/Shader.cpp b/Nuake/src/Rendering/Shaders/Shader.cpp index c28293d9..ab7669a2 100644 --- a/Nuake/src/Rendering/Shaders/Shader.cpp +++ b/Nuake/src/Rendering/Shaders/Shader.cpp @@ -130,7 +130,7 @@ namespace Nuake // Retrieve uniform address and registers it if not already registered. int Shader::FindUniformLocation(std::string uniform) { - if (UniformCache.count(uniform) != 0) + if (UniformCache.find(uniform) == UniformCache.end()) { int addr = glGetUniformLocation(ProgramId, uniform.c_str()); diff --git a/Nuake/src/Scene/Components/LightComponent.cpp b/Nuake/src/Scene/Components/LightComponent.cpp index 32d16f65..6e097223 100644 --- a/Nuake/src/Scene/Components/LightComponent.cpp +++ b/Nuake/src/Scene/Components/LightComponent.cpp @@ -34,14 +34,14 @@ namespace Nuake { CastShadows = toggle; if (CastShadows) { - for (int i = 0; i < 4; i++) + for (int i = 0; i < CSM_AMOUNT; 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++) + for (int i = 0; i < CSM_AMOUNT; i++) { m_Framebuffers[i] = nullptr; } @@ -96,7 +96,7 @@ namespace Nuake { void LightComponent::Draw(TransformComponent transformComponent, Ref cam) { - Renderer::RegisterLight(transformComponent, *this, cam); + } void LightComponent::DrawDeferred(TransformComponent transformComponent, Camera* cam) diff --git a/Nuake/src/Scene/Components/LightComponent.h b/Nuake/src/Scene/Components/LightComponent.h index ca3f8469..c9463df2 100644 --- a/Nuake/src/Scene/Components/LightComponent.h +++ b/Nuake/src/Scene/Components/LightComponent.h @@ -16,6 +16,7 @@ namespace Nuake Directional, Point, Spot }; + const int CSM_AMOUNT = 4; class LightComponent { public: @@ -32,9 +33,9 @@ namespace Nuake float LinearAttenuation = 0.0f; float QuadraticAttenuation = 0.0f; - Ref m_Framebuffers[4]; - glm::mat4 mViewProjections[4]; - float mCascadeSplitDepth[4]; + Ref m_Framebuffers[CSM_AMOUNT]; + glm::mat4 mViewProjections[CSM_AMOUNT]; + float mCascadeSplitDepth[CSM_AMOUNT]; LightComponent(); @@ -57,8 +58,7 @@ namespace Nuake void SetType(LightType type); - float mCascadeSplits[4]; - + float mCascadeSplits[CSM_AMOUNT]; void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection) { @@ -78,7 +78,7 @@ namespace Nuake const float maxZ = nearClip + clipRange; const float range = maxZ - minZ; const float ratio = maxZ / minZ; - for (int i = 0; i < 4; i++) + for (int i = 0; i < CSM_AMOUNT; i++) { const float p = (i + 1) / static_cast(4); const float log = minZ * glm::pow(ratio, p); @@ -93,7 +93,7 @@ namespace Nuake float lastSplitDist = 0.0f; // Calculate Orthographic Projection matrix for each cascade - for (int cascade = 0; cascade < 4; cascade++) + for (int cascade = 0; cascade < CSM_AMOUNT; cascade++) { float splitDist = mCascadeSplits[cascade]; glm::vec4 frustumCorners[8] = @@ -117,7 +117,7 @@ namespace Nuake glm::vec4 invCorner = inverseViewProjection * frustumCorners[i]; frustumCorners[i] = invCorner / invCorner.w; } - for (int i = 0; i < 4; i++) + for (int i = 0; i < CSM_AMOUNT; i++) { glm::vec4 dist = frustumCorners[i + 4] - frustumCorners[i]; frustumCorners[i + 4] = frustumCorners[i] + (dist * splitDist); diff --git a/Nuake/src/Scene/Lighting/Environment.cpp b/Nuake/src/Scene/Lighting/Environment.cpp index 2fa07f28..8b95c093 100644 --- a/Nuake/src/Scene/Lighting/Environment.cpp +++ b/Nuake/src/Scene/Lighting/Environment.cpp @@ -21,7 +21,8 @@ namespace Nuake { m_AmbientColor = color; } - void Environment::Push() { + 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); diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index e878ef4f..3057e42c 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -163,68 +163,55 @@ namespace Nuake { auto view = m_Registry.view(); Ref cam = m_EditorCamera; - if (Engine::IsPlayMode) { + if (Engine::IsPlayMode) + { auto view = m_Registry.view(); - for (auto e : 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) { + Ref shadowShader = ShaderManager::GetShader("resources/Shaders/shadowMap.shader"); + shadowShader->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++) + for (int i = 0; i < CSM_AMOUNT; i++) { light.m_Framebuffers[i]->Bind(); light.m_Framebuffers[i]->Clear(); - Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]); + + shadowShader->SetUniformMat4f("u_LightTransform", light.mViewProjections[i]); + for (auto e : meshView) { auto [transform, mesh] = meshView.get(e); - - Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); - mesh.Draw(); + for(auto& m : mesh.meshes) + Renderer::SubmitMesh(m, transform.GetTransform()); } - std::vector sortedBrushes = std::vector(); - Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.mViewProjections[i]); auto quakeView = m_Registry.view(); - for (auto e : quakeView) { + 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); - //} + for (auto& m : model.Meshes) + Renderer::SubmitMesh(m, transform.GetTransform()); } - 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::Flush(shadowShader, true); } } @@ -233,13 +220,9 @@ namespace Nuake { void Scene::DrawInterface(Vector2 screensize) { for (auto i : m_Interfaces) - { i->Draw(screensize); - } } - - void Scene::Draw() { // Find the camera of the scene. @@ -253,98 +236,23 @@ namespace Nuake { break; } } + + Ref pbrShader = ShaderManager::GetShader("resources/Shaders/pbr.shader"); + glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); Ref env = GetEnvironment(); - if (env->ProceduralSkybox) - { env->ProceduralSkybox->Draw(cam); - } - Renderer::m_Shader->Bind(); + pbrShader->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()); - - for (auto& m : model.meshes) - { - Renderer::SubmitMesh(m, 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; - - Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform()); - Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective()); - - for (auto& b : model.Meshes) - { - Renderer::m_Shader->SetUniformMat4f("u_Model", transform.GetTransform()); - - Renderer::SubmitMesh(b, transform.GetTransform()); - } - } - - Renderer::m_DebugShader->SetUniformMat4f("u_View", cam->GetTransform()); - Renderer::m_DebugShader->SetUniformMat4f("u_Projection", cam->GetPerspective()); - - Renderer::Flush(); - - 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); + // Register the lights auto view = m_Registry.view(); for (auto l : view) { @@ -353,26 +261,87 @@ namespace Nuake { if (light.SyncDirectionWithSky) light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection(); - light.Draw(transform, m_EditorCamera); + Renderer::RegisterLight(transform, light); } + pbrShader->SetUniform3f("u_EyePosition", cam->GetTranslation().x, cam->GetTranslation().y, cam->GetTranslation().z); + pbrShader->SetUniform1i("u_ShowNormal", 0); + + if (cam) + { + pbrShader->SetUniform1f("u_Exposure", cam->Exposure); + pbrShader->SetUniformMat4f("u_View", cam->GetTransform()); + pbrShader->SetUniformMat4f("u_Projection", cam->GetPerspective()); + + auto view = m_Registry.view(); + for (auto e : view) + { + auto [transform, model, parent] = view.get(e); + for (auto& m : model.meshes) + Renderer::SubmitMesh(m, transform.GetTransform()); + } + + auto quakeView = m_Registry.view(); + for (auto e : quakeView) + { + auto [transform, model, parent] = quakeView.get(e); + if (model.IsTransparent) + continue; + + for (auto& b : model.Meshes) + Renderer::SubmitMesh(b, transform.GetTransform()); + } + + Renderer::Flush(pbrShader); + + PhysicsManager::Get()->DrawDebug(); + } + } + + void Scene::EditorDraw() + { + Ref env = GetEnvironment(); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + if (env->ProceduralSkybox) + env->ProceduralSkybox->Draw(m_EditorCamera); + glEnable(GL_CULL_FACE); + + Ref pbrShader = ShaderManager::GetShader("resources/Shaders/pbr.shader"); + pbrShader->Bind(); + + env->Push(); + glCullFace(GL_FRONT); - Renderer::m_Shader->Bind(); - Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0); + glEnable(GL_DEPTH_TEST); + + // Register the 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(); + + Renderer::RegisterLight(transform, light); + } + + pbrShader->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); + Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); + auto view = m_Registry.view(); for (auto e : view) { auto [transform, mesh, 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()); - for(auto& m : mesh.meshes) Renderer::SubmitMesh(m, transform.GetTransform()); } @@ -387,20 +356,19 @@ namespace Nuake { for (auto& b : model.Meshes) Renderer::SubmitMesh(b, transform.GetTransform()); - - Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); - Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); } - Renderer::m_DebugShader->Bind(); + Renderer::Flush(pbrShader); + + Ref flatShader = ShaderManager::GetShader("resources/Shaders/flat.shader"); + flatShader->Bind(); + flatShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); + flatShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); + 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; @@ -412,17 +380,13 @@ namespace Nuake { { 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()); + flatShader->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) { @@ -431,16 +395,15 @@ namespace Nuake { 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); + + flatShader->SetUniformMat4f("u_Model", transform.GetTransform()); + flatShader->SetUniform4f("u_Color", 1.f, 0.0f, 0.1f, 0.5f); for (auto& e : model.Meshes) Renderer::SubmitMesh(e, transform.GetTransform()); } - Renderer::Flush(); + Renderer::Flush(flatShader); } } diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp index f57606af..8782a9ae 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp @@ -6,7 +6,7 @@ #include "src/Scene/Components/QuakeMap.h" #include "src/Scene/Components/ParentComponent.h" #include - +#include extern "C" { #include @@ -24,6 +24,13 @@ extern "C" { #include "src/Scene/Components/WrenScriptComponent.h" namespace Nuake { + struct ProcessedMesh + { + std::vector Vertices; + std::vector Indices; + }; + + Ref DefaultMaterial; void QuakeMapBuilder::CreateTrigger(brush* brush, brush_geometry* brush_inst, @@ -131,7 +138,7 @@ 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_standard_uv(vertex.vertex, face, texture->width, texture->height); + vertex_uv vertex_uv = get_valve_uv(vertex.vertex, face, texture->width, texture->height); Vector3 vertexPos = Vector3( (vertex.vertex.y - brush->center.y) * (1.0f / 64), @@ -139,7 +146,7 @@ namespace Nuake { (vertex.vertex.x - brush->center.x) * (1.0f / 64) ); - Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); + Vector2 vertexUV = Vector2(vertex_uv.u, 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); @@ -149,7 +156,7 @@ namespace Nuake { 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) @@ -228,7 +235,6 @@ namespace Nuake { int lastTextureID = -1; std::string lastTexturePath = ""; - for (int f = 0; f < brush->face_count; ++f) { face* face = &brush->faces[f]; @@ -251,7 +257,7 @@ 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_standard_uv(vertex.vertex, face, texture->width, texture->height); + vertex_uv vertex_uv = get_valve_uv(vertex.vertex, face, texture->width, texture->height); Vector3 vertexPos = Vector3( (vertex.vertex.y - brush->center.y) * (1.0f / 64), @@ -259,7 +265,7 @@ namespace Nuake { (vertex.vertex.x - brush->center.x) * (1.0f / 64) ); - Vector2 vertexUV = Vector2(vertex_uv.u, 1.0 - vertex_uv.v); + Vector2 vertexUV = Vector2(vertex_uv.u, 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); @@ -358,6 +364,7 @@ namespace Nuake { std::string targetname = ""; FGDBrushEntity fgdBrush; bool isEntity = false; + bool isWorldSpawn = false; for (int i = 0; i < entity_inst->property_count; i++) { property* prop = &(entity_inst->properties)[i]; @@ -367,12 +374,11 @@ namespace Nuake { if (key == "origin") { std::vector splits = String::Split(value, ' '); + float x = String::ToFloat(splits[1]); + float y = String::ToFloat(splits[2]); + float z = String::ToFloat(splits[0]); - float x = String::ToFloat(splits[1]) * (1.f / 64.f); - float y = String::ToFloat(splits[2]) * (1.f / 64.f); - float z = String::ToFloat(splits[0]) * (1.f / 64.f); - - Vector3 position = Vector3(x, y, z); + Vector3 position = Vector3(x, y, z) * SCALE_FACTOR; newEntity.GetComponent().Translation = position; } @@ -385,33 +391,145 @@ namespace Nuake { if (type == EntityType::Brush) { fgdBrush = file->GetBrushEntity(value); - isEntity = true; + + if(fgdBrush.Name != "") + isEntity = true; + else + isWorldSpawn = true; } } + else + { + isWorldSpawn = true; + continue; + } } if (key == "targetname") - { targetname = value; - } if (key == "target") - { target = value; - } } - for (int b = 0; b < entity_inst->brush_count; ++b) + if (!isWorldSpawn) { - brush* brush_inst = &entity_inst->brushes[b]; - brush_geometry* brush_geo_inst = &entity_geo_inst->brushes[b]; - if (isEntity) + for (int b = 0; b < entity_inst->brush_count; ++b) { - CreateFuncBrush(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname, fgdBrush); - } - else - { - CreateBrush(brush_inst, brush_geo_inst, m_Scene, newEntity, target, targetname); + 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); } } + else + { + std::map> m_Materials; + std::map, std::vector> m_StaticWorld; + Entity brushEntity = m_Scene->CreateEntity("WorldSpawn"); + newEntity.AddChild(brushEntity); + + TransformComponent& transformComponent = brushEntity.GetComponent(); + BSPBrushComponent& bsp = brushEntity.AddComponent(); + bsp.IsSolid = true; + bsp.IsTransparent = false; + bsp.IsFunc = false; + bsp.IsTrigger = false; + bsp.target = target; + + 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]; + + for (int f = 0; f < brush_inst->face_count; ++f) + { + face* face = &brush_inst->faces[f]; + texture_data* texture = &textures[face->texture_idx]; + + Ref currentMaterial; + if (std::string(texture->name) != "__TB_empty") + { + std::string path = FileSystem::Root + "Textures/" + std::string(texture->name) + ".png"; + if (m_Materials.find(path) == m_Materials.end()) + m_Materials[path] = MaterialManager::Get()->GetMaterial(path); + + currentMaterial = m_Materials[path]; + texture->height = currentMaterial->m_Albedo->GetHeight(); + texture->width = currentMaterial->m_Albedo->GetWidth(); + } + else + { + currentMaterial = MaterialManager::Get()->GetMaterial("resources/Textures/default/Default.png"); + texture->height = texture->width = 1; + } + + + face_geometry* face_geo_inst = &brush_geo_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]; + vertex_uv vertex_uv = get_valve_uv(vertex.vertex, face, texture->width, texture->height); + + Vector3 vertexPos = Vector3( + vertex.vertex.y, + vertex.vertex.z, + vertex.vertex.x + ); + + 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); + Vector3 vertexBitangent = glm::cross(vertexNormal, vertexTangent) * (float)vertex.tangent.w; + + vertices.push_back(Vertex { + vertexPos * SCALE_FACTOR, + vertexUV, + vertexNormal, + vertexTangent, + vertexBitangent, + 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)index); + } + + m_StaticWorld[currentMaterial].push_back({vertices, indices}); + + vertices.clear(); + indices.clear(); + } + } + + // Batching process + for (auto& mat : m_StaticWorld) + { + std::vector batchedVertices; + std::vector batchedIndices; + int indexOffset = 0; + for (auto& pm : mat.second) + { + for(auto& vert : pm.Vertices) + batchedVertices.push_back(vert); + + for (auto& index : pm.Indices) + batchedIndices.push_back(indexOffset + index); + + indexOffset += pm.Vertices.size(); + } + + bsp.Meshes.push_back(CreateRef(batchedVertices, batchedIndices, mat.first)); + } + } + isEntity = false; } } diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.h b/Nuake/src/Scene/Systems/QuakeMapBuilder.h index be17ecbb..aee8b9af 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.h +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.h @@ -12,6 +12,7 @@ namespace Nuake { class QuakeMapBuilder { private: + const float SCALE_FACTOR = 1.f / 64.f; void CreateTrigger(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, const std::string& target, const std::string& targetname); @@ -23,6 +24,7 @@ namespace Nuake { void CreateFuncBrush(brush* brush, brush_geometry* brush_inst, Scene* scene, Entity& parent, const std::string& target, const std::string& targetname, FGDBrushEntity fgdBrush); + public: QuakeMapBuilder() {} diff --git a/Nuake/src/Vendors/libmap/c/geo_generator.c b/Nuake/src/Vendors/libmap/c/geo_generator.c index e3c9a449..10eb6070 100644 --- a/Nuake/src/Vendors/libmap/c/geo_generator.c +++ b/Nuake/src/Vendors/libmap/c/geo_generator.c @@ -218,41 +218,7 @@ void generate_brush_vertices(int entity_idx, int brush_idx) face *face_inst = &entities[entity_idx].brushes[brush_idx].faces[f0]; face_geometry *face_geo_inst = &entity_geo[entity_idx].brushes[brush_idx].faces[f0]; - vec3 normal; - - const char *phong_property = map_data_get_entity_property(entity_idx, "_phong"); - bool phong = phong_property != NULL && strcmp(phong_property, "1") == 0; - if (phong) - { - const char *phong_angle_property = map_data_get_entity_property(entity_idx, "_phong_angle"); - if (phong_angle_property != NULL) - { - double threshold = cos((atof(phong_angle_property) + 0.01) * 0.0174533); - normal = brush_inst->faces[f0].plane_normal; - if (vec3_dot(brush_inst->faces[f0].plane_normal, brush_inst->faces[f1].plane_normal) > threshold) - { - normal = vec3_add(normal, brush_inst->faces[f1].plane_normal); - } - if (vec3_dot(brush_inst->faces[f0].plane_normal, brush_inst->faces[f2].plane_normal) > threshold) - { - normal = vec3_add(normal, brush_inst->faces[f2].plane_normal); - } - normal = vec3_normalize(normal); - } - else - { - normal = vec3_normalize( - vec3_add( - brush_inst->faces[f0].plane_normal, - vec3_add( - brush_inst->faces[f1].plane_normal, - brush_inst->faces[f2].plane_normal))); - } - } - else - { - normal = face_inst->plane_normal; - } + vec3 normal = face_inst->plane_normal; texture_data *texture = map_data_get_texture(face_inst->texture_idx); @@ -296,10 +262,10 @@ void generate_brush_vertices(int entity_idx, int brush_idx) face_geo_inst->vertices = realloc(face_geo_inst->vertices, face_geo_inst->vertex_count * sizeof(face_vertex)); face_geo_inst->vertices[face_geo_inst->vertex_count - 1] = (face_vertex){vertex, normal, uv, tangent}; } - else if(phong) - { - face_geo_inst->vertices[duplicate_index].normal = vec3_add(face_geo_inst->vertices[duplicate_index].normal, normal); - } + //else if(phong) + //{ + // face_geo_inst->vertices[duplicate_index].normal = vec3_add(face_geo_inst->vertices[duplicate_index].normal, normal); + //} } } diff --git a/Nuake/src/Window.cpp b/Nuake/src/Window.cpp index f40d698e..ba0a85ce 100644 --- a/Nuake/src/Window.cpp +++ b/Nuake/src/Window.cpp @@ -226,19 +226,19 @@ namespace Nuake { void Window::Draw() { - // Dont render if no scene is loaded. if (!m_Scene) return; // Dont render if no cam is found. Ref cam = m_Scene->GetCurrentCamera(); - if (!cam) return; + if (!cam) + return; Vector2 size = m_Framebuffer->GetSize(); cam->AspectRatio = size.x / size.y; - Renderer::BeginDraw(cam); + //Renderer::BeginDraw(cam); m_Scene->DrawShadows();