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;
}