diff --git a/include/Engine/Core/ConfigFile.h b/include/Engine/Core/ConfigFile.h index 28c34bd3..54bbbad4 100644 --- a/include/Engine/Core/ConfigFile.h +++ b/include/Engine/Core/ConfigFile.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "../Common.h" #include "ResourceManager.h" @@ -19,12 +20,14 @@ private: public: template T Get(std::string key, T defaultValue); + template + std::vector> GetAll(std::string key); template void Set(std::string key, T value); void SaveToDisk(); - private: +private: boost::filesystem::path m_Path; boost::property_tree::ptree m_PTreeDefaults; boost::property_tree::ptree m_PTreeOverrides; @@ -37,6 +40,21 @@ T ConfigFile::Get(std::string key, T defaultValue) return m_PTreeMerged.get(key, defaultValue); } +template +std::vector> ConfigFile::GetAll(std::string key) +{ + std::vector> out; + auto parent = m_PTreeMerged.find(key); + if (parent == m_PTreeMerged.not_found()) { + return out; + } + for (auto& child : parent->second) { + T value = boost::lexical_cast(child.second.data()); + out.push_back(std::make_pair(child.first, value)); + } + return out; +} + template void ConfigFile::Set(std::string key, T value) { diff --git a/include/Engine/Core/InputController.h b/include/Engine/Core/InputController.h index b91fb448..b87d1eff 100644 --- a/include/Engine/Core/InputController.h +++ b/include/Engine/Core/InputController.h @@ -11,25 +11,22 @@ template class InputController { public: - InputController(std::shared_ptr eventBroker) - : EventBroker(eventBroker) + InputController(EventBroker* eventBroker) + : m_EventBroker(eventBroker) { Initialize(); } virtual void Initialize() { EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &InputController::OnCommand); - EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &InputController::OnMouseMove); } - virtual bool OnCommand(const Events::InputCommand &event) { return false; } - virtual bool OnMouseMove(const Events::MouseMove &event) { return false; } + virtual bool OnCommand(const Events::InputCommand& e) { return false; } protected: - std::shared_ptr EventBroker; + EventBroker* m_EventBroker; private: EventRelay m_EInputCommand; - EventRelay m_EMouseMove; }; #endif diff --git a/include/Engine/Input/EBindGamepadAxis.h b/include/Engine/Input/EBindGamepadAxis.h deleted file mode 100644 index 1f2665ad..00000000 --- a/include/Engine/Input/EBindGamepadAxis.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef Events_BindGamepadAxis_h__ -#define Events_BindGamepadAxis_h__ - -#include "Core/EventBroker.h" -#include "Core/EGamepadAxis.h" - -namespace Events -{ - -/** Called to bind a gamepad axis to an input command. */ -struct BindGamepadAxis : Event -{ - /** The axis to bind. */ - Gamepad::Axis Axis; - /** The command to send. */ - std::string Command; - /** The value to send for positive stimulation. - - Multiplied by the 0-1 clamped value of the axis. - */ - float Value; -}; - -} diff --git a/include/Engine/Input/EBindGamepadButton.h b/include/Engine/Input/EBindGamepadButton.h deleted file mode 100644 index 47dddf31..00000000 --- a/include/Engine/Input/EBindGamepadButton.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef Events_BindGamepadButton_h__ -#define Events_BindGamepadButton_h__ - -#include "Core/EventBroker.h" -#include "Core/EGamepadButton.h" - -namespace Events -{ - -/** Called to bind a gamepad button to an input command. */ -struct BindGamepadButton : Event -{ - /** The gamepad button to bind. */ - Gamepad::Button Button; - /** The command to send. */ - std::string Command; - /** The value to send for positive stimulation. - - Multiplied by the 0-1 clamped value of the button. - */ - float Value; -}; - -} - -#endif diff --git a/include/Engine/Input/EBindKey.h b/include/Engine/Input/EBindKey.h deleted file mode 100644 index fb1c199a..00000000 --- a/include/Engine/Input/EBindKey.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef Events_BindKey_h__ -#define Events_BindKey_h__ - -#include "Core/EventBroker.h" - -namespace Events -{ - -/** Called to bind a keyboard key to an input command. */ -struct BindKey : Event -{ - /** The GLFW key code to bind. */ - int KeyCode; - /** The command to send. */ - std::string Command; - /** The value to send for positive stimulation. - - Multiplied by the 0-1 clamped value of the key. - */ - float Value; -}; - -} - -#endif diff --git a/include/Engine/Input/EBindMouseButton.h b/include/Engine/Input/EBindMouseButton.h deleted file mode 100644 index 78b5dfa3..00000000 --- a/include/Engine/Input/EBindMouseButton.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef Events_BindMouseButton_h__ -#define Events_BindMouseButton_h__ - -#include "Core/EventBroker.h" - -namespace Events -{ - -/** Called to bind a mouse button to an input command. */ -struct BindMouseButton : Event -{ - /** The GLFW mouse button code to bind. */ - int Button; - /** The command to send. */ - std::string Command; - /** The value to send for positive stimulation. - - Multiplied by the 0-1 clamped value of the button. - */ - float Value; -}; - -} - -#endif diff --git a/include/Engine/Input/EBindOrigin.h b/include/Engine/Input/EBindOrigin.h new file mode 100644 index 00000000..e39a6023 --- /dev/null +++ b/include/Engine/Input/EBindOrigin.h @@ -0,0 +1,22 @@ +#ifndef Events_BindOrigin_h__ +#define Events_BindOrigin_h__ + +#include "Core/EventBroker.h" + +namespace Events +{ + +/** Called to bind an input origin to an input command. */ +struct BindOrigin : Event +{ + /** The input origin to bind. */ + std::string Origin; + /** The command to send. */ + std::string Command; + /** The value to send for positive stimulation. */ + float Value = 1.f; +}; + +} + +#endif diff --git a/include/Engine/Input/EInputCommand.h b/include/Engine/Input/EInputCommand.h index 9c190a1e..9ec897d3 100644 --- a/include/Engine/Input/EInputCommand.h +++ b/include/Engine/Input/EInputCommand.h @@ -13,7 +13,7 @@ struct InputCommand : Event /** The command that was sent. */ std::string Command; /** The value of the command. */ - float Value; + float Value = 0; }; } diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h new file mode 100644 index 00000000..d8584494 --- /dev/null +++ b/include/Engine/Input/FirstPersonInputController.h @@ -0,0 +1,70 @@ +#ifndef FirstPersonInputController_h__ +#define FirstPersonInputController_h__ + +#include "../GLM.h" +#include "../Core/InputController.h" +#include "../Core/ELockMouse.h" + +template +class FirstPersonInputController : public InputController +{ +public: + FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID) + : InputController(eventBroker) + , m_PlayerID(playerID) + { + EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); + EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); + } + + const glm::quat Orientation() const { return m_Orientation; } + + void LockMouse() + { + Events::LockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = true; + } + + void UnlockMouse() + { + Events::UnlockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = false; + } + + virtual bool OnCommand(const Events::InputCommand& e) override + { + if (m_PlayerID != e.PlayerID) { + return false; + } + + if (m_MouseLocked) { + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1, 0, 0)); + return true; + } + + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1, 0)) * m_Orientation; + return true; + } + } + + return false; + } + +protected: + const unsigned int m_PlayerID; + glm::quat m_Orientation; + bool m_MouseLocked = false; + + EventRelay m_ELockMouse; + bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; } + EventRelay m_EUnlockMouse; + bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; } +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Input/InputHandler.h b/include/Engine/Input/InputHandler.h new file mode 100644 index 00000000..a9b3c038 --- /dev/null +++ b/include/Engine/Input/InputHandler.h @@ -0,0 +1,25 @@ +#ifndef InputHandler_h__ +#define InputHandler_h__ + +#include "../Common.h" +#include "../Core/EventBroker.h" +#include "InputProxy.h" + +class InputHandler +{ +public: + InputHandler(EventBroker* eventBroker, InputProxy* inputProxy) + : m_EventBroker(eventBroker) + , m_InputProxy(inputProxy) + { } + + virtual bool BindOrigin(std::string origin, std::string command, float value) = 0; + virtual void Update(double dt) { } + virtual float GetCommandValue(std::string command) = 0; + +protected: + EventBroker* m_EventBroker; + InputProxy* m_InputProxy; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Input/InputProxy.h b/include/Engine/Input/InputProxy.h new file mode 100644 index 00000000..c7817c22 --- /dev/null +++ b/include/Engine/Input/InputProxy.h @@ -0,0 +1,46 @@ +#ifndef InputProxy_h__ +#define InputProxy_h__ + +#include "../Common.h" +#include "../Core/ResourceManager.h" +#include "../Core/ConfigFile.h" +#include "EInputCommand.h" +#include "EBindOrigin.h" + +class InputHandler; + +class InputProxy +{ +public: + InputProxy(EventBroker* eventBroker); + ~InputProxy(); + + void LoadBindings(std::string file); + void Update(double dt); + void Process(); + template + void AddHandler(); + void Publish(const Events::InputCommand& e); + +protected: + EventBroker* m_EventBroker; + std::vector m_Handlers; + std::map> m_CommandHandlers; + + // Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame + std::map, std::vector> m_CommandQueue; + + std::map m_CurrentCommandValues; + std::map m_LastCommandValues; + + EventRelay m_EBindOrigin; + bool OnBindOrigin(const Events::BindOrigin& e); +}; + +template +void InputProxy::AddHandler() +{ + m_Handlers.push_back(new T(m_EventBroker, this)); +} + +#endif diff --git a/include/Engine/Input/InputSystem.h b/include/Engine/Input/InputSystem.h deleted file mode 100644 index 2023880b..00000000 --- a/include/Engine/Input/InputSystem.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef InputSystem_h__ -#define InputSystem_h__ - -#include -#include - -#include "Core/System.h" -#include "Core/EKeyUp.h" -#include "Core/EKeyDown.h" -#include "Core/EMousePress.h" -#include "Core/EMouseRelease.h" -#include "Core/EGamepadAxis.h" -#include "Core/EGamepadButton.h" -#include "Core/Util/EnumClassHash.h" -#include "EBindKey.h" -#include "EBindMouseButton.h" -#include "EBindGamepadAxis.h" -#include "EBindGamepadButton.h" -#include "EInputCommand.h" - -namespace Systems -{ - -class InputSystem : public System -{ -public: - InputSystem(World* world, std::shared_ptr eventBroker) - : System(world, eventBroker) - { } - - void RegisterComponents(ComponentFactory* cf) override; - void Initialize() override; - - void Update(double dt) override; - -private: - std::unordered_map> m_CommandKeyboardValues; // command string -> keyboard key value for command - std::unordered_map> m_CommandMouseButtonValues; // command string -> mouse button value for command - std::unordered_map> m_CommandGamepadAxisValues; // command string -> gamepad axis value for command - std::unordered_map> m_CommandGamepadButtonValues; // command string -> gamepad button value for command - // Input binding tables - std::unordered_multimap> m_KeyBindings; // GLFW_KEY... -> command string & value - std::unordered_multimap> m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string - std::unordered_multimap, EnumClassHash> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value - std::unordered_multimap, EnumClassHash> m_GamepadButtonBindings; // Gamepad::Button -> command string - - // Input events - EventRelay m_EKeyDown; - bool OnKeyDown(const Events::KeyDown &event); - EventRelay m_EKeyUp; - bool OnKeyUp(const Events::KeyUp &event); - EventRelay m_EMousePress; - bool OnMousePress(const Events::MousePress &event); - EventRelay m_EMouseRelease; - bool OnMouseRelease(const Events::MouseRelease &event); - EventRelay m_EGamepadAxis; - bool OnGamepadAxis(const Events::GamepadAxis &event); - EventRelay m_EGamepadButtonDown; - bool OnGamepadButtonDown(const Events::GamepadButtonDown &event); - EventRelay m_EGamepadButtonUp; - bool OnGamepadButtonUp(const Events::GamepadButtonUp &event); - // Input binding events - EventRelay m_EBindKey; - bool OnBindKey(const Events::BindKey &event); - EventRelay m_EBindMouseButton; - bool OnBindMouseButton(const Events::BindMouseButton &event); - EventRelay m_EBindGamepadAxis; - bool OnBindGamepadAxis(const Events::BindGamepadAxis &event); - EventRelay m_EBindGamepadButton; - bool OnBindGamepadButton(const Events::BindGamepadButton &event); - - float GetCommandTotalValue(std::string command); - void PublishCommand(int playerID, std::string command, float value); -}; - -} - -#endif diff --git a/include/Engine/Input/KeyboardInputHandler.h b/include/Engine/Input/KeyboardInputHandler.h new file mode 100644 index 00000000..49597fce --- /dev/null +++ b/include/Engine/Input/KeyboardInputHandler.h @@ -0,0 +1,28 @@ +#ifndef KeyboardInputHandler_h__ +#define KeyboardInputHandler_h__ + +#include +#include "InputHandler.h" +#include "Core/EKeyDown.h" +#include "Core/EKeyUp.h" + +class KeyboardInputHandler : public InputHandler +{ +public: + KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy); + + bool BindOrigin(std::string origin, std::string command, float value) override; + virtual float GetCommandValue(std::string command) override; + +private: + std::unordered_map m_OriginKeyCodes; + std::unordered_map> m_KeyBindings; // GLFW_KEY... -> command string & value + std::unordered_map m_CommandValues; + + EventRelay m_EKeyDown; + bool OnKeyDown(const Events::KeyDown& e); + EventRelay m_EKeyUp; + bool OnKeyUp(const Events::KeyUp& e); +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Input/MouseInputHandler.h b/include/Engine/Input/MouseInputHandler.h new file mode 100644 index 00000000..b9193a2d --- /dev/null +++ b/include/Engine/Input/MouseInputHandler.h @@ -0,0 +1,38 @@ +#ifndef MouseInputHandler_h__ +#define MouseInputHandler_h__ + +#include +#include "InputHandler.h" +#include "Core/EMousePress.h" +#include "Core/EMouseRelease.h" +#include "Core/EMouseMove.h" + +class MouseInputHandler : public InputHandler +{ +public: + MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy); + + bool BindOrigin(std::string origin, std::string command, float value) override; + virtual float GetCommandValue(std::string command) override; + +private: + std::unordered_map m_OriginCodes; + std::unordered_map m_OriginAxes; + std::unordered_map> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value + std::unordered_map> m_Axes; // Axis -> command string & value + std::unordered_map m_CommandValues; + std::unordered_map m_ContinuousCommandValues; + + EventRelay m_EMousePress; + bool OnMousePress(const Events::MousePress& e); + EventRelay m_EMouseRelease; + bool OnMouseRelease(const Events::MouseRelease& e); + EventRelay m_EMouseMove; + bool OnMouseMove(const Events::MouseMove& e); + + bool hasOrigin(std::string origin); + + +}; + +#endif diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h new file mode 100644 index 00000000..551ae0f2 --- /dev/null +++ b/include/Engine/Rendering/DebugCameraInputController.h @@ -0,0 +1,48 @@ +#include "../Input/FirstPersonInputController.h" + +template +class DebugCameraInputController : public FirstPersonInputController +{ +public: + DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID) + : FirstPersonInputController(eventBroker, playerID) + { } + + const glm::vec3 Position() const { return m_Position; } + void SetBaseSpeed(float speed) { m_BaseSpeed = speed; } + + virtual bool OnCommand(const Events::InputCommand& e) override + { + if (e.Command == "PrimaryFire") { + if (e.Value > 0) { + LockMouse(); + } else { + UnlockMouse(); + } + return false; + } + + if (e.Command == "Right") { + float value = std::max(-1.f, std::min(e.Value, 1.f)); + m_Velocity.x = value; + } + if (e.Command == "Forward") { + float value = std::max(-1.f, std::min(e.Value, 1.f)); + m_Velocity.z = -value; + } + + return FirstPersonInputController::OnCommand(e); + } + + void Update(double dt) + { + if (glm::length2(m_Velocity) > 0) { + m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_BaseSpeed); + } + } + +protected: + glm::vec3 m_Position = glm::vec3(0, 0, 0); + glm::vec3 m_Velocity = glm::vec3(0, 0, 0); + float m_BaseSpeed = 0.1f; +}; \ No newline at end of file diff --git a/include/Engine/Rendering/DrawScenePass.h b/include/Engine/Rendering/DrawScenePass.h new file mode 100644 index 00000000..782c5a49 --- /dev/null +++ b/include/Engine/Rendering/DrawScenePass.h @@ -0,0 +1,36 @@ +#ifndef DrawScenePass_h__ +#define DrawScenePass_h__ + +#include "IRenderer.h" +#include "DrawScenePassState.h" +#include "FrameBuffer.h" +#include "ShaderProgram.h" +#include "Util/UnorderedMapVec2.h" +#include "Texture.h" + +class DrawScenePass +{ +public: + DrawScenePass(IRenderer* renderer); + ~DrawScenePass() { } + 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; + + ShaderProgram* m_BasicForwardProgram; + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/DrawScenePassState.h b/include/Engine/Rendering/DrawScenePassState.h new file mode 100644 index 00000000..7ce74006 --- /dev/null +++ b/include/Engine/Rendering/DrawScenePassState.h @@ -0,0 +1,15 @@ +#ifndef DrawScenePassState_h__ +#define DrawScenePassState_h__ + +#include "Rendering/RenderState.h" + +class DrawScenePassState : public RenderState +{ +public: + DrawScenePassState(); + ~DrawScenePassState(); +private: + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h new file mode 100644 index 00000000..e1bc42db --- /dev/null +++ b/include/Engine/Rendering/PickingPass.h @@ -0,0 +1,49 @@ +#ifndef PickingPass_h__ +#define PickingPass_h__ + +#include "IRenderer.h" +#include "PickingPassState.h" +#include "FrameBuffer.h" +#include "ShaderProgram.h" +#include "Util/UnorderedMapVec2.h" +#include "../Core/EventBroker.h" +#include "EPicking.h" + +class PickingPass +{ +public: + PickingPass(IRenderer* renderer, EventBroker* eb); + ~PickingPass(); + void InitializeTextures(); + void InitializeFrameBuffers(); + void InitializeShaderPrograms(); + + void Draw(RenderQueueCollection& rq); + + + //Getters + const ShaderProgram& PickingProgram() const { return *m_PickingProgram; } + const std::unordered_map& PickingColorsToEntity() const { return m_PickingColorsToEntity; } + GLuint PickingTexture() const { return m_PickingTexture; } + 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; + + EventBroker* m_EventBroker; + + const IRenderer* m_Renderer; + + ShaderProgram* m_PickingProgram; + + std::unordered_map m_PickingColorsToEntity; + + GLuint m_PickingTexture; + GLuint m_DepthBuffer; + + FrameBuffer m_PickingBuffer; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/PickingPassState.h b/include/Engine/Rendering/PickingPassState.h new file mode 100644 index 00000000..4f6bfe40 --- /dev/null +++ b/include/Engine/Rendering/PickingPassState.h @@ -0,0 +1,15 @@ +#ifndef PickingPassState_h__ +#define PickingPassState_h__ + +#include "Rendering/RenderState.h" + +class PickingPassState : public RenderState +{ +public: + PickingPassState(GLuint frameBuffer); + ~PickingPassState(); + +private: +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h new file mode 100644 index 00000000..e7ba2f80 --- /dev/null +++ b/include/Engine/Rendering/RenderState.h @@ -0,0 +1,23 @@ +#ifndef RenderState_h__ +#define RenderState_h__ + +#include "../Common.h" +#include "../OpenGL.h" +#include "../GLM.h" + +class RenderState +{ +public: + RenderState(); + ~RenderState(); + bool Enable(GLenum GLEnable); + bool CullFace(GLenum GlFaceToCull); + bool ClearColor(glm::vec4 color); + bool Clear(GLbitfield mask); + bool BindBuffer(GLint buffer); +private: + std::vector m_Enables; + float m_preClearColor[4]; + int m_preBuffer; +}; +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 76de0818..886c98ca 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -10,6 +10,21 @@ #include "Util/UnorderedMapVec2.h" #include "FrameBuffer.h" #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" @@ -21,44 +36,87 @@ public: : m_EventBroker(eventBroker) { } - virtual void Initialize() override; - virtual void Update(double dt) override; - virtual void Draw(RenderQueueCollection& rq) override; + virtual void Initialize() override; + virtual void Update(double dt) override; + virtual void Draw(RenderQueueCollection& rq) override; private: - //----------------------Variables----------------------// + //----------------------Variables----------------------// EventBroker* m_EventBroker; - Texture* m_ErrorTexture; - Texture* m_WhiteTexture; - float m_CameraMoveSpeed; - FrameBuffer m_PickingBuffer; - GLuint m_PickingTexture; - GLuint m_DepthBuffer; + Texture* m_ErrorTexture; + Texture* m_WhiteTexture; + float m_CameraMoveSpeed; Model* m_ScreenQuad; Model* m_UnitQuad; Model* m_UnitSphere; - std::unordered_map m_PickingColorsToEntity; + DrawScenePass* m_DrawScenePass; + PickingPass* m_PickingPass; - //----------------------Functions----------------------// - void InitializeWindow(); - void InitializeShaders(); + //----------------------Functions----------------------// + void InitializeWindow(); + void InitializeShaders(); void InitializeTextures(); - void InitializeFrameBuffers(); + void InitializeSSBOs(); + void InitializeRenderPasses(); //TODO: Renderer: Get InputUpdate out of renderer - void InputUpdate(double dt); - void PickingPass(RenderQueueCollection& rq); + void InputUpdate(double dt); + //void PickingPass(RenderQueueCollection& rq); void DrawScreenQuad(GLuint textureToDraw); - void DrawScene(RenderQueueCollection& rq); + //----------------------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_PickingProgram; - ShaderProgram m_DrawScreenQuadProgram; + ShaderProgram* m_BasicForwardProgram; + ShaderProgram* m_DrawScreenQuadProgram; + ShaderProgram* m_CalculateFrustumProgram; + ShaderProgram* m_LightCullProgram; + }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/ShaderProgram.h b/include/Engine/Rendering/ShaderProgram.h index 1b87650e..ad01c029 100644 --- a/include/Engine/Rendering/ShaderProgram.h +++ b/include/Engine/Rendering/ShaderProgram.h @@ -1,6 +1,9 @@ +#ifndef ShaderProgram_h__ +#define ShaderProgram_h__ #include "../Common.h" #include "../OpenGL.h" +#include "../Core/ResourceManager.h" #include class Shader @@ -60,11 +63,13 @@ public: : ShaderType(fileName) { } }; -class ShaderProgram +class ShaderProgram : public Resource { -public: - ShaderProgram() + friend class ResourceManager; +private: + ShaderProgram(std::string) : m_ShaderProgramHandle(0) { } +public: ~ShaderProgram(); void AddShader(std::shared_ptr shader); @@ -79,3 +84,5 @@ private: GLuint m_ShaderProgramHandle; std::vector> m_Shaders; }; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Util/GLError.h b/include/Engine/Rendering/Util/GLError.h index 8202f433..754623d1 100644 --- a/include/Engine/Rendering/Util/GLError.h +++ b/include/Engine/Rendering/Util/GLError.h @@ -9,7 +9,7 @@ inline bool _GLERROR(const char* info, const char* file, const char* func, unsig GLenum error = glGetError(); if (error != GL_NO_ERROR) { - _LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s %i %s", info, error, gluErrorString(error)); + _LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s, %i, %s", info, error, gluErrorString(error)); return true; } diff --git a/include/Game/Game.h b/include/Game/Game.h index 326cf4f5..013d1665 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -9,6 +9,9 @@ #include "GUI/Frame.h" #include "Core/World.h" #include "Rendering/RenderQueueFactory.h" +#include "Input/InputProxy.h" +#include "Input/KeyboardInputHandler.h" +#include "Input/MouseInputHandler.h" #include "Core/EKeyDown.h" #include "Core/EntityXMLFile.h" #include "Core/SystemPipeline.h" @@ -36,6 +39,7 @@ private: EventBroker* m_EventBroker; IRenderer* m_Renderer; InputManager* m_InputManager; + InputProxy* m_InputProxy; GUI::Frame* m_FrameStack; World* m_World; SystemPipeline* m_SystemPipeline; @@ -46,11 +50,11 @@ private: // Network methods void NetworkFunction(); - EventRelay m_EKeyUp; - bool testOnKeyUp(const Events::KeyUp& e); + EventRelay m_EInputCommand; + bool debugOnInputCommand(const Events::InputCommand& e); - void testIntialize(); - void testTick(double dt); + void debugInitialize(); + void debugTick(double dt); EventRelay m_EKeyDown; }; diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index d896a8f6..b43a8aef 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -13,5 +13,6 @@ VSYNC=false Width=1280 Height=720 +FOV=45 [Networking] StartNetwork=false \ No newline at end of file diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini new file mode 100644 index 00000000..3be67287 --- /dev/null +++ b/resources/DefaultInput.ini @@ -0,0 +1,16 @@ +[Mouse] +Sensitivity=0.5 +InvertPitch=false + +[Bindings] +MouseLeft=PrimaryFire +MouseX=Yaw +MouseY=Pitch +W=+Forward +S=-Forward +D=+Right +A=-Right +R=Reload +Space=Jump +LeftControl=Crouch +LeftShift=Sprint diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 1aa59961..4f233ee7 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -61,7 +61,7 @@ - + Models/Core/UnitRaptor.obj @@ -72,8 +72,8 @@ - - + + 20 @@ -84,19 +84,7 @@ - - - - - Models/Core/UnitCylinder.obj - - - - - - - - + @@ -109,7 +97,7 @@ - + diff --git a/resources/Shaders/GridFrustum.comp.glsl b/resources/Shaders/GridFrustum.comp.glsl new file mode 100644 index 00000000..27559370 --- /dev/null +++ b/resources/Shaders/GridFrustum.comp.glsl @@ -0,0 +1,73 @@ +#version 430 + +#define TILE_SIZE 16 +#define NUM_TILES 3600 + +uniform mat4 P; +uniform vec2 ScreenDimensions; + +struct Plane { + vec3 Normal; + float d; +}; +struct Frustum { + Plane Planes[4]; +}; + +layout (std430, binding = 0) buffer FrustumBuffer +{ + Frustum Data[3600]; +} Frustums; + +vec4 ConvertToView(vec4 ScreenCoords) +{ + vec2 normalizedScreenCoords = ScreenCoords.xy / ScreenDimensions; + vec4 clipSpace = vec4( vec2(normalizedScreenCoords.x, normalizedScreenCoords.y) * 2.0 - 1.0, ScreenCoords.z, ScreenCoords.w); + vec4 view = inverse(P) * clipSpace; + view = view / view.w; + return view; +} + +Plane ComputePlane( vec3 p0, vec3 p1, vec3 p2 ) +{ + Plane plane; + + vec3 v0 = p1 - p0; + vec3 v2 = p2 - p0; + + plane.Normal = normalize( cross( v0, v2 ) ); + plane.d = dot( vec3(plane.Normal), p0 ); // Always 0 probably + return plane; +} + +layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; +void main () +{ + if(gl_GlobalInvocationID.x * TILE_SIZE < ScreenDimensions.x && gl_GlobalInvocationID.y * TILE_SIZE < ScreenDimensions.y) { + //Top-Left = 0 | Top-Right = 1 + //Bottom-Left = 2 | Bottom-Right = 3 + vec4 ScreenCoords[4]; + ScreenCoords[0] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y + 1 ) * TILE_SIZE, -1.0, 1.0); // Z-axis might need to be 1 + ScreenCoords[1] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0); + ScreenCoords[2] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0); + ScreenCoords[3] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0); + + vec3 ViewVectors[4]; + for(int i = 0; i < 4; i++) { + ViewVectors[i] = vec3(ConvertToView(ScreenCoords[i])); + } + + vec3 EyePos = vec3(0,0,0); + + Frustum f; + f.Planes[0] = ComputePlane(EyePos, ViewVectors[2], ViewVectors[0]); + f.Planes[1] = ComputePlane(EyePos, ViewVectors[1], ViewVectors[3]); + f.Planes[2] = ComputePlane(EyePos, ViewVectors[0], ViewVectors[1]); + f.Planes[3] = ComputePlane(EyePos, ViewVectors[3], ViewVectors[2]); + + + + + Frustums.Data[gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*80] = f; + } +} \ No newline at end of file diff --git a/resources/Shaders/cullLights.comp.glsl b/resources/Shaders/cullLights.comp.glsl new file mode 100644 index 00000000..e9fa9a95 --- /dev/null +++ b/resources/Shaders/cullLights.comp.glsl @@ -0,0 +1,35 @@ +#version 430 + +//in uvec3 gl_NumWorkGroups; +//in uvec3 gl_WorkGroupID; +//in uvec3 gl_LocalInvocationID; +//in uvec3 gl_GlobalInvocationID; +//in uint gl_LocalInvocationIndex; + + + +#define NUM_LIGHTS 3 +#define MAX_LIGHTS_PER_TILE 200 +#define NUM_TILES 3600 + +struct Plane { + vec3 Normal; + float d; +}; +struct Frustum { + Plane Planes[4]; +}; + +layout (std430, binding = 0) buffer FrustumBuffer +{ + Frustum Data[3600]; +} Frustums; + + + +layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; +void main () +{ + if(1 == 1) { + } +} \ No newline at end of file diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index de24b9cf..97ed3e68 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -73,7 +73,7 @@ source_group(GUI FILES ${SOURCE_FILES_GUI}) set(SOURCE_FILES ${SOURCE_FILES_Core} ${SOURCE_FILES_Core_Util} - #${SOURCE_FILES_Input} + ${SOURCE_FILES_Input} ${SOURCE_FILES_Network} ${SOURCE_FILES_GUI} ${SOURCE_FILES_Rendering} diff --git a/src/Engine/Core/ConfigFile.cpp b/src/Engine/Core/ConfigFile.cpp index 004ebc43..00ab4993 100644 --- a/src/Engine/Core/ConfigFile.cpp +++ b/src/Engine/Core/ConfigFile.cpp @@ -24,8 +24,11 @@ ConfigFile::ConfigFile(std::string path) if (boost::filesystem::exists(m_Path)) { try { boost::property_tree::ini_parser::read_ini(m_Path.string(), m_PTreeOverrides); - for (auto& node : m_PTreeOverrides) { - m_PTreeMerged.put_child(node.first, node.second); + for (auto& topLevelNode : m_PTreeOverrides) { + auto& mergedTopLevelNode = m_PTreeMerged.find(topLevelNode.first); + for (auto& childOverrideNode : topLevelNode.second) { + mergedTopLevelNode->second.put_child(childOverrideNode.first, childOverrideNode.second); + } } } catch (boost::property_tree::ptree_error& e) { LOG_ERROR("Failed to parse \"%s\":\n%s", m_Path.filename().string().c_str(), e.what()); diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp new file mode 100644 index 00000000..ad589df3 --- /dev/null +++ b/src/Engine/Input/InputProxy.cpp @@ -0,0 +1,112 @@ +#include "Input/InputProxy.h" +#include "Input/InputHandler.h" + +InputProxy::InputProxy(EventBroker* eventBroker) + : m_EventBroker(eventBroker) +{ + EVENT_SUBSCRIBE_MEMBER(m_EBindOrigin, &InputProxy::OnBindOrigin); +} + +InputProxy::~InputProxy() +{ + for (auto& handler : m_Handlers) { + delete handler; + } +} + +void InputProxy::LoadBindings(std::string file) +{ + auto config = ResourceManager::Load(file); + for (auto& origin : config->GetAll("Bindings")) { + Events::BindOrigin e; + e.Origin = origin.first; + e.Command = origin.second; + e.Value = 1.f; + if (!e.Command.empty()) { + char prefix = e.Command.at(0); + if (prefix == '+' || prefix == '-') { + e.Command = e.Command.substr(1); + if (prefix == '-') { + e.Value *= -1.f; + } + } + OnBindOrigin(e); + } + } +} + +void InputProxy::Update(double dt) +{ + m_EventBroker->Process(); + m_EventBroker->Process(); + for (auto& handler : m_Handlers) { + handler->Update(dt); + } +} + +void InputProxy::Process() +{ + for (auto& pair : m_CommandHandlers) { + const std::string& command = pair.first; + auto handlers = pair.second; + m_CurrentCommandValues[command] = 0.f; + for (auto& handler : handlers) { + m_CurrentCommandValues[command] += handler->GetCommandValue(command); + } + + auto last = m_LastCommandValues.find(command); + float currentValue = m_CurrentCommandValues[command]; + if (last == m_LastCommandValues.end() || last->second != currentValue) { + Events::InputCommand e; + e.PlayerID = -1; + 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); + m_LastCommandValues[command] = currentValue; + } + } + + // Accumulate the input values of all unique commands published by input handlers + for (auto& pair : m_CommandQueue) { + Events::InputCommand e; + e.PlayerID = pair.first.first; + e.Command = pair.first.second; + e.Value = 0; + for (auto& value : pair.second) { + e.Value += value; + } + //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); + } + m_CommandQueue.clear(); +} + +void InputProxy::Publish(const Events::InputCommand& e) +{ + auto key = std::make_pair(e.PlayerID, e.Command); + m_CommandQueue[key].push_back(e.Value); +} + +bool InputProxy::OnBindOrigin(const Events::BindOrigin& e) +{ + bool originBound = false; + for (auto& handler : m_Handlers) { + bool result = handler->BindOrigin(e.Origin, e.Command, e.Value); + if (result) { + m_CommandHandlers[e.Command].insert(handler); + m_LastCommandValues[e.Command] = 0.f; + if (originBound) { + LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str()); + } + originBound = true; + } + } + + if (!originBound) { + LOG_ERROR("No input handler responded to binding input origin \"%s\"!", e.Origin.c_str()); + } + + return originBound; +} diff --git a/src/Engine/Input/InputSystem.cpp b/src/Engine/Input/InputSystem.cpp deleted file mode 100644 index d11cd73d..00000000 --- a/src/Engine/Input/InputSystem.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "PrecompiledHeader.h" -#include "Input/InputSystem.h" -#include "Core/World.h" - -void Systems::InputSystem::RegisterComponents(ComponentFactory* cf) -{ - -} - -void Systems::InputSystem::Initialize() -{ - // Subscribe to events - EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Systems::InputSystem::OnKeyDown); - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Systems::InputSystem::OnKeyUp); - EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &Systems::InputSystem::OnMousePress); - EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &Systems::InputSystem::OnMouseRelease); - EVENT_SUBSCRIBE_MEMBER(m_EGamepadAxis, &Systems::InputSystem::OnGamepadAxis); - EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonDown, &Systems::InputSystem::OnGamepadButtonDown); - EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonUp, &Systems::InputSystem::OnGamepadButtonUp); - EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &Systems::InputSystem::OnBindKey); - EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &Systems::InputSystem::OnBindMouseButton); - EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadAxis, &Systems::InputSystem::OnBindGamepadAxis); - EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadButton, &Systems::InputSystem::OnBindGamepadButton); -} - -void Systems::InputSystem::Update(double dt) -{ - -} - -bool Systems::InputSystem::OnKeyDown(const Events::KeyDown &event) -{ - auto range = m_KeyBindings.equal_range(event.KeyCode); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandKeyboardValues[command][event.KeyCode] = value; - PublishCommand(1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnKeyUp(const Events::KeyUp &event) -{ - auto range = m_KeyBindings.equal_range(event.KeyCode); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandKeyboardValues[command][event.KeyCode] = 0; - PublishCommand(1, command, GetCommandTotalValue(command));; - } - - return true; -} - -bool Systems::InputSystem::OnMousePress(const Events::MousePress &event) -{ - auto range = m_MouseButtonBindings.equal_range(event.Button); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandMouseButtonValues[command][event.Button] = value; - PublishCommand(1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnMouseRelease(const Events::MouseRelease &event) -{ - auto range = m_MouseButtonBindings.equal_range(event.Button); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandMouseButtonValues[command][event.Button] = 0; - PublishCommand(1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnGamepadAxis(const Events::GamepadAxis &event) -{ - auto range = m_GamepadAxisBindings.equal_range(event.Axis); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandGamepadAxisValues[command][event.Axis] = event.Value * value; - PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnGamepadButtonDown(const Events::GamepadButtonDown &event) -{ - auto range = m_GamepadButtonBindings.equal_range(event.Button); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandGamepadButtonValues[command][event.Button] = value; - PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnGamepadButtonUp(const Events::GamepadButtonUp &event) -{ - auto range = m_GamepadButtonBindings.equal_range(event.Button); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandGamepadButtonValues[command][event.Button] = 0; - PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnBindKey(const Events::BindKey &event) -{ - if (event.Command.empty()) { - return false; - } - - m_KeyBindings.insert(std::make_pair(event.KeyCode, std::make_tuple(event.Command, event.Value))); - LOG_DEBUG("Input: Bound key %i to %s", event.KeyCode, event.Command.c_str()); - - return true; -} - -bool Systems::InputSystem::OnBindMouseButton(const Events::BindMouseButton &event) -{ - if (event.Command.empty()) { - return false; - } - - m_MouseButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value))); - LOG_DEBUG("Input: Bound mouse button %i to %s", event.Button, event.Command.c_str()); - - return true; -} - -bool Systems::InputSystem::OnBindGamepadAxis(const Events::BindGamepadAxis &event) -{ - if (event.Command.empty()) { - return false; - } - - m_GamepadAxisBindings.insert(std::make_pair(event.Axis, std::make_tuple(event.Command, event.Value))); - LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Axis, event.Command.c_str()); - - return true; -} - -bool Systems::InputSystem::OnBindGamepadButton(const Events::BindGamepadButton &event) -{ - if (event.Command.empty()) { - return false; - } - - m_GamepadButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value))); - LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Button, event.Command.c_str()); - - return true; -} - -float Systems::InputSystem::GetCommandTotalValue(std::string command) -{ - float value = 0.f; - - auto keyboardIt = m_CommandKeyboardValues.find(command); - if (keyboardIt != m_CommandKeyboardValues.end()) { - for (auto &key : keyboardIt->second) { - value += key.second; - } - } - - auto mouseButtonIt = m_CommandMouseButtonValues.find(command); - if (mouseButtonIt != m_CommandMouseButtonValues.end()) { - for (auto &button : mouseButtonIt->second) { - value += button.second; - } - } - - auto gamepadAxisIt = m_CommandGamepadAxisValues.find(command); - if (gamepadAxisIt != m_CommandGamepadAxisValues.end()) { - for (auto &axis : gamepadAxisIt->second) { - value += axis.second; - } - } - - auto gamepadButtonIt = m_CommandGamepadButtonValues.find(command); - if (gamepadButtonIt != m_CommandGamepadButtonValues.end()) { - for (auto &button : gamepadButtonIt->second) { - value += button.second; - } - } - - return std::max(-1.f, std::min(value, 1.f)); -} - -void Systems::InputSystem::PublishCommand(int playerID, std::string command, float value) -{ - Events::InputCommand e; - e.PlayerID = playerID; - e.Command = command; - e.Value = value; - EventBroker->Publish(e); - - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, playerID); -} diff --git a/src/Engine/Input/KeyboardInputHandler.cpp b/src/Engine/Input/KeyboardInputHandler.cpp new file mode 100644 index 00000000..0a0994aa --- /dev/null +++ b/src/Engine/Input/KeyboardInputHandler.cpp @@ -0,0 +1,181 @@ +#include "Input/KeyboardInputHandler.h" + +KeyboardInputHandler::KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy) : InputHandler(eventBroker, inputProxy) +{ + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &KeyboardInputHandler::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &KeyboardInputHandler::OnKeyUp); + + m_OriginKeyCodes["Space"] = GLFW_KEY_SPACE; + m_OriginKeyCodes["Apostrophe"] = GLFW_KEY_APOSTROPHE; + m_OriginKeyCodes["Comma"] = GLFW_KEY_COMMA; + m_OriginKeyCodes["Minus"] = GLFW_KEY_MINUS; + m_OriginKeyCodes["Period"] = GLFW_KEY_PERIOD; + m_OriginKeyCodes["Slash"] = GLFW_KEY_SLASH; + m_OriginKeyCodes["0"] = GLFW_KEY_0; + m_OriginKeyCodes["1"] = GLFW_KEY_1; + m_OriginKeyCodes["2"] = GLFW_KEY_2; + m_OriginKeyCodes["3"] = GLFW_KEY_3; + m_OriginKeyCodes["4"] = GLFW_KEY_4; + m_OriginKeyCodes["5"] = GLFW_KEY_5; + m_OriginKeyCodes["6"] = GLFW_KEY_6; + m_OriginKeyCodes["7"] = GLFW_KEY_7; + m_OriginKeyCodes["8"] = GLFW_KEY_8; + m_OriginKeyCodes["9"] = GLFW_KEY_9; + m_OriginKeyCodes["Semicolon"] = GLFW_KEY_SEMICOLON; + m_OriginKeyCodes["Equal"] = GLFW_KEY_EQUAL; + m_OriginKeyCodes["A"] = GLFW_KEY_A; + m_OriginKeyCodes["B"] = GLFW_KEY_B; + m_OriginKeyCodes["C"] = GLFW_KEY_C; + m_OriginKeyCodes["D"] = GLFW_KEY_D; + m_OriginKeyCodes["E"] = GLFW_KEY_E; + m_OriginKeyCodes["F"] = GLFW_KEY_F; + m_OriginKeyCodes["G"] = GLFW_KEY_G; + m_OriginKeyCodes["H"] = GLFW_KEY_H; + m_OriginKeyCodes["I"] = GLFW_KEY_I; + m_OriginKeyCodes["J"] = GLFW_KEY_J; + m_OriginKeyCodes["K"] = GLFW_KEY_K; + m_OriginKeyCodes["L"] = GLFW_KEY_L; + m_OriginKeyCodes["M"] = GLFW_KEY_M; + m_OriginKeyCodes["N"] = GLFW_KEY_N; + m_OriginKeyCodes["O"] = GLFW_KEY_O; + m_OriginKeyCodes["P"] = GLFW_KEY_P; + m_OriginKeyCodes["Q"] = GLFW_KEY_Q; + m_OriginKeyCodes["R"] = GLFW_KEY_R; + m_OriginKeyCodes["S"] = GLFW_KEY_S; + m_OriginKeyCodes["T"] = GLFW_KEY_T; + m_OriginKeyCodes["U"] = GLFW_KEY_U; + m_OriginKeyCodes["V"] = GLFW_KEY_V; + m_OriginKeyCodes["W"] = GLFW_KEY_W; + m_OriginKeyCodes["X"] = GLFW_KEY_X; + m_OriginKeyCodes["Y"] = GLFW_KEY_Y; + m_OriginKeyCodes["Z"] = GLFW_KEY_Z; + m_OriginKeyCodes["LeftBracket"] = GLFW_KEY_LEFT_BRACKET; + m_OriginKeyCodes["Backslash"] = GLFW_KEY_BACKSLASH; + m_OriginKeyCodes["RightBracket"] = GLFW_KEY_RIGHT_BRACKET; + m_OriginKeyCodes["Accent"] = GLFW_KEY_GRAVE_ACCENT; + m_OriginKeyCodes["W1"] = GLFW_KEY_WORLD_1; + m_OriginKeyCodes["W2"] = GLFW_KEY_WORLD_2; + m_OriginKeyCodes["Escape"] = GLFW_KEY_ESCAPE; + m_OriginKeyCodes["Enter"] = GLFW_KEY_ENTER; + m_OriginKeyCodes["Tab"] = GLFW_KEY_TAB; + m_OriginKeyCodes["Backspace"] = GLFW_KEY_BACKSPACE; + m_OriginKeyCodes["Insert"] = GLFW_KEY_INSERT; + m_OriginKeyCodes["Delete"] = GLFW_KEY_DELETE; + m_OriginKeyCodes["Right"] = GLFW_KEY_RIGHT; + m_OriginKeyCodes["Left"] = GLFW_KEY_LEFT; + m_OriginKeyCodes["Down"] = GLFW_KEY_DOWN; + m_OriginKeyCodes["Up"] = GLFW_KEY_UP; + m_OriginKeyCodes["PgUp"] = GLFW_KEY_PAGE_UP; + m_OriginKeyCodes["PgDn"] = GLFW_KEY_PAGE_DOWN; + m_OriginKeyCodes["Home"] = GLFW_KEY_HOME; + m_OriginKeyCodes["End"] = GLFW_KEY_END; + m_OriginKeyCodes["CapsLock"] = GLFW_KEY_CAPS_LOCK; + m_OriginKeyCodes["ScrollLock"] = GLFW_KEY_SCROLL_LOCK; + m_OriginKeyCodes["NumLock"] = GLFW_KEY_NUM_LOCK; + m_OriginKeyCodes["PrintScreen"] = GLFW_KEY_PRINT_SCREEN; + m_OriginKeyCodes["Pause"] = GLFW_KEY_PAUSE; + m_OriginKeyCodes["F1"] = GLFW_KEY_F1; + m_OriginKeyCodes["F2"] = GLFW_KEY_F2; + m_OriginKeyCodes["F3"] = GLFW_KEY_F3; + m_OriginKeyCodes["F4"] = GLFW_KEY_F4; + m_OriginKeyCodes["F5"] = GLFW_KEY_F5; + m_OriginKeyCodes["F6"] = GLFW_KEY_F6; + m_OriginKeyCodes["F7"] = GLFW_KEY_F7; + m_OriginKeyCodes["F8"] = GLFW_KEY_F8; + m_OriginKeyCodes["F9"] = GLFW_KEY_F9; + m_OriginKeyCodes["F10"] = GLFW_KEY_F10; + m_OriginKeyCodes["F11"] = GLFW_KEY_F11; + m_OriginKeyCodes["F12"] = GLFW_KEY_F12; + m_OriginKeyCodes["F13"] = GLFW_KEY_F13; + m_OriginKeyCodes["F14"] = GLFW_KEY_F14; + m_OriginKeyCodes["F15"] = GLFW_KEY_F15; + m_OriginKeyCodes["F16"] = GLFW_KEY_F16; + m_OriginKeyCodes["F17"] = GLFW_KEY_F17; + m_OriginKeyCodes["F18"] = GLFW_KEY_F18; + m_OriginKeyCodes["F19"] = GLFW_KEY_F19; + m_OriginKeyCodes["F20"] = GLFW_KEY_F20; + m_OriginKeyCodes["F21"] = GLFW_KEY_F21; + m_OriginKeyCodes["F22"] = GLFW_KEY_F22; + m_OriginKeyCodes["F23"] = GLFW_KEY_F23; + m_OriginKeyCodes["F24"] = GLFW_KEY_F24; + m_OriginKeyCodes["F25"] = GLFW_KEY_F25; + m_OriginKeyCodes["KP0"] = GLFW_KEY_KP_0; + m_OriginKeyCodes["KP1"] = GLFW_KEY_KP_1; + m_OriginKeyCodes["KP2"] = GLFW_KEY_KP_2; + m_OriginKeyCodes["KP3"] = GLFW_KEY_KP_3; + m_OriginKeyCodes["KP4"] = GLFW_KEY_KP_4; + m_OriginKeyCodes["KP5"] = GLFW_KEY_KP_5; + m_OriginKeyCodes["KP6"] = GLFW_KEY_KP_6; + m_OriginKeyCodes["KP7"] = GLFW_KEY_KP_7; + m_OriginKeyCodes["KP8"] = GLFW_KEY_KP_8; + m_OriginKeyCodes["KP9"] = GLFW_KEY_KP_9; + m_OriginKeyCodes["KPDecimal"] = GLFW_KEY_KP_DECIMAL; + m_OriginKeyCodes["KPDivide"] = GLFW_KEY_KP_DIVIDE; + m_OriginKeyCodes["KPMultiply"] = GLFW_KEY_KP_MULTIPLY; + m_OriginKeyCodes["KPSubtract"] = GLFW_KEY_KP_SUBTRACT; + m_OriginKeyCodes["KPAdd"] = GLFW_KEY_KP_ADD; + m_OriginKeyCodes["KPEnter"] = GLFW_KEY_KP_ENTER; + m_OriginKeyCodes["KPEqual"] = GLFW_KEY_KP_EQUAL; + m_OriginKeyCodes["LeftShift"] = GLFW_KEY_LEFT_SHIFT; + m_OriginKeyCodes["LeftControl"] = GLFW_KEY_LEFT_CONTROL; + m_OriginKeyCodes["LeftAlt"] = GLFW_KEY_LEFT_ALT; + m_OriginKeyCodes["LeftSuper"] = GLFW_KEY_LEFT_SUPER; + m_OriginKeyCodes["RightShift"] = GLFW_KEY_RIGHT_SHIFT; + m_OriginKeyCodes["RightControl"] = GLFW_KEY_RIGHT_CONTROL; + m_OriginKeyCodes["RightAlt"] = GLFW_KEY_RIGHT_ALT; + m_OriginKeyCodes["RightSuper"] = GLFW_KEY_RIGHT_SUPER; + m_OriginKeyCodes["Menu"] = GLFW_KEY_MENU; +} + +bool KeyboardInputHandler::BindOrigin(std::string origin, std::string command, float value) +{ + auto originIt = m_OriginKeyCodes.find(origin); + if (originIt == m_OriginKeyCodes.end()) { + return false; + } + + int keyCode = originIt->second; + m_KeyBindings[keyCode] = std::make_tuple(command, value); + return true; +} + +bool KeyboardInputHandler::OnKeyDown(const Events::KeyDown& e) +{ + auto it = m_KeyBindings.find(e.KeyCode); + if (it == m_KeyBindings.end()) { + return false; + } + + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] += value; + + return true; +} + +bool KeyboardInputHandler::OnKeyUp(const Events::KeyUp& e) +{ + auto it = m_KeyBindings.find(e.KeyCode); + if (it == m_KeyBindings.end()) { + return false; + } + + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] -= value; + + return true; +} + +float KeyboardInputHandler::GetCommandValue(std::string command) +{ + auto it = m_CommandValues.find(command); + if (it != m_CommandValues.end()) { + return m_CommandValues[command]; + } else { + return 0.f; + } +} + diff --git a/src/Engine/Input/MouseInputHandler.cpp b/src/Engine/Input/MouseInputHandler.cpp new file mode 100644 index 00000000..5996b43d --- /dev/null +++ b/src/Engine/Input/MouseInputHandler.cpp @@ -0,0 +1,129 @@ +#include "Input/MouseInputHandler.h" + +MouseInputHandler::MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy) + : InputHandler(eventBroker, inputProxy) +{ + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &MouseInputHandler::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &MouseInputHandler::OnMouseRelease); + EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &MouseInputHandler::OnMouseMove); + + m_OriginCodes["Mouse1"] = GLFW_MOUSE_BUTTON_1; + m_OriginCodes["MouseLeft"] = GLFW_MOUSE_BUTTON_LEFT; + m_OriginCodes["Mouse2"] = GLFW_MOUSE_BUTTON_2; + m_OriginCodes["MouseRight"] = GLFW_MOUSE_BUTTON_RIGHT; + m_OriginCodes["Mouse3"] = GLFW_MOUSE_BUTTON_3; + m_OriginCodes["MouseMiddle"] = GLFW_MOUSE_BUTTON_MIDDLE; + m_OriginCodes["Mouse4"] = GLFW_MOUSE_BUTTON_4; + m_OriginCodes["Mouse5"] = GLFW_MOUSE_BUTTON_5; + m_OriginCodes["Mouse6"] = GLFW_MOUSE_BUTTON_6; + m_OriginCodes["Mouse7"] = GLFW_MOUSE_BUTTON_7; + m_OriginCodes["Mouse8"] = GLFW_MOUSE_BUTTON_8; + + m_OriginAxes["MouseX"] = 'X'; + m_OriginAxes["MouseY"] = 'Y'; +} + +bool MouseInputHandler::BindOrigin(std::string origin, std::string command, float value) +{ + auto originCode = m_OriginCodes.find(origin); + if (originCode != m_OriginCodes.end()) { + int code = originCode->second; + m_Bindings[code] = std::make_tuple(command, value); + return true; + } + + auto originAxis = m_OriginAxes.find(origin); + if (originAxis != m_OriginAxes.end()) { + char axis = originAxis->second; + float multiplier = 1.f; + // Sensitivity + multiplier *= ResourceManager::Load("Input.ini")->Get("Mouse.Sensitivity", 1.f); + if (axis == 'Y') { + if (ResourceManager::Load("Input.ini")->Get("Mouse.InvertPitch", false)) { + multiplier *= -1.f; + } + } + m_Axes[axis] = std::make_tuple(command, value * multiplier); + return true; + } + + return false; +} + +float MouseInputHandler::GetCommandValue(std::string command) +{ + auto it = m_CommandValues.find(command); + if (it != m_CommandValues.end()) { + return m_CommandValues[command]; + } else { + return 0.f; + } +} + +bool MouseInputHandler::OnMousePress(const Events::MousePress& e) +{ + auto it = m_Bindings.find(e.Button); + if (it == m_Bindings.end()) { + return false; + } + + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] += value; + + return true; +} + +bool MouseInputHandler::OnMouseRelease(const Events::MouseRelease& e) +{ + auto it = m_Bindings.find(e.Button); + if (it == m_Bindings.end()) { + return false; + } + + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] -= value; + + return true; +} + +bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e) +{ + if (std::abs(e.DeltaX) > 0) { + auto it = m_Axes.find('X'); + if (it != m_Axes.end()) { + Events::InputCommand ic; + ic.PlayerID = -1; + std::tie(ic.Command, ic.Value) = it->second; + ic.Value *= e.DeltaX; + m_InputProxy->Publish(ic); + } + } + + if (std::abs(e.DeltaY) > 0) { + auto it = m_Axes.find('Y'); + if (it != m_Axes.end()) { + Events::InputCommand ic; + ic.PlayerID = -1; + std::tie(ic.Command, ic.Value) = it->second; + ic.Value *= e.DeltaY; + m_InputProxy->Publish(ic); + } + } + + return true; +} + +bool MouseInputHandler::hasOrigin(std::string origin) +{ + if (m_OriginCodes.find(origin) == m_OriginCodes.end()) { + return false; + } + if (m_OriginAxes.find(origin) == m_OriginAxes.end()) { + return false; + } + return true; +} \ No newline at end of file diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp new file mode 100644 index 00000000..559a0f58 --- /dev/null +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -0,0 +1,66 @@ +#include "Rendering/DrawScenePass.h" + +DrawScenePass::DrawScenePass(IRenderer* renderer) +{ + m_Renderer = renderer; + InitializeTextures(); + InitializeShaderPrograms(); +} + +void DrawScenePass::InitializeTextures() +{ + m_WhiteTexture = ResourceManager::Load("Textures/Core/Blank.png"); +} + +void DrawScenePass::InitializeShaderPrograms() +{ + //Gör så att shaders är en resource, tex som texture classen. Konstruktorn måste vara privat. + m_BasicForwardProgram = ResourceManager::Load("#BasicForwardProgram"); + + m_BasicForwardProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/BasicForward.vert.glsl"))); + m_BasicForwardProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/BasicForward.frag.glsl"))); + m_BasicForwardProgram->Compile(); + m_BasicForwardProgram->Link(); + + +} + +void DrawScenePass::Draw(RenderQueueCollection& rq) +{ + //glBindFramebuffer(GL_FRAMEBUFFER, 0); + GLERROR("Renderer::Draw PickingPass"); + + DrawScenePassState state; + + + //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, "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())); + 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); + } + + 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/DrawScenePassState.cpp b/src/Engine/Rendering/DrawScenePassState.cpp new file mode 100644 index 00000000..59654775 --- /dev/null +++ b/src/Engine/Rendering/DrawScenePassState.cpp @@ -0,0 +1,18 @@ +#include "Rendering/DrawScenePassState.h" + + +DrawScenePassState::DrawScenePassState() +{ + GLERROR("---"); + BindBuffer(0); + GLERROR("---"); + Enable(GL_DEPTH_TEST); + Enable(GL_CULL_FACE); + ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f)); + Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +DrawScenePassState::~DrawScenePassState() +{ + +} diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 1b53d868..b2b29626 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -48,13 +48,21 @@ void FrameBuffer::Generate() switch ((*it)->m_ResourceType) { case GL_TEXTURE_2D: glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); + GLERROR("FrameBuffer generate: glFramebufferTexture2D"); + break; case GL_RENDERBUFFER: glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); + GLERROR("FrameBuffer generate: glFramebufferRenderbuffer"); + if ( (*it)->m_Attachment != GL_COLOR_ATTACHMENT0 || + (*it)->m_Attachment != GL_DEPTH_ATTACHMENT || + (*it)->m_Attachment != GL_STENCIL_ATTACHMENT) + { + LOG_ERROR("RenderBuffer Attachment not valid."); + } break; } - GLERROR("FrameBuffer generate"); if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) { attachments.push_back((*it)->m_Attachment); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp new file mode 100644 index 00000000..7d4cb66f --- /dev/null +++ b/src/Engine/Rendering/PickingPass.cpp @@ -0,0 +1,118 @@ +#include "Rendering/PickingPass.h" + +PickingPass::PickingPass(IRenderer* renderer, EventBroker* eb) +{ + m_Renderer = renderer; + m_EventBroker = eb; + + InitializeTextures(); + InitializeFrameBuffers(); + InitializeShaderPrograms(); +} + +PickingPass::~PickingPass() +{ + +} + +void PickingPass::InitializeTextures() +{ + GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, + glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE); +} + +void PickingPass::InitializeFrameBuffers() +{ + glGenRenderbuffers(1, &m_DepthBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + + m_PickingBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT))); + m_PickingBuffer.AddResource(std::shared_ptr(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0))); + m_PickingBuffer.Generate(); +} + +void PickingPass::InitializeShaderPrograms() +{ + m_PickingProgram = ResourceManager::Load("#PickingProgram"); + + m_PickingProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/Picking.vert.glsl"))); + m_PickingProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Picking.frag.glsl"))); + m_PickingProgram->Compile(); + m_PickingProgram->BindFragDataLocation(0, "TextureFragment"); + m_PickingProgram->Link(); +} + +void PickingPass::Draw(RenderQueueCollection& rq) +{ + m_PickingColorsToEntity.clear(); + PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); + + int r = 1; + int g = 0; + //TODO: Render: Add code for more jobs than modeljobs. + + GLuint ShaderHandle = m_PickingProgram->GetHandle(); + m_PickingProgram->Bind(); + + for (auto &job : rq.Forward) { + auto modelJob = std::dynamic_pointer_cast(job); + + if (modelJob) { + //--------------- + //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. + //--------------- + int pickColor[2] = { r, g }; + for (auto i : m_PickingColorsToEntity) { + if (modelJob->Entity == i.second) { + pickColor[0] = i.first.x; + pickColor[1] = i.first.y; + r -= 1; + } + } + 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())); + 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); + r += 1; + if (r > 255) { + r = 0; + g += 1; + } + } + } + m_PickingBuffer.Unbind(); + GLERROR("PickingPass Error"); + + //Publish pick event every frame with the pick data that can be picked by the event + Events::Picking pickEvent = Events::Picking( + &m_PickingBuffer, + &m_DepthBuffer, + m_Renderer->Camera()->ProjectionMatrix(), + m_Renderer->Camera()->ViewMatrix(), + m_Renderer->Resolution(), + &m_PickingColorsToEntity); + + m_EventBroker->Publish(pickEvent); +} + +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 + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution + GLERROR("Texture initialization failed"); +} diff --git a/src/Engine/Rendering/PickingPassState.cpp b/src/Engine/Rendering/PickingPassState.cpp new file mode 100644 index 00000000..a52fa546 --- /dev/null +++ b/src/Engine/Rendering/PickingPassState.cpp @@ -0,0 +1,20 @@ +#include "Rendering/PickingPassState.h" + + +PickingPassState::PickingPassState(GLuint frameBuffer) +{ + GLERROR("---2"); + BindBuffer(frameBuffer); + GLERROR("---3"); + Enable(GL_DEPTH_TEST); + Enable(GL_CULL_FACE); + + glm::vec4 clearColor = glm::vec4(0.f); + ClearColor(clearColor); + Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +PickingPassState::~PickingPassState() +{ + +} diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/src/Engine/Rendering/RenderQueueFactory.cpp index 81d7391e..4b82647c 100644 --- a/src/Engine/Rendering/RenderQueueFactory.cpp +++ b/src/Engine/Rendering/RenderQueueFactory.cpp @@ -30,7 +30,7 @@ glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity) do { ComponentWrapper transform = world->GetComponent(entity, "Transform"); - position += AbsoluteOrientation(world, entity) * (glm::vec3)transform["Position"]; + position += (glm::vec3)transform["Position"]; entity = world->GetParent(entity); } while (entity != 0); diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp new file mode 100644 index 00000000..017cb5b8 --- /dev/null +++ b/src/Engine/Rendering/RenderState.cpp @@ -0,0 +1,111 @@ +#include "Rendering/RenderState.h" + +RenderState::RenderState() +{ + +} + +bool RenderState::Enable(GLenum GLEnable) +{ + if(glIsEnabled(GLEnable)) + { + //LOG_WARNING("Trying to enable somthing that is already enabled."); + return false; + } + m_Enables.push_back(GLEnable); + glEnable(GLEnable); + if (GLERROR("RenderState::Enable")) + { + return false; + } + return true; +} + +bool RenderState::CullFace(GLenum GLCullFace) +{ + if(!glIsEnabled(GL_CULL_FACE)) + { + LOG_ERROR("Setting GL_CULL_FACE without enabling it."); + return false; + } + + GLint a; + glGetIntegerv(GL_CULL_FACE_MODE, &a); + if(a != GL_BACK) + { + //LOG_INFO("Setting Cullface to back, unessesary since this is already default."); + glCullFace(GLCullFace); + } + if (GLERROR("RenderState::CullFace")) + { + return false; + } + return true; +} + +bool RenderState::ClearColor(glm::vec4 color) +{ + glGetFloatv(GL_COLOR_CLEAR_VALUE, &m_preClearColor[0]); + glClearColor(color.r, color.g, color.b, color.a); + if (GLERROR("RenderState::ClearColor")) { + return false; + } + return true; +} + +bool RenderState::Clear(GLbitfield mask) +{ + glClear(mask); + if (GLERROR("RenderState::Clear")) { + return false; + } + return true; +} + +bool RenderState::BindBuffer(GLint buffer) +{ + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_preBuffer); + if (buffer == m_preBuffer) + { + return true; + } + glBindFramebuffer(GL_FRAMEBUFFER, buffer); + if (GLERROR("RenderState::BindBuffer")) + { + printf("BufferID: %i\npreBufferID: %i\n", buffer, m_preBuffer); + return false; + } + return true; +} + +RenderState::~RenderState() +{ + GLERROR("RenderState::~RenderState Pre"); + GLint n_buffer = -1; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &n_buffer); + + //Set cullface to default + if (glIsEnabled(GL_CULL_FACE)) { + glCullFace(GL_BACK); + } + GLERROR("RenderState::~RenderState glCullFace"); + + //Set color to default + glClearColor(m_preClearColor[0], m_preClearColor[1], m_preClearColor[2], m_preClearColor[3]); + GLERROR("RenderState::~RenderState glClearColor"); + + //Disable Enables + for (auto i : m_Enables) + { + glDisable(i); + } + GLERROR("RenderState::~RenderState glDisable"); + + if(m_preBuffer != 0) + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + m_Enables.clear(); + GLERROR("RenderState::~RenderState glBindFramebuffer"); +} + diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 6f4235d2..c4fa33c4 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -1,4 +1,5 @@ #include "Rendering/Renderer.h" +#include "Rendering/DebugCameraInputController.h" void Renderer::Initialize() { @@ -9,12 +10,14 @@ void Renderer::Initialize() if (m_Camera == nullptr) { m_Camera = m_DefaultCamera; } + TEMPCreateLights(); + InitializeRenderPasses(); glfwSwapInterval(m_VSYNC); InitializeShaders(); InitializeTextures(); - InitializeFrameBuffers(); - + InitializeSSBOs(); + //CalculateFrustum(); m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); @@ -63,26 +66,29 @@ void Renderer::InitializeWindow() void Renderer::InitializeShaders() { - m_BasicForwardProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/BasicForward.vert.glsl"))); - m_BasicForwardProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/BasicForward.frag.glsl"))); - m_BasicForwardProgram.Compile(); - m_BasicForwardProgram.Link(); + m_BasicForwardProgram = ResourceManager::Load("#m_BasicForwardProgram"); - m_PickingProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/Picking.vert.glsl"))); - m_PickingProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/Picking.frag.glsl"))); - m_PickingProgram.Compile(); - m_PickingProgram.BindFragDataLocation(0, "TextureFragment"); - m_PickingProgram.Link(); + m_DrawScreenQuadProgram = ResourceManager::Load("#DrawScreenQuadProgram"); + m_DrawScreenQuadProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/DrawScreenQuad.vert.glsl"))); + m_DrawScreenQuadProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl"))); + m_DrawScreenQuadProgram->Compile(); + m_DrawScreenQuadProgram->Link(); - m_DrawScreenQuadProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/DrawScreenQuad.vert.glsl"))); - 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) { + static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); + glm::vec3 m_Position = m_Camera->Position(); if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS) { @@ -112,164 +118,28 @@ void Renderer::InputUpdate(double dt) m_CameraMoveSpeed = 0.5f; } - - static double mousePosX, mousePosY; - glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); - - if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { - - - double deltaX, deltaY; - deltaX = mousePosX - (float)Resolution().Width / 2; - deltaY = mousePosY - (float)Resolution().Height / 2; - - float rotationY = -deltaY / 300.f; - float rotationX = -deltaX / 300.f; - glm::quat orientation = m_Camera->Orientation(); - - - orientation = orientation * glm::angleAxis(rotationY, glm::vec3(1, 0, 0)); - orientation = glm::angleAxis(rotationX, glm::vec3(0, 1, 0)) * orientation; - - m_Camera->SetOrientation(orientation); - - glfwSetCursorPos(m_Window, Resolution().Width / 2, Resolution().Height / 2); - } - m_Camera->SetPosition(m_Position); + firstPersonInputController.Update(dt); + m_Camera->SetOrientation(firstPersonInputController.Orientation()); + m_Camera->SetPosition(firstPersonInputController.Position()); } void Renderer::Update(double dt) { m_EventBroker->Process(); InputUpdate(dt); - } void Renderer::Draw(RenderQueueCollection& rq) { - //TODO: Renderer: Kanske borde vara längst upp i update. - PickingPass(rq); - DrawScreenQuad(m_PickingTexture); + m_PickingPass->Draw(rq); + //DrawScreenQuad(m_PickingPass->PickingTexture()); + //CullLights(); - DrawScene(rq); + m_DrawScenePass->Draw(rq); + GLERROR("Renderer::Draw m_DrawScenePass->Draw"); glfwSwapBuffers(m_Window); } -void Renderer::DrawScene(RenderQueueCollection& rq) -{ - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - //TODO: Render: Clean up draw code - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - - glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //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, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix)); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); - 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); - } - - 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"); -} - -void Renderer::PickingPass(RenderQueueCollection& rq) -{ - m_PickingColorsToEntity.clear(); - m_PickingBuffer.Bind(); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - - glClearColor(0.f, 0.f, 0.f, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - int r = 1; - int g = 0; - //TODO: Render: Add code for more jobs than modeljobs. - - - GLuint ShaderHandle = m_PickingProgram.GetHandle(); - m_PickingProgram.Bind(); - - for (auto &job : rq.Forward) { - auto modelJob = std::dynamic_pointer_cast(job); - - if (modelJob) { - //--------------- - //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. - //--------------- - int pickColor[2] = { r, g }; - for (auto i : m_PickingColorsToEntity) { - if(modelJob->Entity == i.second) { - pickColor[0] = i.first.x; - pickColor[1] = i.first.y; - r -= 1; - } - } - 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_Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); - 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, 0, modelJob->StartIndex); - r += 1; - if(r > 255) { - r = 0; - g += 1; - } - } - } - m_PickingBuffer.Unbind(); - GLERROR("PickingPass Error"); - - //Publish pick event every frame with the pick data that can be picked by the event - Events::Picking pickEvent = Events::Picking( - &m_PickingBuffer, - &m_DepthBuffer, - m_Camera->ProjectionMatrix(), - m_Camera->ViewMatrix(), - m_Resolution, - &m_PickingColorsToEntity); - - m_EventBroker->Publish(pickEvent); - -} - - void Renderer::DrawScreenQuad(GLuint textureToDraw) { glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -281,7 +151,7 @@ void Renderer::DrawScreenQuad(GLuint textureToDraw) glClear(GL_COLOR_BUFFER_BIT); - m_DrawScreenQuadProgram.Bind(); + m_DrawScreenQuadProgram->Bind(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureToDraw); @@ -291,24 +161,10 @@ void Renderer::DrawScreenQuad(GLuint textureToDraw) , GL_UNSIGNED_INT, 0, m_ScreenQuad->TextureGroups[0].StartIndex); } - void Renderer::InitializeTextures() { m_ErrorTexture=ResourceManager::Load("Textures/Core/ErrorTexture.png"); m_WhiteTexture=ResourceManager::Load("Textures/Core/Blank.png"); - /* - glGenTextures(1, &m_PickingTexture); - glBindTexture(GL_TEXTURE_2D, m_PickingTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, m_Resolution.Width, m_Resolution.Height, 0, GL_RG, GL_FLOAT, NULL);//TODO: Renderer: Fix the precision and Resolution - GLERROR("m_PickingTexture initialization failed"); - */ - - GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, - glm::vec2(m_Resolution.Width, m_Resolution.Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE); } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) @@ -323,15 +179,95 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin GLERROR("Texture initialization failed"); } - - -void Renderer::InitializeFrameBuffers()//TODO: Renderer: Get this to a better location, as its really big +void Renderer::InitializeSSBOs() { - glGenRenderbuffers(1, &m_DepthBuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Resolution.Width, m_Resolution.Height); + 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(); - m_PickingBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT))); - m_PickingBuffer.AddResource(std::shared_ptr(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0))); - m_PickingBuffer.Generate(); -} \ No newline at end of file + 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 0b5cc924..94c18bfe 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -6,6 +6,7 @@ Game::Game(int argc, char* argv[]) ResourceManager::RegisterType("Model"); ResourceManager::RegisterType("Texture"); ResourceManager::RegisterType("EntityXMLFile"); + ResourceManager::RegisterType("ShaderProgram"); m_Config = ResourceManager::Load("Config.ini"); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); @@ -26,9 +27,14 @@ 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))); // Create input manager m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); + m_InputProxy = new InputProxy(m_EventBroker); + m_InputProxy->AddHandler(); + m_InputProxy->AddHandler(); + m_InputProxy->LoadBindings("Input.ini"); // Create the root level GUI frame m_FrameStack = new GUI::Frame(m_EventBroker); @@ -55,7 +61,7 @@ Game::Game(int argc, char* argv[]) boost::thread workerThread(&Game::NetworkFunction, this); m_LastTime = glfwGetTime(); - testIntialize(); + debugInitialize(); } Game::~Game() @@ -74,22 +80,27 @@ void Game::Tick() double dt = currentTime - m_LastTime; m_LastTime = currentTime; + // Handle input in a weird looking but responsive way + m_EventBroker->Process(); m_EventBroker->Swap(); m_InputManager->Update(dt); m_EventBroker->Swap(); + m_InputProxy->Update(dt); + m_EventBroker->Swap(); + m_EventBroker->Clear(); + m_InputProxy->Process(); + m_EventBroker->Swap(); // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); - // DO SYSTEM SHIT HERE - m_EventBroker->Process(); - testTick(dt); + debugTick(dt); m_Renderer->Update(dt); + m_EventBroker->Process(); m_RenderQueueFactory->Update(m_World); - m_Renderer->Update(dt); - m_RenderQueueFactory->Update(m_World); + GLERROR("Game::Tick m_RenderQueueFactory->Update"); m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); - + GLERROR("Game::Tick m_Renderer->Draw"); m_EventBroker->Swap(); m_EventBroker->Clear(); @@ -97,9 +108,9 @@ void Game::Tick() } -bool Game::testOnKeyUp(const Events::KeyUp& e) +bool Game::debugOnInputCommand(const Events::InputCommand& e) { - if (e.KeyCode == GLFW_KEY_R) { + if (e.Command == "DebugReload" && e.Value == 1) { std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); if (!mapToLoad.empty()) { delete m_World; @@ -112,12 +123,12 @@ bool Game::testOnKeyUp(const Events::KeyUp& e) return false; } -void Game::testIntialize() +void Game::debugInitialize() { - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Game::testOnKeyUp); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); } -void Game::testTick(double dt) +void Game::debugTick(double dt) { m_EventBroker->Process(); } diff --git a/tools/deploy.bat b/tools/deploy.bat index 5ef074ef..22d513e6 100755 --- a/tools/deploy.bat +++ b/tools/deploy.bat @@ -21,6 +21,7 @@ RMDIR /S /Q "%DeployLocation%\Shaders" MKLINK "%DeployLocation%\Shaders\" "resources\Shaders" /J :: Configuration files MKLINK "%DeployLocation%\DefaultConfig.ini" "resources\DefaultConfig.ini" /H +MKLINK "%DeployLocation%\DefaultInput.ini" "resources\DefaultInput.ini" /H :: Platform specific binaries IF "%~1"=="" GOTO :EOF