Merge remote-tracking branch 'origin/master' into Networking

# Conflicts:
#	include/Game/Game.h
#	resources/DefaultConfig.ini
#	src/Game/Game.cpp
This commit is contained in:
stiffly
2015-12-14 17:07:12 +01:00
45 changed files with 1582 additions and 655 deletions
+19 -1
View File
@@ -5,6 +5,7 @@
#include <boost/filesystem.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/lexical_cast.hpp>
#include "../Common.h"
#include "ResourceManager.h"
@@ -19,12 +20,14 @@ private:
public:
template <typename T>
T Get(std::string key, T defaultValue);
template <typename T>
std::vector<std::pair<std::string, T>> GetAll(std::string key);
template <typename T>
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<T>(key, defaultValue);
}
template <typename T>
std::vector<std::pair<std::string, T>> ConfigFile::GetAll(std::string key)
{
std::vector<std::pair<std::string, T>> 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<T>(child.second.data());
out.push_back(std::make_pair(child.first, value));
}
return out;
}
template <typename T>
void ConfigFile::Set(std::string key, T value)
{
+4 -7
View File
@@ -11,25 +11,22 @@ template <typename EventContext>
class InputController
{
public:
InputController(std::shared_ptr<dd::EventBroker> 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<dd::EventBroker> EventBroker;
EventBroker* m_EventBroker;
private:
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
};
#endif
-24
View File
@@ -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;
};
}
-26
View File
@@ -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
-25
View File
@@ -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
-25
View File
@@ -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
+22
View File
@@ -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
+1 -1
View File
@@ -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;
};
}
@@ -0,0 +1,70 @@
#ifndef FirstPersonInputController_h__
#define FirstPersonInputController_h__
#include "../GLM.h"
#include "../Core/InputController.h"
#include "../Core/ELockMouse.h"
template <typename EventContext>
class FirstPersonInputController : public InputController<EventContext>
{
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<float>(-val, glm::vec3(1, 0, 0));
return true;
}
if (e.Command == "Yaw") {
float val = glm::radians(e.Value);
m_Orientation = glm::angleAxis<float>(-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<EventContext, Events::LockMouse> m_ELockMouse;
bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; }
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; }
};
#endif
+25
View File
@@ -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
+46
View File
@@ -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 <typename T>
void AddHandler();
void Publish(const Events::InputCommand& e);
protected:
EventBroker* m_EventBroker;
std::vector<InputHandler*> m_Handlers;
std::map<std::string, std::set<InputHandler*>> m_CommandHandlers;
// Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame
std::map<std::pair<unsigned int, std::string>, std::vector<float>> m_CommandQueue;
std::map<std::string, float> m_CurrentCommandValues;
std::map<std::string, float> m_LastCommandValues;
EventRelay<InputProxy, Events::BindOrigin> m_EBindOrigin;
bool OnBindOrigin(const Events::BindOrigin& e);
};
template <typename T>
void InputProxy::AddHandler()
{
m_Handlers.push_back(new T(m_EventBroker, this));
}
#endif
-78
View File
@@ -1,78 +0,0 @@
#ifndef InputSystem_h__
#define InputSystem_h__
#include <array>
#include <unordered_map>
#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<dd::EventBroker> eventBroker)
: System(world, eventBroker)
{ }
void RegisterComponents(ComponentFactory* cf) override;
void Initialize() override;
void Update(double dt) override;
private:
std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandKeyboardValues; // command string -> keyboard key value for command
std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandMouseButtonValues; // command string -> mouse button value for command
std::unordered_map<std::string, std::unordered_map<Gamepad::Axis, float, EnumClassHash>> m_CommandGamepadAxisValues; // command string -> gamepad axis value for command
std::unordered_map<std::string, std::unordered_map<Gamepad::Button, float, EnumClassHash>> m_CommandGamepadButtonValues; // command string -> gamepad button value for command
// Input binding tables
std::unordered_multimap<int, std::tuple<std::string, float>> m_KeyBindings; // GLFW_KEY... -> command string & value
std::unordered_multimap<int, std::tuple<std::string, float>> m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string
std::unordered_multimap<Gamepad::Axis, std::tuple<std::string, float>, EnumClassHash> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value
std::unordered_multimap<Gamepad::Button, std::tuple<std::string, float>, EnumClassHash> m_GamepadButtonBindings; // Gamepad::Button -> command string
// Input events
EventRelay<InputSystem, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown &event);
EventRelay<InputSystem, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp &event);
EventRelay<InputSystem, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress &event);
EventRelay<InputSystem, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease &event);
EventRelay<InputSystem, Events::GamepadAxis> m_EGamepadAxis;
bool OnGamepadAxis(const Events::GamepadAxis &event);
EventRelay<InputSystem, Events::GamepadButtonDown> m_EGamepadButtonDown;
bool OnGamepadButtonDown(const Events::GamepadButtonDown &event);
EventRelay<InputSystem, Events::GamepadButtonUp> m_EGamepadButtonUp;
bool OnGamepadButtonUp(const Events::GamepadButtonUp &event);
// Input binding events
EventRelay<InputSystem, Events::BindKey> m_EBindKey;
bool OnBindKey(const Events::BindKey &event);
EventRelay<InputSystem, Events::BindMouseButton> m_EBindMouseButton;
bool OnBindMouseButton(const Events::BindMouseButton &event);
EventRelay<InputSystem, Events::BindGamepadAxis> m_EBindGamepadAxis;
bool OnBindGamepadAxis(const Events::BindGamepadAxis &event);
EventRelay<InputSystem, Events::BindGamepadButton> m_EBindGamepadButton;
bool OnBindGamepadButton(const Events::BindGamepadButton &event);
float GetCommandTotalValue(std::string command);
void PublishCommand(int playerID, std::string command, float value);
};
}
#endif
@@ -0,0 +1,28 @@
#ifndef KeyboardInputHandler_h__
#define KeyboardInputHandler_h__
#include <GLFW/glfw3.h>
#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<std::string, int> m_OriginKeyCodes;
std::unordered_map<int, std::tuple<std::string, float>> m_KeyBindings; // GLFW_KEY... -> command string & value
std::unordered_map<std::string, float> m_CommandValues;
EventRelay<InputHandler, Events::KeyDown> m_EKeyDown;
bool OnKeyDown(const Events::KeyDown& e);
EventRelay<InputHandler, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp& e);
};
#endif
+38
View File
@@ -0,0 +1,38 @@
#ifndef MouseInputHandler_h__
#define MouseInputHandler_h__
#include <GLFW/glfw3.h>
#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<std::string, int> m_OriginCodes;
std::unordered_map<std::string, char> m_OriginAxes;
std::unordered_map<int, std::tuple<std::string, float>> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value
std::unordered_map<char, std::tuple<std::string, float>> m_Axes; // Axis -> command string & value
std::unordered_map<std::string, float> m_CommandValues;
std::unordered_map<std::string, float> m_ContinuousCommandValues;
EventRelay<InputHandler, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e);
EventRelay<InputHandler, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e);
EventRelay<InputHandler, Events::MouseMove> m_EMouseMove;
bool OnMouseMove(const Events::MouseMove& e);
bool hasOrigin(std::string origin);
};
#endif
@@ -0,0 +1,48 @@
#include "../Input/FirstPersonInputController.h"
template <typename EventContext>
class DebugCameraInputController : public FirstPersonInputController<EventContext>
{
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;
};
+36
View File
@@ -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
@@ -0,0 +1,15 @@
#ifndef DrawScenePassState_h__
#define DrawScenePassState_h__
#include "Rendering/RenderState.h"
class DrawScenePassState : public RenderState
{
public:
DrawScenePassState();
~DrawScenePassState();
private:
};
#endif
+49
View File
@@ -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<glm::vec2, EntityID>& 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<glm::vec2, EntityID> m_PickingColorsToEntity;
GLuint m_PickingTexture;
GLuint m_DepthBuffer;
FrameBuffer m_PickingBuffer;
};
#endif
@@ -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
+23
View File
@@ -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<GLenum> m_Enables;
float m_preClearColor[4];
int m_preBuffer;
};
#endif
+79 -21
View File
@@ -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<glm::vec2, EntityID> 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
+10 -3
View File
@@ -1,6 +1,9 @@
#ifndef ShaderProgram_h__
#define ShaderProgram_h__
#include "../Common.h"
#include "../OpenGL.h"
#include "../Core/ResourceManager.h"
#include <fstream>
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> shader);
@@ -79,3 +84,5 @@ private:
GLuint m_ShaderProgramHandle;
std::vector<std::shared_ptr<Shader>> m_Shaders;
};
#endif
+1 -1
View File
@@ -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;
}
+8 -4
View File
@@ -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<Game, Events::KeyUp> m_EKeyUp;
bool testOnKeyUp(const Events::KeyUp& e);
EventRelay<Game, Events::InputCommand> m_EInputCommand;
bool debugOnInputCommand(const Events::InputCommand& e);
void testIntialize();
void testTick(double dt);
void debugInitialize();
void debugTick(double dt);
EventRelay<Client, Events::KeyDown> m_EKeyDown;
};
+1
View File
@@ -13,5 +13,6 @@ VSYNC=false
Width=1280
Height=720
FOV=45
[Networking]
StartNetwork=false
+16
View File
@@ -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
+5 -17
View File
@@ -61,7 +61,7 @@
<Components>
<c:Transform>
<Position X="0" Y="0"/>
<Orientation X="0.0" Y="0" Z="0.0"/>
<Orientation X="0.0" Y="0" Z="1.0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitRaptor.obj</Resource>
@@ -72,8 +72,8 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0"/>
<Orientation X="0" Y="0" Z="0"/>
<Position X="-0.01" Y="0.55"/>
<Orientation X="0" Y="0" Z="-1"/>
</c:Transform>
<c:RaptorCopter>
<Speed>20</Speed>
@@ -84,19 +84,7 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.4"/>
<Scale X="0.1" Y="0.4" Z="0.1"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCylinder.obj</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.6"/>
<Position X="0" Y="0"/>
<Scale X="1.7" Y="0.03" Z="0.1"/>
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
@@ -109,7 +97,7 @@
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0.6"/>
<Position X="0" Y="0"/>
<Scale X="1.7" Y="0.03" Z="0.1"/>
<Orientation X="0" Y="1.57" Z="0"/>
</c:Transform>
+73
View File
@@ -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;
}
}
+35
View File
@@ -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) {
}
}
+1 -1
View File
@@ -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}
+5 -2
View File
@@ -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());
+112
View File
@@ -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<ConfigFile>(file);
for (auto& origin : config->GetAll<std::string>("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<InputProxy>();
m_EventBroker->Process<InputHandler>();
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;
}
-221
View File
@@ -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);
}
+181
View File
@@ -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;
}
}
+129
View File
@@ -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<ConfigFile>("Input.ini")->Get<float>("Mouse.Sensitivity", 1.f);
if (axis == 'Y') {
if (ResourceManager::Load<ConfigFile>("Input.ini")->Get<bool>("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;
}
+66
View File
@@ -0,0 +1,66 @@
#include "Rendering/DrawScenePass.h"
DrawScenePass::DrawScenePass(IRenderer* renderer)
{
m_Renderer = renderer;
InitializeTextures();
InitializeShaderPrograms();
}
void DrawScenePass::InitializeTextures()
{
m_WhiteTexture = ResourceManager::Load<Texture>("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<ShaderProgram>("#BasicForwardProgram");
m_BasicForwardProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/BasicForward.vert.glsl")));
m_BasicForwardProgram->AddShader(std::shared_ptr<Shader>(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<ModelJob>(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");
}
@@ -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()
{
}
+9 -1
View File
@@ -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);
+118
View File
@@ -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<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0)));
m_PickingBuffer.Generate();
}
void PickingPass::InitializeShaderPrograms()
{
m_PickingProgram = ResourceManager::Load<ShaderProgram>("#PickingProgram");
m_PickingProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Picking.vert.glsl")));
m_PickingProgram->AddShader(std::shared_ptr<Shader>(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<ModelJob>(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");
}
+20
View File
@@ -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()
{
}
+1 -1
View File
@@ -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);
+111
View File
@@ -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");
}
+120 -184
View File
@@ -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<Model>("Models/Core/ScreenQuad.obj");
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
@@ -63,26 +66,29 @@ void Renderer::InitializeWindow()
void Renderer::InitializeShaders()
{
m_BasicForwardProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/BasicForward.vert.glsl")));
m_BasicForwardProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/BasicForward.frag.glsl")));
m_BasicForwardProgram.Compile();
m_BasicForwardProgram.Link();
m_BasicForwardProgram = ResourceManager::Load<ShaderProgram>("#m_BasicForwardProgram");
m_PickingProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Picking.vert.glsl")));
m_PickingProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Picking.frag.glsl")));
m_PickingProgram.Compile();
m_PickingProgram.BindFragDataLocation(0, "TextureFragment");
m_PickingProgram.Link();
m_DrawScreenQuadProgram = ResourceManager::Load<ShaderProgram>("#DrawScreenQuadProgram");
m_DrawScreenQuadProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawScreenQuad.vert.glsl")));
m_DrawScreenQuadProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl")));
m_DrawScreenQuadProgram->Compile();
m_DrawScreenQuadProgram->Link();
m_DrawScreenQuadProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawScreenQuad.vert.glsl")));
m_DrawScreenQuadProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl")));
m_DrawScreenQuadProgram.Compile();
m_DrawScreenQuadProgram.Link();
//m_CalculateFrustumProgram = ResourceManager::Load<ShaderProgram>("#CalculateFrustumProgram");
//m_CalculateFrustumProgram.AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/GridFrustum.comp.glsl")));
//m_CalculateFrustumProgram.Compile();
//m_CalculateFrustumProgram.Link();
//m_LightCullProgram = ResourceManager::Load<ShaderProgram>("#LightCullProgram");
//m_LightCullProgram.AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/cullLights.comp.glsl")));
//m_LightCullProgram.Compile();
//m_LightCullProgram.Link();
}
void Renderer::InputUpdate(double dt)
{
static DebugCameraInputController<Renderer> 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<float>(rotationY, glm::vec3(1, 0, 0));
orientation = glm::angleAxis<float>(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<Renderer>();
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<ModelJob>(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<ModelJob>(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<Texture>("Textures/Core/ErrorTexture.png");
m_WhiteTexture=ResourceManager::Load<Texture>("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<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0)));
m_PickingBuffer.Generate();
}
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");
}
+23 -12
View File
@@ -6,6 +6,7 @@ Game::Game(int argc, char* argv[])
ResourceManager::RegisterType<Model>("Model");
ResourceManager::RegisterType<Texture>("Texture");
ResourceManager::RegisterType<EntityXMLFile>("EntityXMLFile");
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
@@ -26,9 +27,14 @@ Game::Game(int argc, char* argv[])
m_Config->Get<int>("Video.Height", 720)
));
m_Renderer->Initialize();
m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get<float>("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<KeyboardInputHandler>();
m_InputProxy->AddHandler<MouseInputHandler>();
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<InputManager>();
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<Client>();
testTick(dt);
debugTick(dt);
m_Renderer->Update(dt);
m_EventBroker->Process<Client>();
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<std::string>("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<Game>();
}
+1
View File
@@ -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