diff --git a/assets b/assets index 50ee6f8..664f55c 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 50ee6f805f9b8493450366b3a4a771da16350423 +Subproject commit 664f55cd71cfd5a20e5bac39e1427ad398a84a6c diff --git a/src/Components/Particle.h b/src/Components/Particle.h index d08b1a7..065ab62 100644 --- a/src/Components/Particle.h +++ b/src/Components/Particle.h @@ -11,9 +11,10 @@ namespace Components struct Particle : Component { - std::vector ColorSpectrum; std::vector ScaleSpectrum; double LifeTime; + double SpawnTime; + bool Fade; std::vector VelocitySpectrum; std::vector AngularVelocitySpectrum; std::vector OrientationSpectrum; //Keep? diff --git a/src/Components/ParticleEmitter.h b/src/Components/ParticleEmitter.h index 03eaf05..f7cb678 100755 --- a/src/Components/ParticleEmitter.h +++ b/src/Components/ParticleEmitter.h @@ -19,20 +19,22 @@ struct ParticleEmitter : Component , SpawnCount(0) , SpreadAngle(0) , LifeTime(0) - , TimeSinceLastSpawn(100) { } // TEMP fulhack så att partiklarna spawnar direkt + , TimeSinceLastSpawn(100) + , Color(glm::vec4(0)) { } EntityID ParticleTemplate; float SpawnFrequency; float Speed; int SpawnCount; - std::vector ColorSpectrum; + glm::vec4 Color; std::vector ScaleSpectrum; float SpreadAngle; double LifeTime; bool UseGoalVelocity; + bool Fade; glm::vec3 GoalVelocity; std::vector AngularVelocitySpectrum; - std::vector OrientationSpectrum; //Keep? + std::vector OrientationSpectrum; //Keep? noo.. private: double TimeSinceLastSpawn; 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/Events/CreateExplosion.h b/src/Events/CreateExplosion.h new file mode 100644 index 0000000..0fb6310 --- /dev/null +++ b/src/Events/CreateExplosion.h @@ -0,0 +1,27 @@ +#ifndef Event_CreateExplosion_h__ +#define Event_CreateExplosion_h__ + +#include "EventBroker.h" +#include +#include + +namespace Events +{ + struct CreateExplosion : Event + { + CreateExplosion() + : Color(glm::vec4(0)) {} + glm::vec3 Position; + glm::vec4 Color; + double LifeTime; + int ParticlesToSpawn; + std::string spritePath; + glm::quat RelativeUpOrientation; + float Speed; + float SpreadAngle; + std::vector ParticleScale; + }; + +} + +#endif // Event_CreateExplosion_h__ diff --git a/src/GUI/Frame.h b/src/GUI/Frame.h index fccd65b..6a649b5 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(); } ::RenderQueuePair 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 791baa1..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; - //new PlayerHUD(vp1, "PlayerHUD", m_World, 1); + 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; - //new PlayerHUD(vp2, "PlayerHUD", m_World, 2); + 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 bbdfaef..aced664 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.Forward.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.Forward.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.Forward.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/InputManager.cpp b/src/InputManager.cpp index b20e072..01d61ba 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -85,6 +85,7 @@ void InputManager::Update(double dt) EventBroker->Publish(e); } + // // Lock mouse while holding LMB // if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT]) // { diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 142f7ec..ff01e67 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"); @@ -163,7 +167,7 @@ void Renderer::LoadContent() FrameBufferTextures(); m_sphereModel = ResourceManager->Load("Model", "Models/Placeholders/PhysicsTest/Sphere.obj"); - m_Skybox = std::make_shared("Textures/Skybox/sky36", "jpg"); + m_Skybox = std::make_shared("Textures/Skybox/sunset", "jpg"); } void Renderer::Draw(double dt) @@ -267,7 +271,7 @@ void Renderer::DrawFrame(RenderQueuePair &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); @@ -387,7 +391,7 @@ void Renderer::DrawWorld(RenderQueuePair &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 dacc6db..7a1c214 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 @@ -201,7 +219,7 @@ private: void CreateNormalMapTangent(); void ForwardRendering(RenderQueue &rq); - static bool DepthSort(const std::shared_ptr &i, const std::shared_ptr &j) { return (i->Depth < j->Depth); } + static bool DepthSort(const std::shared_ptr &i, const std::shared_ptr &j) { return (i->Depth > j->Depth); } GLuint CreateQuad(); void DrawDebugShadowMap(); diff --git a/src/Systems/ParticleSystem.cpp b/src/Systems/ParticleSystem.cpp index 893bb07..45c3646 100644 --- a/src/Systems/ParticleSystem.cpp +++ b/src/Systems/ParticleSystem.cpp @@ -8,7 +8,7 @@ void Systems::ParticleSystem::Initialize() { m_TransformSystem = m_World->GetSystem(); tempSpawnedExplosions = false; - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Systems::ParticleSystem::OnKeyUp); + EVENT_SUBSCRIBE_MEMBER(m_EExplosion, &ParticleSystem::CreateExplosion); } void Systems::ParticleSystem::Update(double dt) @@ -22,11 +22,14 @@ void Systems::ParticleSystem::Update(double dt) double timeLived = glfwGetTime() - spawnTime; auto eComp = m_World->GetComponent(explosionID); - if(timeLived > eComp->LifeTime) + if(timeLived > eComp->LifeTime && m_ParticlesToEmitter[explosionID] == NULL) { + auto e = m_World->GetComponent(explosionID); + m_World->RemoveEntity(e->ParticleTemplate); m_World->RemoveEntity(explosionID); it = m_ExplosionEmitters.erase(it); //LOG_INFO("Deleted explosion emitter successfully"); + //LOG_INFO("Deleted explosion emitter successfully. nr of emitters%i", m_ExplosionEmitters.size()); } else { @@ -46,69 +49,82 @@ void Systems::ParticleSystem::UpdateEntity(double dt, EntityID entity, EntityID { emitterComponent->TimeSinceLastSpawn += dt; auto emitterTransformComponent = m_World->GetComponent(entity); - if(emitterComponent->TimeSinceLastSpawn > emitterComponent->SpawnFrequency) +// if(emitterComponent->TimeSinceLastSpawn > emitterComponent->SpawnFrequency) +// { +// SpawnParticles(entity); +// emitterComponent->TimeSinceLastSpawn = 0; +// } + } + + auto particleComponent = m_World->GetComponent(entity); + if(particleComponent) + { + + + EntityID particleID = entity; + double timeLived = glfwGetTime() - particleComponent->SpawnTime; + + if(timeLived > particleComponent->LifeTime) { - SpawnParticles(entity); - emitterComponent->TimeSinceLastSpawn = 0; + m_World->RemoveEntity(particleID); + m_ParticlesToEmitter.erase(particleID); + + return; } - - std::list::iterator it; - for(it = m_ParticleEmitter[entity].begin(); it != m_ParticleEmitter[entity].end();) + else { - EntityID particleID = (it)->ParticleID; auto transformComponent = m_World->GetComponent(particleID); - auto particleComponent = m_World->GetComponent(particleID); - - double timeLived = glfwGetTime() - it->SpawnTime; - if(timeLived > particleComponent->LifeTime) + auto eComponent = m_World->GetComponent(m_ParticlesToEmitter[particleID]); + auto sprite = m_World->GetComponent(entity); + // FIX: calculate once + float timeProgress = timeLived / particleComponent->LifeTime; + // ColorInterpolation(timeProgress, particleComponent->ColorSpectrum, color); + // Scale interpolation + if(particleComponent->ScaleSpectrum.size() > 1) + VectorInterpolation(timeProgress, particleComponent->ScaleSpectrum, transformComponent->Scale); + // Velocity interpolation + if(particleComponent->VelocitySpectrum.size() > 1) + VectorInterpolation(timeProgress, particleComponent->VelocitySpectrum, transformComponent->Velocity); + + if(particleComponent->Fade == true) { - m_World->RemoveEntity(particleID); - it = m_ParticleEmitter[entity].erase(it); + std::vector spectrum; + spectrum.push_back(1); + spectrum.push_back(0); + float alpha; + ScalarInterpolation(timeProgress, spectrum, alpha); + sprite->Color.w = alpha; } - else + + + + /*// Angular velocity interpolation + if (particleComponent->AngularVelocitySpectrum.size() != 0) { - // FIX: calculate once - float timeProgress = timeLived / particleComponent->LifeTime; - // ColorInterpolation(timeProgress, particleComponent->ColorSpectrum, color); - // Scale interpolation - if(particleComponent->ScaleSpectrum.size() > 1) - VectorInterpolation(timeProgress, particleComponent->ScaleSpectrum, transformComponent->Scale); - // Velocity interpolation - if(particleComponent->VelocitySpectrum.size() > 1) - VectorInterpolation(timeProgress, particleComponent->VelocitySpectrum, transformComponent->Velocity); - - // Angular velocity interpolation - if (particleComponent->AngularVelocitySpectrum.size() != 0) + if(particleComponent->AngularVelocitySpectrum.size() > 1) { - if(particleComponent->AngularVelocitySpectrum.size() > 1) - { - ScalarInterpolation(timeProgress, particleComponent->AngularVelocitySpectrum, it->AngularVelocity); - transformComponent->Orientation = glm::angleAxis(it->AngularVelocity, it->Orientation); - } - else - { - transformComponent->Orientation *= glm::angleAxis(it->AngularVelocity, it->Orientation); - //it->Orientation = glm::angleAxis(it->AngularVelocity, it->Orientation); - } + ScalarInterpolation(timeProgress, particleComponent->AngularVelocitySpectrum, it->AngularVelocity); + transformComponent->Orientation = glm::angleAxis(it->AngularVelocity, it->Orientation); } - - //Angular velocity interpolation - if(particleComponent->OrientationSpectrum.size() > 1) + else { - VectorInterpolation(timeProgress, particleComponent->OrientationSpectrum, it->Orientation); - glm::vec3 v1 = (particleComponent->OrientationSpectrum[0]); - glm::vec3 v2 = (it->Orientation); - glm::vec3 v3 = glm::normalize(glm::cross(v1,v2)); - float angle = glm::acos(glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2))); - - transformComponent->Orientation = glm::angleAxis(angle, v3); + transformComponent->Orientation *= glm::angleAxis(it->AngularVelocity, it->Orientation); + //it->Orientation = glm::angleAxis(it->AngularVelocity, it->Orientation); } - - - transformComponent->Position += transformComponent->Velocity * (float)dt; - - it++; } + + //Angular velocity interpolation + if(particleComponent->OrientationSpectrum.size() > 1) + { + VectorInterpolation(timeProgress, particleComponent->OrientationSpectrum, it->Orientation); + glm::vec3 v1 = (particleComponent->OrientationSpectrum[0]); + glm::vec3 v2 = (it->Orientation); + glm::vec3 v3 = glm::normalize(glm::cross(v1,v2)); + float angle = glm::acos(glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2))); + + transformComponent->Orientation = glm::angleAxis(angle, v3); + }*/ + transformComponent->Position += transformComponent->Velocity * (float)dt; } } } @@ -127,12 +143,11 @@ void Systems::ParticleSystem::SpawnParticles(EntityID emitterID) glm::vec3 ePosition = m_TransformSystem->AbsolutePosition(emitterID); glm::quat eOrientation = eTransform->Orientation; glm::vec3 paticleSpeed = glm::vec3(eComponent->Speed); - for(int i = 0; i < eComponent->SpawnCount; i++) { - auto particleEntity = m_World->CloneEntity(eComponent->ParticleTemplate); - - auto particleTransform = m_World->GetComponent(particleEntity); + auto ent = m_World->CloneEntity(eComponent->ParticleTemplate); + m_ParticlesToEmitter.insert(std::make_pair(ent, emitterID)); + auto particleTransform = m_World->GetComponent(ent); particleTransform->Position = ePosition; particleTransform->Orientation = eOrientation; @@ -143,16 +158,21 @@ void Systems::ParticleSystem::SpawnParticles(EntityID emitterID) glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(0, 1, 0))) * glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(0, 0, 1))); - auto particleComponent = m_World->AddComponent(particleEntity); - particleComponent->LifeTime = eComponent->LifeTime - 0.5; - particleComponent->ScaleSpectrum = eComponent->ScaleSpectrum; - particleComponent->VelocitySpectrum.push_back(particleTransform->Velocity); + auto particle = m_World->AddComponent(ent); + particle->LifeTime = eComponent->LifeTime; + particle->ScaleSpectrum = eComponent->ScaleSpectrum; + particle->VelocitySpectrum.push_back(particleTransform->Velocity); + particle->Fade = eComponent->Fade; + + auto sprite = m_World->GetComponent(ent); + if(eComponent->Color != glm::vec4(0)) + sprite->Color = eComponent->Color; if (eComponent->ScaleSpectrum.size() > 0) { if (eComponent->ScaleSpectrum.size() > 1) { - particleComponent->ScaleSpectrum = eComponent->ScaleSpectrum; + particle->ScaleSpectrum = eComponent->ScaleSpectrum; } else { @@ -165,22 +185,20 @@ void Systems::ParticleSystem::SpawnParticles(EntityID emitterID) } if(eComponent->UseGoalVelocity) - particleComponent->VelocitySpectrum.push_back(eComponent->GoalVelocity); - particleComponent->OrientationSpectrum = eComponent->OrientationSpectrum; - if(particleComponent->OrientationSpectrum.size() != 0) - particleTransform->Orientation = glm::angleAxis(0.f, particleComponent->OrientationSpectrum[0]); - particleComponent->AngularVelocitySpectrum = eComponent->AngularVelocitySpectrum; + particle->VelocitySpectrum.push_back(eComponent->GoalVelocity); + particle->OrientationSpectrum = eComponent->OrientationSpectrum; + if(particle->OrientationSpectrum.size() != 0) + particleTransform->Orientation = glm::angleAxis(0.f, particle->OrientationSpectrum[0]); + particle->AngularVelocitySpectrum = eComponent->AngularVelocitySpectrum; - ParticleData data; - data.ParticleID = particleEntity; - data.SpawnTime = glfwGetTime(); - if (particleComponent->AngularVelocitySpectrum.size() != 0) - data.AngularVelocity = particleComponent->AngularVelocitySpectrum[0]; - if (particleComponent->OrientationSpectrum.size() != 0) - data.Orientation = particleComponent->OrientationSpectrum[0]; - else data.Orientation = eOrientation * glm::vec3(0,0,-1); - m_ParticleEmitter[emitterID].push_back(data); + particle->SpawnTime = glfwGetTime(); +// if (particle->AngularVelocitySpectrum.size() != 0) +// data.AngularVelocity = particle->AngularVelocitySpectrum[0]; +// if (particle->OrientationSpectrum.size() != 0) +// data.Orientation = particle->OrientationSpectrum[0]; +// else data.Orientation = eOrientation * glm::vec3(0,0,-1); + //m_ParticleEmitter[emitterID].push_back(data); } } @@ -200,23 +218,13 @@ void Systems::ParticleSystem::VectorInterpolation(double timeProgress, std::vect dAxisValue = glm::abs(spectrum[0].y - spectrum[1].y); if (spectrum[0].y > spectrum[1].y) dAxisValue *= -1; - v.y = spectrum[0].y + dAxisValue * timeProgress; + v.y = spectrum[0].y + dAxisValue * timeProgress; dAxisValue = glm::abs(spectrum[0].z - spectrum[1].z); if(spectrum[0].z > spectrum[1].z) dAxisValue *= -1; v.z = spectrum[0].z + dAxisValue * timeProgress; } -// void Systems::ParticleSystem::ColorInterpolation(double timeProgress, std::vector spectrum, Color &c) -// { -// float dColor = glm::abs(spectrum[0].r - spectrum[1].r); -// c.r = spectrum[0].r + dColor * timeProgress; -// dColor = glm::abs(spectrum[0].g - spectrum[1].g); -// c.g = spectrum[0].g + dColor * timeProgress; -// dColor = glm::abs(spectrum[0].b - spectrum[1].b); -// c.b = spectrum[0].b + dColor * timeProgress; -// } - void Systems::ParticleSystem::ScalarInterpolation(double timeProgress, std::vector spectrum, float &alpha) { float dAlpha = glm::abs(spectrum[0] - spectrum[1]); @@ -225,53 +233,41 @@ void Systems::ParticleSystem::ScalarInterpolation(double timeProgress, std::vect alpha = spectrum[0] + dAlpha * timeProgress; } -void Systems::ParticleSystem::CreateExplosion(glm::vec3 _pos, double _lifeTime, int _particlesToSpawn, std::string _spritePath, glm::quat _relativeUpOri, float _speed, float _spreadAngle, float _particleScale) +bool Systems::ParticleSystem::CreateExplosion(const Events::CreateExplosion &e) { + LOG_INFO("Spawning an explosion"); auto explosion = m_World->CreateEntity(); auto emitter = m_World->AddComponent(explosion); - emitter->LifeTime = _lifeTime; - emitter->SpawnCount = _particlesToSpawn; - emitter->Speed = _speed; - emitter->SpreadAngle = _spreadAngle; - emitter->SpawnFrequency = _lifeTime + 20; //temp -// emitter->UseGoalVelocity = true; -// emitter->GoalVelocity = glm::vec3(0,-_speed, 0); + emitter->LifeTime = e.LifeTime; + emitter->SpawnCount = e.ParticlesToSpawn; + emitter->Speed = e.Speed; + emitter->SpreadAngle = e.SpreadAngle; + //emitter->ScaleSpectrum.push_back(glm::vec3(e.ParticleScale)); + emitter->SpawnFrequency = e.LifeTime + 20; //temp + emitter->Fade = true; + emitter->Color = e.Color; + std::vector scale; + scale.push_back(glm::vec3(e.ParticleScale[0])); + if(e.ParticleScale.size() >= 2) + scale.push_back(glm::vec3(e.ParticleScale[1])); + emitter->ScaleSpectrum = scale; + // emitter->GoalVelocity = glm::vec3(0,-_speed, 0); m_World->CommitEntity(explosion); auto particleEnt = m_World->CreateEntity(); + auto templateComponent = m_World->AddComponent(particleEnt); auto TEMP = m_World->AddComponent(particleEnt); - TEMP->Scale = glm::vec3(0); auto spriteComponent = m_World->AddComponent(particleEnt); - spriteComponent->SpriteFile = _spritePath; + spriteComponent->SpriteFile = e.spritePath; m_World->CommitEntity(particleEnt); emitter->ParticleTemplate = particleEnt; - + auto transform = m_World->AddComponent(explosion); - transform->Position = _pos; - transform->Orientation = _relativeUpOri; - + transform->Position = e.Position; + transform->Orientation = e.RelativeUpOrientation; + SpawnParticles(explosion); m_ExplosionEmitters[explosion] = glfwGetTime(); -} -bool Systems::ParticleSystem::OnKeyUp(const Events::KeyUp &e) -{ - if(!tempSpawnedExplosions) - { - if (e.KeyCode == GLFW_KEY_B) - { - tempSpawnedExplosions = true; - CreateExplosion( - glm::vec3(0, 10, 0), - 0.5, - 60, - "Textures/Sprites/NewtonTreeDeleteASAPPlease.png", - glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)), - 40, - glm::pi(), - 0.5f - ); - } - } return true; } \ No newline at end of file diff --git a/src/Systems/ParticleSystem.h b/src/Systems/ParticleSystem.h index e11e73c..f70cc9d 100644 --- a/src/Systems/ParticleSystem.h +++ b/src/Systems/ParticleSystem.h @@ -9,21 +9,13 @@ #include "Components/Sprite.h" #include "EventBroker.h" #include "Events/KeyUp.h" +#include "Events/CreateExplosion.h" #include "Color.h" #include namespace Systems { - struct ParticleData - { - EntityID ParticleID; - double SpawnTime; - float AngularVelocity; - glm::vec3 Orientation; - Color color; - }; - class ParticleSystem : public System { public: @@ -36,7 +28,7 @@ public: void UpdateEntity(double dt, EntityID entity, EntityID parent) override; void Initialize() override; - void CreateExplosion(glm::vec3 _pos, double _lifeTime, int _particlesToSpawn, std::string _spritePath, glm::quat _relativeUpOri, float _speed, float _spreadAngle, float _particleScale); + //void CreateExplosion(glm::vec3 _pos, double _lifeTime, int _particlesToSpawn, std::string _spritePath, glm::quat _relativeUpOri, float _speed, float _spreadAngle, float _particleScale); virtual bool OnCommand(const Events::KeyUp &event) { return false; } @@ -45,19 +37,21 @@ private: float RandomizeAngle(float spreadAngle); //void ScaleInterpolation(double timeProgress, std::vector spectrum, glm::vec3 &scale); void VectorInterpolation(double timeProgress, std::vector spectrum, glm::vec3 &velocity); - //void ColorInterpolation(double timeProgress, std::vector spectrum, Color &color); void ScalarInterpolation(double timeProgress, std::vector spectrum, float &alpha); void Billboard(); - std::map> m_ParticleEmitter; - std::map m_TimeSinceLastSpawn; - std::map m_ExplosionEmitters; + //std::map> m_ParticleEmitter; + std::shared_ptr m_TransformSystem; bool tempSpawnedExplosions; - EventRelay m_EKeyUp; - bool OnKeyUp(const Events::KeyUp &e); - +// EventRelay m_EKeyUp; +// bool OnKeyUp(const Events::KeyUp &e); + EventRelay m_EExplosion; + bool CreateExplosion(const Events::CreateExplosion &e); + + std::map m_ExplosionEmitters; + std::map m_ParticlesToEmitter; }; } diff --git a/src/Systems/TankSteeringSystem.cpp b/src/Systems/TankSteeringSystem.cpp index b5828d2..618af45 100644 --- a/src/Systems/TankSteeringSystem.cpp +++ b/src/Systems/TankSteeringSystem.cpp @@ -130,6 +130,41 @@ bool Systems::TankSteeringSystem::OnCollision( const Events::Collision &e ) auto physicsComponents = m_World->GetComponentsOfType(); auto shellTransform = m_World->GetComponent(shellEntity); //auto otherTransform = m_World->GetComponent(otherEntity); + + { + Events::CreateExplosion e; + e.LifeTime = 3; + e.ParticleScale.push_back(8); + e.ParticlesToSpawn = 20; + e.Position = shellTransform->Position; + e.RelativeUpOrientation = glm::angleAxis(glm::pi() / 2, glm::vec3(1,0,0)); + e.Speed = 3; + e.SpreadAngle = glm::pi(); + e.spritePath = "Textures/Sprites/Smoke1.png"; + e.Color = glm::vec4(0.6,0.6,0.6,1); + EventBroker->Publish(e); + e.LifeTime = 0.7; + e.ParticleScale.push_back(12); + e.ParticlesToSpawn = 10; + e.Position = shellTransform->Position; + e.RelativeUpOrientation = glm::angleAxis(glm::pi() / 2, glm::vec3(1,0,0)); + e.Speed = 17; + e.SpreadAngle = glm::pi(); + e.spritePath = "Textures/Sprites/Fire.png"; + EventBroker->Publish(e); + e.LifeTime = 0.2; + e.ParticleScale.push_back(1); + e.ParticleScale.push_back(15); + e.ParticlesToSpawn = 5; + e.Position = shellTransform->Position; + e.RelativeUpOrientation = glm::angleAxis(glm::pi() / 2, glm::vec3(1,0,0)); + e.Speed = 6; + e.SpreadAngle = glm::pi(); + e.spritePath = "Textures/Sprites/Blast1.png"; + e.Color = glm::vec4(2, 2, 2, 0.2); + EventBroker->Publish(e); + } + for (auto &physComponent : *physicsComponents) { EntityID physicsEntity = std::dynamic_pointer_cast(physComponent)->Entity; diff --git a/src/Systems/TankSteeringSystem.h b/src/Systems/TankSteeringSystem.h index 01fc27a..8c996fa 100644 --- a/src/Systems/TankSteeringSystem.h +++ b/src/Systems/TankSteeringSystem.h @@ -5,6 +5,7 @@ #include "Events/SetVelocity.h" #include "Events/ApplyForce.h" #include "Events/ApplyPointImpulse.h" +#include "Events/CreateExplosion.h" #include "Events/Collision.h" #include "Components/Transform.h" #include "Components/TankSteering.h" 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 66a883a..1916c03 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -177,6 +177,7 @@ + @@ -202,6 +203,7 @@ + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 60b8a53..22319e0 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -171,6 +171,9 @@ {cb06b441-90b8-46ed-b347-4190dac7185b} + + {ddd3c442-7c2f-4690-9308-fcef62deee0b} + {3c2ea0e5-41a1-4b11-a891-1d59ead7223c} @@ -419,6 +422,9 @@ Gameplay\Components + + Particle System\Events + Physics\Events @@ -490,6 +496,10 @@ Gameplay\Systems + + + + GUI Gameplay\Events