From 05b78265befea045240e179c6dee501036adf22a Mon Sep 17 00:00:00 2001 From: viktorljung Date: Mon, 14 Dec 2015 19:10:00 +0100 Subject: [PATCH 01/50] Fixed some transparency bugs and started on component based camera --- assets | 2 +- include/Engine/Rendering/DrawScenePass.h | 6 +++ include/Engine/Rendering/ESetCamera.h | 23 ++++++++ include/Engine/Rendering/RawModel.h | 1 + include/Engine/Rendering/RenderQueue.h | 31 +++++++++++ include/Engine/Rendering/RenderQueueFactory.h | 8 ++- include/Engine/Rendering/Renderer.h | 4 +- resources/Schema/Components.xsd | 1 + resources/Schema/Components/Camera.xml | 6 +++ resources/Schema/Components/Camera.xsd | 19 +++++++ resources/Schema/Entities/Test.xml | 16 +----- src/Engine/Rendering/DrawScenePass.cpp | 1 + src/Engine/Rendering/DrawScenePassState.cpp | 2 + src/Engine/Rendering/RawModel.cpp | 8 ++- src/Engine/Rendering/RenderQueueFactory.cpp | 52 ++++++++++++++----- src/Engine/Rendering/Renderer.cpp | 32 +----------- src/Game/Game.cpp | 20 +++---- 17 files changed, 160 insertions(+), 72 deletions(-) create mode 100644 include/Engine/Rendering/ESetCamera.h create mode 100644 resources/Schema/Components/Camera.xml create mode 100644 resources/Schema/Components/Camera.xsd diff --git a/assets b/assets index b3746822..c5f67434 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b37468222e45ec0b2116f1543c578cb9784d43f2 +Subproject commit c5f674349a915ab1a2b4da632d87a9832d1f6fab diff --git a/include/Engine/Rendering/DrawScenePass.h b/include/Engine/Rendering/DrawScenePass.h index 782c5a49..db52f746 100644 --- a/include/Engine/Rendering/DrawScenePass.h +++ b/include/Engine/Rendering/DrawScenePass.h @@ -25,12 +25,18 @@ public: private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; + static bool DepthSort(const std::shared_ptr &i, const std::shared_ptr &j) + { + return (i->Depth < j->Depth); + }; + Texture* m_WhiteTexture; const IRenderer* m_Renderer; ShaderProgram* m_BasicForwardProgram; + }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/ESetCamera.h b/include/Engine/Rendering/ESetCamera.h new file mode 100644 index 00000000..cf5b0a87 --- /dev/null +++ b/include/Engine/Rendering/ESetCamera.h @@ -0,0 +1,23 @@ +#ifndef Events_SetCamera_h__ +#define Events_SetCamera_h__ + +#include "../Core/EventBroker.h" +#include "../Core/Entity.h" + +namespace Events +{ + +/** Thrown Every frame, use functions to pick*/ +struct SetCamera : Event +{ +public: + SetCamera() { }; + EntityID Entity; + +private: + +}; + +} + +#endif diff --git a/include/Engine/Rendering/RawModel.h b/include/Engine/Rendering/RawModel.h index c8226168..d63e46bb 100644 --- a/include/Engine/Rendering/RawModel.h +++ b/include/Engine/Rendering/RawModel.h @@ -46,6 +46,7 @@ public: struct MaterialGroup { float Shininess; + float Transparency; std::shared_ptr<::Texture> Texture; std::shared_ptr<::Texture> NormalMap; std::shared_ptr<::Texture> SpecularMap; diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 2942c743..1586aef6 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -63,6 +63,37 @@ struct ModelJob : RenderJob } }; +struct TransparentModelJob : RenderJob +{ + unsigned int ShaderID = 0; + unsigned int TextureID = 0; + + //TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this + EntityID Entity; + + glm::mat4 ModelMatrix; + const Texture* DiffuseTexture; + const Texture* NormalTexture; + const Texture* SpecularTexture; + float Shininess = 0.f; + glm::vec4 Color; + const Model* Model = nullptr; + unsigned int StartIndex = 0; + unsigned int EndIndex = 0; + + // Animation + Skeleton* Skeleton = nullptr; + bool NoRootMotion = true; + std::string AnimationName; + double AnimationTime = 0; + + void CalculateHash() override + { + Hash = TextureID; + } +}; + + struct SpriteJob : RenderJob { unsigned int ShaderID = 0; diff --git a/include/Engine/Rendering/RenderQueueFactory.h b/include/Engine/Rendering/RenderQueueFactory.h index b273b672..ff51a515 100644 --- a/include/Engine/Rendering/RenderQueueFactory.h +++ b/include/Engine/Rendering/RenderQueueFactory.h @@ -6,16 +6,19 @@ #include "../Core/ResourceManager.h" #include "Model.h" #include "../GLM.h" +#include "../Core/EventBroker.h" +#include "ESetCamera.h" class RenderQueueFactory { public: - RenderQueueFactory(); + RenderQueueFactory(EventBroker* eventBroker); void Update(World* world); RenderQueueCollection RenderQueues() const { return m_RenderQueues; } private: + EventBroker* m_EventBroker; RenderQueueCollection m_RenderQueues; void FillModels(World* world, RenderQueue* renderQueue); @@ -26,6 +29,9 @@ private: glm::vec3 AbsolutePosition(World* world, EntityID entity); glm::quat AbsoluteOrientation(World* world, EntityID entity); glm::vec3 AbsoluteScale(World* world, EntityID entity); + + EntityID m_CurrentCamera; + }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 886c98ca..c304e879 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -32,8 +32,9 @@ enum lightType class Renderer : public IRenderer { public: - Renderer(EventBroker* eventBroker) + Renderer(EventBroker* eventBroker, World* world) : m_EventBroker(eventBroker) + , m_World(world) { } virtual void Initialize() override; @@ -43,6 +44,7 @@ public: private: //----------------------Variables----------------------// EventBroker* m_EventBroker; + World* m_World; Texture* m_ErrorTexture; Texture* m_WhiteTexture; diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 12fb870e..448d416d 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -6,4 +6,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/Camera.xml b/resources/Schema/Components/Camera.xml new file mode 100644 index 00000000..6b9e70d4 --- /dev/null +++ b/resources/Schema/Components/Camera.xml @@ -0,0 +1,6 @@ + + 1.77 + 90 + 0.01 + 5000 + \ No newline at end of file diff --git a/resources/Schema/Components/Camera.xsd b/resources/Schema/Components/Camera.xsd new file mode 100644 index 00000000..1ac8c394 --- /dev/null +++ b/resources/Schema/Components/Camera.xsd @@ -0,0 +1,19 @@ + + + + + + + + It's a camera thingy! + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 78494ce1..e59d8029 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -13,22 +13,10 @@ - - - Models/ScaleWidget.obj - - - - - - - - - - Models/RotationWidget.obj - + + diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp index 559a0f58..36bf7e81 100644 --- a/src/Engine/Rendering/DrawScenePass.cpp +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -32,6 +32,7 @@ void DrawScenePass::Draw(RenderQueueCollection& rq) DrawScenePassState state; + rq.Forward.Jobs.sort(DrawScenePass::DepthSort); //TODO: Render: Add code for more jobs than modeljobs. for (auto &job : rq.Forward) { diff --git a/src/Engine/Rendering/DrawScenePassState.cpp b/src/Engine/Rendering/DrawScenePassState.cpp index 59654775..fdfe1802 100644 --- a/src/Engine/Rendering/DrawScenePassState.cpp +++ b/src/Engine/Rendering/DrawScenePassState.cpp @@ -8,6 +8,8 @@ DrawScenePassState::DrawScenePassState() GLERROR("---"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); + Enable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f)); Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } diff --git a/src/Engine/Rendering/RawModel.cpp b/src/Engine/Rendering/RawModel.cpp index 962c278f..3e7c472c 100644 --- a/src/Engine/Rendering/RawModel.cpp +++ b/src/Engine/Rendering/RawModel.cpp @@ -78,7 +78,12 @@ RawModel::RawModel(std::string fileName) // Material diffuse color aiColor4D diffuse; material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); - desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, diffuse.a); + + float opacity; + material->Get(AI_MATKEY_OPACITY, opacity); + + desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity); + // Material specular color aiColor4D specular; material->Get(AI_MATKEY_COLOR_SPECULAR, specular); @@ -132,6 +137,7 @@ RawModel::RawModel(std::string fileName) matGroup.EndIndex = m_Indices.size() - 1; // Material shininess material->Get(AI_MATKEY_SHININESS, matGroup.Shininess); + material->Get(AI_MATKEY_OPACITY, matGroup.Transparency); //LOG_DEBUG("Shininess: %f", matGroup.Shininess); // Diffuse texture //LOG_DEBUG("%i diffuse textures found", material->GetTextureCount(aiTextureType_DIFFUSE)); diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/src/Engine/Rendering/RenderQueueFactory.cpp index 4b82647c..77088fc0 100644 --- a/src/Engine/Rendering/RenderQueueFactory.cpp +++ b/src/Engine/Rendering/RenderQueueFactory.cpp @@ -1,9 +1,10 @@ #include "Rendering/RenderQueueFactory.h" -RenderQueueFactory::RenderQueueFactory() +RenderQueueFactory::RenderQueueFactory(EventBroker* eventBroker) { m_RenderQueues = RenderQueueCollection(); + m_EventBroker = eventBroker; } void RenderQueueFactory::Update(World* world) @@ -79,21 +80,44 @@ void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue) Model* model = ResourceManager::Load(resource); for (auto texGroup : model->TextureGroups) { - ModelJob job; - job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0; - job.DiffuseTexture = texGroup.Texture.get(); - job.NormalTexture = texGroup.NormalMap.get(); - job.SpecularTexture = texGroup.SpecularMap.get(); - job.Model = model; - job.StartIndex = texGroup.StartIndex; - job.EndIndex = texGroup.EndIndex; - job.ModelMatrix = model->m_Matrix * ModelMatrix(world, modelC.EntityID); - job.Color = color; - //TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this - job.Entity = modelC.EntityID; + if (color.a < 1.0f || texGroup.Transparency < 1.0f) { + //transparent stuffs + TransparentModelJob job; + job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0; + job.DiffuseTexture = texGroup.Texture.get(); + job.NormalTexture = texGroup.NormalMap.get(); + job.SpecularTexture = texGroup.SpecularMap.get(); + job.Model = model; + job.StartIndex = texGroup.StartIndex; + job.EndIndex = texGroup.EndIndex; + job.ModelMatrix = model->m_Matrix * ModelMatrix(world, modelC.EntityID); + job.Color = color; - renderQueue->Add(job); + job.Entity = modelC.EntityID; + job.Depth = 10.f; //insert real viewspace depth here + + renderQueue->Add(job); + } else { + ModelJob job; + job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0; + job.DiffuseTexture = texGroup.Texture.get(); + job.NormalTexture = texGroup.NormalMap.get(); + job.SpecularTexture = texGroup.SpecularMap.get(); + job.Model = model; + job.StartIndex = texGroup.StartIndex; + job.EndIndex = texGroup.EndIndex; + job.ModelMatrix = model->m_Matrix * ModelMatrix(world, modelC.EntityID); + job.Color = color; + + //TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this + job.Entity = modelC.EntityID; + + renderQueue->Add(job); + } + + + } } } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index c4fa33c4..13538dfb 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -10,6 +10,7 @@ void Renderer::Initialize() if (m_Camera == nullptr) { m_Camera = m_DefaultCamera; } + TEMPCreateLights(); InitializeRenderPasses(); @@ -88,36 +89,6 @@ void Renderer::InitializeShaders() void Renderer::InputUpdate(double dt) { static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); - - glm::vec3 m_Position = m_Camera->Position(); - if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS) - { - m_Position = glm::vec3(0.f, 0.f, 5.f); - } - if (glfwGetKey(m_Window, GLFW_KEY_W) == GLFW_PRESS) - { - m_Position += m_Camera->Forward() * m_CameraMoveSpeed * (float)dt; - } - if (glfwGetKey(m_Window, GLFW_KEY_S) == GLFW_PRESS) - { - m_Position -= m_Camera->Forward() * m_CameraMoveSpeed * (float)dt; - } - if (glfwGetKey(m_Window, GLFW_KEY_D) == GLFW_PRESS) - { - m_Position += m_Camera->Right() * m_CameraMoveSpeed * (float)dt; - } - if (glfwGetKey(m_Window, GLFW_KEY_A) == GLFW_PRESS) - { - m_Position -= m_Camera->Right() * m_CameraMoveSpeed * (float)dt; - } - if (glfwGetKey(m_Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) - { - m_CameraMoveSpeed = 5.f; - } - else { - m_CameraMoveSpeed = 0.5f; - } - firstPersonInputController.Update(dt); m_Camera->SetOrientation(firstPersonInputController.Orientation()); m_Camera->SetPosition(firstPersonInputController.Position()); @@ -237,7 +208,6 @@ void Renderer::CalculateFrustum() { GLERROR("CalculateFrustum Error-1"); m_CalculateFrustumProgram->Bind(); - GLERROR("CalculateFrustum Error1"); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); GLERROR("CalculateFrustum Error2"); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index af96eb29..02ef90c8 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -14,10 +14,17 @@ Game::Game(int argc, char* argv[]) // Create the core event broker m_EventBroker = new EventBroker(); - m_RenderQueueFactory = new RenderQueueFactory(); + m_RenderQueueFactory = new RenderQueueFactory(m_EventBroker); + + // Create a world + m_World = new World(); + std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); + if (!mapToLoad.empty()) { + ResourceManager::Load(mapToLoad)->PopulateWorld(m_World); + } // Create the renderer - m_Renderer = new Renderer(m_EventBroker); + m_Renderer = new Renderer(m_EventBroker, m_World); m_Renderer->SetFullscreen(m_Config->Get("Video.Fullscreen", false)); m_Renderer->SetVSYNC(m_Config->Get("Video.VSYNC", false)); m_Renderer->SetResolution(Rectangle( @@ -27,7 +34,7 @@ Game::Game(int argc, char* argv[]) m_Config->Get("Video.Height", 720) )); m_Renderer->Initialize(); - m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get("Video.FOV", 90.f))); + //m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get("Video.FOV", 90.f))); // Create input manager m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); @@ -41,12 +48,7 @@ Game::Game(int argc, char* argv[]) m_FrameStack->Width = m_Renderer->Resolution().Width; m_FrameStack->Height = m_Renderer->Resolution().Height; - // Create a world - m_World = new World(); - std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); - if (!mapToLoad.empty()) { - ResourceManager::Load(mapToLoad)->PopulateWorld(m_World); - } + // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); From d9ea0192d1ddaca496e8ef1015606dc05cbf30a0 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Mon, 14 Dec 2015 20:07:02 +0100 Subject: [PATCH 02/50] Added RenderSystem and removed RenderQueueFactory --- include/Engine/Editor/EditorSystem.h | 2 +- .../Engine/Rendering/RenderSystem.cpp | 60 +++++++++---------- .../{RenderQueueFactory.h => RenderSystem.h} | 32 +++++----- include/Game/Game.h | 4 +- src/Engine/Editor/EditorSystem.cpp | 2 +- src/Game/Game.cpp | 8 +-- 6 files changed, 51 insertions(+), 57 deletions(-) rename src/Engine/Rendering/RenderQueueFactory.cpp => include/Engine/Rendering/RenderSystem.cpp (81%) rename include/Engine/Rendering/{RenderQueueFactory.h => RenderSystem.h} (50%) diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index 92e237d1..c1958818 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -5,7 +5,7 @@ #include "../Core/ConfigFile.h" #include "../Input/EInputCommand.h" #include "../Rendering/EPicking.h" -#include "../Rendering/RenderQueueFactory.h" +#include "../Rendering/RenderSystem.h" class EditorSystem : public ImpureSystem { diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/include/Engine/Rendering/RenderSystem.cpp similarity index 81% rename from src/Engine/Rendering/RenderQueueFactory.cpp rename to include/Engine/Rendering/RenderSystem.cpp index 69d11336..c9b3a175 100644 --- a/src/Engine/Rendering/RenderQueueFactory.cpp +++ b/include/Engine/Rendering/RenderSystem.cpp @@ -1,30 +1,19 @@ -#include "Rendering/RenderQueueFactory.h" +#include "RenderSystem.h" - -RenderQueueFactory::RenderQueueFactory(EventBroker* eventBroker) +RenderSystem::RenderSystem(EventBroker* eventBrokerer, RenderQueueCollection* renderQueues) + :ImpureSystem(eventBrokerer) { - m_RenderQueues = RenderQueueCollection(); - m_EventBroker = eventBroker; + m_RenderQueues = renderQueues; + Initialize(); } -void RenderQueueFactory::Update(World* world) + +void RenderSystem::Initialize() { - m_RenderQueues.Clear(); - FillModels(world, &m_RenderQueues.Forward); - FillLights(world, &m_RenderQueues.Lights); + } -glm::mat4 RenderQueueFactory::ModelMatrix(World* world, EntityID entity) -{ - glm::vec3 position = AbsolutePosition(world, entity); - glm::quat orientation = AbsoluteOrientation(world, entity); - glm::vec3 scale = AbsoluteScale(world, entity); - - glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale); - return modelMatrix; -} - -glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity) +glm::vec3 RenderSystem::AbsolutePosition(World* world, EntityID entity) { glm::vec3 position; @@ -38,11 +27,11 @@ glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity) } entity = parent; } while (entity != 0); - + return position; } -glm::quat RenderQueueFactory::AbsoluteOrientation(World* world, EntityID entity) +glm::quat RenderSystem::AbsoluteOrientation(World* world, EntityID entity) { glm::quat orientation; @@ -51,11 +40,11 @@ glm::quat RenderQueueFactory::AbsoluteOrientation(World* world, EntityID entity) orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation; entity = world->GetParent(entity); } while (entity != 0); - + return orientation; } -glm::vec3 RenderQueueFactory::AbsoluteScale(World* world, EntityID entity) +glm::vec3 RenderSystem::AbsoluteScale(World* world, EntityID entity) { glm::vec3 scale(1.f); @@ -68,7 +57,17 @@ glm::vec3 RenderQueueFactory::AbsoluteScale(World* world, EntityID entity) return scale; } -void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue) +glm::mat4 RenderSystem::ModelMatrix(World* world, EntityID entity) +{ + glm::vec3 position = AbsolutePosition(world, entity); + glm::quat orientation = AbsoluteOrientation(world, entity); + glm::vec3 scale = AbsoluteScale(world, entity); + + glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale); + return modelMatrix; +} + +void RenderSystem::FillModels(World* world, RenderQueue* renderQueue) { auto models = world->GetComponents("Model"); if (models == nullptr) { @@ -127,14 +126,15 @@ void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue) renderQueue->Add(job); } - - + + } } } -void RenderQueueFactory::FillLights(World* world, RenderQueue* renderQueue) + +void RenderSystem::Update(World* world, double dt) { - + m_RenderQueues->Clear(); + FillModels(world, &m_RenderQueues->Forward); } - diff --git a/include/Engine/Rendering/RenderQueueFactory.h b/include/Engine/Rendering/RenderSystem.h similarity index 50% rename from include/Engine/Rendering/RenderQueueFactory.h rename to include/Engine/Rendering/RenderSystem.h index a53a8666..5e8dce8d 100644 --- a/include/Engine/Rendering/RenderQueueFactory.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -1,37 +1,33 @@ -#ifndef RenderQueueFactory_h__ -#define RenderQueueFactory_h__ +#ifndef RenderSystem_h__ +#define RenderSystem_h__ -#include "../Core/World.h" +#include "../Core/System.h" #include "RenderQueue.h" -#include "../Core/ResourceManager.h" -#include "Model.h" #include "../GLM.h" -#include "../Core/EventBroker.h" +#include "../OpenGL.h" +#include "../Core/ResourceManager.h" #include "ESetCamera.h" +#include "Model.h" -class RenderQueueFactory +class RenderSystem : public ImpureSystem { public: - RenderQueueFactory(EventBroker* eventBroker); - void Update(World* world); - - RenderQueueCollection RenderQueues() const { return m_RenderQueues; } + RenderSystem(EventBroker* eventBrokerer, RenderQueueCollection* renderQueues); + + virtual void Update(World* world, double dt) override; static glm::vec3 AbsolutePosition(World* world, EntityID entity); static glm::quat AbsoluteOrientation(World* world, EntityID entity); static glm::vec3 AbsoluteScale(World* world, EntityID entity); private: - EventBroker* m_EventBroker; - RenderQueueCollection m_RenderQueues; - - void FillModels(World* world, RenderQueue* renderQueue); - void FillLights(World* world, RenderQueue* renderQueue); + RenderQueueCollection* m_RenderQueues; + void Initialize(); + glm::mat4 ModelMatrix(World* world, EntityID entity); - EntityID m_CurrentCamera; - + void FillModels(World* world, RenderQueue* renderQueue); }; #endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 7933c8a1..85337707 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -8,7 +8,6 @@ #include "Core/InputManager.h" #include "GUI/Frame.h" #include "Core/World.h" -#include "Rendering/RenderQueueFactory.h" #include "Input/InputProxy.h" #include "Input/KeyboardInputHandler.h" #include "Input/MouseInputHandler.h" @@ -18,6 +17,7 @@ #include "RaptorCopterSystem.h" #include "PlayerSystem.h" #include "Editor/EditorSystem.h" +#include "Rendering/RenderSystem.h" class Game { @@ -38,7 +38,7 @@ private: GUI::Frame* m_FrameStack; World* m_World; SystemPipeline* m_SystemPipeline; - RenderQueueFactory* m_RenderQueueFactory; + RenderQueueCollection* m_RenderQueues; EventRelay m_EInputCommand; bool debugOnInputCommand(const Events::InputCommand& e); diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index a56ba79c..901afd1f 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -39,7 +39,7 @@ void EditorSystem::Update(World* world, double dt) widgetModel["Visible"] = m_Visible; if (m_Selection != 0) { if (world->HasComponent(m_Selection, "Transform")) { - glm::vec3 pos = RenderQueueFactory::AbsolutePosition(world, m_Selection); + glm::vec3 pos = RenderSystem::AbsolutePosition(world, m_Selection); auto widgetTransform = world->GetComponent(m_Widget, "Transform"); widgetTransform["Position"] = pos; } else { diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 41af1cf4..d1fe7b01 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -14,8 +14,6 @@ Game::Game(int argc, char* argv[]) // Create the core event broker m_EventBroker = new EventBroker(); - m_RenderQueueFactory = new RenderQueueFactory(m_EventBroker); - // Create a world m_World = new World(); std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); @@ -49,12 +47,13 @@ Game::Game(int argc, char* argv[]) m_FrameStack->Height = m_Renderer->Resolution().Height; - + m_RenderQueues = new RenderQueueCollection(); // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(); + m_SystemPipeline->AddSystem(m_RenderQueues); m_LastTime = glfwGetTime(); @@ -90,9 +89,8 @@ void Game::Tick() debugTick(dt); m_Renderer->Update(dt); - m_RenderQueueFactory->Update(m_World); GLERROR("Game::Tick m_RenderQueueFactory->Update"); - m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); + m_Renderer->Draw(*m_RenderQueues); GLERROR("Game::Tick m_Renderer->Draw"); m_EventBroker->Swap(); m_EventBroker->Clear(); From fa66e9ff477ef9b406c8d07c3e0aebe4163c2ba9 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 15 Dec 2015 15:29:19 +0100 Subject: [PATCH 03/50] Camera Switch event now working, Camera models Rotation still bugged --- assets | 2 +- .../Rendering/DebugCameraInputController.h | 3 + include/Engine/Rendering/IRenderer.h | 12 -- include/Engine/Rendering/RenderQueue.h | 4 +- include/Engine/Rendering/RenderSystem.cpp | 110 ++++++++++++++++-- include/Engine/Rendering/RenderSystem.h | 19 ++- include/Engine/Rendering/Renderer.h | 1 - resources/Schema/Components/Camera.xml | 2 +- resources/Schema/Entities/Test.xml | 16 ++- resources/Shaders/BasicForward.frag.glsl | 4 +- resources/Shaders/BasicForward.vert.glsl | 6 +- resources/Shaders/Picking.vert.glsl | 6 +- src/Engine/Rendering/DrawScenePass.cpp | 4 +- src/Engine/Rendering/DummyRenderer.cpp | 7 -- src/Engine/Rendering/PickingPass.cpp | 14 +-- src/Engine/Rendering/Renderer.cpp | 33 ++---- 16 files changed, 164 insertions(+), 79 deletions(-) diff --git a/assets b/assets index c5f67434..008f7278 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c5f674349a915ab1a2b4da632d87a9832d1f6fab +Subproject commit 008f7278216a1750e9f270c70a75c1cd1859bf1f diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h index 614b071c..4d74e288 100644 --- a/include/Engine/Rendering/DebugCameraInputController.h +++ b/include/Engine/Rendering/DebugCameraInputController.h @@ -9,6 +9,9 @@ public: : FirstPersonInputController(eventBroker, playerID) { } + void SetPosition(const glm::vec3 position) { m_Position = position; } + void SetOrientation(const glm::quat orientation) { m_Orientation = orientation; } + const glm::vec3 Position() const { return m_Position; } void SetBaseSpeed(float speed) { m_BaseSpeed = speed; } diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index 1acb2454..d11eb481 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -20,16 +20,6 @@ public: void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; } bool VSYNC() const { return m_VSYNC; } void SetVSYNC(bool vsync) { m_VSYNC = vsync; } - ::Camera* Camera() const { return m_Camera; } - void SetCamera(::Camera* camera) - { - if (camera == nullptr) { - m_Camera = m_DefaultCamera; - } else { - m_Camera = camera; - } - } - virtual void Initialize() = 0; virtual void Update(double dt) = 0; virtual void Draw(RenderQueueCollection& rq) = 0; @@ -40,8 +30,6 @@ protected: bool m_VSYNC = false; int m_GLVersion[2]; std::string m_GLVendor; - ::Camera* m_DefaultCamera; - ::Camera* m_Camera = nullptr; GLFWwindow* m_Window = nullptr; }; diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 1586aef6..5e504913 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -41,7 +41,7 @@ struct ModelJob : RenderJob //TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this EntityID Entity; - glm::mat4 ModelMatrix; + glm::mat4 Matrix; const Texture* DiffuseTexture; const Texture* NormalTexture; const Texture* SpecularTexture; @@ -71,7 +71,7 @@ struct TransparentModelJob : RenderJob //TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this EntityID Entity; - glm::mat4 ModelMatrix; + glm::mat4 Matrix; const Texture* DiffuseTexture; const Texture* NormalTexture; const Texture* SpecularTexture; diff --git a/include/Engine/Rendering/RenderSystem.cpp b/include/Engine/Rendering/RenderSystem.cpp index c9b3a175..e9183f7a 100644 --- a/include/Engine/Rendering/RenderSystem.cpp +++ b/include/Engine/Rendering/RenderSystem.cpp @@ -1,16 +1,52 @@ -#include "RenderSystem.h" +#include "Rendering/RenderSystem.h" +#include "Rendering/DebugCameraInputController.h" RenderSystem::RenderSystem(EventBroker* eventBrokerer, RenderQueueCollection* renderQueues) :ImpureSystem(eventBrokerer) { m_RenderQueues = renderQueues; Initialize(); + EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); } +bool RenderSystem::OnSetCamera(const Events::SetCamera &event) +{ + m_CurrentCamera = event.Entity; + return true; +} + +void RenderSystem::SwitchCamera(EntityID entity) +{ + m_CurrentCamera = entity; + m_SwitchCamera = false; + LOG_INFO("Switched to camera %i", m_CurrentCamera); +} + void RenderSystem::Initialize() { + +} +void RenderSystem::UpdateViewMatrix(ComponentWrapper& cameraTransform) +{ + glm::quat orientation = cameraTransform["Orientation"]; + glm::vec3 position = cameraTransform["Position"]; + + m_ViewMatrix = glm::toMat4(glm::inverse(orientation)) * glm::translate(-position); +} + +void RenderSystem::UpdateProjectionMatrix(ComponentWrapper& cameraComponent) +{ + double fov = (double&)cameraComponent["FOV"]; + double aspectRatio = (double&)cameraComponent["AspectRatio"]; + double nearClip = (double&)cameraComponent["NearClip"]; + double farClip = (double&)cameraComponent["FarClip"]; + + double fovY = atan(tan(glm::radians(fov)/2.0) * aspectRatio) * 2.0; + m_ProjectionMatrix = glm::perspective(fovY, aspectRatio, nearClip, farClip); + } glm::vec3 RenderSystem::AbsolutePosition(World* world, EntityID entity) @@ -57,6 +93,7 @@ glm::vec3 RenderSystem::AbsoluteScale(World* world, EntityID entity) return scale; } + glm::mat4 RenderSystem::ModelMatrix(World* world, EntityID entity) { glm::vec3 position = AbsolutePosition(world, entity); @@ -101,10 +138,10 @@ void RenderSystem::FillModels(World* world, RenderQueue* renderQueue) job.Model = model; job.StartIndex = texGroup.StartIndex; job.EndIndex = texGroup.EndIndex; - job.ModelMatrix = model->m_Matrix * ModelMatrix(world, modelC.EntityID); + job.Matrix = m_ProjectionMatrix * m_ViewMatrix * (model->m_Matrix * ModelMatrix(world, modelC.EntityID)); job.Color = color; - job.Entity = modelC.EntityID; + job.Depth = 10.f; //insert real viewspace depth here renderQueue->Add(job); @@ -117,24 +154,79 @@ void RenderSystem::FillModels(World* world, RenderQueue* renderQueue) job.Model = model; job.StartIndex = texGroup.StartIndex; job.EndIndex = texGroup.EndIndex; - job.ModelMatrix = model->m_Matrix * ModelMatrix(world, modelC.EntityID); + job.Matrix = m_ProjectionMatrix * m_ViewMatrix * (model->m_Matrix * ModelMatrix(world, modelC.EntityID)); job.Color = color; - - //TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this job.Entity = modelC.EntityID; renderQueue->Add(job); } - - - } } } +bool RenderSystem::OnInputCommand(const Events::InputCommand& e) +{ + if (e.Command == "SwitchCamera" && e.Value > 0) { + m_SwitchCamera = true; + return true; + } else { + return false; + } +} + void RenderSystem::Update(World* world, double dt) { + m_EventBroker->Process(); + static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); + + if (m_SwitchCamera) { + auto cameras = world->GetComponents("Camera"); + + if (cameras != nullptr) { + for (auto it = cameras->begin(); it != cameras->end(); it++) { + if ((*it).EntityID == m_CurrentCamera) { + it++; + if (it != cameras->end()) { + SwitchCamera((*it).EntityID); + } else { + SwitchCamera((*cameras->begin()).EntityID); + } + break; + } + } + ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); + ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); + + firstPersonInputController.SetOrientation((glm::quat)cameraTransform["Orientation"]); + firstPersonInputController.SetPosition((glm::vec3)cameraTransform["Position"]); + } + } + + if(world->HasComponent(m_CurrentCamera, "Camera") && world->HasComponent(m_CurrentCamera, "Transform")) { + + ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); + ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); + + firstPersonInputController.Update(dt); + (glm::quat&)cameraTransform["Orientation"] = firstPersonInputController.Orientation(); + (glm::vec3&)cameraTransform["Position"] = firstPersonInputController.Position(); + + + UpdateProjectionMatrix(cameraComponent); + UpdateViewMatrix(cameraTransform); + } else { + m_ProjectionMatrix = glm::perspective(glm::radians(40.f), 1.77f, 0.05f, 5000.f); + m_ViewMatrix = glm::mat4(); + + auto cameras = world->GetComponents("Camera"); + + if (cameras != nullptr) { + ComponentWrapper& cameraC = *cameras->begin(); + m_CurrentCamera = cameraC.EntityID; + } + } + m_RenderQueues->Clear(); FillModels(world, &m_RenderQueues->Forward); } diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 5e8dce8d..35e9d62e 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -8,6 +8,8 @@ #include "../Core/ResourceManager.h" #include "ESetCamera.h" #include "Model.h" +#include "../Core/EKeyDown.h" +#include "../Input/EInputCommand.h" class RenderSystem : public ImpureSystem { @@ -20,14 +22,29 @@ public: static glm::quat AbsoluteOrientation(World* world, EntityID entity); static glm::vec3 AbsoluteScale(World* world, EntityID entity); + + private: RenderQueueCollection* m_RenderQueues; + bool m_SwitchCamera = false; + + EventRelay m_ESetCamera; + bool OnSetCamera(const Events::SetCamera &event); + EntityID m_CurrentCamera = -1; + + void SwitchCamera(EntityID entity); void Initialize(); + void UpdateViewMatrix(ComponentWrapper& cameraTransform); + void UpdateProjectionMatrix(ComponentWrapper& cameraComponent); + glm::mat4 m_ViewMatrix; + glm::mat4 m_ProjectionMatrix; glm::mat4 ModelMatrix(World* world, EntityID entity); - void FillModels(World* world, RenderQueue* renderQueue); + + EventRelay m_EInputCommand; + bool OnInputCommand(const Events::InputCommand& e); }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index b12fcb03..b6fc716c 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -49,7 +49,6 @@ private: Texture* m_ErrorTexture; Texture* m_WhiteTexture; - float m_CameraMoveSpeed; Model* m_ScreenQuad; Model* m_UnitQuad; diff --git a/resources/Schema/Components/Camera.xml b/resources/Schema/Components/Camera.xml index 6b9e70d4..7edb3489 100644 --- a/resources/Schema/Components/Camera.xml +++ b/resources/Schema/Components/Camera.xml @@ -1,6 +1,6 @@ 1.77 - 90 + 60.0 0.01 5000 \ No newline at end of file diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index e59d8029..7b5cb820 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -13,8 +13,22 @@ - + + Models/Camera.obj + + + + + + + + + + + + Models/Camera.obj + diff --git a/resources/Shaders/BasicForward.frag.glsl b/resources/Shaders/BasicForward.frag.glsl index 274ec8d7..9ca4db99 100644 --- a/resources/Shaders/BasicForward.frag.glsl +++ b/resources/Shaders/BasicForward.frag.glsl @@ -1,8 +1,6 @@ #version 430 -uniform mat4 M; -uniform mat4 V; -uniform mat4 P; +uniform mat4 Matrix; uniform vec4 Color; uniform sampler2D texture0; diff --git a/resources/Shaders/BasicForward.vert.glsl b/resources/Shaders/BasicForward.vert.glsl index 20ab9051..a7fe2d9f 100644 --- a/resources/Shaders/BasicForward.vert.glsl +++ b/resources/Shaders/BasicForward.vert.glsl @@ -1,8 +1,6 @@ #version 430 -uniform mat4 M; -uniform mat4 V; -uniform mat4 P; +uniform mat4 Matrix; layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; @@ -25,7 +23,7 @@ out VertexData{ void main() { - gl_Position = P*V*M * vec4(Position, 1.0); + gl_Position = Matrix * vec4(Position, 1.0); Output.Position = Position; Output.TextureCoordinate = TextureCoords; diff --git a/resources/Shaders/Picking.vert.glsl b/resources/Shaders/Picking.vert.glsl index 47c0ecd7..e9680bd1 100644 --- a/resources/Shaders/Picking.vert.glsl +++ b/resources/Shaders/Picking.vert.glsl @@ -1,8 +1,6 @@ #version 430 -uniform mat4 M; -uniform mat4 V; -uniform mat4 P; +uniform mat4 Matrix; layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; @@ -22,7 +20,7 @@ out VertexData{ void main() { - gl_Position = P*V*M * vec4(Position, 1.0); + gl_Position = Matrix * vec4(Position, 1.0); Output.Position = Position; } \ No newline at end of file diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp index 36bf7e81..f0dd1405 100644 --- a/src/Engine/Rendering/DrawScenePass.cpp +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -42,9 +42,7 @@ void DrawScenePass::Draw(RenderQueueCollection& rq) m_BasicForwardProgram->Bind(); //TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix)); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix())); + glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "Matrix"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniform4fv(glGetUniformLocation(ShaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); //TODO: Renderer: bättre textur felhantering samt fler texturer stöd diff --git a/src/Engine/Rendering/DummyRenderer.cpp b/src/Engine/Rendering/DummyRenderer.cpp index 4956a87a..451dfa09 100644 --- a/src/Engine/Rendering/DummyRenderer.cpp +++ b/src/Engine/Rendering/DummyRenderer.cpp @@ -39,13 +39,6 @@ void DummyRenderer::Initialize() exit(EXIT_FAILURE); } - // Create default camera - m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(45.f), 0.01f, 5000.f); - m_DefaultCamera->SetPosition(glm::vec3(0, 0, 0)); - if (m_Camera == nullptr) { - m_Camera = m_DefaultCamera; - } - glfwSwapInterval(m_VSYNC); } diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index d45c0322..98d82f2e 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -71,12 +71,8 @@ void PickingPass::Draw(RenderQueueCollection& rq) } } m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity; - - //Render picking stuff - //TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix)); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix())); + + glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "Matrix"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); glBindVertexArray(modelJob->Model->VAO); @@ -96,15 +92,15 @@ void PickingPass::Draw(RenderQueueCollection& rq) int fbWidth; int fbHeight; glfwGetFramebufferSize(m_Renderer->Window(), &fbWidth, &fbHeight); - Events::Picking pickEvent = Events::Picking( + /* Events::Picking pickEvent = Events::Picking( &m_PickingBuffer, &m_DepthBuffer, m_Renderer->Camera()->ProjectionMatrix(), m_Renderer->Camera()->ViewMatrix(), Rectangle(fbWidth, fbHeight), - &m_PickingColorsToEntity); + &m_PickingColorsToEntity);*/ - m_EventBroker->Publish(pickEvent); + //m_EventBroker->Publish(pickEvent); } void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 4324c204..5a587792 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -4,12 +4,6 @@ void Renderer::Initialize() { InitializeWindow(); - // Create default camera - m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(45.f), 0.01f, 5000.f); - m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10)); - if (m_Camera == nullptr) { - m_Camera = m_DefaultCamera; - } TEMPCreateLights(); InitializeRenderPasses(); @@ -90,10 +84,7 @@ void Renderer::InitializeShaders() void Renderer::InputUpdate(double dt) { - static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); - firstPersonInputController.Update(dt); - m_Camera->SetOrientation(firstPersonInputController.Orientation()); - m_Camera->SetPosition(firstPersonInputController.Position()); + } void Renderer::Update(double dt) @@ -214,17 +205,17 @@ void Renderer::InitializeRenderPasses() void Renderer::CalculateFrustum() { - GLERROR("CalculateFrustum Error-1"); - m_CalculateFrustumProgram->Bind(); - GLERROR("CalculateFrustum Error1"); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); - GLERROR("CalculateFrustum Error2"); - glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix())); - GLERROR("CalculateFrustum Error3"); - glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height); - GLERROR("CalculateFrustum Error4"); - glDispatchCompute(5, 3, 1); - GLERROR("CalculateFrustum Error5"); +// GLERROR("CalculateFrustum Error-1"); +// m_CalculateFrustumProgram->Bind(); +// GLERROR("CalculateFrustum Error1"); +// glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); +// GLERROR("CalculateFrustum Error2"); +// // glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix())); +// GLERROR("CalculateFrustum Error3"); +// // glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height); +// GLERROR("CalculateFrustum Error4"); +// //glDispatchCompute(5, 3, 1); +// GLERROR("CalculateFrustum Error5"); } From 0f1b06f74e49976d98cb9b325723c952fd4af664 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 17 Dec 2015 11:13:34 +0100 Subject: [PATCH 04/50] Fixed camera rotation bug --- assets | 2 +- deps | 2 +- {include => src}/Engine/Rendering/RenderSystem.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename {include => src}/Engine/Rendering/RenderSystem.cpp (96%) diff --git a/assets b/assets index 008f7278..6b574962 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 008f7278216a1750e9f270c70a75c1cd1859bf1f +Subproject commit 6b5749627cc78cddfd4beae6b5a3728cc432a4a5 diff --git a/deps b/deps index f20b9cc1..1ae6ba5b 160000 --- a/deps +++ b/deps @@ -1 +1 @@ -Subproject commit f20b9cc13bffa39c3b5144bacc5eacd34d43052c +Subproject commit 1ae6ba5b1297ed71b560aee211b9f0007ba52547 diff --git a/include/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp similarity index 96% rename from include/Engine/Rendering/RenderSystem.cpp rename to src/Engine/Rendering/RenderSystem.cpp index e9183f7a..b35f69ab 100644 --- a/include/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -31,7 +31,7 @@ void RenderSystem::Initialize() void RenderSystem::UpdateViewMatrix(ComponentWrapper& cameraTransform) { - glm::quat orientation = cameraTransform["Orientation"]; + glm::quat orientation = glm::quat((glm::vec3)cameraTransform["Orientation"]); glm::vec3 position = cameraTransform["Position"]; m_ViewMatrix = glm::toMat4(glm::inverse(orientation)) * glm::translate(-position); @@ -198,7 +198,7 @@ void RenderSystem::Update(World* world, double dt) ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); - firstPersonInputController.SetOrientation((glm::quat)cameraTransform["Orientation"]); + firstPersonInputController.SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); firstPersonInputController.SetPosition((glm::vec3)cameraTransform["Position"]); } } @@ -209,7 +209,7 @@ void RenderSystem::Update(World* world, double dt) ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); firstPersonInputController.Update(dt); - (glm::quat&)cameraTransform["Orientation"] = firstPersonInputController.Orientation(); + (glm::vec3&)cameraTransform["Orientation"] = glm::eulerAngles(firstPersonInputController.Orientation()); (glm::vec3&)cameraTransform["Position"] = firstPersonInputController.Position(); From bd82f75dd0df3cfd54bfb0f0037de4a7fb5c2e90 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 18 Dec 2015 15:28:44 +0100 Subject: [PATCH 05/50] Some merge fixes, needs more work --- assets | 2 +- include/Engine/Rendering/IRenderer.h | 11 +++ include/Engine/Rendering/RenderQueue.h | 2 + include/Engine/Rendering/RenderSystem.h | 2 + include/Engine/Rendering/Renderer.h | 61 +------------ src/Engine/Editor/EditorSystem.cpp | 12 +-- src/Engine/Rendering/RenderSystem.cpp | 2 + src/Engine/Rendering/Renderer.cpp | 109 ++---------------------- src/Game/Game.cpp | 3 +- 9 files changed, 36 insertions(+), 168 deletions(-) diff --git a/assets b/assets index 6b574962..c8e631f4 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6b5749627cc78cddfd4beae6b5a3728cc432a4a5 +Subproject commit c8e631f449515cdbe3647b96ce472839748e28f9 diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index d11eb481..405de00e 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -20,6 +20,15 @@ public: void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; } bool VSYNC() const { return m_VSYNC; } void SetVSYNC(bool vsync) { m_VSYNC = vsync; } + ::Camera* Camera() const { return m_Camera; } + void SetCamera(::Camera* camera) + { + if (camera == nullptr) { + m_Camera = m_DefaultCamera; + } else { + m_Camera = camera; + } + } virtual void Initialize() = 0; virtual void Update(double dt) = 0; virtual void Draw(RenderQueueCollection& rq) = 0; @@ -31,6 +40,8 @@ protected: int m_GLVersion[2]; std::string m_GLVendor; GLFWwindow* m_Window = nullptr; + ::Camera* m_DefaultCamera; + ::Camera* m_Camera = nullptr; }; #endif // Renderer_h__ diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 5e504913..5fb09678 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -8,6 +8,7 @@ #include "../GLM.h" #include "../Core/Util/Rectangle.h" #include "../Core/Entity.h" +#include "Camera.h" class Model; class Skeleton; @@ -168,6 +169,7 @@ struct RenderQueueCollection { RenderQueue Forward; RenderQueue Lights; + Camera* Camera; void Clear() { diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 35e9d62e..e61ade55 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -10,6 +10,7 @@ #include "Model.h" #include "../Core/EKeyDown.h" #include "../Input/EInputCommand.h" +#include "Camera.h" class RenderSystem : public ImpureSystem { @@ -27,6 +28,7 @@ public: private: RenderQueueCollection* m_RenderQueues; bool m_SwitchCamera = false; + Camera* m_Camera = nullptr; EventRelay m_ESetCamera; bool OnSetCamera(const Events::SetCamera &event); diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index b6fc716c..e22b9fec 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -12,23 +12,10 @@ #include "../Core/World.h" #include "PickingPass.h" #include "DrawScenePass.h" - - -#define TILE_SIZE 16 -#define NUM_LIGHTS 3 - - -enum lightType -{ - Point, - Spot, - Directional, - Area -}; - #include "../Core/EventBroker.h" #include "EPicking.h" #include "ImGuiRenderPass.h" +#include "Camera.h" class Renderer : public IRenderer { @@ -69,56 +56,10 @@ private: //void PickingPass(RenderQueueCollection& rq); void DrawScreenQuad(GLuint textureToDraw); - //----------------------Forward+-----------------------// - void CalculateFrustum(); - void CullLights(); - //Frustum - struct Plane { - glm::vec3 Normal; - float d; - }; - struct Frustum { - Plane Planes[4]; - }; - Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution - - //Lights - void TEMPCreateLights(); - //TODO: Renderer: Add Directionllights, spotlights and area lights to this as type. - struct PointLight { - glm::vec4 Position = glm::vec4(0.f); - glm::vec4 Color = glm::vec4(1.f); - float Radius = 5.f; - float Intensity = 0.8f; - float Falloff = 0.3f; - float Padding = 1337; - }; - PointLight m_PointLights[NUM_LIGHTS]; - - struct LightGrid { - int Amount; - int Start; - glm::vec2 Padding; - }; - LightGrid m_LightGrid[80*45]; - - int m_LightOffset = 0; - - int m_LightIndex[80*45*200]; - - //-------------------------SSBO------------------------// - GLuint m_FrustumSSBO = 0; - GLuint m_LightSSBO = 1; - GLuint m_LightGridSSBO = 2; - GLuint m_LightOffsetSSBO = 3; - GLuint m_LightIndexSSBO = 4; - void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); //--------------------ShaderPrograms-------------------// ShaderProgram* m_BasicForwardProgram; ShaderProgram* m_DrawScreenQuadProgram; - ShaderProgram* m_CalculateFrustumProgram; - ShaderProgram* m_LightCullProgram; }; diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 2463aec6..87b8642b 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -114,7 +114,7 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e) EntityID parent = m_World->GetParent(m_Selection); glm::quat inverseParentOrientation; if (parent != 0) { - inverseParentOrientation = glm::inverse(RenderQueueFactory::AbsoluteOrientation(m_World, parent)); + inverseParentOrientation = glm::inverse(RenderSystem::AbsoluteOrientation(m_World, parent)); } (glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Position"] += inverseParentOrientation * movement; } else if (m_WidgetSpace == WidgetSpace::Local) { @@ -130,7 +130,7 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e) EntityID parent = m_World->GetParent(m_Selection); glm::quat parentOrientation; if (parent != 0) { - parentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, parent); + parentOrientation = RenderSystem::AbsoluteOrientation(m_World, parent); } glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"]; //glm::quat currentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection); @@ -235,10 +235,10 @@ void EditorSystem::updateWidget() if (m_Selection != 0) { auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); - glm::vec3 selectionPosition = RenderQueueFactory::AbsolutePosition(m_World, m_Selection); + glm::vec3 selectionPosition = RenderSystem::AbsolutePosition(m_World, m_Selection); widgetTransform["Position"] = selectionPosition; if (m_WidgetSpace == WidgetSpace::Local) { - widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection)); + widgetTransform["Orientation"] = glm::eulerAngles(RenderSystem::AbsoluteOrientation(m_World, m_Selection)); } } } @@ -264,7 +264,7 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) if (m_Selection != 0) { if (m_WidgetSpace == WidgetSpace::Local) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); - widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection)); + widgetTransform["Orientation"] = glm::eulerAngles(RenderSystem::AbsoluteOrientation(m_World, m_Selection)); } } } else if (newMode == WidgetMode::Scale) { @@ -285,7 +285,7 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) if (m_Selection != 0) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); if (m_WidgetSpace == WidgetSpace::Local) { - widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection)); + widgetTransform["Orientation"] = glm::eulerAngles(RenderSystem::AbsoluteOrientation(m_World, m_Selection)); } } } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index b35f69ab..c08d4971 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -8,6 +8,8 @@ RenderSystem::RenderSystem(EventBroker* eventBrokerer, RenderQueueCollection* re Initialize(); EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); + + } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index c67a4757..0ef1e4bf 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -5,20 +5,26 @@ void Renderer::Initialize() { InitializeWindow(); - TEMPCreateLights(); InitializeRenderPasses(); glfwSwapInterval(m_VSYNC); InitializeShaders(); InitializeTextures(); - InitializeSSBOs(); - //CalculateFrustum(); m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj"); m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker); + + + // Create default camera + m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(45.f), 0.01f, 5000.f); + m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10)); + if (m_Camera == nullptr) { + m_Camera = m_DefaultCamera; + } + } void Renderer::InitializeWindow() @@ -70,16 +76,6 @@ void Renderer::InitializeShaders() m_DrawScreenQuadProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl"))); m_DrawScreenQuadProgram->Compile(); m_DrawScreenQuadProgram->Link(); - - //m_CalculateFrustumProgram = ResourceManager::Load("#CalculateFrustumProgram"); - //m_CalculateFrustumProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/GridFrustum.comp.glsl"))); - //m_CalculateFrustumProgram.Compile(); - //m_CalculateFrustumProgram.Link(); - - //m_LightCullProgram = ResourceManager::Load("#LightCullProgram"); - //m_LightCullProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); - //m_LightCullProgram.Compile(); - //m_LightCullProgram.Link(); } void Renderer::InputUpdate(double dt) @@ -98,7 +94,6 @@ void Renderer::Draw(RenderQueueCollection& rq) { m_PickingPass->Draw(rq); //DrawScreenQuad(m_PickingPass->PickingTexture()); - //CullLights(); glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f); @@ -147,94 +142,8 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin GLERROR("Texture initialization failed"); } -void Renderer::InitializeSSBOs() -{ - printf("Size: %i\n", sizeof(m_Frustums)); - glGenBuffers(1, &m_FrustumSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_Frustums), &m_Frustums, GL_DYNAMIC_COPY); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - - GLERROR("m_FrustumSSBO"); - - glGenBuffers(1, &m_LightSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_PointLights), &m_PointLights, GL_DYNAMIC_COPY); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - - GLERROR("m_LightSSBO"); - - - glGenBuffers(1, &m_LightGridSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightGrid), &m_LightGrid, GL_DYNAMIC_COPY); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - - GLERROR("m_LightGridSSBO"); - - - glGenBuffers(1, &m_LightOffsetSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - - GLERROR("m_LightOffsetSSBO"); - - - glGenBuffers(1, &m_LightIndexSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightIndex), &m_LightIndex, GL_DYNAMIC_COPY); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - - GLERROR("m_LightIndexSSBO"); - -} - void Renderer::InitializeRenderPasses() { m_DrawScenePass = new DrawScenePass(this); m_PickingPass = new PickingPass(this, m_EventBroker); } - -void Renderer::CalculateFrustum() -{ -// GLERROR("CalculateFrustum Error-1"); -// m_CalculateFrustumProgram->Bind(); -// GLERROR("CalculateFrustum Error1"); -// glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); -// GLERROR("CalculateFrustum Error2"); -// // glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix())); -// GLERROR("CalculateFrustum Error3"); -// // glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height); -// GLERROR("CalculateFrustum Error4"); -// //glDispatchCompute(5, 3, 1); -// GLERROR("CalculateFrustum Error5"); - -} - -void Renderer::TEMPCreateLights() -{ - for (int i = 0; i < NUM_LIGHTS; i++) { - m_PointLights[i].Position = glm::vec4(i, 0.f, 0.f, 0.f); - m_PointLights[i].Color = glm::vec4(1.f, 0.5f, 0.f + i*0.1f, 1.f); - } -} - -void Renderer::CullLights() -{ - m_LightCullProgram->Bind(); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO); - glDispatchCompute(m_Resolution.Width / TILE_SIZE, m_Resolution.Height / TILE_SIZE, 1); - GLERROR("CullLights Error"); - -} - diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 861c84b0..4ab6f410 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -14,7 +14,6 @@ Game::Game(int argc, char* argv[]) // Create the core event broker m_EventBroker = new EventBroker(); - m_RenderQueueFactory = new RenderQueueFactory(); // Create the renderer m_Renderer = new Renderer(m_EventBroker, m_World); @@ -48,6 +47,8 @@ Game::Game(int argc, char* argv[]) ResourceManager::Load(mapToLoad)->PopulateWorld(m_World); } + m_RenderQueues = new RenderQueueCollection(); + // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); m_SystemPipeline->AddSystem(); From d8c4c6e5ff9138285aed5b10429f5ea5ab64e151 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 7 Jan 2016 15:22:46 +0100 Subject: [PATCH 06/50] Created a primitive SoundSystem. Can play a sound with 'P' button. Using resourcemanager. Not using the created components yet. --- assets | 2 +- deps | 2 +- include/Engine/Sound/EPlaySound.h | 18 +++ include/Engine/Sound/Sound.h | 113 +++++++++++++++++++ include/Engine/Sound/SoundSystem.h | 62 ++++++++++ include/Game/Game.h | 7 ++ resources/Schema/Components.xsd | 2 + resources/Schema/Components/Listener.xml | 3 + resources/Schema/Components/Listener.xsd | 8 ++ resources/Schema/Components/SoundEmitter.xml | 7 ++ resources/Schema/Components/SoundEmitter.xsd | 22 ++++ resources/Schema/Types/Entity.xsd | 2 + src/Engine/CMakeLists.txt | 11 +- src/Engine/Sound/SoundSystem.cpp | 66 +++++++++++ src/Game/Game.cpp | 18 ++- 15 files changed, 338 insertions(+), 5 deletions(-) create mode 100644 include/Engine/Sound/EPlaySound.h create mode 100644 include/Engine/Sound/Sound.h create mode 100644 include/Engine/Sound/SoundSystem.h create mode 100644 resources/Schema/Components/Listener.xml create mode 100644 resources/Schema/Components/Listener.xsd create mode 100644 resources/Schema/Components/SoundEmitter.xml create mode 100644 resources/Schema/Components/SoundEmitter.xsd create mode 100644 src/Engine/Sound/SoundSystem.cpp diff --git a/assets b/assets index 673d4a4e..6cbf2365 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 673d4a4e4c5a3f5bc9fedf82234e8f8751f63a44 +Subproject commit 6cbf2365d49e6280750ea3bcd0f9c271779e6f15 diff --git a/deps b/deps index 1ae6ba5b..293516d6 160000 --- a/deps +++ b/deps @@ -1 +1 @@ -Subproject commit 1ae6ba5b1297ed71b560aee211b9f0007ba52547 +Subproject commit 293516d671b97de26594fe979b7898b7e271e24c diff --git a/include/Engine/Sound/EPlaySound.h b/include/Engine/Sound/EPlaySound.h new file mode 100644 index 00000000..83fc4629 --- /dev/null +++ b/include/Engine/Sound/EPlaySound.h @@ -0,0 +1,18 @@ +#ifndef Events_PlaySound_h__ +#define Events_PlaySound_h__ + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + + struct PlaySound : Event +{ + std::string FilePath; + EntityID emitter; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/Sound.h b/include/Engine/Sound/Sound.h new file mode 100644 index 00000000..ffb9b30e --- /dev/null +++ b/include/Engine/Sound/Sound.h @@ -0,0 +1,113 @@ +#ifndef Sound_h__ +#define Sound_h__ + +#include "Core/ResourceManager.h" + +class Sound : public Resource +{ + friend class ResourceManager; +public: + Sound(std::string path) { m_Buffer = LoadFile(path); } + ~Sound() { ClearBuffer(); } + ALuint Buffer() { return m_Buffer; } + std::string Path() { return m_Path; } + float Gain() { return m_Gain; } + void SetGain(float value) { m_Gain = value; } + void ClearBuffer() { alDeleteBuffers(1, &m_Buffer); m_BufferCache.clear(); }; + +private: + float m_Gain = 1; + ALuint m_Buffer; + std::string m_Path; + + // File info + char m_Type[4]; + unsigned long m_Size, m_ChunkSize; + short m_FormatType, m_Channels; + unsigned long m_SampleRate, m_AvgBytesPerSec; + short m_BytesPerSample, m_BitsPerSample; + unsigned int m_DataSize; + std::map m_BufferCache; + + ALuint LoadFile(std::string path) + { + if (m_BufferCache.find(path) != m_BufferCache.end()) { + return m_BufferCache[path]; + } + + //// Open file + FILE *fp = fopen(path.c_str(), "rb"); + if (!fp) { + printf("Failed to open file %s, no such file exists", path.c_str()); + return 0; + } + + //// CHECK FOR VALID WAVE-FILE + fread(m_Type, sizeof(char), 4, fp); + if (m_Type[0] != 'R' || m_Type[1] != 'I' || m_Type[2] != 'F' || m_Type[3] != 'F') { + printf("ERROR: No RIFF in WAVE-file"); + return 0; + } + + fread(&m_Size, 4 * sizeof(char), 1, fp); + fread(m_Type, sizeof(char), 4, fp); + if (m_Type[0] != 'W' || m_Type[1] != 'A' || m_Type[2] != 'V' || m_Type[3] != 'E') { + printf("ERROR: Not WAVE-file"); + return 0; + } + + fread(m_Type, sizeof(char), 4, fp); + if (m_Type[0] != 'f' || m_Type[1] != 'm' || m_Type[2] != 't' || m_Type[3] != ' ') { + printf("ERROR: No fmt in WAVE-file"); + return 0; + } + + //// READ THE DATA FROM WAVE-FILE + fread(&m_ChunkSize, 4 * sizeof(char), 1, fp); + fread(&m_FormatType, 2 * sizeof(char), 1, fp); + fread(&m_Channels, 2 * sizeof(char), 1, fp); + fread(&m_SampleRate, 4 * sizeof(char), 1, fp); + fread(&m_AvgBytesPerSec, 4 * sizeof(char), 1, fp); + fread(&m_BytesPerSample, 2 * sizeof(char), 1, fp); + fread(&m_BitsPerSample, 2 * sizeof(char), 1, fp); + + fread(m_Type, sizeof(char), 4, fp); + if (m_Type[0] != 'd' || m_Type[1] != 'a' || m_Type[2] != 't' || m_Type[3] != 'a') { + printf("ERROR: WAVE-file Missing data"); + return 0; + } + + fread(&m_DataSize, 4 * sizeof(char), 1, fp); + + unsigned char* buf = new unsigned char[m_DataSize]; + fread(buf, sizeof(char), m_DataSize, fp); + fclose(fp); + + //// Create buffer + ALuint format = 0; + if (m_BitsPerSample == 8) { + if (m_Channels == 1) { + format = AL_FORMAT_MONO8; + } else if (m_Channels == 2) { + format = AL_FORMAT_STEREO8; + } + } + if (m_BitsPerSample == 16) { + if (m_Channels == 1) { + format = AL_FORMAT_MONO16; + } else if (m_Channels == 2) { + format = AL_FORMAT_STEREO16; + } + } + + ALuint buffer; + alGenBuffers(1, &buffer); + alBufferData(buffer, format, buf, m_DataSize, m_SampleRate); + delete[] buf; + + m_BufferCache[path] = buffer; + return buffer; + } +}; + +#endif diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h new file mode 100644 index 00000000..0035a3bb --- /dev/null +++ b/include/Engine/Sound/SoundSystem.h @@ -0,0 +1,62 @@ +#ifndef SoundSystem_h__ +#define SoundSystem_h__ + +#include + +#include "glm/common.hpp" +#include "OpenAL/al.h" +#include "OpenAL/alc.h" + +#include "Core/World.h" +#include "Core/EventBroker.h" +#include "Sound/Sound.h" +#include "Sound/EPlaySound.h" + +struct Source +{ + Sound* SoundResource; + ALuint ALsource; +}; + +class SoundSystem +{ +public: + SoundSystem() { } + SoundSystem(EventBroker* eventBroker); + ~SoundSystem(); + void Update() { } // Update emitters +private: + // Private setters and getters for working with glm + void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; + glm::vec3 listnerPos() { glm::vec3 pos; alGetListener3f(AL_POSITION, &pos.x, &pos.y, &pos.z); return pos; }; + void setListenerVel(glm::vec3 vel) { alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); }; + glm::vec3 listenerVel() { glm::vec3 vel; alGetListener3f(AL_VELOCITY, &vel.x, &vel.y, &vel.z); return vel; }; + void setListenerOri(glm::vec3 ori) { alListener3f(AL_ORIENTATION, ori.x, ori.y, ori.z); }; + glm::vec3 listenerOri() { glm::vec3 ori; alGetListener3f(AL_ORIENTATION, &ori.x, &ori.y, &ori.z); return ori; }; + void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; + void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; + void setSourceOri(ALuint source, glm::vec3 ori) { ALfloat sori[3] = { ori.x, ori.y, ori.z }; alSourcefv(source, AL_ORIENTATION, sori); }; + + // Logic + World* m_World; + EventBroker* m_EventBroker; + + ALuint createSource(); + void playSound(Source source); + void stopSound(Source source); + void stopEmitter(EntityID emitter); + + // OpenAL system variables + ALCdevice* m_ALCdevice = nullptr; + ALCcontext* m_ALCcontext = nullptr; + + // Logic + std::unordered_map m_Sources; + + // Events + EventRelay m_EPlaySound; + bool OnPlaySound(const Events::PlaySound &e); + +}; + +#endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 33dc88a6..6b284c74 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -25,6 +25,10 @@ #include "Network/Server.h" #include "Network/Client.h" +// Sound +#include "Sound/SoundSystem.h" +#include "Sound/EPlaySound.h" + class Game { @@ -54,6 +58,9 @@ private: Network* m_ClientOrServer; bool m_IsClientOrServer = false; + // Sound + SoundSystem* m_SoundSystem; + EventRelay m_EInputCommand; bool debugOnInputCommand(const Events::InputCommand& e); diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index fd04fd39..a287431c 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -8,4 +8,6 @@ + + \ No newline at end of file diff --git a/resources/Schema/Components/Listener.xml b/resources/Schema/Components/Listener.xml new file mode 100644 index 00000000..7d1fac13 --- /dev/null +++ b/resources/Schema/Components/Listener.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/Listener.xsd b/resources/Schema/Components/Listener.xsd new file mode 100644 index 00000000..5f71f11a --- /dev/null +++ b/resources/Schema/Components/Listener.xsd @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/SoundEmitter.xml b/resources/Schema/Components/SoundEmitter.xml new file mode 100644 index 00000000..a032dfbb --- /dev/null +++ b/resources/Schema/Components/SoundEmitter.xml @@ -0,0 +1,7 @@ + + 1.0 + 1.0 + 20.0 + 1.0 + 1.0 + \ No newline at end of file diff --git a/resources/Schema/Components/SoundEmitter.xsd b/resources/Schema/Components/SoundEmitter.xsd new file mode 100644 index 00000000..6bebcac5 --- /dev/null +++ b/resources/Schema/Components/SoundEmitter.xsd @@ -0,0 +1,22 @@ + + + + + + + + + + The "volume" of the emitter. A value betweeen 0-1 + + The pitch of the emitter. A value betweeen 0-1 + + The distance where there will no longer be any attenuation. + + The rolloff rate of the source. + + The distance that the source will be the loudest. + + + + \ No newline at end of file diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 92f7dc31..67612935 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -15,6 +15,8 @@ + + diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 5d43db8b..40bc9cb0 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -9,8 +9,8 @@ find_package(ZLIB REQUIRED) find_package(PNG REQUIRED) find_package(Xerces REQUIRED) # Because FindOpenAL is retarded -#set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/deps/include/AL") -#find_package(OpenAL REQUIRED) +set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/deps/include/OpenAL") +find_package(OpenAL REQUIRED) if(UNIX) find_package(X11 REQUIRED) endif() @@ -52,6 +52,12 @@ file(GLOB SOURCE_FILES_Network ) source_group(Network FILES ${SOURCE_FILES_Network}) +file(GLOB SOURCE_FILES_Sound + "${INCLUDE_PATH}/Sound/*.h" + "Sound/*.cpp" +) +source_group(Sound FILES ${SOURCE_FILES_Sound}) + file(GLOB SOURCE_FILES_Rendering "${INCLUDE_PATH}/Rendering/*.h" "Rendering/*.cpp" @@ -86,6 +92,7 @@ set(SOURCE_FILES ${SOURCE_FILES_Core_Util} ${SOURCE_FILES_Input} ${SOURCE_FILES_Network} + ${SOURCE_FILES_Sound} ${SOURCE_FILES_GUI} ${SOURCE_FILES_Rendering} ${SOURCE_FILES_Rendering_Util} diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp new file mode 100644 index 00000000..965f97a4 --- /dev/null +++ b/src/Engine/Sound/SoundSystem.cpp @@ -0,0 +1,66 @@ +#include "Sound/SoundSystem.h" + +SoundSystem::SoundSystem(EventBroker* eventBroker) +{ + m_EventBroker = eventBroker; + // Initialize OpenAL + m_ALCdevice = alcOpenDevice(nullptr); + if (m_ALCdevice != nullptr) { + m_ALCcontext = alcCreateContext(m_ALCdevice, nullptr); + alcMakeContextCurrent(m_ALCcontext); + } else { + LOG_ERROR("OpenAL failed to initialize."); + } + + alSpeedOfSound(340.29f); // Speed of sound + alDistanceModel(AL_INVERSE_DISTANCE); + + EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); + //m_EPlaySound = decltype(m_EPlaySound)(std::bind(&SoundSystem::OnPlaySound, this, std::placeholders::_1)); + //m_EventBroker->Subscribe(m_EPlaySound); +} + +SoundSystem::~SoundSystem() +{ + alcDestroyContext(m_ALCcontext); + alcCloseDevice(m_ALCdevice); + delete m_ALCcontext; + delete m_ALCdevice; +} + +ALuint SoundSystem::createSource() +{ + ALuint source; + alGenSources((ALuint)1, &source); + alSourcei(source, AL_REFERENCE_DISTANCE, 1.0); + alSourcei(source, AL_MAX_DISTANCE, FLT_MAX); + return source; +} + +void SoundSystem::playSound(Source source) +{ + alSourcei(source.ALsource, AL_BUFFER, source.SoundResource->Buffer()); + alSourcePlay(source.ALsource); +} + +void SoundSystem::stopSound(Source source) +{ } + +void SoundSystem::stopEmitter(EntityID emitter) +{ } + +bool SoundSystem::OnPlaySound(const Events::PlaySound & e) +{ + Sound *sound = ResourceManager::Load(e.FilePath); + if (sound == nullptr) { + return false; + } + ALuint source = createSource(); + Source sauce; + sauce.ALsource = source; + sauce.SoundResource = sound; + playSound(sauce); + LOG_INFO("You are playing an imaginary sound now! :D"); + return false; +} + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 033db642..66ab6fae 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -5,6 +5,7 @@ Game::Game(int argc, char* argv[]) { ResourceManager::RegisterType("ConfigFile"); + ResourceManager::RegisterType("Sound"); ResourceManager::RegisterType("Model"); ResourceManager::RegisterType("Texture"); ResourceManager::RegisterType("EntityXMLFile"); @@ -63,6 +64,9 @@ Game::Game(int argc, char* argv[]) //boost::thread workerThread(&Game::networkFunction, this); networkFunction(); } + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); + m_SoundSystem = new SoundSystem(m_EventBroker); + m_LastTime = glfwGetTime(); } @@ -103,9 +107,11 @@ void Game::Tick() // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); + debugTick(dt); m_Renderer->Update(dt); m_EventBroker->Process(); - + m_EventBroker->Process(); + m_SoundSystem->Update(); m_RenderQueueFactory->Update(m_World); GLERROR("Game::Tick m_RenderQueueFactory->Update"); m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); @@ -114,6 +120,16 @@ void Game::Tick() m_EventBroker->Clear(); } +bool Game::debugOnInputCommand(const Events::InputCommand & e) +{ + if (e.Command == "PlaySound" && e.Value > 0) { + Events::PlaySound e; + e.FilePath = "Audio/crosscounter.wav"; + m_EventBroker->Publish(e); + } + return true; +} + void Game::debugTick(double dt) { m_EventBroker->Process(); From 2838446072fd3464718a342e0768c75ac7050416 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 7 Jan 2016 16:03:33 +0100 Subject: [PATCH 07/50] In lack of camera entity I created a Listener cube to test 3D sound. Works fine. Updates listener pos each tick. --- include/Engine/Sound/SoundSystem.h | 4 ++-- src/Engine/Sound/SoundSystem.cpp | 21 +++++++++++++++------ src/Game/Game.cpp | 9 ++++++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 0035a3bb..0555feb4 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -22,9 +22,9 @@ class SoundSystem { public: SoundSystem() { } - SoundSystem(EventBroker* eventBroker); + SoundSystem(World* world, EventBroker* eventBroker); ~SoundSystem(); - void Update() { } // Update emitters + void Update(); // Update emitters private: // Private setters and getters for working with glm void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 965f97a4..b9736096 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -1,8 +1,9 @@ #include "Sound/SoundSystem.h" -SoundSystem::SoundSystem(EventBroker* eventBroker) +SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) { m_EventBroker = eventBroker; + m_World = world; // Initialize OpenAL m_ALCdevice = alcOpenDevice(nullptr); if (m_ALCdevice != nullptr) { @@ -16,20 +17,29 @@ SoundSystem::SoundSystem(EventBroker* eventBroker) alDistanceModel(AL_INVERSE_DISTANCE); EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); - //m_EPlaySound = decltype(m_EPlaySound)(std::bind(&SoundSystem::OnPlaySound, this, std::placeholders::_1)); - //m_EventBroker->Subscribe(m_EPlaySound); } SoundSystem::~SoundSystem() -{ +{ alcDestroyContext(m_ALCcontext); alcCloseDevice(m_ALCdevice); delete m_ALCcontext; delete m_ALCdevice; } +void SoundSystem::Update() +{ + // Should only be one listener. + auto listenerComponents = m_World->GetComponents("Listener"); + for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { + EntityID listener = (*it).EntityID; + auto transform = m_World->GetComponent(listener, "Transform"); + setListenerPos(transform["Position"]); + } +} + ALuint SoundSystem::createSource() -{ +{ ALuint source; alGenSources((ALuint)1, &source); alSourcei(source, AL_REFERENCE_DISTANCE, 1.0); @@ -60,7 +70,6 @@ bool SoundSystem::OnPlaySound(const Events::PlaySound & e) sauce.ALsource = source; sauce.SoundResource = sound; playSound(sauce); - LOG_INFO("You are playing an imaginary sound now! :D"); return false; } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 66ab6fae..1863fa38 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -65,7 +65,14 @@ Game::Game(int argc, char* argv[]) networkFunction(); } EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); - m_SoundSystem = new SoundSystem(m_EventBroker); + m_SoundSystem = new SoundSystem(m_World, m_EventBroker); + + auto soundListenerCube = m_World->CreateEntity(); + m_World->AttachComponent(soundListenerCube, "Listener"); + m_World->AttachComponent(soundListenerCube, "Transform"); + auto model = m_World->AttachComponent(soundListenerCube, "Model"); + model["Resource"] = "Models/Core/UnitCube.obj"; + model["Color"] = glm::vec4(1, 0, 0, 1); m_LastTime = glfwGetTime(); } From da6e50dc7eb17671664033b871e58fc57c657ba6 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 7 Jan 2016 17:04:43 +0100 Subject: [PATCH 08/50] Correct orientation. Need to clean this up. --- include/Engine/Sound/SoundSystem.h | 17 ++++++++++++++++- src/Engine/Sound/SoundSystem.cpp | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 0555feb4..de31e216 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -4,6 +4,7 @@ #include #include "glm/common.hpp" +#include "glm/gtx/rotate_vector.hpp" #include "OpenAL/al.h" #include "OpenAL/alc.h" @@ -31,7 +32,21 @@ private: glm::vec3 listnerPos() { glm::vec3 pos; alGetListener3f(AL_POSITION, &pos.x, &pos.y, &pos.z); return pos; }; void setListenerVel(glm::vec3 vel) { alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); }; glm::vec3 listenerVel() { glm::vec3 vel; alGetListener3f(AL_VELOCITY, &vel.x, &vel.y, &vel.z); return vel; }; - void setListenerOri(glm::vec3 ori) { alListener3f(AL_ORIENTATION, ori.x, ori.y, ori.z); }; + void setListenerOri(glm::vec3 ori) + { + glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); + forward = glm::rotateX(forward, ori.x); + forward = glm::rotateY(forward, ori.y); + forward = glm::rotateZ(forward, ori.z); + glm::normalize(forward); + glm::vec3 up = glm::vec3(0.0, 1.0, 0.0); + up = glm::rotateX(up, ori.x); + up = glm::rotateY(up, ori.y); + up = glm::rotateZ(up, ori.z); + glm::normalize(up); + ALfloat lori[6] = { forward.x, forward.y, forward.z , up.x, up.y, up.z }; + alListenerfv(AL_ORIENTATION, lori); + }; glm::vec3 listenerOri() { glm::vec3 ori; alGetListener3f(AL_ORIENTATION, &ori.x, &ori.y, &ori.z); return ori; }; void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index b9736096..64312fa8 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -35,6 +35,7 @@ void SoundSystem::Update() EntityID listener = (*it).EntityID; auto transform = m_World->GetComponent(listener, "Transform"); setListenerPos(transform["Position"]); + setListenerOri(transform["Orientation"]); } } From 3cce9f80751d5bc2da692d9570e511e0f92f5967 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 8 Jan 2016 15:29:20 +0100 Subject: [PATCH 09/50] Using absolute transform --- include/Engine/Sound/SoundSystem.h | 28 ++--- resources/Schema/Components/SoundEmitter.xml | 1 + resources/Schema/Components/SoundEmitter.xsd | 1 + src/Engine/Sound/SoundSystem.cpp | 116 ++++++++++++++++--- 4 files changed, 111 insertions(+), 35 deletions(-) diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index de31e216..5a8225ef 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -10,6 +10,7 @@ #include "Core/World.h" #include "Core/EventBroker.h" +#include "Rendering/RenderQueueFactory.h" // Absolute transform #include "Sound/Sound.h" #include "Sound/EPlaySound.h" @@ -27,35 +28,27 @@ public: ~SoundSystem(); void Update(); // Update emitters private: - // Private setters and getters for working with glm + // Help functions for working with OpenaAL void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; glm::vec3 listnerPos() { glm::vec3 pos; alGetListener3f(AL_POSITION, &pos.x, &pos.y, &pos.z); return pos; }; void setListenerVel(glm::vec3 vel) { alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z); }; glm::vec3 listenerVel() { glm::vec3 vel; alGetListener3f(AL_VELOCITY, &vel.x, &vel.y, &vel.z); return vel; }; - void setListenerOri(glm::vec3 ori) - { - glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); - forward = glm::rotateX(forward, ori.x); - forward = glm::rotateY(forward, ori.y); - forward = glm::rotateZ(forward, ori.z); - glm::normalize(forward); - glm::vec3 up = glm::vec3(0.0, 1.0, 0.0); - up = glm::rotateX(up, ori.x); - up = glm::rotateY(up, ori.y); - up = glm::rotateZ(up, ori.z); - glm::normalize(up); - ALfloat lori[6] = { forward.x, forward.y, forward.z , up.x, up.y, up.z }; - alListenerfv(AL_ORIENTATION, lori); - }; + void setListenerOri(glm::vec3 ori); glm::vec3 listenerOri() { glm::vec3 ori; alGetListener3f(AL_ORIENTATION, &ori.x, &ori.y, &ori.z); return ori; }; void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; - void setSourceOri(ALuint source, glm::vec3 ori) { ALfloat sori[3] = { ori.x, ori.y, ori.z }; alSourcefv(source, AL_ORIENTATION, sori); }; + + bool isPlaying(ALuint source); // Logic World* m_World; EventBroker* m_EventBroker; + void initOpenAL(); + void updateEmitters(); + void updateListener(); + void deleteInactiveEmitters(); + void addNewEmitters(); ALuint createSource(); void playSound(Source source); void stopSound(Source source); @@ -71,7 +64,6 @@ private: // Events EventRelay m_EPlaySound; bool OnPlaySound(const Events::PlaySound &e); - }; #endif \ No newline at end of file diff --git a/resources/Schema/Components/SoundEmitter.xml b/resources/Schema/Components/SoundEmitter.xml index a032dfbb..cbcfc440 100644 --- a/resources/Schema/Components/SoundEmitter.xml +++ b/resources/Schema/Components/SoundEmitter.xml @@ -1,4 +1,5 @@ + Audio/crosscounter.wav 1.0 1.0 20.0 diff --git a/resources/Schema/Components/SoundEmitter.xsd b/resources/Schema/Components/SoundEmitter.xsd index 6bebcac5..31c18ce9 100644 --- a/resources/Schema/Components/SoundEmitter.xsd +++ b/resources/Schema/Components/SoundEmitter.xsd @@ -6,6 +6,7 @@ + The "volume" of the emitter. A value betweeen 0-1 diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 64312fa8..fd379d50 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -4,6 +4,17 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) { m_EventBroker = eventBroker; m_World = world; + + initOpenAL(); + + alSpeedOfSound(340.29f); // Speed of sound + alDistanceModel(AL_INVERSE_DISTANCE); + + EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); +} + +void SoundSystem::initOpenAL() +{ // Initialize OpenAL m_ALCdevice = alcOpenDevice(nullptr); if (m_ALCdevice != nullptr) { @@ -12,11 +23,6 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) } else { LOG_ERROR("OpenAL failed to initialize."); } - - alSpeedOfSound(340.29f); // Speed of sound - alDistanceModel(AL_INVERSE_DISTANCE); - - EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); } SoundSystem::~SoundSystem() @@ -28,14 +34,67 @@ SoundSystem::~SoundSystem() } void SoundSystem::Update() +{ + //deleteInactiveEmitters(); // Not tested + addNewEmitters(); + updateEmitters(); + updateListener(); +} + +void SoundSystem::deleteInactiveEmitters() +{ + auto emitterComponents = m_World->GetComponents("SoundEmitter"); + for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + EntityID emitter = (*it).EntityID; + if (isPlaying(m_Sources[emitter].ALsource)) { // The sound is still playing, do not remove + continue; + } + alDeleteBuffers(1, &m_Sources[emitter].ALsource); + delete m_Sources[emitter].SoundResource; + m_Sources.erase(emitter); + } +} + +void SoundSystem::addNewEmitters() +{ + auto emitterComponents = m_World->GetComponents("SoundEmitter"); + for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + EntityID emitter = (*it).EntityID; + std::unordered_map::iterator i; + i = m_Sources.find(emitter); + if (i == m_Sources.end()) { // Did not exist, add it + Source source; + source.ALsource = createSource(); + source.SoundResource = ResourceManager::Load((std::string)(*it)["FilePath"]); + m_Sources[emitter] = source; + } + } +} + +void SoundSystem::updateEmitters() +{ + auto emitterComponents = m_World->GetComponents("SoundEmitter"); + for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + EntityID emitter = (*it).EntityID; + std::unordered_map::iterator i; + i = m_Sources.find(emitter); + if (i != m_Sources.end()) { + setSourcePos(m_Sources[emitter].ALsource, RenderQueueFactory::AbsolutePosition(m_World, emitter)); + } + // No orientation, emitts in all directions + // Velocity for doppler effect + } +} + +void SoundSystem::updateListener() { // Should only be one listener. auto listenerComponents = m_World->GetComponents("Listener"); for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { EntityID listener = (*it).EntityID; - auto transform = m_World->GetComponent(listener, "Transform"); - setListenerPos(transform["Position"]); - setListenerOri(transform["Orientation"]); + setListenerPos(RenderQueueFactory::AbsolutePosition(m_World, listener)); + setListenerOri(glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, listener))); + // Velocity for doppler effect } } @@ -62,15 +121,38 @@ void SoundSystem::stopEmitter(EntityID emitter) bool SoundSystem::OnPlaySound(const Events::PlaySound & e) { - Sound *sound = ResourceManager::Load(e.FilePath); - if (sound == nullptr) { - return false; - } - ALuint source = createSource(); - Source sauce; - sauce.ALsource = source; - sauce.SoundResource = sound; - playSound(sauce); + //Sound *sound = ResourceManager::Load(e.FilePath); + //if (sound == nullptr) { + // return false; + //} + //ALuint source = createSource(); + //Source sauce; + //sauce.ALsource = source; + //sauce.SoundResource = sound; + //playSound(sauce); return false; } +void SoundSystem::setListenerOri(glm::vec3 ori) +{ + glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); + forward = glm::rotateX(forward, ori.x); + forward = glm::rotateY(forward, ori.y); + forward = glm::rotateZ(forward, ori.z); + glm::normalize(forward); + glm::vec3 up = glm::vec3(0.0, 1.0, 0.0); + up = glm::rotateX(up, ori.x); + up = glm::rotateY(up, ori.y); + up = glm::rotateZ(up, ori.z); + glm::normalize(up); + ALfloat lOri[6] = { forward.x, forward.y, forward.z, up.x, up.y, up.z }; + alListenerfv(AL_ORIENTATION, lOri); +} + +bool SoundSystem::isPlaying(ALuint source) +{ + ALenum state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return (state == AL_PLAYING); +} + From a7b43b06a2672faf86e3579cbd45e9fb73991042 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 8 Jan 2016 16:21:59 +0100 Subject: [PATCH 10/50] Camera component and RenderQueue changes --- include/Engine/GUI/Button.h | 2 +- include/Engine/GUI/Frame.h | 4 +- include/Engine/GUI/TextureFrame.h | 2 +- include/Engine/Rendering/Camera.h | 10 +- include/Engine/Rendering/DrawScenePass.h | 2 +- include/Engine/Rendering/DummyRenderer.h | 2 +- include/Engine/Rendering/ESetCamera.h | 4 +- include/Engine/Rendering/IRenderer.h | 2 +- include/Engine/Rendering/PickingPass.h | 2 +- include/Engine/Rendering/RenderQueue.h | 38 +++++++- include/Engine/Rendering/RenderSystem.h | 15 ++- include/Engine/Rendering/Renderer.h | 2 +- include/Game/Game.h | 2 +- resources/Schema/Components/Camera.xml | 1 + resources/Schema/Components/Camera.xsd | 1 + resources/Schema/Entities/Test.xml | 2 + src/Engine/Rendering/Camera.cpp | 9 -- src/Engine/Rendering/DrawScenePass.cpp | 48 +++++----- src/Engine/Rendering/DummyRenderer.cpp | 2 +- src/Engine/Rendering/PickingPass.cpp | 56 ++++++----- src/Engine/Rendering/RenderSystem.cpp | 116 +++++++++++++++-------- src/Engine/Rendering/Renderer.cpp | 8 +- src/Game/Game.cpp | 6 +- 23 files changed, 199 insertions(+), 137 deletions(-) diff --git a/include/Engine/GUI/Button.h b/include/Engine/GUI/Button.h index 91bd9782..80845cb7 100644 --- a/include/Engine/GUI/Button.h +++ b/include/Engine/GUI/Button.h @@ -40,7 +40,7 @@ public: m_TexturePressed = resourceName; } - void Draw(RenderQueueCollection& rq) override + void Draw(RenderScene& rq) override { if (m_Texture == nullptr && !m_TextureReleased.empty()) { SetTexture(m_TextureReleased); diff --git a/include/Engine/GUI/Frame.h b/include/Engine/GUI/Frame.h index 416b8117..4c5f2eb9 100644 --- a/include/Engine/GUI/Frame.h +++ b/include/Engine/GUI/Frame.h @@ -212,7 +212,7 @@ public: virtual void Update(double dt) { } - void DrawLayered(RenderQueueCollection& rq) + void DrawLayered(RenderScene& rq) { if (this->Hidden()) return; @@ -232,7 +232,7 @@ public: } } - virtual void Draw(RenderQueueCollection& rq) { } + virtual void Draw(RenderScene& rq) { } protected: ::EventBroker* m_EventBroker; diff --git a/include/Engine/GUI/TextureFrame.h b/include/Engine/GUI/TextureFrame.h index f02285ca..2c6d34dd 100644 --- a/include/Engine/GUI/TextureFrame.h +++ b/include/Engine/GUI/TextureFrame.h @@ -16,7 +16,7 @@ public: void EnableScissor() { m_ScissorEnabled = true; } void DisableScissor() { m_ScissorEnabled = false; } - void Draw(RenderQueueCollection& rq) override + void Draw(RenderScene& rq) override { if (m_Texture == nullptr) return; diff --git a/include/Engine/Rendering/Camera.h b/include/Engine/Rendering/Camera.h index 660dfd49..a1aae1bd 100644 --- a/include/Engine/Rendering/Camera.h +++ b/include/Engine/Rendering/Camera.h @@ -26,11 +26,6 @@ public: glm::quat Orientation() const { return m_Orientation; } void SetOrientation(glm::quat val); - /*float Pitch() const { return m_Pitch; } - void Pitch(float val); - float Yaw() const { return m_Yaw; } - void Yaw(float val);*/ - glm::mat4 ProjectionMatrix() const { return m_ProjectionMatrix; } glm::mat4 ViewMatrix() const { return m_ViewMatrix; } @@ -46,11 +41,10 @@ public: float FarClip() const { return m_FarClip; } void SetFarClip(float val); - + void UpdateViewMatrix(); + void UpdateProjectionMatrix(); private: - void UpdateViewMatrix(); - void UpdateProjectionMatrix(); glm::vec3 m_Position; glm::quat m_Orientation; diff --git a/include/Engine/Rendering/DrawScenePass.h b/include/Engine/Rendering/DrawScenePass.h index db52f746..4200383f 100644 --- a/include/Engine/Rendering/DrawScenePass.h +++ b/include/Engine/Rendering/DrawScenePass.h @@ -17,7 +17,7 @@ public: void InitializeFrameBuffers(); void InitializeShaderPrograms(); - void Draw(RenderQueueCollection& rq); + void Draw(RenderFrame& rf); //Getters diff --git a/include/Engine/Rendering/DummyRenderer.h b/include/Engine/Rendering/DummyRenderer.h index 56790fa1..176c5834 100644 --- a/include/Engine/Rendering/DummyRenderer.h +++ b/include/Engine/Rendering/DummyRenderer.h @@ -9,7 +9,7 @@ class DummyRenderer : public IRenderer { public: virtual void Initialize() override; - virtual void Draw(RenderQueueCollection& rq) override; + virtual void Draw(RenderFrame& rq) override; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/ESetCamera.h b/include/Engine/Rendering/ESetCamera.h index cf5b0a87..650f3b12 100644 --- a/include/Engine/Rendering/ESetCamera.h +++ b/include/Engine/Rendering/ESetCamera.h @@ -3,16 +3,16 @@ #include "../Core/EventBroker.h" #include "../Core/Entity.h" +#include namespace Events { -/** Thrown Every frame, use functions to pick*/ struct SetCamera : Event { public: SetCamera() { }; - EntityID Entity; + std::string Name; private: diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index 405de00e..42729479 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -31,7 +31,7 @@ public: } virtual void Initialize() = 0; virtual void Update(double dt) = 0; - virtual void Draw(RenderQueueCollection& rq) = 0; + virtual void Draw(RenderFrame& rq) = 0; protected: Rectangle m_Resolution = Rectangle(1280, 720); diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index e1bc42db..e4ff9e27 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -18,7 +18,7 @@ public: void InitializeFrameBuffers(); void InitializeShaderPrograms(); - void Draw(RenderQueueCollection& rq); + void Draw(RenderFrame& rf); //Getters diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 5fb09678..719e5cc7 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -39,9 +39,7 @@ struct ModelJob : RenderJob unsigned int ShaderID = 0; unsigned int TextureID = 0; - //TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this EntityID Entity; - glm::mat4 Matrix; const Texture* DiffuseTexture; const Texture* NormalTexture; @@ -165,7 +163,7 @@ private: int m_Size = 0; }; -struct RenderQueueCollection +struct RenderScene { RenderQueue Forward; RenderQueue Lights; @@ -184,4 +182,38 @@ struct RenderQueueCollection } }; +class RenderFrame +{ +public: + + void Add(RenderScene &scene) + { + RenderScenes.push_back(std::shared_ptr(new RenderScene(scene))); + m_Size++; + } + + void Clear() + { + RenderScenes.clear(); + m_Size = 0; + } + + int Size() const { return m_Size; } + std::list>::const_iterator begin() + { + return RenderScenes.begin(); + } + + std::list>::const_iterator end() + { + return RenderScenes.end(); + } + + std::list> RenderScenes; + + +private: + int m_Size = 0; +}; + #endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index e61ade55..34a9c5f9 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -12,10 +12,11 @@ #include "../Input/EInputCommand.h" #include "Camera.h" + class RenderSystem : public ImpureSystem { public: - RenderSystem(EventBroker* eventBrokerer, RenderQueueCollection* renderQueues); + RenderSystem(EventBroker* eventBrokerer, RenderFrame* renderFrame); virtual void Update(World* world, double dt) override; @@ -26,9 +27,14 @@ public: private: - RenderQueueCollection* m_RenderQueues; + World* m_World = nullptr; + + RenderFrame* m_RenderFrame; bool m_SwitchCamera = false; Camera* m_Camera = nullptr; + Camera* m_DefaultCamera = nullptr; + + std::list m_CameraComponents; EventRelay m_ESetCamera; bool OnSetCamera(const Events::SetCamera &event); @@ -37,13 +43,12 @@ private: void SwitchCamera(EntityID entity); void Initialize(); - void UpdateViewMatrix(ComponentWrapper& cameraTransform); void UpdateProjectionMatrix(ComponentWrapper& cameraComponent); glm::mat4 m_ViewMatrix; glm::mat4 m_ProjectionMatrix; - glm::mat4 ModelMatrix(World* world, EntityID entity); - void FillModels(World* world, RenderQueue* renderQueue); + glm::mat4 ModelMatrix(EntityID entity); + void FillModels(RenderQueue* renderQueue); EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index e22b9fec..d89fc4d2 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -27,7 +27,7 @@ public: virtual void Initialize() override; virtual void Update(double dt) override; - virtual void Draw(RenderQueueCollection& rq) override; + virtual void Draw(RenderFrame& rf) override; private: //----------------------Variables----------------------// diff --git a/include/Game/Game.h b/include/Game/Game.h index 85337707..d9e8821f 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -38,7 +38,7 @@ private: GUI::Frame* m_FrameStack; World* m_World; SystemPipeline* m_SystemPipeline; - RenderQueueCollection* m_RenderQueues; + RenderFrame* m_RenderFrame; EventRelay m_EInputCommand; bool debugOnInputCommand(const Events::InputCommand& e); diff --git a/resources/Schema/Components/Camera.xml b/resources/Schema/Components/Camera.xml index 7edb3489..8a93dec5 100644 --- a/resources/Schema/Components/Camera.xml +++ b/resources/Schema/Components/Camera.xml @@ -1,4 +1,5 @@ + cam 1.77 60.0 0.01 diff --git a/resources/Schema/Components/Camera.xsd b/resources/Schema/Components/Camera.xsd index 1ac8c394..3c462a3b 100644 --- a/resources/Schema/Components/Camera.xsd +++ b/resources/Schema/Components/Camera.xsd @@ -9,6 +9,7 @@ + diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 7b5cb820..df739177 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -18,6 +18,7 @@ Models/Camera.obj + MainCamera @@ -30,6 +31,7 @@ Models/Camera.obj + ActionCamera diff --git a/src/Engine/Rendering/Camera.cpp b/src/Engine/Rendering/Camera.cpp index 6ddf1c6c..ecc5d5cc 100644 --- a/src/Engine/Rendering/Camera.cpp +++ b/src/Engine/Rendering/Camera.cpp @@ -64,15 +64,6 @@ void Camera::SetOrientation(glm::quat val) void Camera::UpdateProjectionMatrix() { -// m_ProjectionMatrix = glm::ortho( -// -16.f, -// 16.f, -// -9.f, -// 9.f, -// m_NearClip, -// m_FarClip -// ); - m_ProjectionMatrix = glm::perspective(m_FOV, m_AspectRatio, m_NearClip, m_FarClip); } diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp index f0dd1405..dd34072f 100644 --- a/src/Engine/Rendering/DrawScenePass.cpp +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -25,40 +25,40 @@ void DrawScenePass::InitializeShaderPrograms() } -void DrawScenePass::Draw(RenderQueueCollection& rq) +void DrawScenePass::Draw(RenderFrame& rf) { //glBindFramebuffer(GL_FRAMEBUFFER, 0); GLERROR("Renderer::Draw PickingPass"); DrawScenePassState state; + for (auto scene : rf.RenderScenes) { + scene->Forward.Jobs.sort(DrawScenePass::DepthSort); - rq.Forward.Jobs.sort(DrawScenePass::DepthSort); + for (auto &job : scene->Forward) { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + GLuint ShaderHandle = m_BasicForwardProgram->GetHandle(); - //TODO: Render: Add code for more jobs than modeljobs. - for (auto &job : rq.Forward) { - auto modelJob = std::dynamic_pointer_cast(job); - if (modelJob) { - GLuint ShaderHandle = m_BasicForwardProgram->GetHandle(); + m_BasicForwardProgram->Bind(); + //TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms + glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "Matrix"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniform4fv(glGetUniformLocation(ShaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); - m_BasicForwardProgram->Bind(); - //TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "Matrix"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniform4fv(glGetUniformLocation(ShaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); + //TODO: Renderer: bättre textur felhantering samt fler texturer stöd + if (modelJob->DiffuseTexture != nullptr) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); + } else { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } - //TODO: Renderer: bättre textur felhantering samt fler texturer stöd - if (modelJob->DiffuseTexture != nullptr) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); - } else { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); + + continue; } - - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); - - continue; } } GLERROR("DrawScene Error"); diff --git a/src/Engine/Rendering/DummyRenderer.cpp b/src/Engine/Rendering/DummyRenderer.cpp index 451dfa09..ab529315 100644 --- a/src/Engine/Rendering/DummyRenderer.cpp +++ b/src/Engine/Rendering/DummyRenderer.cpp @@ -42,7 +42,7 @@ void DummyRenderer::Initialize() glfwSwapInterval(m_VSYNC); } -void DummyRenderer::Draw(RenderQueueCollection& rq) +void DummyRenderer::Draw(RenderFrame& rq) { glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f); glClear(GL_COLOR_BUFFER_BIT); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 0f821617..f7f0558c 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -43,7 +43,7 @@ void PickingPass::InitializeShaderPrograms() m_PickingProgram->Link(); } -void PickingPass::Draw(RenderQueueCollection& rq) +void PickingPass::Draw(RenderFrame& rf) { m_PickingColorsToEntity.clear(); PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); @@ -57,34 +57,38 @@ void PickingPass::Draw(RenderQueueCollection& rq) std::map entityColors; - for (auto &job : rq.Forward) { - auto modelJob = std::dynamic_pointer_cast(job); + for(auto scene : rf.RenderScenes) + { + for (auto &job : scene->Forward) { + auto modelJob = std::dynamic_pointer_cast(job); - if (modelJob) { - int pickColor[2] = { r, g }; - auto color = entityColors.find(modelJob->Entity); - if (color != entityColors.end()) { - pickColor[0] = color->second[0]; - pickColor[1] = color->second[1]; - } else { - entityColors[modelJob->Entity] = glm::vec2(pickColor[0], pickColor[1]); - if (r + 10 > 255) { - r = 0; - g += 1; + if (modelJob) { + int pickColor[2] = { r, g }; + auto color = entityColors.find(modelJob->Entity); + if (color != entityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; } else { - r += 1; + entityColors[modelJob->Entity] = glm::vec2(pickColor[0], pickColor[1]); + if (r + 10 > 255) { + r = 0; + g += 1; + } else { + r += 1; + } } + m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity; + + glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "Matrix"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex); } - m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity; - - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "Matrix"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); - - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex); } } + m_PickingBuffer.Unbind(); GLERROR("PickingPass Error"); @@ -92,15 +96,15 @@ void PickingPass::Draw(RenderQueueCollection& rq) int fbWidth; int fbHeight; glfwGetFramebufferSize(m_Renderer->Window(), &fbWidth, &fbHeight); - /* Events::Picking pickEvent = Events::Picking( + Events::Picking pickEvent = Events::Picking( &m_PickingBuffer, &m_DepthBuffer, m_Renderer->Camera()->ProjectionMatrix(), m_Renderer->Camera()->ViewMatrix(), Rectangle(fbWidth, fbHeight), - &m_PickingColorsToEntity);*/ + &m_PickingColorsToEntity); - //m_EventBroker->Publish(pickEvent); + m_EventBroker->Publish(pickEvent); delete state; } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index c08d4971..33c03e8f 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -1,29 +1,56 @@ #include "Rendering/RenderSystem.h" #include "Rendering/DebugCameraInputController.h" -RenderSystem::RenderSystem(EventBroker* eventBrokerer, RenderQueueCollection* renderQueues) +RenderSystem::RenderSystem(EventBroker* eventBrokerer, RenderFrame* renderFrame) :ImpureSystem(eventBrokerer) { - m_RenderQueues = renderQueues; + m_RenderFrame = renderFrame; Initialize(); EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); - + m_DefaultCamera = new Camera(1.77f /* should be based on width and height */, glm::radians(45.f), 0.01f, 5000.f); + m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10)); + if (m_Camera == nullptr) { + m_Camera = m_DefaultCamera; + } } bool RenderSystem::OnSetCamera(const Events::SetCamera &event) { - m_CurrentCamera = event.Entity; + auto cameras = m_World->GetComponents("Camera"); + + if (cameras != nullptr) { + for (auto it = cameras->begin(); it != cameras->end(); it++) { + if ((std::string)(*it)["Name"] == event.Name) { + SwitchCamera((*it).EntityID); + } + } + } + return true; } void RenderSystem::SwitchCamera(EntityID entity) { - m_CurrentCamera = entity; - m_SwitchCamera = false; - LOG_INFO("Switched to camera %i", m_CurrentCamera); + if(m_World->HasComponent(entity, "Camera")) { + if (m_World->HasComponent(m_CurrentCamera, "Model")) { + m_World->GetComponent(m_CurrentCamera, "Model")["Visible"] = true; + } + + if (m_World->HasComponent(entity, "Model")) { + m_World->GetComponent(entity, "Model")["Visible"] = false; + } + + m_CurrentCamera = entity; + m_SwitchCamera = false; + + LOG_INFO("Switched to %s", m_World->GetComponent(m_CurrentCamera, "Camera")["Name"]); + } else { + LOG_ERROR("Entity %i does not have a CameraComponent", entity); + m_SwitchCamera = false; + } } void RenderSystem::Initialize() @@ -31,24 +58,21 @@ void RenderSystem::Initialize() } -void RenderSystem::UpdateViewMatrix(ComponentWrapper& cameraTransform) -{ - glm::quat orientation = glm::quat((glm::vec3)cameraTransform["Orientation"]); - glm::vec3 position = cameraTransform["Position"]; - - m_ViewMatrix = glm::toMat4(glm::inverse(orientation)) * glm::translate(-position); -} - void RenderSystem::UpdateProjectionMatrix(ComponentWrapper& cameraComponent) { - double fov = (double&)cameraComponent["FOV"]; - double aspectRatio = (double&)cameraComponent["AspectRatio"]; - double nearClip = (double&)cameraComponent["NearClip"]; - double farClip = (double&)cameraComponent["FarClip"]; + double fov = cameraComponent["FOV"]; + double aspectRatio = cameraComponent["AspectRatio"]; + double nearClip = cameraComponent["NearClip"]; + double farClip = cameraComponent["FarClip"]; double fovY = atan(tan(glm::radians(fov)/2.0) * aspectRatio) * 2.0; m_ProjectionMatrix = glm::perspective(fovY, aspectRatio, nearClip, farClip); - + + m_Camera->SetFOV(fovY); + m_Camera->SetAspectRatio(aspectRatio); + m_Camera->SetNearClip(nearClip); + m_Camera->SetFarClip(farClip); + m_Camera->UpdateProjectionMatrix(); } glm::vec3 RenderSystem::AbsolutePosition(World* world, EntityID entity) @@ -95,20 +119,19 @@ glm::vec3 RenderSystem::AbsoluteScale(World* world, EntityID entity) return scale; } - -glm::mat4 RenderSystem::ModelMatrix(World* world, EntityID entity) +glm::mat4 RenderSystem::ModelMatrix(EntityID entity) { - glm::vec3 position = AbsolutePosition(world, entity); - glm::quat orientation = AbsoluteOrientation(world, entity); - glm::vec3 scale = AbsoluteScale(world, entity); + glm::vec3 position = AbsolutePosition(m_World, entity); + glm::quat orientation = AbsoluteOrientation(m_World, entity); + glm::vec3 scale = AbsoluteScale(m_World, entity); glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale); return modelMatrix; } -void RenderSystem::FillModels(World* world, RenderQueue* renderQueue) +void RenderSystem::FillModels(RenderQueue* renderQueue) { - auto models = world->GetComponents("Model"); + auto models = m_World->GetComponents("Model"); if (models == nullptr) { return; } @@ -140,7 +163,7 @@ void RenderSystem::FillModels(World* world, RenderQueue* renderQueue) job.Model = model; job.StartIndex = texGroup.StartIndex; job.EndIndex = texGroup.EndIndex; - job.Matrix = m_ProjectionMatrix * m_ViewMatrix * (model->m_Matrix * ModelMatrix(world, modelC.EntityID)); + job.Matrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix() * (model->m_Matrix * ModelMatrix(modelC.EntityID)); job.Color = color; job.Entity = modelC.EntityID; @@ -156,7 +179,7 @@ void RenderSystem::FillModels(World* world, RenderQueue* renderQueue) job.Model = model; job.StartIndex = texGroup.StartIndex; job.EndIndex = texGroup.EndIndex; - job.Matrix = m_ProjectionMatrix * m_ViewMatrix * (model->m_Matrix * ModelMatrix(world, modelC.EntityID)); + job.Matrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix() * (model->m_Matrix * ModelMatrix(modelC.EntityID)); job.Color = color; job.Entity = modelC.EntityID; @@ -176,9 +199,10 @@ bool RenderSystem::OnInputCommand(const Events::InputCommand& e) } } - void RenderSystem::Update(World* world, double dt) { + m_World = world; + m_EventBroker->Process(); static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); @@ -201,34 +225,42 @@ void RenderSystem::Update(World* world, double dt) ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); firstPersonInputController.SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); - firstPersonInputController.SetPosition((glm::vec3)cameraTransform["Position"]); + firstPersonInputController.SetPosition(cameraTransform["Position"]); } } if(world->HasComponent(m_CurrentCamera, "Camera") && world->HasComponent(m_CurrentCamera, "Transform")) { - ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); - firstPersonInputController.Update(dt); - (glm::vec3&)cameraTransform["Orientation"] = glm::eulerAngles(firstPersonInputController.Orientation()); - (glm::vec3&)cameraTransform["Position"] = firstPersonInputController.Position(); + if(world->GetParent(m_CurrentCamera) == 1) { // world is entity 1, is this ok? + firstPersonInputController.Update(dt); + (glm::vec3&)cameraTransform["Orientation"] = glm::eulerAngles(firstPersonInputController.Orientation()); + (glm::vec3&)cameraTransform["Position"] = firstPersonInputController.Position(); + } + glm::vec3 position = AbsolutePosition(world, m_CurrentCamera); + glm::quat orientation = AbsoluteOrientation(world, m_CurrentCamera); + m_Camera->SetPosition(position); + m_Camera->SetOrientation(orientation); + UpdateProjectionMatrix(cameraComponent); - UpdateViewMatrix(cameraTransform); + m_Camera->UpdateViewMatrix(); } else { - m_ProjectionMatrix = glm::perspective(glm::radians(40.f), 1.77f, 0.05f, 5000.f); - m_ViewMatrix = glm::mat4(); + m_Camera = m_DefaultCamera; auto cameras = world->GetComponents("Camera"); - if (cameras != nullptr) { ComponentWrapper& cameraC = *cameras->begin(); - m_CurrentCamera = cameraC.EntityID; + SwitchCamera(cameraC.EntityID); + world->GetComponent(m_CurrentCamera, "Model")["Visible"] = false; } } - m_RenderQueues->Clear(); - FillModels(world, &m_RenderQueues->Forward); + m_RenderFrame->Clear(); + RenderScene* rs = new RenderScene(); + rs->Camera = m_Camera; + FillModels(&rs->Forward); + m_RenderFrame->Add(*rs); } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 0ef1e4bf..972a6df8 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -90,14 +90,14 @@ void Renderer::Update(double dt) m_ImGuiRenderPass->Update(dt); } -void Renderer::Draw(RenderQueueCollection& rq) +void Renderer::Draw(RenderFrame& rf) { - m_PickingPass->Draw(rq); - //DrawScreenQuad(m_PickingPass->PickingTexture()); + m_Camera = (*rf.begin())->Camera; + m_PickingPass->Draw(rf); glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f); - m_DrawScenePass->Draw(rq); + m_DrawScenePass->Draw(rf); GLERROR("Renderer::Draw m_DrawScenePass->Draw"); m_ImGuiRenderPass->Draw(); glfwSwapBuffers(m_Window); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 4ab6f410..c104a3ad 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -47,14 +47,14 @@ Game::Game(int argc, char* argv[]) ResourceManager::Load(mapToLoad)->PopulateWorld(m_World); } - m_RenderQueues = new RenderQueueCollection(); + m_RenderFrame = new RenderFrame(); // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(m_Renderer); - m_SystemPipeline->AddSystem(m_RenderQueues); + m_SystemPipeline->AddSystem(m_RenderFrame); m_LastTime = glfwGetTime(); @@ -91,7 +91,7 @@ void Game::Tick() m_Renderer->Update(dt); GLERROR("Game::Tick m_RenderQueueFactory->Update"); - m_Renderer->Draw(*m_RenderQueues); + m_Renderer->Draw(*m_RenderFrame); GLERROR("Game::Tick m_Renderer->Draw"); m_EventBroker->Swap(); m_EventBroker->Clear(); From b8db80bc409be60564d28133858a43a31662bd0f Mon Sep 17 00:00:00 2001 From: viktorljung Date: Mon, 11 Jan 2016 10:47:39 +0100 Subject: [PATCH 11/50] Added camera to PickingPass and fixed memory leak --- include/Engine/Rendering/PickingPass.h | 1 + src/Engine/Rendering/PickingPass.cpp | 8 ++++++-- src/Engine/Rendering/RenderSystem.cpp | 1 + src/Engine/Rendering/Renderer.cpp | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index e4ff9e27..eaca4b04 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -37,6 +37,7 @@ private: const IRenderer* m_Renderer; ShaderProgram* m_PickingProgram; + Camera* m_Camera; std::unordered_map m_PickingColorsToEntity; diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index f7f0558c..fbbbd7c0 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -59,6 +59,8 @@ void PickingPass::Draw(RenderFrame& rf) for(auto scene : rf.RenderScenes) { + m_Camera = scene->Camera; + for (auto &job : scene->Forward) { auto modelJob = std::dynamic_pointer_cast(job); @@ -99,8 +101,8 @@ void PickingPass::Draw(RenderFrame& rf) Events::Picking pickEvent = Events::Picking( &m_PickingBuffer, &m_DepthBuffer, - m_Renderer->Camera()->ProjectionMatrix(), - m_Renderer->Camera()->ViewMatrix(), + m_Camera->ProjectionMatrix(), + m_Camera->ViewMatrix(), Rectangle(fbWidth, fbHeight), &m_PickingColorsToEntity); @@ -109,6 +111,8 @@ void PickingPass::Draw(RenderFrame& rf) delete state; } + + void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const { //TODO: Renderer: Make this in a sparate class diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 33c03e8f..f385037b 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -263,4 +263,5 @@ void RenderSystem::Update(World* world, double dt) rs->Camera = m_Camera; FillModels(&rs->Forward); m_RenderFrame->Add(*rs); + delete rs; } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 972a6df8..9a7bfd07 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -92,7 +92,7 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderFrame& rf) { - m_Camera = (*rf.begin())->Camera; + m_Camera = (*rf.begin())->Camera; // Fix this with some better solution m_PickingPass->Draw(rf); glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f); From f0ad28bac4dbe03a4b13f42f549c77b0e20cc085 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 6 Jan 2016 11:39:32 +0100 Subject: [PATCH 12/50] Removed some comments. Basically did nothing --- include/Engine/Network/Network.h | 1 + src/Engine/Input/InputProxy.cpp | 4 ++-- src/Engine/Network/Client.cpp | 14 +++++--------- src/Engine/Network/Server.cpp | 8 ++++++-- src/Game/Game.cpp | 7 +------ 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 0f7baefe..c5107b2b 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -14,6 +14,7 @@ public: virtual ~Network() { }; virtual void Start(World* m_world, EventBroker *eventBroker) = 0; virtual void Update() = 0; + virtual void Close() = 0; }; #endif \ No newline at end of file diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp index c3e4d669..ad589df3 100644 --- a/src/Engine/Input/InputProxy.cpp +++ b/src/Engine/Input/InputProxy.cpp @@ -62,7 +62,7 @@ void InputProxy::Process() e.Command = command; e.Value = currentValue; m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + //LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); m_LastCommandValues[command] = currentValue; } } @@ -78,7 +78,7 @@ void InputProxy::Process() } //e.Value = std::max(-1.f, std::min(e.Value, 1.f)); m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + //LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); } m_CommandQueue.clear(); } diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 5c7e9c8f..a417c4e5 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -17,7 +17,7 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) Client::~Client() { - + m_EventBroker->Unsubscribe(m_EInputCommand); } void Client::Start(World* world, EventBroker* eventBroker) @@ -27,14 +27,10 @@ void Client::Start(World* world, EventBroker* eventBroker) m_World = world; // Subscribe to events - m_EInputCommand = decltype(m_EInputCommand)(std::bind(&Client::OnInputCommand, this, std::placeholders::_1)); - m_EventBroker->Subscribe(m_EInputCommand); + //m_EInputCommand = decltype(m_EInputCommand)(std::bind(&Client::OnInputCommand, this, std::placeholders::_1)); + //m_EventBroker->Subscribe(m_EInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand); - - //while (m_PlayerName.size() > 7) { - // LOG_INFO("Please enter your name (No longer than 7 characters):"); - // std::cin >> m_PlayerName; - //} m_Socket.connect(m_ReceiverEndpoint); LOG_INFO("I am client. BIP BOP"); } @@ -73,7 +69,7 @@ void Client::readFromServer() void Client::sendSnapshotToServer() { - // Reset previouse key state in snapshot. + // Reset previous key state in snapshot. m_NextSnapshot.InputForward = ""; m_NextSnapshot.InputRight = ""; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 261583cc..c53dce8f 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -4,7 +4,9 @@ Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::a { } Server::~Server() -{ } +{ + +} void Server::Start(World* world, EventBroker* eventBroker) @@ -25,6 +27,8 @@ void Server::Update() void Server::Close() { m_ThreadIsRunning = false; + m_Socket.close(); + } void Server::readFromClients() @@ -271,7 +275,7 @@ void Server::parseConnect(Packet& packet) m_StopTimes[i] = std::clock(); - LOG_INFO("Player \"%s\" connected on IP: %s", m_PlayerDefinitions[i].Name, m_PlayerDefinitions[i].Endpoint.address().to_string()); + LOG_INFO("Player \"%s\" connected on IP: %s", m_PlayerDefinitions[i].Name.c_str(), m_PlayerDefinitions[i].Endpoint.address().to_string().c_str()); Packet packet(MessageType::Connect, m_SendPacketID); packet.WritePrimitive(i); // Player ID diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index c66d2641..bf08d340 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -144,10 +144,5 @@ void Game::networkFunction() m_ClientOrServer = new Server(); } m_ClientOrServer->Start(m_World, m_EventBroker); - // I don't think we are reaching this part of the code right now. - // ~Game() is not called if the game is exited by closing console windows - // When server or client is done set it to false. - //m_IsClientOrServer = false; - // Destroy it - //delete m_ClientOrServer; + } \ No newline at end of file From 6c13916eec56406e8267c832bac156022e4a677e Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 6 Jan 2016 13:49:54 +0100 Subject: [PATCH 13/50] Removed unnecessary code. --- src/Engine/Network/Client.cpp | 9 ++++----- src/Engine/Network/Server.cpp | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index a417c4e5..f01509b4 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -42,11 +42,10 @@ void Client::Update() void Client::Close() { - if (m_WasStarted) { - disconnect(); - m_ThreadIsRunning = false; - m_EventBroker->Unsubscribe(m_EInputCommand); - } + disconnect(); + m_ThreadIsRunning = false; + m_Socket.close(); + m_EventBroker->Unsubscribe(m_EInputCommand); } void Client::readFromServer() diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index c53dce8f..bedbf954 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -28,7 +28,6 @@ void Server::Close() { m_ThreadIsRunning = false; m_Socket.close(); - } void Server::readFromClients() From b37ffc74494125b907cd2705da2428c6840aa95c Mon Sep 17 00:00:00 2001 From: Jocke Date: Mon, 11 Jan 2016 14:34:04 +0100 Subject: [PATCH 14/50] WIP Model component not working. --- include/Engine/Core/World.h | 2 + include/Engine/Network/Packet.h | 6 +- include/Engine/Network/Server.h | 1 + src/Engine/Collision/Collision.cpp | 36 ++++---- src/Engine/Core/World.cpp | 8 +- src/Engine/Network/Client.cpp | 68 +++++++++------ src/Engine/Network/Packet.cpp | 23 ++++-- src/Engine/Network/Server.cpp | 127 +++++++++++++++++++++++++---- 8 files changed, 204 insertions(+), 67 deletions(-) diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index 0a121728..c066933a 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -22,6 +22,8 @@ public: void RegisterComponent(ComponentInfo& ci); // Attach a component to an entity and fill it with default values ComponentWrapper AttachComponent(EntityID entity, std::string componentType); + // Check if world has an entity + bool HasEntity(EntityID entity); // Check if an entity has a component bool HasComponent(EntityID entity, std::string componentType) const; // Get a component of an entity diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index daf39962..76cf2cba 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -14,8 +14,9 @@ public: Packet(MessageType type, unsigned int& packetID); // Used to create packet from already existing data buffer. Packet(char* data, const int sizeOfPacket); - ~Packet(); + void Init(MessageType type, unsigned int& packetID); + // Add primitive types like int, float, char... template void WritePrimitive(T val) @@ -23,6 +24,7 @@ public: // Check if we are trying to add more than the package can fit. if (m_MaxPacketSize < m_Offset + sizeof(T)) { LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for!"); + return; } memcpy(m_Data + m_Offset, &val, sizeof(T)); m_Offset += sizeof(T); @@ -50,6 +52,8 @@ public: int Size() { return m_Offset; }; char* Data() { return m_Data; }; + unsigned int DataReadSize() { return m_ReturnDataOffset; } + unsigned int MaxSize() { return m_MaxPacketSize; } private: char* m_Data; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 5c1ac1fb..af454bc1 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -67,6 +67,7 @@ private: void moveMessageHead(char*& data, size_t& length, size_t stepSize); void broadcast(std::string message); void broadcast(Packet& packet); + //void parseShitTest(Packet& packet); // Remove this when network is working void sendSnapshot(); void sendPing(); void checkForTimeOuts(); diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index c4af6258..a767ee95 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -245,23 +245,29 @@ bool attachAABBComponentFromModel(World* world, EntityID id) bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox) { - ComponentWrapper& cTrans = world->GetComponent(AABBComponent.EntityID, "Transform"); - ComponentWrapper model = world->GetComponent(AABBComponent.EntityID, "Model"); - Model* modelRes = ResourceManager::Load(model["Resource"]); - outBox.CreateFromCenter(AABBComponent["BoxCenter"], AABBComponent["BoxSize"]); - glm::vec3 mini = outBox.MinCorner(); - glm::vec3 maxi = outBox.MaxCorner(); + if (world->HasComponent(AABBComponent.EntityID, "Transform") && world->HasComponent(AABBComponent.EntityID, "Model")) + { + ComponentWrapper& cTrans = world->GetComponent(AABBComponent.EntityID, "Transform"); + ComponentWrapper model = world->GetComponent(AABBComponent.EntityID, "Model"); + if(AABBComponent.EntityID == 3); + std::string checkPath = model["Resource"]; + Model* modelRes = ResourceManager::Load(model["Resource"]); + outBox.CreateFromCenter(AABBComponent["BoxCenter"], AABBComponent["BoxSize"]); + glm::vec3 mini = outBox.MinCorner(); + glm::vec3 maxi = outBox.MaxCorner(); - if (modelRes == nullptr) { - return false; + if (modelRes == nullptr) { + return false; + } + glm::mat4 modelMatrix = modelRes->m_Matrix * + glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) * + glm::scale((glm::vec3)cTrans["Scale"]); + + outBox = AABB(modelMatrix * glm::vec4(mini.x, mini.y, mini.z, 1), + modelMatrix * glm::vec4(maxi.x, maxi.y, maxi.z, 1)); + return true; } - glm::mat4 modelMatrix = modelRes->m_Matrix * - glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) * - glm::scale((glm::vec3)cTrans["Scale"]); - - outBox = AABB(modelMatrix * glm::vec4(mini.x, mini.y, mini.z, 1), - modelMatrix * glm::vec4(maxi.x, maxi.y, maxi.z, 1)); - return true; + return false; } bool GetEntityBox(World* world, EntityID entity, AABB& outBox, bool forceBoxFromModel) diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index c94cb8b3..faddeb83 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -80,7 +80,13 @@ ComponentWrapper World::AttachComponent(EntityID entity, std::string componentTy return c; } -bool World::HasComponent(EntityID entity, std::string componentType) const +bool World::HasEntity(EntityID entity) +{ + return m_EntityParents.find(entity) != m_EntityParents.end(); +} + + +bool World::HasComponent(EntityID entity, std::string componentType) { ComponentPool* pool = m_ComponentPools.at(componentType); return pool->KnowsEntity(entity); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index f01509b4..08f68f98 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -50,7 +50,7 @@ void Client::Close() void Client::readFromServer() { - if (m_Socket.available()) { + while (m_Socket.available()) { bytesRead = receive(readBuf, INPUTSIZE); if (bytesRead > 0) { Packet packet(readBuf, bytesRead); @@ -60,7 +60,7 @@ void Client::readFromServer() std::clock_t currentTime = std::clock(); if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { if (isConnected()) { - sendSnapshotToServer(); + //sendSnapshotToServer(); } previousSnapshotMessage = currentTime; } @@ -120,6 +120,8 @@ void Client::parseMessageType(Packet& packet) // Read packet ID m_PreviousPacketID = m_PacketID; // Set previous packet id m_PacketID = packet.ReadPrimitive(); //Read new packet id + if (m_PacketID <= m_PreviousPacketID) + return; //IdentifyPacketLoss(); switch (static_cast(messageType)) { @@ -181,33 +183,45 @@ void Client::parseEventMessage(Packet& packet) void Client::parseSnapshot(Packet& packet) { - std::string tempName; - for (size_t i = 0; i < MAXCONNECTIONS; i++) { - // We're checking for empty name for now. This might not be the best way, - // but it is to avoid sending redundant data. - tempName = packet.ReadString(); - - - // Apply the position data read to the player entity - // New player connected on the server side - if (m_PlayerDefinitions[i].Name == "" && tempName != "") { - m_PlayerDefinitions[i].Name = tempName; - m_PlayerDefinitions[i].EntityID = createPlayer(); - } else if (m_PlayerDefinitions[i].Name != "" && tempName == "") { - // Someone disconnected - // TODO: Insert code here - break; - } else if (m_PlayerDefinitions[i].Name == "" && tempName == "") { - // Not a connected player - break; - } - if (m_PlayerDefinitions[i].EntityID != -1) { - - // Move player to server position - int dataSize = m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform").Info.Meta.Stride; - memcpy(m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform").Data, packet.ReadData(dataSize), dataSize); + std::string componentType = packet.ReadString(); + //LOG_INFO("A snapshot was parsed. first component type is: %s", componentType.c_str()); + int stride = packet.ReadPrimitive(); + int nrOfComponents = (packet.Size() - packet.DataReadSize()) / (stride + sizeof(EntityID)); + if (componentType == "Model") + return; + for (size_t i = 0; i < nrOfComponents; i++) { + EntityID entityID = packet.ReadPrimitive(); + //ComponentWrapper model = m_World->GetComponent(entityID, "Model"); + //std::string checkPath = model["Resource"]; + // Check if entity exists + if (m_World->HasEntity(entityID)) { + // check if component exists + if (m_World->HasComponent(entityID, componentType)) { + //Copy data to component + memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); + } else { + // If component doesen't exist + // Create component + m_World->AttachComponent(entityID, componentType); + // Copy data to newly created component + memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); + } + } else { + // If entity dosen't exist + EntityID newEntityID = m_World->CreateEntity(); + // Check if EntityIDs are out of sync + if (newEntityID != entityID) { + LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the same as the one sent by server \ + EntityIDs are out of sync"); + } + m_World->AttachComponent(newEntityID, componentType); + // Copy data to newly created component + memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); } + //ComponentWrapper model2 = m_World->GetComponent(entityID, "Model"); + //std::string checkPath2 = model2["Resource"]; } + } int Client::receive(char* data, size_t length) diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index 52b15065..86a91f5d 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -3,13 +3,7 @@ Packet::Packet(MessageType type, unsigned int& packetID) { m_Data = new char[m_MaxPacketSize]; - // Create message header - // Add message type - int messageType = static_cast(type); - Packet::WritePrimitive(messageType); - packetID = packetID % 1000; // Packet id modulos - Packet::WritePrimitive(packetID); - packetID++; + Init(type, packetID); } // Create message @@ -28,12 +22,26 @@ Packet::~Packet() delete[] m_Data; } +void Packet::Init(MessageType type, unsigned int & packetID) +{ + m_ReturnDataOffset = 0; + m_Offset = 0; + // Create message header + // Add message type + int messageType = static_cast(type); + Packet::WritePrimitive(messageType); + packetID = packetID % 1000; // Packet id modulos + Packet::WritePrimitive(packetID); + packetID++; +} + void Packet::WriteString(std::string str) { // Message, add one extra byte for null terminator int sizeOfString = str.size() + 1; if (m_Offset + sizeOfString > m_MaxPacketSize) { LOG_WARNING("Package::WriteString(): Data size in packet exceeded maximum package size.\n"); + return; } memcpy(m_Data + m_Offset, str.data(), sizeOfString * sizeof(char)); m_Offset += sizeOfString * sizeof(char); @@ -43,6 +51,7 @@ void Packet::WriteData(char * data, int sizeOfData) { if (m_Offset + sizeOfData > m_MaxPacketSize) { LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size.\n"); + return; } memcpy(m_Data + m_Offset, data, sizeOfData); m_Offset += sizeOfData; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index bedbf954..791f5a42 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -4,7 +4,7 @@ Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::a { } Server::~Server() -{ +{ } @@ -36,7 +36,7 @@ void Server::readFromClients() // program crashed if it executed m_Socket.available() // when closing the program. - if (m_Socket.available()) { + while (m_Socket.available()) { try { bytesRead = receive(readBuffer, INPUTSIZE); Packet packet(readBuffer, bytesRead); @@ -61,7 +61,7 @@ void Server::readFromClients() // Time out logic if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { - checkForTimeOuts(); + //checkForTimeOuts(); timOutTimer = currentTime; } } @@ -152,32 +152,127 @@ void Server::broadcast(Packet& packet) } } } +// +//void Server::parseShitTest(Packet& packet) +//{ +// packet.ReadPrimitive(); // MessageType +// packet.ReadPrimitive(); // Packet ID +// +// std::string componentType = packet.ReadString(); +// //LOG_INFO("A snapshot was parsed. first component type is: %s", componentType.c_str()); +// int stride = packet.ReadPrimitive(); +// int nrOfComponents = (packet.Size() - packet.DataReadSize()) / (stride + sizeof(EntityID)); +// //if (componentType == "Model") +// // return; +// for (size_t i = 0; i < nrOfComponents; i++) { +// EntityID entityID = packet.ReadPrimitive(); +// ComponentWrapper model = m_World->GetComponent(entityID, "Model"); +// std::string checkPath = model["Resource"]; +// // Check if entity exists +// if (m_World->HasEntity(entityID)) { +// // check if component exists +// if (m_World->HasComponent(entityID, componentType)) { +// //Copy data to component +// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); +// } else { +// // If component doesen't exist +// // Create component +// m_World->AttachComponent(entityID, componentType); +// // Copy data to newly created component +// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); +// } +// } else { +// // If entity dosen't exist +// EntityID newEntityID = m_World->CreateEntity(); +// // Check if EntityIDs are out of sync +// if (newEntityID != entityID) { +// LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the same as the one sent by server \ +// EntityIDs are out of sync"); +// } +// m_World->AttachComponent(newEntityID, componentType); +// // Copy data to newly created component +// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); +// } +// ComponentWrapper model2 = m_World->GetComponent(entityID, "Model"); +// std::string checkPath2 = model2["Resource"]; +// } +//} void Server::sendSnapshot() { - Packet packet(MessageType::Snapshot, m_SendPacketID); - for (size_t i = 0; i < MAXCONNECTIONS; i++) { - - // Send an empty name if there is no player connected on this position. - packet.WriteString(m_PlayerDefinitions[i].Name); - - if (m_PlayerDefinitions[i].EntityID == -1) { - continue; + // Should time this + std::unordered_map worldComponentPools = m_World->GetComponentPools(); + for (auto it : worldComponentPools) { + Packet packet(MessageType::Snapshot, m_SendPacketID); + std::string componentType = it.first; + //if (componentType != "Model") + // continue; + ComponentPool* componentPool = it.second; + ComponentInfo componentInfo = componentPool->ComponentInfo(); + packet.WriteString(componentInfo.Name); + packet.WritePrimitive(componentInfo.Meta.Stride); + for (auto componentWrapper : *componentPool) { + if (packet.Size() + componentInfo.Meta.Stride >= packet.MaxSize()) { + broadcast(packet); + //parseShitTest(packet); + // Packet destructor is called (which is what we want). + packet.Init(MessageType::Snapshot, m_SendPacketID); + // Add Component header + packet.WriteString(componentInfo.Name); + packet.WritePrimitive(componentInfo.Meta.Stride); + } + // Component data + packet.WritePrimitive(componentWrapper.EntityID); + packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); } - // Pack transfrom component into data packet - auto transform = m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform"); - packet.WriteData(transform.Data, transform.Info.Meta.Stride); + broadcast(packet); } - broadcast(packet); } +//void Server::sendSnapshot() +//{ +// // Should time this +// std::unordered_map worldComponentPools = m_World->GetComponentPools(); +// for (auto it : worldComponentPools) { +// Packet packet(MessageType::Snapshot, m_SendPacketID); +// std::string componentType = it.first; +// ComponentPool* componentPool = it.second; +// ComponentInfo componentInfo = componentPool->ComponentInfo(); +// if (componentInfo.Name != "Transform") +// continue; +// packet.WriteString(componentInfo.Name); +// packet.WritePrimitive(componentInfo.Meta.Stride); +// auto componentWrapper = *componentPool->begin(); +// packet.WritePrimitive(componentWrapper.EntityID); +// packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); +// +// for (auto componentWrapper : *componentPool) { +// //// When packet is full send it +// //if (packet.Size() + componentInfo.Meta.Stride >= packet.MaxSize()) { +// // broadcast(packet); +// // // Packet destructor is called (which is what we want). +// // packet.Init(MessageType::Snapshot, m_SendPacketID); +// // // Add Component header +// // packet.WriteString(componentInfo.Name); +// // packet.WritePrimitive(componentInfo.Meta.Stride); +// +// //} +// //// Component data +// //packet.WritePrimitive(componentWrapper.EntityID); +// //packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); +// broadcast(packet); +// } +// broadcast(packet); +// } +//} + void Server::sendPing() { // Prints connected players ping for (size_t i = 0; i < MAXCONNECTIONS; i++) { if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) { int ping = 1000 * (m_StopTimes[i] - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); - LOG_INFO("%i: Player %i's ping: %i", m_PacketID, i, ping); + LOG_INFO("Last packetID received %i: Player %i's ping: %i", m_PacketID, i, ping); } } From 3feee7fd35ce5363595cbd6f713d39b0739fafad Mon Sep 17 00:00:00 2001 From: viktorljung Date: Mon, 11 Jan 2016 17:01:17 +0100 Subject: [PATCH 15/50] Changed the structure of how RenderJobs are handled --- include/Engine/Rendering/ModelJob.h | 57 +++++++++++++ include/Engine/Rendering/RenderJob.h | 32 +++++++ include/Engine/Rendering/RenderQueue.h | 107 +++--------------------- include/Engine/Rendering/RenderSystem.h | 3 +- src/Engine/Rendering/DrawScenePass.cpp | 3 +- src/Engine/Rendering/PickingPass.cpp | 2 +- src/Engine/Rendering/RenderSystem.cpp | 58 ++++--------- 7 files changed, 121 insertions(+), 141 deletions(-) create mode 100644 include/Engine/Rendering/ModelJob.h create mode 100644 include/Engine/Rendering/RenderJob.h diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h new file mode 100644 index 00000000..fcb68244 --- /dev/null +++ b/include/Engine/Rendering/ModelJob.h @@ -0,0 +1,57 @@ +#ifndef ModelJob_h__ +#define ModelJob_h__ + +#include + +#include "../Common.h" +#include "../GLM.h" +#include "../Core/ComponentWrapper.h" +#include "Texture.h" +#include "Model.h" + +#include "RenderJob.h" +#include "../Core/ResourceManager.h" +#include "Camera.h" + +struct ModelJob : RenderJob +{ + ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::Model::MaterialGroup texGroup, ComponentWrapper modelComponent) + : RenderJob() + { + Model = model; + TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0; + DiffuseTexture = texGroup.Texture.get(); + NormalTexture = texGroup.NormalMap.get(); + SpecularTexture = texGroup.SpecularMap.get(); + StartIndex = texGroup.StartIndex; + EndIndex = texGroup.EndIndex; + Matrix = matrix; + Color = modelComponent["Color"]; + Entity = modelComponent.EntityID; + }; + + + unsigned int TextureID; + unsigned int ShaderID; + + EntityID Entity; + glm::mat4 Matrix; + const Texture* DiffuseTexture; + const Texture* NormalTexture; + const Texture* SpecularTexture; + float Shininess = 0.f; + glm::vec4 Color; + const ::Model* Model = nullptr; + unsigned int StartIndex = 0; + unsigned int EndIndex = 0; + + + void CalculateHash() override + { + Hash = TextureID; + } + + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderJob.h b/include/Engine/Rendering/RenderJob.h new file mode 100644 index 00000000..4afe0386 --- /dev/null +++ b/include/Engine/Rendering/RenderJob.h @@ -0,0 +1,32 @@ +#ifndef RenderJob_h__ +#define RenderJob_h__ + +#include + +#include "../Common.h" +#include "../GLM.h" +#include "../Core/ComponentWrapper.h" +#include "RenderQueue.h" + + +struct RenderJob +{ + friend class RenderQueue; + +public: + + float Depth; + +protected: + uint64_t Hash; + + virtual void CalculateHash() = 0; + + bool operator<(const RenderJob& rhs) + { + return this->Hash < rhs.Hash; + } + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 719e5cc7..01e9024a 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -9,58 +9,16 @@ #include "../Core/Util/Rectangle.h" #include "../Core/Entity.h" #include "Camera.h" +#include "RenderJob.h" +#include "ModelJob.h" class Model; class Skeleton; class Texture; -class RenderQueue; //TODO: Render: Remove obsolete RenderJobs and fix standard values on variables. +/* -struct RenderJob -{ - friend class RenderQueue; - - float Depth; - -protected: - uint64_t Hash; - - virtual void CalculateHash() = 0; - - bool operator<(const RenderJob& rhs) - { - return this->Hash < rhs.Hash; - } -}; - -struct ModelJob : RenderJob -{ - unsigned int ShaderID = 0; - unsigned int TextureID = 0; - - EntityID Entity; - glm::mat4 Matrix; - const Texture* DiffuseTexture; - const Texture* NormalTexture; - const Texture* SpecularTexture; - float Shininess = 0.f; - glm::vec4 Color; - const Model* Model = nullptr; - unsigned int StartIndex = 0; - unsigned int EndIndex = 0; - - // Animation - Skeleton* Skeleton = nullptr; - bool NoRootMotion = true; - std::string AnimationName; - double AnimationTime = 0; - - void CalculateHash() override - { - Hash = TextureID; - } -}; struct TransparentModelJob : RenderJob { @@ -123,66 +81,23 @@ struct PointLightJob : RenderJob Hash = 0; } }; - -class RenderQueue -{ -public: - template - void Add(T &job) - { - job.CalculateHash(); - Jobs.push_back(std::shared_ptr(new T(job))); - m_Size++; - } - - void Sort() - { - Jobs.sort(); - } - - void Clear() - { - Jobs.clear(); - m_Size = 0; - } - - int Size() const { return m_Size; } - std::list>::const_iterator begin() - { - return Jobs.begin(); - } - - std::list>::const_iterator end() - { - return Jobs.end(); - } - - std::list> Jobs; - -private: - int m_Size = 0; -}; +*/ struct RenderScene { - RenderQueue Forward; - RenderQueue Lights; - Camera* Camera; + ::Camera* Camera; + std::list> ForwardJobs; + std::list> LightJobs; + void Clear() { - Forward.Clear(); - Lights.Clear(); - } - - void Sort() - { - Forward.Sort(); - Lights.Sort(); + ForwardJobs.clear(); + LightJobs.clear(); } }; -class RenderFrame +struct RenderFrame { public: diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 34a9c5f9..e322d51e 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -11,6 +11,7 @@ #include "../Core/EKeyDown.h" #include "../Input/EInputCommand.h" #include "Camera.h" +#include "ModelJob.h" class RenderSystem : public ImpureSystem @@ -48,7 +49,7 @@ private: glm::mat4 m_ProjectionMatrix; glm::mat4 ModelMatrix(EntityID entity); - void FillModels(RenderQueue* renderQueue); + void FillModels(std::list>& jobs); EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp index dd34072f..5da2c0c6 100644 --- a/src/Engine/Rendering/DrawScenePass.cpp +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -32,9 +32,8 @@ void DrawScenePass::Draw(RenderFrame& rf) DrawScenePassState state; for (auto scene : rf.RenderScenes) { - scene->Forward.Jobs.sort(DrawScenePass::DepthSort); - for (auto &job : scene->Forward) { + for (auto &job : scene->ForwardJobs) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { GLuint ShaderHandle = m_BasicForwardProgram->GetHandle(); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index fbbbd7c0..a09f328e 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -61,7 +61,7 @@ void PickingPass::Draw(RenderFrame& rf) { m_Camera = scene->Camera; - for (auto &job : scene->Forward) { + for (auto &job : scene->ForwardJobs) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index f385037b..8e5f2a34 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -129,63 +129,39 @@ glm::mat4 RenderSystem::ModelMatrix(EntityID entity) return modelMatrix; } -void RenderSystem::FillModels(RenderQueue* renderQueue) +void RenderSystem::FillModels(std::list>& jobs) { auto models = m_World->GetComponents("Model"); if (models == nullptr) { return; } - for (auto& modelC : *models) { - bool visible = modelC["Visible"]; + for (auto& modelComponent : *models) { + bool visible = modelComponent["Visible"]; if (!visible) { continue; } - std::string resource = modelC["Resource"]; + std::string resource = modelComponent["Resource"]; if (resource.empty()) { continue; } - glm::vec4 color = modelC["Color"]; - Model* model = ResourceManager::Load(resource); + + + Model* model = ResourceManager::Load<::Model>(resource); if (model == nullptr) { - model = ResourceManager::Load("Models/Core/Error.obj"); + model = ResourceManager::Load<::Model>("Models/Core/Error.obj"); } + + glm::mat4 modelMatrix = ModelMatrix(modelComponent.EntityID); + glm::mat4 matrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix() * (model->m_Matrix * modelMatrix); for (auto texGroup : model->TextureGroups) { - - if (color.a < 1.0f || texGroup.Transparency < 1.0f) { - //transparent stuffs - TransparentModelJob job; - job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0; - job.DiffuseTexture = texGroup.Texture.get(); - job.NormalTexture = texGroup.NormalMap.get(); - job.SpecularTexture = texGroup.SpecularMap.get(); - job.Model = model; - job.StartIndex = texGroup.StartIndex; - job.EndIndex = texGroup.EndIndex; - job.Matrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix() * (model->m_Matrix * ModelMatrix(modelC.EntityID)); - job.Color = color; - job.Entity = modelC.EntityID; - - job.Depth = 10.f; //insert real viewspace depth here - - renderQueue->Add(job); - } else { - ModelJob job; - job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0; - job.DiffuseTexture = texGroup.Texture.get(); - job.NormalTexture = texGroup.NormalMap.get(); - job.SpecularTexture = texGroup.SpecularMap.get(); - job.Model = model; - job.StartIndex = texGroup.StartIndex; - job.EndIndex = texGroup.EndIndex; - job.Matrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix() * (model->m_Matrix * ModelMatrix(modelC.EntityID)); - job.Color = color; - job.Entity = modelC.EntityID; - - renderQueue->Add(job); - } + std::shared_ptr modelJob = std::shared_ptr(new ModelJob(model, m_Camera, matrix, texGroup, modelComponent)); + jobs.push_back(modelJob); } + + + } } @@ -261,7 +237,7 @@ void RenderSystem::Update(World* world, double dt) m_RenderFrame->Clear(); RenderScene* rs = new RenderScene(); rs->Camera = m_Camera; - FillModels(&rs->Forward); + FillModels(rs->ForwardJobs); m_RenderFrame->Add(*rs); delete rs; } From f80ad1377b88b9d3f88a76f1c78b2ac99b04ab7b Mon Sep 17 00:00:00 2001 From: stiffly Date: Mon, 11 Jan 2016 17:52:27 +0100 Subject: [PATCH 16/50] Making use of Doppler effect. Added a bunch of events: Pause, stop, continue, variations of play. --- README.md | 3 +- include/Engine/Sound/EContinueSound.h | 17 ++ include/Engine/Sound/EPauseSound.h | 17 ++ include/Engine/Sound/EPlaySound.h | 2 +- include/Engine/Sound/EPlaySoundOnEntity.h | 21 +++ include/Engine/Sound/EPlaySoundOnPosition.h | 26 +++ include/Engine/Sound/EStopSound.h | 17 ++ include/Engine/Sound/SoundSystem.h | 37 ++-- include/Game/Game.h | 4 +- resources/Schema/Components/SoundEmitter.xml | 1 + resources/Schema/Components/SoundEmitter.xsd | 12 +- src/Engine/Sound/SoundSystem.cpp | 179 +++++++++++++++---- src/Game/Game.cpp | 14 +- 13 files changed, 296 insertions(+), 54 deletions(-) create mode 100644 include/Engine/Sound/EContinueSound.h create mode 100644 include/Engine/Sound/EPauseSound.h create mode 100644 include/Engine/Sound/EPlaySoundOnEntity.h create mode 100644 include/Engine/Sound/EPlaySoundOnPosition.h create mode 100644 include/Engine/Sound/EStopSound.h diff --git a/README.md b/README.md index 7c5f2268..7a488299 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ Libraries bundled along with binaries for Windows (MSVC14), available as a submo | **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) | | **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) | | **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) | -| **[ImGui](https://github.com/ocornut/imgui)** | 2015-12-12 | [MIT License](https://github.com/ocornut/imgui/blob/de3a154f3801de22c8e0bd2aeabf663a70c05972/LICENSE) | +| **[ImGui](https://github.com/ocornut/imgui)** | 2015-12-12 | [MIT License](https://github.com/ocornut/imgui/blob/de3a154f3801de22c8e0bd2aeabf663a70c05972/LICENSE) +| **[OpenAL](https://www.openal.org/)** | 1.1 | [OpenAL License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) | #### External libraries Libraries that are too big to be bundled with the project. diff --git a/include/Engine/Sound/EContinueSound.h b/include/Engine/Sound/EContinueSound.h new file mode 100644 index 00000000..2c624b0b --- /dev/null +++ b/include/Engine/Sound/EContinueSound.h @@ -0,0 +1,17 @@ +#ifndef Events_ContinueSound_h__ +#define Events_ContinueSound_h__ + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct ContinueSound : Event +{ + EntityID EmitterID; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EPauseSound.h b/include/Engine/Sound/EPauseSound.h new file mode 100644 index 00000000..f9e2e6f0 --- /dev/null +++ b/include/Engine/Sound/EPauseSound.h @@ -0,0 +1,17 @@ +#ifndef Events_PauseSound_h__ +#define Events_PauseSound_h__ + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct PauseSound : Event +{ + EntityID EmitterID; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EPlaySound.h b/include/Engine/Sound/EPlaySound.h index 83fc4629..9c9eab0a 100644 --- a/include/Engine/Sound/EPlaySound.h +++ b/include/Engine/Sound/EPlaySound.h @@ -10,7 +10,7 @@ namespace Events struct PlaySound : Event { std::string FilePath; - EntityID emitter; + EntityID EmitterID; }; } diff --git a/include/Engine/Sound/EPlaySoundOnEntity.h b/include/Engine/Sound/EPlaySoundOnEntity.h new file mode 100644 index 00000000..39dea432 --- /dev/null +++ b/include/Engine/Sound/EPlaySoundOnEntity.h @@ -0,0 +1,21 @@ +#ifndef Events_PlaySoundOnEntity_h__ +#define Events_PlaySoundOnEntity_h__ + +#include +#include "Core/Entity.h" +#include "Core/Event.h" + +namespace Events +{ + +// Plays a sound on an entity with a SoundEmitter component attached. +// Sound behavior is thereby specified in the SoundEmitter component. +struct PlaySoundOnEntity : public Event +{ + EntityID EmitterID = 0; + std::string FilePath = ""; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EPlaySoundOnPosition.h b/include/Engine/Sound/EPlaySoundOnPosition.h new file mode 100644 index 00000000..6a6b4d13 --- /dev/null +++ b/include/Engine/Sound/EPlaySoundOnPosition.h @@ -0,0 +1,26 @@ +#ifndef Events_PlaySoundOnPosition_h__ +#define Events_PlaySoundOnPosition_h__ + +#include +#include +#include "Core/Event.h" + +namespace Events +{ + +// Plays a sound on a given position +struct PlaySoundOnPosition : public Event +{ + glm::vec3 Position = glm::vec3(0); + std::string FilePath = ""; + float Gain = 1; + float Pitch = 1; + bool Loop = false; + float MaxDistance = 20; + float RollOffFactor = 1; + float ReferenceDistance = 1; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/EStopSound.h b/include/Engine/Sound/EStopSound.h new file mode 100644 index 00000000..b6cd37b8 --- /dev/null +++ b/include/Engine/Sound/EStopSound.h @@ -0,0 +1,17 @@ +#ifndef Events_StopSound_h__ +#define Events_StopSound_h__ + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct StopSound : Event +{ + EntityID EmitterID; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundSystem.h index 5a8225ef..5100a54b 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundSystem.h @@ -4,7 +4,7 @@ #include #include "glm/common.hpp" -#include "glm/gtx/rotate_vector.hpp" +#include "glm/gtx/rotate_vector.hpp" // Calculate Up vector #include "OpenAL/al.h" #include "OpenAL/alc.h" @@ -13,9 +13,16 @@ #include "Rendering/RenderQueueFactory.h" // Absolute transform #include "Sound/Sound.h" #include "Sound/EPlaySound.h" +#include "Sound/EPlaySoundOnEntity.h" +#include "Sound/EPlaySoundOnPosition.h" +#include "Sound/EPauseSound.h" +#include "Sound/EStopSound.h" +#include "Sound/EContinueSound.h" + struct Source { + Source() { } Sound* SoundResource; ALuint ALsource; }; @@ -38,32 +45,42 @@ private: void setSourcePos(ALuint source, glm::vec3 pos) { ALfloat spos[3] = { pos.x, pos.y, pos.z }; alSourcefv(source, AL_POSITION, spos); }; void setSourceVel(ALuint source, glm::vec3 vel) { ALfloat svel[3] = { vel.x, vel.y, vel.z }; alSourcefv(source, AL_VELOCITY, svel); }; - bool isPlaying(ALuint source); - // Logic - World* m_World; - EventBroker* m_EventBroker; - void initOpenAL(); void updateEmitters(); void updateListener(); void deleteInactiveEmitters(); void addNewEmitters(); - ALuint createSource(); - void playSound(Source source); - void stopSound(Source source); + Source* createSource(std::string filePath); + void playSound(Source* source); + void stopSound(Source* source); void stopEmitter(EntityID emitter); + void stopEmitters(); + bool isPlaying(ALuint source); + void setSoundProperties(ALuint source, float gain, float pitch, bool loop, float maxDistance, float rollOffFactor, float referenceDistance); // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; ALCcontext* m_ALCcontext = nullptr; // Logic - std::unordered_map m_Sources; + World* m_World; + EventBroker* m_EventBroker; + std::unordered_map m_Sources; // Events EventRelay m_EPlaySound; bool OnPlaySound(const Events::PlaySound &e); + EventRelay m_EPlaySoundOnEntity; + bool OnPlaySoundOnEntity(const Events::PlaySoundOnEntity &e); + EventRelay m_EPlaySoundOnPosition; + bool OnPlaySoundOnPosition(const Events::PlaySoundOnPosition &e); + EventRelay m_EPauseSound; + bool OnPauseSound(const Events::PauseSound &e); + EventRelay m_EStopSound; + bool OnStopSound(const Events::StopSound &e); + EventRelay m_EContinueSound; + bool OnContinueSound(const Events::ContinueSound &e); }; #endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 6b284c74..a4264840 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -27,7 +27,9 @@ // Sound #include "Sound/SoundSystem.h" -#include "Sound/EPlaySound.h" +//#include "Sound/EPlaySound.h" +//#include "Sound/EPlaySoundOnEntity.h" +//#include "Sound/EPlaySoundOnPosition.h" class Game diff --git a/resources/Schema/Components/SoundEmitter.xml b/resources/Schema/Components/SoundEmitter.xml index cbcfc440..871919f1 100644 --- a/resources/Schema/Components/SoundEmitter.xml +++ b/resources/Schema/Components/SoundEmitter.xml @@ -2,6 +2,7 @@ Audio/crosscounter.wav 1.0 1.0 + false 20.0 1.0 1.0 diff --git a/resources/Schema/Components/SoundEmitter.xsd b/resources/Schema/Components/SoundEmitter.xsd index 31c18ce9..c734e6ba 100644 --- a/resources/Schema/Components/SoundEmitter.xsd +++ b/resources/Schema/Components/SoundEmitter.xsd @@ -7,15 +7,17 @@ - + The "volume" of the emitter. A value betweeen 0-1 - + The pitch of the emitter. A value betweeen 0-1 - + + If the sound should loop or not. + The distance where there will no longer be any attenuation. - + The rolloff rate of the source. - + The distance that the source will be the loudest. diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index fd379d50..582ca2db 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -8,9 +8,15 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker) initOpenAL(); alSpeedOfSound(340.29f); // Speed of sound - alDistanceModel(AL_INVERSE_DISTANCE); + alDistanceModel(AL_LINEAR_DISTANCE); + alDopplerFactor(1); EVENT_SUBSCRIBE_MEMBER(m_EPlaySound, &SoundSystem::OnPlaySound); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnEntity, &SoundSystem::OnPlaySoundOnEntity); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnPosition, &SoundSystem::OnPlaySoundOnPosition); + EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::OnStopSound); + EVENT_SUBSCRIBE_MEMBER(m_EPauseSound, &SoundSystem::OnPauseSound); + EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundSystem::OnContinueSound); } void SoundSystem::initOpenAL() @@ -27,12 +33,31 @@ void SoundSystem::initOpenAL() SoundSystem::~SoundSystem() { + stopEmitters(); // Stopps emitters + deleteInactiveEmitters(); // Deletes stopped emitters + + std::unordered_map::iterator it; + for (it = m_Sources.begin(); it != m_Sources.end(); it++) { + m_World->DeleteEntity((*it).first); + } + m_Sources.clear(); + alcDestroyContext(m_ALCcontext); alcCloseDevice(m_ALCdevice); delete m_ALCcontext; delete m_ALCdevice; } +void SoundSystem::stopEmitters() +{ + std::unordered_map::iterator it; + for (it = m_Sources.begin(); it != m_Sources.end(); it++) { + if (isPlaying((*it).second->ALsource)) { + stopSound((*it).second); + } + } +} + void SoundSystem::Update() { //deleteInactiveEmitters(); // Not tested @@ -44,14 +69,19 @@ void SoundSystem::Update() void SoundSystem::deleteInactiveEmitters() { auto emitterComponents = m_World->GetComponents("SoundEmitter"); - for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { + for (auto it = emitterComponents->begin(); it != emitterComponents->end();) { EntityID emitter = (*it).EntityID; - if (isPlaying(m_Sources[emitter].ALsource)) { // The sound is still playing, do not remove + if (isPlaying(m_Sources[emitter]->ALsource)) { // The sound is still playing, do not remove + it++; continue; } - alDeleteBuffers(1, &m_Sources[emitter].ALsource); - delete m_Sources[emitter].SoundResource; - m_Sources.erase(emitter); + else { + alDeleteBuffers(1, &m_Sources[emitter]->ALsource); + alDeleteSources(1, &m_Sources[emitter]->ALsource); + //delete m_Sources[emitter]->SoundResource; + m_Sources.erase(emitter); + m_World->DeleteEntity(emitter); + } } } @@ -60,12 +90,19 @@ void SoundSystem::addNewEmitters() auto emitterComponents = m_World->GetComponents("SoundEmitter"); for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { EntityID emitter = (*it).EntityID; - std::unordered_map::iterator i; + std::unordered_map::iterator i; i = m_Sources.find(emitter); if (i == m_Sources.end()) { // Did not exist, add it - Source source; - source.ALsource = createSource(); - source.SoundResource = ResourceManager::Load((std::string)(*it)["FilePath"]); + Source* source = createSource((std::string)(*it)["FilePath"]); + setSoundProperties ( + source->ALsource, + (float)(double)(*it)["Gain"], + (float)(double)(*it)["Pitch"], + (bool)(*it)["Loop"], + (float)(double)(*it)["MaxDistance"], + (float)(double)(*it)["RollOffFactor"], + (float)(double)(*it)["ReferenceDistance"] + ); m_Sources[emitter] = source; } } @@ -76,13 +113,26 @@ void SoundSystem::updateEmitters() auto emitterComponents = m_World->GetComponents("SoundEmitter"); for (auto it = emitterComponents->begin(); it != emitterComponents->end(); it++) { EntityID emitter = (*it).EntityID; - std::unordered_map::iterator i; + std::unordered_map::iterator i; i = m_Sources.find(emitter); if (i != m_Sources.end()) { - setSourcePos(m_Sources[emitter].ALsource, RenderQueueFactory::AbsolutePosition(m_World, emitter)); + glm::vec3 previousPos; + alGetSource3f(m_Sources[emitter]->ALsource, AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get previous pos + glm::vec3 nextPos = RenderQueueFactory::AbsolutePosition(m_World, emitter); // Get next pos + glm::vec3 velocity = nextPos - previousPos; // Calculate velocity + setSourcePos(m_Sources[emitter]->ALsource, nextPos); // Set next pos + setSourceVel(m_Sources[emitter]->ALsource, velocity); // Set velocity + setSoundProperties( + m_Sources[emitter]->ALsource, + (float)(double)(*it)["Gain"], + (float)(double)(*it)["Pitch"], + (bool)(*it)["Loop"], + (float)(double)(*it)["MaxDistance"], + (float)(double)(*it)["RollOffFactor"], + (float)(double)(*it)["ReferenceDistance"] + ); } // No orientation, emitts in all directions - // Velocity for doppler effect } } @@ -92,47 +142,97 @@ void SoundSystem::updateListener() auto listenerComponents = m_World->GetComponents("Listener"); for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { EntityID listener = (*it).EntityID; - setListenerPos(RenderQueueFactory::AbsolutePosition(m_World, listener)); + glm::vec3 previousPos; + alGetListener3f(AL_POSITION, &previousPos.x, &previousPos.y, &previousPos.z); // Get previous pos + glm::vec3 nextPos = RenderQueueFactory::AbsolutePosition(m_World, listener); // Get next (current) pos + glm::vec3 velocity = nextPos - previousPos; // Calculate velocity + setListenerPos(nextPos); + setListenerVel(velocity); setListenerOri(glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, listener))); - // Velocity for doppler effect } } -ALuint SoundSystem::createSource() +Source* SoundSystem::createSource(std::string filePath) { - ALuint source; - alGenSources((ALuint)1, &source); - alSourcei(source, AL_REFERENCE_DISTANCE, 1.0); - alSourcei(source, AL_MAX_DISTANCE, FLT_MAX); + ALuint alSource; + alGenSources((ALuint)1, &alSource); + alSourcei(alSource, AL_REFERENCE_DISTANCE, 1.0); + alSourcei(alSource, AL_MAX_DISTANCE, FLT_MAX); + Source* source = new Source(); + source->ALsource = alSource; + source->SoundResource = ResourceManager::Load(filePath); return source; } -void SoundSystem::playSound(Source source) +void SoundSystem::playSound(Source* source) { - alSourcei(source.ALsource, AL_BUFFER, source.SoundResource->Buffer()); - alSourcePlay(source.ALsource); + alSourcei(source->ALsource, AL_BUFFER, source->SoundResource->Buffer()); + alSourcePlay(source->ALsource); } -void SoundSystem::stopSound(Source source) -{ } +void SoundSystem::stopSound(Source* source) +{ + alSourceStop(source->ALsource); +} void SoundSystem::stopEmitter(EntityID emitter) -{ } +{ + +} bool SoundSystem::OnPlaySound(const Events::PlaySound & e) { - //Sound *sound = ResourceManager::Load(e.FilePath); - //if (sound == nullptr) { - // return false; - //} - //ALuint source = createSource(); - //Source sauce; - //sauce.ALsource = source; - //sauce.SoundResource = sound; - //playSound(sauce); + Source* sauce = createSource(e.FilePath); + playSound(sauce); return false; } +bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) +{ + Source* source = createSource(e.FilePath); + m_Sources[e.emitterID] = source; + playSound(source); + return false; +} + +bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) +{ + Source* source = createSource(e.FilePath); + auto emitterID = m_World->CreateEntity(); + auto transform = m_World->AttachComponent(emitterID, "Transform"); + (glm::vec3&)transform["Position"] = e.Position; + auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); + (float&)(double)emitter["Gain"] = e.Gain; + (float&)(double)emitter["Pitch"] = e.Pitch; + (bool&)emitter["Loop"] = e.Loop; + (float&)(double)emitter["MaxDistance"] = e.MaxDistance; + (float&)(double)emitter["RollOffFactor"] = e.RollOffFactor; + (float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance; + auto model = m_World->AttachComponent(emitterID, "Model"); + (std::string&)model["Resource"] = "Models/Core/UnitCube.obj"; + m_Sources[emitterID] = source; + playSound(source); + return false; +} + +bool SoundSystem::OnPauseSound(const Events::PauseSound & e) +{ + alSourcePause(m_Sources[e.EmitterID]->ALsource); + return false; +} + +bool SoundSystem::OnStopSound(const Events::StopSound & e) +{ + alSourceStop(m_Sources[e.EmitterID]->ALsource); + return false; +} + +bool SoundSystem::OnContinueSound(const Events::ContinueSound & e) +{ + alSourcePlay(m_Sources[e.EmitterID]->ALsource); + return true; +} + void SoundSystem::setListenerOri(glm::vec3 ori) { glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); @@ -156,3 +256,12 @@ bool SoundSystem::isPlaying(ALuint source) return (state == AL_PLAYING); } +void SoundSystem::setSoundProperties(ALuint source, float gain, float pitch, bool loop, float maxDistance, float rollOffFactor, float referenceDistance) +{ + alSourcef(source, AL_GAIN, gain); + alSourcef(source, AL_PITCH, pitch); + alSourcei(source, AL_LOOPING, (int)loop); // YOLO + alSourcef(source, AL_MAX_DISTANCE, maxDistance); + alSourcef(source, AL_ROLLOFF_FACTOR, rollOffFactor); + alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance); +} diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 1863fa38..86682591 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -130,8 +130,20 @@ void Game::Tick() bool Game::debugOnInputCommand(const Events::InputCommand & e) { if (e.Command == "PlaySound" && e.Value > 0) { - Events::PlaySound e; + Events::PlaySoundOnEntity e; + e.emitterID = 18; e.FilePath = "Audio/crosscounter.wav"; + //e.emitterID = 18; // rofl + m_EventBroker->Publish(e); + } + if (e.Command == "Reload" && e.Value > 0) { + Events::PauseSound e; + e.EmitterID = 18; + m_EventBroker->Publish(e); + } + if (e.Command == "Crouch" && e.Value > 0) { + Events::ContinueSound e; + e.EmitterID = 18; m_EventBroker->Publish(e); } return true; From 0cf8d2655745d5b76a6f590c10463ee4f57a904a Mon Sep 17 00:00:00 2001 From: Tleety Date: Mon, 11 Jan 2016 17:56:58 +0100 Subject: [PATCH 17/50] Revert "Revert "Forward+"" This reverts commit b908a9f9c683abae3a745105bd945af980a7d2b1. --- include/Engine/Rendering/DrawFinalPass.h | 38 +++++ include/Engine/Rendering/DrawFinalPassState.h | 15 ++ include/Engine/Rendering/LightCullingPass.h | 78 +++++++++ .../Engine/Rendering/LightCullingPassState.h | 0 include/Engine/Rendering/PickingPass.h | 6 +- include/Engine/Rendering/RenderQueue.h | 11 +- include/Engine/Rendering/Renderer.h | 65 +------- resources/Schema/Components.xsd | 1 + resources/Schema/Components/PointLight.xml | 7 + resources/Schema/Components/PointLight.xsd | 20 +++ resources/Schema/Entities/Test.xml | 8 +- resources/Schema/Types/Entity.xsd | 1 + resources/Shaders/CullLights.comp.glsl | 154 ++++++++++++++++++ resources/Shaders/ForwardPlus.frag.glsl | 132 +++++++++++++++ resources/Shaders/ForwardPlus.vert.glsl | 34 ++++ resources/Shaders/GridFrustum.comp.glsl | 51 +++--- resources/Shaders/cullLights.comp.glsl | 35 ---- src/Engine/Rendering/DrawFinalPass.cpp | 65 ++++++++ src/Engine/Rendering/DrawFinalPassState.cpp | 17 ++ src/Engine/Rendering/DrawScenePass.cpp | 15 +- src/Engine/Rendering/LightCullingPass.cpp | 126 ++++++++++++++ .../Rendering/LightCullingPassState.cpp | 0 src/Engine/Rendering/RenderQueueFactory.cpp | 28 ++++ src/Engine/Rendering/RenderState.cpp | 1 + src/Engine/Rendering/Renderer.cpp | 144 +--------------- 25 files changed, 780 insertions(+), 272 deletions(-) create mode 100644 include/Engine/Rendering/DrawFinalPass.h create mode 100644 include/Engine/Rendering/DrawFinalPassState.h create mode 100644 include/Engine/Rendering/LightCullingPass.h create mode 100644 include/Engine/Rendering/LightCullingPassState.h create mode 100644 resources/Schema/Components/PointLight.xml create mode 100644 resources/Schema/Components/PointLight.xsd create mode 100644 resources/Shaders/CullLights.comp.glsl create mode 100644 resources/Shaders/ForwardPlus.frag.glsl create mode 100644 resources/Shaders/ForwardPlus.vert.glsl delete mode 100644 resources/Shaders/cullLights.comp.glsl create mode 100644 src/Engine/Rendering/DrawFinalPass.cpp create mode 100644 src/Engine/Rendering/DrawFinalPassState.cpp create mode 100644 src/Engine/Rendering/LightCullingPass.cpp create mode 100644 src/Engine/Rendering/LightCullingPassState.cpp diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h new file mode 100644 index 00000000..1a201daf --- /dev/null +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -0,0 +1,38 @@ +#ifndef DrawFinalPass_h__ +#define DrawFinalPass_h__ + +#include "IRenderer.h" +#include "DrawFinalPassState.h" +#include "LightCullingPass.h" +#include "FrameBuffer.h" +#include "ShaderProgram.h" +#include "Util/UnorderedMapVec2.h" +#include "Texture.h" + +class DrawFinalPass +{ +public: + DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass); + ~DrawFinalPass() { } + void InitializeTextures(); + void InitializeFrameBuffers(); + void InitializeShaderPrograms(); + + void Draw(RenderQueueCollection& rq); + + //Getters + + +private: + void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; + + Texture* m_WhiteTexture; + + const IRenderer* m_Renderer; + const LightCullingPass* m_LightCullingPass; + + ShaderProgram* m_ForwardPlusProgram; + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/DrawFinalPassState.h b/include/Engine/Rendering/DrawFinalPassState.h new file mode 100644 index 00000000..72d8e392 --- /dev/null +++ b/include/Engine/Rendering/DrawFinalPassState.h @@ -0,0 +1,15 @@ +#ifndef DrawFinalPassState_h__ +#define DrawFinalPassState_h__ + +#include "Rendering/RenderState.h" + +class DrawFinalPassState : public RenderState +{ +public: + DrawFinalPassState(); + ~DrawFinalPassState(); +private: + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/LightCullingPass.h b/include/Engine/Rendering/LightCullingPass.h new file mode 100644 index 00000000..e08aacdf --- /dev/null +++ b/include/Engine/Rendering/LightCullingPass.h @@ -0,0 +1,78 @@ +#ifndef LightCullingPass_h__ +#define LightCullingPass_h__ + +#define TILE_SIZE 16 +#define NUM_LIGHTS 1000 + +#include "IRenderer.h" +#include "LightCullingPassState.h" +#include "ShaderProgram.h" + + +class LightCullingPass +{ +public: + LightCullingPass(IRenderer* renderer); + ~LightCullingPass(); + + void GenerateNewFrustum(); + void CullLights(); + void FillLightList(RenderQueueCollection& rq); + + GLuint FrustumSSBO() const { return m_FrustumSSBO; } + GLuint LightSSBO() const { return m_LightSSBO; } + GLuint LightGridSSBO() const { return m_LightGridSSBO; } + GLuint LightOffsetSSBO() const { return m_LightOffsetSSBO; } + GLuint LightIndexSSBO() const { return m_LightIndexSSBO; } +private: + + void InitializeSSBOs(); + void InitializeShaderPrograms(); + + const IRenderer* m_Renderer; + + GLuint m_FrustumSSBO = 0; + GLuint m_LightSSBO = 0; + GLuint m_LightGridSSBO = 0; + GLuint m_LightOffsetSSBO = 0; + GLuint m_LightIndexSSBO = 0; + + ShaderProgram* m_CalculateFrustumProgram; + ShaderProgram* m_LightCullProgram; + + struct Plane { + glm::vec3 Normal; + float d; + }; + + struct Frustum { + Plane Planes[4]; + }; + Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution + + //This should be a component + struct PointLight { + glm::vec4 Position = glm::vec4(0.f); + glm::vec4 Color = glm::vec4(1.f); + float Radius = 5.f; + float Intensity = 0.8f; + float Falloff = 0.3f; + float Padding = 1337; + }; + std::vector m_PointLights; + + struct LightGrid { + float Start; + float Amount; + glm::vec2 Padding; + }; + + LightGrid m_LightGrid[80*45]; //TODO: Renderer: Make this change with resolution + + int m_LightOffset = 0; + + float m_LightIndex[80*45*200]; //TODO: Renderer: Make this change with resolution +}; + + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/LightCullingPassState.h b/include/Engine/Rendering/LightCullingPassState.h new file mode 100644 index 00000000..e69de29b diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index e1bc42db..0c1261ce 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -1,6 +1,8 @@ #ifndef PickingPass_h__ #define PickingPass_h__ + + #include "IRenderer.h" #include "PickingPassState.h" #include "FrameBuffer.h" @@ -9,6 +11,8 @@ #include "../Core/EventBroker.h" #include "EPicking.h" + + class PickingPass { public: @@ -20,7 +24,6 @@ public: void Draw(RenderQueueCollection& rq); - //Getters const ShaderProgram& PickingProgram() const { return *m_PickingProgram; } const std::unordered_map& PickingColorsToEntity() const { return m_PickingColorsToEntity; } @@ -28,7 +31,6 @@ public: GLuint DepthBuffer() const { return m_DepthBuffer; } const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; } - private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 2942c743..44d5e172 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -82,11 +82,12 @@ struct SpriteJob : RenderJob struct PointLightJob : RenderJob { - glm::vec3 Position; - glm::vec3 SpecularColor = glm::vec3(1, 1, 1); - glm::vec3 DiffuseColor = glm::vec3(1, 1, 1); - float Radius = 1.f; - float Intensity = 0.8f; + glm::vec4 Position; + glm::vec4 Color; + float Radius; + float Intensity; + float Falloff; + float padding = 123; void CalculateHash() override { diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 19b48e1a..c9f5d76f 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -13,19 +13,8 @@ #include "PickingPass.h" #include "DrawScenePass.h" #include "DebugCameraInputController.h" - - -#define TILE_SIZE 16 -#define NUM_LIGHTS 3 - - -enum lightType -{ - Point, - Spot, - Directional, - Area -}; +#include "LightCullingPass.h" +#include "DrawFinalPass.h" #include "../Core/EventBroker.h" #include "EPicking.h" @@ -58,70 +47,24 @@ private: DrawScenePass* m_DrawScenePass; PickingPass* m_PickingPass; + LightCullingPass* m_LightCullingPass; ImGuiRenderPass* m_ImGuiRenderPass; + DrawFinalPass* m_DrawFinalPass; //----------------------Functions----------------------// void InitializeWindow(); void InitializeShaders(); void InitializeTextures(); - void InitializeSSBOs(); void InitializeRenderPasses(); //TODO: Renderer: Get InputUpdate out of renderer void InputUpdate(double dt); //void PickingPass(RenderQueueCollection& rq); void DrawScreenQuad(GLuint textureToDraw); - //----------------------Forward+-----------------------// - void CalculateFrustum(); - void CullLights(); - //Frustum - struct Plane { - glm::vec3 Normal; - float d; - }; - struct Frustum { - Plane Planes[4]; - }; - Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution - - //Lights - void TEMPCreateLights(); - //TODO: Renderer: Add Directionllights, spotlights and area lights to this as type. - struct PointLight { - glm::vec4 Position = glm::vec4(0.f); - glm::vec4 Color = glm::vec4(1.f); - float Radius = 5.f; - float Intensity = 0.8f; - float Falloff = 0.3f; - float Padding = 1337; - }; - PointLight m_PointLights[NUM_LIGHTS]; - - struct LightGrid { - int Amount; - int Start; - glm::vec2 Padding; - }; - LightGrid m_LightGrid[80*45]; - - int m_LightOffset = 0; - - int m_LightIndex[80*45*200]; - - //-------------------------SSBO------------------------// - GLuint m_FrustumSSBO = 0; - GLuint m_LightSSBO = 1; - GLuint m_LightGridSSBO = 2; - GLuint m_LightOffsetSSBO = 3; - GLuint m_LightIndexSSBO = 4; - void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); //--------------------ShaderPrograms-------------------// ShaderProgram* m_BasicForwardProgram; ShaderProgram* m_DrawScreenQuadProgram; - ShaderProgram* m_CalculateFrustumProgram; - ShaderProgram* m_LightCullProgram; - }; #endif \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 7fcdd565..459fd9d7 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -7,6 +7,7 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/PointLight.xml b/resources/Schema/Components/PointLight.xml new file mode 100644 index 00000000..6b1382db --- /dev/null +++ b/resources/Schema/Components/PointLight.xml @@ -0,0 +1,7 @@ + + + 1.0 + 0.8 + 0.3 + true + \ No newline at end of file diff --git a/resources/Schema/Components/PointLight.xsd b/resources/Schema/Components/PointLight.xsd new file mode 100644 index 00000000..d1a9f52c --- /dev/null +++ b/resources/Schema/Components/PointLight.xsd @@ -0,0 +1,20 @@ + + + + + + + + A pointlight that lights up geometry in a radius. + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 528c7e95..809bca51 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -10,7 +10,7 @@ - + +