From 1d500eb4f65f2bf82b4ba5c718d72a70894a0a5e Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 22 Sep 2015 14:39:08 +0200 Subject: [PATCH] First iteration of GUI code. GUI is rendered on top of everything, world still separate. --- include/Core/Engine.h | 23 ++-- include/Core/RenderQueue.h | 25 +++- include/Core/Renderer.h | 1 + include/Core/Util/Rectangle.h | 3 +- include/GUI/Frame.h | 247 ++++++++++++++++++++++++++++++++++ include/GUI/GameFrame.h | 98 ++++++++++++++ include/GUI/TextureFrame.h | 88 ++++++++++++ include/GUI/Viewport.h | 81 +++++++++++ include/GUI/WorldFrame.h | 241 +++++++++++++++++++++++++++++++++ src/game/CMakeLists.txt | 13 +- src/game/CMakeLists.txt.game | 38 ------ src/game/Core/Renderer.cpp | 51 ++++++- 12 files changed, 855 insertions(+), 54 deletions(-) create mode 100644 include/GUI/Frame.h create mode 100644 include/GUI/GameFrame.h create mode 100644 include/GUI/TextureFrame.h create mode 100644 include/GUI/Viewport.h create mode 100644 include/GUI/WorldFrame.h delete mode 100644 src/game/CMakeLists.txt.game diff --git a/include/Core/Engine.h b/include/Core/Engine.h index a45467f..363191d 100644 --- a/include/Core/Engine.h +++ b/include/Core/Engine.h @@ -52,6 +52,8 @@ #include "Physics/CBoxShape.h" #include "Physics/ESetImpulse.h" +#include "GUI/Frame.h" +#include "GUI/TextureFrame.h" namespace dd { @@ -68,6 +70,16 @@ public: m_Renderer->SetResolution(Rectangle(0, 0, 675, 1080)); m_Renderer->Initialize(); + m_FrameStack = new GUI::Frame(m_EventBroker.get()); + m_FrameStack->Width = 1920; + m_FrameStack->Height = 1080; + { + auto button = new GUI::TextureFrame(m_FrameStack, "SuperButt"); + button->SetTexture("Textures/Test/TestBrick_Diffuse.png"); + button->Width = 100; + button->Height = 25; + } + m_InputManager = std::make_shared(m_Renderer->Window(), m_EventBroker); m_World = std::make_shared(m_EventBroker); @@ -250,13 +262,6 @@ public: // if (glfwGetKey(m_Renderer->Window(), GLFW_KEY_R)) { // ResourceManager::Reload("Shaders/Deferred/3/Fragment.glsl"); // } -// - //TODO Fill up the renderQueue with models (Temp fix) -// TEMPAddToRenderQueue(); - - // Render scene - //TODO send renderqueue to draw. -// m_Renderer->Draw(m_RendererQueue); if (glfwGetKey(m_Renderer->Window(), GLFW_KEY_R)) { ResourceManager::Reload("Shaders/Deferred/3/Fragment.glsl"); @@ -264,6 +269,7 @@ public: //TODO Fill up the renderQueue with models (Temp fix) TEMPAddToRenderQueue(); + m_FrameStack->DrawLayered(m_RendererQueue); // Render scene //TODO send renderqueue to draw. @@ -374,7 +380,6 @@ public: job.EndIndex = texGroup.EndIndex; job.ModelMatrix = modelMatrix; job.Color = color; - job.fileName = fileName; m_RendererQueue.Deferred.Add(job); } @@ -409,8 +414,8 @@ public: } private: - std::shared_ptr m_ResourceManager; std::shared_ptr m_EventBroker; + GUI::Frame* m_FrameStack = nullptr; std::shared_ptr m_Renderer; RenderQueueCollection m_RendererQueue; std::shared_ptr m_InputManager; diff --git a/include/Core/RenderQueue.h b/include/Core/RenderQueue.h index 9984770..4985a2a 100755 --- a/include/Core/RenderQueue.h +++ b/include/Core/RenderQueue.h @@ -22,8 +22,9 @@ #include #include -#include "Texture.h" -#include "Model.h" +#include "Core/Util/Rectangle.h" +#include "Core/Texture.h" +#include "Core/Model.h" namespace dd { @@ -52,8 +53,8 @@ struct ModelJob : RenderJob unsigned int ShaderID; unsigned int TextureID; - std::string fileName; - + glm::mat4 ProjectionMatrix; + glm::mat4 ViewMatrix; glm::mat4 ModelMatrix; GLuint DiffuseTexture; GLuint NormalTexture; @@ -90,6 +91,8 @@ struct SpriteJob : RenderJob unsigned int ShaderID; unsigned int TextureID; + glm::mat4 ProjectionMatrix; + glm::mat4 ViewMatrix; glm::mat4 ModelMatrix; GLuint DiffuseTexture; GLuint NormalTexture; @@ -115,6 +118,17 @@ struct PointLightJob : RenderJob } }; +struct FrameJob : SpriteJob +{ + Rectangle Scissor; + Rectangle Viewport; + + void CalculateHash() override + { + Hash = 0; + } +}; + class RenderQueue { public: @@ -153,12 +167,14 @@ struct RenderQueueCollection RenderQueue Deferred; RenderQueue Forward; RenderQueue Lights; + RenderQueue GUI; void Clear() { Deferred.Clear(); Forward.Clear(); Lights.Clear(); + GUI.Clear(); } void Sort() @@ -166,6 +182,7 @@ struct RenderQueueCollection Deferred.Sort(); Forward.Sort(); Lights.Sort(); + GUI.Sort(); } }; diff --git a/include/Core/Renderer.h b/include/Core/Renderer.h index 1b8e078..c4d0068 100755 --- a/include/Core/Renderer.h +++ b/include/Core/Renderer.h @@ -101,6 +101,7 @@ private: void DrawForward(RenderQueue &objects, RenderQueue &lights); void DrawScene(RenderQueue &objects, ShaderProgram &program); void DrawLightSpheres(RenderQueue &lights); + void DrawGUI(RenderQueue& rq); void DebugKeys(); }; diff --git a/include/Core/Util/Rectangle.h b/include/Core/Util/Rectangle.h index 6ce0695..27af291 100644 --- a/include/Core/Util/Rectangle.h +++ b/include/Core/Util/Rectangle.h @@ -66,7 +66,8 @@ struct Rectangle Height = bottom - Y; } - Rectangle& operator+=(const Rectangle &rhs) { + Rectangle& operator+=(const Rectangle &rhs) + { SetLeft(std::min(Left(), rhs.Left())); SetRight(std::max(Right(), rhs.Right())); SetTop(std::min(Top(), rhs.Top())); diff --git a/include/GUI/Frame.h b/include/GUI/Frame.h new file mode 100644 index 0000000..5015725 --- /dev/null +++ b/include/GUI/Frame.h @@ -0,0 +1,247 @@ +#ifndef GUI_Frame_h__ +#define GUI_Frame_h__ + +#include +#include + +#include "Core/Util/Rectangle.h" +#include "Core/EventBroker.h" +#include "Core/EKeyDown.h" +#include "Core/EKeyUp.h" +#include "Core/ResourceManager.h" +#include "Core/Renderer.h" +#include "Core/RenderQueue.h" +#include "Core/Texture.h" +#include "Input/EInputCommand.h" + +namespace dd +{ +namespace GUI +{ + +class Frame : public Rectangle +{ +public: + enum class Anchor + { + Left, + Right, + Top, + Bottom + }; + + static const int BaseWidth = 1280; + static const int BaseHeight = 720; + + // Set up a base frame with an event broker + Frame(dd::EventBroker* eventBroker) + : EventBroker(eventBroker) + , Rectangle() + { Initialize(); } + + // Create a frame as a child + Frame(Frame* parent, std::string name) + : m_Name(name) + { + SetParent(parent); + Initialize(); + } + + ~Frame() + { + /*for (auto layer : m_Children) + { + for (auto child : layer.second) + { + delete child.second; + } + } + + if (m_Parent) + { + m_Parent->RemoveChild(this); + }*/ + } + + Frame* Parent() const { return m_Parent; } + + void SetParent(Frame* parent) + { + if (parent == nullptr) { + LOG_ERROR("Failed to parent frame \"%s\": Invalid parent", m_Name.c_str()); + return; + } + + Width = parent->Width; + Height = parent->Height; + m_Layer = parent->Layer() + 1; + parent->AddChild(this); + m_Parent = parent; + EventBroker = parent->EventBroker; + } + + void AddChild(Frame* child) + { + m_Children[child->m_Layer].insert(std::make_pair(child->Name(), child)); + if (m_Parent) { + m_Parent->AddChild(child); + } + } + + void RemoveChild(Frame* child) + { + auto it = m_Children.find(child->m_Layer); + if (it != m_Children.end()) { + m_Children.erase(it); + } + + if (m_Parent) { + m_Parent->RemoveChild(child); + } + } + + std::string Name() const { return m_Name; } + void SetName(std::string val) { m_Name = val; } + + int Layer() const { return m_Layer; } + + bool Hidden() const + { + if (m_Parent) + return m_Parent->Hidden() || m_Hidden; + else + return m_Hidden; + } + bool Visible() const + { + return !Hidden(); + } + + virtual void Hide() { m_Hidden = true; } + virtual void Show() { m_Hidden = false; } + + int Left() const override + { + if (m_Parent) + return m_Parent->Left() + X; + else + return X; + } + int Right() const override + { + if (m_Parent) + return std::min(m_Parent->Right(), Left() + Width); + else + return Left() + Width; + } + int Top() const override + { + if (m_Parent) + return m_Parent->Top() + Y; + else + return Y; + } + int Bottom() const override + { + if (m_Parent) + return std::min(m_Parent->Bottom(), Top() + Height); + else + return Top() + Height; + } + + glm::vec2 Scale() + { + if (m_Parent) + return m_Parent->Scale(); + else + return glm::vec2(Width, Height) / glm::vec2(BaseWidth, BaseHeight); + } + + Rectangle AbsoluteRectangle() + { + int left = Left(); + if (m_Parent) + left = std::max(left, m_Parent->Left()); + int top = Top(); + if (m_Parent) + top = std::max(top, m_Parent->Top()); + int width = Right() - left; + int height = Bottom() - top; + return Rectangle(left, top, width, height); + } + + void UpdateLayered(double dt) + { + // Update ourselves + this->Update(dt); + + // Update children + for (auto& pairLayer : m_Children) { + auto children = pairLayer.second; + for (auto& pairChild : children) { + auto child = pairChild.second; + child->Update(dt); + } + } + } + + virtual void Update(double dt) { } + + void DrawLayered(RenderQueueCollection& rq) + { + if (this->Hidden()) + return; + + // Draw ourselves + this->Draw(rq); + + // Draw children + for (auto& pairLayer : m_Children) { + auto children = pairLayer.second; + for (auto& pairChild : children) { + auto child = pairChild.second; + if (child->Hidden()) + continue; + child->Draw(rq); + } + } + } + + virtual void Draw(RenderQueueCollection& rq) { } + +protected: + dd::EventBroker* EventBroker; + + std::string m_Name = "UIParent"; + int m_Layer = 0; + bool m_Hidden = false; + + Frame* m_Parent = nullptr; + typedef std::multimap Children_t; // name -> frame + std::map m_Children; // layer -> Children_t + + virtual bool OnKeyDown(const Events::KeyDown& event) { return false; } + + virtual bool OnKeyUp(const Events::KeyUp& event) { return false; } + + //virtual bool OnMouseDown(const Events::KeyDown &event) { } + //virtual bool OnMouseUp(const Events::KeyDown &event) { } + virtual bool OnCommand(const Events::InputCommand& event) { return false; } + +private: + EventRelay m_EKeyDown; + EventRelay m_EKeyUp; + EventRelay m_EInputCommand; + + void Initialize() + { + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Frame::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Frame::OnKeyUp); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Frame::OnCommand); + } +}; + +} +} + +#endif // GUI_Frame_h__ diff --git a/include/GUI/GameFrame.h b/include/GUI/GameFrame.h new file mode 100644 index 0000000..491163c --- /dev/null +++ b/include/GUI/GameFrame.h @@ -0,0 +1,98 @@ +#ifndef GUI_GameFrame_h__ +#define GUI_GameFrame_h__ + +#include "GUI/Frame.h" +#include "GUI/MainMenuFrame.h" +#include "GUI/WorldFrame.h" +#include "GUI/Viewport.h" +#include "GUI/TextureFrame.h" +#include "GUI/PlayerHUD.h" + +#include "GameWorld.h" +#include "Events/GameStart.h" +#include "Events/GameOver.h" +#include "Events/Dead.h" + +namespace dd +{ +namespace GUI +{ + +class GameFrame : public Frame +{ +public: + GameFrame(Frame* parent, std::string name) + : Frame(parent, name) + , m_GameOver(false) + { + EVENT_SUBSCRIBE_MEMBER(m_EGameStart, &GUI::GameFrame::OnGameStart); + EVENT_SUBSCRIBE_MEMBER(m_EGameOver, &GUI::GameFrame::OnGameOver); + + m_World = std::make_shared(EventBroker, ResourceManager); + m_WorldFrame = new WorldFrame(this, "GameWorldFrame", m_World); + { + vp1 = new Viewport(m_WorldFrame, "Viewport1", m_World); + vp1->X = 0; + vp1->Width = this->Width / 2.f; + new PlayerHUD(vp1, "PlayerHUD", m_World, 1); + + vp2 = new Viewport(m_WorldFrame, "Viewport2", m_World); + vp2->X = vp1->Right(); + vp2->Width = this->Width / 2.f; + new PlayerHUD(vp2, "PlayerHUD", m_World, 2); + + m_FreeCamViewport = new Viewport(m_WorldFrame, "ViewportFreeCam", m_World); + m_FreeCamViewport->Hide(); + } + m_WorldFrame->Hide(); + m_World->Initialize(); + + m_MainMenuFrame = new MainMenuFrame(this, "MainMenu"); + } + +private: + EventRelay m_EGameStart; + + bool OnGameStart(const Events::GameStart& event) + { + m_WorldFrame->Show(); + + return true; + } + + EventRelay m_EGameOver; + + bool OnGameOver(const Events::GameOver& event) + { + m_GameOver = true; + + return true; + } + + std::shared_ptr m_World; + + MainMenuFrame* m_MainMenuFrame; + WorldFrame* m_WorldFrame; + Viewport* vp1; + Viewport* vp2; + Viewport* m_FreeCamViewport; + + bool m_GameOver; + + bool OnKeyUp(const Events::KeyUp& event) override + { + if (event.KeyCode == GLFW_KEY_1) { + if (m_FreeCamViewport->Hidden()) + m_FreeCamViewport->Show(); + else + m_FreeCamViewport->Hide(); + } + + return true; + } +}; + +} +} + +#endif // GUI_GameFrame_h__ diff --git a/include/GUI/TextureFrame.h b/include/GUI/TextureFrame.h new file mode 100644 index 0000000..e177f5e --- /dev/null +++ b/include/GUI/TextureFrame.h @@ -0,0 +1,88 @@ +#ifndef GUI_TextureFrame_h__ +#define GUI_TextureFrame_h__ + +#include "GUI/Frame.h" +#include "Core/Texture.h" + +namespace dd +{ +namespace GUI +{ + +class TextureFrame : public Frame +{ +public: + TextureFrame(Frame* parent, std::string name) + : Frame(parent, name) { } + + void Draw(RenderQueueCollection& rq) override + { + if (m_Texture == nullptr) + return; + + // Main texture + { + FrameJob job; + job.Scissor = m_Parent->AbsoluteRectangle(); + job.Viewport = Rectangle(Left(), Top(), Width, Height); + job.TextureID = m_Texture->ResourceID; + job.DiffuseTexture = *m_Texture; + job.Color = glm::vec4(m_Color.r, m_Color.g, m_Color.b, m_Color.a * m_CurrentFade); + rq.GUI.Add(job); + } + + // Texture while fading + if (m_FadeTexture && m_CurrentFade < 1) { + FrameJob job; + job.Scissor = m_Parent->AbsoluteRectangle(); + job.Viewport = Rectangle(Left(), Top(), Width, Height); + job.TextureID = m_FadeTexture->ResourceID; + job.DiffuseTexture = *m_FadeTexture; + job.Color = glm::vec4(m_Color.r, m_Color.g, m_Color.b, m_Color.a); + rq.GUI.Add(job); + } + } + + dd::Texture* Texture() const { return m_Texture; } + + void SetTexture(std::string resourceName) + { + m_Texture = ResourceManager::Load(resourceName); + } + + void FadeToTexture(std::string resourceName, double duration) + { + m_FadeTexture = m_Texture; + SetTexture(resourceName); + m_FadeDuration = duration; + m_CurrentFade = 0.f; + } + + void Update(double dt) override + { + if (m_CurrentFade < 1) { + m_CurrentFade += dt / m_FadeDuration; + if (m_CurrentFade > 1) { + m_FadeTexture = nullptr; + m_CurrentFade = 1; + m_FadeDuration = 0; + } + } + } + + glm::vec4 Color() const { return m_Color; } + void SetColor(glm::vec4 val) { m_Color = val; } + +protected: + dd::Texture* m_Texture = nullptr; + dd::Texture* m_FadeTexture = nullptr; + glm::vec4 m_Color = glm::vec4(1.f, 1.f, 1.f, 1.f); + float m_FadeDuration = 0.f; + float m_CurrentFade = 1.f; + +}; + +} +} + +#endif // GUI_TextureFrame_h__ diff --git a/include/GUI/Viewport.h b/include/GUI/Viewport.h new file mode 100644 index 0000000..40d54e5 --- /dev/null +++ b/include/GUI/Viewport.h @@ -0,0 +1,81 @@ +#ifndef GUI_Viewport_h__ +#define GUI_Viewport_h__ + +#include + +#include "GUI/Frame.h" +#include "World.h" +#include "Systems/TransformSystem.h" +#include "Components/Transform.h" +#include "Components/Camera.h" +#include "RenderQueue.h" +#include "Camera.h" + +namespace GUI +{ + +class Viewport : public Frame +{ +public: + Viewport(Frame* parent, std::string name, std::shared_ptr world) + : Frame(parent, name) + , m_World(world) + { } + + EntityID CameraEntity() const { return m_CameraEntity; } + void SetCameraEntity(EntityID cameraEntity) + { + m_CameraEntity = cameraEntity; + auto transformComponent = m_World->GetComponent(cameraEntity); + if (!transformComponent) + return; + auto cameraComponent = m_World->GetComponent(cameraEntity); + if (!cameraComponent) + return; + + m_Camera = std::make_shared(cameraComponent->FOV, cameraComponent->NearClip, cameraComponent->FarClip); + } + + + void Update(double dt) override + { + if (!m_TransformSystem) + m_TransformSystem = m_World->GetSystem(); + + auto transformComponent = m_World->GetComponent(m_CameraEntity); + if (!transformComponent) + return; + + auto cameraComponent = m_World->GetComponent(m_CameraEntity); + if (!cameraComponent) + return; + + Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(m_CameraEntity); + + m_Camera->SetFOV(cameraComponent->FOV); + m_Camera->SetNearClip(cameraComponent->NearClip); + m_Camera->SetFarClip(cameraComponent->FarClip); + m_Camera->SetPosition(absoluteTransform.Position); + m_Camera->SetOrientation(absoluteTransform.Orientation); + } + + void Draw(std::shared_ptr renderer) override + { + if (!m_Camera) + return; + + renderer->SetCamera(m_Camera); + renderer->SetViewport(AbsoluteRectangle()); + renderer->DrawWorld(m_Parent->RenderQueue); + } + +private: + std::shared_ptr m_World; + std::shared_ptr m_TransformSystem; + std::shared_ptr m_Camera; + EntityID m_CameraEntity; +}; + +} + +#endif // GUI_Viewport_h__ diff --git a/include/GUI/WorldFrame.h b/include/GUI/WorldFrame.h new file mode 100644 index 0000000..f0bc62e --- /dev/null +++ b/include/GUI/WorldFrame.h @@ -0,0 +1,241 @@ +#ifndef GUI_WorldFrame_h__ +#define GUI_WorldFrame_h__ + +#include "GUI/Frame.h" +#include "GUI/Viewport.h" +#include "RenderQueue.h" +#include "World.h" +#include "Systems/TransformSystem.h" +#include "Events/SetViewportCamera.h" +#include "Components/Transform.h" +#include "Components/Model.h" +#include "Components/Sprite.h" +#include "Components/PointLight.h" +#include "Components/BlendMap.h" + + +namespace GUI +{ + +class WorldFrame : public Frame +{ +public: + WorldFrame(Frame* parent, std::string name, std::shared_ptr world) + : Frame(parent, name) + , m_World(world) + { + EVENT_SUBSCRIBE_MEMBER(m_ESetViewportCamera, &WorldFrame::OnSetViewportCamera); + } + + void Update(double dt) override + { + if (!m_TransformSystem) + m_TransformSystem = m_World->GetSystem(); + + m_World->Update(dt); + } + + void Draw(std::shared_ptr renderer) override + { + RenderQueue.Clear(); + renderer->ClearPointLights(); + + for (auto &pair : *m_World->GetEntities()) + { + EntityID entity = pair.first; + + auto templateComponent = m_World->GetComponent(entity); + if (templateComponent) + continue; + + auto transform = m_World->GetComponent(entity); + if (!transform) + continue; + + auto modelComponent = m_World->GetComponent(entity); + if (modelComponent) + { + Model* modelAsset = nullptr; + if (modelComponent->AverageNormals) + { + modelAsset = ResourceManager->Load("AveragedModel", modelComponent->ModelFile); + } + else + { + modelAsset = ResourceManager->Load("Model", modelComponent->ModelFile); + } + + + if (modelAsset) + { + Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity); + glm::mat4 modelMatrix = glm::translate(glm::mat4(), absoluteTransform.Position) + * glm::toMat4(absoluteTransform.Orientation) + * glm::scale(absoluteTransform.Scale); + auto blendmapComponent = m_World->GetComponent(entity); + if (blendmapComponent) + { + BlendMapTexture RedTexture; + RedTexture.Diffuse = *ResourceManager->Load("Texture", blendmapComponent->TextureRed); + RedTexture.Normal = *ResourceManager->Load("Texture", blendmapComponent->TextureRedNormal); + RedTexture.Specular = *ResourceManager->Load("Texture", blendmapComponent->TextureRedSpecular); + + BlendMapTexture GreenTexture; + GreenTexture.Diffuse = *ResourceManager->Load("Texture", blendmapComponent->TextureGreen); + GreenTexture.Normal = *ResourceManager->Load("Texture", blendmapComponent->TextureGreenNormal); + GreenTexture.Specular = *ResourceManager->Load("Texture", blendmapComponent->TextureGreenSpecular); + + BlendMapTexture BlueTexture; + BlueTexture.Diffuse = *ResourceManager->Load("Texture", blendmapComponent->TextureBlue); + BlueTexture.Normal = *ResourceManager->Load("Texture", blendmapComponent->TextureBlueNormal); + BlueTexture.Specular = *ResourceManager->Load("Texture", blendmapComponent->TextureBlueSpecular); + + float textureRepeat = blendmapComponent->TextureRepeats; + + EnqueueBlendMapModel(modelAsset, RedTexture, GreenTexture, BlueTexture, textureRepeat, modelMatrix, modelComponent->Color); + } + else + { + EnqueueModel(modelAsset, modelMatrix, modelComponent->Transparent, modelComponent->Color); + } + + } + } + + auto spriteComponent = m_World->GetComponent(entity); + if (spriteComponent) + { + auto textureAsset = ResourceManager->Load("Texture", spriteComponent->SpriteFile); + if (textureAsset) + { + Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity); + glm::quat orientation2D = glm::angleAxis(glm::eulerAngles(absoluteTransform.Orientation).z, glm::vec3(0, 0, -1)); + glm::mat4 modelMatrix = glm::translate(absoluteTransform.Position) + * glm::toMat4(orientation2D) + * glm::scale(absoluteTransform.Scale); + EnqueueSprite(textureAsset, modelMatrix, spriteComponent->Color); + } + } + + auto pointLightComponent = m_World->GetComponent(entity); + if (pointLightComponent) + { + glm::vec3 position = m_TransformSystem->AbsolutePosition(entity); + renderer->AddPointLightToDraw( + position, + pointLightComponent->Specular, + pointLightComponent->Diffuse, + pointLightComponent->specularExponent, + pointLightComponent->ConstantAttenuation, + pointLightComponent->LinearAttenuation, + pointLightComponent->QuadraticAttenuation, + pointLightComponent->Radius + ); + } + } + + RenderQueue.Sort(); + } + +protected: + std::shared_ptr m_World; + +private: + struct BlendMapTexture + { + GLuint Diffuse; + GLuint Normal; + GLuint Specular; + }; + + EventRelay m_ESetViewportCamera; + bool OnSetViewportCamera(const Events::SetViewportCamera &event) + { + // Search next layer for viewports and update cameras + auto itpair = m_Children[m_Layer + 1].equal_range(event.ViewportFrame); + for (auto it = itpair.first; it != itpair.second; ++it) + { + auto viewportFrame = dynamic_cast(it->second); + if (!viewportFrame) + continue; + + viewportFrame->SetCameraEntity(event.CameraEntity); + } + + return true; + } + + std::shared_ptr m_TransformSystem; + + void EnqueueModel(Model* model, glm::mat4 modelMatrix, float transparent, glm::vec4 color) + { + for (auto texGroup : model->TextureGroups) + { + ModelJob job; + job.TextureID = texGroup.Texture->ResourceID; + job.DiffuseTexture = *texGroup.Texture; + job.NormalTexture = (texGroup.NormalMap) ? *texGroup.NormalMap : 0; + job.SpecularTexture = (texGroup.SpecularMap) ? *texGroup.SpecularMap : 0; + job.VAO = model->VAO; + job.StartIndex = texGroup.StartIndex; + job.EndIndex = texGroup.EndIndex; + job.ModelMatrix = modelMatrix; + job.Transparent = transparent; + job.Color = color; + + if(job.Transparent) + { + RenderQueue.Forward.Add(job); + } + else + { + RenderQueue.Deferred.Add(job); + } + } + } + + void EnqueueBlendMapModel(Model* model, BlendMapTexture textureRed, BlendMapTexture textureGreen, BlendMapTexture textureBlue, float textureRepeat, glm::mat4 modelMatrix, glm::vec4 color) + { + for (auto texGroup : model->TextureGroups) + { + BlendMapModelJob job; + job.TextureID = texGroup.Texture->ResourceID; + job.DiffuseTexture = *texGroup.Texture; + job.NormalTexture = (texGroup.NormalMap) ? *texGroup.NormalMap : 0; + job.SpecularTexture = (texGroup.SpecularMap) ? *texGroup.SpecularMap : 0; + job.BlendMapTextureRed = textureRed.Diffuse; + job.BlendMapTextureRedNormal = textureRed.Normal; + job.BlendMapTextureRedSpecular = textureRed.Specular; + job.BlendMapTextureGreen = textureGreen.Diffuse; + job.BlendMapTextureGreenNormal = textureGreen.Normal; + job.BlendMapTextureGreenSpecular = textureGreen.Specular; + job.BlendMapTextureBlue = textureBlue.Diffuse; + job.BlendMapTextureBlueNormal = textureBlue.Normal; + job.BlendMapTextureBlueSpecular = textureBlue.Specular; + job.TextureRepeat = textureRepeat; + job.VAO = model->VAO; + job.StartIndex = texGroup.StartIndex; + job.EndIndex = texGroup.EndIndex; + job.ModelMatrix = modelMatrix; + job.Color = color; + + RenderQueue.Deferred.Add(job); + } + } + + void EnqueueSprite(Texture* texture, glm::mat4 modelMatrix, glm::vec4 color) + { + SpriteJob job; + job.TextureID = texture->ResourceID; + job.Texture = *texture; + job.ModelMatrix = modelMatrix; + job.Color = color; + + RenderQueue.Forward.Add(job); + } + +}; + +} + +#endif // GUI_WorldFrame_h__ diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index a63eb23..4361d50 100755 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -79,6 +79,15 @@ file(GLOB SOURCE_FILES_Sound ) source_group(Sound FILES ${SOURCE_FILES_Sound}) +#file(GLOB SOURCE_FILES_GUI +# "${INCLUDE_PATH}/GUI/*.h" +# "GUI/*.cpp" +#) +set(SOURCE_FILES_GUI + "${INCLUDE_PATH}/GUI/Frame.h" +) +source_group(GUI FILES ${SOURCE_FILES_GUI}) + set(SOURCE_FILES ${SOURCE_FILES_Core} ${SOURCE_FILES_Core_Util} @@ -87,7 +96,9 @@ set(SOURCE_FILES ${SOURCE_FILES_Transform} ${SOURCE_FILES_Physics} ${SOURCE_FILES_Game} - ${SOURCE_FILES_Sound} ../../include/Game/EGameOver.h ../../include/Game/Bricks/CPowerUpBrick.h ../../include/Game/CPowerUp.h ../../include/Game/ECreatePowerUp.h ../../include/Game/EPowerUpTaken.h) + ${SOURCE_FILES_Sound} + ${SOURCE_FILES_GUI} +) if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") diff --git a/src/game/CMakeLists.txt.game b/src/game/CMakeLists.txt.game deleted file mode 100644 index 5e236f1..0000000 --- a/src/game/CMakeLists.txt.game +++ /dev/null @@ -1,38 +0,0 @@ -project(game) - -find_package(OpenGL REQUIRED) -find_package(GLEW REQUIRED) -find_package(GLFW REQUIRED) -find_package(Boost REQUIRED) -find_package(assimp REQUIRED) -find_package(ZLIB REQUIRED) -find_package(PNG REQUIRED) - -include_directories( - ${CMAKE_SOURCE_DIR}/include/dd - ${OPENGL_INCLUDE_DIR} - ${GLEW_INCLUDE_DIRS} - ${GLFW_INCLUDE_DIRS} - ${Boost_INCLUDE_DIRS} - ${assimp_INCLUDE_DIRS} - ${PNG_INCLUDE_DIRS} -) - -set(SOURCE_FILES - main.cpp -) - -if(CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") -endif() - -add_executable(game ${SOURCE_FILES}) -target_link_libraries(game - daydream - ${OPENGL_LIBRARIES} - ${GLEW_LIBRARIES} - ${GLFW_LIBRARIES} - ${Boost_LIBRARIES} - ${assimp_LIBRARIES} - ${PNG_LIBRARIES} -) \ No newline at end of file diff --git a/src/game/Core/Renderer.cpp b/src/game/Core/Renderer.cpp index 6534db1..23e9444 100755 --- a/src/game/Core/Renderer.cpp +++ b/src/game/Core/Renderer.cpp @@ -209,10 +209,10 @@ void dd::Renderer::CreateBuffers() void dd::Renderer::Draw(RenderQueueCollection& rq) { - DrawDeferred(rq.Deferred, rq.Lights); rq.Forward.Jobs.sort(dd::Renderer::DepthSort); DrawForward(rq.Forward, rq.Lights); + DrawGUI(rq.GUI); // Finally: Draw the deferred+forward combined texture to the screen glCullFace(GL_BACK); @@ -473,3 +473,52 @@ void dd::Renderer::DebugKeys() m_CurrentScreenBuffer = m_tLighting; } } + +void dd::Renderer::DrawGUI(dd::RenderQueue& rq) +{ + glBindFramebuffer(GL_FRAMEBUFFER, m_fbDeferred3); + glEnable(GL_SCISSOR_TEST); + glDisable(GL_CULL_FACE); + glCullFace(GL_BACK); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + //glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); + + m_spScreen->Bind(); + + glm::mat4 MVP; + + for (auto &job : rq) { + auto frameJob = std::dynamic_pointer_cast(job); + if (frameJob) { + glm::mat4 viewMatrix = glm::mat4(1); //frameJob->ViewMatrix; + glm::mat4 PV = glm::mat4(1); //frameJob->ProjectionMatrix * viewMatrix; + glm::mat4 modelMatrix = glm::mat4(1); //frameJob->ModelMatrix; + MVP = PV * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(*m_spScreen, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); + glUniformMatrix4fv(glGetUniformLocation(*m_spScreen, "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); + glUniformMatrix4fv(glGetUniformLocation(*m_spScreen, "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix)); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, frameJob->DiffuseTexture); + //glActiveTexture(GL_TEXTURE1); + //glBindTexture(GL_TEXTURE_2D, frameJob->NormalTexture); + //glActiveTexture(GL_TEXTURE2); + //glBindTexture(GL_TEXTURE_2D, frameJob->SpecularTexture); + + Rectangle& vp = frameJob->Viewport; + glViewport(vp.X, m_Resolution.Height - vp.Y - vp.Height, vp.Width, vp.Height); + Rectangle& sc = frameJob->Scissor; + glScissor(sc.X, m_Resolution.Height - sc.Y - sc.Height, sc.Width, sc.Height); + + glBindVertexArray(m_ScreenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + + continue; + } + } + + glDisable(GL_SCISSOR_TEST); + glViewport(0, 0, m_Resolution.Width, m_Resolution.Height); +}