diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index 9b7fd487..73aaff5f 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -7,7 +7,6 @@ #include "../Core/ConfigFile.h" #include "../Input/EInputCommand.h" #include "../Rendering/IRenderer.h" -#include "../Rendering/EPicking.h" #include "../Rendering/RenderSystem.h" class EditorSystem : public ImpureSystem @@ -59,8 +58,8 @@ private: bool OnMousePress(const Events::MousePress& e); EventRelay m_EMouseMove; bool OnMouseMove(const Events::MouseMove& e); - EventRelay m_EPicking; - bool OnPicking(const Events::Picking& e); + + void Picking(); void updateWidget(); void setWidgetMode(WidgetMode newMode); diff --git a/include/Engine/Rendering/EPicking.h b/include/Engine/Rendering/EPicking.h deleted file mode 100644 index 85c4b629..00000000 --- a/include/Engine/Rendering/EPicking.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef Events_Picking_h__ -#define Events_Picking_h__ - -#include "../OpenGL.h" -#include "../GLM.h" - -#include "../Core/EventBroker.h" -#include "Util/ScreenCoords.h" -#include "FrameBuffer.h" -#include "../Core/Entity.h" -#include "Util/UnorderedMapVec2.h" - -namespace Events -{ - -/** Thrown Every frame, use functions to pick*/ -struct Picking : Event -{ -public: - Picking(FrameBuffer* pickingBuffer, GLuint* depthBuffer, glm::mat4 projectionMatrix, glm::mat4 viewMatrix, Rectangle resolution, const std::unordered_map* pickingColorsToEntity) - : PickingBuffer(pickingBuffer) - , DepthBuffer(depthBuffer) - , ProjectionMatrix(projectionMatrix) - , ViewMatrix(viewMatrix) - , Resolution(resolution) - , PickingColorsToEntity(pickingColorsToEntity) - { } - - - - struct PickData - { - //Picked Entity - EntityID Entity; - //World position of the "pick" - glm::vec3 Position; - // Depth - float Depth; - }; - - PickData Pick(glm::vec2 screenCoord) const - { - PickData pickData; - - // Invert screen y coordinate - screenCoord.y = Resolution.Height - screenCoord.y; - ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer); - pickData.Depth = data.Depth; - - auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1])); - if (it != PickingColorsToEntity->end()) { - pickData.Entity = it->second; - } else { - pickData.Entity = 0; - } - pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix); - - return pickData; - } - - -private: - FrameBuffer* PickingBuffer; - GLuint* DepthBuffer; - const glm::mat4 ProjectionMatrix; - const glm::mat4 ViewMatrix; - const Rectangle Resolution; - const std::unordered_map* PickingColorsToEntity; - -}; - -} - -#endif diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index 42729479..e4e5c775 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -10,6 +10,13 @@ #include "RenderQueue.h" #include "Model.h" +struct PickData +{ + EntityID Entity; + glm::vec3 Position; //World position + float Depth; +}; + class IRenderer { public: @@ -32,6 +39,7 @@ public: virtual void Initialize() = 0; virtual void Update(double dt) = 0; virtual void Draw(RenderFrame& rq) = 0; + virtual PickData Pick(glm::vec2 screenCord) = 0; protected: Rectangle m_Resolution = Rectangle(1280, 720); diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index eaca4b04..08a06b0e 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -7,7 +7,8 @@ #include "ShaderProgram.h" #include "Util/UnorderedMapVec2.h" #include "../Core/EventBroker.h" -#include "EPicking.h" + + class PickingPass { @@ -28,6 +29,8 @@ public: GLuint DepthBuffer() const { return m_DepthBuffer; } const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; } + + PickData Pick(glm::vec2 screenCoord); private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 01e9024a..4ffb55f2 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -12,11 +12,8 @@ #include "RenderJob.h" #include "ModelJob.h" -class Model; -class Skeleton; -class Texture; -//TODO: Render: Remove obsolete RenderJobs and fix standard values on variables. + /* @@ -88,7 +85,7 @@ struct RenderScene ::Camera* Camera; std::list> ForwardJobs; std::list> LightJobs; - + Rectangle ViewPort; void Clear() { @@ -125,8 +122,7 @@ public: } std::list> RenderScenes; - - + private: int m_Size = 0; }; diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index e322d51e..2fa7b6f5 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -12,12 +12,12 @@ #include "../Input/EInputCommand.h" #include "Camera.h" #include "ModelJob.h" - +#include "Renderer.h" class RenderSystem : public ImpureSystem { public: - RenderSystem(EventBroker* eventBrokerer, RenderFrame* renderFrame); + RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame); virtual void Update(World* world, double dt) override; @@ -29,6 +29,7 @@ public: private: World* m_World = nullptr; + const IRenderer* m_Renderer = nullptr; RenderFrame* m_RenderFrame; bool m_SwitchCamera = false; @@ -44,6 +45,7 @@ private: void SwitchCamera(EntityID entity); void Initialize(); + void UpdateCamera(World* world, double dt); void UpdateProjectionMatrix(ComponentWrapper& cameraComponent); glm::mat4 m_ViewMatrix; glm::mat4 m_ProjectionMatrix; diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index d89fc4d2..b5a5c1b5 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -13,7 +13,6 @@ #include "PickingPass.h" #include "DrawScenePass.h" #include "../Core/EventBroker.h" -#include "EPicking.h" #include "ImGuiRenderPass.h" #include "Camera.h" @@ -29,6 +28,8 @@ public: virtual void Update(double dt) override; virtual void Draw(RenderFrame& rf) override; + virtual PickData Pick(glm::vec2 screenCoord) override; + private: //----------------------Variables----------------------// EventBroker* m_EventBroker; diff --git a/resources/Schema/Components/Camera.xml b/resources/Schema/Components/Camera.xml index 8a93dec5..92225dde 100644 --- a/resources/Schema/Components/Camera.xml +++ b/resources/Schema/Components/Camera.xml @@ -1,6 +1,5 @@ cam - 1.77 60.0 0.01 5000 diff --git a/resources/Schema/Components/Camera.xsd b/resources/Schema/Components/Camera.xsd index 3c462a3b..4f02deb0 100644 --- a/resources/Schema/Components/Camera.xsd +++ b/resources/Schema/Components/Camera.xsd @@ -10,7 +10,6 @@ - diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 87b8642b..405b70aa 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -18,7 +18,6 @@ EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer) EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress); EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorSystem::OnMouseRelease); EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &EditorSystem::OnMouseMove); - EVENT_SUBSCRIBE_MEMBER(m_EPicking, &EditorSystem::OnPicking); } void EditorSystem::Update(World* world, double dt) @@ -32,7 +31,7 @@ void EditorSystem::Update(World* world, double dt) if (!m_Visible) { return; } - + Picking(); updateWidget(); drawUI(world, dt); @@ -177,10 +176,10 @@ bool EditorSystem::OnMouseRelease(const Events::MouseRelease& e) return true; } -bool EditorSystem::OnPicking(const Events::Picking& e) +void EditorSystem::Picking() { for (auto& pos : m_PickingQueue) { - auto result = e.Pick(pos); + auto result = m_Renderer->Pick(pos); EntityID entity = result.Entity; if (glm::length2(m_WidgetCurrentAxis) > 0.f) { } else { @@ -209,7 +208,6 @@ bool EditorSystem::OnPicking(const Events::Picking& e) } } m_PickingQueue.clear(); - return true; }; diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp index 5da2c0c6..eb585aff 100644 --- a/src/Engine/Rendering/DrawScenePass.cpp +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -21,8 +21,6 @@ void DrawScenePass::InitializeShaderPrograms() m_BasicForwardProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/BasicForward.frag.glsl"))); m_BasicForwardProgram->Compile(); m_BasicForwardProgram->Link(); - - } void DrawScenePass::Draw(RenderFrame& rf) diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index a09f328e..9fbdaf8a 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -59,7 +59,7 @@ void PickingPass::Draw(RenderFrame& rf) for(auto scene : rf.RenderScenes) { - m_Camera = scene->Camera; + m_Camera = scene->Camera; for (auto &job : scene->ForwardJobs) { auto modelJob = std::dynamic_pointer_cast(job); @@ -94,25 +94,36 @@ void PickingPass::Draw(RenderFrame& rf) m_PickingBuffer.Unbind(); GLERROR("PickingPass Error"); - //Publish pick event every frame with the pick data that can be picked by the event - int fbWidth; - int fbHeight; - glfwGetFramebufferSize(m_Renderer->Window(), &fbWidth, &fbHeight); - Events::Picking pickEvent = Events::Picking( - &m_PickingBuffer, - &m_DepthBuffer, - m_Camera->ProjectionMatrix(), - m_Camera->ViewMatrix(), - Rectangle(fbWidth, fbHeight), - &m_PickingColorsToEntity); - - m_EventBroker->Publish(pickEvent); delete state; } +PickData PickingPass::Pick(glm::vec2 screenCoord) +{ + int fbWidth; + int fbHeight; + glfwGetFramebufferSize(m_Renderer->Window(), &fbWidth, &fbHeight); + + Rectangle resolution = Rectangle(fbWidth, fbHeight); + PickData pickData; + // Invert screen y coordinate + screenCoord.y = resolution.Height - screenCoord.y; + ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, &m_PickingBuffer, m_DepthBuffer); + pickData.Depth = data.Depth; + + auto it = m_PickingColorsToEntity.find(glm::vec2(data.Color[0], data.Color[1])); + if (it != m_PickingColorsToEntity.end()) { + pickData.Entity = it->second; + } else { + pickData.Entity = 0; + } + pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, resolution, m_Camera->ProjectionMatrix(), m_Camera->ViewMatrix()); + + return pickData; +} + void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const { //TODO: Renderer: Make this in a sparate class diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 8e5f2a34..b9d63552 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -1,15 +1,15 @@ #include "Rendering/RenderSystem.h" #include "Rendering/DebugCameraInputController.h" -RenderSystem::RenderSystem(EventBroker* eventBrokerer, RenderFrame* renderFrame) - :ImpureSystem(eventBrokerer) +RenderSystem::RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame) :ImpureSystem(eventBrokerer) { + m_Renderer = renderer; m_RenderFrame = renderFrame; Initialize(); EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); - m_DefaultCamera = new Camera(1.77f /* should be based on width and height */, glm::radians(45.f), 0.01f, 5000.f); + m_DefaultCamera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10)); if (m_Camera == nullptr) { m_Camera = m_DefaultCamera; @@ -28,7 +28,6 @@ bool RenderSystem::OnSetCamera(const Events::SetCamera &event) } } } - return true; } @@ -42,11 +41,9 @@ void RenderSystem::SwitchCamera(EntityID entity) if (m_World->HasComponent(entity, "Model")) { m_World->GetComponent(entity, "Model")["Visible"] = false; } - m_CurrentCamera = entity; m_SwitchCamera = false; - LOG_INFO("Switched to %s", m_World->GetComponent(m_CurrentCamera, "Camera")["Name"]); } else { LOG_ERROR("Entity %i does not have a CameraComponent", entity); m_SwitchCamera = false; @@ -61,7 +58,7 @@ void RenderSystem::Initialize() void RenderSystem::UpdateProjectionMatrix(ComponentWrapper& cameraComponent) { double fov = cameraComponent["FOV"]; - double aspectRatio = cameraComponent["AspectRatio"]; + double aspectRatio = m_Renderer->Resolution().Width / m_Renderer->Resolution().Height; double nearClip = cameraComponent["NearClip"]; double farClip = cameraComponent["FarClip"]; @@ -146,22 +143,18 @@ void RenderSystem::FillModels(std::list>& jobs) continue; } - Model* model = ResourceManager::Load<::Model>(resource); if (model == nullptr) { model = ResourceManager::Load<::Model>("Models/Core/Error.obj"); } - glm::mat4 modelMatrix = ModelMatrix(modelComponent.EntityID); glm::mat4 matrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix() * (model->m_Matrix * modelMatrix); + for (auto texGroup : model->TextureGroups) { std::shared_ptr modelJob = std::shared_ptr(new ModelJob(model, m_Camera, matrix, texGroup, modelComponent)); jobs.push_back(modelJob); } - - - } } @@ -178,8 +171,21 @@ bool RenderSystem::OnInputCommand(const Events::InputCommand& e) void RenderSystem::Update(World* world, double dt) { m_World = world; - m_EventBroker->Process(); + + UpdateCamera(world, dt); + + m_RenderFrame->Clear(); + RenderScene* rs = new RenderScene(); + rs->Camera = m_Camera; + rs->ViewPort = Rectangle(1280, 720); + FillModels(rs->ForwardJobs); + m_RenderFrame->Add(*rs); + delete rs; +} + +void RenderSystem::UpdateCamera(World* world, double dt) +{ static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); if (m_SwitchCamera) { @@ -199,17 +205,17 @@ void RenderSystem::Update(World* world, double dt) } ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); - + firstPersonInputController.SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); firstPersonInputController.SetPosition(cameraTransform["Position"]); } } - - if(world->HasComponent(m_CurrentCamera, "Camera") && world->HasComponent(m_CurrentCamera, "Transform")) { + + if (world->HasComponent(m_CurrentCamera, "Camera") && world->HasComponent(m_CurrentCamera, "Transform")) { ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); - if(world->GetParent(m_CurrentCamera) == 1) { // world is entity 1, is this ok? + if (world->GetParent(m_CurrentCamera) == 1) { // world is entity 1, is this ok? firstPersonInputController.Update(dt); (glm::vec3&)cameraTransform["Orientation"] = glm::eulerAngles(firstPersonInputController.Orientation()); (glm::vec3&)cameraTransform["Position"] = firstPersonInputController.Position(); @@ -217,7 +223,7 @@ void RenderSystem::Update(World* world, double dt) glm::vec3 position = AbsolutePosition(world, m_CurrentCamera); glm::quat orientation = AbsoluteOrientation(world, m_CurrentCamera); - + m_Camera->SetPosition(position); m_Camera->SetOrientation(orientation); @@ -233,11 +239,5 @@ void RenderSystem::Update(World* world, double dt) world->GetComponent(m_CurrentCamera, "Model")["Visible"] = false; } } - - m_RenderFrame->Clear(); - RenderScene* rs = new RenderScene(); - rs->Camera = m_Camera; - FillModels(rs->ForwardJobs); - m_RenderFrame->Add(*rs); - delete rs; } + diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 9a7bfd07..c7aadd83 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -103,6 +103,11 @@ void Renderer::Draw(RenderFrame& rf) glfwSwapBuffers(m_Window); } +PickData Renderer::Pick(glm::vec2 screenCoord) +{ + return m_PickingPass->Pick(screenCoord); +} + void Renderer::DrawScreenQuad(GLuint textureToDraw) { glBindFramebuffer(GL_FRAMEBUFFER, 0); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index c104a3ad..ab50c7b0 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -54,7 +54,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(m_Renderer); - m_SystemPipeline->AddSystem(m_RenderFrame); + m_SystemPipeline->AddSystem(m_Renderer, m_RenderFrame); m_LastTime = glfwGetTime();