Initial structure

This commit is contained in:
2015-09-04 10:02:06 +02:00
commit 98e363eda6
457 changed files with 127943 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Components_Template_h__
#define Components_Template_h__
#include "Core/Component.h"
namespace dd
{
namespace Components
{
/** Template flag component.
A template entity is used as a blueprint for cloning. For example,
pre-defined particles that a particle emitter will clone and emit into the world.
Systems __MUST__ ignore entities with a Template component for general processing.
__Observe:__ Cloning an entity with a Template component will not remove the template component!
*/
struct Template : public Component { };
}
}
#endif // !Components_Template_h__
+50
View File
@@ -0,0 +1,50 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Components_Transform_h__
#define Components_Transform_h__
#include "Core/Component.h"
namespace dd
{
namespace Components
{
/** Spatial data of an entity. */
struct Transform : public Component
{
Transform()
: Scale(glm::vec3(1.f)) { }
/** Position in world coordinates (meters). */
glm::vec3 Position;
/** Orientation in quaternion form. */
glm::quat Orientation;
/** Current velocity of the entity in m/s. */
glm::vec3 Velocity;
/** Physical scale multiplier. */
glm::vec3 Scale;
};
}
}
#endif // Components_Transform_h__
+86
View File
@@ -0,0 +1,86 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Camera_h__
#define Camera_h__
namespace dd
{
class Camera
{
public:
/** Camera constructor.
@param aspectRatio Aspect ratio.
@param yFOV Vertical FOV.
@param nearClip Near clipping plane in meters.
@param farClip Far clipping plane in meters.
*/
Camera(float aspectRatio, float yFOV, float nearClip, float farClip);
/** Forward vector of the camera */
glm::vec3 Forward();
/** Right vector of the camera */
glm::vec3 Right();
glm::vec3 Position() const { return m_Position; }
void SetPosition(glm::vec3 val);
glm::quat Orientation() const { return m_Orientation; }
void SetOrientation(glm::quat val);
/*float Pitch() const { return m_Pitch; }
void Pitch(float val);
float Yaw() const { return m_Yaw; }
void Yaw(float val);*/
glm::mat4 ProjectionMatrix() const { return m_ProjectionMatrix; }
glm::mat4 ViewMatrix() const { return m_ViewMatrix; }
float AspectRatio() const { return m_AspectRatio; }
void SetAspectRatio(float val);
float FOV() const { return m_FOV; }
void SetFOV(float val);
float NearClip() const { return m_NearClip; }
void SetNearClip(float val);
float FarClip() const { return m_FarClip; }
void SetFarClip(float val);
private:
void UpdateViewMatrix();
void UpdateProjectionMatrix();
float m_AspectRatio;
float m_FOV;
float m_NearClip;
float m_FarClip;
glm::vec3 m_Position;
glm::quat m_Orientation;
glm::mat4 m_ProjectionMatrix;
glm::mat4 m_ViewMatrix;
};
}
#endif // Camera_h__
+34
View File
@@ -0,0 +1,34 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Color_h__
#define Color_h__
namespace dd
{
struct Color
{
float r;
float g;
float b;
};
}
#endif // !Color_h__
+37
View File
@@ -0,0 +1,37 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Component_h__
#define Component_h__
#include "Util/Factory.h"
#include "Core/Entity.h"
namespace dd
{
struct Component
{
EntityID Entity;
};
class ComponentFactory : public Factory<Component> { };
}
#endif // Component_h__
+45
View File
@@ -0,0 +1,45 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Event_ComponentCreated_h__
#define Event_ComponentCreated_h__
#include "EventBroker.h"
#include "Entity.h"
#include "Component.h"
namespace dd
{
namespace Events
{
/** Thrown when a new component is created and attached to an entity. */
struct ComponentCreated : Event
{
/** The entity the component was attached to. */
EntityID Entity;
/** Pointer to the newly created component. */
std::shared_ptr<dd::Component> Component;
};
}
}
#endif // Event_ComponentCreated_h__
+60
View File
@@ -0,0 +1,60 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Events_GamepadAxis_h__
#define Events_GamepadAxis_h__
#include "Core/EventBroker.h"
namespace dd
{
namespace Gamepad
{
/** Gamepad axis type */
enum class Axis
{
LeftX,
LeftY,
RightX,
RightY,
LeftTrigger,
RightTrigger,
LAST = RightTrigger
};
}
namespace Events
{
/** Thrown when a gamepad axis changes value */
struct GamepadAxis : Event
{
/** ID of the gamepad. */
int GamepadID;
/** The axis type. */
Gamepad::Axis Axis;
/** The new value of the axis. */
float Value;
};
}
}
#endif // Events_GamepadAxis_h__
+75
View File
@@ -0,0 +1,75 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Events_GamepadButton_h__
#define Events_GamepadButton_h__
#include "Core/EventBroker.h"
namespace dd
{
namespace Gamepad
{
/** Gamepad button type */
enum class Button
{
Up,
Down,
Left,
Right,
Start,
Back,
LeftThumb,
RightThumb,
LeftShoulder,
RightShoulder,
A,
B,
X,
Y,
LAST = Y
};
}
namespace Events
{
/** Thrown on gamepad button press. */
struct GamepadButtonDown : Event
{
/** ID of the gamepad. */
int GamepadID;
/** The button that was pressed. */
Gamepad::Button Button;
};
/** Thrown on gamepad button release. */
struct GamepadButtonUp : Event
{
/** ID of the gamepad. */
int GamepadID;
/** The button that was released. */
Gamepad::Button Button;
};
}
}
#endif // Events_GamepadButton_h__
+41
View File
@@ -0,0 +1,41 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Events_KeyDown_h__
#define Events_KeyDown_h__
#include "Core/EventBroker.h"
namespace dd
{
namespace Events
{
/** Thrown on key press. */
struct KeyDown : Event
{
/** GLFW key code */
int KeyCode;
};
}
}
#endif // Events_KeyDown_h__
+41
View File
@@ -0,0 +1,41 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Events_KeyUp_h__
#define Events_KeyUp_h__
#include "Core/EventBroker.h"
namespace dd
{
namespace Events
{
/** Thrown on key release. */
struct KeyUp : Event
{
/** GLFW key code */
int KeyCode;
};
}
}
#endif // Events_KeyUp_h__
+39
View File
@@ -0,0 +1,39 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Events_LockMouse_h__
#define Events_LockMouse_h__
#include "Core/EventBroker.h"
namespace dd
{
namespace Events
{
/** Called to lock mouse to the middle of the window. */
struct LockMouse : Event { };
/** Called to unlock mouse from the middle of the window. */
struct UnlockMouse : Event { };
}
}
#endif // Events_LockMouse_h__
+43
View File
@@ -0,0 +1,43 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Events_MouseMove_h__
#define Events_MouseMove_h__
#include "Core/EventBroker.h"
namespace dd
{
namespace Events
{
/** Thrown on mouse movement */
struct MouseMove : Event
{
/** The new position of the cursor in window coordinates. */
double X, Y;
/** The delta movement of the mouse. */
double DeltaX, DeltaY;
};
}
}
#endif // Events_MouseMove_h__
+43
View File
@@ -0,0 +1,43 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Events_MousePress_h__
#define Events_MousePress_h__
#include "Core/EventBroker.h"
namespace dd
{
namespace Events
{
/** Thrown on mouse button press. */
struct MousePress : Event
{
/** GLFW mouse button code */
int Button;
/** The click position in window coordinates. */
double X, Y;
};
}
}
#endif // Events_MousePress_h__
+43
View File
@@ -0,0 +1,43 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Events_MouseRelease_h__
#define Events_MouseRelease_h__
#include "Core/EventBroker.h"
namespace dd
{
namespace Events
{
/** Thrown on mouse button release. */
struct MouseRelease : Event
{
/** GLFW mouse button code */
int Button;
/** The mouse position in window coordinates. */
double X, Y;
};
}
}
#endif // Events_MouseRelease_h__
+181
View File
@@ -0,0 +1,181 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include <sstream>
#include "ResourceManager.h"
#include "OBJ.h"
#include "Model.h"
#include "Texture.h"
#include "EventBroker.h"
#include "RenderQueue.h"
#include "Renderer.h"
#include "InputManager.h"
//TODO: Remove includes that are only here for the temporary draw solution.
#include "World.h"
#include "CTransform.h"
#include "Rendering/CModel.h"
#include "CTemplate.h"
#include "Transform/TransformSystem.h"
namespace dd
{
class Engine
{
public:
Engine(int argc, char* argv[])
{
m_EventBroker = std::make_shared<EventBroker>();
m_Renderer = std::make_shared<Renderer>();
m_Renderer->SetFullscreen(false);
m_Renderer->SetResolution(Rectangle(0, 0, 1920, 1080));
m_Renderer->Initialize();
m_InputManager = std::make_shared<InputManager>(m_Renderer->Window(), m_EventBroker);
m_World = std::make_shared<World>(m_EventBroker);
//TODO: Move this out of engine.h
m_World->ComponentFactory.Register<Components::Transform>();
m_World->SystemFactory.Register<Systems::TransformSystem>([this]() { return new Systems::TransformSystem(m_World.get(), m_EventBroker); });
m_World->AddSystem<Systems::TransformSystem>();
m_World->ComponentFactory.Register<Components::Model>();
m_World->ComponentFactory.Register<Components::Template>();
m_World->Initialize();
auto ent = m_World->CreateEntity();
std::shared_ptr<Components::Transform> transform = m_World->AddComponent<Components::Transform>(ent);
transform->Position = glm::vec3(0.f, 0.f, -10.f);
std::shared_ptr<Components::Model> model = m_World->AddComponent<Components::Model>(ent);
model->ModelFile = "Models/Core/UnitSphere.obj";
m_LastTime = glfwGetTime();
}
bool Running() const { return !glfwWindowShouldClose(m_Renderer->Window()); }
void Tick()
{
double currentTime = glfwGetTime();
double dt = currentTime - m_LastTime;
m_LastTime = currentTime;
ResourceManager::Update();
// Update input
m_InputManager->Update(dt);
m_World->Update(dt);
if (glfwGetKey(m_Renderer->Window(), GLFW_KEY_R)) {
ResourceManager::Reload("Shaders/Deferred/3/Fragment.glsl");
}
//TODO Fill up the renderQueue with models (Temp fix)
TEMPAddToRenderQueue();
// Render scene
//TODO send renderqueue to draw.
m_Renderer->Draw(m_RendererQueue);
// Swap event queues
m_EventBroker->Clear();
glfwPollEvents();
}
std::shared_ptr<Systems::TransformSystem> m_TransformSystem;
//TODO: Get this out of engine.h
void TEMPAddToRenderQueue()
{
if (!m_TransformSystem)
m_TransformSystem = m_World->GetSystem<Systems::TransformSystem>();
m_RendererQueue.Clear();
for (auto &pair : *m_World->GetEntities())
{
EntityID entity = pair.first;
auto templateComponent = m_World->GetComponent<Components::Template>(entity);
if (templateComponent)
continue;
auto transform = m_World->GetComponent<Components::Transform>(entity);
if (!transform)
continue;
auto modelComponent = m_World->GetComponent<Components::Model>(entity);
if (modelComponent)
{
Model* modelAsset = nullptr;
modelAsset = ResourceManager::Load<Model>(modelComponent->ModelFile);
if (modelAsset)
{
Components::Transform absoluteTransform = m_TransformSystem->AbsoluteTransform(entity);
glm::mat4 modelMatrix = glm::translate(glm::mat4(), absoluteTransform.Position)
* glm::toMat4(absoluteTransform.Orientation)
* glm::scale(absoluteTransform.Scale);
EnqueueModel(modelAsset, modelMatrix, modelComponent->Transparent, modelComponent->Color);
}
}
}
m_RendererQueue.Sort();
}
//TODO: Get this out of engine.h
void EnqueueModel(Model* model, glm::mat4 modelMatrix, float transparent, glm::vec4 color)
{
for (auto texGroup : model->TextureGroups)
{
ModelJob job;
job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0;
job.DiffuseTexture = (texGroup.Texture) ? *texGroup.Texture : 0;
job.NormalTexture = (texGroup.NormalMap) ? *texGroup.NormalMap : 0;
job.SpecularTexture = (texGroup.SpecularMap) ? *texGroup.SpecularMap : 0;
job.VAO = model->VAO;
job.ElementBuffer = model->ElementBuffer;
job.StartIndex = texGroup.StartIndex;
job.EndIndex = texGroup.EndIndex;
job.ModelMatrix = modelMatrix;
job.Color = color;
m_RendererQueue.Deferred.Add(job);
}
}
private:
//std::shared_ptr<ResourceManager> m_ResourceManager;
std::shared_ptr<EventBroker> m_EventBroker;
std::shared_ptr<Renderer> m_Renderer;
RenderQueueCollection m_RendererQueue;
std::shared_ptr<InputManager> m_InputManager;
std::shared_ptr<World> m_World;
double m_LastTime;
};
}
+19
View File
@@ -0,0 +1,19 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
typedef unsigned int EntityID;
+168
View File
@@ -0,0 +1,168 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MessageRelay_h__
#define MessageRelay_h__
#include <typeinfo>
#include <functional>
#include <map>
#include <unordered_map>
#include <list>
#define EVENT_SUBSCRIBE_MEMBER(relay, handler) \
relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \
EventBroker->Subscribe(relay);
namespace dd
{
struct Event
{
protected:
Event() { }
};
class EventBroker;
class BaseEventRelay
{
friend class EventBroker;
protected:
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName)
, m_Broker(nullptr) { }
~BaseEventRelay();
public:
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
protected:
std::string m_ContextTypeName;
std::string m_EventTypeName;
EventBroker* m_Broker;
};
template <typename ContextType, typename EventType>
class EventRelay : public BaseEventRelay
{
public:
typedef std::function<bool(const EventType&)> CallbackType;
EventRelay()
: m_Callback(nullptr)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) { }
EventRelay(CallbackType callback)
: m_Callback(callback)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) { }
protected:
bool Receive(const std::shared_ptr<Event> event) override;
private:
CallbackType m_Callback;
};
template <typename ContextType, typename EventType>
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
{
if (m_Callback != nullptr)
{
return m_Callback(*static_cast<const EventType*>(event.get()));
}
else
{
return false;
}
}
class EventBroker
{
template <typename ContextType, typename EventType> friend class EventRelay;
public:
EventBroker()
{
m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>();
}
void Subscribe(BaseEventRelay &relay);
template <typename EventType>
void Publish(const EventType &event);
// Process all events no matter the context.
/*void Process()
{
}*/
/*
Process all events in a given context.
Returns: Number of events processed
*/
template <typename ContextType>
int Process();
int Process(std::string contextTypeName);
void Clear();
void Unsubscribe(BaseEventRelay &relay);
template <typename ContextType>
void UnsubscribeAll();
private:
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
typedef std::string EventTypeName_t; // typeid(EventType).name()
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
ContextRelays_t m_ContextRelays;
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
std::shared_ptr<EventQueue_t> m_EventQueueRead;
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
};
template <typename EventType>
void EventBroker::Publish(const EventType &event)
{
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
for (auto it = itpair.first; it != itpair.second; ++it)
{
it->second->Receive(event);
}*/
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
}
template <typename ContextType>
int EventBroker::Process()
{
const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName);
}
template <typename ContextType>
void EventBroker::UnsubscribeAll()
{
const std::string contextTypeName = typeid(ContextType).name();
m_ContextRelays.erase(contextTypeName);
}
}
#endif // MessageRelay_h__
+42
View File
@@ -0,0 +1,42 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Image_h
#define Image_h
namespace dd
{
struct Image
{
enum class ImageFormat
{
Unknown,
RGB,
RGBA
};
unsigned int Width = 0;
unsigned int Height = 0;
ImageFormat Format = ImageFormat::Unknown;
unsigned char* Data = nullptr;
};
}
#endif
+89
View File
@@ -0,0 +1,89 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef InputController_h__
#define InputController_h__
#include <memory>
#include "EventBroker.h"
#include "EMouseMove.h"
#include "Input/EInputCommand.h"
namespace dd
{
template <typename EventContext>
class InputController
{
public:
InputController(std::shared_ptr<dd::EventBroker> eventBroker)
: EventBroker(eventBroker)
, InGame(true)
{ Initialize(); }
virtual void Initialize()
{
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &InputController::_OnCommand);
EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &InputController::_OnMouseMove);
EVENT_SUBSCRIBE_MEMBER(m_EGameStart, &InputController::OnGameStart);
EVENT_SUBSCRIBE_MEMBER(m_EGameOver, &InputController::OnGameOver);
}
virtual bool OnCommand(const Events::InputCommand &event) { return false; }
virtual bool OnMouseMove(const Events::MouseMove &event) { return false; }
virtual bool OnGameStart(const Events::GameStart &event)
{
InGame = true;
return true;
}
virtual bool OnGameOver(const Events::GameOver &event)
{
InGame = false;
return true;
}
protected:
std::shared_ptr<dd::EventBroker> EventBroker;
bool InGame;
private:
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
EventRelay<EventContext, Events::GameStart> m_EGameStart;
EventRelay<EventContext, Events::GameOver> m_EGameOver;
virtual bool _OnCommand(const Events::InputCommand &event)
{
if (InGame || event.Value == 0)
return OnCommand(event);
else
return false;
}
virtual bool _OnMouseMove(const Events::MouseMove &event)
{
if (InGame)
return OnMouseMove(event);
else
return false;
}
};
}
#endif // InputController_h__
+90
View File
@@ -0,0 +1,90 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef InputManager_h__
#define InputManager_h__
#include <array>
#include "Core/EventBroker.h"
#include "EKeyDown.h"
#include "EKeyUp.h"
#include "EMousePress.h"
#include "EMouseRelease.h"
#include "EMouseMove.h"
#include "ELockMouse.h"
#include "EGamepadAxis.h"
#include "EGamepadButton.h"
namespace dd
{
class InputManager
{
public:
InputManager(GLFWwindow* window, std::shared_ptr<dd::EventBroker> eventBroker)
: m_GLFWWindow(window)
, EventBroker(eventBroker)
, m_CurrentKeyState()
, m_LastKeyState()
, m_CurrentMouseState()
, m_LastMouseState()
, m_CurrentMouseX(0), m_CurrentMouseY(0)
, m_LastMouseX(0), m_LastMouseY(0)
, m_CurrentMouseDeltaX(0), m_CurrentMouseDeltaY(0)
, m_MouseLocked(false)
{ Initialize(); }
void Initialize();
static const short MAX_GAMEPADS = 4;
void Update(double dt);
private:
GLFWwindow* m_GLFWWindow;
std::shared_ptr<dd::EventBroker> EventBroker;
EventRelay<InputManager, Events::LockMouse> m_ELockMouse;
bool OnLockMouse(const Events::LockMouse &event);
EventRelay<InputManager, Events::UnlockMouse> m_EUnlockMouse;
bool OnUnlockMouse(const Events::UnlockMouse &event);
std::array<int, GLFW_KEY_LAST+1> m_CurrentKeyState;
std::array<int, GLFW_KEY_LAST+1> m_LastKeyState;
std::array<int, GLFW_MOUSE_BUTTON_LAST+1> m_CurrentMouseState;
std::array<int, GLFW_MOUSE_BUTTON_LAST+1> m_LastMouseState;
typedef std::array<float, static_cast<int>(Gamepad::Axis::LAST) + 1> GamepadAxisState;
std::array<GamepadAxisState, MAX_GAMEPADS> m_CurrentGamepadAxisState;
std::array<GamepadAxisState, MAX_GAMEPADS> m_LastGamepadAxisState;
typedef std::array<bool, static_cast<int>(Gamepad::Button::LAST) + 1> GamepadButtonState;
std::array<GamepadButtonState, MAX_GAMEPADS> m_CurrentGamepadButtonState;
std::array<GamepadButtonState, MAX_GAMEPADS> m_LastGamepadButtonState;
double m_CurrentMouseX, m_CurrentMouseY;
double m_LastMouseX, m_LastMouseY;
double m_CurrentMouseDeltaX, m_CurrentMouseDeltaY;
bool m_MouseLocked;
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
};
}
#endif // InputManager_h__
+112
View File
@@ -0,0 +1,112 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Model_h__
#define Model_h__
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <memory>
#include <cstdlib>
#include <stack>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <boost/filesystem/path.hpp>
#include "Core/ResourceManager.h"
#include "Core/Texture.h"
#include "Core/Skeleton.h"
namespace dd
{
class Model : public Resource
{
friend class ResourceManager;
private:
Model(std::string fileName);
public:
~Model();
struct Vertex
{
glm::vec3 Position;
glm::vec3 Normal;
glm::vec3 Tangent;
glm::vec3 BiTangent;
glm::vec2 TextureCoords;
glm::vec4 DiffuseVertexColor;
glm::vec4 SpecularVertexColor;
glm::vec4 BoneIndices1;
glm::vec4 BoneIndices2;
glm::vec4 BoneWeights1;
glm::vec4 BoneWeights2;
};
struct MaterialGroup
{
float Shininess;
std::shared_ptr<dd::Texture> Texture;
std::shared_ptr<dd::Texture> NormalMap;
std::shared_ptr<dd::Texture> SpecularMap;
unsigned int StartIndex;
unsigned int EndIndex;
};
GLuint VAO;
GLuint ElementBuffer;
std::vector<MaterialGroup> TextureGroups;
std::vector<std::shared_ptr<Texture>> texture;
glm::mat4 GetMatrix();
std::vector<glm::vec3> Vertices;
std::vector<Vertex> m_Vertices;
std::vector<unsigned int> m_Indices;
Skeleton* m_Skeleton = nullptr;
private:
std::vector<glm::ivec2> BoneIndices;
std::vector<glm::vec2> BoneWeights;
std::vector<glm::vec3> Normals;
std::vector<glm::vec4> DiffuseVertexColor;
std::vector<glm::vec4> SpecularVertexColor;
std::vector<glm::vec3> TangentNormals;
std::vector<glm::vec3> BiTangentNormals;
std::vector<glm::vec2> TextureCoords;
GLuint VertexBuffer;
GLuint DiffuseVertexColorBuffer;
GLuint SpecularVertexColorBuffer;
GLuint NormalBuffer;
GLuint TangentNormalsBuffer;
GLuint BiTangentNormalsBuffer;
GLuint TextureCoordBuffer;
void CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID);
};
}
#endif // Model_h__
+150
View File
@@ -0,0 +1,150 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OBJ_h__
#define OBJ_h__
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <tuple>
#include <map>
#include <boost/filesystem/path.hpp>
#include <boost/program_options.hpp>
#include "ResourceManager.h"
namespace dd
{
class OBJ : public Resource
{
public:
struct MaterialInfo
{
struct TextureMap
{
TextureMap()
: blendu(true)
, blendv(true)
, clamp(false)
, o(std::make_tuple(0.f, 0.f, 0.f))
, s(std::make_tuple(1.f, 1.f, 1.f)) { }
std::string FileName;
// http://paulbourke.net/dataformats/mtl/
// "These options are described in detail in 'Options for texture map statements' on page 5-18."
// Horizontal texture blending
bool blendu; // = true
// Vertical texture blending
bool blendv; // = true
// Clamping
bool clamp; // = false
// Offset
std::tuple<float, float, float> o; // = (0, 0, 0)
// Scale
std::tuple<float, float, float> s; // = (1, 1, 1)
};
struct ColorMap : public TextureMap
{
ColorMap()
: cc(false) { }
// Color correction
bool cc; // = false
};
struct BumpMap : public TextureMap
{
BumpMap()
: bm(1.f) { }
// Bump multiplier
float bm; // = 1?
};
MaterialInfo()
: AmbientColor(std::make_tuple(0.2f, 0.2f, 0.2f))
, DiffuseColor(std::make_tuple(0.8f, 0.8f, 0.8f))
, SpecularColor(std::make_tuple(1.0f, 1.0f, 1.0f))
, TransmissionFilter(std::make_tuple(1.0f, 1.0f, 1.0f))
, OpticalDensity(1.0f)
, Alpha(1.0f)
, Shininess(0.0f)
, IlluminationModel(0) { }
ColorMap DiffuseTexture;
ColorMap SpecularMap;
BumpMap NormalMap;
std::tuple<float, float, float> AmbientColor; // = (0.2, 0.2, 0.2)
std::tuple<float, float, float> DiffuseColor; // = (0.8, 0.8, 0.8)
std::tuple<float, float, float> SpecularColor; // = (1, 1, 1)
std::tuple<float, float, float> TransmissionFilter; // = (1, 1, 1)
float OpticalDensity; // = 1
float Alpha; // = 1
float Shininess; // = 0
int IlluminationModel; // = 0
};
struct FaceDefinition
{
int VertexIndex;
int TextureCoordIndex;
int NormalIndex;
};
struct Face
{
Face() : Material(nullptr) { }
std::vector<FaceDefinition> Definitions;
MaterialInfo* Material;
};
OBJ() : m_CurrentMaterial(nullptr) { }
OBJ(std::string filename) : m_CurrentMaterial(nullptr) { LoadFromFile(filename); }
static OBJ* Create(std::string resourceName) { return new OBJ(resourceName); }
std::vector<std::tuple<float, float, float>> Vertices;
std::vector<std::tuple<float, float, float>> Normals;
std::vector<std::tuple<float, float, float>> TextureCoords;
std::vector<Face> Faces;
std::map<std::string, MaterialInfo> Materials;
bool LoadFromFile(std::string filename);
boost::filesystem::path Path() const { return m_Path; }
private:
boost::filesystem::path m_Path;
boost::filesystem::path m_MaterialPath;
MaterialInfo* m_CurrentMaterial;
void ParseMaterial();
void ParseTextureMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::TextureMap &textureMap);
void ParseColorMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::ColorMap &textureMap);
void ParseBumpMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::BumpMap &textureMap);
};
}
#endif // OBJ_h__
+43
View File
@@ -0,0 +1,43 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PNG_h_
#define PNG_h_
#include <stdexcept>
#include <png.h>
#include "Image.h"
namespace dd
{
class PNG : public Image
{
public:
PNG(std::string path);
~PNG();
private:
};
}
#endif
+170
View File
@@ -0,0 +1,170 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RenderQueue_h__
#define RenderQueue_h__
#include <cstdint>
#include <forward_list>
#include "Texture.h"
#include "Model.h"
namespace dd
{
class RenderQueue;
struct RenderJob
{
friend class RenderQueue;
float Depth;
protected:
uint64_t Hash;
virtual void CalculateHash() = 0;
bool operator<(const RenderJob& rhs)
{
return this->Hash < rhs.Hash;
}
};
struct ModelJob : RenderJob
{
unsigned int ShaderID;
unsigned int TextureID;
glm::mat4 ModelMatrix;
GLuint DiffuseTexture;
GLuint NormalTexture;
GLuint SpecularTexture;
float Shininess;
glm::vec4 Color;
GLuint VAO;
GLuint ElementBuffer;
unsigned int StartIndex;
unsigned int EndIndex;
void CalculateHash() override
{
Hash = TextureID;
}
};
struct BlendMapModelJob : ModelJob
{
GLuint BlendMapTextureRed;
GLuint BlendMapTextureRedNormal;
GLuint BlendMapTextureRedSpecular;
GLuint BlendMapTextureGreen;
GLuint BlendMapTextureGreenNormal;
GLuint BlendMapTextureGreenSpecular;
GLuint BlendMapTextureBlue;
GLuint BlendMapTextureBlueNormal;
GLuint BlendMapTextureBlueSpecular;
float TextureRepeat;
};
struct SpriteJob : RenderJob
{
unsigned int ShaderID;
unsigned int TextureID;
glm::mat4 ModelMatrix;
GLuint Texture;
glm::vec4 Color;
void CalculateHash() override
{
Hash = TextureID;
}
};
struct PointLightJob : RenderJob
{
glm::vec3 Position;
glm::vec3 SpecularColor = glm::vec3(1, 1, 1);
glm::vec3 DiffuseColor = glm::vec3(1, 1, 1);
float Radius = 1.f;
void CalculateHash() override
{
Hash = 0;
}
};
class RenderQueue
{
public:
template <typename T>
void Add(T &job)
{
job.CalculateHash();
Jobs.push_front(std::shared_ptr<T>(new T(job)));
}
void Sort()
{
Jobs.sort();
}
void Clear()
{
Jobs.clear();
}
std::forward_list<std::shared_ptr<RenderJob>>::const_iterator begin()
{
return Jobs.begin();
}
std::forward_list<std::shared_ptr<RenderJob>>::const_iterator end()
{
return Jobs.end();
}
std::forward_list<std::shared_ptr<RenderJob>> Jobs;
};
struct RenderQueueCollection
{
RenderQueue Deferred;
RenderQueue Forward;
RenderQueue Lights;
void Clear()
{
Deferred.Clear();
Forward.Clear();
Lights.Clear();
}
void Sort()
{
Deferred.Sort();
Forward.Sort();
Lights.Sort();
}
};
}
#endif // RenderQueue_h__
+104
View File
@@ -0,0 +1,104 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Renderer_h__
#define Renderer_h__
#include "Util/Rectangle.h"
#include "Camera.h"
#include "RenderQueue.h"
#include "ShaderProgram.h"
namespace dd
{
class Renderer
{
public:
//Render();
GLFWwindow* Window() const { return m_Window; }
Rectangle Resolution() const { return m_Resolution; }
void SetResolution(const Rectangle& resolution) { m_Resolution = resolution; }
bool Fullscreen() { return m_Fullscreen; }
void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; }
bool VSYNC() const { return m_VSYNC; }
void SetVSYNC(bool vsync) { m_VSYNC = vsync; }
//void SetViewport(const Rectangle& viewport) { m_Viewport = viewport; }
//void SetScissor(const Rectangle& scissor) { m_Scissor = scissor; }
const dd::Camera* Camera() const { return m_Camera; }
void SetCamera(const dd::Camera* camera)
{
if (camera == nullptr) {
m_Camera = m_DefaultCamera.get();
} else {
m_Camera = camera;
}
}
void Initialize();
void Draw(RenderQueueCollection& rq);
private:
Rectangle m_Resolution = Rectangle(1280, 720);
bool m_Fullscreen = false;
bool m_VSYNC = false;
//Rectangle m_Viewport;
//Rectangle m_Scissor;
std::unique_ptr<dd::Camera> m_DefaultCamera = nullptr;
const dd::Camera* m_Camera = nullptr;
int m_GLVersion[2];
std::string m_GLVendor;
GLFWwindow* m_Window = nullptr;
ShaderProgram* m_spDeferred1;
ShaderProgram* m_spDeferred2;
ShaderProgram* m_spDeferred3;
ShaderProgram* m_spForward;
ShaderProgram* m_spScreen;
GLuint m_UnitQuad = 0;
Model* m_UnitSphere = nullptr;
GLuint m_rbDepthBuffer = 0;
GLuint m_fbDeferred1 = 0;
GLuint m_GDiffuse = 0;
GLuint m_GPosition = 0;
GLuint m_GNormal = 0;
GLuint m_GSpecular = 0;
GLuint m_fbDeferred2 = 0;
GLuint m_tLighting = 0;
GLuint m_fbDeferred3 = 0;
GLuint m_tFinal = 0;
GLuint m_CurrentScreenBuffer = 0;
void LoadShaders();
void CreateBuffers();
GLuint CreateQuad();
void DrawDeferred(RenderQueue &objects, RenderQueue &lights);
void DrawForward(RenderQueue &objects, RenderQueue &lights);
void DrawScene(RenderQueue &objects, ShaderProgram &program);
void DrawLightSpheres(RenderQueue &lights);
void DebugKeys();
};
}
#endif // Renderer_h__
+234
View File
@@ -0,0 +1,234 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ResourceManager_h__
#define ResourceManager_h__
#include <string>
#include <functional>
#include <vector>
#include <unordered_map>
#include "Util/UnorderedMapPair.h"
#include "Util/Factory.h"
#include "Util/FileWatcher.h"
namespace dd
{
/** Base Resource class.
Implement this class for every resource to be handled by the resource manager.
Implement Create() to return a new object of that type.
*/
class Resource
{
friend class ResourceManager;
protected:
Resource() { }
public:
// Pretend that this is a pure virtual function that you have to implement
// FIXME: Why did we do this again instead of just using the constructor?
// static Resource* Create(std::string resourceName);
virtual void Reload() { }
virtual void OnChildReloaded(Resource* child) { }
unsigned int TypeID;
unsigned int ResourceID;
};
/** Singleton resource manager to keep track of and cache any external engine assets */
class ResourceManager
{
private:
ResourceManager();
public:
/*static ResourceManager& Instance()
{
static ResourceManager s;
return s;
}*/
/** Registers the factory function of a resource type
@tparam T Resource type.
@param factoryFunction Lambda function that creates a new instance of the resource.
*/
template <typename T>
static void RegisterType(std::function<Resource*(std::string)> factoryFunction);
/** Preloads a resource and caches it for future use
@tparam T Resource type.
@param resourceName Fully qualified name of the resource to preload.
*/
template <typename T>
static void Preload(std::string resourceName);
/** Checks if a resource is in cache
@param resourceType Resource type as string.
@param resourceName Fully qualified name of the resource to preload.
*/
// TODO: Templateify
static bool IsResourceLoaded(std::string resourceType, std::string resourceName);
/** Hot-loads a resource and caches it for future use
@tparam T Resource type.
@param resourceName Fully qualified name of the resource to load.
*/
template <typename T>
static T* Load(std::string resourceName, Resource* parent = nullptr);
/** Fetches a loaded resource
@tparam T Resource type.
@param resourceName Fully qualified name of the resource to fetch.
*/
template <typename T>
static T* Fetch(std::string resourceName);
/** Reloads an already loaded resource, keeping its resource ID intact.
@tparam T Resource type.
@param resourceName Fully qualified name of the resource to reload.
*/
static void Reload(std::string resourceName);
static void Update();
private:
static std::unordered_map<std::string, std::function<Resource*(std::string)>> m_FactoryFunctions; // type -> factory function
static std::unordered_map<std::pair<std::string, std::string>, Resource*> m_ResourceCache; // (type, name) -> resource
static std::unordered_map<std::string, Resource*> m_ResourceFromName; // name -> resource
static std::unordered_map<Resource*, Resource*> m_ResourceParents; // resource -> parent resource
// TODO: Getters for IDs
static unsigned int m_CurrentResourceTypeID;
static std::unordered_map<std::string, unsigned int> m_ResourceTypeIDs;
// Number of resources of a type. Doubles as local ID.
static std::unordered_map<unsigned int, unsigned int> m_ResourceCount;
// Flag to suppress hot-load warnings when a preloading resource chain loads another resource
static bool m_Preloading;
static FileWatcher m_FileWatcher;
static void fileWatcherCallback(std::string path, FileWatcher::FileEventFlags flags);
static unsigned int GetTypeID(std::string resourceType);
static unsigned int GetNewResourceID(unsigned int typeID);
// Internal: Create a resource and cache it
template <typename T>
static T* CreateResource(std::string resourceName, Resource* parent);
};
template <typename T>
T* ResourceManager::Load(std::string resourceName, Resource* parent /* = nullptr */)
{
auto resourceType = typeid(T).name();
auto it = m_ResourceCache.find(std::make_pair(resourceType, resourceName));
if (it != m_ResourceCache.end())
return static_cast<T*>(it->second);
if (m_Preloading) {
LOG_INFO("Preloading resource \"%s\"", resourceName.c_str());
} else {
LOG_WARNING("Hot-loading resource \"%s\"", resourceName.c_str());
}
return CreateResource<T>(resourceName, parent);
}
template <typename T>
T* ResourceManager::Fetch(std::string resourceName)
{
auto resourceType = typeid(T).name();
auto it = m_ResourceCache.find(std::make_pair(resourceType, resourceName));
if (it == m_ResourceCache.end())
{
LOG_ERROR("Failed to fetch resource \"%s\": Resource not loaded!", resourceName.c_str());
return nullptr;
} else
{
return static_cast<T*>(it->second);
}
}
template <typename T>
void ResourceManager::RegisterType(std::function<Resource*(std::string)> factoryFunction)
{
m_FactoryFunctions[typeid(T).name()] = factoryFunction;
}
template <typename T>
void ResourceManager::Preload(std::string resourceName)
{
auto resourceType = typeid(T).name();
if (IsResourceLoaded(resourceType, resourceName))
{
LOG_WARNING("Attempted to preload resource \"%s\" multiple times!", resourceName);
return;
}
m_Preloading = true;
LOG_INFO("Preloading resource \"%s\"", resourceName.c_str());
CreateResource<T>(resourceName);
m_Preloading = false;
}
template <typename T>
T* ResourceManager::CreateResource(std::string resourceName, Resource* parent)
{
const char* resourceType = typeid(T).name();
/*auto facIt = m_FactoryFunctions.find(resourceType);
if (facIt == m_FactoryFunctions.end())
{
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": Type not registered", resourceName.c_str(), resourceType);
return nullptr;
}*/
// Call the factory function
T* resource = new T(resourceName);
// Store IDs
resource->TypeID = GetTypeID(resourceType);
resource->ResourceID = GetNewResourceID(resource->TypeID);
// Cache
m_ResourceCache[std::make_pair(resourceType, resourceName)] = resource;
m_ResourceFromName[resourceName] = resource;
if (parent != nullptr)
{
m_ResourceParents[resource] = parent;
}
if (!boost::filesystem::is_directory(resourceName))
{
LOG_DEBUG("Adding watch for %s", resourceName.c_str());
m_FileWatcher.AddWatch(resourceName, fileWatcherCallback);
}
return resource;
}
}
#endif // ResourceManager_h__
+124
View File
@@ -0,0 +1,124 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ShaderProgram_h__
#define ShaderProgram_h__
#include <memory>
#include <string>
#include <fstream>
#include <vector>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
#include "ResourceManager.h"
namespace dd
{
class Shader
{
public:
Shader(GLenum shaderType, std::string resourceName);
virtual ~Shader();
GLenum GetType() const;
std::string GetFileName() const;
GLuint GetHandle() const;
protected:
GLenum m_ShaderType;
std::string m_FileName;
GLuint m_ShaderHandle;
void Compile();
};
template <int SHADERTYPE>
class ShaderType : public Shader, public Resource
{
friend class ResourceManager;
public:
ShaderType(std::string resourceName)
: Shader(SHADERTYPE, resourceName)
{ }
private:
virtual void Reload() override;
};
template <int SHADERTYPE>
void ShaderType<SHADERTYPE>::Reload()
{
Compile();
Resource::Reload();
}
class VertexShader : public ShaderType<GL_VERTEX_SHADER>
{
public:
VertexShader(std::string resourceName)
: ShaderType(resourceName)
{ }
};
class FragmentShader : public ShaderType<GL_FRAGMENT_SHADER>
{
public:
FragmentShader(std::string resourceName)
: ShaderType(resourceName)
{ }
};
class GeometryShader : public ShaderType<GL_GEOMETRY_SHADER>
{
public:
GeometryShader(std::string resourceName)
: ShaderType(resourceName)
{ }
};
class ShaderProgram : public Resource
{
friend class ResourceManager;
protected:
ShaderProgram(std::string resourceName);
~ShaderProgram();
public:
void BindFragDataLocation(int colorNumber, std::string name);
GLuint Link();
GLuint GetHandle();
operator GLuint() const { return m_ShaderProgramHandle; }
void Bind();
void Unbind();
virtual void OnChildReloaded(Resource *child) override;
private:
GLuint m_ShaderProgramHandle = 0;
std::vector<Shader*> m_Shaders;
};
}
#endif // ShaderProgram_h__
+117
View File
@@ -0,0 +1,117 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Skeleton_h__
#define Skeleton_h__
#include <sstream>
namespace dd
{
//struct Bone
//{
// Bone(std::string name, glm::mat4 offsetMatrix)
// : Name(name)
// , OffsetMatrix(offsetMatrix)
// { }
//
// ~Bone()
// {
// for (auto kv : Children) {
// delete kv.second;
// }
// }
//
// std::string Name;
// glm::mat4 OffsetMatrix;
// glm::mat4 LocalMatrix;
//
// std::map<std::string, Bone*> Children;
//};
class Skeleton
{
public:
struct Bone
{
Bone(int id, Bone* parent, std::string name, glm::mat4 offsetMatrix)
: ID(id)
, Parent(parent)
, Name(name)
, OffsetMatrix(offsetMatrix)
{ }
int ID;
std::string Name;
glm::mat4 OffsetMatrix;
Bone* Parent;
std::vector<Bone*> Children;
};
struct Animation
{
struct Keyframe
{
struct BoneProperty
{
int ID;
glm::vec3 Position;
glm::quat Rotation;
glm::vec3 Scale = glm::vec3(1);
};
int Index = 0;
double Time = 0.0;
std::map<int, Keyframe::BoneProperty> BoneProperties;
};
std::string Name;
double Duration;
std::vector<Keyframe> Keyframes;
};
Skeleton() { }
~Skeleton();
Bone* RootBone;
std::map<int, Bone*> Bones;
// Attach a new bone to the skeleton
// Returns: New bone index
int CreateBone(int ID, int parentID, std::string name, glm::mat4 offsetMatrix);
int GetBoneID(std::string name);
std::vector<glm::mat4> GetFrameBones(std::string animationName, double time, bool noRootMotion = false);
void AccumulateBoneTransforms(bool noRootMotion, Animation::Keyframe &currentFrame, Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, Bone* bone, glm::mat4 parentMatrix);
void PrintSkeleton();
void PrintSkeleton(Bone* parent, int depthCount);
std::map<std::string, Animation> Animations;
private:
std::map<std::string, Bone*> m_BonesByName;
int GetKeyframe(Animation& animation, double time);
};
}
#endif // Skeleton_h__
+67
View File
@@ -0,0 +1,67 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef System_h__
#define System_h__
#include "Util/Factory.h"
#include "Entity.h"
#include "Component.h"
#include "EventBroker.h"
#include "ResourceManager.h"
namespace dd
{
class World;
class System
{
public:
System(World* world, std::shared_ptr<EventBroker> eventBroker)
: m_World(world)
, EventBroker(eventBroker)
{ }
virtual ~System() { }
virtual void RegisterComponents(ComponentFactory* cf) { }
virtual void RegisterResourceTypes(std::shared_ptr<dd::ResourceManager> rm) { }
virtual void Initialize() { }
// Called once per system every tick
virtual void Update(double dt) { }
// Called once for every entity in the world every tick
virtual void UpdateEntity(double dt, EntityID entity, EntityID parent) { }
// Called when a component is removed
virtual void OnComponentRemoved(EntityID entity, std::string type, Component* component) { }
// Called when components are committed to an entity
virtual void OnEntityCommit(EntityID entity) { }
virtual void OnEntityRemoved(EntityID entity) { }
protected:
World* m_World;
std::shared_ptr<dd::EventBroker> EventBroker;
};
class SystemFactory : public Factory<System> { };
}
#endif // System_h__
+53
View File
@@ -0,0 +1,53 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Texture_h__
#define Texture_h__
#include <string>
#include <unordered_map>
#include <cstdio>
#include "ResourceManager.h"
#include "PNG.h"
namespace dd
{
class Texture : public Resource
{
friend class ResourceManager;
private:
Texture(std::string path);
public:
~Texture();
void Bind(GLenum textureUnit = GL_TEXTURE0);
operator GLuint() const { return m_Texture; }
private:
GLuint m_Texture = 0;
};
}
#endif // Texture_h__
+18
View File
@@ -0,0 +1,18 @@
//
// Created by imon on 2015-03-31.
//
#ifndef DAYDREAM_ENUMCLASSHASH_H
#define DAYDREAM_ENUMCLASSHASH_H
// http://stackoverflow.com/a/24847480/417018
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
#endif //DAYDREAM_ENUMCLASSHASH_H
+148
View File
@@ -0,0 +1,148 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ComponentFactory_h__
#define ComponentFactory_h__
#include <string>
#include <memory>
#include <functional>
#include <map>
namespace dd
{
/** Generic object factory.
Creates dynamically allocated objects of base type T.
@tparam T Object type.
*/
template <typename T>
class Factory
{
public:
/*void Register(std::string name, std::function<T(void)> factoryFunction)
{
m_FactoryFunctions[name] = factoryFunction;
}*/
/** Register a custom factory function for a type with the factory.
@tparam T2 Object type of base type T.
@param factoryFunction The lambda factory function.
*/
template <typename T2>
void Register(std::function<T*(void)> factoryFunction)
{
m_FactoryFunctions[typeid(T2).name()] = factoryFunction;
}
/** Register a type with the factory.
@tparam T2 Object type of base type T.
*/
template <typename T2>
void Register()
{
m_FactoryFunctions[typeid(T2).name()] = []() { return new T2(); };
m_CopyFunctions[typeid(T2).name()] = [](const T* t) { return new T2(*static_cast<const T2*>(t)); };
}
/** Create an instance of a specific typename.
@param name Typename of type of base type T, as a string.
@returns Pointer to the new object of type T.
*/
T* Create(std::string name)
{
auto it = m_FactoryFunctions.find(name);
if (it != m_FactoryFunctions.end())
{
return it->second();
}
else
{
return nullptr;
}
}
/** Create an instance of a specific type.
@tparam T2 Type of base type T.
@returns Pointer to the new object of type T.
*/
template <typename T2>
T* Create()
{
auto it = m_FactoryFunctions.find(typeid(T2).name());
if (it != m_FactoryFunctions.end())
{
return it->second();
}
else
{
return nullptr;
}
}
/** Create a copy of an existing object of a specific _type_ registered with the factory.
@param name Typename of type of base type T, as a string.
@param toCopy The existing object to copy.
@returns Pointer to the new object of type T2.
*/
T* Copy(std::string name, const T* toCopy)
{
auto it = m_CopyFunctions.find(name);
if (it != m_CopyFunctions.end())
{
return it->second(toCopy);
}
else
{
return nullptr;
}
}
/** Create a copy of an existing object of a specific _typename_ registered with the factory.
@tparam T2 Type of base type T.
@param toCopy The existing object to copy.
@returns Pointer to the new object of type T2.
*/
template <typename T2>
T* Copy(const T* toCopy)
{
auto it = m_CopyFunctions.find(typeid(T2).name());
if (it != m_CopyFunctions.end())
{
return it->second(toCopy);
} else
{
return nullptr;
}
}
private:
std::map<std::string, std::function<T*(void)>> m_FactoryFunctions;
std::map<std::string, std::function<T*(const T*)>> m_CopyFunctions;
};
}
#endif // ComponentFactory_h__
+81
View File
@@ -0,0 +1,81 @@
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <functional>
#include <unordered_map>
#include "Core/Util/Logging.h"
namespace std
{
template<> struct hash < boost::filesystem::path >
{
size_t operator()(const boost::filesystem::path& p) const
{
return boost::filesystem::hash_value(p);
}
};
}
namespace dd
{
class FileWatcher
{
public:
enum class FileEventFlags;
typedef std::function<void(std::string, FileEventFlags)> FileEventCallback_t;
FileWatcher();
FileWatcher(std::string rootPath);
~FileWatcher();
std::string RootPath() const { return m_RootPath.string(); }
void AddWatch(std::string path, FileEventCallback_t callback);
void Start();
bool IsRunning() const { return m_IsRunning; }
void Stop();
void Check();
private:
class Worker;
boost::filesystem::path m_RootPath;
boost::thread m_Thread;
Worker* m_Worker = nullptr;
bool m_IsRunning = false;
};
enum class FileWatcher::FileEventFlags
{
None = 0,
Created = 1 << 0,
SizeChanged = 1 << 1,
TimestampChanged = 1 << 2,
Deleted = 1 << 3,
};
inline FileWatcher::FileEventFlags operator|(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast<FileWatcher::FileEventFlags>(static_cast<int>(a) | static_cast<int>(b)); }
inline bool operator&(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast<int>(a)& static_cast<int>(b); }
class FileWatcher::Worker
{
public:
void operator()();
void AddWatch(std::string path, FileEventCallback_t callback);
void Check();
private:
struct FileInfo
{
int Size;
std::time_t Timestamp;
};
std::unordered_map<boost::filesystem::path, FileEventCallback_t> m_FileCallbacks;
std::unordered_map<boost::filesystem::path, FileInfo> m_FileInfo;
boost::mutex m_Mutex;
FileInfo GetFileInfo(boost::filesystem::path path);
FileEventFlags UpdateFileInfo(boost::filesystem::path path);
};
}
+40
View File
@@ -0,0 +1,40 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GLError_h__
#define GLError_h__
#include "PrecompiledHeader.h"
#include <iostream>
inline bool _GLERROR(const char* info, const char* file, const char* func, unsigned int line)
{
GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
_LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s %i %s", info, error, gluErrorString(error));
return true;
}
return false;
}
#define GLERROR(function) \
_GLERROR(function, __BASE_FILE__, __func__, __LINE__)
#endif // GLError_h__
+107
View File
@@ -0,0 +1,107 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Logging_h__
#define Logging_h__
#ifdef _WIN32
// http://stackoverflow.com/a/2282433
#define __func__ __FUNCTION__
// http://stackoverflow.com/a/8488201
#define __BASE_FILE__ \
(strrchr(__FILE__, '/') \
? strrchr(__FILE__, '/') + 1 \
: (strrchr(__FILE__, '\\') \
? strrchr(__FILE__, '\\') + 1 \
: __FILE__))
#endif
#include <iostream>
#include <limits>
#include <string>
#include <cstdio>
#include <stdarg.h>
enum _LOG_LEVEL
{
LOG_LEVEL_ERROR,
LOG_LEVEL_WARNING,
LOG_LEVEL_INFO,
LOG_LEVEL_DEBUG
};
#ifdef DEBUG
static _LOG_LEVEL LOG_LEVEL = LOG_LEVEL_DEBUG;
#else
static _LOG_LEVEL LOG_LEVEL = LOG_LEVEL_DEBUG;
#endif
const static char* _LOG_LEVEL_PREFIX[] =
{
"E: ",
"W: ",
"",
"D: "
};
static void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int line, const char* format, ...)
{
if (logLevel > LOG_LEVEL)
return;
char* message = nullptr;
va_list args;
va_start(args, format);
size_t size = vsnprintf(message, 0, format, args) + 1;
va_end(args);
va_start(args, format);
message = new char[size];
vsnprintf(message, size, format, args);
va_end(args);
if (logLevel == LOG_LEVEL_ERROR)
{
std::cerr << file << ":" << line << " " << func << std::endl;
std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
}
else
{
std::cout << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
}
delete[] message;
}
#define LOG(logLevel, format, ...) \
_LOG(logLevel, __BASE_FILE__, __func__, __LINE__, format, ##__VA_ARGS__)
#define LOG_ERROR(format, ...) \
LOG(LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
#define LOG_WARNING(format, ...) \
LOG(LOG_LEVEL_WARNING, format, ##__VA_ARGS__)
#define LOG_INFO(format, ...) \
LOG(LOG_LEVEL_INFO, format, ##__VA_ARGS__)
#define LOG_DEBUG(format, ...) \
LOG(LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
#endif // Logging_h__
+120
View File
@@ -0,0 +1,120 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Util_Rectangle_h__
#define Util_Rectangle_h__
#include <algorithm>
namespace dd
{
struct Rectangle
{
Rectangle()
: X(0), Y(0), Width(0), Height(0) { }
Rectangle(int width, int height)
: X(0), Y(0), Width(width), Height(height) { }
Rectangle(int x, int y, int width, int height)
: X(x), Y(y), Width(width), Height(height) { }
/*Rectangle(const Rectangle &rect)
: X(rect.X), Y(rect.Y), Width(rect.Width), Height(rect.Height) { }*/
int X;
int Y;
int Width;
int Height;
virtual int Left() const { return X; }
void SetLeft(int left)
{
Width += X - left;
X = left;
}
virtual int Right() const { return X + Width; }
void SetRight(int right)
{
Width = right - X;
}
virtual int Top() const { return Y; }
void SetTop(int top)
{
Height += Y - top;
Y = top;
}
virtual int Bottom() const { return Y + Height; }
int SetBottom(int bottom)
{
Height = bottom - Y;
}
Rectangle& operator+=(const Rectangle &rhs) {
SetLeft(std::min(Left(), rhs.Left()));
SetRight(std::max(Right(), rhs.Right()));
SetTop(std::min(Top(), rhs.Top()));
SetBottom(std::max(Bottom(), rhs.Bottom()));
}
static bool Intersects(const Rectangle &r1, const Rectangle &r2)
{
return !(r2.Left() > r1.Right() || r2.Right() < r1.Left() || r2.Top() > r1.Bottom() || r2.Bottom() < r1.Top());
}
};
inline bool operator==(const Rectangle &r1, const Rectangle &r2)
{
return (r1.X == r2.X) && (r1.Y == r2.Y) && (r1.Width == r2.Width) && (r1.Height == r2.Height);
}
inline bool operator!=(const Rectangle &lhs, const Rectangle &rhs)
{
return !(lhs == rhs);
}
inline bool operator<(const Rectangle &lhs, const Rectangle &rhs)
{
return (lhs.Width < rhs.Width) && (lhs.Height < rhs.Height);
}
inline bool operator>(const Rectangle &lhs, const Rectangle &rhs)
{
return rhs < lhs;
}
inline bool operator<=(const Rectangle &lhs, const Rectangle &rhs)
{
return !(lhs > rhs);
}
inline bool operator>=(const Rectangle &lhs, const Rectangle &rhs)
{
return !(lhs < rhs);
}
inline Rectangle operator+(Rectangle lhs, const Rectangle &rhs)
{
lhs += rhs;
return lhs;
}
}
#endif // Util_Rectangle_h__
+40
View File
@@ -0,0 +1,40 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef Util_UnorderedMapPair_h__
#define Util_UnorderedMapPair_h__
#include <boost/functional/hash.hpp>
namespace std
{
template<typename S, typename T> struct hash < pair<S, T> >
{
inline size_t operator()(const pair<S, T> & v) const
{
size_t seed = 0;
boost::hash_combine(seed, v.first);
boost::hash_combine(seed, v.second);
return seed;
}
};
}
#endif // Util_UnorderedMapPair_h__
+336
View File
@@ -0,0 +1,336 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef World_h__
#define World_h__
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <vector>
#include <string>
#include <queue>
#include <boost/any.hpp>
#include "Util/Factory.h"
#include "Entity.h"
#include "Component.h"
#include "System.h"
#include "EventBroker.h"
#include "EComponentCreated.h"
#include "ResourceManager.h"
namespace dd
{
/** The entity manager.
Governs over the lifetime of entities.
*/
class World
{
public:
World(std::shared_ptr<dd::EventBroker> eventBroker)
: EventBroker(eventBroker)
, m_LastEntityID(0) { }
~World() { }
/** Initialize the world.
*/
virtual void Initialize();
/** Register world systems.
Called by Initialize.
Implemented to register systems with the systemfactory before
adding them to the world.
*/
virtual void RegisterSystems() {}
/** Add systems to the world.
Called by Initialize.
Implemented to fill the world with the desired systems.
*/
virtual void AddSystems() {}
/** Register components with the world.
Implemented to register World-global components.
@deprecated Components are now registered through individual Systems.
*/
// TODO: Get rid of this
virtual void RegisterComponents() {}
/** Add a system to the World */
template <typename T>
void AddSystem()
{
m_Systems[typeid(T).name()] = std::shared_ptr<System>(SystemFactory.Create<T>());
}
/** Fetch a system by type.
@tparam T The type of the system to fetch.
*/
template <typename T>
std::shared_ptr<T> GetSystem();
/** Creates an empty entity.
@param parent The parent of the entity.
*/
EntityID CreateEntity(EntityID parent = 0);
/** Recursively clones an entity and all of its components and children.
@param entity The entity to clone.
@param parent The new parent of the clone.
*/
EntityID CloneEntity(EntityID entity, EntityID parent = 0);
/** Removes an entity and all its children from the world. */
void RemoveEntity(EntityID entity);
/** Check if an entity is valid and exists in the world.
Returns FALSE if the entity doesn't exist or is in queue to be removed.
@returns Whether the entity exists or not.
*/
bool ValidEntity(EntityID entity);
/** Get the parent of an entity. */
EntityID GetEntityParent(EntityID entity);
/** Get the top level parent of an entity.
Gets the top level parent of an entity. Loops through the scene
graph to find the first entity with the world as its parent.
*/
EntityID GetEntityBaseParent(EntityID entity);
/** Get the children of an entity.
@returns A list of entities parented to this entity.
*/
std::list<EntityID> GetEntityChildren(EntityID entity);
/** Set the parent of an entity.
@param entity The entity to reparent.
@param newParent The new parent of the entity.
*/
void SetEntityParent(EntityID entity, EntityID newParent);
/** Get a property field of an entity by name.
@tparam T The type of the property.
@param entity The entity.
@param property The name of the property to fetch.
*/
template <class T>
T GetProperty(EntityID entity, std::string property)
{
if(m_EntityProperties.find(entity) == m_EntityProperties.end())
return T();
if(m_EntityProperties[entity].find(property) == m_EntityProperties[entity].end())
return T();
return boost::any_cast<T>(m_EntityProperties[entity][property]);
}
/** Set a property field of an entity.
@param entity The entity.
@param property The name of the property to set.
@param value The value of the property.
*/
void SetProperty(EntityID entity, std::string property, boost::any value)
{
m_EntityProperties[entity][property] = value;
}
/** Set a string property field of an entity.
Helper function to be able to set string properties easier.
@param entity The entity.
@param property The name of the property to set.
@param value The value of the property.
*/
void SetProperty(EntityID entity, std::string property, char* value)
{
m_EntityProperties[entity][property] = std::string(value);
}
/** Create and attach component to an entity.
@tparam T The type of component to attach.
@param entity The entity to attach the component to.
@returns The newly attached component.
*/
template <class T>
std::shared_ptr<T> AddComponent(EntityID entity);
/** Remove a component from an entity.
@tparam T The type of the component to remove.
@param entity The entity to remove the component from.
*/
template <class T>
void RemoveComponent(EntityID entity);
/** Fetch a component of an entity.
@tparam T The type of component to fetch.
@param entity The entity to fetch the component from.
*/
template <class T>
T* GetComponent(EntityID entity);
// Triggers commit events in systems
// TODO: Replace completely by EComponentCreated?
void CommitEntity(EntityID entity);
/** Get all components of a specific type.
@tparam T The type of component to query.
@returns A list of components of type T in the World.
*/
template <class T>
std::list<std::shared_ptr<Component>>* GetComponentsOfType();
/*std::vector<EntityID> GetEntityChildren(EntityID entity);*/
/** Moves the world simulation forward one tick.
@param dt Time since last frame in seconds.
*/
virtual void Update(double dt);
// Recursively update through the scene graph
// TODO: Private?
void RecursiveUpdate(std::shared_ptr<System> system, double dt, EntityID parentEntity);
/** Fetch the scene graph.
@returns An std::unordered_map of entities to their parents.
*/
std::unordered_map<EntityID, EntityID>* GetEntities() { return &m_EntityParents; }
dd::SystemFactory SystemFactory;
dd::ComponentFactory ComponentFactory;
protected:
std::shared_ptr<dd::EventBroker> EventBroker;
std::shared_ptr<dd::ResourceManager> ResourceManager;
std::unordered_map<std::string, std::shared_ptr<System>> m_Systems;
EntityID m_LastEntityID;
std::stack<EntityID> m_RecycledEntityIDs;
std::unordered_map<EntityID, EntityID> m_EntityParents; // child -> parent
std::unordered_map<EntityID, std::list<EntityID>> m_EntityChildren; // parent -> child
std::unordered_map<EntityID, std::unordered_map<std::string, boost::any>> m_EntityProperties;
std::unordered_map<std::string, std::list<std::shared_ptr<Component>>> m_ComponentsOfType;
std::unordered_map<EntityID, std::map<std::string, std::shared_ptr<Component>>> m_EntityComponents;
// Internal: Add a component to an entity
void AddComponent(EntityID entity, std::string componentType, std::shared_ptr<Component> component);
std::set<EntityID> m_EntitiesToRemove;
void ProcessEntityRemovals();
EntityID GenerateEntityID();
void RecycleEntityID(EntityID id);
};
template <class T>
std::list<std::shared_ptr<Component>>* World::GetComponentsOfType()
{
const char* componentType = typeid(T).name();
auto it = m_ComponentsOfType.find(componentType);
if (it == m_ComponentsOfType.end())
return nullptr;
return &it->second;
}
template <class T>
std::shared_ptr<T> World::GetSystem()
{
const char* systemType = typeid(T).name();
if (m_Systems.find(systemType) == m_Systems.end())
{
LOG_WARNING("Tried to get pointer to unregistered system \"%s\"!", systemType);
return nullptr;
}
return std::static_pointer_cast<T>(m_Systems.at(systemType));
}
template <class T>
std::shared_ptr<T> World::AddComponent(EntityID entity)
{
const char* componentType = typeid(T).name();
std::shared_ptr<T> component = std::shared_ptr<T>(static_cast<T*>(ComponentFactory.Create<T>()));
if (component == nullptr)
{
LOG_ERROR("Failed to attach invalid component \"%s\" to entity #%i", componentType, entity);
return nullptr;
}
AddComponent(entity, componentType, component);
return component;
}
template <class T>
void World::RemoveComponent(EntityID entity)
{
const char* componentType = typeid(T).name();
auto it = m_EntityComponents[entity].find(componentType);
if (it == m_EntityComponents[entity].end())
return;
auto component = it->second;
component->Entity = 0;
m_ComponentsOfType[componentType].remove(component);
m_EntityComponents[entity].erase(it);
for (auto pair : m_Systems)
{
auto system = pair.second;
system->OnComponentRemoved(entity, componentType, component.get());
}
}
template <class T>
T* World::GetComponent(EntityID entity)
{
auto components = m_EntityComponents[entity];
auto it = components.find(typeid(T).name());
if (it != components.end())
{
return static_cast<T*>(it->second.get());
}
else
{
return nullptr;
}
}
}
#endif // World_h__