Stable Resource Management with 4 unidentified Memory Leaks

This commit is contained in:
lanariel 2013-11-29 10:25:27 +01:00
commit ca20a5af9e
43 changed files with 1020 additions and 387 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Bin/DLL/LightPass.cso Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -152,7 +152,7 @@ OResource* OResource::ByteLoader(const wchar_t filename[], ResourceType type, OR
if(!old)
{
resource = new OResource((OHRESOURCE)data, type, (sizeof(char) * sOut.size()), sizeof(char), filename);
resource = new OResource((OHRESOURCE&)data, type, (sizeof(char) * sOut.size()), sizeof(char), filename);
}
else
{

View File

@ -12,34 +12,49 @@ using namespace Oyster::Resource;
OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc)
{
CustomData &data = fnc(filename);
CustomData data;
memset(&data, 0, sizeof(CustomData));
if(!data.loadedData) return 0;
if(!data.resourceUnloadFnc) return 0;
fnc(filename, data);
OHRESOURCE n = (OHRESOURCE)data.loadedData;
OResource *resource = new OResource(n, ResourceType_UNKNOWN, 0, 0, filename);
if(!data.loadedData)
{
return 0;
}
if(!data.resourceUnloadFnc)
{
return 0;
}
/** For some wierd reason that i don't understand when trying to send data.loadedData directly as a
* parameter to OResource constructor, the value is changed when it arrives in the constructor.
* Doing it like this, storing in a temporary variable, the value stays correct. (What the fuck! I must be overloking something...)*/
//OHRESOURCE temp = data.loadedData;
OResource *resource = new OResource(data.loadedData, ResourceType_UNKNOWN, 0, 0, filename);
resource->customData = new CustomResourceData();
resource->customData->unloadingFunction = data.resourceUnloadFnc;
//resource->resourceData = (OHRESOURCE)data.loadedData;
resource->customData->loadingFunction = fnc;
return resource;
}
void OResource::CustomUnloader()
{
this->customData->unloadingFunction((void*)this->resourceData);
this->customData->unloadingFunction(this->resourceData);
}
OResource* OResource::CustomReloader()
{
CustomUnloader();
const CustomData &data = this->customData->loadingFunction(this->resourceFilename.c_str());
CustomData data;
memset(&data, 0, sizeof(CustomData));
this->customData->loadingFunction(this->resourceFilename.c_str(), data);
this->resourceData = (OHRESOURCE)data.loadedData;
if(data.resourceUnloadFnc)
{
this->customData->unloadingFunction = data.resourceUnloadFnc;
}
return this;
}

View File

@ -0,0 +1,73 @@
/////////////////////////////////////////////////////////////////////
// Created by [Dennis Andersen] [2013]
/////////////////////////////////////////////////////////////////////
#include "..\OResource.h"
#include "..\..\Utilities.h"
#include <fstream>
using namespace Oyster::Resource;
OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc)
{
<<<<<<< HEAD
CustomData &data = fnc(filename);
if(!data.loadedData) return 0;
if(!data.resourceUnloadFnc) return 0;
OHRESOURCE n = (OHRESOURCE)data.loadedData;
OResource *resource = new OResource(n, ResourceType_UNKNOWN, 0, 0, filename);
resource->customData = new CustomResourceData();
resource->customData->unloadingFunction = data.resourceUnloadFnc;
//resource->resourceData = (OHRESOURCE)data.loadedData;
=======
CustomData data;
memset(&data, 0, sizeof(CustomData));
fnc(filename, data);
if(!data.loadedData)
{
return 0;
}
if(!data.resourceUnloadFnc)
{
return 0;
}
/** For some wierd reason that i don't understand when trying to send data.loadedData directly as a
* parameter to OResource constructor, the value is changed when it arrives in the constructor.
* Doing it like this, storing in a temporary variable, the value stays correct. (What the fuck! I must be overloking something...)*/
//OHRESOURCE temp = data.loadedData;
OResource *resource = new OResource(data.loadedData, ResourceType_UNKNOWN, 0, 0, filename);
resource->customData = new CustomResourceData();
resource->customData->unloadingFunction = data.resourceUnloadFnc;
>>>>>>> d08644e8e1ecc56f4d9dfa6a9aa33df94d9e655a
resource->customData->loadingFunction = fnc;
return resource;
}
void OResource::CustomUnloader()
{
this->customData->unloadingFunction(this->resourceData);
}
OResource* OResource::CustomReloader()
{
CustomUnloader();
CustomData data;
memset(&data, 0, sizeof(CustomData));
this->customData->loadingFunction(this->resourceFilename.c_str(), data);
this->resourceData = (OHRESOURCE)data.loadedData;
if(data.resourceUnloadFnc)
{
this->customData->unloadingFunction = data.resourceUnloadFnc;
}
return this;
}

View File

@ -7,17 +7,19 @@
using namespace Oyster::Resource;
OResource::OResource(OHRESOURCE handle, ResourceType type, size_t resourceSize, size_t elementSize, ::std::wstring filename)
: resourceData (handle)
, resourceFilename (filename)
: resourceFilename (filename)
, resourceSize (resourceSize)
, resourceElementSize (elementSize)
, resourceType (type)
, customData (0)
{
resourceData = handle;
}
OResource::~OResource()
{}
{
delete this->customData;
this->customData = 0;
}
OResource* OResource::Load (const wchar_t filename[], ResourceType type)

View File

@ -27,19 +27,33 @@ namespace Oyster
virtual~ OResource();
inline ResourceType GetResourceType() const
{ return this->resourceType; }
{
return this->resourceType;
}
inline const wchar_t* GetResourceFilename() const
{ return this->resourceFilename.c_str(); }
{
return this->resourceFilename.c_str();
}
inline OHRESOURCE GetResourceHandle() const
{ return this->resourceData; }
{
return this->resourceData;
}
inline unsigned long long GetResourceSize() const
{ return this->resourceSize; }
{
return this->resourceSize;
}
inline unsigned long long GetResourceElementSize() const
{ return this->resourceElementSize; }
{
return this->resourceElementSize;
}
inline unsigned int GetResourceID() const
{ return this->resourceID; }
inline void SetResourceID(unsigned int id)
{ this->resourceID = id; }
{
return this->resourceID;
}
inline void SetResourceID(int id)
{
this->resourceID = id;
}
public:
static OResource* Load (const wchar_t filename[], ResourceType type);
@ -63,7 +77,7 @@ namespace Oyster
size_t resourceSize;
size_t resourceElementSize;
::std::wstring resourceFilename;
unsigned int resourceID;
int resourceID;
CustomResourceData *customData;
};

View File

