diff --git a/assets/Models/Submarine.obj b/assets/Models/Submarine.obj old mode 100644 new mode 100755 index 28e65c8..14569fc --- a/assets/Models/Submarine.obj +++ b/assets/Models/Submarine.obj @@ -1879,5 +1879,3 @@ f 166/13/239 259/24/24 401/34/255 f 161/12/240 166/13/239 400/32/253 f 163/27/245 161/12/240 399/29/251 f 256/19/19 163/27/245 398/30/30 -l 300 301 -l 299 298 diff --git a/assets/Textures/Background.png b/assets/Textures/Background.png new file mode 100755 index 0000000..353a610 Binary files /dev/null and b/assets/Textures/Background.png differ diff --git a/assets/Textures/Test/Water.png b/assets/Textures/Test/Water.png new file mode 100755 index 0000000..2db8727 Binary files /dev/null and b/assets/Textures/Test/Water.png differ diff --git a/assets/Textures/Test/Water.psd b/assets/Textures/Test/Water.psd new file mode 100755 index 0000000..583db77 Binary files /dev/null and b/assets/Textures/Test/Water.psd differ diff --git a/include/Core/Engine.h b/include/Core/Engine.h index e47d8f5..dbd1d24 100644 --- a/include/Core/Engine.h +++ b/include/Core/Engine.h @@ -49,8 +49,9 @@ #include "Physics/PhysicsSystem.h" #include "Physics/CPhysics.h" -#include "Physics/CBoxShape.h" +#include "Physics/CRectangleShape.h" #include "Physics/ESetImpulse.h" +#include "Physics/CWaterVolume.h" #include "GUI/Frame.h" #include "GUI/Button.h" @@ -61,14 +62,15 @@ namespace dd class Engine { + public: Engine(int argc, char* argv[]) { - m_EventBroker = std::make_shared(); + m_EventBroker = std::make_shared(); - m_Renderer = std::make_shared(); - m_Renderer->SetFullscreen(false); - //m_Renderer->SetResolution(Rectangle(0, 0, 1920, 1080)); - m_Renderer->SetResolution(Rectangle(0, 0, 675, 1080)); + m_Renderer = std::make_shared(); + m_Renderer->SetFullscreen(false); + //m_Renderer->SetResolution(Rectangle(0, 0, 1920, 1080)); + m_Renderer->SetResolution(Rectangle(0, 0, 675, 1080)); m_Renderer->Initialize(); m_FrameStack = new GUI::Frame(m_EventBroker.get()); @@ -76,28 +78,29 @@ public: m_FrameStack->Height = 1080; auto menu = new GUI::MainMenu(m_FrameStack, "MainMenu"); - m_InputManager = std::make_shared(m_Renderer->Window(), m_EventBroker); + m_InputManager = std::make_shared(m_Renderer->Window(), m_EventBroker); m_World = std::make_shared(m_EventBroker); - //TODO: Move this out of engine.h - m_World->ComponentFactory.Register(); - m_World->SystemFactory.Register( - [this]() { return new Systems::TransformSystem(m_World.get(), m_EventBroker); }); - m_World->AddSystem(); + //TODO: Move this out of engine.h + m_World->ComponentFactory.Register(); + m_World->SystemFactory.Register( + [this]() { return new Systems::TransformSystem(m_World.get(), m_EventBroker); }); + m_World->AddSystem(); m_World->ComponentFactory.Register(); m_World->ComponentFactory.Register(); m_World->ComponentFactory.Register(); - m_World->SystemFactory.Register([this]() { return new Systems::SoundSystem(m_World.get(), m_EventBroker); }); + m_World->SystemFactory.Register( + [this]() { return new Systems::SoundSystem(m_World.get(), m_EventBroker); }); m_World->AddSystem(); - m_World->ComponentFactory.Register(); + m_World->ComponentFactory.Register(); - m_World->ComponentFactory.Register(); - m_World->ComponentFactory.Register(); + m_World->ComponentFactory.Register(); + m_World->ComponentFactory.Register(); m_World->ComponentFactory.Register(); m_World->ComponentFactory.Register(); m_World->ComponentFactory.Register(); @@ -106,39 +109,37 @@ public: m_World->ComponentFactory.Register(); m_World->ComponentFactory.Register(); - m_World->SystemFactory.Register( - [this]() { return new Systems::PhysicsSystem(m_World.get(), m_EventBroker); }); - m_World->AddSystem(); + m_World->SystemFactory.Register( + [this]() { return new Systems::PhysicsSystem(m_World.get(), m_EventBroker); }); + m_World->AddSystem(); - m_World->SystemFactory.Register([this]() { return new Systems::LevelSystem(m_World.get(), m_EventBroker); }); + m_World->SystemFactory.Register( + [this]() { return new Systems::LevelSystem(m_World.get(), m_EventBroker); }); m_World->AddSystem(); - m_World->SystemFactory.Register([this]() { return new Systems::PadSystem(m_World.get(), m_EventBroker); }); + m_World->SystemFactory.Register( + [this]() { return new Systems::PadSystem(m_World.get(), m_EventBroker); }); m_World->AddSystem(); - m_World->SystemFactory.Register([this]() { return new Systems::BallSystem(m_World.get(), m_EventBroker); }); + m_World->SystemFactory.Register( + [this]() { return new Systems::BallSystem(m_World.get(), m_EventBroker); }); m_World->AddSystem(); - m_World->ComponentFactory.Register(); - m_World->ComponentFactory.Register(); + m_World->ComponentFactory.Register(); + m_World->ComponentFactory.Register(); m_World->ComponentFactory.Register(); - m_World->Initialize(); + m_World->ComponentFactory.Register(); + m_World->Initialize(); - //TODO: Remove tobias light-test code. - /*{ - }*/ - //OctoBall { - auto ent = m_World->CreateEntity(); - std::shared_ptr transform = m_World->AddComponent(ent); - transform->Position = glm::vec3(-0.f, 0.26f, -10.f); + auto ent = m_World->CreateEntity(); + std::shared_ptr transform = m_World->AddComponent(ent); + transform->Position = glm::vec3(-0.f, 0.26f, -9.f); transform->Scale = glm::vec3(0.5f, 0.5f, 0.5f); transform->Velocity = glm::vec3(0.0f, -10.f, 0.f); - - auto model = m_World->AddComponent(ent); + auto model = m_World->AddComponent(ent); model->ModelFile = "Models/Test/Ball/Ballopus.obj"; - - std::shared_ptr circleShape = m_World->AddComponent(ent); + std::shared_ptr circleShape = m_World->AddComponent(ent); std::shared_ptr ball = m_World->AddComponent(ent); ball->Speed = 5.f; std::shared_ptr physics = m_World->AddComponent(ent); @@ -147,9 +148,7 @@ public: auto plight = m_World->AddComponent(ent); plight->Radius = 2.f; - m_World->CommitEntity(ent); - - + m_World->CommitEntity(ent); } //PointLightTest @@ -159,60 +158,136 @@ public: transform->Position = glm::vec3(2.f, 1.5f, -9.f); auto pl = m_World->AddComponent(t_Light); pl->Radius = 8.f; + m_World->CommitEntity(t_Light); } //Halfpipe background test model. { auto t_halfPipe = m_World->CreateEntity(); auto transform = m_World->AddComponent(t_halfPipe); - transform->Position = glm::vec3(0.f, 0.f, -13.f); - transform->Scale = glm::vec3(5.f); + transform->Position = glm::vec3(0.f, 0.f, -15.f); + transform->Scale = glm::vec3(15.f); auto model = m_World->AddComponent(t_halfPipe); model->ModelFile = "Models/Test/halfpipe/Halfpipe.obj"; + model->Color = glm::vec4(1.f, 1.f, 1.f, 0.3f); + m_World->CommitEntity(t_halfPipe); } + //Background + { + auto background = m_World->CreateEntity(); + auto transform = m_World->AddComponent(background); + transform->Position = glm::vec3(0.f, 0.f, -30.f); + transform->Scale = glm::vec3(2681.f / 50.f, 1080.f / 50.f, 1.f); + auto sprite = m_World->AddComponent(background); + sprite->SpriteFile = "Textures/Background.png"; + m_World->CommitEntity(background); + } + + //Water test + { + auto t_waterBody = m_World->CreateEntity(); + auto transform = m_World->AddComponent(t_waterBody); + transform->Position = glm::vec3(0.f, -4.5f, -10.f); + transform->Scale = glm::vec3(7.f, 1.5f, 1.f); + auto water = m_World->AddComponent(t_waterBody); + auto body = m_World->AddComponent(t_waterBody); + m_World->CommitEntity(t_waterBody); + } + //TODO: Why does the ball not collide with these bricks? + //BottomBox + { + auto topWall = m_World->CreateEntity(); + auto transform = m_World->AddComponent(topWall); + transform->Position = glm::vec3(0.f, -6.f, -9.9f); + transform->Scale = glm::vec3(10.f, 0.5f, 1.f); + std::shared_ptr sprite = m_World->AddComponent(topWall); + sprite->SpriteFile = "Textures/Core/ErrorTexture.png"; + std::shared_ptr boxShape = m_World->AddComponent( + topWall); + std::shared_ptr physics = m_World->AddComponent(topWall); + physics->Static = true; + m_World->CommitEntity(topWall); + } + //SideBox +// { +// auto topWall = m_World->CreateEntity(); +// std::shared_ptr transform = m_World->AddComponent(topWall); +// transform->Position = glm::vec3(3.f, -3.0f, -9.9f); +// transform->Scale = glm::vec3(0.5f, 3.f, 1.f); +// std::shared_ptr sprite = m_World->AddComponent(topWall); +// sprite->SpriteFile = "Textures/Core/ErrorTexture.png"; +// std::shared_ptr boxShape = m_World->AddComponent( +// topWall); +// std::shared_ptr physics = m_World->AddComponent(topWall); +// physics->Static = true; +// m_World->CommitEntity(topWall); +// } +// //OtherSideBox +// { +// auto topWall = m_World->CreateEntity(); +// std::shared_ptr transform = m_World->AddComponent(topWall); +// transform->Position = glm::vec3(-4.f, -3.0f, -9.9f); +// transform->Scale = glm::vec3(0.5f, 3.0f, 1.f); +// std::shared_ptr sprite = m_World->AddComponent(topWall); +// sprite->SpriteFile = "Textures/Core/ErrorTexture.png"; +// std::shared_ptr boxShape = m_World->AddComponent( +// topWall); +// std::shared_ptr physics = m_World->AddComponent(topWall); +// physics->Static = true; +// m_World->CommitEntity(topWall); +// } + { auto topWall = m_World->CreateEntity(); - std::shared_ptr transform = m_World->AddComponent(topWall); + std::shared_ptr transform = m_World->AddComponent( + topWall); transform->Position = glm::vec3(0.f, 6.f, -10.f); transform->Scale = glm::vec3(20.f, 0.5f, 1.f); std::shared_ptr sprite = m_World->AddComponent(topWall); sprite->SpriteFile = "Textures/Core/ErrorTexture.png"; - std::shared_ptr boxShape = m_World->AddComponent(topWall); + std::shared_ptr boxShape = m_World->AddComponent( + topWall); std::shared_ptr physics = m_World->AddComponent(topWall); physics->Static = true; m_World->CommitEntity(topWall); } + { auto leftWall = m_World->CreateEntity(); - std::shared_ptr transform = m_World->AddComponent(leftWall); + std::shared_ptr transform = m_World->AddComponent( + leftWall); transform->Position = glm::vec3(-4.f, 1.f, -10.f); transform->Scale = glm::vec3(0.5f, 20.f, 1.f); std::shared_ptr sprite = m_World->AddComponent(leftWall); sprite->SpriteFile = "Textures/Core/ErrorTexture.png"; - std::shared_ptr boxShape = m_World->AddComponent(leftWall); + std::shared_ptr boxShape = m_World->AddComponent( + leftWall); std::shared_ptr physics = m_World->AddComponent(leftWall); physics->Static = true; m_World->CommitEntity(leftWall); } + { auto rightWall = m_World->CreateEntity(); - std::shared_ptr transform = m_World->AddComponent(rightWall); + std::shared_ptr transform = m_World->AddComponent( + rightWall); transform->Position = glm::vec3(4.f, 1.f, -10.f); transform->Scale = glm::vec3(0.5f, 20.f, 1.f); std::shared_ptr sprite = m_World->AddComponent(rightWall); sprite->SpriteFile = "Textures/Core/ErrorTexture.png"; - std::shared_ptr boxShape = m_World->AddComponent(rightWall); + std::shared_ptr boxShape = m_World->AddComponent( + rightWall); std::shared_ptr physics = m_World->AddComponent(rightWall); physics->Static = true; @@ -235,7 +310,7 @@ public: m_World->CommitEntity(ent); } - m_LastTime = glfwGetTime(); + m_LastTime = glfwGetTime(); } bool Running() const { return !glfwWindowShouldClose(m_Renderer->Window()); } @@ -256,7 +331,6 @@ public: m_World->Update(dt); m_EventBroker->Process(); m_FrameStack->UpdateLayered(dt); - if (glfwGetKey(m_Renderer->Window(), GLFW_KEY_R)) { ResourceManager::Reload("Shaders/Deferred/3/Fragment.glsl"); } @@ -315,8 +389,6 @@ public: } } - //TODO: Add LightLoadShit - auto pointLightComponent = m_World->GetComponent(entity); if (pointLightComponent) { @@ -327,6 +399,19 @@ public: pointLightComponent->Radius); } + auto parent = m_World->GetEntityParent(entity); + if(parent != 0) { + auto waterParticleComponent = m_World->GetComponent(parent); + if (waterParticleComponent) { + //TODO: Remove hardcoded color. + //TODO: Do i even need modelMatrix? + Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity); + glm::mat4 modelMatrix = glm::translate(absoluteTransform.Position) + * glm::scale(absoluteTransform.Scale); + EnqueueWaterParticles(absoluteTransform.Position, glm::vec4(1.f, 1.f, 1.f, 1.f), modelMatrix, absoluteTransform.Position.z); + } + } + auto spriteComponent = m_World->GetComponent(entity); if (spriteComponent) @@ -407,6 +492,17 @@ public: } + void EnqueueWaterParticles(glm::vec3 position, glm::vec4 color, glm::mat4 modelMatrix, float depth) + { + WaterParticleJob job; + job.Position = position; + job.Color = color; + job.ModelMatrix = modelMatrix; + job.Depth = depth; + + m_RendererQueue.Forward.Add(job); + } + private: std::shared_ptr m_EventBroker; GUI::Frame* m_FrameStack = nullptr; diff --git a/include/Core/RenderQueue.h b/include/Core/RenderQueue.h index 64821ff..0319267 100755 --- a/include/Core/RenderQueue.h +++ b/include/Core/RenderQueue.h @@ -130,6 +130,18 @@ struct FrameJob : SpriteJob } }; +struct WaterParticleJob : RenderJob +{ + glm::vec3 Position; + glm::vec4 Color; + glm::mat4 ModelMatrix; + + void CalculateHash() override + { + Hash = 0; + } +}; + class RenderQueue { public: @@ -138,6 +150,7 @@ public: { job.CalculateHash(); Jobs.push_back(std::shared_ptr(new T(job))); + m_Size++; } void Sort() @@ -148,8 +161,10 @@ public: void Clear() { Jobs.clear(); + m_Size = 0; } + int Size() const { return m_Size; } std::list>::const_iterator begin() { return Jobs.begin(); @@ -161,6 +176,9 @@ public: } std::list> Jobs; + +private: + int m_Size = 0; }; struct RenderQueueCollection diff --git a/include/Core/Renderer.h b/include/Core/Renderer.h index c4d0068..5a2b03f 100755 --- a/include/Core/Renderer.h +++ b/include/Core/Renderer.h @@ -72,12 +72,15 @@ private: ShaderProgram* m_spDeferred3; ShaderProgram* m_spForward; ShaderProgram* m_spScreen; + ShaderProgram* t_m_spWater; + ShaderProgram* t_m_spWater2; GLuint m_ScreenQuad = 0; Model* m_UnitSphere = nullptr; Model* m_UnitQuad = nullptr; Texture* m_StandardNormal; Texture* m_StandardSpecular; + Texture* t_m_WhiteSphereTexture; GLuint m_rbDepthBuffer = 0; GLuint m_fbDeferred1 = 0; @@ -89,11 +92,23 @@ private: GLuint m_tLighting = 0; GLuint m_fbDeferred3 = 0; GLuint m_tFinal = 0; + //Water GTexture + GLuint t_m_Gwater = 0; + //Water blur texture + GLuint t_m_BWater; + GLuint t_m_BWater2; + //WAterpass Framebuffer + GLuint t_m_fbWater; + //Waterpass Framebuffer + GLuint t_m_fbWaterBlur; + GLuint t_m_fbWaterBlur2; + GLuint m_CurrentScreenBuffer = 0; void LoadShaders(); void CreateBuffers(); GLuint CreateQuad(); + GLuint CreateWaterParticleVAO(RenderQueue &particles); static bool DepthSort(const std::shared_ptr &i, const std::shared_ptr &j) { return (i->Depth < j->Depth); } @@ -101,6 +116,7 @@ private: void DrawForward(RenderQueue &objects, RenderQueue &lights); void DrawScene(RenderQueue &objects, ShaderProgram &program); void DrawLightSpheres(RenderQueue &lights); + void DrawWater(RenderQueue &objects); void DrawGUI(RenderQueue& rq); void DebugKeys(); }; diff --git a/include/Game/LevelSystem.h b/include/Game/LevelSystem.h index f7f9170..545d2fb 100755 --- a/include/Game/LevelSystem.h +++ b/include/Game/LevelSystem.h @@ -19,12 +19,12 @@ #include "Game/ELifeLost.h" #include "Game/EResetBall.h" #include "Game/EScoreEvent.h" +#include "Physics/CRectangleShape.h" #include "Game/EMultiBall.h" #include "Game/EGameOver.h" #include "Game/ECreatePowerUp.h" #include "Game/EPowerUpTaken.h" #include "Game/Bricks/CPowerUpBrick.h" -#include "Physics/CBoxShape.h" #include "Physics/CPhysics.h" #include "Physics/CCircleShape.h" #include "Physics/ESetImpulse.h" diff --git a/include/Game/LevelSystem.h.orig b/include/Game/LevelSystem.h.orig new file mode 100755 index 0000000..5e56ad3 --- /dev/null +++ b/include/Game/LevelSystem.h.orig @@ -0,0 +1,149 @@ +// +// Created by Adniklastrator on 2015-09-09. +// + +#ifndef DAYDREAM_LEVELSYSTEM_H +#define DAYDREAM_LEVELSYSTEM_H + +#include "Core/System.h" +#include "Core/CTransform.h" +#include "Core/EventBroker.h" +#include "Core/World.h" +#include "Rendering/CSprite.h" +#include "Rendering/CModel.h" +#include "Game/CBrick.h" +#include "Game/CBall.h" +#include "Game/CLife.h" +#include "Game/CPowerUp.h" +#include "Game/EStageCleared.h" +#include "Game/ELifeLost.h" +#include "Game/EResetBall.h" +#include "Game/EScoreEvent.h" +<<<<<<< HEAD +#include "Physics/CRectangleShape.h" +======= +#include "Game/EMultiBall.h" +#include "Game/EGameOver.h" +#include "Game/ECreatePowerUp.h" +#include "Game/EPowerUpTaken.h" +#include "Game/Bricks/CPowerUpBrick.h" +#include "Physics/CBoxShape.h" +>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db +#include "Physics/CPhysics.h" +#include "Physics/CCircleShape.h" +#include "Physics/ESetImpulse.h" +#include "Physics/EContact.h" +#include "Sound/CCollisionSound.h" +#include "Game/PadSystem.h" +#include +#include +#include + +namespace dd +{ + +namespace Systems +{ + + // Me trying things out. +class Level +{ +public: + int levelRows; + int levelLines; + int levelSpaceBetweenBricks; + int levelSpaceToEdge; + int bricks[]; +}; + +class LevelSystem : public System +{ +public: + LevelSystem(World* world, std::shared_ptr eventBroker) + : System(world, eventBroker) + { } + + void Initialize() override; + + void CreateBasicLevel(int, int, glm::vec2, float); + void CreateLife(int); + void SaveLevel(int, int, glm::vec2, int); // Shouldn't be here, but I'm experimenting. + void LoadLevel(char[20]); + void CreateBrick(int, int, glm::vec2, float, int); + void ProcessCollision(); + + void OnEntityRemoved(EntityID entity); + + void EndLevel(); + + void Update(double dt) override; + void UpdateEntity(double dt, EntityID entity, EntityID parent) override; + + bool Restarting() const { return m_Restarting; } + void SetRestarting(const bool& restarting) { m_Restarting = restarting; } + bool Initialized() const { return m_Initialized; } + void SetInitialized(const bool& initialized) { m_Initialized = initialized; } + int& Lives() { return m_Lives; } + void SetLives(const int& lives) { m_Lives = lives; } + int& PastLives() { return m_PastLives; } + void SetPastLives(const int& pastLives) { m_PastLives = pastLives; } + int& MultiBalls() { return m_MultiBalls; } + void SetMultiBalls(const int& multiBalls) { m_MultiBalls = multiBalls; } + int& PowerUps() { return m_PowerUps; } + void SetPowerUps(const int& powerUps) { m_PowerUps = powerUps; } + int& Score() { return m_Score; } + void SetScore(const int& score) { m_Score = score; } + int& NumberOfBricks() { return m_NumberOfBricks; } + void SetNumberOfBricks(const int& numberOfBricks) { m_NumberOfBricks = numberOfBricks; } + int& Rows() { return m_Rows; } + void SetRows(const int& rows) { m_Rows = rows; } + int& Lines() { return m_Lines; } + void SetLines(const int& lines) { m_Lines = lines; } + float& SpaceToEdge() { return m_SpaceToEdge; } + void SetSpaceToEdge(const float& spaceToEdge) { m_SpaceToEdge = spaceToEdge; } + + glm::vec2& SpaceBetweenBricks() { return m_SpaceBetweenBricks; } + void SetSpaceBetweenBricks(const glm::vec2& spaceBetweenBricks) { m_SpaceBetweenBricks = spaceBetweenBricks; } + float& EdgeX() { return m_EdgeX; } + void SetEdgeX(const float& edgeX) { m_EdgeX = edgeX; } + float& EdgeY() { return m_EdgeY; } + void SetEdgeY(const float& edgeY) { m_EdgeY = edgeY; } + +private: + bool m_Restarting = false; + bool m_Initialized = false; + int m_Lives = 3; + int m_PastLives = 3; + int m_MultiBalls = 0; + int m_PowerUps = 0; + int m_Score = 0; + int m_NumberOfBricks; + int m_Rows = 6; + int m_Lines = 7; + float m_SpaceToEdge = 0.25f; + glm::vec2 m_SpaceBetweenBricks = glm::vec2(1, 0.4); + float m_EdgeX = 3.2f; + float m_EdgeY = 5.2f; + + dd::EventRelay m_EContact; + dd::EventRelay m_ELifeLost; + dd::EventRelay m_EScoreEvent; + dd::EventRelay m_EMultiBall; + dd::EventRelay m_ECreatePowerUp; + dd::EventRelay m_EPowerUpTaken; + dd::EventRelay m_EStageCleared; + + bool OnContact(const dd::Events::Contact &event); + bool OnLifeLost(const dd::Events::LifeLost &event); + bool OnScoreEvent(const dd::Events::ScoreEvent &event); + bool OnMultiBall(const dd::Events::MultiBall &event); + bool OnCreatePowerUp(const dd::Events::CreatePowerUp &event); + bool OnPowerUpTaken(const dd::Events::PowerUpTaken &event); + bool OnStageCleared(const dd::Events::StageCleared &event); +}; + +} + +} + +#endif //DAYDREAM_LEVELSYSTEM_H diff --git a/include/Game/PadSystem.h b/include/Game/PadSystem.h index a4e5f9e..4a53907 100755 --- a/include/Game/PadSystem.h +++ b/include/Game/PadSystem.h @@ -14,7 +14,7 @@ #include "Core/EKeyUp.h" #include "Input/EBindKey.h" #include "Physics/EContact.h" -#include "Physics/CBoxShape.h" +#include "Physics/CRectangleShape.h" #include "Physics/CPhysics.h" #include "Physics/CCircleShape.h" #include "Physics/ESetImpulse.h" diff --git a/include/Physics/CBoxShape.h b/include/Physics/CRectangleShape.h similarity index 100% rename from include/Physics/CBoxShape.h rename to include/Physics/CRectangleShape.h diff --git a/include/Physics/CWaterVolume.h b/include/Physics/CWaterVolume.h new file mode 100755 index 0000000..33adcae --- /dev/null +++ b/include/Physics/CWaterVolume.h @@ -0,0 +1,19 @@ +#ifndef CWATERVOLUME_H +#define CWATERVOLUME_H +#include "Core/Component.h" + +namespace dd +{ +namespace Components +{ + +struct WaterVolume : public Component +{ + +}; + +} + +} + +#endif \ No newline at end of file diff --git a/include/Physics/PhysicsSystem.h b/include/Physics/PhysicsSystem.h old mode 100644 new mode 100755 index 3c456ce..4a53bdb --- a/include/Physics/PhysicsSystem.h +++ b/include/Physics/PhysicsSystem.h @@ -5,7 +5,7 @@ #include "Core/System.h" #include "Core/World.h" -#include "Physics/CBoxShape.h" +#include "CRectangleShape.h" #include "Physics/CPhysics.h" #include #include "Core/CTransform.h" @@ -15,6 +15,8 @@ #include "Physics/CCircleShape.h" #include "Core/EventBroker.h" #include "Game/CPad.h" +#include "Physics/CWaterVolume.h" +#include "Rendering/CSprite.h" namespace dd @@ -64,6 +66,15 @@ private: void CreateBody(EntityID entity); + b2ParticleSystem *m_ParticleSystem; + b2ParticleGroup* t_watergroup; + + std::unordered_map m_EntitiesToParticleHandle; + std::unordered_map m_ParticleHandleToEntities; + + void InitializeWater(); + void SyncWater(); //TODO: Probably remove this + void CreateParticleGroup(EntityID entity); struct Impulse { diff --git a/include/Physics/PhysicsSystem.h.orig b/include/Physics/PhysicsSystem.h.orig new file mode 100755 index 0000000..045c063 --- /dev/null +++ b/include/Physics/PhysicsSystem.h.orig @@ -0,0 +1,146 @@ +#ifndef DAYDREAM_PHYSICSSYSTEM_H +#define DAYDREAM_PHYSICSSYSTEM_H + +#include + +#include "Core/System.h" +#include "Core/World.h" +#include "CRectangleShape.h" +#include "Physics/CPhysics.h" +#include +#include "Core/CTransform.h" +#include "Transform/TransformSystem.h" +#include "Physics/EContact.h" +#include "Physics/ESetImpulse.h" +#include "Physics/CCircleShape.h" +#include "Core/EventBroker.h" +#include "Game/CPad.h" +#include "Physics/CWaterVolume.h" +#include "Rendering/CSprite.h" + + +namespace dd +{ + +namespace Systems +{ + + +class PhysicsSystem : public System +{ + friend class ContractListener; + +public: + PhysicsSystem(World* world, std::shared_ptr eventBroker) + : System(world, eventBroker) {} + + ~PhysicsSystem(); + + EventRelay m_SetImpulse; + bool SetImpulse(const Events::SetImpulse &event); + + void RegisterComponents(ComponentFactory* cf) override; + void Initialize() override; + + // Called once per system every tick + void Update(double dt) override; + // Called once for every entity in the world every tick + void UpdateEntity(double dt, EntityID entity, EntityID parent) override; + + // Called when components are committed to an entity + void OnEntityCommit(EntityID entity) override; + + // Called when an entity is removed + void OnEntityRemoved(EntityID entity) override; + +private: + b2Vec2 m_Gravity; + b2World* m_PhysicsWorld; + float m_TimeStep; + float m_Accumulator; + + int m_VelocityIterations, m_PositionIterations; + + std::unordered_map m_EntitiesToBodies; + std::unordered_map m_BodiesToEntities; + + void CreateBody(EntityID entity); + + b2ParticleSystem *m_ParticleSystem; + b2ParticleGroup* t_watergroup; + + std::unordered_map m_EntitiesToParticleHandle; + std::unordered_map m_ParticleHandleToEntities; + + void InitializeWater(); + void SyncWater(); //TODO: Probably remove this + void CreateParticleGroup(EntityID entity); + + struct Impulse + { + b2Body* Body; + b2Vec2 Impulse; + b2Vec2 Point; + }; + std::list m_Impulses; + + + + class ContactListener : public b2ContactListener + { + public: + ContactListener(PhysicsSystem* physicsSystem) + : m_PhysicsSystem(physicsSystem) { } + + void BeginContact(b2Contact* contact) + { + b2WorldManifold worldManifold; + + contact->GetWorldManifold(&worldManifold); + + Events::Contact e; + e.Entity1 = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()]; + e.Entity2 = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureB()->GetBody()]; +<<<<<<< HEAD + e.Normal = glm::normalize(glm::vec2(worldManifold.normal.x, worldManifold.normal.y)); +======= + e.Normal = glm::normalize(glm::vec2(contact->GetManifold()->localNormal.x, contact->GetManifold()->localNormal.y)); + e.SignificantNormal = glm::normalize((glm::abs(e.Normal.x) > glm::abs(e.Normal.y)) ? glm::vec2(e.Normal.x, 0) : glm::vec2(0, e.Normal.y)); +>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db + + m_PhysicsSystem->EventBroker->Publish(e); + } + void EndContact(b2Contact* contact) + { + + } + void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) + { + EntityID entityA = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()]; + EntityID entityB = m_PhysicsSystem->m_BodiesToEntities[contact->GetFixtureA()->GetBody()]; + + auto physicsComponentA = m_PhysicsSystem->m_World->GetComponent(entityA); + auto physicsComponentB = m_PhysicsSystem->m_World->GetComponent(entityB); + + if (physicsComponentA != nullptr || physicsComponentB != nullptr) { + // Turn of collisions + contact->SetEnabled(false); + } + + } + void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) + { + + } + + private: + PhysicsSystem* m_PhysicsSystem; + }; + + ContactListener* m_ContactListener; +}; + +} +} + +#endif //DAYDREAM_PHYSICSSYSTEM_H diff --git a/src/game/Core/Renderer.cpp b/src/game/Core/Renderer.cpp index 0c93e1d..2226ba2 100755 --- a/src/game/Core/Renderer.cpp +++ b/src/game/Core/Renderer.cpp @@ -91,6 +91,12 @@ void dd::Renderer::LoadShaders() //glBindFragDataLocation(m_SPDeferred2, 0, "FragmentLighting"); m_spDeferred2->Link(); + //Water Pass + t_m_spWater = ResourceManager::Load("Shaders/Deferred/water/"); + t_m_spWater->Link(); + t_m_spWater2 = ResourceManager::Load("Shaders/Deferred/water2/"); + t_m_spWater2->Link(); + // Pass #3: Combining into final image m_spDeferred3 = ResourceManager::Load("Shaders/Deferred/3/"); m_spDeferred3->Link(); @@ -110,11 +116,13 @@ void dd::Renderer::LoadShaders() void dd::Renderer::CreateBuffers() { + //TODO: Make the most common cases of texture create and FBO create into a function so it's not so cluttered in here. m_ScreenQuad = CreateQuad(); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj"); m_StandardNormal = ResourceManager::Load("Textures/Core/NeutralNormalMap.png"); m_StandardSpecular = ResourceManager::Load("Textures/Core/NeutralSpecularMap.png"); + t_m_WhiteSphereTexture = ResourceManager::Load("Textures/Test/Water.png"); glGenRenderbuffers(1, &m_rbDepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_rbDepthBuffer); @@ -149,6 +157,13 @@ void dd::Renderer::CreateBuffers() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glGenTextures(1, &t_m_Gwater); + glBindTexture(GL_TEXTURE_2D, t_m_Gwater); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Create first pass framebuffer glGenFramebuffers(1, &m_fbDeferred1); @@ -185,14 +200,75 @@ void dd::Renderer::CreateBuffers() exit(EXIT_FAILURE); } + //Fill Water Texture + glGenTextures(1, &t_m_Gwater); + glBindTexture(GL_TEXTURE_2D, t_m_Gwater); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Fill water pass + glGenFramebuffers(1, &t_m_fbWater); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWater); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_Gwater, 0); + GLenum waterPassDrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, waterPassDrawBuffers); + if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus); + exit(EXIT_FAILURE); + } + + //water Blur texture + glGenTextures(1, &t_m_BWater); + glBindTexture(GL_TEXTURE_2D, t_m_BWater); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + //Fill waterBlur pass + glGenFramebuffers(1, &t_m_fbWaterBlur); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_BWater, 0); + GLenum waterBlurDrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, waterBlurDrawBuffers); + if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus); + exit(EXIT_FAILURE); + } + + //water Blur texture2 + glGenTextures(1, &t_m_BWater2); + glBindTexture(GL_TEXTURE_2D, t_m_BWater2); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbDepthBuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + //Fill waterBlur pass2 + glGenFramebuffers(1, &t_m_fbWaterBlur2); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur2); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_BWater2, 0); + GLenum waterBlur2DrawBuffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, waterBlur2DrawBuffers); + if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus); + exit(EXIT_FAILURE); + } + // Generate final deferred texture glGenTextures(1, &m_tFinal); glBindTexture(GL_TEXTURE_2D, m_tFinal); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Create third pass framebuffer glGenFramebuffers(1, &m_fbDeferred3); @@ -209,13 +285,13 @@ void dd::Renderer::CreateBuffers() void dd::Renderer::Draw(RenderQueueCollection& rq) { - DrawDeferred(rq.Deferred, rq.Lights); rq.Forward.Jobs.sort(dd::Renderer::DepthSort); + DrawDeferred(rq.Deferred, rq.Lights); DrawForward(rq.Forward, rq.Lights); DrawGUI(rq.GUI); // Finally: Draw the deferred+forward combined texture to the screen - glCullFace(GL_BACK); + glDisable(GL_CULL_FACE); glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); @@ -257,7 +333,7 @@ void dd::Renderer::DrawDeferred(RenderQueue &objects, RenderQueue &lights) glBlendFunc(GL_ONE, GL_ONE); glDepthMask(GL_FALSE); glBindFramebuffer(GL_FRAMEBUFFER, m_fbDeferred2); - glClearColor(0, 0, 0, 1); + glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); m_spDeferred2->Bind(); DrawLightSpheres(lights); @@ -266,7 +342,7 @@ void dd::Renderer::DrawDeferred(RenderQueue &objects, RenderQueue &lights) glCullFace(GL_BACK); glDisable(GL_BLEND); glBindFramebuffer(GL_FRAMEBUFFER, m_fbDeferred3); - glClearColor(0, 0, 0, 1); + glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); m_spDeferred3->Bind(); glUniform3fv(glGetUniformLocation(*m_spDeferred3, "La"), 1, glm::value_ptr(glm::vec3(0.5f))); @@ -280,7 +356,6 @@ void dd::Renderer::DrawDeferred(RenderQueue &objects, RenderQueue &lights) void dd::Renderer::DrawForward(RenderQueue &objects, RenderQueue &lights) { - // Forward-render semi-transparent objects on top of the current framebuffer glDisable(GL_CULL_FACE); glCullFace(GL_BACK); @@ -296,6 +371,19 @@ void dd::Renderer::DrawForward(RenderQueue &objects, RenderQueue &lights) m_spForward->Bind(); DrawScene(objects, *m_spForward); + + //WaterPass + glDisable(GL_CULL_FACE); + glCullFace(GL_BACK); + glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWater); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + t_m_spWater->Bind(); + DrawWater(objects); } void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program) @@ -311,6 +399,7 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program) if (modelJob) { glm::mat4 modelMatrix = modelJob->ModelMatrix; MVP = PV * modelMatrix; + glUniform4fv(glGetUniformLocation(shaderProgramHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix)); @@ -318,7 +407,6 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program) glUniform3fv(glGetUniformLocation(shaderProgramHandle, "LightSpecular"), 1, glm::value_ptr(glm::vec3(1.f))); glUniform3fv(glGetUniformLocation(shaderProgramHandle, "LightDiffuse"), 1, glm::value_ptr(glm::vec3(1.f))); glUniform1f(glGetUniformLocation(shaderProgramHandle, "LightRadius"), 40.0f); - glUniform1f(glGetUniformLocation(shaderProgramHandle, "MaterialShininess"), modelJob->Shininess); glActiveTexture(GL_TEXTURE0); @@ -339,7 +427,6 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program) glBindTexture(GL_TEXTURE_2D, *m_StandardSpecular); } - glBindVertexArray(modelJob->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->ElementBuffer); glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); @@ -355,6 +442,7 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program) glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix)); + glUniform4fv(glGetUniformLocation(shaderProgramHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, spriteJob->DiffuseTexture); @@ -409,6 +497,112 @@ void dd::Renderer::DrawLightSpheres(RenderQueue &lights) } } +void dd::Renderer::DrawWater(RenderQueue &rq) +{ + GLuint shaderProgramHandle = *t_m_spWater; + + glm::mat4 projectionMatrix = m_Camera->ProjectionMatrix(); + glm::mat4 viewMatrix = m_Camera->ViewMatrix(); + glm::mat4 PV = projectionMatrix * viewMatrix; + glm::mat4 MVP; + for ( auto &job : rq ) { + auto waterJob = std::dynamic_pointer_cast(job); + if (waterJob) { + glm::mat4 modelMatrix = waterJob->ModelMatrix; + MVP = PV * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); + glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "M"), 1, GL_FALSE, + glm::value_ptr(modelMatrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "V"), 1, GL_FALSE, + glm::value_ptr(viewMatrix)); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, *t_m_WhiteSphereTexture); + + glBindVertexArray(m_UnitQuad->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_UnitQuad->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, m_UnitQuad->m_Indices.size(), GL_UNSIGNED_INT, 0, 0); + } + } + + + + //blur1 + shaderProgramHandle = *t_m_spWater2; + glDisable(GL_CULL_FACE); + glDepthMask(GL_FALSE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + t_m_spWater2->Bind(); + float radius = 3.f; + + glUniform2fv(glGetUniformLocation(shaderProgramHandle, "dir"), 1, glm::value_ptr(glm::vec2(1.0f, 0.0f))); + glUniform1f(glGetUniformLocation(shaderProgramHandle, "res"), m_Resolution.Width); + glUniform1f(glGetUniformLocation(shaderProgramHandle, "radius"), radius); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, t_m_Gwater); + glBindVertexArray(m_ScreenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + + + //blur2 + shaderProgramHandle = *t_m_spWater2; + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glBindFramebuffer(GL_FRAMEBUFFER, m_fbDeferred3); + t_m_spWater2->Bind(); + + glUniform2fv(glGetUniformLocation(shaderProgramHandle, "dir"), 1, glm::value_ptr(glm::vec2(0.0f, 1.0f))); + glUniform1f(glGetUniformLocation(shaderProgramHandle, "res"), m_Resolution.Height); + glUniform1f(glGetUniformLocation(shaderProgramHandle, "radius"), radius); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, t_m_BWater); + glBindVertexArray(m_ScreenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); +} + + + +GLuint dd::Renderer::CreateWaterParticleVAO(RenderQueue &particles) +{ + float waterVerts[particles.Size()]; + int i = 0; + + for ( auto &job : particles ) { + auto waterJob = std::dynamic_pointer_cast(job); + if (!waterJob) + continue; + waterVerts[i ] = waterJob->Position.x; + waterVerts[i+1] = waterJob->Position.y; + waterVerts[i+2] = waterJob->Position.z; + i+3; + } + + GLuint vbo[1], vao; + glGenBuffers(1, vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); + glBufferData(GL_ARRAY_BUFFER, 3 * particles.Size() * sizeof(float), waterVerts, GL_STATIC_DRAW); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + return vao; +} + GLuint dd::Renderer::CreateQuad() { float quadVertices[] = @@ -472,6 +666,12 @@ void dd::Renderer::DebugKeys() if (glfwGetKey(m_Window, GLFW_KEY_F6)) { m_CurrentScreenBuffer = m_tLighting; } + if (glfwGetKey(m_Window, GLFW_KEY_F7)) { + m_CurrentScreenBuffer = t_m_Gwater; + } + if (glfwGetKey(m_Window, GLFW_KEY_F8)) { + m_CurrentScreenBuffer = t_m_BWater; + } } void dd::Renderer::DrawGUI(dd::RenderQueue& rq) diff --git a/src/game/Core/Shaders/Deferred/1/Fragment.glsl b/src/game/Core/Shaders/Deferred/1/Fragment.glsl old mode 100644 new mode 100755 index 927a681..8f7dbed --- a/src/game/Core/Shaders/Deferred/1/Fragment.glsl +++ b/src/game/Core/Shaders/Deferred/1/Fragment.glsl @@ -24,6 +24,7 @@ layout (binding = 2) uniform sampler2D SpecularMap; uniform mat4 V; uniform float MaterialShininess; +uniform vec4 Color; in VertexData { @@ -49,6 +50,7 @@ void main() { // Diffuse Texture GDiffuse = texture(DiffuseTexture, Input.TextureCoord) * Input.DiffuseColor; + GDiffuse = GDiffuse * Color; // G-buffer Position GPosition = vec4(Input.Position.xyz, 1.0); diff --git a/src/game/Core/Shaders/Deferred/water/Fragment.glsl b/src/game/Core/Shaders/Deferred/water/Fragment.glsl new file mode 100755 index 0000000..dc9d544 --- /dev/null +++ b/src/game/Core/Shaders/Deferred/water/Fragment.glsl @@ -0,0 +1,90 @@ +/* + This file is part of Daydream Engine. + Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung + + Daydream Engine is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Daydream Engine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Daydream Engine. If not, see . +*/ + +#version 440 + +layout (binding=0) uniform sampler2D DiffuseTexture; +layout (binding=1) uniform sampler2D NormalMap; +layout (binding=2) uniform sampler2D SpecularMap; + +uniform mat4 MVP; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform vec3 LightPosition; +uniform float LightRadius; +uniform vec3 LightSpecular; +uniform vec3 LightDiffuse; + +in VertexData +{ + vec3 Position; + vec3 Normal; + vec3 Tangent; + vec3 BiTangent; + vec2 TextureCoord; + vec4 DiffuseColor; + vec4 SpecularColor; + vec4 BoneIndices1; + vec4 BoneIndices2; + vec4 BoneWeights1; + vec4 BoneWeights2; +} Input; + +out vec4 frag_Diffuse; + +vec4 phong(vec3 position, vec3 normal, vec3 specular, float specularExponent) +{ + // Diffuse + vec3 lightPos = vec3(V * vec4(LightPosition, 1.0)); + vec3 distanceToLight = lightPos - position; + vec3 directionToLight = normalize(distanceToLight); + float dotProd = dot(directionToLight, normal); + dotProd = max(dotProd, 0.0); + vec3 Idiffuse = LightDiffuse * dotProd; + + // Specular + //vec3 reflection = reflect(-directionToLight, normal); + vec3 surfaceToViewer = normalize(-position); + vec3 halfWay = normalize(surfaceToViewer + directionToLight); + float dotSpecular = max(dot(halfWay, normal), 0.0); + float specularFactor = pow(dotSpecular, specularExponent); + vec3 Ispecular = specular * LightSpecular * specularFactor; + + //Attenuation + float dist = distance(lightPos, position); + //float attenuation = 1.0 - pow(dist / LightRadius, 2); + float attenuation = pow(max(0.0f, 1.0 - (dist / LightRadius)), 2); + + return vec4((Idiffuse + Ispecular) * attenuation, 1.0); +} + +void main() +{ + vec4 normalTexel = texture(NormalMap, Input.TextureCoord); + mat3 TBN = mat3(Input.Tangent, Input.BiTangent, Input.Normal); + vec3 normal = normalize(vec4(TBN * normalTexel.xyz, 0.0).xyz); + + vec4 specularTexel = texture(SpecularMap, Input.TextureCoord); + + vec4 diffuseTexel = texture(DiffuseTexture, Input.TextureCoord); + vec4 La = vec4(0.3, 0.3, 0.3, 1.0); + vec4 light = phong(Input.Position, normalize(normal), specularTexel.rgb, specularTexel.a); + //frag_Diffuse = light; + frag_Diffuse = diffuseTexel; +} \ No newline at end of file diff --git a/src/game/Core/Shaders/Deferred/water/Vertex.glsl b/src/game/Core/Shaders/Deferred/water/Vertex.glsl new file mode 100755 index 0000000..64a9e26 --- /dev/null +++ b/src/game/Core/Shaders/Deferred/water/Vertex.glsl @@ -0,0 +1,83 @@ +/* + This file is part of Daydream Engine. + Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung + + Daydream Engine is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Daydream Engine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Daydream Engine. If not, see . +*/ + +#version 440 + +uniform mat4 MVP; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform mat4 Bones[100]; + +layout (location = 0) in vec3 Position; +layout (location = 1) in vec3 Normal; +layout (location = 2) in vec3 Tangent; +layout (location = 3) in vec3 BiTangent; +layout (location = 4) in vec2 TextureCoord; +layout (location = 5) in vec4 DiffuseColor; +layout (location = 6) in vec4 SpecularColor; +layout (location = 7) in vec4 BoneIndices1; +layout (location = 8) in vec4 BoneIndices2; +layout (location = 9) in vec4 BoneWeights1; +layout (location = 10) in vec4 BoneWeights2; + +out VertexData +{ + vec3 Position; + vec3 Normal; + vec3 Tangent; + vec3 BiTangent; + vec2 TextureCoord; + vec4 DiffuseColor; + vec4 SpecularColor; + vec4 BoneIndices1; + vec4 BoneIndices2; + vec4 BoneWeights1; + vec4 BoneWeights2; +} Output; + +void main() +{ + mat4 boneTransform = mat4(1); + if (length(BoneWeights1 + BoneWeights2) > 0) { + boneTransform = BoneWeights1[0] * Bones[int(BoneIndices1[0])] + + BoneWeights1[1] * Bones[int(BoneIndices1[1])] + + BoneWeights1[2] * Bones[int(BoneIndices1[2])] + + BoneWeights1[3] * Bones[int(BoneIndices1[3])] + + BoneWeights2[0] * Bones[int(BoneIndices2[0])] + + BoneWeights2[1] * Bones[int(BoneIndices2[1])] + + BoneWeights2[2] * Bones[int(BoneIndices2[2])] + + BoneWeights2[3] * Bones[int(BoneIndices2[3])]; + } + + //gl_Position = MVP * boneTransform * vec4(Position, 1.0); + gl_Position = MVP * vec4(Position, 1.0); + + //TODO: Make sure that boneTransform works here. + Output.Position = (V * M * boneTransform * vec4(Position, 1.0)).xyz; + Output.Normal = (inverse(transpose(V * M)) * boneTransform * vec4(Normal, 0.0)).xyz; + Output.Tangent = Tangent; + Output.BiTangent = BiTangent; + Output.TextureCoord = TextureCoord; + Output.DiffuseColor = DiffuseColor; + Output.SpecularColor = SpecularColor; + Output.BoneIndices1 = BoneIndices1; + Output.BoneIndices2 = BoneIndices2; + Output.BoneWeights1 = BoneWeights1; + Output.BoneWeights2 = BoneWeights2; +} \ No newline at end of file diff --git a/src/game/Core/Shaders/Deferred/water2/Fragment.glsl b/src/game/Core/Shaders/Deferred/water2/Fragment.glsl new file mode 100755 index 0000000..b82af8f --- /dev/null +++ b/src/game/Core/Shaders/Deferred/water2/Fragment.glsl @@ -0,0 +1,70 @@ +/* + This file is part of Daydream Engine. + Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung + + Daydream Engine is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Daydream Engine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Daydream Engine. If not, see . +*/ + +#version 440 + +uniform vec2 dir; +uniform float res; +uniform float radius; + +layout (binding=0) uniform sampler2D WaterTexture; + +in VertexData +{ + vec3 Position; + vec2 TextureCoord; +} Input; + +out vec4 frag_Diffuse; + +void main() +{ + vec4 WaterTexel = texture(WaterTexture, Input.TextureCoord); + + vec4 sum = vec4(0.0); + vec2 tc = Input.TextureCoord; + + //How much blur, 1 = blur by one pixel. + float blur = radius/res; + + float hstep = dir.x; + float vstep = dir.y; + + float Threshhold = 0.1; + + //apply filter using a 9 tap filter with predefined gaussian weights + + sum += texture(WaterTexture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162; + sum += texture(WaterTexture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541; + sum += texture(WaterTexture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216; + sum += texture(WaterTexture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946; + + sum += texture(WaterTexture, vec2(tc.x, tc.y)) * 0.2270270270; + + sum += texture(WaterTexture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946; + sum += texture(WaterTexture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216; + sum += texture(WaterTexture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541; + sum += texture(WaterTexture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162; + + frag_Diffuse = vec4(sum.rgb, 1.0) * vec4(0.0, 0.6, 1.5, 1.0); + float avgColor = frag_Diffuse.r + frag_Diffuse.g + frag_Diffuse.b; + avgColor = avgColor/3; + if ( avgColor*dir.y > Threshhold ){ + frag_Diffuse = vec4(0.0, 0.3, 1.0, 1.0); + } +} \ No newline at end of file diff --git a/src/game/Core/Shaders/Deferred/water2/Vertex.glsl b/src/game/Core/Shaders/Deferred/water2/Vertex.glsl new file mode 100755 index 0000000..08bb198 --- /dev/null +++ b/src/game/Core/Shaders/Deferred/water2/Vertex.glsl @@ -0,0 +1,34 @@ +/* + This file is part of Daydream Engine. + Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung + + Daydream Engine is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Daydream Engine is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Daydream Engine. If not, see . +*/ + +#version 440 + +layout (location = 0) in vec3 Position; + +out VertexData +{ + vec3 Position; + vec2 TextureCoord; +} Output; + +void main() +{ + gl_Position = vec4(Position, 1.0); + Output.Position = Position; + Output.TextureCoord = (vec2(Position) + 1) / 2; +} \ No newline at end of file diff --git a/src/game/Game/PadSystem.cpp b/src/game/Game/PadSystem.cpp index 0b3b252..9926f08 100755 --- a/src/game/Game/PadSystem.cpp +++ b/src/game/Game/PadSystem.cpp @@ -72,6 +72,7 @@ void dd::Systems::PadSystem::Update(double dt) transform->Velocity += acceleration * (float)dt; transform->Velocity -= transform->Velocity * pad->SlowdownModifier * (float)dt; + if (Left()) { acceleration.x = -pad->AccelerationSpeed; } else if (Right()) { @@ -188,10 +189,9 @@ bool dd::Systems::PadSystem::OnContact(const dd::Events::Contact &event) //float movementX = (event.ContactPoint.x - transformPad->Position.x) * movementMultiplier; float movementY = glm::cos((abs(movementX) / ((1.6f) * movementMultiplier)) * 3.14159265359f / 2)+ 0.2; - //std::cout << movementX << " " << movementY << std::endl; - float len = glm::length(transformBall->Velocity); + //auto pointlight = m_World->AddComponent(ent); transformBall->Velocity += glm::vec3(transformPad->Velocity.x, 0, 0); diff --git a/src/game/Game/PadSystem.cpp.orig b/src/game/Game/PadSystem.cpp.orig new file mode 100755 index 0000000..7d21606 --- /dev/null +++ b/src/game/Game/PadSystem.cpp.orig @@ -0,0 +1,313 @@ +// +// Created by Adniklastrator on 2015-09-10. +// + +#include "PrecompiledHeader.h" +#include "Game/PadSystem.h" +#include "Core/World.h" +#include +#include +#include + + +void dd::Systems::PadSystem::Initialize() +{ + Events::BindKey r; + r.KeyCode = GLFW_KEY_RIGHT; + r.Command = "right"; + EventBroker->Publish(r); + + Events::BindKey l; + l.KeyCode = GLFW_KEY_LEFT; + l.Command = "left"; + EventBroker->Publish(l); + + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PadSystem::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PadSystem::OnKeyUp); + EVENT_SUBSCRIBE_MEMBER(m_EContact, &PadSystem::OnContact); + EVENT_SUBSCRIBE_MEMBER(m_EContactPowerUp, &PadSystem::OnContactPowerUp); + EVENT_SUBSCRIBE_MEMBER(m_EResetBall, &PadSystem::OnResetBall); + EVENT_SUBSCRIBE_MEMBER(m_EMultiBall, &PadSystem::OnMultiBall); + EVENT_SUBSCRIBE_MEMBER(m_EStageCleared, &PadSystem::OnStageCleared); +} + +void dd::Systems::PadSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) +{ + auto ball = m_World->GetComponent(entity); + if (ball != nullptr) { + if (ReplaceBall() == true) { + SetReplaceBall(false); + + auto transform = m_World->GetComponent(entity); + transform->Position = glm::vec3(0.0f, 0.26f, -10.f); + transform->Velocity = glm::vec3(0.0f, -ball->Speed, 0.f); + } + } +} + +void dd::Systems::PadSystem::Update(double dt) +{ + if (Entity() == 0) { + for (auto it = m_World->GetEntities()->begin(); it != m_World->GetEntities()->end(); it++) { + if (m_World->GetProperty(it->first, "Name") == "Pad") { + SetEntity(it->first); + SetTransform(m_World->GetComponent(Entity())); + SetPad(m_World->GetComponent(Entity())); + break; + } + } + } + + auto transform = Transform(); + auto pad = Pad(); + auto acceleration = Acceleration(); + + if (transform->Velocity.x < -pad->MaxSpeed) { + transform->Velocity.x = -pad->MaxSpeed; + } + else if (transform->Velocity.x > pad->MaxSpeed) { + transform->Velocity.x = pad->MaxSpeed; + } + transform->Position += transform->Velocity * (float)dt; + transform->Velocity += acceleration * (float)dt; + transform->Velocity -= transform->Velocity * pad->SlowdownModifier * (float)dt; + + + if (Left()) { + acceleration.x = -pad->AccelerationSpeed; +<<<<<<< HEAD + } + else if (Right()) { +======= + } else if (Right()) { +>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db + acceleration.x = pad->AccelerationSpeed; + } else { + acceleration.x = 0.f; + } + + SetTransform(transform); + SetPad(pad); + SetAcceleration(acceleration); + + if (MultiBall() == true) { + SetMultiBall(false); + + Events::MultiBall e; + e.padTransform = transform; + EventBroker->Publish(e); + } + + return; +} + +EntityID dd::Systems::PadSystem::CreateBall() +{ + auto ent = m_World->CreateEntity(); + std::shared_ptr transform = m_World->AddComponent(ent); + transform->Position = glm::vec3(0.5f, 0.26f, -10.f); + transform->Scale = glm::vec3(0.5f, 0.5f, 0.5f); + auto model = m_World->AddComponent(ent); + model->ModelFile = "Models/Test/Ball/Ballopus.obj"; + //auto pointlight = m_World->AddComponent(ent); + std::shared_ptr circleShape = m_World->AddComponent(ent); + std::shared_ptr cball = m_World->AddComponent(ent); + std::shared_ptr physics = m_World->AddComponent(ent); + physics->Static = false; + + cball->Speed = 10; + + m_World->CommitEntity(ent); + + return ent; +} + +bool dd::Systems::PadSystem::OnKeyDown(const dd::Events::KeyDown &event) +{ + int val = event.KeyCode; + if (val == GLFW_KEY_UP) { + //std::cout << "Up!" << std::endl; + } else if (val == GLFW_KEY_DOWN) { + //std::cout << "Down!" << std::endl; + } else if (val == GLFW_KEY_LEFT) { + //std::cout << "Left!" << std::endl; + //acceleration.x = -0.01f; + SetLeft(true); + } else if (val == GLFW_KEY_RIGHT) { + //std::cout << "Right!" << std::endl; + //acceleration.x = 0.01f; + SetRight(true); + } else if (val == GLFW_KEY_R) { + SetReplaceBall(true); + } else if (val == GLFW_KEY_M) { + SetMultiBall(true); + } else if (val == GLFW_KEY_D) { + return false; + } + return true; +} + +bool dd::Systems::PadSystem::OnKeyUp(const dd::Events::KeyUp &event) +{ + int val = event.KeyCode; + if (val == GLFW_KEY_UP) { + + } else if (val == GLFW_KEY_DOWN) { + + } else if (val == GLFW_KEY_LEFT) { + SetLeft(false); + } else if (val == GLFW_KEY_RIGHT) { + SetRight(false); + } + return true; +} + +bool dd::Systems::PadSystem::OnContact(const dd::Events::Contact &event) +{ + /* + EntityID entityBall = event.Entity2; + auto ball = m_World->GetComponent(entityBall); + if (ball == NULL) { + return false; + } + EntityID entityPad = event.Entity1; + auto pad = m_World->GetComponent(entityPad); + if (pad == NULL) { + return false; + } + auto transformBall = m_World->GetComponent(entityBall); + auto transformPad = m_World->GetComponent(entityPad); + + float movementMultiplier = 0.5f; + + //float movementX = (event.ContactPoint.x - transformPad->Position.x) * movementMultiplier; + //float movementY = glm::cos((abs(movementX) / (3.2f * movementMultiplier)) * 3.14159265359f / 2) * 2.f; + if (whatX > 0) { + movementX = movementMultiplier * whatX; + //std::cout << "Right!" << std::endl; + } else { + movementX = movementMultiplier * whatX; + //std::cout << "Left!" << std::endl; + } + + // std::cout << movementX << " " << movementY << std::endl; + + //float movementX = (event.ContactPoint.x - transformPad->Position.x) * movementMultiplier; +<<<<<<< HEAD + float movementY = glm::cos((abs(movementX) / ((1.6f) * movementMultiplier)) * 3.14159265359f / 2) + 1; +======= + float movementY = glm::cos((abs(movementX) / ((1.6f) * movementMultiplier)) * 3.14159265359f / 2)+ 0.2; +>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db + + //std::cout << movementX << " " << movementY << std::endl; + + float len = glm::length(transformBall->Velocity); + //auto pointlight = m_World->AddComponent(ent); + + + transformBall->Velocity += glm::vec3(transformPad->Velocity.x, 0, 0); + transformBall->Velocity = glm::normalize(transformBall->Velocity) * len; + + + //transform->Velocity = glm::vec3(movementX, movementY, 0.f); + */ +} + +bool dd::Systems::PadSystem::OnContactPowerUp(const dd::Events::Contact &event) +{ + EntityID entityPower; + EntityID entityPad; + auto powerUp = m_World->GetComponent(event.Entity1); + auto pad = m_World->GetComponent(event.Entity2); + if (powerUp != nullptr) { + entityPower = event.Entity1; + } else { + powerUp = m_World->GetComponent(event.Entity2); + if (powerUp != nullptr) { + entityPower = event.Entity2; + } + } + if (pad != nullptr) { + entityPad = event.Entity2; + } else { + pad = m_World->GetComponent(event.Entity1); + if (pad != nullptr) { + entityPad = event.Entity1; + } + } + + if (entityPower == NULL || entityPad == NULL) { + return false; + } + + pad = m_World->GetComponent(entityPad); + if (pad == nullptr) { + return false; + } + + m_World->RemoveComponent(entityPower); + m_World->RemoveComponent(entityPower); + m_World->RemoveComponent(entityPower); + m_World->RemoveEntity(entityPower); + Events::PowerUpTaken ep; + ep.Name = "Something"; + EventBroker->Publish(ep); + + Events::MultiBall e; + auto transform = m_World->GetComponent(entityPad); + e.padTransform = transform; + EventBroker->Publish(e); + return true; +} + +bool dd::Systems::PadSystem::OnResetBall(const dd::Events::ResetBall &event) +{ + SetReplaceBall(true); + return true; +} + +bool dd::Systems::PadSystem::OnMultiBall(const dd::Events::MultiBall &event) +{ + auto ent1 = CreateBall(); + auto ent2 = CreateBall(); + auto transform1 = m_World->GetComponent(ent1); + auto transform2 = m_World->GetComponent(ent2); + auto ball1 = m_World->GetComponent(ent1); + auto ball2 = m_World->GetComponent(ent2); + auto padTransform = event.padTransform; + float x1 = padTransform->Position.x - 2, x2 = padTransform->Position.x + 2; + if (x1 < -3.1) { + x1 = 3; + } + if (x2 > 3.1) { + x2 = -3; + } + transform1->Position = glm::vec3(x1, -5.5, -10); + transform2->Position = glm::vec3(x2, -5.5, -10); + + transform1->Velocity = glm::normalize(glm::vec3(5, 5 ,0.f)) * ball1->Speed; + transform2->Velocity = glm::normalize(glm::vec3(-5, 5 ,0.f)) * ball2->Speed; + + return true; +} + +bool dd::Systems::PadSystem::OnStageCleared(const dd::Events::StageCleared &event) +{ + auto entity = CreateBall(); + return true; +} + +bool dd::Systems::PadSystem::PadSteeringInputController::OnCommand(const Events::InputCommand &event) +{ + std::string command = event.Command; + + std::cout << "Command!" << std::endl; + + if (command == "right") { + std::cout << "Right!" << std::endl; + } else if (command == "left") { + std::cout << "Left!" << std::endl; + } + + return true; +} \ No newline at end of file diff --git a/src/game/Physics/PhysicsSystem.cpp b/src/game/Physics/PhysicsSystem.cpp old mode 100644 new mode 100755 index 2a868f6..a61a5a2 --- a/src/game/Physics/PhysicsSystem.cpp +++ b/src/game/Physics/PhysicsSystem.cpp @@ -12,7 +12,7 @@ void dd::Systems::PhysicsSystem::Initialize() { m_ContactListener = new ContactListener(this); - m_Gravity = b2Vec2(0.f, 0.f); + m_Gravity = b2Vec2(0.f, -9.82f); m_PhysicsWorld = new b2World(m_Gravity); m_TimeStep = 1.f/60.f; @@ -22,9 +22,19 @@ void dd::Systems::PhysicsSystem::Initialize() m_PhysicsWorld->SetContactListener(m_ContactListener); + InitializeWater(); + EVENT_SUBSCRIBE_MEMBER(m_SetImpulse, PhysicsSystem::SetImpulse); } +void dd::Systems::PhysicsSystem::InitializeWater() +{ + b2ParticleSystemDef m_ParticleSystemDef; + m_ParticleSystemDef.radius = 0.13f; + + m_ParticleSystem = m_PhysicsWorld->CreateParticleSystem(&m_ParticleSystemDef); +} + bool dd::Systems::PhysicsSystem::SetImpulse(const Events::SetImpulse &event) { b2Body* body = m_EntitiesToBodies[event.Entity]; @@ -72,9 +82,6 @@ void dd::Systems::PhysicsSystem::Update(double dt) body->SetTransform(position, angle); - body->SetLinearVelocity(b2Vec2(transformComponent->Velocity.x, transformComponent->Velocity.y)); - - } } @@ -82,8 +89,6 @@ void dd::Systems::PhysicsSystem::Update(double dt) i.Body->ApplyLinearImpulse(i.Impulse, i.Point, true); } m_Impulses.clear(); - - m_Accumulator += dt; while(m_Accumulator >= m_TimeStep) { @@ -91,7 +96,6 @@ void dd::Systems::PhysicsSystem::Update(double dt) m_Accumulator -= dt; } - for (auto i : m_EntitiesToBodies) { EntityID entity = i.first; b2Body* body = i.second; @@ -104,7 +108,8 @@ void dd::Systems::PhysicsSystem::Update(double dt) auto transformComponent = m_World->GetComponent(entity); if (! transformComponent) continue; - if (m_World->GetEntityParent(entity) == 0) { + auto parent = m_World->GetEntityParent(entity); + if (parent == 0) { b2Vec2 position = body->GetPosition(); transformComponent->Position.x = position.x; transformComponent->Position.y = position.y; @@ -114,12 +119,24 @@ void dd::Systems::PhysicsSystem::Update(double dt) transformComponent->Orientation = glm::quat(glm::vec3(0, 0, -angle)); - b2Vec2 velocity = body->GetLinearVelocity(); - transformComponent->Velocity.x = velocity.x; - transformComponent->Velocity.y = velocity.y; - } } + + b2Vec2* positionBuffer = m_ParticleSystem->GetPositionBuffer(); + for (auto i : m_EntitiesToParticleHandle) { + EntityID entity = i.first; + b2ParticleHandle* particleH = i.second; + + b2Vec2 positionB2 = positionBuffer[particleH->GetIndex()]; + glm::vec2 position = glm::vec2(positionB2.x, positionB2.y); + + + EntityID entityParent = m_World->GetEntityParent(entity); + auto transform = m_World->GetComponent(entity); + auto transformParent = m_World->GetComponent(entityParent); + + transform->Position = glm::vec3(position.x, position.y, -10) - transformParent->Position; + } } void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) @@ -127,12 +144,19 @@ void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, Entity } - void dd::Systems::PhysicsSystem::OnEntityCommit(EntityID entity) { auto physicsComponent = m_World->GetComponent(entity); - if(physicsComponent) { + auto waterComponent = m_World->GetComponent(entity); + + if (physicsComponent && waterComponent) { + LOG_ERROR("Entity has both water and physics component, this is illegal. The police has been alerted."); + return; + } + if (physicsComponent) { CreateBody(entity); + } else if (waterComponent) { + CreateParticleGroup(entity); } } @@ -189,7 +213,7 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity) auto boxComponent = m_World->GetComponent(entity); if (boxComponent) { b2PolygonShape* bShape = new b2PolygonShape(); - bShape->SetAsBox(absoluteTransform.Scale.x/2, absoluteTransform.Scale.y/2); //TODO: THIS SUCKS DUDE 4?!?!?!? + bShape->SetAsBox(absoluteTransform.Scale.x/2, absoluteTransform.Scale.y/2); pShape = bShape; } else { auto circleComponent = m_World->GetComponent(entity); @@ -201,7 +225,7 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity) if (absoluteTransform.Scale.x != absoluteTransform.Scale.y && absoluteTransform.Scale.y != absoluteTransform.Scale.z) { LOG_WARNING("Circles has to be of uniform scale."); } - pShape->m_radius = absoluteTransform.Scale.x/2; //TODO: THIS ALSO SUCKS 4 WTH + pShape->m_radius = absoluteTransform.Scale.x/2; } } @@ -226,6 +250,44 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity) m_BodiesToEntities.insert(std::make_pair(body, entity)); } +void dd::Systems::PhysicsSystem::CreateParticleGroup(EntityID e) +{ + //TODO: Lägg alla pd i en lista + auto transform = m_World->GetComponent(e); + if (!transform) { + LOG_ERROR("No Transform component in CreateParticleGroup"); + return; + } + + b2ParticleGroupDef pd; + b2PolygonShape shape; + + shape.SetAsBox(transform->Scale.x/2.f, transform->Scale.y/2.f); + pd.shape = &shape; + pd.flags = b2_tensileParticle; + pd.position.Set(transform->Position.x, transform->Position.y); + //TODO: PUT IN LIST + t_watergroup = m_ParticleSystem->CreateParticleGroup(pd); + b2Vec2* t_ParticlePositions = m_ParticleSystem->GetPositionBuffer(); + for(int i = 0; i < m_ParticleSystem->GetParticleCount(); i++){ + { + auto t_waterparticle = m_World->CreateEntity(e); + auto transformChild = m_World->AddComponent(t_waterparticle); + //auto sprite = m_World->AddComponent(t_waterparticle); + + transformChild->Position = glm::vec3(t_ParticlePositions[i].x - transform->Position.x, t_ParticlePositions[i].y - transform->Position.y, -9.5f); + transformChild->Scale = glm::vec3(m_ParticleSystem->GetRadius())/transform->Scale; + //sprite->SpriteFile = "Textures/Ball.png"; + m_World->CommitEntity(t_waterparticle); + + m_EntitiesToParticleHandle.insert(std::make_pair(t_waterparticle, m_ParticleSystem->GetParticleHandleFromIndex(i))); + m_ParticleHandleToEntities.insert(std::make_pair( m_ParticleSystem->GetParticleHandleFromIndex(i), t_waterparticle)); + } + + } + LOG_INFO("ParticleCount: %i", m_ParticleSystem->GetParticleCount()); +} + dd::Systems::PhysicsSystem::~PhysicsSystem() { if (m_ContactListener != nullptr) { diff --git a/src/game/Physics/PhysicsSystem.cpp.orig b/src/game/Physics/PhysicsSystem.cpp.orig new file mode 100755 index 0000000..a38e5aa --- /dev/null +++ b/src/game/Physics/PhysicsSystem.cpp.orig @@ -0,0 +1,326 @@ +#include "PrecompiledHeader.h" +#include "Physics/PhysicsSystem.h" + + + +void dd::Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf) +{ + cf->Register(); +} + +void dd::Systems::PhysicsSystem::Initialize() +{ + m_ContactListener = new ContactListener(this); + + m_Gravity = b2Vec2(0.f, -9.82f); + m_PhysicsWorld = new b2World(m_Gravity); + + m_TimeStep = 1.f/60.f; + m_VelocityIterations = 6; + m_PositionIterations = 2; + m_Accumulator = 0.f; + + m_PhysicsWorld->SetContactListener(m_ContactListener); + + InitializeWater(); + + EVENT_SUBSCRIBE_MEMBER(m_SetImpulse, PhysicsSystem::SetImpulse); +} + +void dd::Systems::PhysicsSystem::InitializeWater() +{ + b2ParticleSystemDef m_ParticleSystemDef; + m_ParticleSystemDef.radius = 0.1f; + + m_ParticleSystem = m_PhysicsWorld->CreateParticleSystem(&m_ParticleSystemDef); +} + +bool dd::Systems::PhysicsSystem::SetImpulse(const Events::SetImpulse &event) +{ + b2Body* body = m_EntitiesToBodies[event.Entity]; + + b2Vec2 impulse; + impulse.x = event.Impulse.x; + impulse.y = event.Impulse.y; + + b2Vec2 point; + point.x = event.Point.x; + point.y = event.Point.y; + + + Impulse i; + i.Body = body; + i.Impulse = impulse; + i.Point = point; + + m_Impulses.push_back(i); + + return true; +} + +void dd::Systems::PhysicsSystem::Update(double dt) +{ + for (auto i : m_EntitiesToBodies) { + EntityID entity = i.first; + b2Body* body = i.second; + + auto transformComponent = m_World->GetComponent(entity); + if (! transformComponent) + continue; + + if (body == nullptr) { + //LOG_ERROR("This body should not exist"); + continue; + } + +<<<<<<< HEAD + if (m_World->GetEntityParent(entity) == 0) { +======= + if (m_World->GetEntityParent(entity) == 0) { //TODO: Make this work with childs too +>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db + b2Vec2 position; + position.x = transformComponent->Position.x; + position.y = transformComponent->Position.y; + + float angle = -glm::eulerAngles(transformComponent->Orientation).z; + + body->SetTransform(position, angle); + +<<<<<<< HEAD + } + } + +======= + body->SetLinearVelocity(b2Vec2(transformComponent->Velocity.x, transformComponent->Velocity.y)); + + + } + } + + for (auto i : m_Impulses) { + i.Body->ApplyLinearImpulse(i.Impulse, i.Point, true); + } + m_Impulses.clear(); + + +>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db + m_Accumulator += dt; + while(m_Accumulator >= m_TimeStep) + { + m_PhysicsWorld->Step(m_TimeStep, m_VelocityIterations, m_PositionIterations); + m_Accumulator -= dt; + } + + for (auto i : m_EntitiesToBodies) { + EntityID entity = i.first; + b2Body* body = i.second; + + if (body == nullptr) { + //LOG_ERROR("This body should not exist"); + continue; + } + + auto transformComponent = m_World->GetComponent(entity); + if (! transformComponent) + continue; +<<<<<<< HEAD + auto parent = m_World->GetEntityParent(entity); + if (parent == 0) { +======= + if (m_World->GetEntityParent(entity) == 0) { +>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db + b2Vec2 position = body->GetPosition(); + transformComponent->Position.x = position.x; + transformComponent->Position.y = position.y; + + float angle = body->GetAngle(); + + + transformComponent->Orientation = glm::quat(glm::vec3(0, 0, -angle)); +<<<<<<< HEAD +======= + + b2Vec2 velocity = body->GetLinearVelocity(); + transformComponent->Velocity.x = velocity.x; + transformComponent->Velocity.y = velocity.y; +>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db + + } + } + + b2Vec2* positionBuffer = m_ParticleSystem->GetPositionBuffer(); + for (auto i : m_EntitiesToParticleHandle) { + EntityID entity = i.first; + b2ParticleHandle* particleH = i.second; + + b2Vec2 positionB2 = positionBuffer[particleH->GetIndex()]; + glm::vec2 position = glm::vec2(positionB2.x, positionB2.y); + + + EntityID entityParent = m_World->GetEntityParent(entity); + auto transform = m_World->GetComponent(entity); + auto transformParent = m_World->GetComponent(entityParent); + + transform->Position = glm::vec3(position.x, position.y, -10) - transformParent->Position; + } +} + +void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) +{ + +} + +void dd::Systems::PhysicsSystem::OnEntityCommit(EntityID entity) +{ + auto physicsComponent = m_World->GetComponent(entity); + auto waterComponent = m_World->GetComponent(entity); + + if (physicsComponent && waterComponent) { + LOG_ERROR("Entity has both water and physics component, this is illegal. The police has been alerted."); + return; + } + if (physicsComponent) { + CreateBody(entity); + } else if (waterComponent) { + CreateParticleGroup(entity); + } +} + + +void dd::Systems::PhysicsSystem::OnEntityRemoved(EntityID entity) +{ + b2Body* body = m_EntitiesToBodies[entity]; + + if (body != nullptr) { + m_EntitiesToBodies.erase(entity); + m_BodiesToEntities.erase(body); + + m_PhysicsWorld->DestroyBody(body); + } + +} + + +void dd::Systems::PhysicsSystem::CreateBody(EntityID entity) +{ + auto physicsComponent = m_World->GetComponent(entity); + if(!physicsComponent){ + LOG_ERROR("No PhysicsComponent in CreateBody"); + return; + } + + + auto transformComponent = m_World->GetComponent(entity); + if(!transformComponent) { + LOG_ERROR("No TransformComponent in CreateBody"); + return; + } + + auto absoluteTransform = m_World->GetSystem()->AbsoluteTransform(entity); + + b2BodyDef bodyDef; + bodyDef.position.Set(absoluteTransform.Position.x, absoluteTransform.Position.y); + + + bodyDef.angle = -glm::eulerAngles(absoluteTransform.Orientation).z; + + if (physicsComponent->Static) { + bodyDef.type = b2_staticBody; + } else { + bodyDef.type = b2_dynamicBody; + + } + + + b2Body* body = m_PhysicsWorld->CreateBody(&bodyDef); + + b2Shape* pShape; + + auto boxComponent = m_World->GetComponent(entity); + if (boxComponent) { + b2PolygonShape* bShape = new b2PolygonShape(); + bShape->SetAsBox(absoluteTransform.Scale.x/2, absoluteTransform.Scale.y/2); + pShape = bShape; + } else { + auto circleComponent = m_World->GetComponent(entity); + if (circleComponent) { + pShape = new b2CircleShape(); + pShape->m_radius = absoluteTransform.Scale.x; + + + if (absoluteTransform.Scale.x != absoluteTransform.Scale.y && absoluteTransform.Scale.y != absoluteTransform.Scale.z) { + LOG_WARNING("Circles has to be of uniform scale."); + } + pShape->m_radius = absoluteTransform.Scale.x/2; + + } + } + + if(physicsComponent->Static) { + body->CreateFixture(pShape, 0); //Density kanske ska vara 0 på statiska kroppar + } + else { + //TODO: FIX THIS SHIT INTO COMPONENTS + b2FixtureDef fixtureDef; + fixtureDef.shape = pShape; + fixtureDef.density = 1.f; + fixtureDef.restitution = 1.0f; + fixtureDef.friction = 0.0f; + body->CreateFixture(&fixtureDef); + + } + + delete pShape; + + m_EntitiesToBodies.insert(std::make_pair(entity, body)); + m_BodiesToEntities.insert(std::make_pair(body, entity)); +} + +void dd::Systems::PhysicsSystem::CreateParticleGroup(EntityID e) +{ + //TODO: Lägg alla pd i en lista + auto transform = m_World->GetComponent(e); + if (!transform) { + LOG_ERROR("No Transform component in CreateParticleGroup"); + return; + } + + b2ParticleGroupDef pd; + b2PolygonShape shape; + + shape.SetAsBox(transform->Scale.x/2.f, transform->Scale.y/2.f); + pd.shape = &shape; + pd.flags = b2_tensileParticle; + pd.linearVelocity = b2Vec2(0, 5.f); + pd.position.Set(transform->Position.x, transform->Position.y); + //TODO: PUT IN LIST + t_watergroup = m_ParticleSystem->CreateParticleGroup(pd); + b2Vec2* t_ParticlePositions = m_ParticleSystem->GetPositionBuffer(); + for(int i = 0; i < m_ParticleSystem->GetParticleCount(); i++){ + { + auto t_waterparticle = m_World->CreateEntity(e); + auto transformChild = m_World->AddComponent(t_waterparticle); + //auto sprite = m_World->AddComponent(t_waterparticle); + + + + transformChild->Position = glm::vec3(t_ParticlePositions[i].x - transform->Position.x, t_ParticlePositions[i].y - transform->Position.y, -9.5f); + transformChild->Scale = glm::vec3(m_ParticleSystem->GetRadius())/transform->Scale; + //sprite->SpriteFile = "Textures/Ball.png"; + m_World->CommitEntity(t_waterparticle); + + m_EntitiesToParticleHandle.insert(std::make_pair(t_waterparticle, m_ParticleSystem->GetParticleHandleFromIndex(i))); + m_ParticleHandleToEntities.insert(std::make_pair( m_ParticleSystem->GetParticleHandleFromIndex(i), t_waterparticle)); + } + + } + LOG_INFO("ParticleCount: %i", m_ParticleSystem->GetParticleCount()); +} + +dd::Systems::PhysicsSystem::~PhysicsSystem() +{ + if (m_ContactListener != nullptr) { + delete m_ContactListener; + m_ContactListener = nullptr; + } +}