Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6cf7c12d34 | |||
| 4a817613e3 | |||
| 6a3c14540d | |||
| 5602b32507 | |||
| 1431bd1a11 | |||
| 1e370bac13 | |||
| 7c714d1f98 | |||
| d182e6c453 | |||
| e76a6b74a3 | |||
| e82911cb8b | |||
| 7464facab9 | |||
| f14c62f3d3 | |||
| d406059c79 | |||
| 59b261534a | |||
| 45b87ed6b1 | |||
| 53d5736420 | |||
| 3da69c8a1b | |||
| 16d636a87c | |||
| 4da33ff4ec | |||
| c2435fda2d | |||
| 433331e752 | |||
| 094c7fbb44 | |||
| 0b60979c7b | |||
| 2366cd3520 | |||
| 725a8896ce | |||
| 80f028edf2 | |||
| 8c563a2d76 | |||
| 91edab34bc | |||
| 6326a60a79 | |||
| bb900c5110 | |||
| cefc4e5257 | |||
| 37cf42527b | |||
| aa805f9a41 | |||
| 9d3313e3ed | |||
| dc4f5ad26e | |||
| eaca1c4dd1 | |||
| 0367826f16 | |||
| 352074da04 | |||
| 53ef749736 | |||
| de6e74c0b1 | |||
| 90a79c702f | |||
| 393a774140 | |||
| 578018607a | |||
| 58d827f7d0 | |||
| 3085ccdfbf | |||
| c9b140bd6b | |||
| c9d1ba6cae | |||
| eb9c217eb4 | |||
| d597c7e60e | |||
| 0dbe0fe48e | |||
| 1e1ce4e127 | |||
| 9fbea18330 | |||
| f337305dee | |||
| d7de4fc694 | |||
| 03bbe25a1e |
+1
-1
Submodule assets updated: 4bd902b697...b37468222e
@@ -1,13 +1,13 @@
|
|||||||
# XERCES_FOUND
|
# Xerces_FOUND
|
||||||
# XERCES_INCLUDE_DIRS
|
# Xerces_INCLUDE_DIRS
|
||||||
# XERCES_LIBRARIES
|
# Xerces_LIBRARIES
|
||||||
|
|
||||||
find_path(XERCES_INCLUDE_DIR xercesc/dom/dom.hpp
|
find_path(Xerces_INCLUDE_DIR xercesc/dom/dom.hpp
|
||||||
/usr/local/include
|
/usr/local/include
|
||||||
/usr/include
|
/usr/include
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(XERCES_LIBRARY
|
find_library(Xerces_LIBRARY
|
||||||
NAMES
|
NAMES
|
||||||
xerces-c_3
|
xerces-c_3
|
||||||
xerces-c_3D
|
xerces-c_3D
|
||||||
@@ -16,8 +16,8 @@ find_library(XERCES_LIBRARY
|
|||||||
/usr/lib
|
/usr/lib
|
||||||
)
|
)
|
||||||
|
|
||||||
set(XERCES_INCLUDE_DIRS ${XERCES_INCLUDE_DIR})
|
set(Xerces_INCLUDE_DIRS ${Xerces_INCLUDE_DIR})
|
||||||
set(XERCES_LIBRARIES ${XERCES_LIBRARY})
|
set(Xerces_LIBRARIES ${Xerces_LIBRARY})
|
||||||
|
|
||||||
find_package_handle_standard_args(Xerces DEFAULT_MSG XERCES_LIBRARY XERCES_INCLUDE_DIR)
|
find_package_handle_standard_args(Xerces DEFAULT_MSG Xerces_LIBRARY Xerces_INCLUDE_DIR)
|
||||||
mark_as_advanced(Xerces_FOUND XERCES_INCLUDE_DIR XERCES_LIBRARY)
|
mark_as_advanced(Xerces_FOUND Xerces_INCLUDE_DIR Xerces_LIBRARY)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define ComponentWrapper_h__
|
#define ComponentWrapper_h__
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "EntityWrapper.h"
|
#include "Entity.h"
|
||||||
#include "ComponentInfo.h"
|
#include "ComponentInfo.h"
|
||||||
#include "Util/Any.h"
|
#include "Util/Any.h"
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ struct ComponentWrapper
|
|||||||
ComponentWrapper(const ComponentInfo& componentInfo, char* data)
|
ComponentWrapper(const ComponentInfo& componentInfo, char* data)
|
||||||
: Info(componentInfo)
|
: Info(componentInfo)
|
||||||
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
||||||
, Data(data + sizeof(EntityID))
|
, Data(data + sizeof(::EntityID))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
const ComponentInfo& Info;
|
const ComponentInfo& Info;
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef Entity_h__
|
||||||
|
#define Entity_h__
|
||||||
|
|
||||||
|
typedef unsigned int EntityID;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#include "ResourceManager.h"
|
|
||||||
|
|
||||||
class EntityFile : public Resource
|
|
||||||
{
|
|
||||||
friend class ResourceManager;
|
|
||||||
|
|
||||||
private:
|
|
||||||
EntityFile(std::string path);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
};
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#ifndef Entity_h__
|
|
||||||
#define Entity_h__
|
|
||||||
|
|
||||||
typedef unsigned int EntityID;
|
|
||||||
|
|
||||||
struct EntityWrapper
|
|
||||||
{
|
|
||||||
EntityWrapper(EntityID entityID)
|
|
||||||
: ID(entityID)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
EntityID ID;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
#ifndef EntityXMLFile_h__
|
||||||
|
#define EntityXMLFile_h__
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include <xercesc/dom/DOM.hpp>
|
||||||
|
#include <xercesc/dom/DOMLSInput.hpp>
|
||||||
|
#include <xercesc/dom/DOMElement.hpp>
|
||||||
|
#include <xercesc/framework/Wrapper4InputSource.hpp>
|
||||||
|
#include <xercesc/framework/LocalFileInputSource.hpp>
|
||||||
|
#include <xercesc/framework/LocalFileFormatTarget.hpp>
|
||||||
|
#include <xercesc/framework/MemBufFormatTarget.hpp>
|
||||||
|
#include <xercesc/framework/MemBufInputSource.hpp>
|
||||||
|
#include <xercesc/sax/HandlerBase.hpp>
|
||||||
|
#include <xercesc/util/PlatformUtils.hpp>
|
||||||
|
#include <xercesc/util/XMLFloat.hpp>
|
||||||
|
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
|
||||||
|
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSParticle.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSModelGroup.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSAnnotation.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSValue.hpp>
|
||||||
|
#include <xercesc/framework/XMLValidator.hpp>
|
||||||
|
|
||||||
|
#include "ResourceManager.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "ComponentInfo.h"
|
||||||
|
class World;
|
||||||
|
|
||||||
|
class EntityPreprocessorXMLErrorHandler : public xercesc::DOMErrorHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool handleError(const xercesc::DOMError &e) override
|
||||||
|
{
|
||||||
|
char* message = xercesc::XMLString::transcode(e.getMessage());
|
||||||
|
std::cerr << "Preprocessor DOMError: " << message << std::endl;
|
||||||
|
xercesc::XMLString::release(&message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class EntityParserXMLErrorHandler : public xercesc::ErrorHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void warning(const xercesc::SAXParseException& e) override
|
||||||
|
{
|
||||||
|
reportParseException("Warning", e);
|
||||||
|
}
|
||||||
|
void error(const xercesc::SAXParseException& e) override
|
||||||
|
{
|
||||||
|
reportParseException("Error", e);
|
||||||
|
}
|
||||||
|
void fatalError(const xercesc::SAXParseException& e) override
|
||||||
|
{
|
||||||
|
reportParseException("FATAL ERROR", e);
|
||||||
|
}
|
||||||
|
void resetErrors() override { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void reportParseException(std::string type, const xercesc::SAXParseException& e)
|
||||||
|
{
|
||||||
|
char* message = xercesc::XMLString::transcode(e.getMessage());
|
||||||
|
char* systemID = xercesc::XMLString::transcode(e.getSystemId());
|
||||||
|
std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl;
|
||||||
|
std::cerr << type << ": " << message << std::endl;
|
||||||
|
xercesc::XMLString::release(&systemID);
|
||||||
|
xercesc::XMLString::release(&message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class XSTR
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
XSTR(const XMLCh* const xmlString)
|
||||||
|
{
|
||||||
|
m_AsChar = xercesc::XMLString::transcode(xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
XSTR(const char* normalString)
|
||||||
|
{
|
||||||
|
m_AsXMLCh = xercesc::XMLString::transcode(normalString);
|
||||||
|
}
|
||||||
|
|
||||||
|
~XSTR()
|
||||||
|
{
|
||||||
|
if (m_AsChar != nullptr) {
|
||||||
|
xercesc::XMLString::release(&m_AsChar);
|
||||||
|
}
|
||||||
|
if (m_AsXMLCh != nullptr) {
|
||||||
|
xercesc::XMLString::release(&m_AsXMLCh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const char*() const { return m_AsChar; }
|
||||||
|
operator const XMLCh*() const { return m_AsXMLCh; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* m_AsChar = nullptr;
|
||||||
|
XMLCh* m_AsXMLCh = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EntityXMLFile : public Resource
|
||||||
|
{
|
||||||
|
friend class ResourceManager;
|
||||||
|
|
||||||
|
private:
|
||||||
|
EntityXMLFile(std::string path);
|
||||||
|
|
||||||
|
public:
|
||||||
|
~EntityXMLFile();
|
||||||
|
|
||||||
|
void PopulateWorld(World* world);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static unsigned int InstanceCount;
|
||||||
|
|
||||||
|
std::string m_EntityFile;
|
||||||
|
xercesc::XMLGrammarPool* m_GrammarPool = nullptr;
|
||||||
|
EntityParserXMLErrorHandler* m_ErrorHandler = nullptr;
|
||||||
|
xercesc::XercesDOMParser* m_DOMParser = nullptr;
|
||||||
|
xercesc::DOMDocument* m_DOMDocument = nullptr;
|
||||||
|
std::map<std::string, ComponentInfo> m_ComponentInfo;
|
||||||
|
|
||||||
|
// Preprocesses the entity file to insert include-by-copy child entities
|
||||||
|
// TODO: Make this work in memory instead of saving to file
|
||||||
|
void preprocess(std::string inPath, std::string outPath);
|
||||||
|
|
||||||
|
void parseComponentInfo();
|
||||||
|
void parseDefaults();
|
||||||
|
void predictComponentAllocation();
|
||||||
|
void parseEntityGraph(World* world, xercesc::DOMElement* parent, EntityID parentEntity);
|
||||||
|
std::size_t getTypeStride(std::string typeName);
|
||||||
|
float getFloatAttribute(const xercesc::DOMElement* element, const char* attribute) const;
|
||||||
|
void writeData(const xercesc::DOMElement* element, std::string typeName, char* outData);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -17,119 +17,119 @@ class EventBroker;
|
|||||||
|
|
||||||
class BaseEventRelay
|
class BaseEventRelay
|
||||||
{
|
{
|
||||||
friend class EventBroker;
|
friend class EventBroker;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
|
BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
|
||||||
: m_ContextTypeName(contextTypeName)
|
: m_ContextTypeName(contextTypeName)
|
||||||
, m_EventTypeName(eventTypeName)
|
, m_EventTypeName(eventTypeName)
|
||||||
, m_Broker(nullptr)
|
, m_Broker(nullptr)
|
||||||
{ }
|
{ }
|
||||||
~BaseEventRelay();
|
~BaseEventRelay();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
|
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string m_ContextTypeName;
|
std::string m_ContextTypeName;
|
||||||
std::string m_EventTypeName;
|
std::string m_EventTypeName;
|
||||||
EventBroker* m_Broker;
|
EventBroker* m_Broker;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ContextType, typename EventType>
|
template <typename ContextType, typename EventType>
|
||||||
class EventRelay : public BaseEventRelay
|
class EventRelay : public BaseEventRelay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<bool(const EventType&)> CallbackType;
|
typedef std::function<bool(const EventType&)> CallbackType;
|
||||||
|
|
||||||
EventRelay()
|
EventRelay()
|
||||||
: m_Callback(nullptr)
|
: m_Callback(nullptr)
|
||||||
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
|
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
|
||||||
{ }
|
{ }
|
||||||
EventRelay(CallbackType callback)
|
EventRelay(CallbackType callback)
|
||||||
: m_Callback(callback)
|
: m_Callback(callback)
|
||||||
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
|
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Receive(const std::shared_ptr<Event> event) override;
|
bool Receive(const std::shared_ptr<Event> event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CallbackType m_Callback;
|
CallbackType m_Callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ContextType, typename EventType>
|
template <typename ContextType, typename EventType>
|
||||||
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
|
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
|
||||||
{
|
{
|
||||||
if (m_Callback != nullptr) {
|
if (m_Callback != nullptr) {
|
||||||
return m_Callback(*static_cast<const EventType*>(event.get()));
|
return m_Callback(*static_cast<const EventType*>(event.get()));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EventBroker
|
class EventBroker
|
||||||
{
|
{
|
||||||
template <typename ContextType, typename EventType> friend class EventRelay;
|
template <typename ContextType, typename EventType> friend class EventRelay;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EventBroker()
|
EventBroker()
|
||||||
{
|
{
|
||||||
m_EventQueueRead = std::make_shared<EventQueue_t>();
|
m_EventQueueRead = std::make_shared<EventQueue_t>();
|
||||||
m_EventQueueWrite = std::make_shared<EventQueue_t>();
|
m_EventQueueWrite = std::make_shared<EventQueue_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Subscribe(BaseEventRelay &relay);
|
void Subscribe(BaseEventRelay &relay);
|
||||||
template <typename EventType>
|
template <typename EventType>
|
||||||
void Publish(const EventType &event);
|
void Publish(const EventType &event);
|
||||||
/*
|
/*
|
||||||
Process all events in a given context.
|
Process all events in a given context.
|
||||||
Returns: Number of events processed
|
Returns: Number of events processed
|
||||||
*/
|
*/
|
||||||
template <typename ContextType>
|
template <typename ContextType>
|
||||||
int Process();
|
int Process();
|
||||||
int Process(std::string contextTypeName);
|
int Process(std::string contextTypeName);
|
||||||
void Swap();
|
void Swap();
|
||||||
void Clear();
|
void Clear();
|
||||||
void Unsubscribe(BaseEventRelay &relay);
|
void Unsubscribe(BaseEventRelay &relay);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_IsProcessing = false;
|
bool m_IsProcessing = false;
|
||||||
|
|
||||||
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
|
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
|
||||||
typedef std::string EventTypeName_t; // typeid(EventType).name()
|
typedef std::string EventTypeName_t; // typeid(EventType).name()
|
||||||
|
|
||||||
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
|
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
|
||||||
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
|
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
|
||||||
ContextRelays_t m_ContextRelays;
|
ContextRelays_t m_ContextRelays;
|
||||||
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
|
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
|
||||||
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
|
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
|
||||||
|
|
||||||
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
|
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_EventQueueRead;
|
||||||
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
|
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
|
||||||
|
|
||||||
void subscribeImmediate(BaseEventRelay& relay);
|
void subscribeImmediate(BaseEventRelay& relay);
|
||||||
void unsubscribeImmediate(BaseEventRelay& relay);
|
void unsubscribeImmediate(BaseEventRelay& relay);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename EventType>
|
template <typename EventType>
|
||||||
void EventBroker::Publish(const EventType &event)
|
void EventBroker::Publish(const EventType &event)
|
||||||
{
|
{
|
||||||
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
|
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
|
||||||
for (auto it = itpair.first; it != itpair.second; ++it)
|
for (auto it = itpair.first; it != itpair.second; ++it)
|
||||||
{
|
{
|
||||||
it->second->Receive(event);
|
it->second->Receive(event);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
|
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ContextType>
|
template <typename ContextType>
|
||||||
int EventBroker::Process()
|
int EventBroker::Process()
|
||||||
{
|
{
|
||||||
const std::string contextTypeName = typeid(ContextType).name();
|
const std::string contextTypeName = typeid(ContextType).name();
|
||||||
return Process(contextTypeName);
|
return Process(contextTypeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void Reload(std::string resourceName);
|
static void Reload(std::string resourceName);
|
||||||
|
|
||||||
|
static void Release(std::string resourceType, std::string resourceName);
|
||||||
|
|
||||||
static void Update();
|
static void Update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef System_h__
|
||||||
|
#define System_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "ComponentWrapper.h"
|
||||||
|
|
||||||
|
class System
|
||||||
|
{
|
||||||
|
friend class SystemPipeline;
|
||||||
|
|
||||||
|
public:
|
||||||
|
System(EventBroker* eventBroker, std::string componentType)
|
||||||
|
: m_EventBroker(eventBroker)
|
||||||
|
, m_ComponentType(componentType)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string m_ComponentType;
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef SystemPipeline_h__
|
||||||
|
#define SystemPipeline_h__
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "EventBroker.h"
|
||||||
|
#include "System.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
class SystemPipeline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SystemPipeline(EventBroker* eventBroker)
|
||||||
|
: m_EventBroker(eventBroker)
|
||||||
|
{ }
|
||||||
|
~SystemPipeline()
|
||||||
|
{
|
||||||
|
for (auto& pair : m_Systems) {
|
||||||
|
for (auto& system : pair.second) {
|
||||||
|
delete system;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Arguments>
|
||||||
|
void AddSystem(Arguments... args)
|
||||||
|
{
|
||||||
|
System* system = new T(m_EventBroker, args...);
|
||||||
|
if (!system->m_ComponentType.empty()) {
|
||||||
|
m_Systems[system->m_ComponentType].push_back(system);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name());
|
||||||
|
delete system;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(World* world, double dt)
|
||||||
|
{
|
||||||
|
for (auto& pair : m_Systems) {
|
||||||
|
const std::string& componentName = pair.first;
|
||||||
|
auto& systems = pair.second;
|
||||||
|
const ComponentPool* pool = world->GetComponents(componentName);
|
||||||
|
if (pool == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (auto& component : *pool) {
|
||||||
|
for (auto& system : systems) {
|
||||||
|
system->Update(world, component, dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
std::unordered_map<std::string, std::vector<System*>> m_Systems;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#define World_h__
|
#define World_h__
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "EntityWrapper.h"
|
#include "Entity.h"
|
||||||
#include "ObjectPool.h"
|
#include "ObjectPool.h"
|
||||||
#include "ComponentPool.h"
|
#include "ComponentPool.h"
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@ public:
|
|||||||
World() = default;
|
World() = default;
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
|
// Create empty entity
|
||||||
EntityID CreateEntity(EntityID parent = 0);
|
EntityID CreateEntity(EntityID parent = 0);
|
||||||
|
|
||||||
// Register a component type and allocate space for it
|
// Register a component type and allocate space for it
|
||||||
@@ -21,10 +22,12 @@ public:
|
|||||||
// Get a component of an entity
|
// Get a component of an entity
|
||||||
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
||||||
// Get all components of the specified type
|
// Get all components of the specified type
|
||||||
const ComponentPool& GetComponents(std::string componentType);
|
const ComponentPool* GetComponents(std::string componentType);
|
||||||
|
// Get entity parent
|
||||||
|
EntityID GetParent(EntityID entity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EntityID m_CurrentEntityID = 0;
|
EntityID m_CurrentEntityID = 1;
|
||||||
|
|
||||||
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
||||||
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
|
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef DrawScenePass_h__
|
||||||
|
#define DrawScenePass_h__
|
||||||
|
|
||||||
|
#include "IRenderer.h"
|
||||||
|
#include "DrawScenePassState.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
#include "Util/UnorderedMapVec2.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
|
||||||
|
class DrawScenePass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DrawScenePass(IRenderer* renderer);
|
||||||
|
~DrawScenePass() { }
|
||||||
|
void InitializeTextures();
|
||||||
|
void InitializeFrameBuffers();
|
||||||
|
void InitializeShaderPrograms();
|
||||||
|
|
||||||
|
void Draw(RenderQueueCollection& rq);
|
||||||
|
|
||||||
|
//Getters
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
|
||||||
|
|
||||||
|
Texture* m_WhiteTexture;
|
||||||
|
|
||||||
|
const IRenderer* m_Renderer;
|
||||||
|
|
||||||
|
ShaderProgram* m_BasicForwardProgram;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef DrawScenePassState_h__
|
||||||
|
#define DrawScenePassState_h__
|
||||||
|
|
||||||
|
#include "Rendering/RenderState.h"
|
||||||
|
|
||||||
|
class DrawScenePassState : public RenderState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DrawScenePassState();
|
||||||
|
~DrawScenePassState();
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#ifndef Events_Picking_h__
|
||||||
|
#define Events_Picking_h__
|
||||||
|
|
||||||
|
#include "../OpenGL.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "Util/ScreenCoords.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include "../Core/Entity.h"
|
||||||
|
#include "Util/UnorderedMapVec2.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Thrown Every frame, use functions to pick*/
|
||||||
|
struct Picking : Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Picking(FrameBuffer* pickingBuffer, GLuint* depthBuffer, glm::mat4 projectionMatrix, glm::mat4 viewMatrix, Rectangle resolution, const std::unordered_map<glm::vec2, EntityID>* pickingColorsToEntity)
|
||||||
|
: PickingBuffer(pickingBuffer)
|
||||||
|
, DepthBuffer(depthBuffer)
|
||||||
|
, ProjectionMatrix(projectionMatrix)
|
||||||
|
, ViewMatrix(viewMatrix)
|
||||||
|
, Resolution(resolution)
|
||||||
|
, PickingColorsToEntity(pickingColorsToEntity)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct PickData
|
||||||
|
{
|
||||||
|
//Picked Entity
|
||||||
|
EntityID Entity;
|
||||||
|
//World position of the "pick"
|
||||||
|
glm::vec3 Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
PickData Pick(glm::vec2 screenCoord) const
|
||||||
|
{
|
||||||
|
PickData pickData;
|
||||||
|
|
||||||
|
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer);
|
||||||
|
|
||||||
|
auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1]));
|
||||||
|
if (it != PickingColorsToEntity->end()) {
|
||||||
|
pickData.Entity = it->second;
|
||||||
|
} else {
|
||||||
|
pickData.Entity = -1;
|
||||||
|
}
|
||||||
|
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, Resolution.Width - screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);
|
||||||
|
|
||||||
|
return pickData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
FrameBuffer* PickingBuffer;
|
||||||
|
GLuint* DepthBuffer;
|
||||||
|
const glm::mat4 ProjectionMatrix;
|
||||||
|
const glm::mat4 ViewMatrix;
|
||||||
|
const Rectangle Resolution;
|
||||||
|
const std::unordered_map<glm::vec2, EntityID>* PickingColorsToEntity;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef PickingPass_h__
|
||||||
|
#define PickingPass_h__
|
||||||
|
|
||||||
|
#include "IRenderer.h"
|
||||||
|
#include "PickingPassState.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
#include "Util/UnorderedMapVec2.h"
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "EPicking.h"
|
||||||
|
|
||||||
|
class PickingPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PickingPass(IRenderer* renderer, EventBroker* eb);
|
||||||
|
~PickingPass();
|
||||||
|
void InitializeTextures();
|
||||||
|
void InitializeFrameBuffers();
|
||||||
|
void InitializeShaderPrograms();
|
||||||
|
|
||||||
|
void Draw(RenderQueueCollection& rq);
|
||||||
|
|
||||||
|
|
||||||
|
//Getters
|
||||||
|
const ShaderProgram& PickingProgram() const { return *m_PickingProgram; }
|
||||||
|
const std::unordered_map<glm::vec2, EntityID>& PickingColorsToEntity() const { return m_PickingColorsToEntity; }
|
||||||
|
GLuint PickingTexture() const { return m_PickingTexture; }
|
||||||
|
GLuint DepthBuffer() const { return m_DepthBuffer; }
|
||||||
|
const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
|
||||||
|
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
|
const IRenderer* m_Renderer;
|
||||||
|
|
||||||
|
ShaderProgram* m_PickingProgram;
|
||||||
|
|
||||||
|
std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity;
|
||||||
|
|
||||||
|
GLuint m_PickingTexture;
|
||||||
|
GLuint m_DepthBuffer;
|
||||||
|
|
||||||
|
FrameBuffer m_PickingBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef PickingPassState_h__
|
||||||
|
#define PickingPassState_h__
|
||||||
|
|
||||||
|
#include "Rendering/RenderState.h"
|
||||||
|
|
||||||
|
class PickingPassState : public RenderState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PickingPassState(GLuint frameBuffer);
|
||||||
|
~PickingPassState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "../GLM.h"
|
#include "../GLM.h"
|
||||||
#include "../Core/Util/Rectangle.h"
|
#include "../Core/Util/Rectangle.h"
|
||||||
#include "../Core/EntityWrapper.h"
|
#include "../Core/Entity.h"
|
||||||
|
|
||||||
class Model;
|
class Model;
|
||||||
class Skeleton;
|
class Skeleton;
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ private:
|
|||||||
void FillLights(World* world, RenderQueue* renderQueue);
|
void FillLights(World* world, RenderQueue* renderQueue);
|
||||||
|
|
||||||
glm::mat4 ModelMatrix(World* world, EntityID entity);
|
glm::mat4 ModelMatrix(World* world, EntityID entity);
|
||||||
glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent);
|
|
||||||
|
glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
||||||
|
glm::quat AbsoluteOrientation(World* world, EntityID entity);
|
||||||
|
glm::vec3 AbsoluteScale(World* world, EntityID entity);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef RenderState_h__
|
||||||
|
#define RenderState_h__
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../OpenGL.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
|
||||||
|
class RenderState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RenderState();
|
||||||
|
~RenderState();
|
||||||
|
bool Enable(GLenum GLEnable);
|
||||||
|
bool CullFace(GLenum GlFaceToCull);
|
||||||
|
bool ClearColor(glm::vec4 color);
|
||||||
|
bool Clear(GLbitfield mask);
|
||||||
|
bool BindBuffer(GLint buffer);
|
||||||
|
private:
|
||||||
|
std::vector<GLenum> m_Enables;
|
||||||
|
float m_preClearColor[4];
|
||||||
|
int m_preBuffer;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -10,48 +10,109 @@
|
|||||||
#include "Util/UnorderedMapVec2.h"
|
#include "Util/UnorderedMapVec2.h"
|
||||||
#include "FrameBuffer.h"
|
#include "FrameBuffer.h"
|
||||||
#include "../Core/World.h"
|
#include "../Core/World.h"
|
||||||
|
#include "PickingPass.h"
|
||||||
|
#include "DrawScenePass.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TILE_SIZE 16
|
||||||
|
#define NUM_LIGHTS 5000
|
||||||
|
|
||||||
|
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "EPicking.h"
|
||||||
|
|
||||||
class Renderer : public IRenderer
|
class Renderer : public IRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Initialize() override;
|
Renderer(EventBroker* eventBroker)
|
||||||
virtual void Update(double dt) override;
|
: m_EventBroker(eventBroker)
|
||||||
virtual void Draw(RenderQueueCollection& rq) override;
|
{ }
|
||||||
|
|
||||||
|
virtual void Initialize() override;
|
||||||
|
virtual void Update(double dt) override;
|
||||||
|
virtual void Draw(RenderQueueCollection& rq) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//----------------------Variables----------------------//
|
//----------------------Variables----------------------//
|
||||||
Texture* m_ErrorTexture;
|
EventBroker* m_EventBroker;
|
||||||
Texture* m_WhiteTexture;
|
|
||||||
float m_CameraMoveSpeed;
|
Texture* m_ErrorTexture;
|
||||||
FrameBuffer m_PickingBuffer;
|
Texture* m_WhiteTexture;
|
||||||
GLuint m_PickingTexture;
|
float m_CameraMoveSpeed;
|
||||||
GLuint m_DepthBuffer;
|
|
||||||
|
|
||||||
Model* m_ScreenQuad;
|
Model* m_ScreenQuad;
|
||||||
Model* m_UnitQuad;
|
Model* m_UnitQuad;
|
||||||
Model* m_UnitSphere;
|
Model* m_UnitSphere;
|
||||||
|
|
||||||
|
DrawScenePass* m_DrawScenePass;
|
||||||
|
PickingPass* m_PickingPass;
|
||||||
|
|
||||||
|
//----------------------Functions----------------------//
|
||||||
std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity;
|
void InitializeWindow();
|
||||||
|
void InitializeShaders();
|
||||||
//----------------------Functions----------------------//
|
|
||||||
void InitializeWindow();
|
|
||||||
void InitializeShaders();
|
|
||||||
void InitializeTextures();
|
void InitializeTextures();
|
||||||
void InitializeFrameBuffers();
|
void InitializeSSBOs();
|
||||||
|
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);
|
||||||
void DrawScene(RenderQueueCollection& rq);
|
|
||||||
|
|
||||||
|
//----------------------Forward+-----------------------//
|
||||||
|
void CalculateFrustum();
|
||||||
|
void CullLights();
|
||||||
|
void DrawForwardPlus(RenderQueueCollection& rq);
|
||||||
|
//Frustum
|
||||||
|
struct Plane {
|
||||||
|
glm::vec3 Normal;
|
||||||
|
float d;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Frustum {
|
||||||
|
Plane Planes[4];
|
||||||
|
};
|
||||||
|
Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution
|
||||||
|
|
||||||
|
//Lights
|
||||||
|
void TEMPCreateLights();
|
||||||
|
//TODO: Renderer: Add Directionllights, spotlights and area lights to this as type.
|
||||||
|
struct PointLight {
|
||||||
|
glm::vec4 Position = glm::vec4(0.f);
|
||||||
|
glm::vec4 Color = glm::vec4(1.f);
|
||||||
|
float Radius = 5.f;
|
||||||
|
float Intensity = 0.8f;
|
||||||
|
float Falloff = 0.3f;
|
||||||
|
float Padding = 1337;
|
||||||
|
};
|
||||||
|
PointLight m_PointLights[NUM_LIGHTS];
|
||||||
|
|
||||||
|
struct LightGrid {
|
||||||
|
float Start;
|
||||||
|
float Amount;
|
||||||
|
glm::vec2 Padding;
|
||||||
|
};
|
||||||
|
|
||||||
|
LightGrid m_LightGrid[80*45];
|
||||||
|
|
||||||
|
int m_LightOffset = 0;
|
||||||
|
|
||||||
|
float m_LightIndex[80*45*200];
|
||||||
|
|
||||||
|
//-------------------------SSBO------------------------//
|
||||||
|
GLuint m_FrustumSSBO = 0;
|
||||||
|
GLuint m_LightSSBO = 0;
|
||||||
|
GLuint m_LightGridSSBO = 0;
|
||||||
|
GLuint m_LightOffsetSSBO = 0;
|
||||||
|
GLuint m_LightIndexSSBO = 0;
|
||||||
|
|
||||||
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_PickingProgram;
|
ShaderProgram* m_DrawScreenQuadProgram;
|
||||||
ShaderProgram m_DrawScreenQuadProgram;
|
ShaderProgram* m_CalculateFrustumProgram;
|
||||||
|
ShaderProgram* m_LightCullProgram;
|
||||||
|
ShaderProgram* m_ForwardPlusProgram;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
|
#ifndef ShaderProgram_h__
|
||||||
|
#define ShaderProgram_h__
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "../OpenGL.h"
|
#include "../OpenGL.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
class Shader
|
class Shader
|
||||||
@@ -60,11 +63,13 @@ public:
|
|||||||
: ShaderType(fileName) { }
|
: ShaderType(fileName) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShaderProgram
|
class ShaderProgram : public Resource
|
||||||
{
|
{
|
||||||
public:
|
friend class ResourceManager;
|
||||||
ShaderProgram()
|
private:
|
||||||
|
ShaderProgram(std::string)
|
||||||
: m_ShaderProgramHandle(0) { }
|
: m_ShaderProgramHandle(0) { }
|
||||||
|
public:
|
||||||
~ShaderProgram();
|
~ShaderProgram();
|
||||||
|
|
||||||
void AddShader(std::shared_ptr<Shader> shader);
|
void AddShader(std::shared_ptr<Shader> shader);
|
||||||
@@ -79,3 +84,5 @@ private:
|
|||||||
GLuint m_ShaderProgramHandle;
|
GLuint m_ShaderProgramHandle;
|
||||||
std::vector<std::shared_ptr<Shader>> m_Shaders;
|
std::vector<std::shared_ptr<Shader>> m_Shaders;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -9,7 +9,7 @@ inline bool _GLERROR(const char* info, const char* file, const char* func, unsig
|
|||||||
GLenum error = glGetError();
|
GLenum error = glGetError();
|
||||||
if (error != GL_NO_ERROR)
|
if (error != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
_LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s %i %s", info, error, gluErrorString(error));
|
_LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s, %i, %s", info, error, gluErrorString(error));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ class ScreenCoords
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScreenCoords() = delete;
|
ScreenCoords() = delete;
|
||||||
|
|
||||||
|
struct PixelData
|
||||||
|
{
|
||||||
|
int Color[2];
|
||||||
|
float Depth;
|
||||||
|
};
|
||||||
|
|
||||||
//Return world position from given screenspace coordinates and depth value in viewspace.
|
//Return world position from given screenspace coordinates and depth value in viewspace.
|
||||||
static glm::vec3 ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
static glm::vec3 ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
||||||
static glm::vec3 ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
static glm::vec3 ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
||||||
@@ -18,8 +25,8 @@ public:
|
|||||||
static glm::vec3 ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
static glm::vec3 ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
||||||
//Return data from the given buffers at the coordinates given in screenspace. Buffer should probably have a texture that covers the screen.
|
//Return data from the given buffers at the coordinates given in screenspace. Buffer should probably have a texture that covers the screen.
|
||||||
//Data is given as R = x, B = y, and
|
//Data is given as R = x, B = y, and
|
||||||
static glm::vec3 ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
static PixelData ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
||||||
static glm::vec3 ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
static PixelData ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
||||||
//Return EntityID of the clicked coordinate in given screenspace coordinates.
|
//Return EntityID of the clicked coordinate in given screenspace coordinates.
|
||||||
//EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth);
|
//EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
#include "GUI/Frame.h"
|
#include "GUI/Frame.h"
|
||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
#include "Rendering/RenderQueueFactory.h"
|
#include "Rendering/RenderQueueFactory.h"
|
||||||
|
#include "Core/EKeyDown.h"
|
||||||
|
#include "Core/EntityXMLFile.h"
|
||||||
|
#include "Core/SystemPipeline.h"
|
||||||
|
#include "RaptorCopterSystem.h"
|
||||||
|
#include "PlayerSystem.h"
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
@@ -27,7 +32,14 @@ private:
|
|||||||
InputManager* m_InputManager;
|
InputManager* m_InputManager;
|
||||||
GUI::Frame* m_FrameStack;
|
GUI::Frame* m_FrameStack;
|
||||||
World* m_World;
|
World* m_World;
|
||||||
|
SystemPipeline* m_SystemPipeline;
|
||||||
RenderQueueFactory* m_RenderQueueFactory;
|
RenderQueueFactory* m_RenderQueueFactory;
|
||||||
|
|
||||||
|
EventRelay<Game, Events::KeyUp> m_EKeyUp;
|
||||||
|
bool testOnKeyUp(const Events::KeyUp& e);
|
||||||
|
|
||||||
|
void testIntialize();
|
||||||
|
void testTick(double dt);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
#include <list>
|
|
||||||
#include <tuple>
|
|
||||||
#include <boost/any.hpp>
|
|
||||||
#include "GLM.h"
|
|
||||||
#include "Core/World.h"
|
|
||||||
#include "Core/Util/Any.h"
|
|
||||||
|
|
||||||
class HardcodedTestWorld : public World
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HardcodedTestWorld()
|
|
||||||
: World()
|
|
||||||
{
|
|
||||||
registerTestComponents();
|
|
||||||
createTestEntities();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void registerTestComponents()
|
|
||||||
{
|
|
||||||
ComponentWrapperFactory f;
|
|
||||||
|
|
||||||
|
|
||||||
f = ComponentWrapperFactory("Test");
|
|
||||||
f.AddProperty("TestInteger", 1337);
|
|
||||||
f.AddProperty("TestFloat", 13.37f);
|
|
||||||
f.AddProperty("TestString", std::string("Carlito"));
|
|
||||||
RegisterComponent(f);
|
|
||||||
|
|
||||||
f = ComponentWrapperFactory("Debug");
|
|
||||||
f.AddProperty("Name", std::string("Unnamed"));
|
|
||||||
RegisterComponent(f);
|
|
||||||
|
|
||||||
f = ComponentWrapperFactory("Transform");
|
|
||||||
f.AddProperty("Position", glm::vec3(0.f, 0.f, 0.f));
|
|
||||||
f.AddProperty("Orientation", glm::quat());
|
|
||||||
f.AddProperty("Scale", glm::vec3(1.f, 1.f, 1.f));
|
|
||||||
RegisterComponent(f);
|
|
||||||
|
|
||||||
f = ComponentWrapperFactory("Model");
|
|
||||||
f.AddProperty("Resource", std::string());
|
|
||||||
f.AddProperty("Color", glm::vec4(1.f, 1.f, 1.f, 1.f));
|
|
||||||
f.AddProperty("Visible", true);
|
|
||||||
RegisterComponent(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void createTestEntities()
|
|
||||||
{
|
|
||||||
World& world = *this;
|
|
||||||
|
|
||||||
// Create an entity
|
|
||||||
EntityID e = world.CreateEntity();
|
|
||||||
|
|
||||||
// Attach a Debug component
|
|
||||||
ComponentWrapper debug = world.AttachComponent(e, "Debug");
|
|
||||||
// Set the Name field of the Debug component using subscript operator
|
|
||||||
debug["Name"] = "Carlito";
|
|
||||||
|
|
||||||
// Attach a Transform component
|
|
||||||
world.AttachComponent(e, "Transform");
|
|
||||||
// Fetch the component based on EntityID and component type
|
|
||||||
ComponentWrapper transform = world.GetComponent(e, "Transform");
|
|
||||||
// Set the fields of the Transform component
|
|
||||||
transform["Position"] = glm::vec3(0.f, 0.f, 0.f);
|
|
||||||
transform["Scale"] = glm::vec3(1.f, 1.f, 1.f);
|
|
||||||
|
|
||||||
// Move on the X axis by fetching field as reference
|
|
||||||
((glm::vec3&)transform["Position"]).x += 10.f;
|
|
||||||
// Shrink by a factor of 100
|
|
||||||
((glm::vec3&)transform["Scale"]) /= 100.f;
|
|
||||||
|
|
||||||
// Loop through all Transform components and print them
|
|
||||||
for (auto& transform : world.GetComponents("Transform")) {
|
|
||||||
glm::vec3 pos = transform["Position"];
|
|
||||||
std::cout << "Position: " << pos.x << " " << pos.y << " " << pos.z << std::endl;
|
|
||||||
glm::vec3 scale = transform["Scale"];
|
|
||||||
std::cout << "Scale: " << scale.x << " " << scale.y << " " << scale.z << std::endl;
|
|
||||||
|
|
||||||
// Fetch the Debug component also present in this entity
|
|
||||||
ComponentWrapper debug = world.GetComponent(transform.EntityID, "Debug");
|
|
||||||
std::cout << "Name: " << (std::string)debug["Name"] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create some test widgets
|
|
||||||
{
|
|
||||||
EntityID entityScaleWidget = world.CreateEntity();
|
|
||||||
ComponentWrapper transform = world.AttachComponent(entityScaleWidget, "Transform");
|
|
||||||
transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f);
|
|
||||||
ComponentWrapper model = world.AttachComponent(entityScaleWidget, "Model");
|
|
||||||
model["Resource"] = "Models/ScaleWidget.obj";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
EntityID entityRotationWidget = world.CreateEntity();
|
|
||||||
ComponentWrapper transform = world.AttachComponent(entityRotationWidget, "Transform");
|
|
||||||
transform["Position"] = glm::vec3(1.5f, 0.f, 0.f);
|
|
||||||
ComponentWrapper model = world.AttachComponent(entityRotationWidget, "Model");
|
|
||||||
model["Resource"] = "Models/RotationWidget.obj";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
EntityID entityDummyScene = world.CreateEntity();
|
|
||||||
ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform");
|
|
||||||
transform["Position"] = glm::vec3(0, 0.f, 0.f);
|
|
||||||
ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model");
|
|
||||||
model["Resource"] = "Models/DummyScene.obj";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef PlayerSystem_h__
|
||||||
|
#define PlayerSystem_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/common.hpp>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "Core/EKeyDown.h"
|
||||||
|
#include "Core/EKeyUp.h"
|
||||||
|
|
||||||
|
struct KeyInput
|
||||||
|
{
|
||||||
|
bool Forward = false;
|
||||||
|
bool Left = false;
|
||||||
|
bool Back = false;
|
||||||
|
bool Right = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlayerSystem : public System
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PlayerSystem(EventBroker* eventBroker)
|
||||||
|
: System(eventBroker, "Player")
|
||||||
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Update(World* world, ComponentWrapper& player, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_Speed = 5;
|
||||||
|
glm::vec3 m_Direction;
|
||||||
|
KeyInput input;
|
||||||
|
|
||||||
|
EventRelay<PlayerSystem, Events::KeyDown> m_EKeyDown;
|
||||||
|
bool OnKeyDown(const Events::KeyDown &event);
|
||||||
|
EventRelay<PlayerSystem, Events::KeyUp> m_EKeyUp;
|
||||||
|
bool OnKeyUp(const Events::KeyUp &event);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
|
class RaptorCopterSystem : public System
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaptorCopterSystem(EventBroker* eventBroker)
|
||||||
|
: System(eventBroker, "RaptorCopter")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void Initialize() { }
|
||||||
|
|
||||||
|
virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override
|
||||||
|
{
|
||||||
|
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
|
||||||
|
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"];
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
[Debug]
|
[Debug]
|
||||||
LogLevel=1
|
LogLevel=1
|
||||||
|
LoadMap=
|
||||||
|
|
||||||
[Video]
|
[Video]
|
||||||
Fullscreen=false
|
Fullscreen=false
|
||||||
VSYNC=false
|
VSYNC=false
|
||||||
Width=1280
|
Width=1280
|
||||||
Height=720
|
Height=720
|
||||||
|
FOV=45
|
||||||
@@ -2,5 +2,8 @@
|
|||||||
|
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="components" elementFormDefault="qualified">
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="components" elementFormDefault="qualified">
|
||||||
<xs:include schemaLocation="Components/Transform.xsd"/>
|
<xs:include schemaLocation="Components/Transform.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Model.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Test.xsd"/>
|
<xs:include schemaLocation="Components/Test.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/RaptorCopter.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Player.xsd"/>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<c:Model>
|
||||||
|
<Resource></Resource>
|
||||||
|
<Color R="1" G="1" B="1" A="1"/>
|
||||||
|
<Visible>true</Visible>
|
||||||
|
</c:Model>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?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="Model">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A visible model loaded from disk</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Resource" type="t:string" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Model file</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="Color" type="t:Color" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Color tint</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="Visible" type="t:bool" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Wether the model is visible or not</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<c:Player>
|
||||||
|
<Velocity X="0" Y="0" Z="0"/>
|
||||||
|
</c:Player>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?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="Player">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0</Speed>
|
||||||
|
<Axis X="0" Y="0" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?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="RaptorCopter">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Speed" type="t:double" minOccurs="0"/>
|
||||||
|
<xs:element name="Axis" type="t:Vector" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
<Integer>1</Integer>
|
<Integer>1</Integer>
|
||||||
<Float>1.333</Float>
|
<Float>1.333</Float>
|
||||||
<Vector X="1.33333" Y="2.33333" Z="3.33333"/>
|
<Vector X="1.33333" Y="2.33333" Z="3.33333"/>
|
||||||
<Quaternion I="1.33333" J="2.33333" K="3.33333"/>
|
<Quaternion X="1.33333" Y="2.33333" Z="3.33333" W="4.44444"/>
|
||||||
</c:Test>
|
</c:Test>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<TransformComponent>
|
<c:Transform>
|
||||||
<Position X="0" Y="0" Z="0"/>
|
<Position X="0" Y="0" Z="0"/>
|
||||||
<Orientation I="0" J="0" K="0"/>
|
<Orientation X="0" Y="0" Z="0" W="0"/>
|
||||||
<Scale X="1" Y="1" Z="1"/>
|
<Scale X="1" Y="1" Z="1"/>
|
||||||
</TransformComponent>
|
</c:Transform>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<xs:element name="Position" type="t:Vector" minOccurs="0">
|
<xs:element name="Position" type="t:Vector" minOccurs="0">
|
||||||
<xs:annotation><xs:documentation>The position vector</xs:documentation></xs:annotation>
|
<xs:annotation><xs:documentation>The position vector</xs:documentation></xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="Orientation" type="t:Quaternion" minOccurs="0"/>
|
<xs:element name="Orientation" type="t:Vector" minOccurs="0"/>
|
||||||
<xs:element name="Scale" type="t:Vector" minOccurs="0"/>
|
<xs:element name="Scale" type="t:Vector" minOccurs="0"/>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|||||||
@@ -3,18 +3,122 @@
|
|||||||
<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">
|
<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>
|
<Components>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="1.02" Y="3.123123" Z="41.123"/>
|
<Orientation X="0" Y="0" Z="0"/>
|
||||||
<Orientation I="1.234" J="1.234" K="1.234"/>
|
|
||||||
<Scale X="1.02" Y="3.123123" Z="41.123"/>
|
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Test>
|
|
||||||
<Integer>12</Integer>
|
|
||||||
<Double>11.11</Double>
|
|
||||||
<String>Hello World</String>
|
|
||||||
</c:Test>
|
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
<xi:include href="OtherEntity.xml"/>
|
<Entity>
|
||||||
<xi:include href="OtherEntity.xml"/>
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Scale X="10000" Y="10000" Z="10000"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitPlane.obj</Resource>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-1.5"/>
|
||||||
|
<Scale X="1" Y="1" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/ScaleWidget.obj</Resource>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.5"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/RotationWidget.obj</Resource>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Player>
|
||||||
|
<Velocity X="0" Y="0" Z="0"/>
|
||||||
|
</c:Player>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="2.5"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.obj</Resource>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="-0"/>
|
||||||
|
<Scale X="1" Y="1" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
<!--<c:Move>
|
||||||
|
<Speed>1</Speed>
|
||||||
|
<Direction X="-1"/>
|
||||||
|
<Rotation Y="3.14"/>
|
||||||
|
</c:Move>-->
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0"/>
|
||||||
|
<Orientation X="0.0" Y="0" Z="1.0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitRaptor.obj</Resource>
|
||||||
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.01" Y="0.55"/>
|
||||||
|
<Orientation X="0" Y="0" Z="-1"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>20</Speed>
|
||||||
|
<Axis Y="1"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0"/>
|
||||||
|
<Scale X="1.7" Y="0.03" Z="0.1"/>
|
||||||
|
<Orientation X="0" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.obj</Resource>
|
||||||
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0"/>
|
||||||
|
<Scale X="1.7" Y="0.03" Z="0.1"/>
|
||||||
|
<Orientation X="0" Y="1.57" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.obj</Resource>
|
||||||
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
|
</c:Model>
|
||||||
|
</Components>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</Entity>
|
||||||
@@ -3,6 +3,10 @@
|
|||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="types" elementFormDefault="qualified">
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="types" elementFormDefault="qualified">
|
||||||
<xs:include schemaLocation="Types/Quaternion.xsd"/>
|
<xs:include schemaLocation="Types/Quaternion.xsd"/>
|
||||||
<xs:include schemaLocation="Types/Vector.xsd"/>
|
<xs:include schemaLocation="Types/Vector.xsd"/>
|
||||||
|
<xs:include schemaLocation="Types/Color.xsd"/>
|
||||||
|
<xs:simpleType name="bool">
|
||||||
|
<xs:restriction base="xs:boolean"></xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
<xs:simpleType name="int">
|
<xs:simpleType name="int">
|
||||||
<xs:restriction base="xs:integer"></xs:restriction>
|
<xs:restriction base="xs:integer"></xs:restriction>
|
||||||
</xs:simpleType>
|
</xs:simpleType>
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="types" elementFormDefault="qualified">
|
||||||
|
<xs:complexType name="Color">
|
||||||
|
<xs:attribute name="R" type="xs:decimal" default="0.0"/>
|
||||||
|
<xs:attribute name="G" type="xs:decimal" default="0.0"/>
|
||||||
|
<xs:attribute name="B" type="xs:decimal" default="0.0"/>
|
||||||
|
<xs:attribute name="A" type="xs:decimal" default="1.0"/>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:schema>
|
||||||
@@ -7,11 +7,14 @@
|
|||||||
<xs:element name="Entity">
|
<xs:element name="Entity">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<xs:all>
|
||||||
<xs:element name="Components">
|
<xs:element name="Components" minOccurs="0">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<xs:all>
|
||||||
<xs:element ref="c:Transform" minOccurs="0"/>
|
<xs:element ref="c:Transform" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:Model" minOccurs="0"/>
|
||||||
<xs:element ref="c:Test" minOccurs="0"/>
|
<xs:element ref="c:Test" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:RaptorCopter" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:Player" minOccurs="0"/>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
uniform mat4 M;
|
||||||
|
uniform mat4 V;
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform vec4 Color;
|
||||||
|
|
||||||
|
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) {
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
vec4 L = lightPos - position;
|
||||||
|
float dist = length(L);
|
||||||
|
L = normalize(L);
|
||||||
|
|
||||||
|
float attenuation = CalcAttenuation(lightRadius, dist);
|
||||||
|
|
||||||
|
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) * 80));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
totalLighting.Diffuse += result.Diffuse;
|
||||||
|
totalLighting.Specular += result.Specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * 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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
#define TILE_SIZE 16
|
||||||
|
#define NUM_TILES 3600
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform vec2 ScreenDimensions;
|
||||||
|
|
||||||
|
struct Plane {
|
||||||
|
vec3 Normal;
|
||||||
|
float d;
|
||||||
|
};
|
||||||
|
struct Frustum {
|
||||||
|
Plane Planes[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std430, binding = 0) buffer FrustumBuffer
|
||||||
|
{
|
||||||
|
Frustum Data[];
|
||||||
|
} Frustums;
|
||||||
|
|
||||||
|
vec4 ConvertToView(vec4 ScreenCoords)
|
||||||
|
{
|
||||||
|
vec2 normalizedScreenCoords = ScreenCoords.xy / ScreenDimensions;
|
||||||
|
vec4 clipSpace = vec4( vec2(normalizedScreenCoords.x, normalizedScreenCoords.y) * 2.0 - 1.0, ScreenCoords.z, ScreenCoords.w);
|
||||||
|
vec4 view = inverse(P) * clipSpace;
|
||||||
|
view = view / view.w;
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
Plane ComputePlane( vec3 p0, vec3 p1, vec3 p2 )
|
||||||
|
{
|
||||||
|
Plane plane;
|
||||||
|
|
||||||
|
vec3 v0 = p1 - p0;
|
||||||
|
vec3 v2 = p2 - p0;
|
||||||
|
|
||||||
|
plane.Normal = normalize( cross( v0, v2 ) );
|
||||||
|
plane.d = dot( vec3(plane.Normal), p0 ); // Always 0 probably
|
||||||
|
return plane;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||||
|
void main ()
|
||||||
|
{
|
||||||
|
//Top-Left = 0 | Top-Right = 1
|
||||||
|
//Bottom-Left = 2 | Bottom-Right = 3
|
||||||
|
vec4 ScreenCoords[4];
|
||||||
|
ScreenCoords[0] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0);
|
||||||
|
ScreenCoords[1] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0);
|
||||||
|
ScreenCoords[2] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0);
|
||||||
|
ScreenCoords[3] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vec3 ViewVectors[4];
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
ViewVectors[i] = vec3(ConvertToView(ScreenCoords[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 EyePos = vec3(0.0, 0.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*80] = f;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ out vec4 TextureFragment;
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
TextureFragment = vec4(PickingColor, 0, 1);
|
TextureFragment = vec4(PickingColor/255, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 1024
|
||||||
|
#define NUM_TILES 3600
|
||||||
|
#define TILE_SIZE 16
|
||||||
|
|
||||||
|
uniform mat4 V;
|
||||||
|
|
||||||
|
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 * 80));
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,481 @@
|
|||||||
|
#include "Core/EntityXMLFile.h"
|
||||||
|
#include "Core/World.h"
|
||||||
|
|
||||||
|
unsigned int EntityXMLFile::InstanceCount = 0;
|
||||||
|
|
||||||
|
EntityXMLFile::EntityXMLFile(std::string path)
|
||||||
|
: m_EntityFile(path)
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
|
||||||
|
if (InstanceCount == 0) {
|
||||||
|
XMLPlatformUtils::Initialize();
|
||||||
|
}
|
||||||
|
InstanceCount++;
|
||||||
|
|
||||||
|
m_GrammarPool = new XMLGrammarPoolImpl();
|
||||||
|
m_ErrorHandler = new EntityParserXMLErrorHandler();
|
||||||
|
m_DOMParser = new XercesDOMParser(nullptr, XMLPlatformUtils::fgMemoryManager, m_GrammarPool);
|
||||||
|
m_DOMParser->setErrorHandler(m_ErrorHandler);
|
||||||
|
m_DOMParser->setDoNamespaces(true);
|
||||||
|
m_DOMParser->setDoXInclude(true);
|
||||||
|
m_DOMParser->setDoSchema(true);
|
||||||
|
m_DOMParser->setValidationSchemaFullChecking(true);
|
||||||
|
m_DOMParser->setValidationScheme(xercesc::XercesDOMParser::Val_Auto);
|
||||||
|
m_DOMParser->setValidationSchemaFullChecking(true);
|
||||||
|
m_DOMParser->setValidationConstraintFatal(false);
|
||||||
|
m_DOMParser->setIncludeIgnorableWhitespace(false);
|
||||||
|
// Make sure schema grammar is kept after validation
|
||||||
|
m_DOMParser->cacheGrammarFromParse(true);
|
||||||
|
|
||||||
|
// HACK: Use Sax2 parser instead so the entire DOM doesn't have to reside in memory
|
||||||
|
m_DOMParser->parse(m_EntityFile.c_str());
|
||||||
|
m_DOMDocument = m_DOMParser->getDocument();
|
||||||
|
|
||||||
|
// 1. Fill in ComponentInfo name, fields, default values and metadata from PSVI
|
||||||
|
parseComponentInfo();
|
||||||
|
// 2. Parse default value files for those components
|
||||||
|
parseDefaults();
|
||||||
|
// 3. Allocate component structures
|
||||||
|
predictComponentAllocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityXMLFile::~EntityXMLFile()
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
|
||||||
|
if (m_DOMParser != nullptr) {
|
||||||
|
delete m_DOMParser;
|
||||||
|
}
|
||||||
|
if (m_ErrorHandler != nullptr) {
|
||||||
|
delete m_ErrorHandler;
|
||||||
|
}
|
||||||
|
if (m_GrammarPool != nullptr) {
|
||||||
|
delete m_GrammarPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceCount--;
|
||||||
|
if (InstanceCount == 0) {
|
||||||
|
XMLPlatformUtils::Terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityXMLFile::PopulateWorld(World* world)
|
||||||
|
{
|
||||||
|
for (auto& pair : m_ComponentInfo) {
|
||||||
|
world->RegisterComponent(pair.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Parse entity hierarchy
|
||||||
|
auto root = m_DOMDocument->getDocumentElement();
|
||||||
|
parseEntityGraph(world, root, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EntityXMLFile::preprocess(std::string inPath, std::string outPath)
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
|
||||||
|
static const XMLCh gLS[] = { 'L', 'S', '\0' };
|
||||||
|
DOMImplementationLS* di = static_cast<DOMImplementationLS*>(DOMImplementationRegistry::getDOMImplementation(gLS));
|
||||||
|
|
||||||
|
// Parse the file
|
||||||
|
DOMLSParser* parser = di->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, nullptr);
|
||||||
|
DOMConfiguration* config = parser->getDomConfig();
|
||||||
|
config->setParameter(XMLUni::fgDOMNamespaces, true);
|
||||||
|
config->setParameter(XMLUni::fgXercesSchema, true);
|
||||||
|
config->setParameter(XMLUni::fgXercesHandleMultipleImports, true);
|
||||||
|
config->setParameter(XMLUni::fgXercesSchemaFullChecking, true);
|
||||||
|
config->setParameter(XMLUni::fgXercesDoXInclude, true);
|
||||||
|
auto errHandler = new EntityPreprocessorXMLErrorHandler();
|
||||||
|
config->setParameter(XMLUni::fgDOMErrorHandler, errHandler);
|
||||||
|
|
||||||
|
auto source = new LocalFileInputSource(XSTR(inPath.c_str()));
|
||||||
|
Wrapper4InputSource* domSourceWrapper = new Wrapper4InputSource(source);
|
||||||
|
DOMDocument* doc = parser->parse(dynamic_cast<DOMLSInput*>(domSourceWrapper));
|
||||||
|
|
||||||
|
// Serialize and output the new XML
|
||||||
|
DOMLSSerializer* writer = di->createLSSerializer();
|
||||||
|
DOMLSOutput* output = di->createLSOutput();
|
||||||
|
XMLFormatTarget* formatTarget = new LocalFileFormatTarget(outPath.c_str());
|
||||||
|
// TODO: MemBufFormatTarget* formatTarget = new MemBufFormatTarget()
|
||||||
|
output->setByteStream(formatTarget);
|
||||||
|
writer->write(doc, output);
|
||||||
|
|
||||||
|
delete formatTarget;
|
||||||
|
output->release();
|
||||||
|
writer->release();
|
||||||
|
parser->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityXMLFile::parseComponentInfo()
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
bool wasChanged;
|
||||||
|
XSModel* xsModel = m_GrammarPool->getXSModel(wasChanged);
|
||||||
|
|
||||||
|
// Find component xsd element declarations
|
||||||
|
std::cout << "Enumerating components..." << std::endl;
|
||||||
|
// <xs:element name="ComponentName">
|
||||||
|
auto topLevelElements = xsModel->getComponents(XSConstants::ELEMENT_DECLARATION);
|
||||||
|
for (unsigned int i = 0; i < topLevelElements->getLength(); ++i) {
|
||||||
|
auto element = static_cast<XSElementDeclaration*>(topLevelElements->item(i));
|
||||||
|
|
||||||
|
std::string nameSpace(XSTR(element->getNamespace()));
|
||||||
|
if (nameSpace != "components") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentInfo compInfo;
|
||||||
|
|
||||||
|
// Name
|
||||||
|
compInfo.Name = XSTR(element->getName());
|
||||||
|
// Annotation
|
||||||
|
auto componentAnnotation = element->getAnnotation();
|
||||||
|
if (componentAnnotation != nullptr) {
|
||||||
|
// Parse annotation XML
|
||||||
|
char* annotationString = XMLString::transcode(componentAnnotation->getAnnotationString());
|
||||||
|
MemBufInputSource annotationInput(reinterpret_cast<const XMLByte*>(annotationString), strlen(annotationString), "MemBuf: Annotation String");
|
||||||
|
XercesDOMParser parser(nullptr, XMLPlatformUtils::fgMemoryManager, m_GrammarPool);
|
||||||
|
parser.setErrorHandler(m_ErrorHandler);
|
||||||
|
parser.parse(annotationInput);
|
||||||
|
XMLString::release(&annotationString);
|
||||||
|
auto doc = parser.getDocument();
|
||||||
|
|
||||||
|
// Add allocation estimation(s)
|
||||||
|
auto allocationTags = doc->getElementsByTagName(XSTR("meta:allocation"));
|
||||||
|
for (int i = 0; i < allocationTags->getLength(); ++i) {
|
||||||
|
auto allocation = dynamic_cast<DOMElement*>(allocationTags->item(i));
|
||||||
|
auto child = allocation->getFirstChild();
|
||||||
|
if (child == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSValue::Status status;
|
||||||
|
XSValue* val = XSValue::getActualValue(child->getNodeValue(), XSValue::dt_integer, status);
|
||||||
|
compInfo.Meta.Allocation += val->fData.fValue.f_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save documentation string
|
||||||
|
auto documentationTags = doc->getElementsByTagName(XSTR("xs:documentation"));
|
||||||
|
if (documentationTags->getLength() != 0) {
|
||||||
|
auto child = documentationTags->item(0)->getFirstChild();
|
||||||
|
if (child != nullptr) {
|
||||||
|
compInfo.Meta.Annotation = XSTR(child->getNodeValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: Parse annotation string XML
|
||||||
|
// compInfo.Meta.Allocation = ...
|
||||||
|
} else {
|
||||||
|
std::cout << "Warning: Component is missing an annotation!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <xs:complexType>
|
||||||
|
auto typeDefinition = element->getTypeDefinition();
|
||||||
|
if (typeDefinition->getTypeCategory() != XSTypeDefinition::COMPLEX_TYPE) {
|
||||||
|
std::cerr << "Error: Type definition wasn't COMPLEX_TYPE! Skipping." << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto complexTypeDefinition = dynamic_cast<XSComplexTypeDefinition*>(typeDefinition);
|
||||||
|
|
||||||
|
// <xs:all>
|
||||||
|
auto modelGroupParticle = complexTypeDefinition->getParticle();
|
||||||
|
if (modelGroupParticle->getTermType() != XSParticle::TERM_MODELGROUP) {
|
||||||
|
std::cerr << "Error: Model group particle wasn't TERM_MODELGROUP! Skipping." << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto modelGroup = modelGroupParticle->getModelGroupTerm();
|
||||||
|
|
||||||
|
// <xs:element...
|
||||||
|
// <xs:attribute...
|
||||||
|
unsigned int fieldOffset = 0;
|
||||||
|
auto particles = modelGroup->getParticles();
|
||||||
|
for (unsigned int i = 0; i < particles->size(); ++i) {
|
||||||
|
auto particle = particles->elementAt(i);
|
||||||
|
if (particle->getTermType() != XSParticle::TERM_ELEMENT) {
|
||||||
|
std::cerr << "Error: Particle wasn't TERM_ELEMENT! Skipping." << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto elementDeclaration = particle->getElementTerm();
|
||||||
|
|
||||||
|
std::string name = XSTR(elementDeclaration->getName());
|
||||||
|
std::string type = XSTR(elementDeclaration->getTypeDefinition()->getName());
|
||||||
|
|
||||||
|
size_t stride = getTypeStride(type);
|
||||||
|
if (stride == 0) {
|
||||||
|
std::cout << "Warning: Field \"" << name << "\" in component \"" << compInfo.Name << "\" uses unexpected field type \"" << type << "\". Skipping." << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
compInfo.FieldTypes[name] = type;
|
||||||
|
compInfo.FieldOffsets[name] = fieldOffset;
|
||||||
|
fieldOffset += getTypeStride(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
compInfo.Meta.Stride = fieldOffset;
|
||||||
|
m_ComponentInfo[compInfo.Name] = compInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityXMLFile::parseDefaults()
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
|
||||||
|
for (auto& ci : m_ComponentInfo) {
|
||||||
|
// Allocate memory for default values
|
||||||
|
ci.second.Defaults = std::shared_ptr<char>(new char[ci.second.Meta.Stride]);
|
||||||
|
memset(ci.second.Defaults.get(), 0, ci.second.Meta.Stride);
|
||||||
|
|
||||||
|
XercesDOMParser parser(nullptr, XMLPlatformUtils::fgMemoryManager);
|
||||||
|
parser.setErrorHandler(m_ErrorHandler);
|
||||||
|
|
||||||
|
std::string componentName = ci.first;
|
||||||
|
LOG_DEBUG("Parsing defaults for component %s", componentName.c_str());
|
||||||
|
boost::filesystem::path defaultsFile = "Schema/Components/" + componentName + ".xml";
|
||||||
|
|
||||||
|
parser.parse(defaultsFile.string().c_str());
|
||||||
|
auto doc = parser.getDocument();
|
||||||
|
if (doc == nullptr) {
|
||||||
|
LOG_ERROR("%s not found! Skipping.", defaultsFile.string().c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the node in the components namespace matching the component name
|
||||||
|
std::string tagName = "c:" + componentName;
|
||||||
|
auto rootNodes = doc->getElementsByTagName(XSTR(tagName.c_str()));
|
||||||
|
if (rootNodes->getLength() == 0) {
|
||||||
|
LOG_ERROR("Couldn't find defaults for component \"%s\"! Skipping.", componentName.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto componentElement = dynamic_cast<DOMElement*>(rootNodes->item(0));
|
||||||
|
|
||||||
|
// Fill the default value buffer with values
|
||||||
|
for (auto& field : ci.second.FieldOffsets) {
|
||||||
|
std::string fieldName = field.first;
|
||||||
|
auto fieldNodes = componentElement->getElementsByTagName(XSTR(fieldName.c_str()));
|
||||||
|
auto fieldNode = fieldNodes->item(0);
|
||||||
|
if (fieldNode == nullptr) {
|
||||||
|
LOG_ERROR("Defaults for component \"%s\" is missing field \"%s\"!", componentName.c_str(), fieldName.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto fieldElement = dynamic_cast<DOMElement*>(fieldNode);
|
||||||
|
|
||||||
|
std::string fieldType = ci.second.FieldTypes.at(fieldName);
|
||||||
|
unsigned int fieldOffset = ci.second.FieldOffsets.at(fieldName);
|
||||||
|
writeData(fieldElement, fieldType, ci.second.Defaults.get() + fieldOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityXMLFile::predictComponentAllocation()
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
|
||||||
|
auto root = m_DOMDocument->getDocumentElement();
|
||||||
|
|
||||||
|
// Count static instances of components present in entity hierarchy
|
||||||
|
auto components = m_DOMDocument->getElementsByTagNameNS(XSTR("components"), XSTR("*"));
|
||||||
|
for (int i = 0; i < components->getLength(); ++i) {
|
||||||
|
auto component = dynamic_cast<DOMElement*>(components->item(i));
|
||||||
|
|
||||||
|
std::string componentName = XSTR(component->getLocalName());
|
||||||
|
auto& compInfo = m_ComponentInfo.at(componentName);
|
||||||
|
compInfo.Meta.Allocation += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "COMPONENT INFO" << std::endl;
|
||||||
|
for (auto& pair : m_ComponentInfo) {
|
||||||
|
ComponentInfo& ci = pair.second;
|
||||||
|
std::cout << "Component: " << ci.Name << " (" << ci.Meta.Annotation << ")" << std::endl;
|
||||||
|
std::cout << " Allocation: " << ci.Meta.Allocation << std::endl;
|
||||||
|
std::cout << " Fields:" << std::endl;
|
||||||
|
|
||||||
|
// Calculate component size
|
||||||
|
std::size_t stride = 0;
|
||||||
|
// Add size of fields
|
||||||
|
for (auto& field : ci.FieldTypes) {
|
||||||
|
std::cout << " " << field.second << " " << field.first << " (" << getTypeStride(field.second) << " byte)" << std::endl;
|
||||||
|
stride += getTypeStride(field.second);
|
||||||
|
}
|
||||||
|
std::cout << " Stride: " << ci.Meta.Stride << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityXMLFile::parseEntityGraph(World* world, xercesc::DOMElement* element, EntityID parentEntity)
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
|
||||||
|
// Create entity
|
||||||
|
EntityID entity = world->CreateEntity(parentEntity);
|
||||||
|
LOG_DEBUG("Created entity %i, parent %i", entity, parentEntity);
|
||||||
|
|
||||||
|
// Add components
|
||||||
|
auto components = m_DOMDocument->evaluate(XSTR("Components/*"), element, nullptr, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, nullptr);
|
||||||
|
for (int i = 0; i < components->getSnapshotLength(); i++) {
|
||||||
|
components->snapshotItem(i);
|
||||||
|
auto componentElement = dynamic_cast<DOMElement*>(components->getNodeValue());
|
||||||
|
std::string componentName = XSTR(componentElement->getLocalName());
|
||||||
|
auto& ci = m_ComponentInfo.at(componentName);
|
||||||
|
|
||||||
|
// Attach the component
|
||||||
|
auto c = world->AttachComponent(entity, componentName);
|
||||||
|
LOG_DEBUG("Attached %s component", componentName.c_str());
|
||||||
|
|
||||||
|
// Write field data
|
||||||
|
auto fields = componentElement->getChildNodes();
|
||||||
|
for (int j = 0; j < fields->getLength(); ++j) {
|
||||||
|
auto fieldNode = fields->item(j);
|
||||||
|
auto nodeType = fieldNode->getNodeType();
|
||||||
|
if (nodeType != DOMNode::ELEMENT_NODE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto field = dynamic_cast<DOMElement*>(fields->item(j));
|
||||||
|
//const XMLCh* value = fields->item(j)->getTextContent();
|
||||||
|
std::string fieldName(XSTR(field->getLocalName()));
|
||||||
|
if (ci.FieldTypes.find(fieldName) == ci.FieldTypes.end()) {
|
||||||
|
std::cout << "Warning: Component \"" << componentName << "\" contains invalid field \"" << fieldName << "\". Skipping." << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fieldType = ci.FieldTypes.at(fieldName);
|
||||||
|
unsigned int fieldOffset = ci.FieldOffsets.at(fieldName);
|
||||||
|
std::string fieldValue(XSTR(field->getTextContent()));
|
||||||
|
LOG_DEBUG(" %s %s = %s", fieldType.c_str(), fieldName.c_str(), fieldValue.c_str());
|
||||||
|
writeData(field, fieldType, c.Data + fieldOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recurse children
|
||||||
|
auto children = m_DOMDocument->evaluate(XSTR("Children/Entity"), element, nullptr, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, nullptr);
|
||||||
|
for (int i = 0; i < children->getSnapshotLength(); i++) {
|
||||||
|
children->snapshotItem(i);
|
||||||
|
parseEntityGraph(world, dynamic_cast<DOMElement*>(children->getNodeValue()), entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
//auto components = m_DOMDocument->getElementsByTagNameNS(XSTR("components"), XSTR("*"));
|
||||||
|
//for (int i = 0; i < components->getLength(); ++i) {
|
||||||
|
// auto component = dynamic_cast<DOMElement*>(components->item(i));
|
||||||
|
|
||||||
|
// std::string componentName = XSTR(component->getLocalName());
|
||||||
|
// auto& compStore = m_ComponentStore.at(componentName);
|
||||||
|
// auto& compInfo = compStore.Info;
|
||||||
|
|
||||||
|
// char* data = &compStore.Data[compStore.Size*compStore.Stride];
|
||||||
|
// compStore.Size += 1;
|
||||||
|
|
||||||
|
// auto fields = component->getChildNodes();
|
||||||
|
// for (int j = 0; j < fields->getLength(); ++j) {
|
||||||
|
// auto field = fields->item(j);
|
||||||
|
// auto nodeType = field->getNodeType();
|
||||||
|
// if (nodeType != DOMNode::ELEMENT_NODE) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// //auto field = dynamic_cast<DOMElement*>(fields->item(j));
|
||||||
|
// //const XMLCh* value = fields->item(j)->getTextContent();
|
||||||
|
// std::string fieldName = XSTR(field->getLocalName());
|
||||||
|
// if (compInfo.FieldTypes.find(fieldName) == compInfo.FieldTypes.end()) {
|
||||||
|
// std::cout << "Warning: Component \"" << componentName << "\" contains invalid field \"" << fieldName << "\". Skipping." << std::endl;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::string fieldType = compInfo.FieldTypes.at(fieldName);
|
||||||
|
// unsigned int fieldOffset = compInfo.FieldOffsets.at(fieldName);
|
||||||
|
|
||||||
|
// XSValue::DataType dataType = XSValue::getDataType(XSTR(fieldType.c_str()));
|
||||||
|
// if (dataType == XSValue::DataType::dt_MAXCOUNT) {
|
||||||
|
// // TODO:
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (dataType == XSValue::DataType::dt_string) {
|
||||||
|
// char* str = XMLString::transcode(field->getTextContent());
|
||||||
|
// std::string standardString(str);
|
||||||
|
// XMLString::release(&str);
|
||||||
|
// memcpy(&data[fieldOffset], reinterpret_cast<char*>(&standardString), getTypeStride(fieldType));
|
||||||
|
// } else {
|
||||||
|
// XSValue::Status status;
|
||||||
|
// XSValue* val = XSValue::getActualValue(field->getTextContent(), dataType, status);
|
||||||
|
// memcpy(&data[fieldOffset], reinterpret_cast<char*>(&val->fData.fValue), getTypeStride(fieldType));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//auto entities = m_DOMDocument->getElementsByTagName(XSTR("Entity"));
|
||||||
|
//for (int i = 0; i < entities->getLength(); ++i) {
|
||||||
|
// auto entity = dynamic_cast<DOMElement*>(entities->item(i));
|
||||||
|
|
||||||
|
|
||||||
|
// //entity->setIdAttribute()
|
||||||
|
|
||||||
|
// std::cout << "ENTITY " << i + 1 << std::endl;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t EntityXMLFile::getTypeStride(std::string typeName)
|
||||||
|
{
|
||||||
|
std::map<std::string, size_t> typeStrides{
|
||||||
|
{ "bool", sizeof(bool) },
|
||||||
|
{ "int", sizeof(int) },
|
||||||
|
{ "double", sizeof(double) },
|
||||||
|
{ "string", sizeof(std::string) },
|
||||||
|
{ "Vector", sizeof(glm::vec3) },
|
||||||
|
{ "Quaternion", sizeof(glm::quat) },
|
||||||
|
{ "Color", sizeof(glm::vec4) }
|
||||||
|
};
|
||||||
|
|
||||||
|
auto it = typeStrides.find(typeName);
|
||||||
|
return (it != typeStrides.end()) ? it->second : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float EntityXMLFile::getFloatAttribute(const xercesc::DOMElement* element, const char* attribute) const
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
XSValue::Status status;
|
||||||
|
XSValue* val = XSValue::getActualValue(element->getAttribute(XSTR(attribute)), xercesc::XSValue::DataType::dt_float, status);
|
||||||
|
if (val == nullptr) {
|
||||||
|
LOG_ERROR("Element \"%s\" doesn't have an \"%s\" attribute!", XSTR(element->getTagName()), attribute);
|
||||||
|
return 0.f;
|
||||||
|
} else {
|
||||||
|
return val->fData.fValue.f_float;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityXMLFile::writeData(const xercesc::DOMElement* element, std::string typeName, char* outData)
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
|
||||||
|
XSValue::DataType dataType = XSValue::getDataType(XSTR(typeName.c_str()));
|
||||||
|
if (dataType == XSValue::DataType::dt_MAXCOUNT) {
|
||||||
|
if (typeName == "Vector") {
|
||||||
|
glm::vec3 vec;
|
||||||
|
vec.x = getFloatAttribute(element, "X");
|
||||||
|
vec.y = getFloatAttribute(element, "Y");
|
||||||
|
vec.z = getFloatAttribute(element, "Z");
|
||||||
|
memcpy(outData, reinterpret_cast<char*>(&vec), getTypeStride(typeName));
|
||||||
|
} else if (typeName == "Color") {
|
||||||
|
glm::vec4 vec;
|
||||||
|
vec.r = getFloatAttribute(element, "R");
|
||||||
|
vec.g = getFloatAttribute(element, "G");
|
||||||
|
vec.b = getFloatAttribute(element, "B");
|
||||||
|
vec.a = getFloatAttribute(element, "A");
|
||||||
|
memcpy(outData, reinterpret_cast<char*>(&vec), getTypeStride(typeName));
|
||||||
|
} else if (typeName == "Quaternion") {
|
||||||
|
glm::quat q;
|
||||||
|
q.x = getFloatAttribute(element, "X");
|
||||||
|
q.y = getFloatAttribute(element, "Y");
|
||||||
|
q.z = getFloatAttribute(element, "Z");
|
||||||
|
q.w = getFloatAttribute(element, "W");
|
||||||
|
memcpy(outData, reinterpret_cast<char*>(&q), getTypeStride(typeName));
|
||||||
|
}
|
||||||
|
} else if (dataType == XSValue::DataType::dt_string) {
|
||||||
|
char* str = XMLString::transcode(element->getTextContent());
|
||||||
|
std::string standardString(str);
|
||||||
|
new (outData) std::string(str);
|
||||||
|
XMLString::release(&str);
|
||||||
|
//memcpy(outData, reinterpret_cast<char*>(&standardString), getTypeStride(typeName));
|
||||||
|
} else {
|
||||||
|
XSValue::Status status;
|
||||||
|
XSValue* val = XSValue::getActualValue(element->getTextContent(), dataType, status);
|
||||||
|
memcpy(outData, reinterpret_cast<char*>(&val->fData.fValue), getTypeStride(typeName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -35,6 +35,20 @@ void ResourceManager::Reload(std::string resourceName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ResourceManager::Release(std::string resourceType, std::string resourceName)
|
||||||
|
{
|
||||||
|
auto key = std::make_pair(resourceType, resourceName);
|
||||||
|
if (m_ResourceCache.find(key) == m_ResourceCache.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto resource = m_ResourceCache.at(key);
|
||||||
|
m_ResourceCache.erase(key);
|
||||||
|
m_ResourceFromName.erase(resourceName);
|
||||||
|
m_ResourceParents.erase(resource);
|
||||||
|
delete resource;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int ResourceManager::GetNewResourceID(unsigned int typeID)
|
unsigned int ResourceManager::GetNewResourceID(unsigned int typeID)
|
||||||
{
|
{
|
||||||
return m_ResourceCount[typeID]++;
|
return m_ResourceCount[typeID]++;
|
||||||
|
|||||||
@@ -41,9 +41,16 @@ ComponentWrapper World::GetComponent(EntityID entity, std::string componentType)
|
|||||||
return pool->GetByEntity(entity);
|
return pool->GetByEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ComponentPool& World::GetComponents(std::string componentType)
|
const ComponentPool* World::GetComponents(std::string componentType)
|
||||||
{
|
{
|
||||||
return *m_ComponentPools.at(componentType);
|
auto it = m_ComponentPools.find(componentType);
|
||||||
|
return (it != m_ComponentPools.end()) ? it->second : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EntityID World::GetParent(EntityID entity)
|
||||||
|
{
|
||||||
|
return m_EntityParents.at(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityID World::generateEntityID()
|
EntityID World::generateEntityID()
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include "Rendering/DrawScenePass.h"
|
||||||
|
|
||||||
|
DrawScenePass::DrawScenePass(IRenderer* renderer)
|
||||||
|
{
|
||||||
|
m_Renderer = renderer;
|
||||||
|
InitializeTextures();
|
||||||
|
InitializeShaderPrograms();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawScenePass::InitializeTextures()
|
||||||
|
{
|
||||||
|
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawScenePass::InitializeShaderPrograms()
|
||||||
|
{
|
||||||
|
//Gör så att shaders är en resource, tex som texture classen. Konstruktorn måste vara privat.
|
||||||
|
m_BasicForwardProgram = ResourceManager::Load<ShaderProgram>("#BasicForwardProgram");
|
||||||
|
|
||||||
|
m_BasicForwardProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/BasicForward.vert.glsl")));
|
||||||
|
m_BasicForwardProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/BasicForward.frag.glsl")));
|
||||||
|
m_BasicForwardProgram->Compile();
|
||||||
|
m_BasicForwardProgram->Link();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawScenePass::Draw(RenderQueueCollection& rq)
|
||||||
|
{
|
||||||
|
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
GLERROR("DrawScenePass::Draw: Pre");
|
||||||
|
|
||||||
|
DrawScenePassState state;
|
||||||
|
m_BasicForwardProgram->Bind();
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: Render: Add code for more jobs than modeljobs.
|
||||||
|
for (auto &job : rq.Forward) {
|
||||||
|
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||||
|
if (modelJob) {
|
||||||
|
GLuint ShaderHandle = m_BasicForwardProgram->GetHandle();
|
||||||
|
|
||||||
|
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix()));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix()));
|
||||||
|
glUniform4fv(glGetUniformLocation(ShaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
|
||||||
|
|
||||||
|
//TODO: Renderer: bättre textur felhantering samt fler texturer stöd
|
||||||
|
if (modelJob->DiffuseTexture != nullptr) {
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture);
|
||||||
|
} else {
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(modelJob->Model->VAO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||||
|
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GLERROR("DrawScenePass::Draw: End");
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#include "Rendering/DrawScenePassState.h"
|
||||||
|
|
||||||
|
|
||||||
|
DrawScenePassState::DrawScenePassState()
|
||||||
|
{
|
||||||
|
GLERROR("---");
|
||||||
|
BindBuffer(0);
|
||||||
|
GLERROR("---");
|
||||||
|
Enable(GL_DEPTH_TEST);
|
||||||
|
Enable(GL_CULL_FACE);
|
||||||
|
ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f));
|
||||||
|
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawScenePassState::~DrawScenePassState()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -48,13 +48,21 @@ void FrameBuffer::Generate()
|
|||||||
switch ((*it)->m_ResourceType) {
|
switch ((*it)->m_ResourceType) {
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0);
|
||||||
|
GLERROR("FrameBuffer generate: glFramebufferTexture2D");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case GL_RENDERBUFFER:
|
case GL_RENDERBUFFER:
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle);
|
||||||
|
GLERROR("FrameBuffer generate: glFramebufferRenderbuffer");
|
||||||
|
if ( (*it)->m_Attachment != GL_COLOR_ATTACHMENT0 ||
|
||||||
|
(*it)->m_Attachment != GL_DEPTH_ATTACHMENT ||
|
||||||
|
(*it)->m_Attachment != GL_STENCIL_ATTACHMENT)
|
||||||
|
{
|
||||||
|
LOG_ERROR("RenderBuffer Attachment not valid.");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLERROR("FrameBuffer generate");
|
|
||||||
|
|
||||||
if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) {
|
if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) {
|
||||||
attachments.push_back((*it)->m_Attachment);
|
attachments.push_back((*it)->m_Attachment);
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
#include "Rendering/PickingPass.h"
|
||||||
|
|
||||||
|
PickingPass::PickingPass(IRenderer* renderer, EventBroker* eb)
|
||||||
|
{
|
||||||
|
m_Renderer = renderer;
|
||||||
|
m_EventBroker = eb;
|
||||||
|
|
||||||
|
InitializeTextures();
|
||||||
|
InitializeFrameBuffers();
|
||||||
|
InitializeShaderPrograms();
|
||||||
|
}
|
||||||
|
|
||||||
|
PickingPass::~PickingPass()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickingPass::InitializeTextures()
|
||||||
|
{
|
||||||
|
GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR,
|
||||||
|
glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickingPass::InitializeFrameBuffers()
|
||||||
|
{
|
||||||
|
glGenRenderbuffers(1, &m_DepthBuffer);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
||||||
|
|
||||||
|
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
|
||||||
|
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0)));
|
||||||
|
m_PickingBuffer.Generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickingPass::InitializeShaderPrograms()
|
||||||
|
{
|
||||||
|
m_PickingProgram = ResourceManager::Load<ShaderProgram>("#PickingProgram");
|
||||||
|
|
||||||
|
m_PickingProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Picking.vert.glsl")));
|
||||||
|
m_PickingProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Picking.frag.glsl")));
|
||||||
|
m_PickingProgram->Compile();
|
||||||
|
m_PickingProgram->BindFragDataLocation(0, "TextureFragment");
|
||||||
|
m_PickingProgram->Link();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickingPass::Draw(RenderQueueCollection& rq)
|
||||||
|
{
|
||||||
|
m_PickingColorsToEntity.clear();
|
||||||
|
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
|
||||||
|
|
||||||
|
int r = 1;
|
||||||
|
int g = 0;
|
||||||
|
//TODO: Render: Add code for more jobs than modeljobs.
|
||||||
|
|
||||||
|
GLuint ShaderHandle = m_PickingProgram->GetHandle();
|
||||||
|
m_PickingProgram->Bind();
|
||||||
|
|
||||||
|
for (auto &job : rq.Forward) {
|
||||||
|
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||||
|
|
||||||
|
if (modelJob) {
|
||||||
|
//---------------
|
||||||
|
//TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame.
|
||||||
|
//---------------
|
||||||
|
int pickColor[2] = { r, g };
|
||||||
|
for (auto i : m_PickingColorsToEntity) {
|
||||||
|
if (modelJob->Entity == i.second) {
|
||||||
|
pickColor[0] = i.first.x;
|
||||||
|
pickColor[1] = i.first.y;
|
||||||
|
r -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity;
|
||||||
|
|
||||||
|
//Render picking stuff
|
||||||
|
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix()));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix()));
|
||||||
|
glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||||
|
|
||||||
|
glBindVertexArray(modelJob->Model->VAO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||||
|
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex);
|
||||||
|
r += 1;
|
||||||
|
if (r > 255) {
|
||||||
|
r = 0;
|
||||||
|
g += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_PickingBuffer.Unbind();
|
||||||
|
GLERROR("PickingPass Error");
|
||||||
|
|
||||||
|
//Publish pick event every frame with the pick data that can be picked by the event
|
||||||
|
Events::Picking pickEvent = Events::Picking(
|
||||||
|
&m_PickingBuffer,
|
||||||
|
&m_DepthBuffer,
|
||||||
|
m_Renderer->Camera()->ProjectionMatrix(),
|
||||||
|
m_Renderer->Camera()->ViewMatrix(),
|
||||||
|
m_Renderer->Resolution(),
|
||||||
|
&m_PickingColorsToEntity);
|
||||||
|
|
||||||
|
m_EventBroker->Publish(pickEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const
|
||||||
|
{
|
||||||
|
//TODO: Renderer: Make this in a sparate class
|
||||||
|
glGenTextures(1, texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, *texture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution
|
||||||
|
GLERROR("Texture initialization failed");
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#include "Rendering/PickingPassState.h"
|
||||||
|
|
||||||
|
|
||||||
|
PickingPassState::PickingPassState(GLuint frameBuffer)
|
||||||
|
{
|
||||||
|
GLERROR("---2");
|
||||||
|
BindBuffer(frameBuffer);
|
||||||
|
GLERROR("---3");
|
||||||
|
Enable(GL_DEPTH_TEST);
|
||||||
|
Enable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
glm::vec4 clearColor = glm::vec4(0.f);
|
||||||
|
ClearColor(clearColor);
|
||||||
|
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
PickingPassState::~PickingPassState()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -34,10 +34,10 @@ RawModel::RawModel(std::string fileName)
|
|||||||
numIndices += face.mNumIndices;
|
numIndices += face.mNumIndices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Vertex count %i", numVertices);
|
//LOG_DEBUG("Vertex count %i", numVertices);
|
||||||
LOG_DEBUG("Index count %i", numIndices);
|
//LOG_DEBUG("Index count %i", numIndices);
|
||||||
|
|
||||||
LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
|
//LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
|
||||||
|
|
||||||
std::vector<std::tuple<std::string, glm::mat4>> boneInfo;
|
std::vector<std::tuple<std::string, glm::mat4>> boneInfo;
|
||||||
std::map<std::string, int> boneNameMapping;
|
std::map<std::string, int> boneNameMapping;
|
||||||
@@ -132,35 +132,35 @@ RawModel::RawModel(std::string fileName)
|
|||||||
matGroup.EndIndex = m_Indices.size() - 1;
|
matGroup.EndIndex = m_Indices.size() - 1;
|
||||||
// Material shininess
|
// Material shininess
|
||||||
material->Get(AI_MATKEY_SHININESS, matGroup.Shininess);
|
material->Get(AI_MATKEY_SHININESS, matGroup.Shininess);
|
||||||
LOG_DEBUG("Shininess: %f", matGroup.Shininess);
|
//LOG_DEBUG("Shininess: %f", matGroup.Shininess);
|
||||||
// Diffuse texture
|
// Diffuse texture
|
||||||
LOG_DEBUG("%i diffuse textures found", material->GetTextureCount(aiTextureType_DIFFUSE));
|
//LOG_DEBUG("%i diffuse textures found", material->GetTextureCount(aiTextureType_DIFFUSE));
|
||||||
if (material->GetTextureCount(aiTextureType_DIFFUSE)) {
|
if (material->GetTextureCount(aiTextureType_DIFFUSE)) {
|
||||||
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();
|
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
|
||||||
LOG_DEBUG("Diffuse texture: %s", absolutePath.c_str());
|
//LOG_DEBUG("Diffuse texture: %s", absolutePath.c_str());
|
||||||
matGroup.Texture = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
|
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));
|
||||||
if (material->GetTextureCount(aiTextureType_HEIGHT)) {
|
if (material->GetTextureCount(aiTextureType_HEIGHT)) {
|
||||||
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();
|
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
|
||||||
LOG_DEBUG("Normal map: %s", absolutePath.c_str());
|
//LOG_DEBUG("Normal map: %s", absolutePath.c_str());
|
||||||
matGroup.NormalMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
|
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));
|
||||||
if (material->GetTextureCount(aiTextureType_SPECULAR)) {
|
if (material->GetTextureCount(aiTextureType_SPECULAR)) {
|
||||||
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();
|
std::string absolutePath = (boost::filesystem::path(fileName).branch_path() / path.C_Str()).string();
|
||||||
LOG_DEBUG("Specular map: %s", absolutePath.c_str());
|
//LOG_DEBUG("Specular map: %s", absolutePath.c_str());
|
||||||
matGroup.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
|
matGroup.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(absolutePath));
|
||||||
}
|
}
|
||||||
TextureGroups.push_back(matGroup);
|
TextureGroups.push_back(matGroup);
|
||||||
@@ -216,20 +216,20 @@ RawModel::RawModel(std::string fileName)
|
|||||||
m_Skeleton = new Skeleton();
|
m_Skeleton = new Skeleton();
|
||||||
CreateSkeleton(boneInfo, boneNameMapping, scene->mRootNode, -1);
|
CreateSkeleton(boneInfo, boneNameMapping, scene->mRootNode, -1);
|
||||||
int numBones = m_Skeleton->Bones.size();
|
int numBones = m_Skeleton->Bones.size();
|
||||||
LOG_DEBUG("Bone count: %i", numBones);
|
//LOG_DEBUG("Bone count: %i", numBones);
|
||||||
if (numBones > 0) {
|
if (numBones > 0) {
|
||||||
m_Skeleton->PrintSkeleton();
|
m_Skeleton->PrintSkeleton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animations
|
// Animations
|
||||||
LOG_DEBUG("Animation count: %i", scene->mNumAnimations);
|
//LOG_DEBUG("Animation count: %i", scene->mNumAnimations);
|
||||||
for (int i = 0; i < scene->mNumAnimations; ++i) {
|
for (int i = 0; i < scene->mNumAnimations; ++i) {
|
||||||
auto animation = scene->mAnimations[i];
|
auto animation = scene->mAnimations[i];
|
||||||
std::string animationName = animation->mName.C_Str();
|
std::string animationName = animation->mName.C_Str();
|
||||||
LOG_DEBUG("Animation: %s", animationName.c_str());
|
//LOG_DEBUG("Animation: %s", animationName.c_str());
|
||||||
LOG_DEBUG("Duration: %f", animation->mDuration);
|
//LOG_DEBUG("Duration: %f", animation->mDuration);
|
||||||
LOG_DEBUG("Ticks per second: %f", animation->mTicksPerSecond);
|
//LOG_DEBUG("Ticks per second: %f", animation->mTicksPerSecond);
|
||||||
|
|
||||||
Skeleton::Animation skelAnim;
|
Skeleton::Animation skelAnim;
|
||||||
skelAnim.Name = animationName;
|
skelAnim.Name = animationName;
|
||||||
@@ -303,7 +303,7 @@ void RawModel::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &b
|
|||||||
|
|
||||||
// Find the bone by name in the bone info list
|
// Find the bone by name in the bone info list
|
||||||
if (boneNameMapping.find(nodeName) == boneNameMapping.end()) {
|
if (boneNameMapping.find(nodeName) == boneNameMapping.end()) {
|
||||||
LOG_DEBUG("Node \"%s\" was not a bone", nodeName.c_str());
|
//LOG_DEBUG("Node \"%s\" was not a bone", nodeName.c_str());
|
||||||
} else {
|
} else {
|
||||||
glm::mat4 offsetMatrix;
|
glm::mat4 offsetMatrix;
|
||||||
int ID = boneNameMapping[nodeName];
|
int ID = boneNameMapping[nodeName];
|
||||||
|
|||||||
@@ -15,49 +15,87 @@ void RenderQueueFactory::Update(World* world)
|
|||||||
|
|
||||||
glm::mat4 RenderQueueFactory::ModelMatrix(World* world, EntityID entity)
|
glm::mat4 RenderQueueFactory::ModelMatrix(World* world, EntityID entity)
|
||||||
{
|
{
|
||||||
//should really return absolute model matrix based on parents position, scale and orientation
|
glm::vec3 position = AbsolutePosition(world, entity);
|
||||||
//GetAbsolutePosition(World* world, ComponentWrapper transformComponent)
|
glm::quat orientation = AbsoluteOrientation(world, entity);
|
||||||
|
glm::vec3 scale = AbsoluteScale(world, entity);
|
||||||
|
|
||||||
ComponentWrapper transformComponent = world->GetComponent(entity, "Transform");
|
glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale);
|
||||||
glm::vec3 position = transformComponent["Position"];
|
|
||||||
glm::vec3 scale = transformComponent["Scale"];
|
|
||||||
glm::quat oritentation = transformComponent["Orientation"];
|
|
||||||
|
|
||||||
glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(oritentation) * glm::scale(scale);
|
|
||||||
return modelMatrix;
|
return modelMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent)
|
|
||||||
|
glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity)
|
||||||
{
|
{
|
||||||
// positionComponent.EntityID
|
glm::vec3 position;
|
||||||
return glm::vec3();
|
|
||||||
|
do {
|
||||||
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
|
position += (glm::vec3)transform["Position"];
|
||||||
|
entity = world->GetParent(entity);
|
||||||
|
} while (entity != 0);
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat RenderQueueFactory::AbsoluteOrientation(World* world, EntityID entity)
|
||||||
|
{
|
||||||
|
glm::quat orientation;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
|
orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation;
|
||||||
|
entity = world->GetParent(entity);
|
||||||
|
} while (entity != 0);
|
||||||
|
|
||||||
|
return orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 RenderQueueFactory::AbsoluteScale(World* world, EntityID entity)
|
||||||
|
{
|
||||||
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
|
glm::vec3 scale = (glm::vec3)transform["Scale"];
|
||||||
|
|
||||||
|
EntityID parent = world->GetParent(entity);
|
||||||
|
if (parent != 0) {
|
||||||
|
return AbsoluteScale(world, parent) * scale;
|
||||||
|
} else {
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
|
void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
|
||||||
{
|
{
|
||||||
for(auto& modelC : world->GetComponents("Model")) {
|
auto models = world->GetComponents("Model");
|
||||||
ModelJob job;
|
if (models == nullptr) {
|
||||||
std::string resource = modelC["Resource"];
|
return;
|
||||||
glm::vec4 color = modelC["Color"];
|
}
|
||||||
Model* model = ResourceManager::Load<Model>(resource);
|
|
||||||
|
|
||||||
for (auto texGroup : model->TextureGroups) {
|
for (auto& modelC : *models) {
|
||||||
job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0;
|
std::string resource = modelC["Resource"];
|
||||||
job.DiffuseTexture = texGroup.Texture.get();
|
if (resource.empty()) {
|
||||||
job.NormalTexture = texGroup.NormalMap.get();
|
continue;
|
||||||
job.SpecularTexture = texGroup.SpecularMap.get();
|
}
|
||||||
job.Model = model;
|
glm::vec4 color = modelC["Color"];
|
||||||
job.StartIndex = texGroup.StartIndex;
|
Model* model = ResourceManager::Load<Model>(resource);
|
||||||
job.EndIndex = texGroup.EndIndex;
|
|
||||||
job.ModelMatrix = model->m_Matrix * ModelMatrix(world, modelC.EntityID);
|
|
||||||
job.Color = color;
|
|
||||||
|
|
||||||
//TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this
|
for (auto texGroup : model->TextureGroups) {
|
||||||
job.Entity = modelC.EntityID;
|
ModelJob job;
|
||||||
|
job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0;
|
||||||
|
job.DiffuseTexture = texGroup.Texture.get();
|
||||||
|
job.NormalTexture = texGroup.NormalMap.get();
|
||||||
|
job.SpecularTexture = texGroup.SpecularMap.get();
|
||||||
|
job.Model = model;
|
||||||
|
job.StartIndex = texGroup.StartIndex;
|
||||||
|
job.EndIndex = texGroup.EndIndex;
|
||||||
|
job.ModelMatrix = model->m_Matrix * ModelMatrix(world, modelC.EntityID);
|
||||||
|
job.Color = color;
|
||||||
|
|
||||||
renderQueue->Add(job);
|
//TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this
|
||||||
}
|
job.Entity = modelC.EntityID;
|
||||||
}
|
|
||||||
|
renderQueue->Add(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderQueueFactory::FillLights(World* world, RenderQueue* renderQueue)
|
void RenderQueueFactory::FillLights(World* world, RenderQueue* renderQueue)
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
#include "Rendering/RenderState.h"
|
||||||
|
|
||||||
|
RenderState::RenderState()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderState::Enable(GLenum GLEnable)
|
||||||
|
{
|
||||||
|
if(glIsEnabled(GLEnable))
|
||||||
|
{
|
||||||
|
//LOG_WARNING("Trying to enable somthing that is already enabled.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_Enables.push_back(GLEnable);
|
||||||
|
glEnable(GLEnable);
|
||||||
|
if (GLERROR("RenderState::Enable"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderState::CullFace(GLenum GLCullFace)
|
||||||
|
{
|
||||||
|
if(!glIsEnabled(GL_CULL_FACE))
|
||||||
|
{
|
||||||
|
//LOG_ERROR("Setting GL_CULL_FACE without enabling it.");
|
||||||
|
Enable(GL_CULL_FACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
glCullFace(GLCullFace);
|
||||||
|
if (GLERROR("RenderState::CullFace"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderState::ClearColor(glm::vec4 color)
|
||||||
|
{
|
||||||
|
glGetFloatv(GL_COLOR_CLEAR_VALUE, &m_preClearColor[0]);
|
||||||
|
glClearColor(color.r, color.g, color.b, color.a);
|
||||||
|
if (GLERROR("RenderState::ClearColor")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderState::Clear(GLbitfield mask)
|
||||||
|
{
|
||||||
|
glClear(mask);
|
||||||
|
if (GLERROR("RenderState::Clear")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderState::BindBuffer(GLint buffer)
|
||||||
|
{
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_preBuffer);
|
||||||
|
if (buffer == m_preBuffer)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, buffer);
|
||||||
|
if (GLERROR("RenderState::BindBuffer"))
|
||||||
|
{
|
||||||
|
printf("BufferID: %i\npreBufferID: %i\n", buffer, m_preBuffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderState::~RenderState()
|
||||||
|
{
|
||||||
|
GLERROR("RenderState::~RenderState Pre");
|
||||||
|
GLint n_buffer = -1;
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &n_buffer);
|
||||||
|
|
||||||
|
//Set cullface to default
|
||||||
|
if (glIsEnabled(GL_CULL_FACE)) {
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
}
|
||||||
|
GLERROR("RenderState::~RenderState glCullFace");
|
||||||
|
|
||||||
|
//Set color to default
|
||||||
|
glClearColor(m_preClearColor[0], m_preClearColor[1], m_preClearColor[2], m_preClearColor[3]);
|
||||||
|
GLERROR("RenderState::~RenderState glClearColor");
|
||||||
|
|
||||||
|
//Disable Enables
|
||||||
|
for (auto i : m_Enables)
|
||||||
|
{
|
||||||
|
glDisable(i);
|
||||||
|
}
|
||||||
|
GLERROR("RenderState::~RenderState glDisable");
|
||||||
|
|
||||||
|
if(m_preBuffer != 0)
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
m_Enables.clear();
|
||||||
|
GLERROR("RenderState::~RenderState glBindFramebuffer");
|
||||||
|
}
|
||||||
|
|
||||||
+177
-161
@@ -3,19 +3,20 @@
|
|||||||
void Renderer::Initialize()
|
void Renderer::Initialize()
|
||||||
{
|
{
|
||||||
InitializeWindow();
|
InitializeWindow();
|
||||||
|
|
||||||
// Create default camera
|
// Create default camera
|
||||||
m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(45.f), 0.01f, 5000.f);
|
m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(90.0f), 0.01f, 5000.f);
|
||||||
m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10));
|
m_DefaultCamera->SetPosition(glm::vec3(0, 1, 10));
|
||||||
if (m_Camera == nullptr) {
|
if (m_Camera == nullptr) {
|
||||||
m_Camera = m_DefaultCamera;
|
m_Camera = m_DefaultCamera;
|
||||||
}
|
}
|
||||||
|
TEMPCreateLights();
|
||||||
|
InitializeRenderPasses();
|
||||||
|
|
||||||
glfwSwapInterval(m_VSYNC);
|
glfwSwapInterval(m_VSYNC);
|
||||||
InitializeShaders();
|
InitializeShaders();
|
||||||
InitializeTextures();
|
InitializeTextures();
|
||||||
InitializeFrameBuffers();
|
InitializeSSBOs();
|
||||||
|
CalculateFrustum();
|
||||||
|
|
||||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||||
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
|
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
|
||||||
@@ -64,22 +65,29 @@ void Renderer::InitializeWindow()
|
|||||||
|
|
||||||
void Renderer::InitializeShaders()
|
void Renderer::InitializeShaders()
|
||||||
{
|
{
|
||||||
m_BasicForwardProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/BasicForward.vert.glsl")));
|
m_BasicForwardProgram = ResourceManager::Load<ShaderProgram>("#m_BasicForwardProgram");
|
||||||
m_BasicForwardProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/BasicForward.frag.glsl")));
|
|
||||||
m_BasicForwardProgram.Compile();
|
|
||||||
m_BasicForwardProgram.Link();
|
|
||||||
|
|
||||||
m_PickingProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Picking.vert.glsl")));
|
m_DrawScreenQuadProgram = ResourceManager::Load<ShaderProgram>("#DrawScreenQuadProgram");
|
||||||
m_PickingProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Picking.frag.glsl")));
|
m_DrawScreenQuadProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawScreenQuad.vert.glsl")));
|
||||||
m_PickingProgram.Compile();
|
m_DrawScreenQuadProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl")));
|
||||||
m_PickingProgram.BindFragDataLocation(0, "TextureFragment");
|
m_DrawScreenQuadProgram->Compile();
|
||||||
m_PickingProgram.Link();
|
m_DrawScreenQuadProgram->Link();
|
||||||
|
|
||||||
m_DrawScreenQuadProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawScreenQuad.vert.glsl")));
|
m_CalculateFrustumProgram = ResourceManager::Load<ShaderProgram>("#CalculateFrustumProgram");
|
||||||
m_DrawScreenQuadProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl")));
|
m_CalculateFrustumProgram->AddShader(std::shared_ptr<Shader>(new ComputeShader("Shaders/GridFrustum.comp.glsl")));
|
||||||
m_DrawScreenQuadProgram.Compile();
|
m_CalculateFrustumProgram->Compile();
|
||||||
m_DrawScreenQuadProgram.Link();
|
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();
|
||||||
|
|
||||||
|
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 Renderer::InputUpdate(double dt)
|
void Renderer::InputUpdate(double dt)
|
||||||
@@ -113,26 +121,8 @@ void Renderer::InputUpdate(double dt)
|
|||||||
m_CameraMoveSpeed = 0.5f;
|
m_CameraMoveSpeed = 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double mousePosX, mousePosY;
|
static double mousePosX, mousePosY;
|
||||||
glfwGetCursorPos(m_Window, &mousePosX, &mousePosY);
|
glfwGetCursorPos(m_Window, &mousePosX, &mousePosY);
|
||||||
if (glfwGetMouseButton(m_Window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) {
|
|
||||||
glm::vec3 data = ScreenCoords::ToPixelData(mousePosX, m_Resolution.Height - mousePosY, &m_PickingBuffer, m_DepthBuffer);
|
|
||||||
glm::vec2 color = glm::vec2(data);
|
|
||||||
float depth = data.z;
|
|
||||||
|
|
||||||
glm::vec3 viewPos = ScreenCoords::ToWorldPos(mousePosX, m_Resolution.Height - mousePosY, depth, m_Resolution, m_Camera->ProjectionMatrix(), m_Camera->ViewMatrix());
|
|
||||||
// glm::vec3 worldPos = glm::vec3(glm::inverse(m_Camera->ViewMatrix()) * glm::vec4(viewPos, 1.f));
|
|
||||||
|
|
||||||
//printf("R: %f, G: %f, Depth: %f\n", color.r, color.g, depth);
|
|
||||||
//printf("view: x: %f, y: %f z: %f, Length: %f\n\n", viewPos.x, viewPos.y, viewPos.z, glm::length(viewPos));
|
|
||||||
|
|
||||||
if (color != glm::vec2(0, 0)) {
|
|
||||||
EntityID pickedEntity = m_PickingColorsToEntity[color];
|
|
||||||
printf("Picked Entity: %i", pickedEntity);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) {
|
if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) {
|
||||||
|
|
||||||
@@ -158,39 +148,176 @@ void Renderer::InputUpdate(double dt)
|
|||||||
|
|
||||||
void Renderer::Update(double dt)
|
void Renderer::Update(double dt)
|
||||||
{
|
{
|
||||||
InputUpdate(dt);
|
m_EventBroker->Process<Renderer>();
|
||||||
|
InputUpdate(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Draw(RenderQueueCollection& rq)
|
void Renderer::Draw(RenderQueueCollection& rq)
|
||||||
{
|
{
|
||||||
//TODO: Renderer: Kanske borde vara längst upp i update.
|
m_PickingPass->Draw(rq);
|
||||||
PickingPass(rq);
|
//DrawScreenQuad(m_PickingPass->PickingTexture());
|
||||||
DrawScreenQuad(m_PickingTexture);
|
CullLights();
|
||||||
|
|
||||||
DrawScene(rq);
|
//m_DrawScenePass->Draw(rq);
|
||||||
|
DrawForwardPlus(rq);
|
||||||
|
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
|
||||||
glfwSwapBuffers(m_Window);
|
glfwSwapBuffers(m_Window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawScene(RenderQueueCollection& rq)
|
void Renderer::DrawScreenQuad(GLuint textureToDraw)
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
//TODO: Render: Clean up draw code
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
||||||
|
m_DrawScreenQuadProgram->Bind();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureToDraw);
|
||||||
|
|
||||||
|
glBindVertexArray(m_ScreenQuad->VAO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
||||||
|
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->TextureGroups[0].EndIndex - m_ScreenQuad->TextureGroups[0].StartIndex +1
|
||||||
|
, GL_UNSIGNED_INT, 0, m_ScreenQuad->TextureGroups[0].StartIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::InitializeTextures()
|
||||||
|
{
|
||||||
|
m_ErrorTexture=ResourceManager::Load<Texture>("Textures/Core/ErrorTexture.png");
|
||||||
|
m_WhiteTexture=ResourceManager::Load<Texture>("Textures/Core/Blank.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
||||||
|
{
|
||||||
|
glGenTextures(1, texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, *texture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, NULL);//TODO: Renderer: Fix the precision and Resolution
|
||||||
|
GLERROR("Texture initialization failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::InitializeSSBOs()
|
||||||
|
{
|
||||||
|
printf("Size: %i\n", sizeof(m_Frustums));
|
||||||
|
glGenBuffers(1, &m_FrustumSSBO);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO);
|
||||||
|
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_Frustums), &m_Frustums, GL_DYNAMIC_COPY);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
GLERROR("m_FrustumSSBO");
|
||||||
|
|
||||||
|
glGenBuffers(1, &m_LightSSBO);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
|
||||||
|
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_PointLights), &m_PointLights, GL_DYNAMIC_COPY);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
GLERROR("m_LightSSBO");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glGenBuffers(1, &m_LightGridSSBO);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO);
|
||||||
|
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightGrid), &m_LightGrid, GL_DYNAMIC_COPY);
|
||||||
|
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(m_LightIndex), &m_LightIndex, GL_DYNAMIC_COPY);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
GLERROR("m_LightIndexSSBO");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::InitializeRenderPasses()
|
||||||
|
{
|
||||||
|
m_DrawScenePass = new DrawScenePass(this);
|
||||||
|
m_PickingPass = new PickingPass(this, m_EventBroker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::CalculateFrustum()
|
||||||
|
{
|
||||||
|
GLERROR("CalculateFrustum Error: Pre");
|
||||||
|
|
||||||
|
m_CalculateFrustumProgram->Bind();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix()));
|
||||||
|
glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height);
|
||||||
|
glDispatchCompute(5, 3, 1);
|
||||||
|
|
||||||
|
GLERROR("CalculateFrustum Error: End");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::TEMPCreateLights()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_LIGHTS; i++)
|
||||||
|
{
|
||||||
|
glm::vec3 pos = glm::vec3(cos(i) * i/10.f , 0.5f, sin(i) * i/10.f);
|
||||||
|
m_PointLights[i].Position = glm::vec4(pos, 1.f);
|
||||||
|
m_PointLights[i].Color = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand()%255 / 255.f, 1.f);
|
||||||
|
m_PointLights[i].Radius = 5.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::CullLights()
|
||||||
|
{
|
||||||
|
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, 0);
|
||||||
|
|
||||||
|
|
||||||
|
m_LightCullProgram->Bind();
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(m_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_Resolution.Width / TILE_SIZE, m_Resolution.Height / TILE_SIZE, 1);
|
||||||
|
|
||||||
|
GLERROR("CullLights Error: End");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::DrawForwardPlus(RenderQueueCollection& rq)
|
||||||
|
{
|
||||||
|
GLERROR("Renderer::DrawForwardPlus: Pre");
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(GL_BACK);
|
glClearColor(200.f / 255, 0.f / 255, 200.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_ForwardPlusProgram->Bind();
|
||||||
|
GLuint ShaderHandle = m_ForwardPlusProgram->GetHandle();
|
||||||
|
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO);
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
|
||||||
//TODO: Render: Add code for more jobs than modeljobs.
|
//TODO: Render: Add code for more jobs than modeljobs.
|
||||||
for (auto &job : rq.Forward) {
|
for (auto &job : rq.Forward) {
|
||||||
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();
|
|
||||||
|
|
||||||
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->ModelMatrix));
|
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
|
||||||
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix()));
|
||||||
@@ -213,117 +340,6 @@ void Renderer::DrawScene(RenderQueueCollection& rq)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GLERROR("Renderer::DrawForwardPlus: End");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::PickingPass(RenderQueueCollection& rq)
|
|
||||||
{
|
|
||||||
m_PickingBuffer.Bind();
|
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
glCullFace(GL_BACK);
|
|
||||||
|
|
||||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
int r = 30;
|
|
||||||
int g = 0;
|
|
||||||
//TODO: Render: Add code for more jobs than modeljobs.
|
|
||||||
|
|
||||||
|
|
||||||
GLuint ShaderHandle = m_PickingProgram.GetHandle();
|
|
||||||
m_PickingProgram.Bind();
|
|
||||||
|
|
||||||
for (auto &job : rq.Forward) {
|
|
||||||
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
|
||||||
|
|
||||||
if (modelJob) {
|
|
||||||
glm::vec2 pickColor = glm::vec2(r/255.f, g/255.f);
|
|
||||||
m_PickingColorsToEntity[pickColor] = modelJob->Entity;
|
|
||||||
|
|
||||||
|
|
||||||
//Render picking stuff
|
|
||||||
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix()));
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix()));
|
|
||||||
glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(pickColor));
|
|
||||||
|
|
||||||
glBindVertexArray(modelJob->Model->VAO);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
|
||||||
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
|
|
||||||
r+=50;
|
|
||||||
if(r > 255) {
|
|
||||||
r = 0;
|
|
||||||
g+=50;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_PickingBuffer.Unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::DrawScreenQuad(GLuint textureToDraw)
|
|
||||||
{
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
|
|
||||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
|
|
||||||
m_DrawScreenQuadProgram.Bind();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textureToDraw);
|
|
||||||
|
|
||||||
glBindVertexArray(m_ScreenQuad->VAO);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer);
|
|
||||||
glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->TextureGroups[0].EndIndex - m_ScreenQuad->TextureGroups[0].StartIndex +1
|
|
||||||
, GL_UNSIGNED_INT, 0, m_ScreenQuad->TextureGroups[0].StartIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::InitializeTextures()
|
|
||||||
{
|
|
||||||
m_ErrorTexture=ResourceManager::Load<Texture>("Textures/Core/ErrorTexture.png");
|
|
||||||
m_WhiteTexture=ResourceManager::Load<Texture>("Textures/Core/Blank.png");
|
|
||||||
/*
|
|
||||||
glGenTextures(1, &m_PickingTexture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_PickingTexture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, m_Resolution.Width, m_Resolution.Height, 0, GL_RG, GL_FLOAT, NULL);//TODO: Renderer: Fix the precision and Resolution
|
|
||||||
GLERROR("m_PickingTexture initialization failed");
|
|
||||||
*/
|
|
||||||
|
|
||||||
GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR,
|
|
||||||
glm::vec2(m_Resolution.Width, m_Resolution.Height), GL_RG8, GL_RG, GL_FLOAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
|
||||||
{
|
|
||||||
glGenTextures(1, texture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, *texture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, NULL);//TODO: Renderer: Fix the precision and Resolution
|
|
||||||
GLERROR("Texture initialization failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::InitializeFrameBuffers()//TODO: Renderer: Get this to a better location, as its really big
|
|
||||||
{
|
|
||||||
glGenRenderbuffers(1, &m_DepthBuffer);
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer);
|
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Resolution.Width, m_Resolution.Height);
|
|
||||||
|
|
||||||
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT)));
|
|
||||||
m_PickingBuffer.AddResource(std::shared_ptr<BufferResource>(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0)));
|
|
||||||
m_PickingBuffer.Generate();
|
|
||||||
}
|
|
||||||
@@ -29,22 +29,31 @@ glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, float scr
|
|||||||
return ToWorldPos(screenCoord.x, screenCoord.y, depth, screenWidth, screenHeight, cameraProjectionMat, cameraViewMat);
|
return ToWorldPos(screenCoord.x, screenCoord.y, depth, screenWidth, screenHeight, cameraProjectionMat, cameraViewMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
ScreenCoords::PixelData ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
||||||
{
|
{
|
||||||
PickDataBuffer->Bind();
|
PickDataBuffer->Bind();
|
||||||
glm::vec2 pixelData;
|
unsigned char pdata[2];
|
||||||
glReadPixels(x, y, 1, 1, GL_RG, GL_FLOAT, &pixelData);
|
glReadPixels(x, y, 1, 1, GL_RG, GL_UNSIGNED_BYTE, &pdata);
|
||||||
PickDataBuffer->Unbind();
|
PickDataBuffer->Unbind();
|
||||||
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer);
|
||||||
float depthData;
|
float depthData;
|
||||||
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData);
|
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
return glm::vec3(pixelData, depthData);
|
PixelData p;
|
||||||
|
p.Color[0] = (int)pdata[0];
|
||||||
|
p.Color[1] = (int)pdata[1];
|
||||||
|
p.Depth = depthData;
|
||||||
|
|
||||||
|
GLERROR("ScreenCoords::ToPixelData Error");
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 ScreenCoords::ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
ScreenCoords::PixelData ScreenCoords::ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
||||||
{
|
{
|
||||||
return ToPixelData(screenCoord.x, screenCoord.y, PickDataBuffer, DepthBuffer);
|
return ToPixelData(screenCoord.x, screenCoord.y, PickDataBuffer, DepthBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ file(GLOB SOURCE_FILES
|
|||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
${SOURCE_FILES}
|
${SOURCE_FILES}
|
||||||
"Game.cpp"
|
"Game.cpp"
|
||||||
|
"PlayerSystem.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBRARIES
|
set(LIBRARIES
|
||||||
|
|||||||
+88
-43
@@ -1,69 +1,114 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "HardcodedTestWorld.h"
|
|
||||||
|
|
||||||
Game::Game(int argc, char* argv[])
|
Game::Game(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
|
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
|
||||||
ResourceManager::RegisterType<Model>("Model");
|
ResourceManager::RegisterType<Model>("Model");
|
||||||
ResourceManager::RegisterType<Texture>("Texture");
|
ResourceManager::RegisterType<Texture>("Texture");
|
||||||
|
ResourceManager::RegisterType<EntityXMLFile>("EntityXMLFile");
|
||||||
|
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
|
||||||
|
|
||||||
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
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
|
||||||
m_EventBroker = new EventBroker();
|
m_EventBroker = new EventBroker();
|
||||||
|
|
||||||
m_RenderQueueFactory = new RenderQueueFactory();
|
m_RenderQueueFactory = new RenderQueueFactory();
|
||||||
|
|
||||||
// Create the renderer
|
// Create the renderer
|
||||||
m_Renderer = new Renderer();
|
m_Renderer = new Renderer(m_EventBroker);
|
||||||
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
|
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
|
||||||
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
|
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
|
||||||
m_Renderer->SetResolution(Rectangle(
|
m_Renderer->SetResolution(Rectangle(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
m_Config->Get<int>("Video.Width", 1280),
|
m_Config->Get<int>("Video.Width", 1280),
|
||||||
m_Config->Get<int>("Video.Height", 720)
|
m_Config->Get<int>("Video.Height", 720)
|
||||||
));
|
));
|
||||||
m_Renderer->Initialize();
|
m_Renderer->Initialize();
|
||||||
|
m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get<float>("Video.FOV", 90.f)));
|
||||||
|
|
||||||
// Create input manager
|
// Create input manager
|
||||||
m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker);
|
m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker);
|
||||||
|
|
||||||
// Create the root level GUI frame
|
// Create the root level GUI frame
|
||||||
m_FrameStack = new GUI::Frame(m_EventBroker);
|
m_FrameStack = new GUI::Frame(m_EventBroker);
|
||||||
m_FrameStack->Width = m_Renderer->Resolution().Width;
|
m_FrameStack->Width = m_Renderer->Resolution().Width;
|
||||||
m_FrameStack->Height = m_Renderer->Resolution().Height;
|
m_FrameStack->Height = m_Renderer->Resolution().Height;
|
||||||
|
|
||||||
// Create a TEST WORLD
|
// Create a world
|
||||||
m_World = new HardcodedTestWorld();
|
m_World = new World();
|
||||||
|
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
|
||||||
|
if (!mapToLoad.empty()) {
|
||||||
|
ResourceManager::Load<EntityXMLFile>(mapToLoad)->PopulateWorld(m_World);
|
||||||
|
}
|
||||||
|
|
||||||
m_LastTime = glfwGetTime();
|
// Create system pipeline
|
||||||
|
m_SystemPipeline = new SystemPipeline(m_EventBroker);
|
||||||
|
m_SystemPipeline->AddSystem<RaptorCopterSystem>();
|
||||||
|
m_SystemPipeline->AddSystem<PlayerSystem>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
m_LastTime = glfwGetTime();
|
||||||
|
|
||||||
|
testIntialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::~Game()
|
Game::~Game()
|
||||||
{
|
{
|
||||||
delete m_FrameStack;
|
delete m_FrameStack;
|
||||||
delete m_EventBroker;
|
delete m_EventBroker;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::Tick()
|
void Game::Tick()
|
||||||
{
|
{
|
||||||
double currentTime = glfwGetTime();
|
double currentTime = glfwGetTime();
|
||||||
double dt = currentTime - m_LastTime;
|
double dt = currentTime - m_LastTime;
|
||||||
m_LastTime = currentTime;
|
m_LastTime = currentTime;
|
||||||
|
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_InputManager->Update(dt);
|
m_InputManager->Update(dt);
|
||||||
m_Renderer->Update(dt);
|
m_EventBroker->Swap();
|
||||||
m_EventBroker->Swap();
|
|
||||||
|
// Iterate through systems and update world!
|
||||||
|
m_SystemPipeline->Update(m_World, dt);
|
||||||
|
testTick(dt);
|
||||||
|
m_Renderer->Update(dt);
|
||||||
|
|
||||||
m_RenderQueueFactory->Update(m_World);
|
m_RenderQueueFactory->Update(m_World);
|
||||||
|
GLERROR("Game::Tick m_RenderQueueFactory->Update");
|
||||||
|
m_Renderer->Draw(m_RenderQueueFactory->RenderQueues());
|
||||||
|
GLERROR("Game::Tick m_Renderer->Draw");
|
||||||
|
m_EventBroker->Swap();
|
||||||
|
m_EventBroker->Clear();
|
||||||
|
|
||||||
m_Renderer->Draw(m_RenderQueueFactory->RenderQueues());
|
glfwPollEvents();
|
||||||
|
}
|
||||||
m_EventBroker->Swap();
|
|
||||||
m_EventBroker->Clear();
|
|
||||||
|
bool Game::testOnKeyUp(const Events::KeyUp& e)
|
||||||
glfwPollEvents();
|
{
|
||||||
|
if (e.KeyCode == GLFW_KEY_R) {
|
||||||
|
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
|
||||||
|
if (!mapToLoad.empty()) {
|
||||||
|
delete m_World;
|
||||||
|
m_World = new World();
|
||||||
|
ResourceManager::Release("EntityXMLFile", mapToLoad);
|
||||||
|
ResourceManager::Load<EntityXMLFile>(mapToLoad)->PopulateWorld(m_World);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::testIntialize()
|
||||||
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Game::testOnKeyUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::testTick(double dt)
|
||||||
|
{
|
||||||
|
m_EventBroker->Process<Game>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include "PlayerSystem.h"
|
||||||
|
|
||||||
|
|
||||||
|
void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt)
|
||||||
|
{
|
||||||
|
if (input.Forward) {
|
||||||
|
m_Direction.z = -1;
|
||||||
|
} else if (input.Back) {
|
||||||
|
m_Direction.z = 1;
|
||||||
|
} else {
|
||||||
|
m_Direction.z = 0;
|
||||||
|
}
|
||||||
|
if (input.Left) {
|
||||||
|
m_Direction.x = -1;
|
||||||
|
} else if (input.Right) {
|
||||||
|
m_Direction.x = 1;
|
||||||
|
} else {
|
||||||
|
m_Direction.x = 0;
|
||||||
|
}
|
||||||
|
m_EventBroker->Process<PlayerSystem>();
|
||||||
|
ComponentWrapper& transform = world->GetComponent(player.EntityID, "Transform");
|
||||||
|
(glm::vec3&)player["Velocity"] = m_Speed * float(dt) * m_Direction;
|
||||||
|
(glm::vec3&)transform["Position"] += (glm::vec3)player["Velocity"];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerSystem::OnKeyDown(const Events::KeyDown & event)
|
||||||
|
{
|
||||||
|
if (event.KeyCode == GLFW_KEY_W) {
|
||||||
|
input.Forward = true;
|
||||||
|
}
|
||||||
|
if (event.KeyCode == GLFW_KEY_A) {
|
||||||
|
input.Left = true;
|
||||||
|
}
|
||||||
|
if (event.KeyCode == GLFW_KEY_S) {
|
||||||
|
input.Back = true;
|
||||||
|
}
|
||||||
|
if (event.KeyCode == GLFW_KEY_D) {
|
||||||
|
input.Right = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerSystem::OnKeyUp(const Events::KeyUp & event)
|
||||||
|
{
|
||||||
|
if (event.KeyCode == GLFW_KEY_W) {
|
||||||
|
input.Forward = false;
|
||||||
|
}
|
||||||
|
if (event.KeyCode == GLFW_KEY_A) {
|
||||||
|
input.Left = false;
|
||||||
|
}
|
||||||
|
if (event.KeyCode == GLFW_KEY_S) {
|
||||||
|
input.Back = false;
|
||||||
|
}
|
||||||
|
if (event.KeyCode == GLFW_KEY_D) {
|
||||||
|
input.Right = false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user