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

# Conflicts:
#	resources/Schema/Types/Entity.xsd
This commit is contained in:
stiffly
2016-01-15 16:25:32 +01:00
46 changed files with 1306 additions and 347 deletions
+4 -4
View File
@@ -7,10 +7,10 @@
#include <vector> #include <vector>
#include "Core/Ray.h" #include "../Core/Ray.h"
#include "Core/AABB.h" #include "../Core/AABB.h"
#include "Engine/Rendering/RawModel.h" #include "../Rendering/RawModel.h"
#include "Core/Entity.h" #include "../Core/Entity.h"
class World; class World;
struct ComponentWrapper; struct ComponentWrapper;
+4 -4
View File
@@ -4,10 +4,10 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <glm/common.hpp> #include <glm/common.hpp>
#include "Common.h" #include "../Common.h"
#include "Core/System.h" #include "../Core/System.h"
#include "Core/EventBroker.h" #include "../Core/EventBroker.h"
#include "Core/EKeyUp.h" #include "../Core/EKeyUp.h"
class CollisionSystem : public PureSystem class CollisionSystem : public PureSystem
{ {
+2 -2
View File
@@ -4,8 +4,8 @@
#include <glm/common.hpp> #include <glm/common.hpp>
#include <unordered_set> #include <unordered_set>
#include "Core/System.h" #include "../Core/System.h"
#include "Core/EventBroker.h" #include "../Core/EventBroker.h"
#include "ETrigger.h" #include "ETrigger.h"
class AABB; class AABB;
+1 -1
View File
@@ -2,7 +2,7 @@
#define Ray_h__ #define Ray_h__
#include "../GLM.h" #include "../GLM.h"
#include "Common.h" #include "../Common.h"
class Ray class Ray
{ {
+132 -39
View File
@@ -12,7 +12,6 @@
/** Base Resource class. /** Base Resource class.
Implement this class for every resource to be handled by the resource manager. 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 class Resource
{ {
@@ -22,6 +21,23 @@ protected:
Resource() { } Resource() { }
public: public:
//Should be thrown in a Resource's constructor if it cannot complete because another resource is still loading.
//Not actually an error, just a message to the ResourceManager.
struct StillLoadingException : public std::exception
{
virtual const char* what() const throw()
{
return "Resource is still loading.";
}
};
struct FailedLoadingException : public std::exception
{
virtual const char* what() const throw()
{
return "Resource is failed to load.";
}
};
// Pretend that this is a pure virtual function that you have to implement // 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? // FIXME: Why did we do this again instead of just using the constructor?
// static Resource* Create(std::string resourceName); // static Resource* Create(std::string resourceName);
@@ -33,6 +49,15 @@ public:
unsigned int ResourceID; unsigned int ResourceID;
}; };
//Any class inheriting from this class will always be loaded on the master thread, not on a parallel worker thread.
//This is important in case some instructions must be executed on the main thread, e.g. OpenGL commands, like glBindBuffer.
//This resource can still be loaded asyncronously, but it will not be loaded in a thread, instead it's constructor will
//be called once on every ResourceManager::Load, just throw StillLoadingException in the constructor if it is not done yet.
class ThreadUnsafeResource : public Resource
{
friend class ResourceManager;
};
/** Singleton resource manager to keep track of and cache any external engine assets */ /** Singleton resource manager to keep track of and cache any external engine assets */
class ResourceManager class ResourceManager
{ {
@@ -40,6 +65,7 @@ private:
ResourceManager(); ResourceManager();
public: public:
static bool UseThreading;
/*static ResourceManager& Instance() /*static ResourceManager& Instance()
{ {
static ResourceManager s; static ResourceManager s;
@@ -49,15 +75,6 @@ public:
template <typename T> template <typename T>
static void RegisterType(std::string typeName); static void RegisterType(std::string typeName);
/** 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);
static void Preload(std::string resourceType, std::string resourceName);
/** Checks if a resource is in cache /** Checks if a resource is in cache
@param resourceType Resource type as string. @param resourceType Resource type as string.
@@ -66,14 +83,19 @@ public:
// TODO: Templateify // TODO: Templateify
static bool IsResourceLoaded(std::string resourceType, std::string resourceName); static bool IsResourceLoaded(std::string resourceType, std::string resourceName);
/** Hot-loads a resource and caches it for future use /** Return value should always be a valid pointer, will throw an exception on error.
If the resource has been loaded already, returns a pointer to it.
If Async is false: Hot-loads a resource, caches it for future use, and returns a pointer to it.
If Async is true: If the resource is not loaded yet, starts loading the resource
in the background and throws Resource::StillLoadingException immediately.
@tparam T Resource type. @tparam T Resource type.
@tparam async Set this to true if the resource should be loaded asyncronously.
@param resourceName Fully qualified name of the resource to load. @param resourceName Fully qualified name of the resource to load.
*/ */
template <typename T> template <typename T, bool async = false>
static T* Load(std::string resourceName, Resource* parent = nullptr); static T* Load(const std::string& resourceName, Resource* parent = nullptr);
static Resource* Load(std::string resourceType, std::string resourceName, Resource* parent = nullptr);
/** Reloads an already loaded resource, keeping its resource ID intact. /** Reloads an already loaded resource, keeping its resource ID intact.
@@ -87,19 +109,31 @@ public:
static void Update(); static void Update();
private: private:
//This is a haxy way to make sure that IsMainThread is run when the program starts, so the master thread id is set.
struct MasterThreadChecker
{
MasterThreadChecker()
{
ResourceManager::IsMainThread();
}
};
const static MasterThreadChecker m_Checker;
static std::unordered_map<std::string, std::string> m_CompilerTypenameToResourceType; static std::unordered_map<std::string, std::string> m_CompilerTypenameToResourceType;
static std::unordered_map<std::string, std::function<Resource*(std::string)>> m_FactoryFunctions; // type -> factory function 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::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<std::string, Resource*> m_ResourceFromName; // name -> resource
static std::unordered_map<Resource*, Resource*> m_ResourceParents; // resource -> parent resource static std::unordered_map<Resource*, Resource*> m_ResourceParents; // resource -> parent resource
static std::unordered_map<std::pair<std::string, std::string>, boost::thread> m_LoadingThreads; // (type, name) -> loading thread
static std::unordered_map<std::pair<std::string, std::string>, std::exception_ptr> m_LoadingThreadExceptions; // (type, name) -> exceptions
static boost::recursive_mutex m_Mutex;
// TODO: Getters for IDs // TODO: Getters for IDs
static unsigned int m_CurrentResourceTypeID; static unsigned int m_CurrentResourceTypeID;
static std::unordered_map<std::string, unsigned int> m_ResourceTypeIDs; static std::unordered_map<std::string, unsigned int> m_ResourceTypeIDs;
// Number of resources of a type. Doubles as local ID. // Number of resources of a type. Doubles as local ID.
static std::unordered_map<unsigned int, unsigned int> m_ResourceCount; 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 FileWatcher m_FileWatcher;
static void fileWatcherCallback(std::string path, FileWatcher::FileEventFlags flags); static void fileWatcherCallback(std::string path, FileWatcher::FileEventFlags flags);
@@ -108,22 +142,13 @@ private:
static unsigned int GetNewResourceID(unsigned int typeID); static unsigned int GetNewResourceID(unsigned int typeID);
// Internal: Create a resource and cache it // Internal: Create a resource and cache it
static Resource* CreateResource(std::string resourceType, std::string resourceName, Resource* parent); static Resource* createResourceThrowing(const std::string& resourceType, const std::string& resourceName, Resource* parent);
static Resource* createResource(const std::string& resourceType, const std::string& resourceName, Resource* parent, std::exception_ptr& exception);
static Resource* cacheResource(Resource* resource, const std::string& resourceType, const std::string& resourceName, Resource* parent);
static bool IsMainThread();
}; };
template <typename T>
T* ResourceManager::Load(std::string resourceName, Resource* parent /* = nullptr */)
{
auto resourceTypename = typeid(T).name();
auto it = m_CompilerTypenameToResourceType.find(resourceTypename);
if (it == m_CompilerTypenameToResourceType.end()) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename);
return nullptr;
}
return static_cast<T*>(Load(it->second, resourceName, parent));
}
template <typename T> template <typename T>
void ResourceManager::RegisterType(std::string typeName) void ResourceManager::RegisterType(std::string typeName)
{ {
@@ -131,17 +156,85 @@ void ResourceManager::RegisterType(std::string typeName)
m_FactoryFunctions[typeName] = [](std::string resourceName) { return new T(resourceName); }; m_FactoryFunctions[typeName] = [](std::string resourceName) { return new T(resourceName); };
} }
template <typename T> template <typename T, bool async>
void ResourceManager::Preload(std::string resourceName) static T* ResourceManager::Load(const std::string& resourceName, Resource* parent /* = nullptr */)
{ {
auto resourceTypename = typeid(T).name(); auto resourceTypename = typeid(T).name();
auto it = m_CompilerTypenameToResourceType.find(resourceTypename); auto iter = m_CompilerTypenameToResourceType.find(resourceTypename);
if (it == m_CompilerTypenameToResourceType.end()) { if (iter == m_CompilerTypenameToResourceType.end()) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename); LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename);
return; throw Resource::FailedLoadingException();
} }
Preload(it->second, resourceName); std::string resourceType = iter->second;
constexpr bool mustNotLoadInThread = std::is_base_of<ThreadUnsafeResource, T>::value;
if (mustNotLoadInThread && !IsMainThread()) {
LOG_ERROR("Failed to Load \"%s\": ThreadUnsafeResource type \"%s\" load in the constructor of another resource that is loaded asyncronously.", resourceName.c_str(), iter->second.c_str());
throw Resource::FailedLoadingException();
}
auto cacheKey = std::make_pair(resourceType, resourceName);
decltype(m_ResourceCache)::iterator it;
//If a thread has already been launched to load this resource.
auto tIt = m_LoadingThreads.find(cacheKey);
if (UseThreading && tIt != m_LoadingThreads.end()) {
if (async) {
//Throw StillLoadingException if the thread is still working.
if (!tIt->second.try_join_for(boost::chrono::nanoseconds(1))) {
throw Resource::StillLoadingException();
}
//Else we know the thread has completed.
} else {
//Wait for the thread to finish loading.
tIt->second.join();
}
//When the thread is done, delete the thread.
m_LoadingThreads.erase(tIt);
//Rethrow the thread exception if it threw any.
auto excIt = m_LoadingThreadExceptions.find(cacheKey);
std::exception_ptr exception = excIt->second;
m_LoadingThreadExceptions.erase(excIt);
if (exception) {
std::rethrow_exception(exception);
}
}
//If resource has already been cached and completely loaded.
it = m_ResourceCache.find(cacheKey);
if (it != m_ResourceCache.end()) {
if (it->second != nullptr) {
return static_cast<T*>(it->second);
} else {
//Don't return null on failure, exception instead.
throw Resource::FailedLoadingException();
}
}
//If resource is not cached..
if (UseThreading && async) {
if (mustNotLoadInThread) {
try {
return static_cast<T*>(createResourceThrowing(resourceType, resourceName, parent));
} catch (const Resource::StillLoadingException&) {
throw;
}
} else {
//Create a thread that loads the resource into cache.
m_LoadingThreads[cacheKey] = boost::thread(createResource, resourceType, resourceName, parent, m_LoadingThreadExceptions[cacheKey]);
throw Resource::StillLoadingException();
}
} else {
//load and return the resource.
while (true) {
try {
return static_cast<T*>(createResourceThrowing(resourceType, resourceName, parent));
} catch (const Resource::StillLoadingException&) {
continue;
} catch (const std::exception&) {
throw;
}
}
}
} }
#endif #endif
+1 -1
View File
@@ -3,7 +3,7 @@
#include "../Core/ResourceManager.h" #include "../Core/ResourceManager.h"
class BaseTexture : public Resource class BaseTexture : public ThreadUnsafeResource
{ {
friend class ResourceManager; friend class ResourceManager;
+38
View File
@@ -0,0 +1,38 @@
#ifndef DrawFinalPass_h__
#define DrawFinalPass_h__
#include "IRenderer.h"
#include "DrawFinalPassState.h"
#include "LightCullingPass.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class DrawFinalPass
{
public:
DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass);
~DrawFinalPass() { }
void InitializeTextures();
void InitializeFrameBuffers();
void InitializeShaderPrograms();
void Draw(RenderScene& scene);
//Getters
private:
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
Texture* m_WhiteTexture;
const IRenderer* m_Renderer;
const LightCullingPass* m_LightCullingPass;
ShaderProgram* m_ForwardPlusProgram;
};
#endif
@@ -0,0 +1,15 @@
#ifndef DrawFinalPassState_h__
#define DrawFinalPassState_h__
#include "Rendering/RenderState.h"
class DrawFinalPassState : public RenderState
{
public:
DrawFinalPassState();
~DrawFinalPassState();
private:
};
#endif
+4
View File
@@ -9,6 +9,8 @@
#include "Camera.h" #include "Camera.h"
#include "RenderQueue.h" #include "RenderQueue.h"
#include "Model.h" #include "Model.h"
#include "../Core/World.h" //So temp
struct PickData struct PickData
{ {
@@ -43,6 +45,8 @@ public:
virtual void Draw(RenderFrame& rq) = 0; virtual void Draw(RenderFrame& rq) = 0;
virtual PickData Pick(glm::vec2 screenCord) = 0; virtual PickData Pick(glm::vec2 screenCord) = 0;
World* m_World; //Temp world, untill viktor merge.
protected: protected:
Rectangle m_Resolution = Rectangle::Rectangle(1280, 720); Rectangle m_Resolution = Rectangle::Rectangle(1280, 720);
bool m_Fullscreen = false; bool m_Fullscreen = false;
@@ -0,0 +1,83 @@
#ifndef LightCullingPass_h__
#define LightCullingPass_h__
#define TILE_SIZE 16
#define MAX_LIGHTS_PER_TILE 200
#include "IRenderer.h"
#include "LightCullingPassState.h"
#include "ShaderProgram.h"
#include "RenderQueue.h"
class LightCullingPass
{
public:
LightCullingPass(IRenderer* renderer);
~LightCullingPass();
void GenerateNewFrustum(RenderScene& scene);
void OnResolutionChange();
void SetSSBOSizes();
void CullLights(RenderScene& scene);
void FillLightList(RenderScene& scene);
GLuint FrustumSSBO() const { return m_FrustumSSBO; }
GLuint LightSSBO() const { return m_LightSSBO; }
GLuint LightGridSSBO() const { return m_LightGridSSBO; }
GLuint LightOffsetSSBO() const { return m_LightOffsetSSBO; }
GLuint LightIndexSSBO() const { return m_LightIndexSSBO; }
private:
void InitializeSSBOs();
void InitializeShaderPrograms();
const IRenderer* m_Renderer;
GLuint m_FrustumSSBO = 0;
GLuint m_LightSSBO = 0;
GLuint m_LightGridSSBO = 0;
GLuint m_LightOffsetSSBO = 0;
GLuint m_LightIndexSSBO = 0;
ShaderProgram* m_CalculateFrustumProgram;
ShaderProgram* m_LightCullProgram;
int m_NumberOfTiles = 0;
struct Plane {
glm::vec3 Normal;
float d;
};
struct Frustum {
Plane Planes[4];
};
Frustum* m_Frustums;
//This should be a component
struct PointLight {
glm::vec4 Position = glm::vec4(0.f);
glm::vec4 Color = glm::vec4(1.f);
float Radius = 5.f;
float Intensity = 0.8f;
float Falloff = 0.3f;
float Padding = 1337;
};
std::vector<PointLight> m_PointLights;
struct LightGrid {
float Start;
float Amount;
glm::vec2 Padding;
};
LightGrid* m_LightGrid;
int m_LightOffset = 0;
float* m_LightIndex;
};
#endif
+5 -1
View File
@@ -4,7 +4,7 @@
#include "RawModel.h" #include "RawModel.h"
#include "../OpenGL.h" #include "../OpenGL.h"
class Model : public RawModel class Model : public ThreadUnsafeResource
{ {
friend class ResourceManager; friend class ResourceManager;
@@ -13,11 +13,15 @@ private:
public: public:
~Model(); ~Model();
const std::vector<RawModel::MaterialGroup>& MaterialGroups() const { return m_RawModel->MaterialGroups; }
const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; }
const std::vector<RawModel::Vertex>& Vertices() const { return m_RawModel->m_Vertices; }
GLuint VAO; GLuint VAO;
GLuint ElementBuffer; GLuint ElementBuffer;
private: private:
RawModel* m_RawModel;
GLuint VertexBuffer; GLuint VertexBuffer;
GLuint DiffuseVertexColorBuffer; GLuint DiffuseVertexColorBuffer;
GLuint SpecularVertexColorBuffer; GLuint SpecularVertexColorBuffer;
+8 -8
View File
@@ -15,16 +15,16 @@
struct ModelJob : RenderJob struct ModelJob : RenderJob
{ {
ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::Model::MaterialGroup texGroup, ComponentWrapper modelComponent, World* world) ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, World* world)
: RenderJob() : RenderJob()
{ {
Model = model; Model = model;
TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0; TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0;
DiffuseTexture = texGroup.Texture.get(); DiffuseTexture = matGroup.Texture.get();
NormalTexture = texGroup.NormalMap.get(); NormalTexture = matGroup.NormalMap.get();
SpecularTexture = texGroup.SpecularMap.get(); SpecularTexture = matGroup.SpecularMap.get();
StartIndex = texGroup.StartIndex; StartIndex = matGroup.StartIndex;
EndIndex = texGroup.EndIndex; EndIndex = matGroup.EndIndex;
Matrix = matrix; Matrix = matrix;
Color = modelComponent["Color"]; Color = modelComponent["Color"];
Entity = modelComponent.EntityID; Entity = modelComponent.EntityID;
@@ -44,7 +44,7 @@ struct ModelJob : RenderJob
const ::Model* Model = nullptr; const ::Model* Model = nullptr;
unsigned int StartIndex = 0; unsigned int StartIndex = 0;
unsigned int EndIndex = 0; unsigned int EndIndex = 0;
const World* World; World* World;
void CalculateHash() override void CalculateHash() override
{ {
+4 -1
View File
@@ -1,6 +1,8 @@
#ifndef PickingPass_h__ #ifndef PickingPass_h__
#define PickingPass_h__ #define PickingPass_h__
#include "IRenderer.h" #include "IRenderer.h"
#include "PickingPassState.h" #include "PickingPassState.h"
#include "FrameBuffer.h" #include "FrameBuffer.h"
@@ -9,6 +11,8 @@
#include "../Core/EventBroker.h" #include "../Core/EventBroker.h"
#include "../Core/World.h" #include "../Core/World.h"
class PickingPass class PickingPass
{ {
public: public:
@@ -21,7 +25,6 @@ public:
void Draw(RenderScene& scene); void Draw(RenderScene& scene);
void ClearPicking(); void ClearPicking();
//Getters //Getters
const ShaderProgram& PickingProgram() const { return *m_PickingProgram; } const ShaderProgram& PickingProgram() const { return *m_PickingProgram; }
//const std::unordered_map<glm::ivec2, EntityID>& PickingColorsToEntity() const { return m_PickingColorsToEntity; } //const std::unordered_map<glm::ivec2, EntityID>& PickingColorsToEntity() const { return m_PickingColorsToEntity; }
+39
View File
@@ -0,0 +1,39 @@
#ifndef PointLightJob_h__
#define PointLightJob_h__
#include <cstdint>
#include "../Common.h"
#include "../GLM.h"
#include "../Core/ComponentWrapper.h"
#include "RenderJob.h"
#include "../Core/Transform.h"
#include "../Core/World.h"
struct PointLightJob : RenderJob
{
PointLightJob(ComponentWrapper transformComponent, ComponentWrapper pointLightComponent, World* m_World)
: RenderJob()
{
Position = glm::vec4((glm::vec3)transformComponent["Position"], 1.0f);
Position = glm::vec4(Transform::AbsolutePosition(m_World, transformComponent.EntityID), 1.f);
Color = (glm::vec4)pointLightComponent["Color"];
Radius = (double)pointLightComponent["Radius"];
Intensity = (double)pointLightComponent["Intensity"];
Falloff = (double)pointLightComponent["Falloff"];
};
glm::vec4 Position;
glm::vec4 Color;
float Radius;
float Intensity;
float Falloff;
float padding = 123;
void CalculateHash() override
{
Hash = 0;
}
};
#endif
+4 -1
View File
@@ -47,14 +47,17 @@ public:
{ {
float Shininess; float Shininess;
float Transparency; float Transparency;
std::string TexturePath;
std::shared_ptr<::Texture> Texture; std::shared_ptr<::Texture> Texture;
std::string NormalMapPath;
std::shared_ptr<::Texture> NormalMap; std::shared_ptr<::Texture> NormalMap;
std::string SpecularMapPath;
std::shared_ptr<::Texture> SpecularMap; std::shared_ptr<::Texture> SpecularMap;
unsigned int StartIndex; unsigned int StartIndex;
unsigned int EndIndex; unsigned int EndIndex;
}; };
std::vector<MaterialGroup> TextureGroups; std::vector<MaterialGroup> MaterialGroups;
std::vector<Vertex> m_Vertices; std::vector<Vertex> m_Vertices;
std::vector<unsigned int> m_Indices; std::vector<unsigned int> m_Indices;
+9 -8
View File
@@ -11,7 +11,7 @@
#include "Camera.h" #include "Camera.h"
#include "RenderJob.h" #include "RenderJob.h"
#include "ModelJob.h" #include "ModelJob.h"
#include "PointLightJob.h"
/* /*
@@ -34,11 +34,12 @@ struct SpriteJob : RenderJob
struct PointLightJob : RenderJob struct PointLightJob : RenderJob
{ {
glm::vec3 Position; glm::vec4 Position;
glm::vec3 SpecularColor = glm::vec3(1, 1, 1); glm::vec4 Color;
glm::vec3 DiffuseColor = glm::vec3(1, 1, 1); float Radius;
float Radius = 1.f; float Intensity;
float Intensity = 0.8f; float Falloff;
float padding = 123;
void CalculateHash() override void CalculateHash() override
{ {
@@ -51,13 +52,13 @@ struct RenderScene
{ {
::Camera* Camera; ::Camera* Camera;
std::list<std::shared_ptr<RenderJob>> ForwardJobs; std::list<std::shared_ptr<RenderJob>> ForwardJobs;
std::list<std::shared_ptr<RenderJob>> LightJobs; std::list<std::shared_ptr<RenderJob>> PointLightJobs;
Rectangle Viewport; Rectangle Viewport;
void Clear() void Clear()
{ {
ForwardJobs.clear(); ForwardJobs.clear();
LightJobs.clear(); PointLightJobs.clear();
} }
}; };
+2
View File
@@ -13,6 +13,7 @@
#include "Camera.h" #include "Camera.h"
#include "ModelJob.h" #include "ModelJob.h"
#include "Renderer.h" #include "Renderer.h"
#include "PointLightJob.h"
#include "../Core/Transform.h" #include "../Core/Transform.h"
#include "DebugCameraInputController.h" #include "DebugCameraInputController.h"
@@ -45,6 +46,7 @@ private:
void updateProjectionMatrix(ComponentWrapper& cameraComponent); void updateProjectionMatrix(ComponentWrapper& cameraComponent);
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world); void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand; EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e); bool OnInputCommand(const Events::InputCommand& e);
+7 -2
View File
@@ -12,9 +12,12 @@
#include "../Core/World.h" #include "../Core/World.h"
#include "PickingPass.h" #include "PickingPass.h"
#include "DrawScenePass.h" #include "DrawScenePass.h"
#include "LightCullingPass.h"
#include "DrawFinalPass.h"
#include "../Core/EventBroker.h" #include "../Core/EventBroker.h"
#include "ImGuiRenderPass.h" #include "ImGuiRenderPass.h"
#include "Camera.h" #include "Camera.h"
#include "../Core/Transform.h"
class Renderer : public IRenderer class Renderer : public IRenderer
{ {
@@ -44,24 +47,26 @@ private:
DrawScenePass* m_DrawScenePass; DrawScenePass* m_DrawScenePass;
PickingPass* m_PickingPass; PickingPass* m_PickingPass;
LightCullingPass* m_LightCullingPass;
ImGuiRenderPass* m_ImGuiRenderPass; ImGuiRenderPass* m_ImGuiRenderPass;
DrawFinalPass* m_DrawFinalPass;
//----------------------Functions----------------------// //----------------------Functions----------------------//
void InitializeWindow(); void InitializeWindow();
void InitializeShaders(); void InitializeShaders();
void InitializeTextures(); void InitializeTextures();
void InitializeSSBOs();
void InitializeRenderPasses(); void InitializeRenderPasses();
//TODO: Renderer: Get InputUpdate out of renderer //TODO: Renderer: Get InputUpdate out of renderer
void InputUpdate(double dt); void InputUpdate(double dt);
//void PickingPass(RenderQueueCollection& rq); //void PickingPass(RenderQueueCollection& rq);
void DrawScreenQuad(GLuint textureToDraw); void DrawScreenQuad(GLuint textureToDraw);
static bool DepthSort(const std::shared_ptr<RenderJob> &i, const std::shared_ptr<RenderJob> &j) { return (i->Depth < j->Depth); }
void FillDepth(RenderScene& scene);
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
//--------------------ShaderPrograms-------------------// //--------------------ShaderPrograms-------------------//
ShaderProgram* m_BasicForwardProgram; ShaderProgram* m_BasicForwardProgram;
ShaderProgram* m_DrawScreenQuadProgram; ShaderProgram* m_DrawScreenQuadProgram;
}; };
#endif #endif
+3
View File
@@ -17,3 +17,6 @@ IsServer=false
Name=Bob Name=Bob
Address=127.0.0.1 Address=127.0.0.1
Port=13 Port=13
[Multithreading]
ResourceLoading=true
+1
View File
@@ -8,6 +8,7 @@
<xs:include schemaLocation="Components/Player.xsd"/> <xs:include schemaLocation="Components/Player.xsd"/>
<xs:include schemaLocation="Components/Camera.xsd"/> <xs:include schemaLocation="Components/Camera.xsd"/>
<xs:include schemaLocation="Components/AABB.xsd"/> <xs:include schemaLocation="Components/AABB.xsd"/>
<xs:include schemaLocation="Components/PointLight.xsd"/>
<xs:include schemaLocation="Components/Trigger.xsd"/> <xs:include schemaLocation="Components/Trigger.xsd"/>
<xs:include schemaLocation="Components/Health.xsd"/> <xs:include schemaLocation="Components/Health.xsd"/>
<xs:include schemaLocation="Components/Listener.xsd"/> <xs:include schemaLocation="Components/Listener.xsd"/>
@@ -0,0 +1,7 @@
<c:PointLight>
<Color R="1" G="1" B="1" A="1"/>
<Radius>1.0</Radius>
<Intensity>0.8</Intensity>
<Falloff>0.3</Falloff>
<Visible>true</Visible>
</c:PointLight>
@@ -0,0 +1,20 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="PointLight">
<xs:annotation>
<xs:documentation>A pointlight that lights up geometry in a radius.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Color" type="t:Color" minOccurs="0"/>
<xs:element name="Radius" type="t:double" minOccurs="0"/>
<xs:element name="Intensity" type="t:double" minOccurs="0"/>
<xs:element name="Falloff" type="t:double" minOccurs="0" minInclusive="0" maxInclusive="1"/>
<xs:element name="Visible" type="t:bool" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -17,7 +17,7 @@
<Scale X="1" Y="1" Z="1"/> <Scale X="1" Y="1" Z="1"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/ScaleWidget.obj</Resource> <Resource>Models/Core/UnitSphere.obj</Resource>
</c:Model> </c:Model>
</Components> </Components>
</Entity> </Entity>
+55 -47
View File
@@ -1,49 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
</c:Model>
<c:Transform>
<Scale X="100" Y="1" Z="100"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>An error</Resource>
</c:Model>
<c:Transform>
<Position X="1" Y="1" Z="0"/>
<Orientation X="0" Y="0.785390019" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Model>
<Resource>An error</Resource>
</c:Model>
<c:Transform>
<Position X="2" Y="0" Z="0"/>
<Orientation X="0" Y="0.785390019" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:Camera/>
<c:Transform>
<Position X="5.85247707" Y="3.8454349" Z="-1.14486957"/>
<Orientation X="2.51327395" Y="1.23916209" Z="-3.1415925"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
<Entity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd" xmlns:c="components">
<Components>
<c:Transform>
<Position X="0" Y="0" Z="0"/>
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0" Z="0"/>
<Scale X="100" Y="1" Z="100"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitPlane.obj</Resource>
</c:Model>
</Components>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="1" Y="1" Z="0"/>
<Orientation X="0" Y="0.78539" Z="0"/>
</c:Transform>
<c:Model>
<Resource>An error</Resource>
</c:Model>
</Components>
<Children>
<Entity>
<Components>
<c:Transform>
<Position X="2" Y="0" Z="0"/>
<Orientation X="0" Y="0.78539" Z="0"/>
</c:Transform>
<c:Model>
<Resource>An error</Resource>
</c:Model>
</Components>
<Children>
</Children>
</Entity>
</Children>
</Entity>
</Children>
</Entity> </Entity>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:Camera/>
<c:Transform>
<Position X="-8.58846378" Y="9.3929615" Z="14.3944101"/>
<Orientation X="-0.645772398" Y="-0.314115167" Z="-4.700399e-08"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource></Resource>
</c:Model>
<c:Transform/>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+1
View File
@@ -16,6 +16,7 @@
<xs:element ref="c:RaptorCopter" minOccurs="0"/> <xs:element ref="c:RaptorCopter" minOccurs="0"/>
<xs:element ref="c:Player" minOccurs="0"/> <xs:element ref="c:Player" minOccurs="0"/>
<xs:element ref="c:Health" minOccurs="0"/> <xs:element ref="c:Health" minOccurs="0"/>
<xs:element ref="c:PointLight" minOccurs="0"/>
<xs:element ref="c:Listener" minOccurs="0"/> <xs:element ref="c:Listener" minOccurs="0"/>
<xs:element ref="c:SoundEmitter" minOccurs="0"/> <xs:element ref="c:SoundEmitter" minOccurs="0"/>
</xs:all> </xs:all>
+154
View File
@@ -0,0 +1,154 @@
#version 430
//in uvec3 gl_NumWorkGroups; //contains the number of workgroups that have been dispatched to a compute shader
//in uvec3 gl_WorkGroupID; //contains the index of the workgroup currently being operated on by a compute shader
//in uvec3 gl_LocalInvocationID; //contains the index of work item currently being operated on by a compute shader
//in uvec3 gl_GlobalInvocationID; //contains the global index of work item currently being operated on by a compute shader
//in uint gl_LocalInvocationIndex; //contains the local linear index of work item currently being operated on by a compute shader
#define MAX_LIGHTS_PER_TILE 200
#define TILE_SIZE 16
uniform mat4 V;
uniform vec2 ScreenDimensions;
struct Plane {
vec3 Normal;
float d;
};
struct Frustum {
Plane Planes[4];
};
layout (std430, binding = 0) buffer FrustumBuffer
{
Frustum Data[];
} Frustums;
struct PointLight {
vec4 Position;
vec4 Color;
float Radius;
float Intensity;
float Falloff;
float Padding;
};
layout (std430, binding = 1) buffer LightBuffer
{
PointLight List[];
} PointLights;
struct LightGrid {
float Start;
float Amount;
vec2 Padding;
};
layout (std430, binding = 2) buffer LightGridBuffer
{
LightGrid Data[];
} LightGrids;
layout (std430, binding = 3) buffer LightOffsetBuffer
{
int LightOffset[];
};
layout (std430, binding = 4) buffer LightIndexBuffer
{
float LightIndex[];
};
shared int GroupLightCount;
shared int GroupLightIndexStartOffset;
shared int GroupLightIndex[MAX_LIGHTS_PER_TILE];
shared Frustum GroupFrustum;
int GroupIndex;
bool SphereInsidePlane(vec3 center, float radius, Plane plane)
{
return dot(plane.Normal, center) - plane.d > -radius;
}
bool SphereInsideFrustrum(vec3 center, float radius, Frustum frustum/*, float zNear, float zFar*/)
{
//Check depth here
//if ( sphere.c.z - sphere.r > zNear || sphere.c.z + sphere.r < zFar )
//{
// result = false;
//}
for (int i =0; i < 4; i++)
{
if(! SphereInsidePlane(center, radius, frustum.Planes[i]))
{
return false;
}
}
return true;
}
void AppendLight(int li)
{
int index;
index = atomicAdd(GroupLightCount, 1);
if( index < MAX_LIGHTS_PER_TILE )
{
GroupLightIndex[index] = int(li);
}
}
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main ()
{
GroupIndex = int(gl_WorkGroupID.x + (gl_WorkGroupID.y * int(ScreenDimensions.x/TILE_SIZE)));
if(gl_LocalInvocationIndex == 0)
{
GroupLightCount = 0;
GroupFrustum = Frustums.Data[GroupIndex];
}
barrier();
memoryBarrierShared();
for(int i = int(gl_LocalInvocationIndex); i < PointLights.List.length(); i += TILE_SIZE*TILE_SIZE)
{
PointLight light = PointLights.List[i];
//if pointlight
//Pos i view antagligen
if(SphereInsideFrustrum( vec3(V * light.Position), light.Radius, GroupFrustum))
{
//TODO: Fix transparent and opaque list, and depth test.
AppendLight( i );
}
//if conelight
//if directional
}
barrier();
memoryBarrierShared();
if(gl_LocalInvocationIndex == 0)
{
GroupLightIndexStartOffset = atomicAdd(LightOffset[0], GroupLightCount);
LightGrids.Data[GroupIndex].Start = GroupLightIndexStartOffset;
LightGrids.Data[GroupIndex].Amount = GroupLightCount;
}
barrier();
for (uint i = gl_LocalInvocationIndex; i < GroupLightCount; i += TILE_SIZE * TILE_SIZE )
{
LightIndex[GroupLightIndexStartOffset + i] = GroupLightIndex[i];
}
}
+132
View File
@@ -0,0 +1,132 @@
#version 430
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform vec4 Color;
uniform vec2 ScreenDimensions;
uniform sampler2D texture0;
#define TILE_SIZE 16
struct PointLight {
vec4 Position;
vec4 Color;
float Radius;
float Intensity;
float Falloff;
float Padding;
};
layout (std430, binding = 1) buffer LightBuffer
{
PointLight List[];
} PointLights;
struct LightGrid {
float Start;
float Amount;
vec2 Padding;
};
layout (std430, binding = 2) buffer LightGridBuffer
{
LightGrid Data[];
} LightGrids;
layout (std430, binding = 4) buffer LightIndexBuffer
{
float LightIndex[];
};
in VertexData{
vec3 Position;
vec3 Normal;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Input;
out vec4 fragmentColor;
vec4 scene_ambient = vec4(0.3,0.3,0.3,1);
struct LightResult {
vec4 Diffuse;
vec4 Specular;
};
float CalcAttenuation(float radius, float dist, float falloff) {
return 1.0 - smoothstep(radius * 0.3, radius, dist);
}
vec4 CalcSpecular(vec4 lightColor, vec4 viewVec, vec4 lightVec, vec4 normal) {
vec4 R = normalize( reflect(-lightVec, normal));
float RdotV = max( dot(R, viewVec), 0.0);
return lightColor * pow(RdotV, 90.0);
}
vec4 CalcDiffuse(vec4 lightColor, vec4 lightVec, vec4 normal) {
float power = max( dot(normal, lightVec), 0.0);
return lightColor * power;
}
LightResult CalcPointLight(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff)
{
vec4 L = lightPos - position;
float dist = length(L);
L = normalize(L);
float attenuation = CalcAttenuation(lightRadius, dist, falloff);
LightResult result;
result.Diffuse = CalcDiffuse(lightColor, L, normal) * attenuation * intensity;
result.Specular = CalcSpecular(lightColor, viewVec, L, normal) * attenuation * intensity;
return result;
}
void main()
{
vec4 texel = texture2D(texture0, Input.TextureCoordinate);
vec4 position = V * M * vec4(Input.Position, 1.0);
vec4 normal = V * vec4(Input.Normal, 0.0);
vec4 viewVec = normalize(-position);
vec2 tilePos;
tilePos.x = int(gl_FragCoord.x/16);
tilePos.y = int(gl_FragCoord.y/16);
LightResult totalLighting;
totalLighting.Diffuse = scene_ambient;
int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE)));
int start = int(LightGrids.Data[currentTile].Start);
int amount = int(LightGrids.Data[currentTile].Amount);
//for(int i = 0; i < 3; i++)
for(int i = start; i < start + amount; i++)
{
int l = int(LightIndex[i]);
LightResult result = CalcPointLight(V * PointLights.List[l].Position, PointLights.List[l].Radius, PointLights.List[l].Color, PointLights.List[l].Intensity, viewVec, position, normal, PointLights.List[i].Falloff);
totalLighting.Diffuse += result.Diffuse;
totalLighting.Specular += result.Specular;
}
fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color;
//fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color;
//fragmentColor += vec4(0.0, LightGrids.Data[currentTile].Amount/3.0, 0, 1);
//fragmentColor = texel * Input.DiffuseColor * Color;
if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 )
{
//fragmentColor += vec4(0.5, 0, 0, 0);
} else {
//fragmentColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/3.0, 0, 0, 1);
}
}
+34
View File
@@ -0,0 +1,34 @@
#version 430
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec3 Tangent;
layout(location = 3) in vec3 BiTangent;
layout(location = 4) in vec2 TextureCoords;
layout(location = 5) in vec4 DiffuseVertexColor;
layout(location = 6) in vec4 SpecularVertexColor;
layout(location = 7) in vec4 BoneIndices1;
layout(location = 8) in vec4 BoneIndices2;
layout(location = 9) in vec4 BoneWeights1;
layout(location = 10) in vec4 BoneWeights2;
out VertexData{
vec3 Position;
vec3 Normal;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Output;
void main()
{
gl_Position = P*V*M * vec4(Position, 1.0);
Output.Position = Position;
Output.TextureCoordinate = TextureCoords;
Output.Normal = Normal;
Output.DiffuseColor = DiffuseVertexColor;
}
+27 -25
View File
@@ -1,7 +1,6 @@
#version 430 #version 430
#define TILE_SIZE 16 #define TILE_SIZE 16
#define NUM_TILES 3600
uniform mat4 P; uniform mat4 P;
uniform vec2 ScreenDimensions; uniform vec2 ScreenDimensions;
@@ -16,7 +15,7 @@ struct Frustum {
layout (std430, binding = 0) buffer FrustumBuffer layout (std430, binding = 0) buffer FrustumBuffer
{ {
Frustum Data[3600]; Frustum Data[];
} Frustums; } Frustums;
vec4 ConvertToView(vec4 ScreenCoords) vec4 ConvertToView(vec4 ScreenCoords)
@@ -43,31 +42,34 @@ Plane ComputePlane( vec3 p0, vec3 p1, vec3 p2 )
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main () void main ()
{ {
if(gl_GlobalInvocationID.x * TILE_SIZE < ScreenDimensions.x && gl_GlobalInvocationID.y * TILE_SIZE < ScreenDimensions.y) { //Top-Left = 0 | Top-Right = 1
//Top-Left = 0 | Top-Right = 1 //Bottom-Left = 2 | Bottom-Right = 3
//Bottom-Left = 2 | Bottom-Right = 3 vec4 ScreenCoords[4];
vec4 ScreenCoords[4]; ScreenCoords[0] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0);
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[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[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);
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]);
vec3 ViewVectors[4];
Frustums.Data[gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*80] = f; for(int i = 0; i < 4; i++) {
ViewVectors[i] = vec3(ConvertToView(ScreenCoords[i]));
} }
vec3 EyePos = vec3(0.0, 0.0 ,0.0);
Frustum f;
f.Planes[0] = ComputePlane(EyePos, ViewVectors[2], ViewVectors[0]); // left plane
f.Planes[1] = ComputePlane(EyePos, ViewVectors[1], ViewVectors[3]); // right plane
f.Planes[2] = ComputePlane(EyePos, ViewVectors[0], ViewVectors[1]); // top plane
f.Planes[3] = ComputePlane(EyePos, ViewVectors[3], ViewVectors[2]); // bottom plane
if ( gl_GlobalInvocationID.x < ScreenDimensions.x / TILE_SIZE && gl_GlobalInvocationID.y < ScreenDimensions.y / TILE_SIZE ) { // inside the screen
Frustums.Data[gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*int(ScreenDimensions.x/TILE_SIZE)] = f;
}
} }
-35
View File
@@ -1,35 +0,0 @@
#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) {
}
}
+3 -3
View File
@@ -225,11 +225,11 @@ bool attachAABBComponentFromModel(World* world, EntityID id)
return false; return false;
} }
glm::mat4 modelMatrix = modelRes->m_Matrix; glm::mat4 modelMatrix = modelRes->Matrix();
glm::vec3 mini = glm::vec3(INFINITY, INFINITY, INFINITY); glm::vec3 mini = glm::vec3(INFINITY, INFINITY, INFINITY);
glm::vec3 maxi = glm::vec3(-INFINITY, -INFINITY, -INFINITY); glm::vec3 maxi = glm::vec3(-INFINITY, -INFINITY, -INFINITY);
for (const auto& v : modelRes->m_Vertices) { for (const auto& v : modelRes->Vertices()) {
const auto& wPos = modelMatrix * glm::vec4(v.Position.x, v.Position.y, v.Position.z, 1); const auto& wPos = modelMatrix * glm::vec4(v.Position.x, v.Position.y, v.Position.z, 1);
maxi.x = std::max(wPos.x, maxi.x); maxi.x = std::max(wPos.x, maxi.x);
maxi.y = std::max(wPos.y, maxi.y); maxi.y = std::max(wPos.y, maxi.y);
@@ -255,7 +255,7 @@ bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox)
if (modelRes == nullptr) { if (modelRes == nullptr) {
return false; return false;
} }
glm::mat4 modelMatrix = modelRes->m_Matrix * glm::mat4 modelMatrix = modelRes->Matrix() *
glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) * glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) *
glm::scale((glm::vec3)cTrans["Scale"]); glm::scale((glm::vec3)cTrans["Scale"]);
+56 -48
View File
@@ -1,4 +1,7 @@
#include "Core/ResourceManager.h" #include "Core/ResourceManager.h"
#include "boost/thread/thread.hpp"
#include "boost/thread/mutex.hpp"
#include "boost/thread/lock_guard.hpp"
std::unordered_map<std::string, std::string> ResourceManager::m_CompilerTypenameToResourceType; std::unordered_map<std::string, std::string> ResourceManager::m_CompilerTypenameToResourceType;
std::unordered_map<std::string, std::function<Resource*(std::string)>> ResourceManager::m_FactoryFunctions; std::unordered_map<std::string, std::function<Resource*(std::string)>> ResourceManager::m_FactoryFunctions;
@@ -6,10 +9,13 @@ std::unordered_map<std::pair<std::string, std::string>, Resource*> ResourceManag
std::unordered_map<std::string, Resource*> ResourceManager::m_ResourceFromName; std::unordered_map<std::string, Resource*> ResourceManager::m_ResourceFromName;
std::unordered_map<Resource*, Resource*> ResourceManager::m_ResourceParents; std::unordered_map<Resource*, Resource*> ResourceManager::m_ResourceParents;
unsigned int ResourceManager::m_CurrentResourceTypeID = 0; unsigned int ResourceManager::m_CurrentResourceTypeID = 0;
bool ResourceManager::UseThreading = false;
std::unordered_map<std::string, unsigned int> ResourceManager::m_ResourceTypeIDs; std::unordered_map<std::string, unsigned int> ResourceManager::m_ResourceTypeIDs;
std::unordered_map<unsigned int, unsigned int> ResourceManager::m_ResourceCount; std::unordered_map<unsigned int, unsigned int> ResourceManager::m_ResourceCount;
bool ResourceManager::m_Preloading = false;
FileWatcher ResourceManager::m_FileWatcher; FileWatcher ResourceManager::m_FileWatcher;
std::unordered_map<std::pair<std::string, std::string>, boost::thread> ResourceManager::m_LoadingThreads;
std::unordered_map<std::pair<std::string, std::string>, std::exception_ptr> ResourceManager::m_LoadingThreadExceptions;
boost::recursive_mutex ResourceManager::m_Mutex;
unsigned int ResourceManager::GetTypeID(std::string resourceType) unsigned int ResourceManager::GetTypeID(std::string resourceType)
{ {
@@ -74,63 +80,65 @@ void ResourceManager::Update()
m_FileWatcher.Check(); m_FileWatcher.Check();
} }
void ResourceManager::Preload(std::string resourceType, std::string resourceName) Resource* ResourceManager::createResource(const std::string& resourceType, const std::string& resourceName, Resource* parent, std::exception_ptr& exception)
{
if (IsResourceLoaded(resourceType, resourceName)) {
//LOG_WARNING("Attempted to preload resource \"%s\" multiple times!", resourceName.c_str());
return;
}
m_Preloading = true;
LOG_INFO("Preloading resource \"%s\"", resourceName.c_str());
CreateResource(resourceType, resourceName, nullptr);
m_Preloading = false;
}
Resource* ResourceManager::Load(std::string resourceType, std::string resourceName, Resource* parent /*= nullptr*/)
{
auto it = m_ResourceCache.find(std::make_pair(resourceType, resourceName));
if (it != m_ResourceCache.end()) {
return 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(resourceType, resourceName, parent);
}
Resource* ResourceManager::CreateResource(std::string resourceType, std::string resourceName, Resource* parent)
{ {
auto facIt = m_FactoryFunctions.find(resourceType); auto facIt = m_FactoryFunctions.find(resourceType);
if (facIt == m_FactoryFunctions.end()) { if (facIt == m_FactoryFunctions.end()) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceType.c_str()); LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceType.c_str());
return nullptr; cacheResource(nullptr, resourceType, resourceName, parent);
//This basically throws an exception.
exception = std::make_exception_ptr(Resource::FailedLoadingException()); return nullptr;
} }
// Call the factory function // Call the factory function
Resource* resource;
try { try {
resource = facIt->second(resourceName); return cacheResource(facIt->second(resourceName), resourceType, resourceName, parent);
} catch (const Resource::StillLoadingException&) {
exception = std::current_exception(); return nullptr;
} catch (const std::exception& e) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": %s", resourceName.c_str(), resourceType.c_str(), e.what());
cacheResource(nullptr, resourceType, resourceName, parent);
exception = std::current_exception(); return nullptr;
}
}
Resource* ResourceManager::createResourceThrowing(const std::string& resourceType, const std::string& resourceName, Resource* parent)
{
std::exception_ptr exception;
Resource* res = createResource(resourceType, resourceName, parent, exception);
if (exception) {
std::rethrow_exception(exception);
}
return res;
}
Resource* ResourceManager::cacheResource(Resource* resource, const std::string& resourceType, const std::string& resourceName, Resource* parent)
{
//Lock the mutex immediately, and unlock it when leaving the code block.
boost::lock_guard<decltype(m_Mutex)> guard(m_Mutex);
if (resource != nullptr) {
// Store IDs // Store IDs
resource->TypeID = GetTypeID(resourceType); resource->TypeID = GetTypeID(resourceType);
resource->ResourceID = GetNewResourceID(resource->TypeID); resource->ResourceID = GetNewResourceID(resource->TypeID);
} catch (const std::exception& e) {
resource = nullptr;
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": %s", resourceName.c_str(), resourceType.c_str(), e.what());
} }
// Cache
m_ResourceCache[std::make_pair(resourceType, resourceName)] = resource; // Cache
m_ResourceFromName[resourceName] = resource; m_ResourceCache[std::make_pair(resourceType, resourceName)] = resource;
if (parent != nullptr) { m_ResourceFromName[resourceName] = resource;
m_ResourceParents[resource] = parent; 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); //if (!boost::filesystem::is_directory(resourceName)) {
} // LOG_DEBUG("Adding watch for %s", resourceName.c_str());
return resource; // m_FileWatcher.AddWatch(resourceName, fileWatcherCallback);
//}
return resource;
}
bool ResourceManager::IsMainThread()
{
static boost::thread::id MainThreadId = boost::this_thread::get_id();
return boost::this_thread::get_id() == MainThreadId;
} }
+66
View File
@@ -0,0 +1,66 @@
#include "Rendering/DrawFinalPass.h"
DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass)
{
m_Renderer = renderer;
m_LightCullingPass = lightCullingPass;
InitializeTextures();
InitializeShaderPrograms();
}
void DrawFinalPass::InitializeTextures()
{
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
}
void DrawFinalPass::InitializeShaderPrograms()
{
m_ForwardPlusProgram = ResourceManager::Load<ShaderProgram>("#ForwardPlusProgram");
m_ForwardPlusProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/ForwardPlus.vert.glsl")));
m_ForwardPlusProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/ForwardPlus.frag.glsl")));
m_ForwardPlusProgram->Compile();
m_ForwardPlusProgram->Link();
}
void DrawFinalPass::Draw(RenderScene& scene)
{
GLERROR("DrawFinalPass::Draw: Pre");
DrawFinalPassState state;
m_ForwardPlusProgram->Bind();
GLuint shaderHandle = m_ForwardPlusProgram->GetHandle();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO());
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()));
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
//TODO: Render: Add code for more jobs than modeljobs.
for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if(modelJob) {
//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->Matrix));
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
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("DrawFinalPass::Draw: END");
}
@@ -0,0 +1,18 @@
#include "Rendering/DrawFinalPassState.h"
DrawFinalPassState::DrawFinalPassState()
{
BindFramebuffer(0);
Enable(GL_BLEND);
BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
ClearColor(glm::vec4(200.f / 255, 0.f / 255, 200.f / 255, 0.f));
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
DrawFinalPassState::~DrawFinalPassState()
{
}
+4 -5
View File
@@ -14,7 +14,6 @@ void DrawScenePass::InitializeTextures()
void DrawScenePass::InitializeShaderPrograms() 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 = 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 VertexShader("Shaders/BasicForward.vert.glsl")));
@@ -26,16 +25,16 @@ void DrawScenePass::InitializeShaderPrograms()
void DrawScenePass::Draw(RenderScene& scene) void DrawScenePass::Draw(RenderScene& scene)
{ {
//glBindFramebuffer(GL_FRAMEBUFFER, 0); //glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLERROR("Renderer::Draw PickingPass"); GLERROR("DrawScenePass::Draw: Pre");
DrawScenePassState state = DrawScenePassState(); DrawScenePassState state = DrawScenePassState();
m_BasicForwardProgram->Bind();
for (auto &job : scene.ForwardJobs) { for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job); auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if (modelJob) { if (modelJob) {
GLuint ShaderHandle = m_BasicForwardProgram->GetHandle(); GLuint ShaderHandle = m_BasicForwardProgram->GetHandle();
m_BasicForwardProgram->Bind();
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms //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->Matrix)); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
@@ -57,7 +56,7 @@ void DrawScenePass::Draw(RenderScene& scene)
//continue; //continue;
} }
}
GLERROR("DrawScene Error"); }
GLERROR("DrawScenePass::Draw: End");
} }
+151
View File
@@ -0,0 +1,151 @@
#include "Rendering/LightCullingPass.h"
LightCullingPass::LightCullingPass(IRenderer* renderer)
{
m_Renderer = renderer;
SetSSBOSizes();
InitializeSSBOs();
InitializeShaderPrograms();
//GenerateNewFrustum(TODO);
}
LightCullingPass::~LightCullingPass()
{
}
void LightCullingPass::GenerateNewFrustum(RenderScene& scene)
{
if (scene.PointLightJobs.size() == 0)
return;
GLERROR("CalculateFrustum Error: Pre");
m_CalculateFrustumProgram->Bind();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
glDispatchCompute((int)(m_Renderer->Resolution().Width/(TILE_SIZE*TILE_SIZE) + 1), (int)(m_Renderer->Resolution().Height/(TILE_SIZE*TILE_SIZE) + 1), 1);
GLERROR("CalculateFrustum Error: End");
}
void LightCullingPass::OnResolutionChange()
{
SetSSBOSizes();
}
void LightCullingPass::SetSSBOSizes()
{
m_NumberOfTiles = (int)(m_Renderer->Resolution().Width*m_Renderer->Resolution().Height)/TILE_SIZE;
//m_Frustums = new Frustum[s];
//m_LightGrid = new LightGrid[s];
//m_LightIndex = new float[s*200];
m_Frustums = new Frustum[m_NumberOfTiles];
m_LightGrid = new LightGrid[m_NumberOfTiles];
m_LightIndex = new float[m_NumberOfTiles*MAX_LIGHTS_PER_TILE];
}
void LightCullingPass::CullLights(RenderScene& scene)
{
GLERROR("CullLights Error: Pre");
m_LightOffset = 0;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
if (m_PointLights.size() > 0) {
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(PointLight) * m_PointLights.size(), &(m_PointLights[0]), GL_DYNAMIC_COPY);
} else {
GLfloat zero = 0.f;
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat), &zero , GL_DYNAMIC_COPY);
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
m_LightCullProgram->Bind();
glUniform2f(glGetUniformLocation(m_LightCullProgram->GetHandle(), "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(scene.Camera->ViewMatrix()));
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_Renderer->Resolution().Width / TILE_SIZE, m_Renderer->Resolution().Height / TILE_SIZE, 1);
GLERROR("CullLights Error: End");
}
void LightCullingPass::FillLightList(RenderScene& scene)
{
m_PointLights.clear();
for(auto &job : scene.PointLightJobs) {
auto pointLightjob = std::dynamic_pointer_cast<PointLightJob>(job);
if (pointLightjob) {
PointLight p;
p.Color = pointLightjob->Color;
p.Falloff = pointLightjob->Falloff;
p.Intensity = pointLightjob->Intensity;
p.Position = glm::vec4(glm::vec3(pointLightjob->Position), 1.f);
p.Radius = pointLightjob->Radius;
p.Padding = 123.f;
m_PointLights.push_back(p);
continue;
}
}
}
void LightCullingPass::InitializeSSBOs()
{
glGenBuffers(1, &m_FrustumSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Frustum)*m_NumberOfTiles, m_Frustums, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_FrustumSSBO");
glGenBuffers(1, &m_LightSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
if(m_PointLights.size() > 0) {
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(PointLight) * m_PointLights.size(), &(m_PointLights[0]), GL_DYNAMIC_COPY);
}
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(LightGrid)*m_NumberOfTiles, m_LightGrid, GL_DYNAMIC_COPY);
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);
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(float)*m_NumberOfTiles*MAX_LIGHTS_PER_TILE, m_LightIndex, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightIndexSSBO");
}
void LightCullingPass::InitializeShaderPrograms()
{
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();
}
+62 -48
View File
@@ -1,60 +1,74 @@
#include "Rendering/Model.h" #include "Rendering/Model.h"
Model::Model(std::string fileName) Model::Model(std::string fileName)
: RawModel(fileName)
{ {
// Generate GL buffers //Try loading the model asyncronously, if it throws any exceptions then let it propagate back to caller.
GLuint buffer; m_RawModel = ResourceManager::Load<RawModel, true>(fileName);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &ElementBuffer); for (auto& group : m_RawModel->MaterialGroups) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer); if (!group.TexturePath.empty()) {
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(unsigned int), &m_Indices[0], GL_STATIC_DRAW); group.Texture = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.TexturePath));
}
if (!group.NormalMapPath.empty()) {
group.NormalMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.NormalMapPath));
}
if (!group.SpecularMapPath.empty()) {
group.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.SpecularMapPath));
}
}
glGenVertexArrays(1, &VAO); // Generate GL buffers
glBindVertexArray(VAO); GLuint buffer;
GLERROR("GLEW: BufferFail4"); glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, m_RawModel->m_Vertices.size() * sizeof(RawModel::Vertex), &m_RawModel->m_Vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, buffer); glGenBuffers(1, &ElementBuffer);
std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4, 4, 4, 4, 4 }; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBuffer);
int stride = 0; glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_RawModel->m_Indices.size() * sizeof(unsigned int), &m_RawModel->m_Indices[0], GL_STATIC_DRAW);
for (int size : structSizes) {
stride += size;
}
stride *= sizeof(GLfloat);
int offset = 0;
{
int element = 0;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * offset)); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
}
GLERROR("GLEW: BufferFail5");
glEnableVertexAttribArray(0); glGenVertexArrays(1, &VAO);
glEnableVertexAttribArray(1); glBindVertexArray(VAO);
glEnableVertexAttribArray(2); GLERROR("GLEW: BufferFail4");
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glEnableVertexAttribArray(6);
glEnableVertexAttribArray(7);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(9);
glEnableVertexAttribArray(10);
GLERROR("GLEW: BufferFail5");
//CreateBuffers(); glBindBuffer(GL_ARRAY_BUFFER, buffer);
std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4, 4, 4, 4, 4 };
int stride = 0;
for (int size : structSizes) {
stride += size;
}
stride *= sizeof(GLfloat);
int offset = 0;
{
int element = 0;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * offset)); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
}
GLERROR("GLEW: BufferFail5");
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glEnableVertexAttribArray(6);
glEnableVertexAttribArray(7);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(9);
glEnableVertexAttribArray(10);
GLERROR("GLEW: BufferFail5");
//CreateBuffers();
} }
Model::~Model() Model::~Model()
+4 -10
View File
@@ -145,9 +145,7 @@ RawModel::RawModel(std::string fileName)
aiString path; aiString path;
aiTextureMapping mapping; aiTextureMapping mapping;
material->GetTexture(aiTextureType_DIFFUSE, 0, &path, &mapping); material->GetTexture(aiTextureType_DIFFUSE, 0, &path, &mapping);
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string(); matGroup.TexturePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
//LOG_DEBUG("Diffuse texture: %s", absolutePath.c_str());
matGroup.Texture = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
} }
// Normal map // Normal map
//LOG_DEBUG("%i normal maps found", material->GetTextureCount(aiTextureType_HEIGHT)); //LOG_DEBUG("%i normal maps found", material->GetTextureCount(aiTextureType_HEIGHT));
@@ -155,9 +153,7 @@ RawModel::RawModel(std::string fileName)
aiString path; aiString path;
aiTextureMapping mapping; aiTextureMapping mapping;
material->GetTexture(aiTextureType_HEIGHT, 0, &path, &mapping); material->GetTexture(aiTextureType_HEIGHT, 0, &path, &mapping);
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string(); matGroup.NormalMapPath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
//LOG_DEBUG("Normal map: %s", absolutePath.c_str());
matGroup.NormalMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
} }
// Specular map // Specular map
//LOG_DEBUG("%i specular maps found", material->GetTextureCount(aiTextureType_SPECULAR)); //LOG_DEBUG("%i specular maps found", material->GetTextureCount(aiTextureType_SPECULAR));
@@ -165,11 +161,9 @@ RawModel::RawModel(std::string fileName)
aiString path; aiString path;
aiTextureMapping mapping; aiTextureMapping mapping;
material->GetTexture(aiTextureType_SPECULAR, 0, &path, &mapping); material->GetTexture(aiTextureType_SPECULAR, 0, &path, &mapping);
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string(); matGroup.SpecularMapPath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
//LOG_DEBUG("Specular map: %s", absolutePath.c_str());
matGroup.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
} }
TextureGroups.push_back(matGroup); MaterialGroups.push_back(matGroup);
// Bones // Bones
std::map<int, std::vector<std::tuple<int, float>>> vertexWeights; std::map<int, std::vector<std::tuple<int, float>>> vertexWeights;
+1
View File
@@ -3,6 +3,7 @@
bool RenderState::Enable(GLenum cap) bool RenderState::Enable(GLenum cap)
{ {
if (glIsEnabled(cap)) { if (glIsEnabled(cap)) {
//LOG_WARNING("Trying to enable somthing that is already enabled.");
return false; return false;
} }
m_ResetFunctions.push_back(std::bind(glDisable, cap)); m_ResetFunctions.push_back(std::bind(glDisable, cap));
+43 -11
View File
@@ -90,20 +90,51 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World
continue; continue;
} }
Model* model = ResourceManager::Load<::Model>(resource); Model* model;
if (model == nullptr) { try {
model = ResourceManager::Load<::Model>("Models/Core/Error.obj"); model = ResourceManager::Load<::Model, true>(resource);
} catch (const Resource::StillLoadingException&) {
//continue;
model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.obj");
} catch (const std::exception&) {
try {
model = ResourceManager::Load<::Model>("Models/Core/Error.obj");
} catch (const std::exception&) {
continue;
}
} }
glm::mat4 modelMatrix = Transform::ModelMatrix(modelComponent.EntityID, world); glm::mat4 modelMatrix = Transform::ModelMatrix(modelComponent.EntityID, world);
for (auto matGroup : model->MaterialGroups()) {
for (auto texGroup : model->TextureGroups) { std::shared_ptr<ModelJob> modelJob = std::shared_ptr<ModelJob>(new ModelJob(model, m_Camera, modelMatrix, matGroup, modelComponent, world));
std::shared_ptr<ModelJob> modelJob = std::shared_ptr<ModelJob>(new ModelJob(model, m_Camera, modelMatrix, texGroup, modelComponent, world));
jobs.push_back(modelJob); jobs.push_back(modelJob);
} }
} }
} }
void RenderSystem::fillLight(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
{
auto pointLights = world->GetComponents("PointLight");
if (pointLights == nullptr) {
return;
}
for (auto& pointlightC : *pointLights) {
bool visible = pointlightC["Visible"];
if (!visible) {
continue;
}
auto transformC = world->GetComponent(pointlightC.EntityID, "Transform");
if (&transformC == nullptr) {
return;
}
std::shared_ptr<PointLightJob> pointLightJob = std::shared_ptr<PointLightJob>(new PointLightJob(transformC, pointlightC, m_World));
jobs.push_back(pointLightJob);
}
}
bool RenderSystem::OnInputCommand(const Events::InputCommand& e) bool RenderSystem::OnInputCommand(const Events::InputCommand& e)
{ {
if (e.Command == "SwitchCamera" && e.Value > 0) { if (e.Command == "SwitchCamera" && e.Value > 0) {
@@ -124,11 +155,12 @@ void RenderSystem::Update(World* world, double dt)
//Only supports opaque geometry atm //Only supports opaque geometry atm
m_RenderFrame->Clear(); m_RenderFrame->Clear();
RenderScene rs; RenderScene scene;
rs.Camera = m_Camera; scene.Camera = m_Camera;
rs.Viewport = Rectangle(1280, 720); scene.Viewport = Rectangle(1280, 720);
fillModels(rs.ForwardJobs, world); fillModels(scene.ForwardJobs, world);
m_RenderFrame->Add(rs); fillLight(scene.PointLightJobs, world);
m_RenderFrame->Add(scene);
} }
+33 -8
View File
@@ -92,16 +92,22 @@ void Renderer::Update(double dt)
void Renderer::Draw(RenderFrame& frame) void Renderer::Draw(RenderFrame& frame)
{ {
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f); glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_PickingPass->ClearPicking(); m_PickingPass->ClearPicking();
for (auto scene : frame.RenderScenes){ for (auto scene : frame.RenderScenes){
m_Camera = scene->Camera; // remove renderer camera when Editor uses the render scene cameras. m_Camera = scene->Camera; // remove renderer camera when Editor uses the render scene cameras.
FillDepth(*scene);
m_PickingPass->Draw(*scene); m_PickingPass->Draw(*scene);
m_LightCullingPass->GenerateNewFrustum(*scene);
m_LightCullingPass->FillLightList(*scene);
m_LightCullingPass->CullLights(*scene);
m_DrawFinalPass->Draw(*scene);
//m_DrawScenePass->Draw(rq);
m_DrawScenePass->Draw(*scene);
GLERROR("Renderer::Draw m_DrawScenePass->Draw"); GLERROR("Renderer::Draw m_DrawScenePass->Draw");
} }
@@ -131,14 +137,14 @@ void Renderer::DrawScreenQuad(GLuint textureToDraw)
glBindVertexArray(m_ScreenQuad->VAO); glBindVertexArray(m_ScreenQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->TextureGroups[0].EndIndex - m_ScreenQuad->TextureGroups[0].StartIndex +1 glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].EndIndex - m_ScreenQuad->MaterialGroups()[0].StartIndex +1
, GL_UNSIGNED_INT, 0, m_ScreenQuad->TextureGroups[0].StartIndex); , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].StartIndex);
} }
void Renderer::InitializeTextures() void Renderer::InitializeTextures()
{ {
m_ErrorTexture=ResourceManager::Load<Texture>("Textures/Core/ErrorTexture.png"); m_ErrorTexture = ResourceManager::Load<Texture>("Textures/Core/ErrorTexture.png");
m_WhiteTexture=ResourceManager::Load<Texture>("Textures/Core/Blank.png"); m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
} }
void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
@@ -149,7 +155,7 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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_MIN_FILTER, filtering);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, NULL);//TODO: Renderer: Fix the precision and Resolution 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"); GLERROR("Texture initialization failed");
} }
@@ -157,4 +163,23 @@ void Renderer::InitializeRenderPasses()
{ {
m_DrawScenePass = new DrawScenePass(this); m_DrawScenePass = new DrawScenePass(this);
m_PickingPass = new PickingPass(this, m_EventBroker); m_PickingPass = new PickingPass(this, m_EventBroker);
m_LightCullingPass = new LightCullingPass(this);
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass);
}
//Temp func
void Renderer::FillDepth(RenderScene& scene)
{
for (auto job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if(! modelJob) {
return;
}
glm::vec3 abspos = Transform::AbsolutePosition(modelJob->World, modelJob->Entity);
glm::vec3 worldpos = glm::vec3(scene.Camera->ViewMatrix() * glm::vec4(abspos, 1));
modelJob->Depth = worldpos.z;
}
scene.ForwardJobs.sort(Renderer::DepthSort);
} }
+32 -32
View File
@@ -2,48 +2,48 @@
Texture::Texture(std::string path) Texture::Texture(std::string path)
{ {
PNG image(path); PNG image(path);
if (image.Width == 0 && image.Height == 0 || image.Format == Image::ImageFormat::Unknown) { if (image.Width == 0 && image.Height == 0 || image.Format == Image::ImageFormat::Unknown) {
image = PNG("Textures/Core/ErrorTexture.png"); image = PNG("Textures/Core/ErrorTexture.png");
if (image.Width == 0 && image.Height == 0 || image.Format == Image::ImageFormat::Unknown) { if (image.Width == 0 && image.Height == 0 || image.Format == Image::ImageFormat::Unknown) {
LOG_ERROR("Couldn't even load the error texture. This is a dark day indeed."); LOG_ERROR("Couldn't even load the error texture. This is a dark day indeed.");
return; return;
} }
} }
this->Width = image.Width; this->Width = image.Width;
this->Height = image.Height; this->Height = image.Height;
GLint format; GLint format;
switch (image.Format) { switch (image.Format) {
case Image::ImageFormat::RGB: case Image::ImageFormat::RGB:
format = GL_RGB; format = GL_RGB;
break; break;
case Image::ImageFormat::RGBA: case Image::ImageFormat::RGBA:
format = GL_RGBA; format = GL_RGBA;
break; break;
} }
// Construct the OpenGL texture // Construct the OpenGL texture
glGenTextures(1, &m_Texture); glGenTextures(1, &m_Texture);
glBindTexture(GL_TEXTURE_2D, m_Texture); glBindTexture(GL_TEXTURE_2D, m_Texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, format, image.Width, image.Height, 0, format, GL_UNSIGNED_BYTE, image.Data); glTexImage2D(GL_TEXTURE_2D, 0, format, image.Width, image.Height, 0, format, GL_UNSIGNED_BYTE, image.Data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLERROR("Texture load"); GLERROR("Texture load");
} }
Texture::~Texture() Texture::~Texture()
{ {
glDeleteTextures(1, &m_Texture); glDeleteTextures(1, &m_Texture);
} }
void Texture::Bind(GLenum textureUnit /* = GL_TEXTURE0 */) void Texture::Bind(GLenum textureUnit /* = GL_TEXTURE0 */)
{ {
glActiveTexture(textureUnit); glActiveTexture(textureUnit);
glBindTexture(GL_TEXTURE_2D, m_Texture); glBindTexture(GL_TEXTURE_2D, m_Texture);
} }
+4
View File
@@ -9,11 +9,13 @@ Game::Game(int argc, char* argv[])
ResourceManager::RegisterType<ConfigFile>("ConfigFile"); ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<Sound>("Sound"); ResourceManager::RegisterType<Sound>("Sound");
ResourceManager::RegisterType<Model>("Model"); ResourceManager::RegisterType<Model>("Model");
ResourceManager::RegisterType<RawModel>("RawModel");
ResourceManager::RegisterType<Texture>("Texture"); ResourceManager::RegisterType<Texture>("Texture");
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram"); ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
ResourceManager::RegisterType<EntityFile>("EntityFile"); ResourceManager::RegisterType<EntityFile>("EntityFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini"); m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
ResourceManager::UseThreading = m_Config->Get<bool>("Multithreading.ResourceLoading", true);
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1)); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
// Create the core event broker // Create the core event broker
@@ -56,6 +58,8 @@ Game::Game(int argc, char* argv[])
EntityFileParser fp(file); EntityFileParser fp(file);
fp.MergeEntities(m_World); fp.MergeEntities(m_World);
} }
//SO MUCH TEMP PLEASE REMOVE ME OMFG VIKTOR HELP
m_Renderer->m_World = m_World;
// Create system pipeline // Create system pipeline
m_SystemPipeline = new SystemPipeline(m_EventBroker); m_SystemPipeline = new SystemPipeline(m_EventBroker);