diff --git a/src/Engine.h b/src/Engine.h index 22f8451..a8e7ef6 100755 --- a/src/Engine.h +++ b/src/Engine.h @@ -25,16 +25,18 @@ public: m_ResourceManager->RegisterType("Model", [rm](std::string resourceName) { return new Model(rm, *rm->Load("OBJ", resourceName)); }); m_ResourceManager->RegisterType("Texture", [](std::string resourceName) { return new Texture(resourceName); }); + m_FrameStack = new GUI::Frame(m_EventBroker, m_ResourceManager); + m_FrameStack->Width = 1920; + m_FrameStack->Height = 1080; + m_Renderer = std::make_shared(m_ResourceManager); + m_Renderer->SetFullscreen(false); + m_Renderer->SetResolution(*static_cast(m_FrameStack)); m_Renderer->Initialize(); m_InputManager = std::make_shared(m_Renderer->GetWindow(), m_EventBroker); - m_FrameStack = new GUI::Frame(m_EventBroker, m_ResourceManager); - m_FrameStack->Width = 1280; - m_FrameStack->Height = 720; new GUI::GameFrame(m_FrameStack, "GameFrame"); - //m_World = std::make_shared(m_EventBroker, m_ResourceManager); //m_World->Initialize(); diff --git a/src/EventBroker.h b/src/EventBroker.h index e29437a..5daa273 100644 --- a/src/EventBroker.h +++ b/src/EventBroker.h @@ -139,11 +139,7 @@ template void EventBroker::UnsubscribeAll() { const std::string contextTypeName = typeid(ContextType).name(); - auto contextIt = m_ContextRelays.find(contextTypeName); - if (contextIt != m_ContextRelays.end()) - { - m_ContextRelays.erase(contextIt); - } + m_ContextRelays.erase(contextTypeName); } #endif // MessageRelay_h__ diff --git a/src/GUI/Frame.h b/src/GUI/Frame.h index e502fea..47d5146 100644 --- a/src/GUI/Frame.h +++ b/src/GUI/Frame.h @@ -25,6 +25,9 @@ public: Bottom }; + static const int BaseWidth = 1280; + static const int BaseHeight = 720; + // Set up a base frame with an event broker Frame(std::shared_ptr<::EventBroker> eventBroker, std::shared_ptr<::ResourceManager> resourceManager) : EventBroker(eventBroker) @@ -33,14 +36,14 @@ public: , m_Name("UIParent") , m_Layer(0) , m_Hidden(false) - { } + { Initialize(); } // Create a frame as a child Frame(Frame* parent, std::string name) : m_Name(name) , m_Layer(0) , m_Hidden(false) - { SetParent(std::shared_ptr(parent)); } + { SetParent(std::shared_ptr(parent)); Initialize(); } ::RenderQueue RenderQueue; @@ -89,7 +92,10 @@ public: } int Right() const override { - return Left() + Width; + if (m_Parent) + return std::min(m_Parent->Right(), Left() + Width); + else + return Left() + Width; } int Top() const override { @@ -100,14 +106,34 @@ public: } int Bottom() const override { - return Top() + Height; + 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() { - return Rectangle(Left(), Top(), Width, Height); + int left = Left(); + int top = Top(); + int width = Right() - left; + int height = Bottom() - top; + return Rectangle(left, top, width, height); } + 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) { } + void UpdateLayered(double dt) { if (this->Hidden()) @@ -137,7 +163,7 @@ public: return; // Draw ourselves - renderer->SetViewport(AbsoluteRectangle()); + renderer->SetScissor(AbsoluteRectangle()); this->Draw(renderer); // Draw children @@ -150,7 +176,7 @@ public: if (child->Hidden()) continue; Rectangle rect = child->AbsoluteRectangle(); - renderer->SetViewport(rect); + renderer->SetScissor(rect); child->Draw(renderer); } } @@ -170,6 +196,15 @@ protected: typedef std::multimap> Children_t; // name -> frame std::map m_Children; // layer -> Children_t +private: + EventRelay m_EKeyDown; + EventRelay m_EKeyUp; + + void Initialize() + { + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Frame::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Frame::OnKeyUp); + } }; } diff --git a/src/GUI/GameFrame.h b/src/GUI/GameFrame.h index 19f66ac..f180835 100644 --- a/src/GUI/GameFrame.h +++ b/src/GUI/GameFrame.h @@ -6,6 +6,7 @@ #include "GUI/Viewport.h" #include "GUI/TextureFrame.h" #include "GUI/PlayerHUD.h" +#include "VehicleSelection.h" #include "GameWorld.h" @@ -18,23 +19,22 @@ public: GameFrame(Frame* parent, std::string name) : Frame(parent, name) { - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &GameFrame::OnKeyUp); - m_World = std::make_shared(EventBroker, ResourceManager); auto worldFrame = new WorldFrame(this, "GameWorldFrame", m_World); { vp1 = new Viewport(worldFrame, "Viewport1", m_World); vp1->X = 0; - vp1->Width = 640; + vp1->Width = this->Width / 2.f; new PlayerHUD(vp1, "PlayerHUD", m_World, 1); + //new VehicleSelection(vp1, "VehicleSelection", m_World, 1); vp2 = new Viewport(worldFrame, "Viewport2", m_World); vp2->X = vp1->Right(); - vp2->Width = 640; + vp2->Width = this->Width / 2.f; new PlayerHUD(vp2, "PlayerHUD", m_World, 2); m_FreeCamViewport = new Viewport(worldFrame, "ViewportFreeCam", m_World); - m_FreeCamViewport->Show(); + m_FreeCamViewport->Hide(); } m_World->Initialize(); } @@ -47,7 +47,7 @@ private: Viewport* vp2; Viewport* m_FreeCamViewport; - bool OnKeyUp(const Events::KeyUp &event) + bool OnKeyUp(const Events::KeyUp &event) override { if (event.KeyCode == GLFW_KEY_1) { diff --git a/src/GUI/PlayerHUD.h b/src/GUI/PlayerHUD.h index b094d4c..7ea4dda 100644 --- a/src/GUI/PlayerHUD.h +++ b/src/GUI/PlayerHUD.h @@ -1,9 +1,9 @@ -#include "GUI/Frame.h" -#include "GUI/HealthOverlay.h" - #ifndef GUI_PlayerHUD_h__ #define GUI_PlayerHUD_h__ +#include "GUI/Frame.h" +#include "GUI/HealthOverlay.h" + namespace GUI { diff --git a/src/GUI/TextureFrame.h b/src/GUI/TextureFrame.h index 6018478..f15dfd8 100644 --- a/src/GUI/TextureFrame.h +++ b/src/GUI/TextureFrame.h @@ -13,7 +13,10 @@ public: TextureFrame(Frame* parent, std::string name) : Frame(parent, name) , m_Texture(nullptr) + , m_FadeTexture(nullptr) , m_Color(glm::vec4(1.f, 1.f, 1.f, 1.f)) + , m_FadeDuration(0.f) + , m_CurrentFade(1.f) { } void Draw(std::shared_ptr renderer) override @@ -22,13 +25,28 @@ public: return; RenderQueue.Clear(); - SpriteJob job; - job.TextureID = m_Texture->ResourceID; - job.Texture = *m_Texture; - job.Color = m_Color; - RenderQueue.Add(job); + + // Main texture + { + SpriteJob job; + job.TextureID = m_Texture->ResourceID; + job.Texture = *m_Texture; + job.Color = glm::vec4(m_Color.r, m_Color.g, m_Color.b, m_Color.a * m_CurrentFade); + RenderQueue.Add(job); + } + + // Texture while fading + if (m_FadeTexture && m_CurrentFade < 1) + { + SpriteJob job; + job.TextureID = m_FadeTexture->ResourceID; + job.Texture = *m_FadeTexture; + job.Color = glm::vec4(m_Color.r, m_Color.g, m_Color.b, m_Color.a); + RenderQueue.Add(job); + } renderer->SetCamera(nullptr); + renderer->SetViewport(Rectangle(Left(), Top(), Width, Height)); renderer->DrawFrame(RenderQueue); } @@ -38,12 +56,37 @@ public: m_Texture = ResourceManager->Load<::Texture>("Texture", 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: ::Texture* m_Texture; + ::Texture* m_FadeTexture; glm::vec4 m_Color; + float m_FadeDuration; + float m_CurrentFade; }; diff --git a/src/GUI/VehicleSelection.h b/src/GUI/VehicleSelection.h new file mode 100644 index 0000000..fa11ceb --- /dev/null +++ b/src/GUI/VehicleSelection.h @@ -0,0 +1,115 @@ +#ifndef GUI_VehicleSelection_h__ +#define GUI_VehicleSelection_h__ + +#include "GUI/Frame.h" +#include "GUI/HealthOverlay.h" + +namespace GUI +{ + + class VehicleSelection : public Frame + { + public: + VehicleSelection(Frame* parent, std::string name, std::shared_ptr world, int playerID) + : Frame(parent, name) + , m_World(world) + , m_PlayerID(playerID) + { + ResourceManager->Preload("Texture", "Textures/GUI/VehicleSelection/1.png"); + ResourceManager->Preload("Texture", "Textures/GUI/VehicleSelection/2.png"); + ResourceManager->Preload("Texture", "Textures/GUI/VehicleSelection/3.png"); + ResourceManager->Preload("Texture", "Textures/GUI/VehicleSelection/4.png"); + + m_CurrentSelection = 0; + + glm::vec2 scale = Scale(); + m_CurrentCoordinate = -m_SelectionCoordinates[0] * scale + glm::vec2(Width / 2.f, Height / 2.f); + m_TargetCoordinate = m_CurrentCoordinate; + m_CurrentSize = m_SelectionSizes[0] * scale; + m_TargetSize = m_CurrentSize; + m_CurrentAlpha = 0.f; + + m_Background = new TextureFrame(this, "VehicleSelectImage1"); + m_Background->X = m_CurrentCoordinate.x; + m_Background->Y = m_CurrentCoordinate.y; + m_Background->Width = m_CurrentSize.x; + m_Background->Height = m_CurrentSize.y; + m_Background->SetTexture("Textures/GUI/VehicleSelection/1.png"); + } + + bool OnKeyUp(const Events::KeyUp &event) override + { + if (event.KeyCode == GLFW_KEY_LEFT) + { + m_CurrentSelection--; + } + else if (event.KeyCode == GLFW_KEY_RIGHT) + { + m_CurrentSelection++; + } + m_CurrentSelection = (m_CurrentSelection < 0) ? 0 : ((m_CurrentSelection > 3) ? 3 : m_CurrentSelection); + + std::stringstream ss; + ss << "Textures/GUI/VehicleSelection/" << m_CurrentSelection + 1 << ".png"; + m_Background->FadeToTexture(ss.str(), 1.f); + + glm::vec2 scale = Scale(); + glm::vec2 coord = -m_SelectionCoordinates[m_CurrentSelection]; + m_TargetCoordinate = coord * scale + glm::vec2(Width / 2.f, Height / 2.f); + glm::vec2 size = m_SelectionSizes[m_CurrentSelection]; + m_TargetSize = size * scale; + + return true; + } + + void Update(double dt) override + { + + + glm::vec2 posDiff = m_TargetCoordinate - m_CurrentCoordinate; + m_CurrentCoordinate += posDiff * 2.f * (float)dt; + + glm::vec2 sizeDiff = m_TargetSize - m_CurrentSize; + m_CurrentSize += sizeDiff * 3.f * (float)dt; + + m_CurrentAlpha += (1 - m_CurrentAlpha) * 3.f * (float)dt; + + m_Background->X = m_CurrentCoordinate.x; + m_Background->Y = m_CurrentCoordinate.y; + m_Background->Width = m_CurrentSize.x; + m_Background->Height = m_CurrentSize.y; + } + + protected: + std::shared_ptr m_World; + int m_PlayerID; + int m_CurrentSelection; + static glm::vec2 m_SelectionCoordinates[4]; + static glm::vec2 m_SelectionSizes[4]; + + glm::vec2 m_CurrentCoordinate; + glm::vec2 m_TargetCoordinate; + glm::vec2 m_CurrentSize; + glm::vec2 m_TargetSize; + float m_CurrentAlpha; + + TextureFrame* m_Background; + }; + + glm::vec2 VehicleSelection::m_SelectionCoordinates[4] = { + glm::vec2(339, 506), + glm::vec2(639, 377), + glm::vec2(1249, 399), + glm::vec2(1535, 628) + }; + + glm::vec2 VehicleSelection::m_SelectionSizes[4] = { + glm::vec2(1632, 918), + glm::vec2(1793, 1009), + glm::vec2(1793, 1009), + glm::vec2(1854, 1043) + }; + +} + +#endif // GUI_VehicleSelection_h__ diff --git a/src/GUI/Viewport.h b/src/GUI/Viewport.h index 88af865..44c8e81 100644 --- a/src/GUI/Viewport.h +++ b/src/GUI/Viewport.h @@ -65,6 +65,7 @@ public: return; renderer->SetCamera(m_Camera); + renderer->SetViewport(AbsoluteRectangle()); renderer->DrawWorld(m_Parent->RenderQueue); } diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 4769312..0c1fd1d 100755 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -5,6 +5,9 @@ Renderer::Renderer(std::shared_ptr<::ResourceManager> resourceManager) : ResourceManager(resourceManager) { m_VSync = false; + m_Fullscreen = false; + m_Width = 1280; + m_Height = 720; #ifdef DEBUG m_DrawNormals = false; m_DrawWireframe = false; @@ -38,11 +41,12 @@ void Renderer::Initialize() } // Create a window - m_Width = 1280; - m_Height = 720; - // Antialiasing - //glfwWindowHint(GLFW_SAMPLES, 16); - m_Window = glfwCreateWindow(m_Width, m_Height, "OpenGL", nullptr, nullptr); + GLFWmonitor* monitor = nullptr; + if (m_Fullscreen) + { + monitor = glfwGetPrimaryMonitor(); + } + m_Window = glfwCreateWindow(m_Width, m_Height, "OpenGL", monitor, nullptr); if (!m_Window) { LOG_ERROR("GLFW: Failed to create window"); @@ -260,7 +264,7 @@ void Renderer::DrawFrame(RenderQueue &rq) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); - glScissor(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); + glScissor(m_Scissor.X, m_Height - m_Scissor.Y - m_Scissor.Height, m_Scissor.Width, m_Scissor.Height); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClearColor(0.0f, 0.5f, 0.0f, 1.0f); @@ -364,7 +368,7 @@ void Renderer::DrawWorld(RenderQueue &rq) */ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbBasePass); glViewport(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); - glScissor(m_Viewport.X, m_Height - m_Viewport.Y - m_Viewport.Height, m_Viewport.Width, m_Viewport.Height); + glScissor(m_Scissor.X, m_Height - m_Scissor.Y - m_Scissor.Height, m_Scissor.Width, m_Scissor.Height); //glViewport(0, 0, m_Width, m_Height); // Clear G-buffer diff --git a/src/Renderer.h b/src/Renderer.h index ecdecfc..9116b67 100755 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -43,11 +43,27 @@ public: void UpdateCamera(int cameraIdentifier, glm::vec3 position, glm::quat orientation, float FOV, float nearClip, float farClip); #pragma region NEWSTUFF + void SetResolution(const Rectangle &resolution) + { + m_Width = resolution.Width; + m_Height = resolution.Height; + } + + void SetFullscreen(bool fullscreen) + { + m_Fullscreen = fullscreen; + } + void SetViewport(const Rectangle &viewport) { m_Viewport = viewport; } + void SetScissor(const Rectangle &scissor) + { + m_Scissor = scissor; + } + void SetCamera(std::shared_ptr camera) { m_Camera = camera; @@ -94,6 +110,7 @@ public: private: std::shared_ptr<::ResourceManager> ResourceManager; + bool m_Fullscreen; int m_Width, m_Height; struct Viewport @@ -109,6 +126,7 @@ private: std::unordered_map> m_Cameras; Rectangle m_Viewport; + Rectangle m_Scissor; std::shared_ptr m_Camera; struct Light diff --git a/src/Texture.cpp b/src/Texture.cpp index 373db0d..8d76d39 100755 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -8,13 +8,14 @@ Texture::Texture(std::string path) void Texture::Load(std::string path) { - auto cachedTexture = m_TextureCache.find(path); - if (cachedTexture == m_TextureCache.end()) + m_Texture = SOIL_load_OGL_texture(path.c_str(), 0, 0, SOIL_FLAG_INVERT_Y); + + if (m_Texture == 0) { - m_TextureCache[path] = SOIL_load_OGL_texture(path.c_str(), 0, 0, SOIL_FLAG_INVERT_Y); + LOG_ERROR("SOIL: Failed to load texture \"%s\"", path.c_str()); + return; } - m_Texture = m_TextureCache[path]; glBindTexture(GL_TEXTURE_2D, m_Texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index d4f45a9..e7a59ac 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -209,6 +209,7 @@ + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index a6e3f4e..89ed807 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -524,6 +524,9 @@ Base\Components + + GUI +