@ -23,58 +23,83 @@ public:
} resourcePrivate;
OHRESOURCE OysterResource::LoadResource(const wchar_t* filename, ResourceType type)
OHRESOURCE OysterResource::LoadResource(const wchar_t* filename, ResourceType type, int customID, bool force)
{
if(!filename) return 0;
OResource *resourceData = resourcePrivate.FindResource(filename);
if(resourceData)
{
if(force)
{
return OysterResource::ReloadResource(filename);
}
else
{
//Add new reference
resourcePrivate.SaveResource(resourceData, false);
return resourceData->GetResourceHandle();
}
}
else
{
resourceData = OResource::Load(filename, type);
if(!resourceData) return 0;
if(resourceData)
{
resourceData->SetResourceID(customID);
resourcePrivate.SaveResource(resourceData);
}
}
return resourceData->GetResourceHandle();
}
OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc, unsigned int CustomId)
OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc, int customId, bool force)
{
if(!filename) return 0;
if(!loadFnc) return 0;
if(!filename)
{
return 0;
}
if(!loadFnc)
{
return 0;
}
OResource *resourceData = resourcePrivate.FindResource(filename);
if(resourceData)
{
if(force)
{
return OysterResource::ReloadResource(filename);
}
else
{
//Add new reference
resourcePrivate.SaveResource(resourceData, false);
return resourceData->GetResourceHandle();
}
}
else
{
resourceData = OResource::Load(filename, loadFnc);
if(!resourceData) return 0;
resourceData->SetResourceID(CustomId);
if(resourceData)
{
resourceData->SetResourceID(customId);
resourcePrivate.SaveResource(resourceData);
}
}
return (OHRESOURCE)resourceData->GetResourceHandle();
}
OHRESOURCE ReloadResource(const wchar_t filename[])
OHRESOURCE OysterResource::ReloadResource(const wchar_t filename[])
{
OResource *resourceData = resourcePrivate.FindResource(filename);
if(!resourceData) return 0; //The resource has not been loaded
return OResource::Reload(resourceData)->GetResourceHandle();
}
OHRESOURCE ReloadResource(OHRESOURCE resource)
OHRESOURCE OysterResource::ReloadResource(OHRESOURCE resource)
{
OResource *resourceData = resourcePrivate.FindResource(resource);
if(!resourceData) return 0; //The resource has not been loaded
@ -89,12 +114,13 @@ void OysterResource::Clean()
for (i; i != last; i++)
{
if(OResource::Release(i->second))
{
//Remove all the references
while (!OResource::Release(i->second));
const wchar_t* temp = i->second->GetResourceFilename();
delete resourcePrivate.resources[temp];
resourcePrivate.resources.erase(temp);
}
}
}
void OysterResource::ReleaseResource(const OHRESOURCE& resourceData)
@ -110,6 +136,19 @@ void OysterResource::ReleaseResource(const OHRESOURCE& resourceData)
}
}
}
void OysterResource::ReleaseResource(const wchar_t filename[])
{
OResource* t = resourcePrivate.FindResource(filename);
if(t)
{
if(OResource::Release(t))
{
const wchar_t* temp = t->GetResourceFilename();
delete resourcePrivate.resources[temp];
resourcePrivate.resources.erase(temp);
}
}
}
void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int id)
{
@ -117,13 +156,27 @@ void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int
if(t) t->SetResourceID(id);
}
void OysterResource::SetResourceId(const wchar_t c[], unsigned int id)
{
OResource* t = resourcePrivate.FindResource(c);
if(t) t->SetResourceID(id);
}
ResourceType OysterResource::GetResourceType (const OHRESOURCE& resourceData)
{
OResource* t = resourcePrivate.FindResource(resourceData);
if(t) return t->GetResourceType();
return ResourceType_UNKNOWN;
return ResourceType_INVALID;
}
ResourceType OysterResource::GetResourceType (const wchar_t c[])
{
OResource* t = resourcePrivate.FindResource(c);
if(t) return t->GetResourceType();
return ResourceType_INVALID;
}
const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceData)
{
@ -133,7 +186,15 @@ const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceDa
return 0;
}
unsigned int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
OHRESOURCE OysterResource::GetResourceHandle(const wchar_t filename[])
{
OResource* t = resourcePrivate.FindResource(filename);
if(t) return t->GetResourceHandle();
return 0;
}
int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
{
OResource* t = resourcePrivate.FindResource(resourceData);
@ -141,7 +202,14 @@ unsigned int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
return -1;
}
int OysterResource::GetResourceId(const wchar_t c[])
{
OResource* t = resourcePrivate.FindResource(c);
if(t) return t->GetResourceID();
return -1;
}
OResource* ResourcePrivate::FindResource(const OHRESOURCE& h) const

View File

@ -12,11 +12,11 @@ namespace Oyster
{
struct CustomData;
/** A Resource handle representing various resources */
typedef unsigned long OHRESOURCE;
typedef void* OHRESOURCE;
/** Typedef on a fuction required for custom unloading */
typedef void(*CustomUnloadFunction)(void* loadedData);
/** Typedef on a fuction required for custom loading */
typedef CustomData&(*CustomLoadFunction)(const wchar_t filename[]);
typedef void(*CustomLoadFunction)(const wchar_t filename[], CustomData& outData);
/** An enum class representing all avalible resources that is supported. */
enum ResourceType
@ -31,15 +31,14 @@ namespace Oyster
ResourceType_COUNT, /**< Not used. */
ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */
ResourceType_INVALID = -2, /**< Invalid or non existing resource */
};
/** A struct to return when doing a custom resource Load
* By loading this way you are handing over the ownership to the resource loaded.
*/
/** A struct to fill when doing a custom resource Load. */
struct CustomData
{
void* loadedData; ///<! The loaded resource interpeted as a void*.
CustomUnloadFunction resourceUnloadFnc; ///<! The function that will be used to free the resource when needed.
void* loadedData; //<! The loaded resource interpeted as a void*.
CustomUnloadFunction resourceUnloadFnc; //<! The function that will be used to free the resource when needed.
};
/** A resource handler interface to interact with when loading resources.
@ -55,16 +54,17 @@ namespace Oyster
* @param force If set to true, the resource will be reloaded if it already exists. If it does not, nothing happens.
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
*/
static OHRESOURCE LoadResource(const wchar_t filename[], ResourceType type);
static OHRESOURCE LoadResource(const wchar_t filename[], ResourceType type, int customId = -1, bool force = false);
/**
* Load a resource with a custom loading function
* @param filename The path to the resource.
* @param force If set to true, the resource will be reloaded even if exists.
* @param loadFnc If set, this gives you the right to do custom resource loading if your recource type is not supported.
* @param customId A custom ID that can be used.
* @param force If set to true, the resource will be reloaded even if exists.
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
*/
static OHRESOURCE LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc = 0, unsigned int CustomId = 0);
static OHRESOURCE LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc = 0, int customId = -1, bool force = false);
/**
* Reload a resource
@ -93,29 +93,63 @@ namespace Oyster
*/
static void ReleaseResource(const OHRESOURCE& resource);
/**
* Release a reference to the resource handle
* @param resource The resource filename to release reference.
* @return Nothing
*/
static void ReleaseResource(const wchar_t filename[]);
/** Set a user defined ID
* @param resource A handle to accociate the id with.
* @param id A user defined identifier that the resource handler does not touch.
*/
static void SetResourceId(const OHRESOURCE& resource, unsigned int id);
/** Set a user defined ID
* If the resource is not loaded the id will not be set.
* @param resource A filename to accociate the id with.
* @param id A user defined identifier that the resource handler does not touch.
*/
static void SetResourceId(const wchar_t filename[], unsigned int id);
/** Get a resource type given a OHRESOURCE handle
* @param resource The handle to check
* @return Returns the resource type of the handle
*/
static ResourceType GetResourceType(const OHRESOURCE& resource);
/** Get a resource type given a filename
* If the resource is not loaded the id will not be set.
* @param resource The filename to check
* @return Returns the resource type of the handle
*/
static ResourceType GetResourceType (const wchar_t filename[]);
/** Get a resource filename given a OHRESOURCE handle
* @param resource The handle to check
* @return Returns the accociated filename
*/
static const wchar_t* GetResourceFilename(const OHRESOURCE& resource);
/** Get a resource handle given a filename
* If the resource is not loaded function returns 0.
* @param resource The filename to check
* @return Returns the accociated handle
*/
static OHRESOURCE GetResourceHandle(const wchar_t filename[]);
/** Get a user defined ID accociated with a handle
* @param resource The handle to check
* @return Returns the accociated ID
*/
static unsigned int GetResourceId(const OHRESOURCE& resource);
static int GetResourceId(const OHRESOURCE& resource);
/** Get a user defined ID accociated with a filename
* @param resource The filename to check
* @return Returns the accociated ID
*/
static int GetResourceId(const wchar_t filename[]);
};
}

