From 6d2272f62edc19f84e6233c4f265984a19061f61 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 2 Feb 2016 23:24:02 +0100 Subject: [PATCH] EditorRenderSystem that draws normally invisible cameras and AABBs --- include/Engine/Editor/EditorRenderSystem.h | 24 ++++++ include/Engine/Rendering/ModelJob.h | 3 +- include/Engine/Rendering/RenderState.h | 1 + src/Engine/Editor/EditorRenderSystem.cpp | 98 ++++++++++++++++++++++ src/Engine/Editor/EditorSystem.cpp | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 6 ++ src/Engine/Rendering/RenderState.cpp | 14 ++++ src/Game/Game.cpp | 2 + 8 files changed, 148 insertions(+), 2 deletions(-) create mode 100755 include/Engine/Editor/EditorRenderSystem.h create mode 100755 src/Engine/Editor/EditorRenderSystem.cpp diff --git a/include/Engine/Editor/EditorRenderSystem.h b/include/Engine/Editor/EditorRenderSystem.h new file mode 100755 index 00000000..5076b3a6 --- /dev/null +++ b/include/Engine/Editor/EditorRenderSystem.h @@ -0,0 +1,24 @@ +#include "../Core/System.h" +#include "../Rendering/IRenderer.h" +#include "../Rendering/ModelJob.h" +#include "../Rendering/Camera.h" +#include "../Rendering/ESetCamera.h" + +class EditorRenderSystem : public ImpureSystem +{ +public: + EditorRenderSystem(World* world, EventBroker* eventBroker, IRenderer* renderer, RenderFrame* renderFrame); + + virtual void Update(double dt) override; + +private: + IRenderer* m_Renderer; + RenderFrame* m_RenderFrame; + Camera* m_Camera; + EntityWrapper m_CurrentCamera = EntityWrapper::Invalid; + + EventRelay m_ESetCamera; + bool OnSetCamera(Events::SetCamera& e); + + void enqueueModel(RenderScene& scene, EntityWrapper entity, const glm::mat4& modelMatrix, const std::string& modelResource, bool wireframe); +}; \ No newline at end of file diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 58993ea1..726fb81d 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -164,7 +164,7 @@ struct ModelJob : RenderJob std::vector SpecularTexture; std::vector IncandescenceTexture; float Shininess = 0.f; - glm::vec4 Color; + glm::vec4 Color = glm::vec4(1.f, 1.f, 1.f, 1.f); const ::Model* Model = nullptr; ::Skeleton* Skeleton = nullptr; std::vector<::Skeleton::AnimationData> Animations; @@ -182,6 +182,7 @@ struct ModelJob : RenderJob glm::vec4 FillColor = glm::vec4(0); float FillPercentage = 0.0; bool IsShielded; + bool Wireframe = false; void CalculateHash() override { Hash = ShaderID << 20 + ModelID << 10 + TextureID; diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index 24f908a9..f59bdc78 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -25,6 +25,7 @@ public: bool StencilMask(GLuint mask); bool DepthMask(GLboolean flag); bool DepthFunc(GLenum func); + bool PolygonMode(GLenum face, GLenum mode); bool AlphaFunc(GLenum func, GLclampf thresholder); private: diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp new file mode 100755 index 00000000..48e3899c --- /dev/null +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -0,0 +1,98 @@ +#include "Editor/EditorRenderSystem.h" + +EditorRenderSystem::EditorRenderSystem(World* world, EventBroker* eventBroker, IRenderer* renderer, RenderFrame* renderFrame) + : System(world, eventBroker) + , m_Renderer(renderer) + , m_RenderFrame(renderFrame) +{ + EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorRenderSystem::OnSetCamera); + auto resolution = renderer->Resolution(); + m_Camera = new Camera((float)resolution.Width / resolution.Height, glm::radians(45.f), 0.01f, 5000.f); +} + +void EditorRenderSystem::Update(double dt) +{ + if (m_CurrentCamera.Valid()) { + m_Camera->SetPosition(Transform::AbsolutePosition(m_CurrentCamera)); + m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera)); + } + + RenderScene scene; + scene.Camera = m_Camera; + + auto cameras = m_World->GetComponents("Camera"); + if (cameras != nullptr) { + for (auto& cCamera : *cameras) { + EntityWrapper entity(m_World, cCamera.EntityID); + glm::mat4 modelMatrix = Transform::ModelMatrix(entity); + enqueueModel(scene, entity, modelMatrix, "Models/Camera.mesh", false); + } + } + + auto aabbs = m_World->GetComponents("AABB"); + if (aabbs != nullptr) { + for (auto& cAABB : *aabbs) { + EntityWrapper entity(m_World, cAABB.EntityID); + glm::vec3 absPosition = Transform::AbsolutePosition(entity) + (glm::vec3)cAABB["Origin"]; + glm::vec3 absScale = Transform::AbsoluteScale(entity) * (glm::vec3)cAABB["Size"]; + glm::mat4 modelMatrix = glm::translate(absPosition) * glm::scale(absScale); + enqueueModel(scene, entity, modelMatrix, "Models/Core/UnitCube.mesh", true); + } + } + + m_RenderFrame->Add(scene); +} + +bool EditorRenderSystem::OnSetCamera(Events::SetCamera& e) +{ + ComponentWrapper cTransform = e.CameraEntity["Transform"]; + ComponentWrapper cCamera = e.CameraEntity["Camera"]; + m_Camera->SetFOV(static_cast((double)cCamera["FOV"])); + m_Camera->SetNearClip(static_cast((double)cCamera["NearClip"])); + m_Camera->SetFarClip(static_cast((double)cCamera["FarClip"])); + m_Camera->SetPosition(cTransform["Position"]); + m_Camera->SetOrientation(glm::quat((const glm::vec3&)cTransform["Orientation"])); + m_CurrentCamera = e.CameraEntity; + return true; +} + +void EditorRenderSystem::enqueueModel(RenderScene& scene, EntityWrapper entity, const glm::mat4& modelMatrix, const std::string& modelResource, bool wireframe) +{ + Model* model; + try { + model = ResourceManager::Load<::Model, true>(modelResource); + } catch (const Resource::StillLoadingException&) { + return; + } catch (const std::exception&) { + try { + model = ResourceManager::Load<::Model>("Models/Core/Error.mesh"); + } catch (const std::exception&) { + return; + } + } + + for (auto matGroup : model->MaterialGroups()) { + std::shared_ptr modelJob = std::make_shared(); + modelJob->Model = model; + modelJob->TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0; + modelJob->DiffuseTexture = matGroup.Texture.get(); + modelJob->NormalTexture = nullptr; + modelJob->SpecularTexture = nullptr; + modelJob->IncandescenceTexture = nullptr; + modelJob->DiffuseColor = matGroup.DiffuseColor; + modelJob->SpecularColor = matGroup.SpecularColor; + modelJob->IncandescenceColor = matGroup.IncandescenceColor; + modelJob->StartIndex = matGroup.StartIndex; + modelJob->EndIndex = matGroup.EndIndex; + modelJob->Matrix = modelMatrix; + modelJob->Entity = entity.ID; + glm::vec3 abspos = Transform::AbsolutePosition(entity); + glm::vec3 worldpos = glm::vec3(m_Camera->ViewMatrix() * glm::vec4(abspos, 1)); + modelJob->Depth = worldpos.z; + modelJob->World = m_World; + modelJob->Wireframe = wireframe; + + scene.OpaqueObjects.push_back(modelJob); + } +} + diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index edadfb4e..6d89ba0c 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -13,7 +13,7 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame m_EditorWorldSystemPipeline = new SystemPipeline(m_EditorWorld, m_EventBroker, IsClient, IsServer); m_EditorWorldSystemPipeline->AddSystem(0); m_EditorWorldSystemPipeline->AddSystem(0, m_Renderer); - m_EditorWorldSystemPipeline->AddSystem(1, m_Renderer, m_RenderFrame); + m_EditorWorldSystemPipeline->AddSystem(2, m_Renderer, m_RenderFrame); m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); m_ActualCamera = m_EditorCamera; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 6cdf42d1..e94b3a89 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -917,6 +917,8 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list(job); if (modelJob) { + RenderState jobState; + //bind forward program m_ForwardPlusProgram->Bind(); glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); @@ -980,6 +982,10 @@ void DrawFinalPass::DrawToDepthStencilBuffer(std::listModel->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 56812f9a..167504c2 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -155,6 +155,20 @@ bool RenderState::AlphaFunc(GLenum func, GLclampf thresholder) return !GLERROR("AlphaFunc"); } +bool RenderState::PolygonMode(GLenum face, GLenum mode) +{ + GLint originalMode[2]; + glGetIntegerv(GL_POLYGON_MODE, &originalMode[0]); + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + m_ResetFunctions.push_back(std::bind(glPolygonMode, GL_FRONT, originalMode[0])); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + m_ResetFunctions.push_back(std::bind(glPolygonMode, GL_BACK, originalMode[1])); + } + glPolygonMode(face, mode); + return !GLERROR("RenderState::PolygonMode"); +} + RenderState::~RenderState() { for (auto& f : boost::adaptors::reverse(m_ResetFunctions)) { diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 5e82dc2e..531a18a0 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -4,6 +4,7 @@ #include "Collision/EntityAABB.h" #include "Collision/TriggerSystem.h" #include "Collision/CollisionSystem.h" +#include "Editor/EditorRenderSystem.h" #include "Systems/RaptorCopterSystem.h" #include "Systems/HealthSystem.h" #include "Systems/PlayerMovementSystem.h" @@ -164,6 +165,7 @@ Game::Game(int argc, char* argv[]) ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling); ++updateOrderLevel; + m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame); m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame, m_OctreeFrustrumCulling); ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame);