diff --git a/Bin/DLL/DebugCameraVertex.cso b/Bin/DLL/DebugCameraVertex.cso index db8c9bce..d1e96f0c 100644 Binary files a/Bin/DLL/DebugCameraVertex.cso and b/Bin/DLL/DebugCameraVertex.cso differ diff --git a/Bin/DLL/DebugPixel.cso b/Bin/DLL/DebugPixel.cso index 8f2b274b..fb01961e 100644 Binary files a/Bin/DLL/DebugPixel.cso and b/Bin/DLL/DebugPixel.cso differ diff --git a/Bin/DLL/DebugVertex.cso b/Bin/DLL/DebugVertex.cso index eb211e78..409bf6f3 100644 Binary files a/Bin/DLL/DebugVertex.cso and b/Bin/DLL/DebugVertex.cso differ diff --git a/Bin/DLL/GamePhysics_x86D.dll b/Bin/DLL/GamePhysics_x86D.dll index 600f7736..75aaa30f 100644 Binary files a/Bin/DLL/GamePhysics_x86D.dll and b/Bin/DLL/GamePhysics_x86D.dll differ diff --git a/Bin/DLL/GamePhysics_x86D.exp b/Bin/DLL/GamePhysics_x86D.exp index 6e03abce..6176e02a 100644 Binary files a/Bin/DLL/GamePhysics_x86D.exp and b/Bin/DLL/GamePhysics_x86D.exp differ diff --git a/Bin/DLL/GamePhysics_x86D.ilk b/Bin/DLL/GamePhysics_x86D.ilk index f00af251..59b3b901 100644 Binary files a/Bin/DLL/GamePhysics_x86D.ilk and b/Bin/DLL/GamePhysics_x86D.ilk differ diff --git a/Bin/DLL/GamePhysics_x86D.pdb b/Bin/DLL/GamePhysics_x86D.pdb index 44554c38..e58ea3ba 100644 Binary files a/Bin/DLL/GamePhysics_x86D.pdb and b/Bin/DLL/GamePhysics_x86D.pdb differ diff --git a/Bin/DLL/OysterGraphics_x86D.dll b/Bin/DLL/OysterGraphics_x86D.dll index ce514407..5a957f4c 100644 Binary files a/Bin/DLL/OysterGraphics_x86D.dll and b/Bin/DLL/OysterGraphics_x86D.dll differ diff --git a/Bin/DLL/OysterGraphics_x86D.exp b/Bin/DLL/OysterGraphics_x86D.exp index 3679e007..25d30be5 100644 Binary files a/Bin/DLL/OysterGraphics_x86D.exp and b/Bin/DLL/OysterGraphics_x86D.exp differ diff --git a/Bin/DLL/OysterGraphics_x86D.ilk b/Bin/DLL/OysterGraphics_x86D.ilk index 8e111f12..8d009ca4 100644 Binary files a/Bin/DLL/OysterGraphics_x86D.ilk and b/Bin/DLL/OysterGraphics_x86D.ilk differ diff --git a/Bin/DLL/OysterGraphics_x86D.pdb b/Bin/DLL/OysterGraphics_x86D.pdb index 2b032b64..91810085 100644 Binary files a/Bin/DLL/OysterGraphics_x86D.pdb and b/Bin/DLL/OysterGraphics_x86D.pdb differ diff --git a/Bin/DLL/PixelGatherData.cso b/Bin/DLL/PixelGatherData.cso index 3ff8c1e0..1b5ca385 100644 Binary files a/Bin/DLL/PixelGatherData.cso and b/Bin/DLL/PixelGatherData.cso differ diff --git a/Bin/DLL/TextureDebug.cso b/Bin/DLL/TextureDebug.cso new file mode 100644 index 00000000..702c27d8 Binary files /dev/null and b/Bin/DLL/TextureDebug.cso differ diff --git a/Bin/DLL/VertexGatherData.cso b/Bin/DLL/VertexGatherData.cso index 45dd4a63..facb06b5 100644 Binary files a/Bin/DLL/VertexGatherData.cso and b/Bin/DLL/VertexGatherData.cso differ diff --git a/Code/Misc/Misc.vcxproj b/Code/Misc/Misc.vcxproj index e2947725..ca39cada 100644 --- a/Code/Misc/Misc.vcxproj +++ b/Code/Misc/Misc.vcxproj @@ -150,12 +150,17 @@ + + + + + diff --git a/Code/Misc/Misc.vcxproj.filters.orig b/Code/Misc/Misc.vcxproj.filters.orig new file mode 100644 index 00000000..f3327ce5 --- /dev/null +++ b/Code/Misc/Misc.vcxproj.filters.orig @@ -0,0 +1,72 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + +<<<<<<< HEAD +======= + + Source Files + + + Source Files + +>>>>>>> 48c812b0338b859aa6c00c8504dd2f16a4bb44f9 + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/Code/Misc/Resource/Loaders/ByteLoader.cpp b/Code/Misc/Resource/Loaders/ByteLoader.cpp index 86a571ca..622d3a71 100644 --- a/Code/Misc/Resource/Loaders/ByteLoader.cpp +++ b/Code/Misc/Resource/Loaders/ByteLoader.cpp @@ -1,3 +1,6 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// #include "..\OResource.h" #include "..\..\Utilities.h" diff --git a/Code/Misc/Resource/Loaders/CustomLoader.cpp b/Code/Misc/Resource/Loaders/CustomLoader.cpp index 84cb9302..312c4c53 100644 --- a/Code/Misc/Resource/Loaders/CustomLoader.cpp +++ b/Code/Misc/Resource/Loaders/CustomLoader.cpp @@ -1,3 +1,6 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// #include "..\OResource.h" #include "..\..\Utilities.h" @@ -9,7 +12,7 @@ using namespace Oyster::Resource; OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc) { - const CustomData &data = fnc(); + const CustomData &data = fnc(filename); if(!data.loadedData) return 0; if(!data.resourceUnloadFnc) return 0; @@ -31,7 +34,7 @@ OResource* OResource::CustomReloader() { CustomUnloader(); - const CustomData &data = this->customData->loadingFunction(); + const CustomData &data = this->customData->loadingFunction(this->resourceFilename.c_str()); this->resourceData = (OHRESOURCE)data.loadedData; if(data.resourceUnloadFnc) diff --git a/Code/Misc/Resource/OResource.cpp b/Code/Misc/Resource/OResource.cpp index af0bc14a..4311669f 100644 --- a/Code/Misc/Resource/OResource.cpp +++ b/Code/Misc/Resource/OResource.cpp @@ -1,3 +1,7 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + #include "OResource.h" using namespace Oyster::Resource; diff --git a/Code/Misc/Resource/OResource.h b/Code/Misc/Resource/OResource.h index 221fb3ad..c0e32ba5 100644 --- a/Code/Misc/Resource/OResource.h +++ b/Code/Misc/Resource/OResource.h @@ -47,7 +47,7 @@ namespace Oyster static OResource* Reload (OResource* resource); static bool Release (OResource* resource); - Utility::DynamicMemory::RefCount resourceRef; + Utility::DynamicMemory::ReferenceCount resourceRef; private: static OResource* ByteLoader (const wchar_t filename[], ResourceType type, OResource* old = 0); diff --git a/Code/Misc/Resource/OResourceHandler.cpp b/Code/Misc/Resource/OResourceHandler.cpp index a6fcffbc..9d911875 100644 --- a/Code/Misc/Resource/OResourceHandler.cpp +++ b/Code/Misc/Resource/OResourceHandler.cpp @@ -60,7 +60,8 @@ OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunc if(!resourceData) return 0; - if(resourceData) resourceData->SetResourceID(CustomId); + resourceData->SetResourceID(CustomId); + resourcePrivate.SaveResource(resourceData); return (OHRESOURCE)resourceData->GetResourceHandle(); diff --git a/Code/Misc/Resource/OysterResource.h b/Code/Misc/Resource/OysterResource.h index 3e449196..16d5122d 100644 --- a/Code/Misc/Resource/OysterResource.h +++ b/Code/Misc/Resource/OysterResource.h @@ -13,8 +13,10 @@ namespace Oyster struct CustomData; /** A Resource handle representing various resources */ typedef unsigned long OHRESOURCE; - typedef void(*CustomUnloadFunction)(void*); - typedef const CustomData&(*CustomLoadFunction)(); + /** Typedef on a fuction required for custom unloading */ + typedef void(*CustomUnloadFunction)(void* loadedData); + /** Typedef on a fuction required for custom loading */ + typedef const CustomData&(*CustomLoadFunction)(const wchar_t filename[]); /** An enum class representing all avalible resources that is supported. */ enum ResourceType @@ -26,7 +28,7 @@ namespace Oyster ResourceType_Byte_UNICODE, /**< Handle can be interpeted as char[] or char* */ ResourceType_Byte_UTF16LE, /**< Handle can be interpeted as char[] or char* */ - ResourceType_COUNT, /**< Handle can be interpeted as ? */ + ResourceType_COUNT, /**< Not used. */ ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */ }; diff --git a/Code/Misc/Thread/IThreadObject.h b/Code/Misc/Thread/IThreadObject.h new file mode 100644 index 00000000..b21c942e --- /dev/null +++ b/Code/Misc/Thread/IThreadObject.h @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#ifndef MISC_I_THREAD_OBJECT_H +#define MISC_I_THREAD_OBJECT_H + + + +namespace Oyster +{ + namespace Thread + { + /** + * Inherit this class to get threading compatibility. + */ + class IThreadObject + { + public: + /** + * Override this to get notified when the thread is started. + */ + virtual void ThreadEntry() { } + /** + * Override this to get notified when the thread is about to exit. + */ + virtual void ThreadExit() { } + /** + * This function is required to get threading working. + */ + virtual bool DoWork ( ) = 0; + }; + } +} + +#endif // !MISC_I_THREAD_OBJECT_H + diff --git a/Code/Misc/Thread/OysterMutex.cpp b/Code/Misc/Thread/OysterMutex.cpp new file mode 100644 index 00000000..a8dfd20f --- /dev/null +++ b/Code/Misc/Thread/OysterMutex.cpp @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#include "OysterMutex.h" + +#include +#include +#include + + + +OysterMutex::OysterMutex() +{} + +OysterMutex::OysterMutex(bool initialOwnership) +{ + if(initialOwnership) + { + this->mutex.lock(); + this->id = std::this_thread::get_id(); + } +} +OysterMutex::~OysterMutex() +{ +} +void OysterMutex::LockMutex() +{ + if(std::this_thread::get_id() == this->id) return; + + this->mutex.lock(); + + this->id = std::this_thread::get_id(); +} +void OysterMutex::LockMutex(unsigned int msec) +{ + if(std::this_thread::get_id() == this->id) return; + + auto start = std::chrono::high_resolution_clock::now(); + auto end = start + std::chrono::milliseconds(msec); + + do + { + if(this->mutex.try_lock()) + { + this->mutex.lock(); + this->id = std::this_thread::get_id(); + return; + } + } while (std::chrono::high_resolution_clock::now() < end); + + this->mutex.lock(); +} +void OysterMutex::UnlockMutex() +{ + //Let the owner unlock + if(std::this_thread::get_id() != this->id) return; + + this->mutex.unlock(); + this->id = std::thread::id(); + +} +bool OysterMutex::IsTaken() +{ + return !this->mutex.try_lock(); +} +void OysterMutex::Reset() +{ + if(!this->mutex.try_lock()) + this->mutex.unlock(); +} \ No newline at end of file diff --git a/Code/Misc/Thread/OysterMutex.h b/Code/Misc/Thread/OysterMutex.h new file mode 100644 index 00000000..b36585c1 --- /dev/null +++ b/Code/Misc/Thread/OysterMutex.h @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#ifndef MISC_OYSTER_MUTEX_H +#define MISC_OYSTER_MUTEX_H + +#include +#include +#include + +class OysterMutex +{ +public: + OysterMutex(); + OysterMutex(bool initialOwnership); + virtual~OysterMutex(); + void LockMutex(); + void LockMutex(unsigned int timeSpan); + void UnlockMutex(); + /** Returns true if mutex is taken */ + bool IsTaken(); + /** This function resets resource locking */ + void Reset(); + +private: + std::mutex mutex; + std::thread::id id; + + OysterMutex(const OysterMutex&); +}; + +#endif // !MISC_OYSTER_MUTEX_H diff --git a/Code/Misc/Thread/OysterThread.h b/Code/Misc/Thread/OysterThread.h new file mode 100644 index 00000000..873497ad --- /dev/null +++ b/Code/Misc/Thread/OysterThread.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#ifndef MISC_OYSTER_THREAD_H +#define MISC_OYSTER_THREAD_H + +#include "IThreadObject.h" + +namespace Oyster +{ + namespace Thread + { + enum OYSTER_THREAD_ERROR + { + OYSTER_THREAD_ERROR_FAILED, + OYSTER_THREAD_ERROR_SUCCESS, + }; + + class OysterThread + { + private: + struct PrivateData; + PrivateData *privateData; + + OysterThread(const OysterThread& original); + const OysterThread& operator=(const OysterThread& original); + + public: + OysterThread(); + virtual~OysterThread(); + + OYSTER_THREAD_ERROR Create(IThreadObject* worker, bool start); + OYSTER_THREAD_ERROR Start(); + void Stop(); + void Pause(); + void Pause(int mSec); + void Resume(); + OYSTER_THREAD_ERROR Reset(IThreadObject* worker = 0); + void Terminate(); + void Wait(); + void Wait(int mSec); + OYSTER_THREAD_ERROR Swap(const OysterThread* other); + bool IsActive(); + }; + } +} + +#endif // !MISC_OYSTER_THREAD_H diff --git a/Code/Misc/Thread/OysterThread_Impl.cpp b/Code/Misc/Thread/OysterThread_Impl.cpp new file mode 100644 index 00000000..171c8aa9 --- /dev/null +++ b/Code/Misc/Thread/OysterThread_Impl.cpp @@ -0,0 +1,253 @@ +///////////////////////////////////////////////////////////////////// +// Created by [Dennis Andersen] [2013] +///////////////////////////////////////////////////////////////////// + +#include "OysterThread.h" +#include "OysterMutex.h" +#include "..\Utilities.h" +#include +#include + +using namespace Oyster::Thread; +using namespace Utility::DynamicMemory::SmartPointer; + + +#pragma region Declerations + + struct ThreadData; + /** A typical Oyster thread function */ + typedef void (*ThreadFunction)(StdSmartPointer&); + + enum OYSTER_THREAD_STATE + { + OYSTER_THREAD_STATE_RESET, + OYSTER_THREAD_STATE_RUNNING, + OYSTER_THREAD_STATE_PAUSED, + OYSTER_THREAD_STATE_STOPED, + OYSTER_THREAD_STATE_TERMINATED, + OYSTER_THREAD_STATE_DEAD, + }; + + //TODO: Add a threadStartPackage struct that contains all the necasary data to fire of a thread + struct ThreadData + { + OYSTER_THREAD_STATE state; // workerThread; // threadData; + + PrivateData() + :threadData(new ThreadData()) + { + threadData->owner = 0; + threadData->workerThread = 0; + threadData->callingThread; + threadData->state = OYSTER_THREAD_STATE_STOPED; + } + ~PrivateData() + { + //@todo TODO: Make detatch avalible. + //this->threadData->workerThread->detach(); + + this->threadData->owner = 0; + + this->threadData->state = OYSTER_THREAD_STATE_DEAD; + } + + }; + +#pragma endregion + + + +static void ThreadingFunction(StdSmartPointer &origin) +{ + bool shouldContinue; + StdSmartPointer w = origin; + +theBegining: + + while(w->state == OYSTER_THREAD_STATE_STOPED); + w->mutexLock.LockMutex(); + w->owner->ThreadEntry(); + w->mutexLock.UnlockMutex(); + + while (w->state != OYSTER_THREAD_STATE_STOPED && w->state != OYSTER_THREAD_STATE_DEAD) + { + + w->mutexLock.LockMutex(); + { + shouldContinue = w->owner->DoWork(); + } + w->mutexLock.UnlockMutex(); + + if(!shouldContinue) + { + goto theEnd; + } + if(w->state == OYSTER_THREAD_STATE_TERMINATED) + { + return; + } + else if(w->state == OYSTER_THREAD_STATE_RESET) + { + goto theBegining; + } + else if(w->msec > 0) + { + std::this_thread::sleep_for(std::chrono::milliseconds(w->msec)); + } + + while (w->state == OYSTER_THREAD_STATE_PAUSED); + } + + if(w->state == OYSTER_THREAD_STATE_DEAD) + { + return; + } + +theEnd: + + w->mutexLock.LockMutex(); + w->owner->ThreadExit(); + w->mutexLock.UnlockMutex(); + + w->state = OYSTER_THREAD_STATE_DEAD; +} + +OysterThread::OysterThread() +{ + this->privateData = new PrivateData(); +} +OysterThread::~OysterThread() +{ + delete this->privateData; + this->privateData = 0; +} + +OYSTER_THREAD_ERROR OysterThread::Create(IThreadObject* worker, bool start) +{ + if(!this->privateData) return OYSTER_THREAD_ERROR_FAILED; + if(this->privateData->threadData->workerThread) return OYSTER_THREAD_ERROR_FAILED; + + this->privateData->threadData->owner = worker; + + ThreadFunction fnc = ThreadingFunction; + + //Maby move this thread creation to a seperate Start() function because std::thread fires the thread when it is created. :( + this->privateData->threadData->workerThread = new std::thread(fnc, this->privateData->threadData); + + if(!this->privateData->threadData->workerThread) + return OYSTER_THREAD_ERROR_FAILED; + + if(start) + { + //@todo TODO: No need to lock since the other thread end is only reading this value. Worst case scenario is n lost cycles. + this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING; + } + return OYSTER_THREAD_ERROR_SUCCESS; +} +OYSTER_THREAD_ERROR OysterThread::Start() +{ + if(!this->privateData->threadData->workerThread) + return OYSTER_THREAD_ERROR_FAILED; + + this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING; + return OYSTER_THREAD_ERROR_SUCCESS; +} +void OysterThread::Stop() +{ + this->privateData->threadData->mutexLock.LockMutex(); + this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED; + this->privateData->threadData->mutexLock.UnlockMutex(); +} +void OysterThread::Pause() +{ + this->privateData->threadData->mutexLock.LockMutex(); + this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED; + this->privateData->threadData->mutexLock.UnlockMutex(); +} +void OysterThread::Pause(int msec) +{ + + if(std::this_thread::get_id() == this->privateData->threadData->workerThread->get_id()) + { + this->privateData->threadData->msec = msec; + } + else + { + this->privateData->threadData->mutexLock.LockMutex(); + this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED; + this->privateData->threadData->msec = msec; + this->privateData->threadData->mutexLock.UnlockMutex(); + } +} +void OysterThread::Resume() +{ + this->privateData->threadData->mutexLock.LockMutex(); + this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING; + this->privateData->threadData->mutexLock.UnlockMutex(); +} +OYSTER_THREAD_ERROR OysterThread::Reset(IThreadObject* worker) +{ + this->privateData->threadData->mutexLock.LockMutex(); + if(worker) + { + this->privateData->threadData->owner = worker; + } + this->privateData->threadData->callingThread = std::this_thread::get_id(); + this->privateData->threadData->msec = 0; + this->privateData->threadData->mutexLock.UnlockMutex(); + + return OYSTER_THREAD_ERROR_SUCCESS; +} +void OysterThread::Terminate() +{ + delete this->privateData->threadData->workerThread; + this->privateData->threadData->mutexLock.Reset(); + this->privateData->threadData->workerThread = 0; + this->privateData->threadData->callingThread = std::thread::id(); + this->privateData->threadData->msec = 0; + this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED; +} +void OysterThread::Wait() +{ + if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD) + { + return; + } + + if(this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id()) return; + + this->privateData->threadData->workerThread->join(); +} +void OysterThread::Wait(int msec) +{ + if(this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id()) return; + + std::this_thread::sleep_for(std::chrono::milliseconds(msec)); +} +OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other) +{ + this->privateData->threadData->workerThread->swap(*other->privateData->threadData->workerThread); + return OYSTER_THREAD_ERROR_SUCCESS; +} +bool OysterThread::IsActive() +{ + if (this->privateData->threadData->state == OYSTER_THREAD_STATE_RUNNING) + return true; + + return false; +} + \ No newline at end of file diff --git a/Code/Misc/Utilities-InlineImpl.h b/Code/Misc/Utilities-InlineImpl.h index dc047153..b8c4c6da 100644 --- a/Code/Misc/Utilities-InlineImpl.h +++ b/Code/Misc/Utilities-InlineImpl.h @@ -2,6 +2,7 @@ // Inline and template implementations for // the Utility Collection of Miscellanious Handy Functions // © Dan Andersson 2013 +// © Dennis Andersen 2013 TODO: Is this correct? ///////////////////////////////////////////////////////////////////// #ifndef UTILITIES_INLINE_IMPL_H @@ -149,8 +150,7 @@ namespace Utility return this->ownedArray != NULL; } - template - Type* UniqueArray::Release() + templateType* UniqueArray::Release() { Type *copy = this->ownedArray; this->ownedArray = NULL; @@ -162,6 +162,113 @@ namespace Utility { return this->operator bool(); } + + namespace SmartPointer + { + template + void StdSmartPointer::Destroy() + { + delete this->_rc; + this->_rc = NULL; + delete this->_ptr; + this->_ptr = NULL; + } + template StdSmartPointer::StdSmartPointer() + :_rc(0), _ptr(0) + { } + template StdSmartPointer::StdSmartPointer(T* p) + :_ptr(p) + { + this->_rc = new ReferenceCount(); + this->_rc->Incref(); + } + template StdSmartPointer::StdSmartPointer(const StdSmartPointer& d) + :_ptr(d._ptr), _rc(d._rc) + { + if(this->_rc) + this->_rc->Incref(); + } + template StdSmartPointer::~StdSmartPointer() + { + if (this->_rc && this->_rc->Decref() == 0) + { + Destroy(); + } + } + template StdSmartPointer& StdSmartPointer::operator= (const StdSmartPointer& p) + { + if (this != &p) + { + //Last to go? + if(this->_rc && this->_rc->Release() == 0) + { + //Call child specific + Destroy(); + } + + this->_ptr = p._ptr; + this->_rc = p._rc; + this->_rc->Add(); + } + return *this; + } + template StdSmartPointer& StdSmartPointer::operator= (T* p) + { + if (this->_ptr != p) + { + //Last to go? + if(this->_rc) + { + if(this->_rc->Decref() == 0) + { + //Call child specific + Destroy(); + this->_rc = new ReferenceCount(); + } + } + else + this->_rc = new ReferenceCount(); + + this->_ptr = p; + this->_rc->Incref(); + } + return *this; + } + template inline bool StdSmartPointer::operator== (const StdSmartPointer& d) + { + return d._ptr == this->_ptr; + } + template inline bool StdSmartPointer::operator== (const T& p) + { + return &p == this->_ptr; + } + template inline T& StdSmartPointer::operator* () + { + return *this->_ptr; + } + template inline T* StdSmartPointer::operator-> () + { + return this->_ptr; + } + template inline StdSmartPointer::operator T* () + { + return this->_ptr; + } + + /** + * Returns the connected pointer */ + template inline T* StdSmartPointer::Get() + { + return this->_ptr; + } + + /** Checks if the pointer is valid (not NULL) + Returns true for valid, else false. */ + template inline bool StdSmartPointer::IsValid() + { + return (this->_ptr != NULL) ? true : false; + } + } } } diff --git a/Code/Misc/Utilities.h b/Code/Misc/Utilities.h index 6a48ad7e..e5ef5778 100644 --- a/Code/Misc/Utilities.h +++ b/Code/Misc/Utilities.h @@ -1,7 +1,8 @@ //!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//! // Utility Collection of Miscellanious Handy Functions // © Dan Andersson 2013 -//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//! +// © Dennis Andersen 2013 + #ifndef UTILITIES_H #define UTILITIES_H @@ -106,20 +107,62 @@ namespace Utility mutable Type *ownedArray; }; - struct RefCount + struct ReferenceCount { private: int count; public: - RefCount() :count(0) { } - RefCount(const RefCount& o) { count = o.count; } - const RefCount& operator=(const RefCount& o) { count = o.count; return *this;} - void Incref() { this->count++; } - void Incref(int c) { this->count += c; } - int Decref() { return --this->count;} - void Reset() { this->count = 0; } + ReferenceCount() :count(0) { } + ReferenceCount(const ReferenceCount& o) { count = o.count; } + inline const ReferenceCount& operator=(const ReferenceCount& o) { count = o.count; return *this;} + inline void Incref() { this->count++; } + inline void Incref(int c) { this->count += c; } + inline int Decref() { return --this->count;} + inline void Reset() { this->count = 0; } }; + + namespace SmartPointer + { + //! Smart pointer for a regular object. + /** + * Regular objects, objects that is deleted normaly (ie not COM objects, or array pointers) + * can use this class to easy the use of dynamic memory + */ + template + struct StdSmartPointer + { + private: + ReferenceCount *_rc; + T *_ptr; + + /** Destroys the pointer and returns the memory allocated. */ + void Destroy(); + + public: + StdSmartPointer(); + StdSmartPointer(T* p); + StdSmartPointer(const StdSmartPointer& d); + virtual~StdSmartPointer(); + StdSmartPointer& operator= (const StdSmartPointer& p); + StdSmartPointer& operator= (T* p); + bool operator== (const StdSmartPointer& d); + bool operator== (const T& p); + T& operator* (); + T* operator-> (); + operator T* (); + + /** + * Returns the connected pointer */ + T* Get(); + + /** Checks if the pointer is valid (not NULL) + Returns true for valid, else false. */ + bool IsValid(); + }; + } + + } namespace String diff --git a/Code/Misc/Utilities.h.orig b/Code/Misc/Utilities.h.orig new file mode 100644 index 00000000..6d3e801b --- /dev/null +++ b/Code/Misc/Utilities.h.orig @@ -0,0 +1,319 @@ +//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//! +// Utility Collection of Miscellanious Handy Functions +// © Dan Andersson 2013 +<<<<<<< HEAD +//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//! +======= +// © Dennis Andersen 2013 +///////////////////////////////////////////////////////////////////// +>>>>>>> 48c812b0338b859aa6c00c8504dd2f16a4bb44f9 + +#ifndef UTILITIES_H +#define UTILITIES_H + +#include +#include +#include +#include +#include + +namespace Utility +{ + namespace DynamicMemory + { + //! If dynamicInstance is not NULL, then delete + template void SafeDeleteInstance( Type *dynamicInstance ); + + //! If dynamicArray is not NULL, then delete [] + template void SafeDeleteArray( Type dynamicArray[] ); + + //! Wrapper to safely transfer dynamic ownership/responsibility + template struct UniquePointer + { + public: + //! Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. + //! If NULL is assigned is equavalent with clearing all responsibilities from this UniquePointer. + UniquePointer( Type *assignedInstance = NULL ); + + //! Will auto delete assigned dynamic instance. + ~UniquePointer(); + + //! Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted. + //! If NULL is assigned is equavalent with clearing all responsibilities from this UniquePointer. + UniquePointer & operator = ( Type *assignedInstance ); + + //! Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted. + //! If donor had nothing, is equavalent with clearing all responsibilities from this UniquePointer. + UniquePointer & operator = ( const UniquePointer &donor ); + + //! Access the assigned dynamic instance. Will crash if nothing there + operator Type* (); + + //! Access the assigned dynamic instance. Will crash if nothing there + operator const Type* () const; + + //! Access members of the assigned dynamic instance. Will crash if nothing there + Type * operator -> (); + + //! Access members of the assigned dynamic instance. Will crash if nothing there + const Type * operator -> () const; + + //! If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. + operator bool () const; + + //! This UniquePointer drops all claims of ownership/responsibility and returns the dynamic instance. Now it is your responsibility to delete. + Type* Release(); + + //! (inline) If true, this UniquePointer have a current ownership/responsibility of a dynamic instance. + bool HaveOwnership() const; + + private: + mutable Type *ownedInstance; + }; + + template + struct UniqueArray + { //! Wrapper to safely transfer dynamic ownership/responsibility + public: + //! Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. + //! If NULL is assigned is equavalent with clearing all responsibilities from this UniqueArray. + UniqueArray( Type assignedArray[] = NULL ); + + //! Will auto delete assigned dynamic array. + ~UniqueArray(); + + //! Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted. + //! If NULL is assigned is equavalent with clearing all responsibilities from this UniqueArray. + UniqueArray & operator = ( Type assignedArray[] ); + + //! Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted. + //! If donor had nothing, is equavalent with clearing all responsibilities from this UniqueArray. + UniqueArray & operator = ( const UniqueArray &donor ); + + //! Accesses the instance at index i of this UniqeArray's owned dynamic array. + //! Will crash if out-of-bound or there is no assigned array. + template Type & operator [] ( Index i ); + + //! Accesses the instance at index i of this UniqeArray's owned dynamic array. + //! Will crash if out-of-bound or there is no assigned array. + template const Type & operator [] ( Index i ) const; + + //! If true, this UniqueArray have a current ownership/responsibility of a dynamic instance. + operator bool () const; + + //! This UniqueArray drops all claims of ownership/responsibility and returns the dynamic array. Now it is your responsibility to delete. + Type* Release(); + + //! (inline) If true, this UniqueArray have a current ownership/responsibility of a dynamic array. + bool HaveOwnership() const; + + private: + mutable Type *ownedArray; + }; + + struct ReferenceCount + { + private: + int count; + + public: + ReferenceCount() :count(0) { } + ReferenceCount(const ReferenceCount& o) { count = o.count; } + inline const ReferenceCount& operator=(const ReferenceCount& o) { count = o.count; return *this;} + inline void Incref() { this->count++; } + inline void Incref(int c) { this->count += c; } + inline int Decref() { return --this->count;} + inline void Reset() { this->count = 0; } + }; + + namespace SmartPointer + { + //! Smart pointer for a regular object. + /** + * Regular objects, objects that is deleted normaly (ie not COM objects, or array pointers) + * can use this class to easy the use of dynamic memory + */ + template + struct StdSmartPointer + { + private: + ReferenceCount *_rc; + T *_ptr; + + /** Destroys the pointer and returns the memory allocated. */ + void Destroy(); + + public: + StdSmartPointer(); + StdSmartPointer(T* p); + StdSmartPointer(const StdSmartPointer& d); + virtual~StdSmartPointer(); + StdSmartPointer& operator= (const StdSmartPointer& p); + StdSmartPointer& operator= (T* p); + bool operator== (const StdSmartPointer& d); + bool operator== (const T& p); + T& operator* (); + T* operator-> (); + operator T* (); + + /** + * Returns the connected pointer */ + T* Get(); + + /** Checks if the pointer is valid (not NULL) + Returns true for valid, else false. */ + bool IsValid(); + }; + } + + + } + + namespace String + { + // string + + ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, char delim, ::std::string::size_type offset = 0 ); + ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::string &delim, ::std::string::size_type offset = 0 ); + ::std::vector<::std::string> & Split( ::std::vector<::std::string> &output, const ::std::string &str, const ::std::vector<::std::string> &delim, ::std::string::size_type offset = 0 ); + ::std::string Trim( const ::std::string &str ); + ::std::string & ToLowerCase( ::std::string &output, const ::std::string &str ); + ::std::string & ToLowerCase( ::std::string &str ); + ::std::string & ToUpperCase( ::std::string &output, const ::std::string &str ); + ::std::string & ToUpperCase( ::std::string &str ); + ::std::string & ExtractDirPath( ::std::string &output, const ::std::string &file, char dirDelimeter ); + ::std::string & ExtractDirPath( ::std::string &output, const ::std::string &file, const ::std::string &dirDelimeter ); + ::std::string & ReplaceCharacters( ::std::string &str, char characterToReplace, char newCharacter, const ::std::string::size_type &offset = 0, const ::std::string::size_type &end = ::std::string::npos ); + + // wstring + + ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, char delim, ::std::wstring::size_type offset = 0 ); + ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, const ::std::wstring &delim, ::std::wstring::size_type offset = 0 ); + ::std::vector<::std::wstring> & Split( ::std::vector<::std::wstring> &output, const ::std::wstring &str, const ::std::vector<::std::wstring> &delim, ::std::wstring::size_type offset = 0 ); + ::std::wstring & wToLowerCase( ::std::wstring &output, const ::std::wstring &str ); + ::std::wstring & wToLowerCase( ::std::wstring &str ); + + //To wstring + + ::std::wstring & StringToWstring( const ::std::string &str, ::std::wstring &wstr ); + ::std::string & WStringToString( const ::std::wstring &wstr, ::std::string &str ); + } + + namespace Stream + { + float* ReadFloats( float *output, ::std::istream &input, unsigned int numFloats ); + } + + namespace StaticArray + { + template + inline unsigned int NumElementsOf( const ScalarType(&)[num] ) + { return num; } + + template + inline ScalarType & FirstElementOf( ScalarType (&arr)[num] ) + { return arr[0]; } + + template + inline ScalarType & LastElementOf( ScalarType (&arr)[num] ) + { return arr[num-1]; } + } + + namespace Element + { + template + inline void Swap( ScalarType &elementA, ScalarType &elementB, ScalarType &swapSpace ) + { swapSpace = elementA; elementA = elementB; elementB = swapSpace; } + + template + inline void Swap( ScalarType &elementA, ScalarType &elementB ) + { ScalarType swapSpace; Swap( elementA, elementB, swapSpace ); } + } + + namespace Value + { + using ::std::numeric_limits; + + template + inline ValueType Abs( const ValueType &value ) + { return value < 0 ? value * -1 : value; } + + template + inline ValueType Max( const ValueType &valueA, const ValueType &valueB ) + { return valueA > valueB ? valueA : valueB; } + + template + inline ValueType Min( const ValueType &valueA, const ValueType &valueB ) + { return valueA < valueB ? valueA : valueB; } + + template + inline ValueType Average( const ValueType &valueA, const ValueType &valueB ) + { return (valueA + valueB) * 0.5f; } + + template + inline ValueType AverageWithDelta( const ValueType &origin, const ValueType &delta ) + { return origin + (delta * 0.5f); } + + template + inline ValueType Radian( const ValueType °ree ) + { return degree * (3.1415926535897932384626433832795f / 180.0f); } + + template + inline ValueType Degree( const ValueType &radian ) + { return radian * (180.0f / 3.1415926535897932384626433832795f); } + + // SPECIALIZATIONS //!//!//!//!//!//!//!//!//!//!//!//!//!//! + + template<> inline char Average( const char &valueA, const char &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline unsigned char Average( const unsigned char &valueA, const unsigned char &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline int Average( const int &valueA, const int &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline unsigned int Average( const unsigned int &valueA, const unsigned int &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline long Average( const long &valueA, const long &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline unsigned long Average( const unsigned long &valueA, const unsigned long &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline long long Average( const long long &valueA, const long long &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline unsigned long long Average( const unsigned long long &valueA, const unsigned long long &valueB ) + { return (valueA + valueB) >> 1; } + + template<> inline char AverageWithDelta( const char &origin, const char &delta ) + { return origin + (delta >> 1); } + + template<> inline unsigned char AverageWithDelta( const unsigned char &origin, const unsigned char &delta ) + { return origin + (delta >> 1); } + + template<> inline int AverageWithDelta( const int &origin, const int &delta ) + { return origin + (delta >> 1); } + + template<> inline unsigned int AverageWithDelta( const unsigned int &origin, const unsigned int &delta ) + { return origin + (delta >> 1); } + + template<> inline long AverageWithDelta( const long &origin, const long &delta ) + { return origin + (delta >> 1); } + + template<> inline unsigned long AverageWithDelta( const unsigned long &origin, const unsigned long &delta ) + { return origin + (delta >> 1); } + + template<> inline long long AverageWithDelta( const long long &origin, const long long &delta ) + { return origin + (delta >> 1); } + + template<> inline unsigned long long AverageWithDelta( const unsigned long long &origin, const unsigned long long &delta ) + { return origin + (delta >> 1); } + } +} + +#include "Utilities-InlineImpl.h" + +#endif \ No newline at end of file diff --git a/Code/OysterGraphics/Core/Core.h b/Code/OysterGraphics/Core/Core.h index 4efb5b8d..a270dd35 100644 --- a/Code/OysterGraphics/Core/Core.h +++ b/Code/OysterGraphics/Core/Core.h @@ -159,7 +159,7 @@ namespace Oyster Compute }; - static void SetShaderEffect(ShaderEffect); + static void SetShaderEffect(ShaderEffect&); static void CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *desc, int ElementCount,int VertexIndex,ID3D11InputLayout *&Layout); diff --git a/Code/OysterGraphics/Core/ShaderManager.cpp b/Code/OysterGraphics/Core/ShaderManager.cpp index 0b0c4fba..9789e199 100644 --- a/Code/OysterGraphics/Core/ShaderManager.cpp +++ b/Code/OysterGraphics/Core/ShaderManager.cpp @@ -328,7 +328,7 @@ namespace Oyster /// \todo smart Set ie. not resetting the shader /// \todo research states /// \todo smart buffer set - void Core::ShaderManager::SetShaderEffect(ShaderEffect se) + void Core::ShaderManager::SetShaderEffect(ShaderEffect& se) { Set::Pixel(se.Shaders.Pixel); Set::Vertex(se.Shaders.Vertex); diff --git a/Code/OysterGraphics/FileLoader/ObjReader.cpp b/Code/OysterGraphics/FileLoader/ObjReader.cpp index aa613710..116c8245 100644 --- a/Code/OysterGraphics/FileLoader/ObjReader.cpp +++ b/Code/OysterGraphics/FileLoader/ObjReader.cpp @@ -117,9 +117,11 @@ Oyster::Graphics::Model::ModelInfo* OBJReader::toModel() modelInfo->Indexed = false; modelInfo->VertexCount = (int)desc.NumElements; modelInfo->Vertices = b; + + Oyster::Resource::OHRESOURCE diffuse = Oyster::Resource::OysterResource::LoadResource(L"bth.png",Oyster::Graphics::Loading::LoadTexture); //Oyster::Resource::OysterResource::LoadResource(L"Normal.png",(Oyster::Resource::CustomLoadFunction)Oyster::Graphics::Loading::LoadTexture); - + modelInfo->Material.push_back((ID3D11ShaderResourceView*)diffuse); return modelInfo; } diff --git a/Code/OysterGraphics/FileLoader/TextureLoader.cpp b/Code/OysterGraphics/FileLoader/TextureLoader.cpp index 24caeae3..0937a706 100644 --- a/Code/OysterGraphics/FileLoader/TextureLoader.cpp +++ b/Code/OysterGraphics/FileLoader/TextureLoader.cpp @@ -1,7 +1,729 @@ #include "TextureLoader.h" #include "..\Core\Dx11Includes.h" +#include "..\Core\Core.h" -Oyster::Resource::CustomData* Oyster::Graphics::Loading::LoadTexture() +HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, + const wchar_t* fileName, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView ); + +const Oyster::Resource::CustomData& Oyster::Graphics::Loading::LoadTexture(const wchar_t filename[]) { - return NULL; + ID3D11ShaderResourceView* srv; + Oyster::Resource::CustomData Ret; + HRESULT hr = CreateWICTextureFromFileEx(Core::device,Core::deviceContext,filename,0,D3D11_USAGE_DEFAULT,D3D11_BIND_SHADER_RESOURCE,0,0,false,NULL,&srv); + if(hr!=S_OK) + { + memset(&Ret,0,sizeof(Ret)); + } + else + { + Ret.loadedData = srv; + Ret.resourceUnloadFnc = Loading::UnloadTexture; + } + + return Ret; +} + +void Oyster::Graphics::Loading::UnloadTexture(void* data) +{ + ID3D11ShaderResourceView* srv = (ID3D11ShaderResourceView*)data; + SAFE_RELEASE(srv); +} + + +#include +#include +#include + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) +#include +#endif + +#pragma warning(push) +#pragma warning(disable : 4005) +#include +#pragma warning(pop) + + +template class ScopedObject : public Microsoft::WRL::ComPtr {}; + +//------------------------------------------------------------------------------------- +// WIC Pixel Format Translation Data +//------------------------------------------------------------------------------------- +struct WICTranslate +{ + GUID wic; + DXGI_FORMAT format; +}; + +static WICTranslate g_WICFormats[] = +{ + { GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT }, + + { GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT }, + { GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM }, + + { GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM }, + { GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM }, // DXGI 1.1 + { GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM }, // DXGI 1.1 + + { GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, // DXGI 1.1 + { GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM }, + +#ifdef DXGI_1_2_FORMATS + + { GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM }, + { GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM }, + +#endif // DXGI_1_2_FORMATS + + { GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT }, + { GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT }, + { GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM }, + { GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM }, + + { GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM }, +}; + +//------------------------------------------------------------------------------------- +// WIC Pixel Format nearest conversion table +//------------------------------------------------------------------------------------- + +struct WICConvert +{ + GUID source; + GUID target; +}; + +static WICConvert g_WICConvert[] = +{ + // Note target GUID in this conversion table must be one of those directly supported formats (above). + + { GUID_WICPixelFormatBlackWhite, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM + + { GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + + { GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM + { GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM + + { GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT + { GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT + +#ifdef DXGI_1_2_FORMATS + + { GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM + +#else + + { GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat16bppBGRA5551, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat16bppBGR565, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + +#endif // DXGI_1_2_FORMATS + + { GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM + + { GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + + { GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + + { GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + { GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT + + { GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + { GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + { GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + { GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + { GUID_WICPixelFormat32bppRGBE, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT + + { GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + { GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM + { GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM + { GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT +#endif + + // We don't support n-channel formats +}; + +static bool g_WIC2 = false; + +//-------------------------------------------------------------------------------------- + +bool _IsWIC2() +{ + return g_WIC2; +} + +IWICImagingFactory* _GetWIC() +{ + static IWICImagingFactory* s_Factory = nullptr; + + if ( s_Factory ) + return s_Factory; + +#if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + HRESULT hr = CoCreateInstance( + CLSID_WICImagingFactory2, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory2), + (LPVOID*)&s_Factory + ); + + if ( SUCCEEDED(hr) ) + { + // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed + g_WIC2 = true; + } + else + { + hr = CoCreateInstance( + CLSID_WICImagingFactory1, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory), + (LPVOID*)&s_Factory + ); + + if ( FAILED(hr) ) + { + s_Factory = nullptr; + return nullptr; + } + } +#else + HRESULT hr = CoCreateInstance( + CLSID_WICImagingFactory, + nullptr, + CLSCTX_INPROC_SERVER, + __uuidof(IWICImagingFactory), + (LPVOID*)&s_Factory + ); + + if ( FAILED(hr) ) + { + s_Factory = nullptr; + return nullptr; + } +#endif + + return s_Factory; +} + + +//--------------------------------------------------------------------------------- +static DXGI_FORMAT _WICToDXGI( const GUID& guid ) +{ + for( size_t i=0; i < _countof(g_WICFormats); ++i ) + { + if ( memcmp( &g_WICFormats[i].wic, &guid, sizeof(GUID) ) == 0 ) + return g_WICFormats[i].format; + } + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + if ( g_WIC2 ) + { + if ( memcmp( &GUID_WICPixelFormat96bppRGBFloat, &guid, sizeof(GUID) ) == 0 ) + return DXGI_FORMAT_R32G32B32_FLOAT; + } +#endif + + return DXGI_FORMAT_UNKNOWN; +} + +//--------------------------------------------------------------------------------- +static size_t _WICBitsPerPixel( REFGUID targetGuid ) +{ + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return 0; + + ScopedObject cinfo; + if ( FAILED( pWIC->CreateComponentInfo( targetGuid, &cinfo ) ) ) + return 0; + + WICComponentType type; + if ( FAILED( cinfo->GetComponentType( &type ) ) ) + return 0; + + if ( type != WICPixelFormat ) + return 0; + + Microsoft::WRL::ComPtr pfinfo; + if ( FAILED( cinfo.As( &pfinfo ) ) ) + return 0; + + UINT bpp; + if ( FAILED( pfinfo->GetBitsPerPixel( &bpp ) ) ) + return 0; + + return bpp; +} + + +//-------------------------------------------------------------------------------------- +static DXGI_FORMAT MakeSRGB( _In_ DXGI_FORMAT format ) +{ + switch( format ) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + + case DXGI_FORMAT_BC1_UNORM: + return DXGI_FORMAT_BC1_UNORM_SRGB; + + case DXGI_FORMAT_BC2_UNORM: + return DXGI_FORMAT_BC2_UNORM_SRGB; + + case DXGI_FORMAT_BC3_UNORM: + return DXGI_FORMAT_BC3_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8A8_UNORM: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8X8_UNORM: + return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + case DXGI_FORMAT_BC7_UNORM: + return DXGI_FORMAT_BC7_UNORM_SRGB; + + default: + return format; + } +} + +static HRESULT CreateTextureFromWIC( _In_ ID3D11Device* d3dDevice, + _In_opt_ ID3D11DeviceContext* d3dContext, + _In_ IWICBitmapFrameDecode *frame, + _In_ size_t maxsize, + _In_ D3D11_USAGE usage, + _In_ unsigned int bindFlags, + _In_ unsigned int cpuAccessFlags, + _In_ unsigned int miscFlags, + _In_ bool forceSRGB, + _Out_opt_ ID3D11Resource** texture, + _Out_opt_ ID3D11ShaderResourceView** textureView ) +{ + UINT width, height; + HRESULT hr = frame->GetSize( &width, &height ); + if ( FAILED(hr) ) + return hr; + + assert( width > 0 && height > 0 ); + + if ( !maxsize ) + { + // This is a bit conservative because the hardware could support larger textures than + // the Feature Level defined minimums, but doing it this way is much easier and more + // performant for WIC than the 'fail and retry' model used by DDSTextureLoader + + switch( d3dDevice->GetFeatureLevel() ) + { + case D3D_FEATURE_LEVEL_9_1: + case D3D_FEATURE_LEVEL_9_2: + maxsize = 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + break; + + case D3D_FEATURE_LEVEL_9_3: + maxsize = 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + break; + + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_10_1: + maxsize = 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/; + break; + + default: + maxsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + break; + } + } + + assert( maxsize > 0 ); + + UINT twidth, theight; + if ( width > maxsize || height > maxsize ) + { + float ar = static_cast(height) / static_cast(width); + if ( width > height ) + { + twidth = static_cast( maxsize ); + theight = static_cast( static_cast(maxsize) * ar ); + } + else + { + theight = static_cast( maxsize ); + twidth = static_cast( static_cast(maxsize) / ar ); + } + assert( twidth <= maxsize && theight <= maxsize ); + } + else + { + twidth = width; + theight = height; + } + + // Determine format + WICPixelFormatGUID pixelFormat; + hr = frame->GetPixelFormat( &pixelFormat ); + if ( FAILED(hr) ) + return hr; + + WICPixelFormatGUID convertGUID; + memcpy( &convertGUID, &pixelFormat, sizeof(WICPixelFormatGUID) ); + + size_t bpp = 0; + + DXGI_FORMAT format = _WICToDXGI( pixelFormat ); + if ( format == DXGI_FORMAT_UNKNOWN ) + { + if ( memcmp( &GUID_WICPixelFormat96bppRGBFixedPoint, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) + { +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + if ( g_WIC2 ) + { + memcpy( &convertGUID, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R32G32B32_FLOAT; + } + else +#endif + { + memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R32G32B32A32_FLOAT; + } + } + else + { + for( size_t i=0; i < _countof(g_WICConvert); ++i ) + { + if ( memcmp( &g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 ) + { + memcpy( &convertGUID, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) ); + + format = _WICToDXGI( g_WICConvert[i].target ); + assert( format != DXGI_FORMAT_UNKNOWN ); + bpp = _WICBitsPerPixel( convertGUID ); + break; + } + } + } + + if ( format == DXGI_FORMAT_UNKNOWN ) + return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); + } + else + { + bpp = _WICBitsPerPixel( pixelFormat ); + } + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) || defined(_WIN7_PLATFORM_UPDATE) + if ( (format == DXGI_FORMAT_R32G32B32_FLOAT) && d3dContext != 0 && textureView != 0 ) + { + // Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT + UINT fmtSupport = 0; + hr = d3dDevice->CheckFormatSupport( DXGI_FORMAT_R32G32B32_FLOAT, &fmtSupport ); + if ( FAILED(hr) || !( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) + { + // Use R32G32B32A32_FLOAT instead which is required for Feature Level 10.0 and up + memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R32G32B32A32_FLOAT; + bpp = 128; + } + } +#endif + + if ( !bpp ) + return E_FAIL; + + // Handle sRGB formats + if ( forceSRGB ) + { + format = MakeSRGB( format ); + } + else + { + ScopedObject metareader; + if ( SUCCEEDED( frame->GetMetadataQueryReader( &metareader ) ) ) + { + GUID containerFormat; + if ( SUCCEEDED( metareader->GetContainerFormat( &containerFormat ) ) ) + { + // Check for sRGB colorspace metadata + bool sRGB = false; + + PROPVARIANT value; + PropVariantInit( &value ); + + if ( memcmp( &containerFormat, &GUID_ContainerFormatPng, sizeof(GUID) ) == 0 ) + { + // Check for sRGB chunk + if ( SUCCEEDED( metareader->GetMetadataByName( L"/sRGB/RenderingIntent", &value ) ) && value.vt == VT_UI1 ) + { + sRGB = true; + } + } + else if ( SUCCEEDED( metareader->GetMetadataByName( L"System.Image.ColorSpace", &value ) ) && value.vt == VT_UI2 && value.uiVal == 1 ) + { + sRGB = true; + } + + PropVariantClear( &value ); + + if ( sRGB ) + format = MakeSRGB( format ); + } + } + } + + // Verify our target format is supported by the current device + // (handles WDDM 1.0 or WDDM 1.1 device driver cases as well as DirectX 11.0 Runtime without 16bpp format support) + UINT support = 0; + hr = d3dDevice->CheckFormatSupport( format, &support ); + if ( FAILED(hr) || !(support & D3D11_FORMAT_SUPPORT_TEXTURE2D) ) + { + // Fallback to RGBA 32-bit format which is supported by all devices + memcpy( &convertGUID, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID) ); + format = DXGI_FORMAT_R8G8B8A8_UNORM; + bpp = 32; + } + + // Allocate temporary memory for image + size_t rowPitch = ( twidth * bpp + 7 ) / 8; + size_t imageSize = rowPitch * theight; + + std::unique_ptr temp( new (std::nothrow) uint8_t[ imageSize ] ); + if (!temp) + return E_OUTOFMEMORY; + + // Load image data + if ( memcmp( &convertGUID, &pixelFormat, sizeof(GUID) ) == 0 + && twidth == width + && theight == height ) + { + // No format conversion or resize needed + hr = frame->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); + if ( FAILED(hr) ) + return hr; + } + else if ( twidth != width || theight != height ) + { + // Resize + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + ScopedObject scaler; + hr = pWIC->CreateBitmapScaler( &scaler ); + if ( FAILED(hr) ) + return hr; + + hr = scaler->Initialize( frame, twidth, theight, WICBitmapInterpolationModeFant ); + if ( FAILED(hr) ) + return hr; + + WICPixelFormatGUID pfScaler; + hr = scaler->GetPixelFormat( &pfScaler ); + if ( FAILED(hr) ) + return hr; + + if ( memcmp( &convertGUID, &pfScaler, sizeof(GUID) ) == 0 ) + { + // No format conversion needed + hr = scaler->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); + if ( FAILED(hr) ) + return hr; + } + else + { + ScopedObject FC; + hr = pWIC->CreateFormatConverter( &FC ); + if ( FAILED(hr) ) + return hr; + + hr = FC->Initialize( scaler.Get(), convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom ); + if ( FAILED(hr) ) + return hr; + + hr = FC->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); + if ( FAILED(hr) ) + return hr; + } + } + else + { + // Format conversion but no resize + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + ScopedObject FC; + hr = pWIC->CreateFormatConverter( &FC ); + if ( FAILED(hr) ) + return hr; + + hr = FC->Initialize( frame, convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom ); + if ( FAILED(hr) ) + return hr; + + hr = FC->CopyPixels( 0, static_cast( rowPitch ), static_cast( imageSize ), temp.get() ); + if ( FAILED(hr) ) + return hr; + } + + // See if format is supported for auto-gen mipmaps (varies by feature level) + bool autogen = false; + if ( d3dContext != 0 && textureView != 0 ) // Must have context and shader-view to auto generate mipmaps + { + UINT fmtSupport = 0; + hr = d3dDevice->CheckFormatSupport( format, &fmtSupport ); + if ( SUCCEEDED(hr) && ( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) + { + autogen = true; + } + } + + // Create texture + D3D11_TEXTURE2D_DESC desc; + desc.Width = twidth; + desc.Height = theight; + desc.MipLevels = (autogen) ? 0 : 1; + desc.ArraySize = 1; + desc.Format = format; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = usage; + desc.CPUAccessFlags = cpuAccessFlags; + + if ( autogen ) + { + desc.BindFlags = bindFlags | D3D11_BIND_RENDER_TARGET; + desc.MiscFlags = miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS; + } + else + { + desc.BindFlags = bindFlags; + desc.MiscFlags = miscFlags; + } + + D3D11_SUBRESOURCE_DATA initData; + initData.pSysMem = temp.get(); + initData.SysMemPitch = static_cast( rowPitch ); + initData.SysMemSlicePitch = static_cast( imageSize ); + + ID3D11Texture2D* tex = nullptr; + //Error with miscFlags Generate Mips + hr = d3dDevice->CreateTexture2D( &desc, (autogen) ? nullptr : &initData, &tex ); + /// Replace To get Texture Data + if ( SUCCEEDED(hr) && tex != 0 ) + { + if (textureView != 0) + { + D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + memset( &SRVDesc, 0, sizeof( SRVDesc ) ); + SRVDesc.Format = desc.Format; + + SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1; + + hr = d3dDevice->CreateShaderResourceView( tex, &SRVDesc, textureView ); + if ( FAILED(hr) ) + { + tex->Release(); + return hr; + } + + if ( autogen ) + { + assert( d3dContext != 0 ); + d3dContext->UpdateSubresource( tex, 0, nullptr, temp.get(), static_cast(rowPitch), static_cast(imageSize) ); + d3dContext->GenerateMips( *textureView ); + } + } + + if (texture != 0) + { + *texture = tex; + } + else + { + //SetDebugObjectName(tex, "WICTextureLoader"); + tex->Release(); + } + } + + return hr; +} + +HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice, + ID3D11DeviceContext* d3dContext, + const wchar_t* fileName, + size_t maxsize, + D3D11_USAGE usage, + unsigned int bindFlags, + unsigned int cpuAccessFlags, + unsigned int miscFlags, + bool forceSRGB, + ID3D11Resource** texture, + ID3D11ShaderResourceView** textureView ) +{ + if ( texture ) + { + *texture = nullptr; + } + if ( textureView ) + { + *textureView = nullptr; + } + + if (!d3dDevice || !fileName || (!texture && !textureView)) + return E_INVALIDARG; + + IWICImagingFactory* pWIC = _GetWIC(); + if ( !pWIC ) + return E_NOINTERFACE; + + // Initialize WIC + ScopedObject decoder; + HRESULT hr = pWIC->CreateDecoderFromFilename( fileName, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &decoder ); + if ( FAILED(hr) ) + return hr; + + ScopedObject frame; + hr = decoder->GetFrame( 0, &frame ); + if ( FAILED(hr) ) + return hr; + + hr = CreateTextureFromWIC( d3dDevice, d3dContext, frame.Get(), maxsize, + usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB, + texture, textureView ); + + return hr; } \ No newline at end of file diff --git a/Code/OysterGraphics/FileLoader/TextureLoader.h b/Code/OysterGraphics/FileLoader/TextureLoader.h index a5148fb4..bb096fec 100644 --- a/Code/OysterGraphics/FileLoader/TextureLoader.h +++ b/Code/OysterGraphics/FileLoader/TextureLoader.h @@ -6,8 +6,8 @@ namespace Oyster { namespace Loading { - void UnloadTexture(); - Oyster::Resource::CustomData* LoadTexture(); + void UnloadTexture(void* loadedData); + const Oyster::Resource::CustomData& LoadTexture(const wchar_t filename[]); } } } \ No newline at end of file diff --git a/Code/OysterGraphics/OysterGraphics.vcxproj b/Code/OysterGraphics/OysterGraphics.vcxproj index 5bf9ebf3..f084ffb2 100644 --- a/Code/OysterGraphics/OysterGraphics.vcxproj +++ b/Code/OysterGraphics/OysterGraphics.vcxproj @@ -223,9 +223,16 @@ + + Pixel + Pixel + Pixel + Pixel + + diff --git a/Code/OysterGraphics/OysterGraphics.vcxproj.filters b/Code/OysterGraphics/OysterGraphics.vcxproj.filters index 6525139a..2e96961c 100644 --- a/Code/OysterGraphics/OysterGraphics.vcxproj.filters +++ b/Code/OysterGraphics/OysterGraphics.vcxproj.filters @@ -87,8 +87,10 @@ + + \ No newline at end of file diff --git a/Code/OysterGraphics/Render/Resources/Resources.cpp b/Code/OysterGraphics/Render/Resources/Resources.cpp index 3ff3fa3c..d06145fa 100644 --- a/Code/OysterGraphics/Render/Resources/Resources.cpp +++ b/Code/OysterGraphics/Render/Resources/Resources.cpp @@ -7,6 +7,7 @@ const std::wstring PathFromExeToHlsl = L"..\\..\\..\\Code\\OysterGraphics\\Shade const std::wstring VertexTransformDebug = L"TransformDebugVertex"; const std::wstring VertexDebug = L"DebugVertex"; const std::wstring PixelRed = L"DebugPixel"; +const std::wstring PixelTexture = L"Texture"; typedef Oyster::Graphics::Core::ShaderManager::ShaderType ShaderType; typedef Oyster::Graphics::Core::ShaderManager::Get GetShader; @@ -19,7 +20,7 @@ namespace Oyster { namespace Render { - Shader::ShaderEffect Resources::obj; + Shader::ShaderEffect Resources::obj;// = Shader::ShaderEffect();; Buffer Resources::ModelData = Buffer(); Buffer Resources::VPData = Buffer(); @@ -36,6 +37,8 @@ namespace Oyster /** Load Pixel Shader for d3dcompile */ Core::ShaderManager::Init(PathFromExeToHlsl + L"SimpleDebug\\" + L"DebugPixel.hlsl", ShaderType::Pixel, PixelRed, false); + Core::ShaderManager::Init(PathFromExeToHlsl + L"SimpleDebug\\" + L"TextureDebug.hlsl", ShaderType::Pixel, PixelTexture, false); + #else /** Load Vertex Shader with Precompiled */ @@ -75,6 +78,23 @@ namespace Oyster ID3D11RasterizerState* rs = NULL; Oyster::Graphics::Core::device->CreateRasterizerState(&rdesc,&rs); + + D3D11_SAMPLER_DESC sdesc; + sdesc.Filter = D3D11_FILTER_ANISOTROPIC; + /// @todo parata med fredrik om wraping + sdesc.AddressU = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; + sdesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + sdesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER; + sdesc.MipLODBias = 0; + sdesc.MaxAnisotropy =4; + sdesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + *sdesc.BorderColor = *Oyster::Math::Float4(0,0,0,1).element; + sdesc.MinLOD = 0; + sdesc.MaxLOD = D3D11_FLOAT32_MAX; + + ID3D11SamplerState** ss = new ID3D11SamplerState*[1]; + Oyster::Graphics::Core::device->CreateSamplerState(&sdesc,ss); + #pragma endregion #pragma region Setup Views @@ -84,7 +104,7 @@ namespace Oyster #pragma region Create Shader Effects /** @todo Create ShaderEffects */ obj.Shaders.Pixel = GetShader::Pixel(PixelRed); - obj.Shaders.Vertex = GetShader::Vertex(VertexTransformDebug); + obj.Shaders.Vertex = GetShader::Vertex(VertexDebug); D3D11_INPUT_ELEMENT_DESC indesc[] = { @@ -98,6 +118,8 @@ namespace Oyster obj.IAStage.Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; obj.CBuffers.Vertex.push_back(&VPData); obj.RenderStates.Rasterizer = rs; + obj.RenderStates.SampleCount = 1; + obj.RenderStates.SampleState = ss; ModelData.Apply(1); #pragma endregion diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GatherGBuffer/GBufferHeader.hlsli b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GatherGBuffer/GBufferHeader.hlsli index d39f6ae5..3aaed031 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GatherGBuffer/GBufferHeader.hlsli +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GatherGBuffer/GBufferHeader.hlsli @@ -28,6 +28,8 @@ struct PixelOut Texture2D Diffuse : register(t0); Texture2D Specular : register(t1); +SamplerState Sampler : register(s0); + cbuffer PerFrame : register(b0) { matrix View; diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GatherGBuffer/PixelGatherData.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GatherGBuffer/PixelGatherData.hlsl index 61f0e20f..b43db0c1 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GatherGBuffer/PixelGatherData.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/GatherGBuffer/PixelGatherData.hlsl @@ -3,7 +3,7 @@ PixelOut main(VertexOut input) { PixelOut output; - output.DiffuseGlow = float4(1.0f, 0.0f, 0.0f, 1.0f); + output.DiffuseGlow = Diffuse.Sample(Sampler, input.UV); output.NormalSpec = float4(input.normal, 1.0f); return output; } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/SimpleDebug/Debug.hlsli b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/Debug.hlsli new file mode 100644 index 00000000..9e66825e --- /dev/null +++ b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/Debug.hlsli @@ -0,0 +1,25 @@ +cbuffer PerFrame : register(b0) +{ + matrix View; + float4x4 Projection; +} + +cbuffer PerModel : register(b1) +{ + matrix World; +} + +struct VertexIn +{ + float3 pos : POSITION; + float2 UV : TEXCOORD; + float3 normal : NORMAL; +}; + +struct VertexOut +{ + float4 Pos : SV_POSITION; + float2 UV : TEXCOORD; + float3 Normal : NORMAL; + float4 Wpos : POSITION; +}; \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugCameraVertex.hlsl b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugCameraVertex.hlsl index 76e7dbed..93145d1c 100644 --- a/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugCameraVertex.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugCameraVertex.hlsl @@ -1,28 +1,13 @@ -cbuffer PerFrame : register(b0) -{ - matrix View; - float4x4 Projection; -} +#include "Debug.hlsli" -cbuffer PerModel : register(b1) -{ - matrix World; -} -struct VertexIn +VertexOut main( VertexIn input ) { - float3 pos : POSITION; - float2 UV : TEXCOORD; - float3 normal : NORMAL; -}; - -float4 main( VertexIn input ) : SV_POSITION -{ - float4 postTransform = mul( World, float4(input.pos,1) ); - //float4 postTransform = float4(input.pos,1); - //return postTransform; - //return mul(View, float4(input.pos,1)); + VertexOut outp; + outp.Wpos = mul( World, float4(input.pos,1) ); matrix VP = mul(Projection, View); - //matrix WVP = mul(World, VP); - return mul(VP, postTransform ); + outp.Pos = mul(VP, outp.Wpos ); + outp.UV = input.UV; + outp.Normal = input.normal; + return outp; } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugPixel.hlsl b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugPixel.hlsl index 627d8592..49bc7450 100644 --- a/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugPixel.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugPixel.hlsl @@ -1,4 +1,6 @@ -float4 main() : SV_TARGET0 +#include "Debug.hlsli" + +float4 main() : SV_TARGET { return float4(1.0f, 0.0f, 0.0f, 1.0f); } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugVertex.hlsl b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugVertex.hlsl index 94efe039..9908555c 100644 --- a/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugVertex.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/DebugVertex.hlsl @@ -1,4 +1,4 @@ float4 main( float4 pos : POSITION ) : SV_POSITION { - return pos; + return pos*0.1f; } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/HLSL/SimpleDebug/TextureDebug.hlsl b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/TextureDebug.hlsl new file mode 100644 index 00000000..a489adbe --- /dev/null +++ b/Code/OysterGraphics/Shader/HLSL/SimpleDebug/TextureDebug.hlsl @@ -0,0 +1,9 @@ +#include "Debug.hlsli" + +Texture2D tex : register(t0); +SamplerState S1 : register(s0); + +float4 main(VertexOut inp) : SV_TARGET0 +{ + return tex.Sample(S1,inp.UV); +} \ No newline at end of file diff --git a/Code/Tester/MainTest.cpp b/Code/Tester/MainTest.cpp index 607ba3b4..dde166d7 100644 --- a/Code/Tester/MainTest.cpp +++ b/Code/Tester/MainTest.cpp @@ -201,6 +201,7 @@ HRESULT InitDirect3D() HRESULT Update(float deltaTime) { + m->WorldMatrix.m14 += 0.0001f; return S_OK; }