View File

@ -0,0 +1,162 @@
/////////////////////////////////////////////////////////////////////
// Created by [Dennis Andersen] [2013]
/////////////////////////////////////////////////////////////////////
#ifndef MISC_OYSTER_RESOURCE_H
#define MISC_OYSTER_RESOURCE_H
namespace Oyster
{
namespace Resource
{
struct CustomData;
/** A Resource handle representing various resources */
typedef void* OHRESOURCE;
/** Typedef on a fuction required for custom unloading */
typedef void(*CustomUnloadFunction)(void* loadedData);
/** Typedef on a fuction required for custom loading */
<<<<<<< HEAD
typedef CustomData&(*CustomLoadFunction)(const wchar_t filename[]);
=======
typedef void(*CustomLoadFunction)(const wchar_t filename[], CustomData& outData);
>>>>>>> d08644e8e1ecc56f4d9dfa6a9aa33df94d9e655a
/** An enum class representing all avalible resources that is supported. */
enum ResourceType
{
//Byte
ResourceType_Byte_Raw, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_ANSI, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_UTF8, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_UNICODE, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_UTF16LE, /**< Handle can be interpeted as char[] or char* */
ResourceType_COUNT, /**< Not used. */
ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */
ResourceType_INVALID = -2, /**< Invalid or non existing resource */
};
/** A struct to fill when doing a custom resource Load. */
struct CustomData
{
void* loadedData; //<! The loaded resource interpeted as a void*.
CustomUnloadFunction resourceUnloadFnc; //<! The function that will be used to free the resource when needed.
};
/** A resource handler interface to interact with when loading resources.
* The resource handler uses the filename to make resources unuiqe.
*/
class OysterResource
{
public:
/**
* Load a resource given a type.
* @param filename The path to the resource.
* @param type The resource type to load.
* @param force If set to true, the resource will be reloaded if it already exists. If it does not, nothing happens.
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
*/
static OHRESOURCE LoadResource(const wchar_t filename[], ResourceType type, int customId = -1, bool force = false);
/**
* Load a resource with a custom loading function
* @param filename The path to the resource.
* @param loadFnc If set, this gives you the right to do custom resource loading if your recource type is not supported.
* @param customId A custom ID that can be used.
* @param force If set to true, the resource will be reloaded even if exists.
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
*/
static OHRESOURCE LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc = 0, int customId = -1, bool force = false);
/**
* Reload a resource
* @param filename The path to the resource.
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
*/
static OHRESOURCE ReloadResource(const wchar_t filename[]);
/**
* Reload a resource
* @param filename The path to the resource.
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
*/
static OHRESOURCE ReloadResource(OHRESOURCE resource);
/**
* Releases all resources loaded by the resource handler.
* @return Nothing
*/
static void Clean();
/**
* Release a reference to the resource handle
* @param resource The handle to release.
* @return Nothing
*/
static void ReleaseResource(const OHRESOURCE& resource);
/**
* Release a reference to the resource handle
* @param resource The resource filename to release reference.
* @return Nothing
*/
static void ReleaseResource(const wchar_t filename[]);
/** Set a user defined ID
* @param resource A handle to accociate the id with.
* @param id A user defined identifier that the resource handler does not touch.
*/
static void SetResourceId(const OHRESOURCE& resource, unsigned int id);
/** Set a user defined ID
* If the resource is not loaded the id will not be set.
* @param resource A filename to accociate the id with.
* @param id A user defined identifier that the resource handler does not touch.
*/
static void SetResourceId(const wchar_t filename[], unsigned int id);
/** Get a resource type given a OHRESOURCE handle
* @param resource The handle to check
* @return Returns the resource type of the handle
*/
static ResourceType GetResourceType(const OHRESOURCE& resource);
/** Get a resource type given a filename
* If the resource is not loaded the id will not be set.
* @param resource The filename to check
* @return Returns the resource type of the handle
*/
static ResourceType GetResourceType (const wchar_t filename[]);
/** Get a resource filename given a OHRESOURCE handle
* @param resource The handle to check
* @return Returns the accociated filename
*/
static const wchar_t* GetResourceFilename(const OHRESOURCE& resource);
/** Get a resource handle given a filename
* If the resource is not loaded function returns 0.
* @param resource The filename to check
* @return Returns the accociated handle
*/
static OHRESOURCE GetResourceHandle(const wchar_t filename[]);
/** Get a user defined ID accociated with a handle
* @param resource The handle to check
* @return Returns the accociated ID
*/
static int GetResourceId(const OHRESOURCE& resource);
/** Get a user defined ID accociated with a filename
* @param resource The filename to check
* @return Returns the accociated ID
*/
static int GetResourceId(const wchar_t filename[]);
};
}
}
#endif

View File

@ -8,6 +8,7 @@
#include <thread>
#include <future>
using namespace Oyster::Thread;
OysterMutex::OysterMutex()
@ -64,8 +65,3 @@ bool OysterMutex::IsTaken()
{
return !this->mutex.try_lock();
}
void OysterMutex::Reset()
{
if(!this->mutex.try_lock())
this->mutex.unlock();
}

View File

@ -9,6 +9,10 @@
#include <thread>
#include <atomic>
namespace Oyster
{
namespace Thread
{
class OysterMutex
{
public:
@ -20,8 +24,6 @@ public:
void UnlockMutex();
/** Returns true if mutex is taken */
bool IsTaken();
/** This function resets resource locking */
void Reset();
private:
std::mutex mutex;
@ -29,5 +31,7 @@ private:
OysterMutex(const OysterMutex&);
};
}
}
#endif // !MISC_OYSTER_MUTEX_H

View File

