Merge branch 'OctTree' of github.com:teamfisk/TacticalZ into OctTree
# Conflicts: # src/Engine/Core/OctTree.cpp
This commit is contained in:
@@ -9,6 +9,7 @@ Libraries bundled along with binaries for Windows (MSVC14), available as a submo
|
||||
| **[Assimp](http://assimp.sourceforge.net)** | 3.1.1 | [BSD 3-Clause License](http://assimp.sourceforge.net/main_license.html) |
|
||||
| **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) |
|
||||
| **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) |
|
||||
| **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
|
||||
|
||||
#### External libraries
|
||||
Libraries that are too big to be bundled with the project.
|
||||
|
||||
+1
-1
Submodule assets updated: 6b30aa83cf...4bd902b697
@@ -0,0 +1,23 @@
|
||||
# XERCES_FOUND
|
||||
# XERCES_INCLUDE_DIRS
|
||||
# XERCES_LIBRARIES
|
||||
|
||||
find_path(XERCES_INCLUDE_DIR xercesc/dom/dom.hpp
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
find_library(XERCES_LIBRARY
|
||||
NAMES
|
||||
xerces-c_3
|
||||
xerces-c_3D
|
||||
PATHS
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
set(XERCES_INCLUDE_DIRS ${XERCES_INCLUDE_DIR})
|
||||
set(XERCES_LIBRARIES ${XERCES_LIBRARY})
|
||||
|
||||
find_package_handle_standard_args(Xerces DEFAULT_MSG XERCES_LIBRARY XERCES_INCLUDE_DIR)
|
||||
mark_as_advanced(Xerces_FOUND XERCES_INCLUDE_DIR XERCES_LIBRARY)
|
||||
+1
-1
Submodule deps updated: 65d3f3bc31...1b478d3159
@@ -0,0 +1,31 @@
|
||||
#ifndef ComponentInfo_h__
|
||||
#define ComponentInfo_h__
|
||||
|
||||
#include "../Common.h"
|
||||
|
||||
struct ComponentInfo
|
||||
{
|
||||
struct Meta_t
|
||||
{
|
||||
std::string Annotation;
|
||||
unsigned int Allocation = 0;
|
||||
unsigned int Stride = 0;
|
||||
};
|
||||
|
||||
std::string Name;
|
||||
std::unordered_map<std::string, std::string> FieldTypes;
|
||||
std::unordered_map<std::string, unsigned int> FieldOffsets;
|
||||
Meta_t Meta;
|
||||
std::shared_ptr<char> Defaults = nullptr;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct std::hash<ComponentInfo>
|
||||
{
|
||||
inline std::size_t operator()(const ComponentInfo& v) const
|
||||
{
|
||||
return std::hash<std::string>()(v.Name);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef ComponentPool_h__
|
||||
#define ComponentPool_h__
|
||||
|
||||
#include "MemoryPool.h"
|
||||
#include "ComponentInfo.h"
|
||||
#include "ComponentWrapper.h"
|
||||
|
||||
class ComponentPoolForwardIterator
|
||||
: public std::iterator<std::forward_iterator_tag, ComponentWrapper>
|
||||
{
|
||||
public:
|
||||
ComponentPoolForwardIterator(const ComponentInfo& componentInfo, const MemoryPool<char>::iterator begin, const MemoryPool<char>::iterator end)
|
||||
: m_ComponentInfo(componentInfo)
|
||||
, m_MemoryPoolIterator(begin)
|
||||
, m_MemoryPoolEnd(end)
|
||||
{ }
|
||||
|
||||
ComponentPoolForwardIterator(const ComponentPoolForwardIterator& other) = default;
|
||||
ComponentPoolForwardIterator(ComponentPoolForwardIterator&& other) = default;
|
||||
~ComponentPoolForwardIterator() = default;
|
||||
ComponentPoolForwardIterator& operator=(const ComponentPoolForwardIterator& other) = default;
|
||||
ComponentPoolForwardIterator& operator++();
|
||||
ComponentPoolForwardIterator& operator++(int);
|
||||
bool operator!=(const ComponentPoolForwardIterator& other) const;
|
||||
bool operator==(const ComponentPoolForwardIterator& other) const;
|
||||
ComponentWrapper operator*() const;
|
||||
|
||||
private:
|
||||
const ComponentInfo& m_ComponentInfo;
|
||||
MemoryPool<char>::iterator m_MemoryPoolIterator;
|
||||
const MemoryPool<char>::iterator m_MemoryPoolEnd;
|
||||
};
|
||||
|
||||
class ComponentPool
|
||||
{
|
||||
public:
|
||||
typedef ComponentPoolForwardIterator iterator;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef size_t size_type;
|
||||
typedef ComponentWrapper value_type;
|
||||
typedef ComponentWrapper* pointer;
|
||||
typedef ComponentWrapper& reference;
|
||||
|
||||
ComponentPool(const ::ComponentInfo& ci)
|
||||
: m_ComponentInfo(ci)
|
||||
, m_Pool(ci.Meta.Allocation, sizeof(EntityID) + ci.Meta.Stride)
|
||||
{ }
|
||||
ComponentPool(const ComponentPool& other) = delete;
|
||||
ComponentPool(const ComponentPool&& other) = delete;
|
||||
|
||||
const ::ComponentInfo& ComponentInfo() const { return m_ComponentInfo; }
|
||||
|
||||
// Allocate space for a component and store which entity it belongs to in internal structure
|
||||
ComponentWrapper Allocate(EntityID entity);
|
||||
// Get the component belonging to a specific entity
|
||||
ComponentWrapper GetByEntity(EntityID ent);
|
||||
// Delete a component and free its memory
|
||||
void Delete(ComponentWrapper& wrapper);
|
||||
|
||||
iterator begin() const;
|
||||
iterator end() const;
|
||||
|
||||
//Dumps information about what the pool memory looks like right now
|
||||
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
|
||||
//Interpret the data in the memory as InterpretType.
|
||||
template <typename InterpretType = char, typename OutStream>
|
||||
void Dump(OutStream& out) const;
|
||||
|
||||
//Dumps information about what the pool memory looks like right now
|
||||
//into std::cout. Interpret the data in the memory as InterpretType.
|
||||
template <typename InterpretType = char>
|
||||
void Dump() const;
|
||||
|
||||
private:
|
||||
::ComponentInfo m_ComponentInfo;
|
||||
MemoryPool<char> m_Pool;
|
||||
std::unordered_map<EntityID, char*> m_EntityToComponent;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,105 @@
|
||||
#ifndef ComponentWrapper_h__
|
||||
#define ComponentWrapper_h__
|
||||
|
||||
#include "../Common.h"
|
||||
#include "EntityWrapper.h"
|
||||
#include "ComponentInfo.h"
|
||||
#include "Util/Any.h"
|
||||
|
||||
struct ComponentWrapper
|
||||
{
|
||||
ComponentWrapper(const ComponentInfo& componentInfo, char* data)
|
||||
: Info(componentInfo)
|
||||
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
||||
, Data(data + sizeof(EntityID))
|
||||
{ }
|
||||
|
||||
const ComponentInfo& Info;
|
||||
const ::EntityID EntityID;
|
||||
char* Data;
|
||||
|
||||
template <typename T>
|
||||
T& Property(std::string name)
|
||||
{
|
||||
unsigned int offset = Info.FieldOffsets.at(name);
|
||||
return *reinterpret_cast<T*>(&Data[offset]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SetProperty(std::string name, const T value) { Property<T>(name) = value; }
|
||||
//template <typename T>
|
||||
//void SetProperty(std::string name, T& value) { Property<T>(name) = value; }
|
||||
|
||||
// Specialization for string literals
|
||||
template <std::size_t N>
|
||||
void SetProperty(std::string name, const char(&value)[N]) { Property<std::string>(name) = std::string(value); }
|
||||
|
||||
struct SubscriptProxy
|
||||
{
|
||||
friend struct ComponentWrapper;
|
||||
private:
|
||||
SubscriptProxy(ComponentWrapper* component, std::string propertyName)
|
||||
: m_Component(component)
|
||||
, m_PropertyName(propertyName)
|
||||
{ }
|
||||
|
||||
ComponentWrapper* m_Component;
|
||||
std::string m_PropertyName;
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
operator T&() { return m_Component->Property<T>(m_PropertyName); }
|
||||
|
||||
template <typename T>
|
||||
void operator=(const T val) { m_Component->SetProperty<T>(m_PropertyName, val); }
|
||||
// TODO: Pass by reference and rvalue (universal reference?)
|
||||
//template <typename T>
|
||||
//void operator=(T& val) { m_Component->SetProperty<T>(m_PropertyName, val); }
|
||||
|
||||
// Specialization for string literals
|
||||
template<std::size_t N>
|
||||
void operator=(const char(&val)[N]) { m_Component->SetProperty<N>(m_PropertyName, val); }
|
||||
};
|
||||
SubscriptProxy operator[](std::string propertyName) { return SubscriptProxy(this, propertyName); }
|
||||
};
|
||||
|
||||
// TODO: Move this to Tests once entity importing is finished
|
||||
class ComponentWrapperFactory
|
||||
{
|
||||
public:
|
||||
ComponentWrapperFactory() = default;
|
||||
ComponentWrapperFactory(std::string componentTypeName, std::size_t allocation = 0)
|
||||
{
|
||||
m_ComponentInfo.Name = componentTypeName;
|
||||
m_ComponentInfo.Meta.Allocation = allocation;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddProperty(std::string fieldName, T defaultValue)
|
||||
{
|
||||
m_DefaultValues.push_back(defaultValue);
|
||||
m_ComponentInfo.FieldTypes[fieldName] = typeid(T).name();
|
||||
m_ComponentInfo.FieldOffsets[fieldName] = m_ComponentInfo.Meta.Stride;
|
||||
m_ComponentInfo.Meta.Stride += sizeof(T);
|
||||
}
|
||||
|
||||
ComponentInfo& Finalize()
|
||||
{
|
||||
m_ComponentInfo.Defaults = std::shared_ptr<char>(new char[m_ComponentInfo.Meta.Stride]);
|
||||
std::size_t offset = 0;
|
||||
for (auto& val : m_DefaultValues) {
|
||||
memcpy(m_ComponentInfo.Defaults.get() + offset, val.Data.get(), val.Size);
|
||||
offset += val.Size;
|
||||
}
|
||||
|
||||
return m_ComponentInfo;
|
||||
}
|
||||
|
||||
operator ComponentInfo&() { return Finalize(); }
|
||||
|
||||
private:
|
||||
ComponentInfo m_ComponentInfo;
|
||||
std::vector<Any> m_DefaultValues;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,480 @@
|
||||
#include "../Common.h"
|
||||
#include <sstream>
|
||||
#include "../GLM.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#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 "EntityWrapper.h"
|
||||
#include "ComponentWrapper.h"
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct ComponentPool
|
||||
{
|
||||
std::string ComponentName;
|
||||
unsigned int Size = 0;
|
||||
unsigned int Stride = 0;
|
||||
ComponentInfo Info;
|
||||
char* Data = nullptr;
|
||||
|
||||
// TODO: Iterators
|
||||
ComponentWrapper at(unsigned int index)
|
||||
{
|
||||
// TODO: EntityID
|
||||
return ComponentWrapper(0, &Info, Data + (index*Stride));
|
||||
}
|
||||
};
|
||||
|
||||
class EntityFactory
|
||||
{
|
||||
public:
|
||||
EntityFactory(std::string entityFile)
|
||||
: m_EntityFile(entityFile)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
~EntityFactory()
|
||||
{
|
||||
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 Preprocess(boost::filesystem::path inPath, boost::filesystem::path 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.string().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.string().c_str());
|
||||
// TODO: MemBufFormatTarget* formatTarget = new MemBufFormatTarget()
|
||||
output->setByteStream(formatTarget);
|
||||
writer->write(doc, output);
|
||||
|
||||
delete formatTarget;
|
||||
output->release();
|
||||
writer->release();
|
||||
parser->release();
|
||||
}
|
||||
void Parse()
|
||||
{
|
||||
// HACK: Use Sax2 parser instead so the whole 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
|
||||
AllocateComponentStore();
|
||||
// 4. Parse entity hierarchy
|
||||
ParseEntityGraph();
|
||||
}
|
||||
|
||||
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;
|
||||
public:
|
||||
std::map<std::string, ComponentPool> m_ComponentStore;
|
||||
std::vector<EntityWrapper*> m_Entities;
|
||||
private:
|
||||
|
||||
/*
|
||||
Preprocess an XML file and output a new one
|
||||
where xsi:includes are processed, since apparently
|
||||
Xerces can't handle processing includes before validating schema.
|
||||
*/
|
||||
|
||||
void 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 ParseDefaults()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AllocateComponentStore()
|
||||
{
|
||||
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
|
||||
unsigned int stride = 0;
|
||||
// Reserve space for Entity pointer
|
||||
stride += sizeof(EntityWrapper*);
|
||||
std::cout << " Entity " << " (" << sizeof(EntityWrapper*) << " byte)" << std::endl;
|
||||
// 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: " << stride << std::endl;
|
||||
|
||||
ComponentPool cs;
|
||||
cs.ComponentName = ci.Name;
|
||||
cs.Stride = stride;
|
||||
cs.Info = ci;
|
||||
cs.Data = new char[stride*ci.Meta.Allocation];
|
||||
m_ComponentStore[cs.ComponentName] = cs;
|
||||
}
|
||||
}
|
||||
|
||||
void ParseEntityGraph()
|
||||
{
|
||||
using namespace xercesc;
|
||||
|
||||
auto root = m_DOMDocument->getDocumentElement();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
size_t getTypeStride(std::string typeName)
|
||||
{
|
||||
std::map<std::string, size_t> typeStrides{
|
||||
{ "int", sizeof(int) },
|
||||
{ "double", sizeof(double) },
|
||||
{ "string", sizeof(std::string) },
|
||||
{ "Vector", sizeof(glm::vec3) },
|
||||
{ "Quaternion", sizeof(glm::quat) },
|
||||
};
|
||||
|
||||
auto it = typeStrides.find(typeName);
|
||||
return (it != typeStrides.end()) ? it->second : 0;
|
||||
}
|
||||
};
|
||||
|
||||
unsigned int EntityFactory::InstanceCount = 0;
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "ResourceManager.h"
|
||||
|
||||
class EntityFile : public Resource
|
||||
{
|
||||
friend class ResourceManager;
|
||||
|
||||
private:
|
||||
EntityFile(std::string path);
|
||||
|
||||
public:
|
||||
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef Entity_h__
|
||||
#define Entity_h__
|
||||
|
||||
typedef unsigned int EntityID;
|
||||
|
||||
struct EntityWrapper
|
||||
{
|
||||
EntityWrapper(EntityID entityID)
|
||||
: ID(entityID)
|
||||
{ }
|
||||
|
||||
EntityID ID;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
|
||||
MemoryPool()
|
||||
: m_StartAddress(nullptr)
|
||||
, m_SlotIsAllocated()
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef Util_Any_h__
|
||||
#define Util_Any_h__
|
||||
|
||||
#include <memory>
|
||||
|
||||
struct Any
|
||||
{
|
||||
Any() { }
|
||||
|
||||
template <typename T>
|
||||
Any(const T& value)
|
||||
{
|
||||
Data = std::shared_ptr<char>(new char[sizeof(T)]);
|
||||
Size = sizeof(T);
|
||||
memcpy(Data.get(), &value, Size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Any(T&& value)
|
||||
{
|
||||
Data = std::shared_ptr<char>(new char[sizeof(T)]);
|
||||
Size = sizeof(T);
|
||||
memcpy(Data.get(), &value, Size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Any& operator=(const T& value)
|
||||
{
|
||||
return Any(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Any& operator=(T&& value)
|
||||
{
|
||||
return Any(value);
|
||||
}
|
||||
|
||||
std::shared_ptr<char> Data = nullptr;
|
||||
std::size_t Size = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef World_h__
|
||||
#define World_h__
|
||||
|
||||
#include "../Common.h"
|
||||
#include "EntityWrapper.h"
|
||||
#include "ObjectPool.h"
|
||||
#include "ComponentPool.h"
|
||||
|
||||
class World
|
||||
{
|
||||
public:
|
||||
World() = default;
|
||||
~World();
|
||||
|
||||
EntityID CreateEntity(EntityID parent = 0);
|
||||
|
||||
// Register a component type and allocate space for it
|
||||
void RegisterComponent(ComponentInfo& ci);
|
||||
// Attach a component to an entity and fill it with default values
|
||||
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
|
||||
// Get a component of an entity
|
||||
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
||||
// Get all components of the specified type
|
||||
const ComponentPool& GetComponents(std::string componentType);
|
||||
|
||||
private:
|
||||
EntityID m_CurrentEntityID = 0;
|
||||
|
||||
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
||||
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
|
||||
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
|
||||
|
||||
EntityID generateEntityID();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef Client_h__
|
||||
#define Client_h__
|
||||
|
||||
#include <boost\asio.hpp>
|
||||
|
||||
class Client
|
||||
{
|
||||
Client();
|
||||
~Client();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef Server_h__
|
||||
#define Server_h__
|
||||
|
||||
#include <boost\asio.hpp>
|
||||
|
||||
class Server
|
||||
{
|
||||
Server();
|
||||
~Server();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,10 +46,7 @@ public:
|
||||
float FarClip() const { return m_FarClip; }
|
||||
void SetFarClip(float val);
|
||||
|
||||
float m_AspectRatio;
|
||||
float m_FOV;
|
||||
float m_NearClip;
|
||||
float m_FarClip;
|
||||
|
||||
|
||||
private:
|
||||
void UpdateViewMatrix();
|
||||
@@ -60,6 +57,11 @@ private:
|
||||
|
||||
glm::mat4 m_ProjectionMatrix;
|
||||
glm::mat4 m_ViewMatrix;
|
||||
|
||||
float m_AspectRatio;
|
||||
float m_FOV;
|
||||
float m_NearClip;
|
||||
float m_FarClip;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
#ifndef FrameBuffer_h__
|
||||
#define FrameBuffer_h__
|
||||
|
||||
#include "../OpenGL.h"
|
||||
#include "Util/GLError.h"
|
||||
|
||||
class BufferResource
|
||||
{
|
||||
public:
|
||||
BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment);
|
||||
|
||||
GLuint* m_ResourceHandle;
|
||||
GLenum m_ResourceType;
|
||||
GLenum m_Attachment;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
template <GLenum RESOURCETYPE>
|
||||
class ResourceType : public BufferResource
|
||||
{
|
||||
public:
|
||||
ResourceType(GLuint* resourceHandle, GLenum attachment)
|
||||
: BufferResource(resourceHandle, RESOURCETYPE, attachment) { }
|
||||
};
|
||||
|
||||
class Texture2D : public ResourceType<GL_TEXTURE_2D>
|
||||
{
|
||||
public:
|
||||
Texture2D(GLuint* resourceHandle, GLenum attachment)
|
||||
: ResourceType(resourceHandle, attachment) { };
|
||||
|
||||
~Texture2D();
|
||||
};
|
||||
|
||||
class RenderBuffer : public ResourceType<GL_RENDERBUFFER>
|
||||
{
|
||||
public:
|
||||
RenderBuffer(GLuint* resourceHandle, GLenum attachment)
|
||||
: ResourceType(resourceHandle, attachment)
|
||||
{ };
|
||||
|
||||
~RenderBuffer();
|
||||
};
|
||||
|
||||
class FrameBuffer
|
||||
{
|
||||
public:
|
||||
FrameBuffer()
|
||||
: m_BufferHandle(0) { }
|
||||
~FrameBuffer();
|
||||
|
||||
void AddResource(std::shared_ptr<BufferResource> resource);
|
||||
void Generate();
|
||||
void Bind();
|
||||
void Unbind();
|
||||
GLuint GetHandle();
|
||||
|
||||
private:
|
||||
GLuint m_BufferHandle;
|
||||
std::vector<std::shared_ptr<BufferResource>> m_Resources;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -3,9 +3,12 @@
|
||||
|
||||
#include "../Common.h"
|
||||
#include "../OpenGL.h"
|
||||
#include "../GLM.h"
|
||||
#include "../Core/Util/Rectangle.h"
|
||||
#include "Util/ScreenCoords.h"
|
||||
#include "Camera.h"
|
||||
#include "RenderQueue.h"
|
||||
#include "Model.h"
|
||||
|
||||
class IRenderer
|
||||
{
|
||||
@@ -28,6 +31,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void Initialize() = 0;
|
||||
virtual void Update(double dt) = 0;
|
||||
virtual void Draw(RenderQueueCollection& rq) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -7,12 +7,15 @@
|
||||
#include "../Common.h"
|
||||
#include "../GLM.h"
|
||||
#include "../Core/Util/Rectangle.h"
|
||||
#include "../Core/EntityWrapper.h"
|
||||
|
||||
class Model;
|
||||
class Skeleton;
|
||||
class Texture;
|
||||
class RenderQueue;
|
||||
|
||||
//TODO: Render: Remove obsolete RenderJobs and fix standard values on variables.
|
||||
|
||||
struct RenderJob
|
||||
{
|
||||
friend class RenderQueue;
|
||||
@@ -35,6 +38,9 @@ struct ModelJob : RenderJob
|
||||
unsigned int ShaderID = 0;
|
||||
unsigned int TextureID = 0;
|
||||
|
||||
//TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this
|
||||
EntityID Entity;
|
||||
|
||||
glm::mat4 ModelMatrix;
|
||||
const Texture* DiffuseTexture;
|
||||
const Texture* NormalTexture;
|
||||
@@ -80,30 +86,7 @@ struct PointLightJob : RenderJob
|
||||
glm::vec3 SpecularColor = glm::vec3(1, 1, 1);
|
||||
glm::vec3 DiffuseColor = glm::vec3(1, 1, 1);
|
||||
float Radius = 1.f;
|
||||
|
||||
void CalculateHash() override
|
||||
{
|
||||
Hash = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct FrameJob : SpriteJob
|
||||
{
|
||||
Rectangle Scissor;
|
||||
Rectangle Viewport;
|
||||
std::string Name;
|
||||
|
||||
void CalculateHash() override
|
||||
{
|
||||
Hash = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct WaterParticleJob : RenderJob
|
||||
{
|
||||
glm::vec3 Position;
|
||||
glm::vec4 Color;
|
||||
glm::mat4 ModelMatrix;
|
||||
float Intensity = 0.8f;
|
||||
|
||||
void CalculateHash() override
|
||||
{
|
||||
@@ -152,25 +135,19 @@ private:
|
||||
|
||||
struct RenderQueueCollection
|
||||
{
|
||||
RenderQueue Deferred;
|
||||
RenderQueue Forward;
|
||||
RenderQueue Lights;
|
||||
RenderQueue GUI;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Deferred.Clear();
|
||||
Forward.Clear();
|
||||
Lights.Clear();
|
||||
GUI.Clear();
|
||||
}
|
||||
|
||||
void Sort()
|
||||
{
|
||||
Deferred.Sort();
|
||||
Forward.Sort();
|
||||
Lights.Sort();
|
||||
GUI.Sort();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef RenderQueueFactory_h__
|
||||
#define RenderQueueFactory_h__
|
||||
|
||||
#include "../Core/World.h"
|
||||
#include "RenderQueue.h"
|
||||
#include "../Core/ResourceManager.h"
|
||||
#include "Model.h"
|
||||
#include "../GLM.h"
|
||||
|
||||
class RenderQueueFactory
|
||||
{
|
||||
public:
|
||||
RenderQueueFactory();
|
||||
void Update(World* world);
|
||||
|
||||
|
||||
RenderQueueCollection RenderQueues() const { return m_RenderQueues; }
|
||||
private:
|
||||
RenderQueueCollection m_RenderQueues;
|
||||
|
||||
void FillModels(World* world, RenderQueue* renderQueue);
|
||||
void FillLights(World* world, RenderQueue* renderQueue);
|
||||
|
||||
glm::mat4 ModelMatrix(World* world, EntityID entity);
|
||||
glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef Renderer_h__
|
||||
#define Renderer_h__
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "IRenderer.h"
|
||||
#include "ShaderProgram.h"
|
||||
//TODO: Temp resourceManager
|
||||
#include "../Core/ResourceManager.h"
|
||||
#include "Util/UnorderedMapVec2.h"
|
||||
#include "FrameBuffer.h"
|
||||
#include "../Core/World.h"
|
||||
|
||||
class Renderer : public IRenderer
|
||||
{
|
||||
public:
|
||||
virtual void Initialize() override;
|
||||
virtual void Update(double dt) override;
|
||||
virtual void Draw(RenderQueueCollection& rq) override;
|
||||
|
||||
private:
|
||||
//----------------------Variables----------------------//
|
||||
Texture* m_ErrorTexture;
|
||||
Texture* m_WhiteTexture;
|
||||
float m_CameraMoveSpeed;
|
||||
FrameBuffer m_PickingBuffer;
|
||||
GLuint m_PickingTexture;
|
||||
GLuint m_DepthBuffer;
|
||||
|
||||
Model* m_ScreenQuad;
|
||||
Model* m_UnitQuad;
|
||||
Model* m_UnitSphere;
|
||||
|
||||
|
||||
|
||||
std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity;
|
||||
|
||||
//----------------------Functions----------------------//
|
||||
void InitializeWindow();
|
||||
void InitializeShaders();
|
||||
void InitializeTextures();
|
||||
void InitializeFrameBuffers();
|
||||
//TODO: Renderer: Get InputUpdate out of renderer
|
||||
void InputUpdate(double dt);
|
||||
void PickingPass(RenderQueueCollection& rq);
|
||||
void DrawScreenQuad(GLuint textureToDraw);
|
||||
void DrawScene(RenderQueueCollection& rq);
|
||||
|
||||
|
||||
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
|
||||
//--------------------ShaderPrograms-------------------//
|
||||
ShaderProgram m_BasicForwardProgram;
|
||||
ShaderProgram m_PickingProgram;
|
||||
ShaderProgram m_DrawScreenQuadProgram;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
#include "../Common.h"
|
||||
#include "../OpenGL.h"
|
||||
#include <fstream>
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
static GLuint CompileShader(GLenum shaderType, std::string fileName);
|
||||
|
||||
Shader(GLenum shaderType, std::string fileName);
|
||||
|
||||
virtual ~Shader();
|
||||
|
||||
GLuint Compile();
|
||||
|
||||
GLenum GetType() const;
|
||||
std::string GetFileName() const;
|
||||
GLuint GetHandle() const;
|
||||
bool IsCompiled() const;
|
||||
protected:
|
||||
GLenum m_ShaderType;
|
||||
std::string m_FileName;
|
||||
GLint m_ShaderHandle;
|
||||
};
|
||||
|
||||
template <int SHADERTYPE>
|
||||
class ShaderType : public Shader
|
||||
{
|
||||
public:
|
||||
ShaderType(std::string fileName)
|
||||
: Shader(SHADERTYPE, fileName) { }
|
||||
};
|
||||
|
||||
class VertexShader : public ShaderType<GL_VERTEX_SHADER>
|
||||
{
|
||||
public:
|
||||
VertexShader(std::string fileName)
|
||||
: ShaderType(fileName) { }
|
||||
};
|
||||
|
||||
class FragmentShader : public ShaderType<GL_FRAGMENT_SHADER>
|
||||
{
|
||||
public:
|
||||
FragmentShader(std::string fileName)
|
||||
: ShaderType(fileName) { }
|
||||
};
|
||||
|
||||
class GeometryShader : public ShaderType<GL_GEOMETRY_SHADER>
|
||||
{
|
||||
public:
|
||||
GeometryShader(std::string fileName)
|
||||
: ShaderType(fileName) { }
|
||||
};
|
||||
|
||||
class ComputeShader : public ShaderType<GL_COMPUTE_SHADER>
|
||||
{
|
||||
public:
|
||||
ComputeShader(std::string fileName)
|
||||
: ShaderType(fileName) { }
|
||||
};
|
||||
|
||||
class ShaderProgram
|
||||
{
|
||||
public:
|
||||
ShaderProgram()
|
||||
: m_ShaderProgramHandle(0) { }
|
||||
~ShaderProgram();
|
||||
|
||||
void AddShader(std::shared_ptr<Shader> shader);
|
||||
void Compile();
|
||||
GLuint Link();
|
||||
GLuint GetHandle();
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void BindFragDataLocation(int index, std::string name);
|
||||
|
||||
private:
|
||||
GLuint m_ShaderProgramHandle;
|
||||
std::vector<std::shared_ptr<Shader>> m_Shaders;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef ScreenCoords_h__
|
||||
#define ScreenCoords_h__
|
||||
|
||||
#include "../../Common.h"
|
||||
#include "../../OpenGL.h"
|
||||
#include "../../GLM.h"
|
||||
#include "../../Core/Util/Rectangle.h"
|
||||
#include "../FrameBuffer.h"
|
||||
|
||||
class ScreenCoords
|
||||
{
|
||||
public:
|
||||
ScreenCoords() = delete;
|
||||
//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(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
|
||||
static glm::vec3 ToWorldPos(glm::vec2 screenCoord, 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.
|
||||
//Data is given as R = x, B = y, and
|
||||
static glm::vec3 ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
||||
static glm::vec3 ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
|
||||
//Return EntityID of the clicked coordinate in given screenspace coordinates.
|
||||
//EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef UnorderedMapVec2_h__
|
||||
#define UnorderedMapVec2_h__
|
||||
|
||||
#include <functional>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
template<>
|
||||
struct std::hash<glm::vec2>
|
||||
{
|
||||
inline std::size_t operator()(const glm::vec2 &v) const
|
||||
{
|
||||
return boost::hash<float>()(v.x) ^ boost::hash<float>()(v.y);
|
||||
}
|
||||
|
||||
inline bool operator()(const glm::vec2& a, const glm::vec2& b)const
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
+6
-4
@@ -3,12 +3,12 @@
|
||||
|
||||
#include "Core/ResourceManager.h"
|
||||
#include "Core/ConfigFile.h"
|
||||
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Rendering/DummyRenderer.h"
|
||||
#include "Rendering/Renderer.h"
|
||||
#include "Core/InputManager.h"
|
||||
|
||||
#include "GUI/Frame.h"
|
||||
#include "Core/World.h"
|
||||
#include "Rendering/RenderQueueFactory.h"
|
||||
|
||||
class Game
|
||||
{
|
||||
@@ -26,6 +26,8 @@ private:
|
||||
IRenderer* m_Renderer;
|
||||
InputManager* m_InputManager;
|
||||
GUI::Frame* m_FrameStack;
|
||||
World* m_World;
|
||||
RenderQueueFactory* m_RenderQueueFactory;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
#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,28 @@
|
||||
#version 430
|
||||
|
||||
uniform mat4 M;
|
||||
uniform mat4 V;
|
||||
uniform mat4 P;
|
||||
uniform vec4 Color;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
|
||||
|
||||
in VertexData{
|
||||
vec3 Position;
|
||||
vec3 Normal;
|
||||
vec2 TextureCoordinate;
|
||||
vec4 DiffuseColor;
|
||||
}Input;
|
||||
|
||||
|
||||
out vec4 fragmentColor;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texel = texture2D(texture0, Input.TextureCoordinate);
|
||||
fragmentColor = texel * Input.DiffuseColor * Color;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,19 @@
|
||||
#version 430
|
||||
|
||||
layout (binding = 0) uniform sampler2D Texture;
|
||||
|
||||
in VertexData{
|
||||
vec2 TextureCoordinate;
|
||||
}Input;
|
||||
|
||||
out vec4 fragmentColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texel = texture(Texture, Input.TextureCoordinate);
|
||||
|
||||
fragmentColor = texel;
|
||||
//fragmentColor = vec4(1,0.5,0.7,1);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#version 430
|
||||
|
||||
layout (location = 0) in vec3 Position;
|
||||
|
||||
out VertexData{
|
||||
vec2 TextureCoordinate;
|
||||
}Output;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(Position, 1.0);
|
||||
Output.TextureCoordinate = (vec2(Position) + 1) / 2;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#version 430
|
||||
|
||||
uniform mat4 M;
|
||||
uniform mat4 V;
|
||||
uniform mat4 P;
|
||||
uniform vec2 PickingColor;
|
||||
|
||||
in VertexData{
|
||||
vec3 Position;
|
||||
}Input;
|
||||
|
||||
out vec4 TextureFragment;
|
||||
|
||||
void main()
|
||||
{
|
||||
TextureFragment = vec4(PickingColor, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#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;
|
||||
}Output;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = P*V*M * vec4(Position, 1.0);
|
||||
|
||||
Output.Position = Position;
|
||||
}
|
||||
@@ -7,6 +7,7 @@ find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono)
|
||||
find_package(assimp REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(PNG REQUIRED)
|
||||
find_package(Xerces REQUIRED)
|
||||
# Because FindOpenAL is retarded
|
||||
#set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/deps/include/AL")
|
||||
#find_package(OpenAL REQUIRED)
|
||||
@@ -23,6 +24,7 @@ include_directories(
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${assimp_INCLUDE_DIRS}
|
||||
${PNG_INCLUDE_DIRS}
|
||||
${Xerces_INCLUDE_DIRS}
|
||||
${OPENAL_INCLUDE_DIR}
|
||||
${X11_INCLUDE_DIRS}
|
||||
)
|
||||
@@ -44,6 +46,12 @@ file(GLOB SOURCE_FILES_Input
|
||||
)
|
||||
source_group(Input FILES ${SOURCE_FILES_Input})
|
||||
|
||||
file(GLOB SOURCE_FILES_Network
|
||||
"${INCLUDE_PATH}/Network/*.h"
|
||||
"Network/*.cpp"
|
||||
)
|
||||
source_group(Network FILES ${SOURCE_FILES_Network})
|
||||
|
||||
file(GLOB SOURCE_FILES_Rendering
|
||||
"${INCLUDE_PATH}/Rendering/*.h"
|
||||
"Rendering/*.cpp"
|
||||
@@ -52,6 +60,7 @@ file(GLOB SOURCE_FILES_Rendering_Util
|
||||
"${INCLUDE_PATH}/Rendering/Util/*.h"
|
||||
"Rendering/Util/*.cpp"
|
||||
)
|
||||
|
||||
source_group(Rendering FILES ${SOURCE_FILES_Rendering})
|
||||
source_group(Rendering\\Util FILES ${SOURCE_FILES_Rendering_Util})
|
||||
|
||||
@@ -65,8 +74,10 @@ set(SOURCE_FILES
|
||||
${SOURCE_FILES_Core}
|
||||
${SOURCE_FILES_Core_Util}
|
||||
#${SOURCE_FILES_Input}
|
||||
${SOURCE_FILES_Network}
|
||||
${SOURCE_FILES_GUI}
|
||||
${SOURCE_FILES_Rendering}
|
||||
${SOURCE_FILES_Rendering_Util}
|
||||
)
|
||||
|
||||
set(LIBRARIES
|
||||
@@ -76,6 +87,7 @@ set(LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
${assimp_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
${Xerces_LIBRARIES}
|
||||
${OPENAL_LIBRARY}
|
||||
${X11_LIBRARIES}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "Core/ComponentPool.h"
|
||||
|
||||
|
||||
|
||||
ComponentWrapper ComponentPoolForwardIterator::operator*() const
|
||||
{
|
||||
char* data = &(*m_MemoryPoolIterator);
|
||||
ComponentWrapper wrapper(m_ComponentInfo, data);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
bool ComponentPoolForwardIterator::operator==(const ComponentPoolForwardIterator& other) const
|
||||
{
|
||||
return m_MemoryPoolIterator == other.m_MemoryPoolIterator;
|
||||
}
|
||||
|
||||
bool ComponentPoolForwardIterator::operator!=(const ComponentPoolForwardIterator& other) const
|
||||
{
|
||||
return m_MemoryPoolIterator != other.m_MemoryPoolIterator;
|
||||
}
|
||||
|
||||
ComponentPoolForwardIterator& ComponentPoolForwardIterator::operator++(int)
|
||||
{
|
||||
ComponentPoolForwardIterator copyIter(*this);
|
||||
operator++();
|
||||
return copyIter;
|
||||
}
|
||||
|
||||
ComponentPoolForwardIterator& ComponentPoolForwardIterator::operator++()
|
||||
{
|
||||
++m_MemoryPoolIterator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//const ::ComponentInfo& ComponentPool::ComponentInfo() const
|
||||
//{
|
||||
// return m_ComponentInfo;
|
||||
//}
|
||||
|
||||
ComponentWrapper ComponentPool::Allocate(EntityID entity)
|
||||
{
|
||||
char* data = m_Pool.Allocate();
|
||||
memcpy(data, &entity, sizeof(EntityID));
|
||||
m_EntityToComponent[entity] = data;
|
||||
return ComponentWrapper(m_ComponentInfo, data);
|
||||
}
|
||||
|
||||
ComponentWrapper ComponentPool::GetByEntity(EntityID ent)
|
||||
{
|
||||
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent));
|
||||
}
|
||||
|
||||
void ComponentPool::Delete(ComponentWrapper& wrapper)
|
||||
{
|
||||
m_EntityToComponent.erase(wrapper.EntityID);
|
||||
m_Pool.Free(wrapper.Data);
|
||||
}
|
||||
|
||||
ComponentPool::iterator ComponentPool::begin() const
|
||||
{
|
||||
return iterator(m_ComponentInfo, m_Pool.begin(), m_Pool.end());
|
||||
}
|
||||
|
||||
ComponentPool::iterator ComponentPool::end() const
|
||||
{
|
||||
return iterator(m_ComponentInfo, m_Pool.end(), m_Pool.end());
|
||||
}
|
||||
|
||||
template <typename InterpretType /*= char*/>
|
||||
void ComponentPool::Dump() const
|
||||
{
|
||||
m_Pool.Dump<InterpretType>();
|
||||
}
|
||||
|
||||
template <typename InterpretType /*= char*/, typename OutStream>
|
||||
void ComponentPool::Dump(OutStream& out) const
|
||||
{
|
||||
m_Pool.Dump<InterpretType>(out);
|
||||
}
|
||||
@@ -168,6 +168,7 @@ void OctTree::AddBox(const AABB& box)
|
||||
}
|
||||
|
||||
//remove the content (boxes) in the tree, but dont rememove the tree-structure
|
||||
//TODO: Only clear dynamic boxes, AddDynamic, AddStatic
|
||||
void OctTree::ClearBoxes()
|
||||
{
|
||||
if (hasChildren()) {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "Core/World.h"
|
||||
|
||||
World::~World()
|
||||
{
|
||||
for (auto& pool : m_ComponentPools) {
|
||||
delete pool.second;
|
||||
}
|
||||
}
|
||||
|
||||
EntityID World::CreateEntity(EntityID parent /*= 0*/)
|
||||
{
|
||||
EntityID newEntity = generateEntityID();
|
||||
m_EntityParents[newEntity] = parent;
|
||||
if (parent != 0) {
|
||||
m_EntityChildren.insert(std::make_pair(parent, newEntity));
|
||||
}
|
||||
return newEntity;
|
||||
}
|
||||
|
||||
void World::RegisterComponent(ComponentInfo& ci)
|
||||
{
|
||||
m_ComponentPools[ci.Name] = new ComponentPool(ci);
|
||||
}
|
||||
|
||||
ComponentWrapper World::AttachComponent(EntityID entity, std::string componentType)
|
||||
{
|
||||
ComponentPool* pool = m_ComponentPools.at(componentType);
|
||||
const ComponentInfo& ci = pool->ComponentInfo();
|
||||
|
||||
// Allocate space for the component
|
||||
ComponentWrapper c = pool->Allocate(entity);
|
||||
// Write default values
|
||||
memcpy(c.Data, ci.Defaults.get(), ci.Meta.Stride);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
ComponentWrapper World::GetComponent(EntityID entity, std::string componentType)
|
||||
{
|
||||
ComponentPool* pool = m_ComponentPools.at(componentType);
|
||||
return pool->GetByEntity(entity);
|
||||
}
|
||||
|
||||
const ComponentPool& World::GetComponents(std::string componentType)
|
||||
{
|
||||
return *m_ComponentPools.at(componentType);
|
||||
}
|
||||
|
||||
EntityID World::generateEntityID()
|
||||
{
|
||||
// TODO: Make EntityID generation smarter
|
||||
return m_CurrentEntityID++;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "Network\Client.h"
|
||||
|
||||
Client::Client()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "Network\Server.h"
|
||||
|
||||
Server::Server()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -17,6 +17,12 @@ glm::vec3 Camera::Forward()
|
||||
{
|
||||
return m_Orientation * glm::vec3(0, 0, -1);
|
||||
}
|
||||
|
||||
glm::vec3 Camera::Right()
|
||||
{
|
||||
return m_Orientation * glm::vec3(1, 0, 0);
|
||||
}
|
||||
|
||||
//
|
||||
//glm::vec3 Camera::Right()
|
||||
//{
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
#include "Rendering/FrameBuffer.h"
|
||||
|
||||
|
||||
BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment)
|
||||
{
|
||||
m_ResourceHandle = resourceHandle;
|
||||
m_ResourceType = resourceType;
|
||||
m_Attachment = attachment;
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
if (m_ResourceHandle != 0) {
|
||||
glDeleteTextures(1, m_ResourceHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RenderBuffer::~RenderBuffer()
|
||||
{
|
||||
if (m_ResourceHandle != 0) {
|
||||
glDeleteRenderbuffers(1, m_ResourceHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
if (m_BufferHandle != 0) {
|
||||
glDeleteFramebuffers(1, &m_BufferHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBuffer::AddResource(std::shared_ptr<BufferResource> resource)
|
||||
{
|
||||
m_Resources.push_back(resource);
|
||||
}
|
||||
|
||||
void FrameBuffer::Generate()
|
||||
{
|
||||
std::vector<GLenum> attachments;
|
||||
|
||||
glGenFramebuffers(1, &m_BufferHandle);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle);
|
||||
|
||||
for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) {
|
||||
switch ((*it)->m_ResourceType) {
|
||||
case GL_TEXTURE_2D:
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0);
|
||||
break;
|
||||
case GL_RENDERBUFFER:
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle);
|
||||
break;
|
||||
}
|
||||
|
||||
GLERROR("FrameBuffer generate");
|
||||
|
||||
if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) {
|
||||
attachments.push_back((*it)->m_Attachment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLenum* bufferTextures = &attachments[0];
|
||||
glDrawBuffers(1, bufferTextures);
|
||||
|
||||
if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBuffer::Bind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle);
|
||||
}
|
||||
|
||||
void FrameBuffer::Unbind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
GLuint FrameBuffer::GetHandle()
|
||||
{
|
||||
return m_BufferHandle;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "Rendering/RenderQueueFactory.h"
|
||||
|
||||
|
||||
RenderQueueFactory::RenderQueueFactory()
|
||||
{
|
||||
m_RenderQueues = RenderQueueCollection();
|
||||
}
|
||||
|
||||
void RenderQueueFactory::Update(World* world)
|
||||
{
|
||||
m_RenderQueues.Clear();
|
||||
FillModels(world, &m_RenderQueues.Forward);
|
||||
FillLights(world, &m_RenderQueues.Lights);
|
||||
}
|
||||
|
||||
glm::mat4 RenderQueueFactory::ModelMatrix(World* world, EntityID entity)
|
||||
{
|
||||
//should really return absolute model matrix based on parents position, scale and orientation
|
||||
//GetAbsolutePosition(World* world, ComponentWrapper transformComponent)
|
||||
|
||||
ComponentWrapper transformComponent = world->GetComponent(entity, "Transform");
|
||||
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;
|
||||
}
|
||||
|
||||
glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent)
|
||||
{
|
||||
// positionComponent.EntityID
|
||||
return glm::vec3();
|
||||
}
|
||||
|
||||
void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
|
||||
{
|
||||
for(auto& modelC : world->GetComponents("Model")) {
|
||||
ModelJob job;
|
||||
std::string resource = modelC["Resource"];
|
||||
glm::vec4 color = modelC["Color"];
|
||||
Model* model = ResourceManager::Load<Model>(resource);
|
||||
|
||||
for (auto texGroup : model->TextureGroups) {
|
||||
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;
|
||||
|
||||
//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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
#include "Rendering/Renderer.h"
|
||||
|
||||
void Renderer::Initialize()
|
||||
{
|
||||
InitializeWindow();
|
||||
|
||||
// Create default camera
|
||||
m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(45.f), 0.01f, 5000.f);
|
||||
m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10));
|
||||
if (m_Camera == nullptr) {
|
||||
m_Camera = m_DefaultCamera;
|
||||
}
|
||||
|
||||
glfwSwapInterval(m_VSYNC);
|
||||
InitializeShaders();
|
||||
InitializeTextures();
|
||||
InitializeFrameBuffers();
|
||||
|
||||
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
|
||||
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");
|
||||
}
|
||||
|
||||
void Renderer::InitializeWindow()
|
||||
{
|
||||
// Initialize GLFW
|
||||
if (!glfwInit()) {
|
||||
LOG_ERROR("GLFW: Initialization failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Create a window
|
||||
GLFWmonitor* monitor = nullptr;
|
||||
if (m_Fullscreen) {
|
||||
monitor = glfwGetPrimaryMonitor();
|
||||
}
|
||||
//glfwWindowHint(GLFW_SAMPLES, 8);
|
||||
m_Window = glfwCreateWindow(m_Resolution.Width, m_Resolution.Height, "daydream", monitor, nullptr);
|
||||
if (!m_Window) {
|
||||
LOG_ERROR("GLFW: Failed to create window");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
glfwMakeContextCurrent(m_Window);
|
||||
|
||||
// GL version info
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &m_GLVersion[0]);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &m_GLVersion[1]);
|
||||
m_GLVendor = (GLchar*)glGetString(GL_VENDOR);
|
||||
std::stringstream ss;
|
||||
ss << m_GLVendor << " OpenGL " << m_GLVersion[0] << "." << m_GLVersion[1];
|
||||
#ifdef DEBUG
|
||||
ss << " DEBUG";
|
||||
#endif
|
||||
LOG_INFO(ss.str().c_str());
|
||||
glfwSetWindowTitle(m_Window, ss.str().c_str());
|
||||
|
||||
// Initialize GLEW
|
||||
if (glewInit() != GLEW_OK) {
|
||||
LOG_ERROR("GLEW: Initialization failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::InitializeShaders()
|
||||
{
|
||||
m_BasicForwardProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/BasicForward.vert.glsl")));
|
||||
m_BasicForwardProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/BasicForward.frag.glsl")));
|
||||
m_BasicForwardProgram.Compile();
|
||||
m_BasicForwardProgram.Link();
|
||||
|
||||
m_PickingProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Picking.vert.glsl")));
|
||||
m_PickingProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Picking.frag.glsl")));
|
||||
m_PickingProgram.Compile();
|
||||
m_PickingProgram.BindFragDataLocation(0, "TextureFragment");
|
||||
m_PickingProgram.Link();
|
||||
|
||||
m_DrawScreenQuadProgram.AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/DrawScreenQuad.vert.glsl")));
|
||||
m_DrawScreenQuadProgram.AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl")));
|
||||
m_DrawScreenQuadProgram.Compile();
|
||||
m_DrawScreenQuadProgram.Link();
|
||||
|
||||
}
|
||||
|
||||
void Renderer::InputUpdate(double dt)
|
||||
{
|
||||
glm::vec3 m_Position = m_Camera->Position();
|
||||
if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS)
|
||||
{
|
||||
m_Position = glm::vec3(0.f, 0.f, 5.f);
|
||||
}
|
||||
if (glfwGetKey(m_Window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
{
|
||||
m_Position += m_Camera->Forward() * m_CameraMoveSpeed * (float)dt;
|
||||
}
|
||||
if (glfwGetKey(m_Window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
{
|
||||
m_Position -= m_Camera->Forward() * m_CameraMoveSpeed * (float)dt;
|
||||
}
|
||||
if (glfwGetKey(m_Window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
{
|
||||
m_Position += m_Camera->Right() * m_CameraMoveSpeed * (float)dt;
|
||||
}
|
||||
if (glfwGetKey(m_Window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
{
|
||||
m_Position -= m_Camera->Right() * m_CameraMoveSpeed * (float)dt;
|
||||
}
|
||||
if (glfwGetKey(m_Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||
{
|
||||
m_CameraMoveSpeed = 5.f;
|
||||
}
|
||||
else {
|
||||
m_CameraMoveSpeed = 0.5f;
|
||||
}
|
||||
|
||||
|
||||
static double 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) {
|
||||
|
||||
|
||||
double deltaX, deltaY;
|
||||
deltaX = mousePosX - (float)Resolution().Width / 2;
|
||||
deltaY = mousePosY - (float)Resolution().Height / 2;
|
||||
|
||||
float rotationY = -deltaY / 300.f;
|
||||
float rotationX = -deltaX / 300.f;
|
||||
glm::quat orientation = m_Camera->Orientation();
|
||||
|
||||
|
||||
orientation = orientation * glm::angleAxis<float>(rotationY, glm::vec3(1, 0, 0));
|
||||
orientation = glm::angleAxis<float>(rotationX, glm::vec3(0, 1, 0)) * orientation;
|
||||
|
||||
m_Camera->SetOrientation(orientation);
|
||||
|
||||
glfwSetCursorPos(m_Window, Resolution().Width / 2, Resolution().Height / 2);
|
||||
}
|
||||
m_Camera->SetPosition(m_Position);
|
||||
}
|
||||
|
||||
void Renderer::Update(double dt)
|
||||
{
|
||||
InputUpdate(dt);
|
||||
|
||||
}
|
||||
|
||||
void Renderer::Draw(RenderQueueCollection& rq)
|
||||
{
|
||||
//TODO: Renderer: Kanske borde vara längst upp i update.
|
||||
PickingPass(rq);
|
||||
DrawScreenQuad(m_PickingTexture);
|
||||
|
||||
DrawScene(rq);
|
||||
glfwSwapBuffers(m_Window);
|
||||
}
|
||||
|
||||
void Renderer::DrawScene(RenderQueueCollection& rq)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
//TODO: Render: Clean up draw code
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
//TODO: Render: Add code for more jobs than modeljobs.
|
||||
for (auto &job : rq.Forward) {
|
||||
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||
if (modelJob) {
|
||||
GLuint ShaderHandle = m_BasicForwardProgram.GetHandle();
|
||||
|
||||
m_BasicForwardProgram.Bind();
|
||||
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
|
||||
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix()));
|
||||
glUniform4fv(glGetUniformLocation(ShaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
|
||||
|
||||
//TODO: Renderer: bättre textur felhantering samt fler texturer stöd
|
||||
if (modelJob->DiffuseTexture != nullptr) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture);
|
||||
} else {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
|
||||
}
|
||||
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
#include "Rendering/ShaderProgram.h"
|
||||
|
||||
GLuint Shader::CompileShader(GLenum shaderType, std::string fileName)
|
||||
{
|
||||
LOG_INFO("Compiling shader \"%s\"", fileName.c_str());
|
||||
|
||||
std::string shaderFile;
|
||||
std::ifstream in(fileName, std::ios::in);
|
||||
if (!in) {
|
||||
LOG_ERROR("Error: Failed to open shader file \"%s\"", fileName.c_str());
|
||||
return 0;
|
||||
}
|
||||
in.seekg(0, std::ios::end);
|
||||
shaderFile.resize((int)in.tellg());
|
||||
in.seekg(0, std::ios::beg);
|
||||
in.read(&shaderFile[0], shaderFile.size());
|
||||
in.close();
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
if (GLERROR("glCreateShader"))
|
||||
return 0;
|
||||
|
||||
const GLchar* shaderFiles = shaderFile.c_str();
|
||||
const GLint length = shaderFile.length();
|
||||
glShaderSource(shader, 1, &shaderFiles, &length);
|
||||
if (GLERROR("glShaderSource"))
|
||||
return 0;
|
||||
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint compileStatus;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
|
||||
if (compileStatus != GL_TRUE) {
|
||||
LOG_ERROR("Shader compilation failed");
|
||||
GLsizei infoLogLength;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
GLchar* infolog = new GLchar[infoLogLength];
|
||||
glGetShaderInfoLog(shader, infoLogLength, &infoLogLength, infolog);
|
||||
LOG_ERROR(infolog);
|
||||
delete[] infolog;
|
||||
}
|
||||
|
||||
if (GLERROR("glCompileShader"))
|
||||
return 0;
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
Shader::Shader(GLenum shaderType, std::string fileName) : m_ShaderType(shaderType), m_FileName(fileName)
|
||||
{
|
||||
m_ShaderHandle = 0;
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
if (m_ShaderHandle != 0) {
|
||||
glDeleteShader(m_ShaderHandle);
|
||||
}
|
||||
}
|
||||
|
||||
GLuint Shader::Compile()
|
||||
{
|
||||
m_ShaderHandle = CompileShader(m_ShaderType, m_FileName);
|
||||
return m_ShaderHandle;
|
||||
}
|
||||
|
||||
GLenum Shader::GetType() const
|
||||
{
|
||||
return m_ShaderType;
|
||||
}
|
||||
|
||||
std::string Shader::GetFileName() const
|
||||
{
|
||||
return m_FileName;
|
||||
}
|
||||
|
||||
GLuint Shader::GetHandle() const
|
||||
{
|
||||
return m_ShaderHandle;
|
||||
}
|
||||
|
||||
bool Shader::IsCompiled() const
|
||||
{
|
||||
return m_ShaderHandle != 0;
|
||||
}
|
||||
|
||||
ShaderProgram::~ShaderProgram()
|
||||
{
|
||||
if (m_ShaderProgramHandle != 0) {
|
||||
glDeleteProgram(m_ShaderProgramHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgram::AddShader(std::shared_ptr<Shader> shader)
|
||||
{
|
||||
m_Shaders.push_back(shader);
|
||||
}
|
||||
|
||||
void ShaderProgram::Compile()
|
||||
{
|
||||
if (m_ShaderProgramHandle == 0)
|
||||
{
|
||||
m_ShaderProgramHandle = glCreateProgram();
|
||||
}
|
||||
|
||||
for (auto &shader : m_Shaders)
|
||||
{
|
||||
if (!shader->IsCompiled())
|
||||
{
|
||||
shader->Compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLuint ShaderProgram::Link()
|
||||
{
|
||||
if (m_Shaders.size() == 0)
|
||||
{
|
||||
LOG_ERROR("Failed to link shader program: No shaders bound");
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_INFO("Linking shader program");
|
||||
|
||||
for (auto &shader : m_Shaders)
|
||||
{
|
||||
glAttachShader(m_ShaderProgramHandle, shader->GetHandle());
|
||||
}
|
||||
glLinkProgram(m_ShaderProgramHandle);
|
||||
if (GLERROR("glLinkProgram"))
|
||||
return 0;
|
||||
m_Shaders.clear();
|
||||
|
||||
return m_ShaderProgramHandle;
|
||||
}
|
||||
|
||||
GLuint ShaderProgram::GetHandle()
|
||||
{
|
||||
return m_ShaderProgramHandle;
|
||||
}
|
||||
|
||||
void ShaderProgram::Bind()
|
||||
{
|
||||
if (m_ShaderProgramHandle == 0)
|
||||
return;
|
||||
|
||||
glUseProgram(m_ShaderProgramHandle);
|
||||
}
|
||||
|
||||
void ShaderProgram::Unbind()
|
||||
{
|
||||
glActiveShaderProgram(0, 0);
|
||||
}
|
||||
|
||||
void ShaderProgram::BindFragDataLocation(int index, std::string name)
|
||||
{
|
||||
|
||||
if (m_ShaderProgramHandle == 0)
|
||||
return;
|
||||
|
||||
glBindFragDataLocation(m_ShaderProgramHandle, index, name.c_str());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "Rendering/Util/ScreenCoords.h"
|
||||
|
||||
glm::vec3 ScreenCoords::ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat)
|
||||
{
|
||||
glm::vec3 ndc;
|
||||
ndc.x = (x / screenWidth)*2.f - 1.f;
|
||||
ndc.y = (y / screenHeight)*2.f - 1.f;
|
||||
ndc.z = depth*2.f - 1.f;
|
||||
glm::vec4 clipSpace = glm::vec4(ndc, 1.0f);
|
||||
glm::vec4 EyeSpace = glm::inverse(cameraProjectionMat) * clipSpace;
|
||||
glm::vec4 WorldSpace = glm::inverse(cameraViewMat) * EyeSpace;
|
||||
WorldSpace = glm::vec4(glm::vec3(WorldSpace) / WorldSpace.w, 1.f);
|
||||
|
||||
return glm::vec3(WorldSpace);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat)
|
||||
{
|
||||
return ToWorldPos(screenCoord.x, screenCoord.y, depth, resolution.Width, resolution.Height, cameraProjectionMat, cameraViewMat);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenCoords::ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat)
|
||||
{
|
||||
return ToWorldPos(x, y, depth, resolution.Width, resolution.Height, cameraProjectionMat, cameraViewMat);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat)
|
||||
{
|
||||
return ToWorldPos(screenCoord.x, screenCoord.y, depth, screenWidth, screenHeight, cameraProjectionMat, cameraViewMat);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
||||
{
|
||||
PickDataBuffer->Bind();
|
||||
glm::vec2 pixelData;
|
||||
glReadPixels(x, y, 1, 1, GL_RG, GL_FLOAT, &pixelData);
|
||||
PickDataBuffer->Unbind();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer);
|
||||
float depthData;
|
||||
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
return glm::vec3(pixelData, depthData);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenCoords::ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer)
|
||||
{
|
||||
return ToPixelData(screenCoord.x, screenCoord.y, PickDataBuffer, DepthBuffer);
|
||||
}
|
||||
+13
-3
@@ -1,8 +1,11 @@
|
||||
#include "Game.h"
|
||||
#include "HardcodedTestWorld.h"
|
||||
|
||||
Game::Game(int argc, char* argv[])
|
||||
{
|
||||
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
|
||||
ResourceManager::RegisterType<Model>("Model");
|
||||
ResourceManager::RegisterType<Texture>("Texture");
|
||||
|
||||
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
|
||||
@@ -10,8 +13,10 @@ Game::Game(int argc, char* argv[])
|
||||
// Create the core event broker
|
||||
m_EventBroker = new EventBroker();
|
||||
|
||||
m_RenderQueueFactory = new RenderQueueFactory();
|
||||
|
||||
// Create the renderer
|
||||
m_Renderer = new DummyRenderer();
|
||||
m_Renderer = new Renderer();
|
||||
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
|
||||
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
|
||||
m_Renderer->SetResolution(Rectangle(
|
||||
@@ -30,6 +35,9 @@ Game::Game(int argc, char* argv[])
|
||||
m_FrameStack->Width = m_Renderer->Resolution().Width;
|
||||
m_FrameStack->Height = m_Renderer->Resolution().Height;
|
||||
|
||||
// Create a TEST WORLD
|
||||
m_World = new HardcodedTestWorld();
|
||||
|
||||
m_LastTime = glfwGetTime();
|
||||
}
|
||||
|
||||
@@ -47,10 +55,12 @@ void Game::Tick()
|
||||
|
||||
m_EventBroker->Swap();
|
||||
m_InputManager->Update(dt);
|
||||
m_Renderer->Update(dt);
|
||||
m_EventBroker->Swap();
|
||||
|
||||
RenderQueueCollection rq;
|
||||
m_Renderer->Draw(rq);
|
||||
m_RenderQueueFactory->Update(m_World);
|
||||
|
||||
m_Renderer->Draw(m_RenderQueueFactory->RenderQueues());
|
||||
|
||||
m_EventBroker->Swap();
|
||||
m_EventBroker->Clear();
|
||||
|
||||
@@ -92,11 +92,12 @@ BOOST_AUTO_TEST_CASE(octTest)
|
||||
glm::vec3 mini = glm::vec3(-1, -1, -1);
|
||||
glm::vec3 maxi = glm::vec3(1, 1, 1);
|
||||
OctTree tree(AABB(mini, maxi), 2);
|
||||
tree.AddBox(AABB(mini, 0.1f*maxi));
|
||||
tree.AddBox(AABB(mini, -0.9f*maxi));
|
||||
OctTree::Output data;
|
||||
BOOST_CHECK(tree.RayCollides({ glm::vec3(0, 0, 0), glm::normalize(mini) }, data));
|
||||
glm::vec3 origin = 3.0f * mini;
|
||||
BOOST_CHECK(tree.RayCollides({origin , glm::normalize(mini - origin) }, data));
|
||||
tree.ClearBoxes();
|
||||
BOOST_CHECK(!tree.RayCollides({ glm::vec3(0, 0, 0), glm::normalize(mini) }, data));
|
||||
BOOST_CHECK(!tree.RayCollides({ origin , glm::normalize(mini - origin) }, data));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "Core/ComponentPool.h"
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ComponentPoolTest)
|
||||
{
|
||||
// TODO: Write an updated test for component pool
|
||||
BOOST_CHECK(false);
|
||||
//ComponentInfo ci;
|
||||
//ci.Name = "Test";
|
||||
//ci.FieldTypes["Field"] = "int";
|
||||
//ci.FieldOffsets["Field"] = 0;
|
||||
//ci.Meta.Allocation = 3;
|
||||
//ci.Meta.Stride = sizeof(EntityID) + sizeof(int);
|
||||
|
||||
//std::vector<ComponentWrapper> wrappers;
|
||||
//ComponentPool pool(ci);
|
||||
//for (int i = 0; i < 4; i++) {
|
||||
// ComponentWrapper c = pool.New();
|
||||
// c.EntityID = i;
|
||||
// unsigned int offset = c.Info.FieldOffsets.at("Field");
|
||||
// memcpy(&c.Data[offset], &i, sizeof(int));
|
||||
// wrappers.push_back(c);
|
||||
//}
|
||||
|
||||
//int i = 0;
|
||||
//for (auto& c : pool) {
|
||||
// BOOST_CHECK(c.EntityID == i);
|
||||
// BOOST_CHECK((int)c["Field"] == i);
|
||||
// i++;
|
||||
//}
|
||||
|
||||
//pool.Delete(wrappers[1]);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
namespace utf = boost::unit_test;
|
||||
|
||||
#include "Common.h"
|
||||
#include "GLM.h"
|
||||
#include "Core/World.h"
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WorldTestSingleAllocation, * boost::unit_test::tolerance(0.001))
|
||||
{
|
||||
World w;
|
||||
|
||||
auto f = ComponentWrapperFactory("Test");
|
||||
f.AddProperty("TestInteger", 1337);
|
||||
f.AddProperty("TestDouble", 13.37);
|
||||
f.AddProperty("TestString", std::string("Carlito"));
|
||||
f.AddProperty("TestVec3", glm::vec3(1.f, 2.f, 3.f));
|
||||
w.RegisterComponent(f);
|
||||
|
||||
EntityID e = w.CreateEntity();
|
||||
ComponentWrapper c = w.AttachComponent(e, "Test");
|
||||
|
||||
// Check default values
|
||||
BOOST_TEST((int)c["TestInteger"] == c.Property<int>("TestInteger"));
|
||||
BOOST_TEST((int)c["TestInteger"] == 1337);
|
||||
BOOST_TEST((double)c["TestDouble"] == 13.37);
|
||||
BOOST_TEST((std::string)c["TestString"] == "Carlito");
|
||||
glm::vec3 vec3 = c["TestVec3"];
|
||||
BOOST_TEST(vec3.x == 1.f);
|
||||
BOOST_TEST(vec3.y == 2.f);
|
||||
BOOST_TEST(vec3.z == 3.f);
|
||||
|
||||
// Change values
|
||||
((int&)c["TestInteger"]) += 1;
|
||||
BOOST_TEST((int)c["TestInteger"] == 1338);
|
||||
((double&)c["TestDouble"]) += 1.11;
|
||||
std::cout << (double)c["TestDouble"] << std::endl;
|
||||
BOOST_TEST((double)c["TestDouble"] == 14.48);
|
||||
c["TestString"] = "Siesta";
|
||||
BOOST_TEST((std::string)c["TestString"] == "Siesta");
|
||||
((glm::vec3&)c["TestVec3"]).y += 1.f;
|
||||
BOOST_TEST(((glm::vec3)c["TestVec3"]).y == 3.f);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WorldTestMultipleAllocations, * utf::tolerance(0.00001))
|
||||
{
|
||||
World w;
|
||||
|
||||
// Create allocation for 3 entities
|
||||
auto f = ComponentWrapperFactory("Test", 3);
|
||||
f.AddProperty("TestInteger", 1337);
|
||||
f.AddProperty("TestDouble", 13.37);
|
||||
f.AddProperty("TestString", std::string("Carlito"));
|
||||
f.AddProperty("TestVec3", glm::vec3(1.f, 2.f, 3.f));
|
||||
w.RegisterComponent(f);
|
||||
|
||||
// Create 6 entities with Test components
|
||||
// 3 will reside in contiguous memory
|
||||
// 3 will be allocated dynamically
|
||||
for (int i = 0; i < 6; i++) {
|
||||
EntityID e = w.CreateEntity();
|
||||
ComponentWrapper c = w.AttachComponent(e, "Test");
|
||||
c["TestInteger"] = i;
|
||||
}
|
||||
|
||||
// Loop through them and check data
|
||||
int i = 0;
|
||||
for (auto& c : w.GetComponents("Test")) {
|
||||
BOOST_TEST((int)c["TestInteger"] == i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MayaExporter", "MayaExporter\MayaExporter.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM = Release|ARM
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|ARM.ActiveCfg = Debug|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|ARM.ActiveCfg = Release|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
** Meta object code from reading C++ file 'Menu.h'
|
||||
**
|
||||
** Created by: The Qt Meta Object Compiler version 63 (Qt 4.8.6)
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../../Menu.h"
|
||||
#if !defined(Q_MOC_OUTPUT_REVISION)
|
||||
#error "The header file 'Menu.h' doesn't include <QObject>."
|
||||
#elif Q_MOC_OUTPUT_REVISION != 63
|
||||
#error "This file was generated using the moc from 4.8.6. It"
|
||||
#error "cannot be used with the include files from this version of Qt."
|
||||
#error "(The moc has changed too much.)"
|
||||
#endif
|
||||
|
||||
QT_BEGIN_MOC_NAMESPACE
|
||||
static const uint qt_meta_data_Menu[] = {
|
||||
|
||||
// content:
|
||||
6, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
7, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
0, // flags
|
||||
0, // signalCount
|
||||
|
||||
// slots: signature, parameters, type, tag, flags
|
||||
14, 6, 5, 5, 0x08,
|
||||
35, 5, 5, 5, 0x08,
|
||||
59, 5, 5, 5, 0x08,
|
||||
75, 5, 5, 5, 0x08,
|
||||
95, 5, 5, 5, 0x08,
|
||||
116, 5, 5, 5, 0x08,
|
||||
137, 5, 5, 5, 0x08,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
static const char qt_meta_stringdata_Menu[] = {
|
||||
"Menu\0\0checked\0ExportSelected(bool)\0"
|
||||
"ExportPathClicked(bool)\0ExportAll(bool)\0"
|
||||
"CancelClicked(bool)\0Button1Clicked(bool)\0"
|
||||
"Button2Clicked(bool)\0Button3Clicked(bool)\0"
|
||||
};
|
||||
|
||||
void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
Q_ASSERT(staticMetaObject.cast(_o));
|
||||
Menu *_t = static_cast<Menu *>(_o);
|
||||
switch (_id) {
|
||||
case 0: _t->ExportSelected((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
case 1: _t->ExportPathClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
case 2: _t->ExportAll((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
case 3: _t->CancelClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
case 4: _t->Button1Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
case 5: _t->Button2Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
case 6: _t->Button3Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QMetaObjectExtraData Menu::staticMetaObjectExtraData = {
|
||||
0, qt_static_metacall
|
||||
};
|
||||
|
||||
const QMetaObject Menu::staticMetaObject = {
|
||||
{ &QWidget::staticMetaObject, qt_meta_stringdata_Menu,
|
||||
qt_meta_data_Menu, &staticMetaObjectExtraData }
|
||||
};
|
||||
|
||||
#ifdef Q_NO_DATA_RELOCATION
|
||||
const QMetaObject &Menu::getStaticMetaObject() { return staticMetaObject; }
|
||||
#endif //Q_NO_DATA_RELOCATION
|
||||
|
||||
const QMetaObject *Menu::metaObject() const
|
||||
{
|
||||
return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
|
||||
}
|
||||
|
||||
void *Menu::qt_metacast(const char *_clname)
|
||||
{
|
||||
if (!_clname) return 0;
|
||||
if (!strcmp(_clname, qt_meta_stringdata_Menu))
|
||||
return static_cast<void*>(const_cast< Menu*>(this));
|
||||
return QWidget::qt_metacast(_clname);
|
||||
}
|
||||
|
||||
int Menu::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
_id = QWidget::qt_metacall(_c, _id, _a);
|
||||
if (_id < 0)
|
||||
return _id;
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
if (_id < 7)
|
||||
qt_static_metacall(this, _c, _id, _a);
|
||||
_id -= 7;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
QT_END_MOC_NAMESPACE
|
||||
@@ -0,0 +1,29 @@
|
||||
/****************************************************************************
|
||||
** Resource object code
|
||||
**
|
||||
** Created by: The Resource Compiler for Qt version 4.8.6
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
*****************************************************************************/
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
int QT_MANGLE_NAMESPACE(qInitResources_leeeeel)()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_leeeeel))
|
||||
|
||||
int QT_MANGLE_NAMESPACE(qCleanupResources_leeeeel)()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_leeeeel))
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/********************************************************************************
|
||||
** Form generated from reading UI file 'MayaExporter.ui'
|
||||
**
|
||||
** Created by: Qt User Interface Compiler version 4.8.6
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef UI_MAYAEXPORTER_H
|
||||
#define UI_MAYAEXPORTER_H
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QButtonGroup>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QMenuBar>
|
||||
#include <QtGui/QStatusBar>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Ui_leeeeelClass
|
||||
{
|
||||
public:
|
||||
QMenuBar *menuBar;
|
||||
QToolBar *mainToolBar;
|
||||
QWidget *centralWidget;
|
||||
QStatusBar *statusBar;
|
||||
|
||||
void setupUi(QMainWindow *leeeeelClass)
|
||||
{
|
||||
if (leeeeelClass->objectName().isEmpty())
|
||||
leeeeelClass->setObjectName(QString::fromUtf8("leeeeelClass"));
|
||||
leeeeelClass->resize(600, 400);
|
||||
menuBar = new QMenuBar(leeeeelClass);
|
||||
menuBar->setObjectName(QString::fromUtf8("menuBar"));
|
||||
leeeeelClass->setMenuBar(menuBar);
|
||||
mainToolBar = new QToolBar(leeeeelClass);
|
||||
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
|
||||
leeeeelClass->addToolBar(mainToolBar);
|
||||
centralWidget = new QWidget(leeeeelClass);
|
||||
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
|
||||
leeeeelClass->setCentralWidget(centralWidget);
|
||||
statusBar = new QStatusBar(leeeeelClass);
|
||||
statusBar->setObjectName(QString::fromUtf8("statusBar"));
|
||||
leeeeelClass->setStatusBar(statusBar);
|
||||
|
||||
retranslateUi(leeeeelClass);
|
||||
|
||||
QMetaObject::connectSlotsByName(leeeeelClass);
|
||||
} // setupUi
|
||||
|
||||
void retranslateUi(QMainWindow *leeeeelClass)
|
||||
{
|
||||
leeeeelClass->setWindowTitle(QApplication::translate("leeeeelClass", "leeeeel", 0, QApplication::UnicodeUTF8));
|
||||
} // retranslateUi
|
||||
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
class leeeeelClass: public Ui_leeeeelClass {};
|
||||
} // namespace Ui
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // UI_MAYAEXPORTER_H
|
||||
@@ -0,0 +1,42 @@
|
||||
#include "MayaIncludes.h"
|
||||
#include "Menu.h"
|
||||
#include <iostream>
|
||||
#include <maya/MFnPlugin.h>
|
||||
using namespace std;
|
||||
QDialog* dialog;
|
||||
Menu* menu;
|
||||
|
||||
// called when the plugin is loaded
|
||||
EXPORT MStatus initializePlugin(MObject obj)
|
||||
{
|
||||
MStatus res = MS::kSuccess;
|
||||
|
||||
MFnPlugin myPlugin(obj, "Maya plugin", "1.0", "Any", &res);
|
||||
if (MFAIL(res))
|
||||
{
|
||||
CHECK_MSTATUS(res);
|
||||
}
|
||||
|
||||
MGlobal::displayInfo("Maya plugin loaded!");
|
||||
|
||||
dialog = new QDialog();
|
||||
dialog->setWindowTitle("Custom Exporter");
|
||||
|
||||
menu = new Menu(dialog);
|
||||
|
||||
dialog->resize(300, 200);
|
||||
dialog->show();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
EXPORT MStatus uninitializePlugin(MObject obj)
|
||||
{
|
||||
MFnPlugin plugin(obj);
|
||||
|
||||
MGlobal::displayInfo("Maya plugin unloaded!");
|
||||
|
||||
delete dialog;
|
||||
delete menu;
|
||||
return MS::kSuccess;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<UI version="4.0" >
|
||||
<class>leeeeelClass</class>
|
||||
<widget class="QMainWindow" name="leeeeelClass" >
|
||||
<property name="objectName" >
|
||||
<string notr="true">leeeeelClass</string>
|
||||
</property>
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>leeeeel</string>
|
||||
</property>
|
||||
<widget class="QMenuBar" name="menuBar" />
|
||||
<widget class="QToolBar" name="mainToolBar" />
|
||||
<widget class="QWidget" name="centralWidget" />
|
||||
<widget class="QStatusBar" name="statusBar" />
|
||||
</widget>
|
||||
<layoutDefault spacing="6" margin="11" />
|
||||
<pixmapfunction></pixmapfunction>
|
||||
<resources>
|
||||
<include location="leeeeel.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</UI>
|
||||
@@ -0,0 +1,246 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B12702AD-ABFB-343A-A199-8E24837244A3}</ProjectGuid>
|
||||
<Keyword>Qt4VSv1.0</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<ProjectName>MayaExporter</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.23107.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<TargetExt>.mll</TargetExt>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<TargetExt>.mll</TargetExt>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;QT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\Maya2016\include;.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\Maya2016\lib;$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>qtmaind.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>QT_DLL;QT_NO_IMPORT_QT47_QML;UNICODE;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\Maya2016\include;.\GeneratedFiles;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\Maya2016\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<AdditionalOptions> /SUBSYSTEM:WINDOWS</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;QT_DLL;QT_NO_DEBUG;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat />
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>qtmain.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;QT_DLL;QT_NO_DEBUG;QT_NO_IMPORT_QT47_QML;UNICODE;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DebugInformationFormat>
|
||||
</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>qtmain.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
<AdditionalOptions> /SUBSYSTEM:WINDOWS</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Menu.cpp" />
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_Menu.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\qrc_leeeeel.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_Menu.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="MayaExporter.ui">
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Uic%27ing %(Identity)...</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Uic%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Uic%27ing %(Identity)...</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Uic%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="Menu.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing Menu.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -D_WINDLL -D_UNICODE "-IC:\Program Files\Autodesk\Maya2016\include" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing Menu.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DQT_DLL -DQT_NO_IMPORT_QT47_QML -DUNICODE -DWIN32 -D_WINDLL -D_UNICODE "-IC:\Program Files\Autodesk\Maya2016\include" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing Menu.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing Menu.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DNDEBUG -DQT_DLL -DQT_NO_DEBUG -DQT_NO_IMPORT_QT47_QML -DUNICODE -DWIN32 "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="GeneratedFiles\ui_MayaExporter.h" />
|
||||
<ClInclude Include="MayaIncludes.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="leeeeel.qrc">
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(FullPath);%(AdditionalInputs)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(FullPath);%(AdditionalInputs)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Rcc%27ing %(Identity)...</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Rcc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(FullPath);%(AdditionalInputs)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(FullPath);%(AdditionalInputs)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Rcc%27ing %(Identity)...</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Rcc%27ing %(Identity)...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\qrc_%(Filename).cpp;%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp</Command>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties MocDir=".\GeneratedFiles\$(ConfigurationName)" UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" lupdateOptions="" lupdateOnBuild="0" lreleaseOptions="" Qt5Version_x0020_Win32="4.8.6" Qt5Version_x0020_x64="Maya2016" MocOptions="" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;cxx;c;def</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Form Files">
|
||||
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
||||
<Extensions>ui</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
||||
<Extensions>qrc;*</Extensions>
|
||||
<ParseFiles>false</ParseFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||
<Extensions>moc;h;cpp</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Debug">
|
||||
<UniqueIdentifier>{bd033994-5bd0-43b7-8fdf-7b8a213a1c55}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Release">
|
||||
<UniqueIdentifier>{f53efcfb-95d1-44a6-a82f-295bb0b0509c}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GeneratedFiles\qrc_leeeeel.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_Menu.cpp">
|
||||
<Filter>Generated Files\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_Menu.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Menu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="leeeeel.qrc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Menu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="MayaExporter.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="MayaIncludes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GeneratedFiles\ui_MayaExporter.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
|
||||
<QTDIR>C:\Program Files\Autodesk\Maya2016</QTDIR>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
|
||||
<QTDIR>C:\Program Files\Autodesk\Maya2016</QTDIR>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
|
||||
<QTDIR>C:\Program Files\Autodesk\Maya2016</QTDIR>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LocalDebuggerEnvironment>PATH=$(QTDIR)\bin%3b$(PATH)</LocalDebuggerEnvironment>
|
||||
<QTDIR>C:\Program Files\Autodesk\Maya2016</QTDIR>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef MAYAINCLUDES_H
|
||||
#define MAYAINCLUDES_H
|
||||
|
||||
#define NT_PLUGIN
|
||||
#define REQUIRE_IOSTREAM
|
||||
#define EXPORT __declspec(dllexport)
|
||||
|
||||
|
||||
#include <maya/MFnMesh.h>
|
||||
#include <maya/MFnTransform.h>
|
||||
#include <maya/MFloatPointArray.h>
|
||||
#include <maya/MPointArray.h>
|
||||
#include <maya/MIntArray.h>
|
||||
#include <maya/MPoint.h>
|
||||
#include <maya/MMatrix.h>
|
||||
#include <maya/MEulerRotation.h>
|
||||
#include <maya/MVector.h>
|
||||
#include <maya/MItDag.h>
|
||||
#include <maya/MFnCamera.h>
|
||||
#include <maya/M3dView.h>
|
||||
#include <maya/MItMeshPolygon.h>
|
||||
#include <maya/MPlugArray.h>
|
||||
#include <maya/MFnDependencyNode.h>
|
||||
#include <maya/MFnLambertShader.h>
|
||||
#include <maya/MFnBlinnShader.h>
|
||||
#include <maya/MFnPhongShader.h>
|
||||
#include <maya/MImage.h>
|
||||
#include <maya/MFnPointLight.h>
|
||||
#include <maya/MSelectionList.h>
|
||||
#include <maya/MItDependencyNodes.h>
|
||||
#include <maya/MFnNurbsCurve.h>
|
||||
#include <maya/MCommandMessage.h>
|
||||
|
||||
|
||||
// Wrappers
|
||||
#include <maya/MGlobal.h>
|
||||
#include <maya/MCallbackIdArray.h>
|
||||
|
||||
#include <maya/MQtUtil.h>
|
||||
|
||||
|
||||
// Messages
|
||||
#include <maya/MMessage.h>
|
||||
#include <maya/MTimerMessage.h>
|
||||
#include <maya/MDGMessage.h>
|
||||
#include <maya/MEventMessage.h>
|
||||
#include <maya/MPolyMessage.h>
|
||||
#include <maya/MNodeMessage.h>
|
||||
#include <maya/MDagPath.h>
|
||||
#include <maya/MDagMessage.h>
|
||||
#include <maya/MUiMessage.h>
|
||||
#include <maya/MModelMessage.h>
|
||||
|
||||
// Commands
|
||||
#include <maya/MPxCommand.h>
|
||||
|
||||
// Libraries to link from Maya
|
||||
#pragma comment(lib,"Foundation.lib")
|
||||
#pragma comment(lib,"OpenMaya.lib")
|
||||
#pragma comment(lib,"OpenMayaUI.lib")
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,239 @@
|
||||
#include "Menu.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Menu::Menu()
|
||||
{
|
||||
}
|
||||
|
||||
Menu::Menu(QDialog* dialog)
|
||||
{
|
||||
// Save the dialog pointer. Needed when the application gets destroyed
|
||||
dialogPointer = dialog;
|
||||
|
||||
// Create QpushButtons & give them names
|
||||
exportSelectedButton = new QPushButton("&Export Selected", this);
|
||||
browseButton = new QPushButton("&...", this);
|
||||
exportAllButton = new QPushButton("&Export All", this);
|
||||
cancelButton = new QPushButton("&Cancel", this);
|
||||
|
||||
// Option box and checkboxes
|
||||
QGroupBox *optionsBox = new QGroupBox(tr("Options"));
|
||||
|
||||
exportAnimationsButton = new QCheckBox(tr("&Export Animations"));
|
||||
copyTexturesButton = new QCheckBox(tr("&Copy Textures"));
|
||||
button3 = new QCheckBox(tr("option3"));
|
||||
|
||||
exportAnimationsButton->setChecked(true);
|
||||
copyTexturesButton->setChecked(true);
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(exportAnimationsButton);
|
||||
vbox->addWidget(copyTexturesButton);
|
||||
vbox->addWidget(button3);
|
||||
vbox->addStretch(1);
|
||||
optionsBox->setLayout(vbox);
|
||||
|
||||
// Connect the buttons with signals & functions
|
||||
connect(exportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(ExportSelected(bool)));
|
||||
connect(browseButton, SIGNAL(clicked(bool)), this, SLOT(ExportPathClicked(bool)));
|
||||
connect(exportAllButton, SIGNAL(clicked(bool)), this, SLOT(ExportAll(bool)));
|
||||
connect(cancelButton, SIGNAL(clicked(bool)), this, SLOT(CancelClicked(bool)));
|
||||
|
||||
connect(exportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(Button1Clicked(bool)));
|
||||
connect(copyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(Button2Clicked(bool)));
|
||||
connect(button3, SIGNAL(clicked(bool)), this, SLOT(Button3Clicked(bool)));
|
||||
|
||||
// Creating several layouts, adding widgets & adding them to one layout in the end
|
||||
QHBoxLayout* topLayout = new QHBoxLayout;
|
||||
QVBoxLayout* midLayout = new QVBoxLayout;
|
||||
QHBoxLayout* botLayout = new QHBoxLayout;
|
||||
QVBoxLayout* baseLayout = new QVBoxLayout;
|
||||
|
||||
exportPath = new QLineEdit;
|
||||
fileDialog = new QFileDialog;
|
||||
|
||||
QLabel* exportLabel = new QLabel;
|
||||
exportLabel->setText("Export Path:");
|
||||
|
||||
midLayout->addWidget(optionsBox);
|
||||
|
||||
topLayout->addWidget(exportLabel);
|
||||
topLayout->addWidget(exportPath);
|
||||
topLayout->addWidget(browseButton);
|
||||
|
||||
botLayout->addWidget(exportSelectedButton);
|
||||
botLayout->addWidget(exportAllButton);
|
||||
botLayout->addWidget(cancelButton);
|
||||
|
||||
baseLayout->addLayout(topLayout);
|
||||
baseLayout->addLayout(midLayout);
|
||||
|
||||
baseLayout->addSpacing(10);
|
||||
|
||||
baseLayout->addLayout(botLayout);
|
||||
baseLayout->addStretch();
|
||||
|
||||
// Set the layout for our window
|
||||
dialog->setLayout(baseLayout);
|
||||
|
||||
}
|
||||
|
||||
void Menu::ExportSelected(bool checked)
|
||||
{
|
||||
// Retrieving the objects we currently have selected
|
||||
MSelectionList selected;
|
||||
MGlobal::getActiveSelectionList(selected);
|
||||
|
||||
// Loop through or list of selection(s)
|
||||
for (unsigned int i = 0; i < selected.length();i++)
|
||||
{
|
||||
MObject object;
|
||||
selected.getDependNode(i, object);
|
||||
MFnDependencyNode thisNode(object);
|
||||
|
||||
cout << thisNode.name().asChar() << endl;
|
||||
GetMeshData(object);
|
||||
}
|
||||
if (exportPath->text().isEmpty())
|
||||
cout << "Please select a folder." << endl;
|
||||
else
|
||||
cout << exportPath->text().toLocal8Bit().constData() << endl;
|
||||
}
|
||||
|
||||
void Menu::ExportPathClicked(bool)
|
||||
{
|
||||
// Opens up a file dialog. Save/Changes the name in the exportPath
|
||||
fileDialog->setFileMode(QFileDialog::Directory);
|
||||
fileDialog->setOption(QFileDialog::ShowDirsOnly);
|
||||
QString fileName = fileDialog->getExistingDirectory(this, "Select", "/home", QFileDialog::ShowDirsOnly);
|
||||
exportPath->setText(fileName);
|
||||
}
|
||||
|
||||
void Menu::ExportAll(bool)
|
||||
{
|
||||
MDagPath path;
|
||||
|
||||
// Loop through all nodes in the scene
|
||||
MItDependencyNodes it(MFn::kInvalid);
|
||||
for (;!it.isDone();it.next())
|
||||
{
|
||||
MObject node = it.thisNode();
|
||||
if (node.hasFn(MFn::kMesh))
|
||||
{
|
||||
MFnDependencyNode thisNode(node);
|
||||
|
||||
cout << thisNode.name().asChar() << endl;
|
||||
GetMeshData(node);
|
||||
}
|
||||
}
|
||||
if (exportPath->text().isEmpty())
|
||||
cout << "Please select a folder." << endl;
|
||||
else
|
||||
cout << exportPath->text().toLocal8Bit().constData() << endl;
|
||||
}
|
||||
|
||||
void Menu::CancelClicked(bool)
|
||||
{
|
||||
dialogPointer->close();
|
||||
}
|
||||
|
||||
void Menu::Button1Clicked(bool)
|
||||
{
|
||||
if(exportAnimationsButton->isChecked())
|
||||
cout << "1 checked!" << endl;
|
||||
else
|
||||
cout << "1 unchecked!" << endl;
|
||||
}
|
||||
|
||||
void Menu::Button2Clicked(bool)
|
||||
{
|
||||
if (copyTexturesButton->isChecked())
|
||||
cout << "2 checked!" << endl;
|
||||
else
|
||||
cout << "2 unchecked!" << endl;
|
||||
}
|
||||
|
||||
void Menu::Button3Clicked(bool)
|
||||
{
|
||||
if (button3->isChecked())
|
||||
cout << "3 checked!" << endl;
|
||||
else
|
||||
cout << "3 unchecked!" << endl;
|
||||
}
|
||||
|
||||
void Menu::GetMeshData(MObject object)
|
||||
{
|
||||
// In here, we retrieve triangulated polygons from the mesh
|
||||
MFnMesh mesh(object);
|
||||
|
||||
map<UINT, vector<UINT>> vertexToIndex;
|
||||
|
||||
vector<VertexLayout> verticesData;
|
||||
vector<UINT>indexArray;
|
||||
|
||||
MIntArray intdexOffsetVertexCount, vertices, triangleList;
|
||||
MPointArray dummy;
|
||||
|
||||
UINT vertexIndex;
|
||||
MVector normal;
|
||||
MPoint pos;
|
||||
float2 UV;
|
||||
VertexLayout thisVertex;
|
||||
|
||||
for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next())
|
||||
{
|
||||
vector<UINT> localVertexToGlobalIndex;
|
||||
meshPolyIter.getVertices(vertices);
|
||||
|
||||
meshPolyIter.getTriangles(dummy, triangleList);
|
||||
UINT indexOffset = verticesData.size();
|
||||
|
||||
for (UINT i = 0; i < vertices.length(); i++)
|
||||
{
|
||||
vertexIndex = meshPolyIter.vertexIndex(i);
|
||||
pos = meshPolyIter.point(i);
|
||||
pos.get(thisVertex.pos);
|
||||
|
||||
meshPolyIter.getNormal(i, normal);
|
||||
thisVertex.normal[0] = normal[0];
|
||||
thisVertex.normal[1] = normal[1];
|
||||
thisVertex.normal[2] = normal[2];
|
||||
|
||||
meshPolyIter.getUV(i, UV);
|
||||
thisVertex.uv[0] = UV[0];
|
||||
thisVertex.uv[1] = UV[1];
|
||||
|
||||
verticesData.push_back(thisVertex);
|
||||
localVertexToGlobalIndex.push_back(vertexIndex);
|
||||
|
||||
cout << "Pos: " << thisVertex.pos[0] << "/" << thisVertex.pos[1] << "/" << thisVertex.pos[2] << endl;
|
||||
cout << "Normals: " << thisVertex.normal[0] << "/" << thisVertex.normal[1] << "/" << thisVertex.normal[2] << endl;
|
||||
cout << "UV: " << thisVertex.uv[0] << "/" << thisVertex.uv[1] << endl;
|
||||
}
|
||||
for (UINT i = 0; i < triangleList.length(); i++)
|
||||
{
|
||||
UINT k = 0;
|
||||
while (localVertexToGlobalIndex[k] != triangleList[i])
|
||||
k++;
|
||||
indexArray.push_back(indexOffset + k);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Menu::exportMaterial(MObject object)
|
||||
{
|
||||
MItDependencyNodes matIt(MFn::kLambert);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Menu::~Menu()
|
||||
{
|
||||
//delete exportSelectedButton;
|
||||
//delete browseButton;
|
||||
//delete exportPath;
|
||||
//delete fileDialog;
|
||||
fileDialog->~QFileDialog();
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef BUTTONS_H
|
||||
#define BUTTONS_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "MayaIncludes.h"
|
||||
// Qt
|
||||
#pragma comment(lib, "QtCore4")
|
||||
#pragma comment(lib, "QtGui4")
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
|
||||
#include <maya/MQtUtil.h>
|
||||
#include <QtGui/qwidget.h>
|
||||
#include <QtGui/qapplication.h>
|
||||
#include <QtGui/qdialog.h>
|
||||
#include <QtGui/qpushbutton.h>
|
||||
#include <QtGui/qboxlayout.h>
|
||||
#include <QtGui/qformlayout.h>
|
||||
#include <QtCore/qthread.h>
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtGui/qlistwidget.h>
|
||||
#include <QtUiTools/quiloader.h>
|
||||
#include <QtCore/qfile.h>
|
||||
#include <QtGui/qlabel.h>
|
||||
#include <QtGui/qcheckbox.h>
|
||||
#include <QtGui/qradiobutton.h>
|
||||
#include <QtGui/qfiledialog.h>
|
||||
#include <QtGui/qlineedit.h>
|
||||
#include <QtGui/qgroupbox.h>
|
||||
|
||||
struct VertexLayout
|
||||
{
|
||||
float pos[3];
|
||||
float normal[3];
|
||||
float uv[2];
|
||||
};
|
||||
|
||||
class Menu : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Menu(QDialog* dialog);
|
||||
~Menu();
|
||||
|
||||
void GetMeshData(MObject object);
|
||||
void exportMaterial(MObject object);
|
||||
|
||||
private slots:
|
||||
void ExportSelected(bool checked);
|
||||
void ExportPathClicked(bool);
|
||||
void ExportAll(bool);
|
||||
void CancelClicked(bool);
|
||||
|
||||
void Button1Clicked(bool);
|
||||
void Button2Clicked(bool);
|
||||
void Button3Clicked(bool);
|
||||
|
||||
|
||||
private:
|
||||
Menu();
|
||||
QPushButton* exportSelectedButton;
|
||||
QPushButton* browseButton;
|
||||
QPushButton* exportAllButton;
|
||||
QPushButton* cancelButton;
|
||||
|
||||
QCheckBox* exportAnimationsButton;
|
||||
QCheckBox* copyTexturesButton;
|
||||
QCheckBox* button3;
|
||||
|
||||
QLineEdit* exportPath;
|
||||
QFileDialog* fileDialog;
|
||||
QDialog* dialogPointer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
<RCC>
|
||||
<qresource prefix="leeeeel">
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"type": "service_account",
|
||||
"private_key_id": "cca18cfac73794c4d2976833949829fe150ead81",
|
||||
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCvgdm4HeS54TS9\nS58jhxbaxrFL5yOyyofJo51CtBAMT0aCuV41ngoethfJArjwO1ZziaPRX0ZrQvBC\n3XtIcBblkR/6w0uYF3lTcwuxqpbNrkptQNc7ms91pYHeRJS/u+U0hmnmS+TI8q4c\nm47xbtpw2ym8Uvq1anvYgmnlQQNNgaFcuYSgFLPhRL2TdOR82fz055rHUeEIT3YG\n7RpZBokWQFaZT5KsWbBjjEMlfexg11/9tK1zbDCjqU/JSBRmzmXh0kEbRCWQWC5k\n+ZHSrcD8Sj3d6nfBsxiu8yAW0pYqMEDNnlX69ovqjVlfa1PO+J+7IwY1svde872C\nzrC1huyzAgMBAAECggEASiq2he7kDIUWE3SUkJ/y0Ysru2a3GEQsM9LXjyumqH0L\n0AxjuobJwgazcHedDbAVrYeZ2c3IZWWJQMh147uygVrdx8ul82TgGZrBc1gimFKy\nEw9WpVKbnxzND8+tiITvrE2tDOw/h4e+ekpmkrKEzzJepb3vQqD4KxuZgo8BxUtw\n1bBAq2hKKukc1IlzXv0cegWYqfw1wA3vFngQh+B/ueR3kbLUWu130z2Ls/SnBdHt\nYaIbER6YUrQ6eG2cQrjh711zMjMgMsinyh+MR/VHERspPR7HnNJkEb8LXivoLQE4\nUbBTihups769NJUr3CSqKXHIwv8QO9EfJ6IN8pglwQKBgQDyMEJW3iE0tKaBgtXY\nzJ4TWOkTOoKAnbuZd19ZbqARPfa+6apT4NWCz7pVXcZKv7rsMZTbCHAf3HfptCAq\nQSVkuRZaCv6SOUaWp0kk8cxIJpbvwMeqBY/BDmQr8SzUir6N0M+7G3tV/joqpY5c\n2V1udZeR0Ch4V+F9M/osmyvOIQKBgQC5hBpQlMmeQivk9P1eHkiB1w9RlLIrYjcQ\ndaSFOwgMiswK2/I04P/9BhXXeIin5r5EmpfHOM32wTdu5RkU5Ts428JqAshQBSwZ\nEciofEJ0fvmxCR+d+imG+Kq2BOneatOC6aYBVWr2VUDq8KyD4jL8tju6KOLvssRR\nsoK26wAYUwKBgQCexHpI3jfgiGj7UB0GkiUyw7+P5nR1AnJgSfxM8ZOnmfpu71nE\nwQjXR3x8yAvdJtHQUzSlXmO6z1og7/+CE9ECtb9safa3PysCSkpOGOF1jy61n6iE\n0j6KLfgHQoTEFOyUpYX4wCxblFznZj7sqWZxqk8hvNc7BUmCPZfMtDDEYQKBgQCP\nK+ZrHgjjvEnH71LCmjh3DBRkb495b9jzOPd5Yu95TnzePJSWPrcQ/OtKWVmNysQ4\nid5s/+fkcYVobiKHP8oOvXsy+WbCatt3lYP4k71tzrjA6jueXfxCkBKfWvdqkaMe\nu1dEXDmqVm09Y/Sf66hR5AoAR6GsP5jHPC8pH//4xQKBgQDlVw8Q6Xq5FFUfURvF\n6p8XsCgheykLDzFZHv2neL4ESXpt2flCaLcb+pC8+IrNDorC8BX6JiZD2WngMn+s\nClAkq4TgGE5Mjmk5ZOhrpg69H7O87OcNK5Cc12+tnoPsnvEcuF8CoGWIy3A6PNt+\nROnL6yOGeh2IHowPjrO3ODKO4Q==\n-----END PRIVATE KEY-----\n",
|
||||
"client_email": "account-1@toggltospreadsheet.iam.gserviceaccount.com",
|
||||
"client_id": "108608534336227301760",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://accounts.google.com/o/oauth2/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/account-1%40toggltospreadsheet.iam.gserviceaccount.com"
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
import base64
|
||||
import sys
|
||||
import re
|
||||
import pip
|
||||
try:
|
||||
import requests
|
||||
except ImportError:
|
||||
print 'requests module not installed.'
|
||||
print 'Installing requests...'
|
||||
pip.main(['install', 'requests'])
|
||||
import requests
|
||||
|
||||
try:
|
||||
import gspread
|
||||
except ImportError:
|
||||
print 'gspread module not installed.'
|
||||
print 'Installing gspread...'
|
||||
pip.main(['install', 'gspread'])
|
||||
import gspread
|
||||
|
||||
import json
|
||||
import time
|
||||
from oauth2client.client import SignedJwtAssertionCredentials
|
||||
|
||||
def write_to_sheet(values, estimatedTime):
|
||||
# Note: This is Andreas client email & private google API key. Plz no share
|
||||
client_email = 'account-1@toggltospreadsheet.iam.gserviceaccount.com'
|
||||
private_key = 'nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCvgdm4HeS54TS9\nS58jhxbaxrFL5yOyyofJo51CtBAMT0aCuV41ngoethfJArjwO1ZziaPRX0ZrQvBC\n3XtIcBblkR/6w0uYF3lTcwuxqpbNrkptQNc7ms91pYHeRJS/u+U0hmnmS+TI8q4c\nm47xbtpw2ym8Uvq1anvYgmnlQQNNgaFcuYSgFLPhRL2TdOR82fz055rHUeEIT3YG\n7RpZBokWQFaZT5KsWbBjjEMlfexg11/9tK1zbDCjqU/JSBRmzmXh0kEbRCWQWC5k\n+ZHSrcD8Sj3d6nfBsxiu8yAW0pYqMEDNnlX69ovqjVlfa1PO+J+7IwY1svde872C\nzrC1huyzAgMBAAECggEASiq2he7kDIUWE3SUkJ/y0Ysru2a3GEQsM9LXjyumqH0L\n0AxjuobJwgazcHedDbAVrYeZ2c3IZWWJQMh147uygVrdx8ul82TgGZrBc1gimFKy\nEw9WpVKbnxzND8+tiITvrE2tDOw/h4e+ekpmkrKEzzJepb3vQqD4KxuZgo8BxUtw\n1bBAq2hKKukc1IlzXv0cegWYqfw1wA3vFngQh+B/ueR3kbLUWu130z2Ls/SnBdHt\nYaIbER6YUrQ6eG2cQrjh711zMjMgMsinyh+MR/VHERspPR7HnNJkEb8LXivoLQE4\nUbBTihups769NJUr3CSqKXHIwv8QO9EfJ6IN8pglwQKBgQDyMEJW3iE0tKaBgtXY\nzJ4TWOkTOoKAnbuZd19ZbqARPfa+6apT4NWCz7pVXcZKv7rsMZTbCHAf3HfptCAq\nQSVkuRZaCv6SOUaWp0kk8cxIJpbvwMeqBY/BDmQr8SzUir6N0M+7G3tV/joqpY5c\n2V1udZeR0Ch4V+F9M/osmyvOIQKBgQC5hBpQlMmeQivk9P1eHkiB1w9RlLIrYjcQ\ndaSFOwgMiswK2/I04P/9BhXXeIin5r5EmpfHOM32wTdu5RkU5Ts428JqAshQBSwZ\nEciofEJ0fvmxCR+d+imG+Kq2BOneatOC6aYBVWr2VUDq8KyD4jL8tju6KOLvssRR\nsoK26wAYUwKBgQCexHpI3jfgiGj7UB0GkiUyw7+P5nR1AnJgSfxM8ZOnmfpu71nE\nwQjXR3x8yAvdJtHQUzSlXmO6z1og7/+CE9ECtb9safa3PysCSkpOGOF1jy61n6iE\n0j6KLfgHQoTEFOyUpYX4wCxblFznZj7sqWZxqk8hvNc7BUmCPZfMtDDEYQKBgQCP\nK+ZrHgjjvEnH71LCmjh3DBRkb495b9jzOPd5Yu95TnzePJSWPrcQ/OtKWVmNysQ4\nid5s/+fkcYVobiKHP8oOvXsy+WbCatt3lYP4k71tzrjA6jueXfxCkBKfWvdqkaMe\nu1dEXDmqVm09Y/Sf66hR5AoAR6GsP5jHPC8pH//4xQKBgQDlVw8Q6Xq5FFUfURvF\n6p8XsCgheykLDzFZHv2neL4ESXpt2flCaLcb+pC8+IrNDorC8BX6JiZD2WngMn+s\nClAkq4TgGE5Mjmk5ZOhrpg69H7O87OcNK5Cc12+tnoPsnvEcuF8CoGWIy3A6PNt+\nROnL6yOGeh2IHowPjrO3ODKO4Q=='
|
||||
|
||||
# Change the path, otherwise the the json_key will not be found and writing to the Sheet will fail.
|
||||
json_key = json.load(open('TogglToSpreadSheet-cca18cfac737.json'))
|
||||
scope = ['https://spreadsheets.google.com/feeds']
|
||||
|
||||
credentials = SignedJwtAssertionCredentials(json_key['client_email'], json_key['private_key'].encode(), scope)
|
||||
gc = gspread.authorize(credentials)
|
||||
sh = gc.open_by_url('https://docs.google.com/spreadsheets/d/1P8HFfktwSAF0rgi9rxpNvdMdR0GYuo845qAGikeJUh8/edit#gid=0')
|
||||
worksheet = sh.get_worksheet(0)
|
||||
|
||||
currentDate = time.strftime("%Y-%m-%d")
|
||||
results = [currentDate,values]
|
||||
worksheet.insert_row(results, 3)
|
||||
worksheet.update_acell("F2", estimatedTime)
|
||||
return;
|
||||
|
||||
def get_totaltime_data():
|
||||
api_token = '136ab033e06f9202497093b989f59f39'
|
||||
_workspace_id = 1190663
|
||||
print 'Sending Request...'
|
||||
|
||||
r = requests.get('https://toggl.com/reports/api/v2/summary', auth=(api_token, 'api_token'), params={'workspace_id': _workspace_id, 'since' : '2015-11-01', 'user_agent': 'api_test'})
|
||||
if r.status_code != 200:
|
||||
print 'Request Failed. Check your API Token'
|
||||
return;
|
||||
index = []
|
||||
|
||||
rWorkspace = requests.get('https://www.toggl.com/api/v8/workspaces/1190663/projects', auth=(api_token, 'api_token'))
|
||||
workspaceText = rWorkspace.text
|
||||
taskMap = map(int, re.findall(r'\d+', workspaceText))
|
||||
estimatedTime = 0
|
||||
counter = 0
|
||||
index = [x-1 for x, i in enumerate(taskMap) if i == 1190663]
|
||||
|
||||
|
||||
for x in index:
|
||||
timeMap = []
|
||||
rProject = requests.get('https://www.toggl.com/reports/api/v2/project', auth=(api_token, 'api_token'), params={'user_agent': 'api_test','workspace_id': _workspace_id, 'project_id': taskMap[x]})
|
||||
if r.status_code != 200:
|
||||
print 'rProject request Failed. Check your API Token'
|
||||
return;
|
||||
projectText = rProject.text
|
||||
text = projectText.replace('null','0')
|
||||
finalText = text.replace('0.0', '0')
|
||||
timeMap = map(int, re.findall(r'\d+', finalText))
|
||||
estimatedTime = estimatedTime + timeMap[6]
|
||||
counter+= 1
|
||||
|
||||
wholeText = r.text
|
||||
allNumbers = map(int, re.findall('\d+', wholeText))
|
||||
totalTime = allNumbers[0]
|
||||
timeleft = totalTime
|
||||
hours = totalTime / 3600000
|
||||
timeleft -= hours * 3600000
|
||||
min = timeleft / 60000
|
||||
timeleft -= min * 60000
|
||||
sec = timeleft / 1000
|
||||
estimatedTimeInHours = estimatedTime / 3600
|
||||
|
||||
str = 'Total Time: ' + repr(hours) +':' + repr(min) + ':' + repr(sec)
|
||||
print str
|
||||
result = repr(hours) + ':' + repr(min) +':' + repr(sec)
|
||||
#result = []
|
||||
#result.append(hours);
|
||||
#result.append(min);
|
||||
#result.append(sec);
|
||||
|
||||
print 'Writing to Sheet...'
|
||||
write_to_sheet(result, estimatedTimeInHours)
|
||||
return;
|
||||
|
||||
get_totaltime_data()
|
||||
print 'Done!'
|
||||
@@ -18,8 +18,6 @@ RMDIR "%DeployLocation%\Schema"
|
||||
MKLINK "%DeployLocation%\Schema\" "resources\Schema" /J
|
||||
:: Shaders
|
||||
RMDIR /S /Q "%DeployLocation%\Shaders"
|
||||
MKDIR "%DeployLocation%\Shaders"
|
||||
MKLINK "%DeployLocation%\Shaders\" "resources\Shaders" /J
|
||||
MKLINK "%DeployLocation%\Shaders\" "resources\Shaders" /J
|
||||
:: Configuration files
|
||||
MKLINK "%DeployLocation%\DefaultConfig.ini" "resources\DefaultConfig.ini" /H
|
||||
|
||||
Reference in New Issue
Block a user