@ -6,7 +6,6 @@
#define MISC_OYSTER_THREAD_H
#include "IThreadObject.h"
namespace Oyster
{
namespace Thread
@ -23,11 +22,10 @@ namespace Oyster
struct PrivateData;
PrivateData *privateData;
OysterThread(const OysterThread& original);
const OysterThread& operator=(const OysterThread& original);
public:
OysterThread();
OysterThread(const OysterThread& original);
const OysterThread& operator=(const OysterThread& original);
virtual~OysterThread();
OYSTER_THREAD_ERROR Create(IThreadObject* worker, bool start);

View File

@ -7,6 +7,7 @@
#include "..\Utilities.h"
#include <thread>
#include <assert.h>
#include <atomic>
using namespace Oyster::Thread;
using namespace Utility::DynamicMemory::SmartPointer;
@ -24,23 +25,22 @@ using namespace Utility::DynamicMemory::SmartPointer;
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; //<! The current thread state.
std::atomic<OYSTER_THREAD_STATE> state; //<! The current thread state.
//OYSTER_THREAD_STATE state; //<! The current thread state.
StdSmartPointer<std::thread> workerThread; //<! The worker thread.
std::thread::id callingThread; //<! The owner thread.
IThreadObject *owner; //<! The owner of the thread as IThread.
int msec; //<! A timer in miliseconds.
OysterMutex mutexLock; //<! The lock, locking the member variabls.
std::atomic<int> msec; //<! A timer in miliseconds.
//OysterMutex mutexLock; //<! The lock, locking the member variabls.
ThreadData() {}
private:
~ThreadData() {}
ThreadData(const ThreadData&) {};
};
struct OysterThread::PrivateData
@ -55,10 +55,14 @@ using namespace Utility::DynamicMemory::SmartPointer;
threadData->callingThread;
threadData->state = OYSTER_THREAD_STATE_STOPED;
}
PrivateData(const PrivateData& o)
{
threadData = o.threadData;
}
~PrivateData()
{
//@todo TODO: Make detatch avalible.
//this->threadData->workerThread->detach();
this->threadData->workerThread->detach();
this->threadData->owner = 0;
@ -70,35 +74,46 @@ using namespace Utility::DynamicMemory::SmartPointer;
#pragma endregion
int tempId = 0;
std::vector<int> IDS;
static void ThreadingFunction(StdSmartPointer<ThreadData> &origin)
{
bool shouldContinue;
StdSmartPointer<ThreadData> w = origin;
theBegining:
while(w->state == OYSTER_THREAD_STATE_STOPED);
w->mutexLock.LockMutex();
while(w->state == OYSTER_THREAD_STATE_STOPED)
{
std::this_thread::yield();
}
// w->mutexLock.LockMutex();
if(w->owner)
{
w->owner->ThreadEntry();
w->mutexLock.UnlockMutex();
}
// w->mutexLock.UnlockMutex();
while (w->state != OYSTER_THREAD_STATE_STOPED && w->state != OYSTER_THREAD_STATE_DEAD)
{
w->mutexLock.LockMutex();
// w->mutexLock.LockMutex();
{
if(w->owner)
{
shouldContinue = w->owner->DoWork();
}
w->mutexLock.UnlockMutex();
}
// w->mutexLock.UnlockMutex();
if(!shouldContinue)
{
goto theEnd;
}
if(w->state == OYSTER_THREAD_STATE_TERMINATED)
if(w->state == OYSTER_THREAD_STATE_DEAD)
{
return;
goto theEnd;
}
else if(w->state == OYSTER_THREAD_STATE_RESET)
{
@ -109,19 +124,26 @@ theBegining:
std::this_thread::sleep_for(std::chrono::milliseconds(w->msec));
}
while (w->state == OYSTER_THREAD_STATE_PAUSED);
while (w->state == OYSTER_THREAD_STATE_PAUSED)
{
std::this_thread::yield();
}
}
if(w->state == OYSTER_THREAD_STATE_DEAD)
{
w->workerThread->detach();
return;
}
theEnd:
w->mutexLock.LockMutex();
// w->mutexLock.LockMutex();
if(w->owner)
{
w->owner->ThreadExit();
w->mutexLock.UnlockMutex();
}
// w->mutexLock.UnlockMutex();
w->state = OYSTER_THREAD_STATE_DEAD;
}
@ -130,6 +152,14 @@ OysterThread::OysterThread()
{
this->privateData = new PrivateData();
}
OysterThread::OysterThread(const OysterThread& original)
{
this->privateData = new PrivateData(*original.privateData);
}
const OysterThread& OysterThread::operator=(const OysterThread& original)
{
return *this;
}
OysterThread::~OysterThread()
{
delete this->privateData;
@ -153,30 +183,33 @@ OYSTER_THREAD_ERROR OysterThread::Create(IThreadObject* worker, bool start)
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->owner)
return OYSTER_THREAD_ERROR_FAILED;
if(!this->privateData->threadData->workerThread)
return OYSTER_THREAD_ERROR_FAILED;
if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD)
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->mutexLock.LockMutex();
this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED;
this->privateData->threadData->mutexLock.UnlockMutex();
//this->privateData->threadData->mutexLock.UnlockMutex();
}
void OysterThread::Pause()
{
this->privateData->threadData->mutexLock.LockMutex();
//this->privateData->threadData->mutexLock.LockMutex();
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
this->privateData->threadData->mutexLock.UnlockMutex();
//this->privateData->threadData->mutexLock.UnlockMutex();
}
void OysterThread::Pause(int msec)
{
@ -187,39 +220,34 @@ void OysterThread::Pause(int msec)
}
else
{
this->privateData->threadData->mutexLock.LockMutex();
//this->privateData->threadData->mutexLock.LockMutex();
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
this->privateData->threadData->msec = msec;
this->privateData->threadData->mutexLock.UnlockMutex();
//this->privateData->threadData->mutexLock.UnlockMutex();
}
}
void OysterThread::Resume()
{
this->privateData->threadData->mutexLock.LockMutex();
// this->privateData->threadData->mutexLock.LockMutex();
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
this->privateData->threadData->mutexLock.UnlockMutex();
// this->privateData->threadData->mutexLock.UnlockMutex();
}
OYSTER_THREAD_ERROR OysterThread::Reset(IThreadObject* worker)
{
this->privateData->threadData->mutexLock.LockMutex();
// 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();
// 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;
this->privateData->threadData->state = OYSTER_THREAD_STATE_DEAD;
}
void OysterThread::Wait()
{

View File

@ -165,8 +165,7 @@ namespace Utility
namespace SmartPointer
{
template<typename T>
void StdSmartPointer<T>::Destroy()
template<typename T> void StdSmartPointer<T>::Destroy()
{
delete this->_rc;
this->_rc = NULL;
@ -200,7 +199,7 @@ namespace Utility
if (this != &p)
{
//Last to go?
if(this->_rc && this->_rc->Release() == 0)
if(this->_rc && this->_rc->Decref() == 0)
{
//Call child specific
Destroy();
@ -208,7 +207,7 @@ namespace Utility
this->_ptr = p._ptr;
this->_rc = p._rc;
this->_rc->Add();
this->_rc->Incref();
}
return *this;
}
@ -254,16 +253,14 @@ namespace Utility
{
return this->_ptr;
}
/**
* Returns the connected pointer */
template<typename T> inline StdSmartPointer<T>::operator bool()
{
return (this->_ptr != 0);
}
template<typename T> inline T* StdSmartPointer<T>::Get()
{
return this->_ptr;
}
/** Checks if the pointer is valid (not NULL)
Returns true for valid, else false. */
template<typename T> inline bool StdSmartPointer<T>::IsValid()
{
return (this->_ptr != NULL) ? true : false;

View File

@ -12,6 +12,7 @@
#include <vector>
#include <locale>
#include <limits>
#include <atomic>
namespace Utility
{
@ -110,12 +111,12 @@ namespace Utility
struct ReferenceCount
{
private:
int count;
std::atomic<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;}
ReferenceCount(const ReferenceCount& o) { count.store(o.count); }
inline const ReferenceCount& operator=(const ReferenceCount& o) { count.store(o.count); return *this;}
inline void Incref() { this->count++; }
inline void Incref(int c) { this->count += c; }
inline int Decref() { return --this->count;}
@ -151,6 +152,7 @@ namespace Utility
T& operator* ();
T* operator-> ();
operator T* ();
operator bool();
/**
* Returns the connected pointer */

View File

@ -1,4 +1,5 @@
#include "Core.h"
#include <vld.h>
using namespace Oyster::Graphics;
using std::string;

View File

@ -158,12 +158,18 @@ namespace Oyster
Pixel,
Compute
};
struct ShaderData
{
size_t size;
char* data;
};
static void SetShaderEffect(ShaderEffect&);
static void CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *desc, int ElementCount,int VertexIndex,ID3D11InputLayout *&Layout);
static bool Init(std::wstring filename, ShaderType type, std::wstring name, bool Precompiled = true);
static bool Init(std::wstring filename, ShaderType type, std::wstring name);
static void* CreateShader(ShaderData data, ShaderType type);
struct Get
{
@ -184,6 +190,8 @@ namespace Oyster
static void Hull(int Index);
static void Domain(int Index);
};
static void Clean();
};
//Set resulotion Before Calling Full Init

View File

@ -1,6 +1,8 @@
#include "Core.h"
#include <fstream>
#include <map>
#include "../FileLoader/GeneralLoader.h"
#include "Resource\OysterResource.h"
const char* ShaderFunction = "main";
@ -8,15 +10,8 @@ namespace Oyster
{
namespace Graphics
{
bool LoadPrecompiled(std::wstring filename, Core::ShaderManager::ShaderType type, std::wstring name);
bool LoadCompile(std::wstring filename, Core::ShaderManager::ShaderType type, std::wstring name);
namespace
{
struct ShaderData
{
size_t size;
char* data;
};
std::vector<ID3D11PixelShader*> PS;
std::map<std::wstring,int> PSMap;
@ -26,213 +21,146 @@ namespace Oyster
std::vector<ID3D11ComputeShader*> CS;
std::map<std::wstring,int> CSMap;
std::vector<ID3D11DomainShader*> DS;
std::map<std::wstring,int> DSMap;
std::vector<ID3D11HullShader*> HS;
std::map<std::wstring,int> HSMap;
std::vector<ID3D11VertexShader*> VS;
std::vector<ShaderData> VData;
std::vector<Core::ShaderManager::ShaderData> VData;
std::map<std::wstring,int> VSMap;
}
#pragma region Init
bool Core::ShaderManager::Init(std::wstring filename, ShaderType type, std::wstring name, bool Precompiled)
bool Core::ShaderManager::Init(std::wstring filename, ShaderType type, std::wstring name)
{
if(Precompiled)
{
return LoadPrecompiled(filename, type, name);
}
else
{
return LoadCompile(filename, type, name);
}
return true;
}
bool LoadPrecompiled(std::wstring filename, Core::ShaderManager::ShaderType type, std::wstring name)
{
std::ifstream stream;
ShaderData sd;
//Create Vertex shader and Layout
stream.open(filename, std::ifstream::in | std::ifstream::binary);
if(stream.good())
{
stream.seekg(0, std::ios::end);
sd.size = size_t(stream.tellg());
sd.data = new char[sd.size];
stream.seekg(0, std::ios::beg);
stream.read(&sd.data[0], sd.size);
stream.close();
ID3D11VertexShader* vertex;
ID3D11GeometryShader* geometry;
ID3D11PixelShader* pixel;
ID3D11ComputeShader* compute;
void* data;
bool ForceReload;
#if defined (_DEBUG) | defined (DEBUG)
ForceReload = true;
#else
ForceReload = false;
#endif
switch (type)
{
case Core::ShaderManager::ShaderType::Vertex:
if(VSMap.count(name))
return false;
if(FAILED(Core::device->CreateVertexShader(sd.data, sd.size, 0, &vertex)))
case Oyster::Graphics::Core::ShaderManager::Vertex:
if(!VSMap.count(name) || ForceReload)
{
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderV, -1, ForceReload);
if(data)
{
return false;
}
VSMap[name] = VS.size();
VS.push_back(vertex);
VData.push_back(sd);
break;
case Core::ShaderManager::ShaderType::Hull:
case Core::ShaderManager::ShaderType::Domain:
return false;
case Core::ShaderManager::ShaderType::Geometry:
if(GSMap.count(name))
return false;
if(FAILED(Core::device->CreateGeometryShader(sd.data, sd.size, 0, &geometry)))
{
return false;
VS.push_back((ID3D11VertexShader*)data);
}
}
break;
case Oyster::Graphics::Core::ShaderManager::Hull:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderH, -1, ForceReload);
if(!HSMap.count(name) || ForceReload)
{
if(data!=0)
{
HSMap[name] = HS.size();
HS.push_back((ID3D11HullShader*)data);
}
}
break;
case Oyster::Graphics::Core::ShaderManager::Domain:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderD, -1, ForceReload);
if(!DSMap.count(name) || ForceReload)
{
if(data!=0)
{
DSMap[name] = DS.size();
DS.push_back((ID3D11DomainShader*)data);
}
}
break;
case Oyster::Graphics::Core::ShaderManager::Geometry:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderG, -1, ForceReload);
if(!GSMap.count(name) || ForceReload)
{
if(data!=0)
{
GSMap[name] = GS.size();
GS.push_back(geometry);
break;
case Core::ShaderManager::ShaderType::Pixel:
if(PSMap.count(name))
return false;
if(FAILED(Core::device->CreatePixelShader(sd.data, sd.size, 0, &pixel)))
{
return false;
GS.push_back((ID3D11GeometryShader*)data);
}
}
break;
case Oyster::Graphics::Core::ShaderManager::Pixel:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderP, -1, ForceReload);
if(!PSMap.count(name) || ForceReload)
{
if(data!=0)
{
PSMap[name] = PS.size();
PS.push_back(pixel);
break;
case Core::ShaderManager::ShaderType::Compute:
if(CSMap.count(name))
return false;
if(FAILED(Core::device->CreateComputeShader(sd.data, sd.size, 0, &compute)))
{
return false;
PS.push_back((ID3D11PixelShader*)data);
}
}
break;
case Oyster::Graphics::Core::ShaderManager::Compute:
data = Resource::OysterResource::LoadResource(filename.c_str(),Loading::LoadShaderC, -1, ForceReload);
if(!CSMap.count(name) || ForceReload)
{
if(data!=0)
{
CSMap[name] = CS.size();
CS.push_back(compute);
CS.push_back((ID3D11ComputeShader*)data);
}
}
break;
default:
break;
}
}
else
{
return false;
}
return true;
}
bool LoadCompile(std::wstring filename, Core::ShaderManager::ShaderType type, std::wstring name)
void* Core::ShaderManager::CreateShader(Core::ShaderManager::ShaderData data, Core::ShaderManager::ShaderType type)
{
/// \todo error reporting
ID3D10Blob *Shader,*Error;
HRESULT hr;
switch (type)
{
case Core::ShaderManager::ShaderType::Pixel:
ID3D11PixelShader* pixel;
if(FAILED(D3DCompileFromFile(filename.c_str(),NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,ShaderFunction,"ps_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error)))
{
std::string fel = (char*)Error->GetBufferPointer();
Error->Release();
return false;
}
if(FAILED(Core::device->CreatePixelShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&pixel)))
{
Shader->Release();
return false;
}
Shader->Release();
if(!PSMap.count(name))
{
PSMap[name] = PS.size();
PS.push_back(pixel);
}
else
{
PS[PSMap[name]] = pixel;
}
case Oyster::Graphics::Core::ShaderManager::Vertex:
ID3D11VertexShader* vs;
hr = Core::device->CreateVertexShader(data.data,data.size,NULL,&vs);
if(hr == S_OK)
VData.push_back(data);
return vs;
break;
case Core::ShaderManager::ShaderType::Geometry:
ID3D11GeometryShader* geometry;
if(FAILED(D3DCompileFromFile(filename.c_str(),NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,ShaderFunction,"gs_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error)))
{
std::string fel = (char*)Error->GetBufferPointer();
Error->Release();
return false;
}
if(FAILED(Core::device->CreateGeometryShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&geometry)))
{
Shader->Release();
return false;
}
Shader->Release();
if(!GSMap.count(name))
{
GSMap[name] = GS.size();
GS.push_back(geometry);
}
else
{
GS[GSMap[name]] = geometry;
}
case Oyster::Graphics::Core::ShaderManager::Hull:
ID3D11HullShader* hs;
Core::device->CreateHullShader(data.data,data.size,NULL,&hs);
delete[] data.data;
return hs;
break;
case Core::ShaderManager::ShaderType::Vertex:
ID3D11VertexShader* vertex;
if(FAILED(D3DCompileFromFile(filename.c_str(),NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,ShaderFunction,"vs_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error)))
{
std::string fel = (char*)Error->GetBufferPointer();
Error->Release();
return false;
}
if(FAILED(Core::device->CreateVertexShader(Shader->GetBufferPointer(),Shader->GetBufferSize(),NULL,&vertex)))
{
Shader->Release();
return false;
}
if(!VSMap.count(name))
{
VSMap[name] = VS.size();
VS.push_back(vertex);
ShaderData sd;
sd.size = Shader->GetBufferSize();
sd.data = new char[sd.size];
memcpy(sd.data,Shader->GetBufferPointer(),sd.size);
VData.push_back(sd);
}
else
{
VS[VSMap[name]] = vertex;
delete[] VData[VSMap[name]].data;
VData[VSMap[name]].size = Shader->GetBufferSize();
VData[VSMap[name]].data = new char[VData[VSMap[name]].size];
memcpy(VData[VSMap[name]].data,Shader->GetBufferPointer(),VData[VSMap[name]].size);
}
Shader->Release();
case Oyster::Graphics::Core::ShaderManager::Domain:
ID3D11DomainShader* ds;
Core::device->CreateDomainShader(data.data,data.size,NULL,&ds);
delete[] data.data;
return ds;
break;
case Oyster::Graphics::Core::ShaderManager::Geometry:
ID3D11GeometryShader* gs;
Core::device->CreateGeometryShader(data.data,data.size,NULL,&gs);
delete[] data.data;
return gs;
break;
case Oyster::Graphics::Core::ShaderManager::Pixel:
ID3D11PixelShader* ps;
Core::device->CreatePixelShader(data.data,data.size,NULL,&ps);
delete[] data.data;
return ps;
break;
case Oyster::Graphics::Core::ShaderManager::Compute:
ID3D11ComputeShader* cs;
Core::device->CreateComputeShader(data.data,data.size,NULL,&cs);
delete[] data.data;
return cs;
break;
}
return true;
return NULL;
}
#pragma endregion
@ -348,5 +276,13 @@ namespace Oyster
float test[4] = {0};
Core::deviceContext->OMSetBlendState(se.RenderStates.BlendState,test,-1);
}
void Core::ShaderManager::Clean()
{
for(int i = 0; i < VData.size(); ++i)
{
delete[] VData[i].data;
}
}
}
}

View File

@ -3,6 +3,7 @@
#include "../Render/Resources/Resources.h"
#include "../Render/Rendering/Render.h"
#include "../FileLoader/ObjReader.h"
#include "../../Misc/Resource/OysterResource.h"
namespace Oyster
{
@ -60,7 +61,17 @@ namespace Oyster
void API::DeleteModel(Model::Model* model)
{
Model::ModelInfo* info = (Model::ModelInfo*)model->info;
delete model;
info->Vertices->~Buffer();
}
void API::Clean()
{
SAFE_DELETE(Core::viewPort);
Oyster::Resource::OysterResource::Clean();
Oyster::Graphics::Core::ShaderManager::Clean();
Oyster::Graphics::Render::Resources::Clean();
}
}
}

View File

@ -28,6 +28,7 @@ namespace Oyster
};
static State Init(HWND Window, bool MSAA_Quality, bool Fullscreen, Oyster::Math::Float2 StartResulotion);
static void Clean();
//! @brief from Oyster::Math Float4x4, expects corect methods
static void NewFrame(Oyster::Math::Float4x4 View, Oyster::Math::Float4x4 Projection);
static void RenderScene(Oyster::Graphics::Model::Model* models, int count);

View File

@ -7,10 +7,27 @@ namespace Oyster
namespace Loading
{
void UnloadTexture(void* loadedData);
Oyster::Resource::CustomData& LoadTexture(const wchar_t filename[]);
void LoadTexture(const wchar_t filename[], Oyster::Resource::CustomData& out);
void UnloadShader(void* loadedData);
Oyster::Resource::CustomData& LoadShader(const wchar_t filename[]);
void UnloadShaderP(void* loadedData);
void LoadShaderP(const wchar_t filename[], Oyster::Resource::CustomData& out);
void UnloadShaderG(void* loadedData);
void LoadShaderG(const wchar_t filename[], Oyster::Resource::CustomData& out);
void UnloadShaderC(void* loadedData);
void LoadShaderC(const wchar_t filename[], Oyster::Resource::CustomData& out);
void UnloadShaderV(void* loadedData);
void LoadShaderV(const wchar_t filename[], Oyster::Resource::CustomData& out);
void UnloadShaderH(void* loadedData);
void LoadShaderH(const wchar_t filename[], Oyster::Resource::CustomData& out);
void UnloadShaderD(void* loadedData);
void LoadShaderD(const wchar_t filename[], Oyster::Resource::CustomData& out);
void LoadShader(const wchar_t filename[], Oyster::Resource::CustomData& out, int type);
}
}
}

View File

@ -2,7 +2,7 @@
#include "..\Definitions\GraphicalDefinition.h"
#include <sstream>
#include <fstream>
#include "TextureLoader.h"
#include "GeneralLoader.h"
using namespace std;
OBJReader::OBJReader()
@ -24,7 +24,7 @@ void OBJReader::readOBJFile( std::wstring fileName )
float vertexData;
std::string face1, face2, face3;
inStream.open( fileName, std::fstream::in );
inStream.open( fileName + L".obj", std::fstream::in );
if( inStream.is_open() )
{
@ -94,6 +94,8 @@ void OBJReader::readOBJFile( std::wstring fileName )
}
inStream.close();
Mat = Oyster::Resource::OysterResource::LoadResource((fileName + L".jpg").c_str(),Oyster::Graphics::Loading::LoadTexture);
}
Oyster::Graphics::Model::ModelInfo* OBJReader::toModel()
@ -117,12 +119,7 @@ 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"orca_tex.jpg",Oyster::Graphics::Loading::LoadTexture);
//Oyster::Resource::OysterResource::LoadResource(L"Normal.png",(Oyster::Resource::CustomLoadFunction)Oyster::Graphics::Loading::LoadTexture);
void* v = (void*)diffuse;
modelInfo->Material.push_back((ID3D11ShaderResourceView*)v);
modelInfo->Material.push_back((ID3D11ShaderResourceView*)Mat);
return modelInfo;
}

View File

@ -43,6 +43,7 @@ class OBJReader
int _mPos, _mNormal, _mTexel;
void stringSplit( std::string strToSplit );
void addToOBJarray();
void* Mat;
public:
OBJReader();

View File

@ -0,0 +1,189 @@
#include "GeneralLoader.h"
#include "..\Core\Dx11Includes.h"
#include "..\Core\Core.h"
#include <fstream>
namespace Oyster
{
namespace Graphics
{
namespace Loading
{
void UnloadShaderP(void* loadedData)
{
ID3D11PixelShader* ps = ((ID3D11PixelShader*)loadedData);
SAFE_RELEASE(ps);
}
void UnloadShaderG(void* loadedData)
{
ID3D11GeometryShader* gs = ((ID3D11GeometryShader*)loadedData);
SAFE_RELEASE(gs);
}
void UnloadShaderC(void* loadedData)
{
ID3D11ComputeShader* ps = ((ID3D11ComputeShader*)loadedData);
SAFE_RELEASE(ps);
}
void UnloadShaderH(void* loadedData)
{
ID3D11HullShader* ps = ((ID3D11HullShader*)loadedData);
SAFE_RELEASE(ps);
}
void UnloadShaderD(void* loadedData)
{
ID3D11DomainShader* ps = ((ID3D11DomainShader*)loadedData);
SAFE_RELEASE(ps);
}
void UnloadShaderV(void* loadedData)
{
ID3D11VertexShader* ps = ((ID3D11VertexShader*)loadedData);
SAFE_RELEASE(ps);
}
void LoadShaderP(const wchar_t filename[], Oyster::Resource::CustomData& out)
{
LoadShader(filename,out,Core::ShaderManager::Pixel);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderP;
}
void LoadShaderG(const wchar_t filename[], Oyster::Resource::CustomData& out)
{
LoadShader(filename,out,Core::ShaderManager::Geometry);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderG;
}
void LoadShaderC(const wchar_t filename[], Oyster::Resource::CustomData& out)
{
LoadShader(filename,out,Core::ShaderManager::Compute);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderC;
}
void LoadShaderH(const wchar_t filename[], Oyster::Resource::CustomData& out)
{
LoadShader(filename,out,Core::ShaderManager::Hull);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderH;
}
void LoadShaderD(const wchar_t filename[], Oyster::Resource::CustomData& out)
{
LoadShader(filename,out,Core::ShaderManager::Domain);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderD;
}
void LoadShaderV(const wchar_t filename[], Oyster::Resource::CustomData& out)
{
LoadShader(filename,out,Core::ShaderManager::Vertex);
if(out.loadedData==NULL)
{
memset(&out,0,sizeof(out));
return;
}
out.resourceUnloadFnc = UnloadShaderV;
}
void LoadShader(const wchar_t filename[], Oyster::Resource::CustomData& out, int type)
{
Core::ShaderManager::ShaderData data;
#ifdef _DEBUG
ID3DBlob *Shader=NULL, *Error=NULL;
HRESULT hr;
switch (Core::ShaderManager::ShaderType(type))
{
case Oyster::Graphics::Core::ShaderManager::Vertex:
hr = D3DCompileFromFile(filename,NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,"main","vs_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error);
break;
case Oyster::Graphics::Core::ShaderManager::Hull:
hr = D3DCompileFromFile(filename,NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,"main","hs_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error);
break;
case Oyster::Graphics::Core::ShaderManager::Domain:
hr = D3DCompileFromFile(filename,NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,"main","ds_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error);
break;
case Oyster::Graphics::Core::ShaderManager::Geometry:
hr = D3DCompileFromFile(filename,NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,"main","gs_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error);
break;
case Oyster::Graphics::Core::ShaderManager::Pixel:
hr = D3DCompileFromFile(filename,NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,"main","ps_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error);
break;
case Oyster::Graphics::Core::ShaderManager::Compute:
hr = D3DCompileFromFile(filename,NULL,D3D_COMPILE_STANDARD_FILE_INCLUDE,"main","cs_5_0",D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,0,&Shader,&Error);
break;
default:
break;
}
if(FAILED(hr))
{
if(Error)
{
Error->Release();
}
if(Shader)
{
Shader->Release();
}
memset(&out,0,sizeof(out));
return;
}
data.size = Shader->GetBufferSize();
data.data = new char[data.size];
memcpy(data.data,Shader->GetBufferPointer(),data.size);
#else
stream.open(filename, std::ifstream::in | std::ifstream::binary);
if(stream.good())
{
stream.seekg(0, std::ios::end);
sd.size = size_t(stream.tellg());
sd.data = new char[sd.size];
stream.seekg(0, std::ios::beg);
stream.read(&sd.data[0], sd.size);
stream.close();
}
else
{
memset(&out,0,sizeof(out));
return;
}
#endif
out.loadedData = Core::ShaderManager::CreateShader(data, Core::ShaderManager::ShaderType(type));
}
}
}
}

View File

@ -1,4 +1,4 @@
#include "TextureLoader.h"
#include "GeneralLoader.h"
#include "..\Core\Dx11Includes.h"
#include "..\Core\Core.h"
@ -14,22 +14,19 @@ HRESULT CreateWICTextureFromFileEx( ID3D11Device* d3dDevice,
ID3D11Resource** texture,
ID3D11ShaderResourceView** textureView );
Oyster::Resource::CustomData& Oyster::Graphics::Loading::LoadTexture(const wchar_t filename[])
void Oyster::Graphics::Loading::LoadTexture(const wchar_t filename[], Oyster::Resource::CustomData& out)
{
ID3D11ShaderResourceView* srv = NULL;
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));
memset(&out,0,sizeof(out));
}
else
{
Ret.loadedData = (void*)srv;
Ret.resourceUnloadFnc = Loading::UnloadTexture;
out.loadedData = (void*)srv;
out.resourceUnloadFnc = Loading::UnloadTexture;
}
return Ret;
}
void Oyster::Graphics::Loading::UnloadTexture(void* data)

View File

@ -69,21 +69,29 @@
<OutDir>$(SolutionDir)..\Bin\DLL\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)..\Bin\DLL\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)..\Bin\DLL\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)..\Bin\DLL\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -99,6 +107,9 @@
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
<FxCompile>
<ObjectFileOutput>$(SolutionDir)..\Bin\Content\Shaders\%(Filename).cso</ObjectFileOutput>
</FxCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@ -111,6 +122,9 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<FxCompile>
<ObjectFileOutput>$(SolutionDir)..\Bin\Content\Shaders\%(Filename).cso</ObjectFileOutput>
</FxCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
@ -127,6 +141,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<FxCompile>
<ObjectFileOutput>$(SolutionDir)..\Bin\Content\Shaders\%(Filename).cso</ObjectFileOutput>
</FxCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@ -143,6 +160,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<FxCompile>
<ObjectFileOutput>$(SolutionDir)..\Bin\Content\Shaders\%(Filename).cso</ObjectFileOutput>
</FxCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Core\Buffer.cpp" />
@ -151,6 +171,7 @@
<ClCompile Include="Core\ShaderManager.cpp" />
<ClCompile Include="DllInterfaces\GFXAPI.cpp" />
<ClCompile Include="FileLoader\ObjReader.cpp" />
<ClCompile Include="FileLoader\ShaderLoader.cpp" />
<ClCompile Include="FileLoader\TextureLoader.cpp" />
<ClCompile Include="Render\Preparations\BasicPreparations.cpp" />
<ClCompile Include="Render\Rendering\BasicRender.cpp" />
@ -161,7 +182,7 @@
<ClInclude Include="Core\Dx11Includes.h" />
<ClInclude Include="DllInterfaces\GFXAPI.h" />
<ClInclude Include="FileLoader\ObjReader.h" />
<ClInclude Include="FileLoader\TextureLoader.h" />
<ClInclude Include="FileLoader\GeneralLoader.h" />
<ClInclude Include="Model\Model.h" />
<ClInclude Include="Model\ModelInfo.h" />
<ClInclude Include="Render\Preparations\Preparations.h" />
@ -192,6 +213,16 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">5.0</ShaderModel>
</FxCompile>
<FxCompile Include="Shader\HLSL\Deffered Shaders\Render\LightPass.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4.0</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">4.0</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.0</ShaderModel>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4.0</ShaderModel>
</FxCompile>
<FxCompile Include="Shader\HLSL\SimpleDebug\DebugCameraVertex.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>
@ -232,7 +263,8 @@
</ItemGroup>
<ItemGroup>
<None Include="Shader\HLSL\Deffered Shaders\GatherGBuffer\GBufferHeader.hlsli" />
<None Include="Shader\HLSL\SimpleDebug\Debug.hlsli" />
<None Include="Shader\HLSL\Deffered Shaders\Render\Defines.hlsli" />
<None Include="Shader\HLSL\SimpleDebug\Debug.hlsl" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -45,6 +45,9 @@
<ClCompile Include="DllInterfaces\GFXAPI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FileLoader\ShaderLoader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Core\Core.h">
@ -71,15 +74,15 @@
<ClInclude Include="FileLoader\ObjReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FileLoader\TextureLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Core\Dx11Includes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DllInterfaces\GFXAPI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FileLoader\GeneralLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<FxCompile Include="Shader\HLSL\SimpleDebug\DebugVertex.hlsl" />
@ -88,9 +91,11 @@
<FxCompile Include="Shader\HLSL\Deffered Shaders\GatherGBuffer\PixelGatherData.hlsl" />
<FxCompile Include="Shader\HLSL\Deffered Shaders\GatherGBuffer\VertexGatherData.hlsl" />
<FxCompile Include="Shader\HLSL\SimpleDebug\TextureDebug.hlsl" />
<FxCompile Include="Shader\HLSL\Deffered Shaders\Render\LightPass.hlsl" />
</ItemGroup>
<ItemGroup>
<None Include="Shader\HLSL\Deffered Shaders\GatherGBuffer\GBufferHeader.hlsli" />
<None Include="Shader\HLSL\SimpleDebug\Debug.hlsli" />
<None Include="Shader\HLSL\SimpleDebug\Debug.hlsl" />
<None Include="Shader\HLSL\Deffered Shaders\Render\Defines.hlsli" />
</ItemGroup>
</Project>

View File

@ -32,12 +32,12 @@ namespace Oyster
#ifdef _DEBUG
/** Load Vertex Shader for d3dcompile*/
Core::ShaderManager::Init(PathFromExeToHlsl + L"SimpleDebug\\" +L"DebugCameraVertex.hlsl",ShaderType::Vertex, VertexTransformDebug, false);
Core::ShaderManager::Init(PathFromExeToHlsl + L"SimpleDebug\\" +L"DebugVertex.hlsl",ShaderType::Vertex, VertexDebug, false);
Core::ShaderManager::Init(PathFromExeToHlsl + L"SimpleDebug\\" +L"DebugCameraVertex.hlsl",ShaderType::Vertex, VertexTransformDebug);
Core::ShaderManager::Init(PathFromExeToHlsl + L"SimpleDebug\\" +L"DebugVertex.hlsl",ShaderType::Vertex, VertexDebug);
/** 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);
Core::ShaderManager::Init(PathFromExeToHlsl + L"SimpleDebug\\" + L"DebugPixel.hlsl", ShaderType::Pixel, PixelRed);
Core::ShaderManager::Init(PathFromExeToHlsl + L"SimpleDebug\\" + L"TextureDebug.hlsl", ShaderType::Pixel, PixelTexture);
#else
@ -148,6 +148,39 @@ namespace Oyster
#pragma endregion
return Core::Init::Sucsess;
}
void Resources::Clean()
{
Resources::ModelData.~Buffer();
Resources::VPData.~Buffer();
for(int i = 0; i < obj.CBuffers.Vertex.size(); ++i)
{
//SAFE_RELEASE(obj.CBuffers.Vertex[i]);
}
for(int i = 0; i < obj.CBuffers.Pixel.size(); ++i)
{
SAFE_DELETE(obj.CBuffers.Pixel[i]);
}
for(int i = 0; i < obj.CBuffers.Geometry.size(); ++i)
{
SAFE_DELETE(obj.CBuffers.Geometry[i]);
}
SAFE_RELEASE(obj.IAStage.Layout);
SAFE_RELEASE(obj.RenderStates.BlendState);
SAFE_RELEASE(obj.RenderStates.DepthStencil);
SAFE_RELEASE(obj.RenderStates.Rasterizer);
for(int i = 0; i < obj.RenderStates.SampleCount; ++i)
{
SAFE_RELEASE(obj.RenderStates.SampleState[i]);
}
SAFE_DELETE_ARRAY(obj.RenderStates.SampleState);
}
}
}
}

View File

@ -20,6 +20,7 @@ namespace Oyster
static Core::Buffer VPData;
static Core::Init::State Init();
static void Clean();
};
}
}

View File

@ -6,6 +6,7 @@
// Copyright (c) Stefan Petersson 2011. All rights reserved.
//--------------------------------------------------------------------------------------
#define NOMINMAX
#include <vld.h>
#include <Windows.h>
#include "DllInterfaces\GFXAPI.h"
@ -16,7 +17,7 @@
//--------------------------------------------------------------------------------------
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
Oyster::Graphics::Model::Model* m = new Oyster::Graphics::Model::Model();
Oyster::Graphics::Model::Model* m = NULL;
Oyster::Math::Float4x4 V;
Oyster::Math::Float4x4 P;
@ -90,6 +91,8 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdL
}
}
Oyster::Graphics::API::DeleteModel(m);
Oyster::Graphics::API::Clean();
return (int) msg.wParam;
}
@ -183,7 +186,7 @@ HRESULT InitDirect3D()
#pragma endregion
#pragma region Obj
m = Oyster::Graphics::API::CreateModel(L"orca_dummy.obj");
m = Oyster::Graphics::API::CreateModel(L"orca");
#pragma endregion

View File

@ -71,24 +71,32 @@
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\Bin\Executable\$(ProjectName)\</OutDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\Bin\Executable\$(ProjectName)\</OutDir>
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
<IncludePath>C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\Bin\Executable\$(ProjectName)\</OutDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\Bin\Executable\$(ProjectName)\</OutDir>
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
<IncludePath>C:\Program Files (x86)\Visual Leak Detector\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>