Преглед изворни кода

Importer uses newly added TextureData

Marko Pintera пре 13 година
родитељ
комит
7510922d21

+ 3 - 20
CamelotD3D9Renderer/Include/CmD3D9Texture.h

@@ -77,24 +77,13 @@ namespace CamelotEngine {
 		bool mHwGammaWriteSupported;
 		D3DMULTISAMPLE_TYPE mFSAAType;
 		DWORD mFSAAQuality;
-		
-		// TODO PORT - Loading tex from streams not supported
-        // needed to store data between prepareImpl and loadImpl
-        //typedef SharedPtr<vector<MemoryDataStreamPtr>::type > LoadedStreams;
 
 		/// internal method, load a cube texture
-		//void _loadCubeTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams);
+		//void _loadCubeTex(IDirect3DDevice9* d3d9Device, const vector<DataStreamPtr>::type& imageDataStreams);
 		/// internal method, load a normal texture
-		//void _loadNormTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams);
+		//void _loadNormTex(IDirect3DDevice9* d3d9Device, const vector<DataStreamPtr>::type& imageDataStreams);
 		/// internal method, load a volume texture
-		//void _loadVolumeTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams);
-
-		/// internal method, prepare a cube texture
-		//LoadedStreams _prepareCubeTex();
-		/// internal method, prepare a normal texture
-		//LoadedStreams _prepareNormTex();
-		/// internal method, prepare a volume texture
-		//LoadedStreams _prepareVolumeTex();
+		//void _loadVolumeTex(IDirect3DDevice9* d3d9Device, const vector<DataStreamPtr>::type& imageDataStreams);
 
 		/// internal method, create a blank normal 1D/2D texture		
 		void _createNormTex(IDirect3DDevice9* d3d9Device);
@@ -144,12 +133,6 @@ namespace CamelotEngine {
         void loadImpl();		 
 		/// Loads this texture into the specified device.
 		void loadImpl(IDirect3DDevice9* d3d9Device);
-        /// overriden from Resource
-        void prepareImpl();
-        /// overriden from Resource
-        void unprepareImpl();
-		/// overriden from Resource
-		void postLoadImpl();
 
 		/// gets the texture resources attached to the given device.
 		TextureResources* getTextureResources(IDirect3DDevice9* d3d9Device);

+ 136 - 260
CamelotD3D9Renderer/Source/CmD3D9Texture.cpp

@@ -245,129 +245,6 @@ namespace CamelotEngine
 		//	OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::loadImpl" );
 		//}				
 	}
-	/****************************************************************************************/
-	void D3D9Texture::prepareImpl()
-	{		
-		if (mUsage & TU_RENDERTARGET)
-		{
-			return;
-		}
-
-		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
-		
-		// TODO PORT - Loading tex from streams not supported
-  //      LoadedStreams loadedStreams;
-
-		//// prepare load based on tex.type
-		//switch (getTextureType())
-		//{
-		//case TEX_TYPE_1D:
-		//case TEX_TYPE_2D:
-		//	loadedStreams = _prepareNormTex();
-		//	break;
-		//case TEX_TYPE_3D:
-		//	loadedStreams = _prepareVolumeTex();
-		//	break;
-		//case TEX_TYPE_CUBE_MAP:
-		//	loadedStreams = _prepareCubeTex();
-		//	break;
-		//default:
-		//	OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::prepareImpl" );
-		//}
-
-		//mLoadedStreams = loadedStreams;		
-	}
-    /****************************************************************************************/
-	// TODO PORT - Loading tex from streams not supported
-	//D3D9Texture::LoadedStreams D3D9Texture::_prepareCubeTex()
-	//{
-	//	assert(getTextureType() == TEX_TYPE_CUBE_MAP);
-
- //       LoadedStreams loadedStreams = LoadedStreams(new vector<MemoryDataStreamPtr>::type());
- //       // DDS load?
-	//	if (getSourceFileType() == "dds")
-	//	{
- //           // find & load resource data
-	//		DataStreamPtr dstream = 
-	//			ResourceGroupManager::getSingleton().openResource(
-	//				mName, mGroup, true, this);
- //           loadedStreams->push_back(MemoryDataStreamPtr(new MemoryDataStream(dstream)));
- //       }
- //       else
- //       {
-	//		// Load from 6 separate files
-	//		// Use OGRE its own codecs
-	//		String baseName, ext;
-	//		size_t pos = mName.find_last_of(".");
-	//		baseName = mName.substr(0, pos);
-	//		if ( pos != String::npos )
-	//			ext = mName.substr(pos+1);
-	//		static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"};
-
-	//		for(size_t i = 0; i < 6; i++)
-	//		{
-	//			String fullName = baseName + suffixes[i];
-	//			if (!ext.empty())
-	//				fullName = fullName + "." + ext;
-
- //           	// find & load resource data intro stream to allow resource
-	//			// group changes if required
-	//			DataStreamPtr dstream = 
-	//				ResourceGroupManager::getSingleton().openResource(
-	//					fullName, mGroup, true, this);
-
- //               loadedStreams->push_back(MemoryDataStreamPtr(new MemoryDataStream(dstream)));
-	//		}
- //       }
-
- //       return loadedStreams;
-	//}
-	/****************************************************************************************/
-	// TODO PORT - Loading tex from streams not supported
-	//D3D9Texture::LoadedStreams D3D9Texture::_prepareVolumeTex()
-	//{
-	//	assert(getTextureType() == TEX_TYPE_3D);
-
-	//	// find & load resource data
-	//	DataStreamPtr dstream = 
-	//		ResourceGroupManager::getSingleton().openResource(
-	//			mName, mGroup, true, this);
-
- //       LoadedStreams loadedStreams = LoadedStreams(new vector<MemoryDataStreamPtr>::type());
- //       loadedStreams->push_back(MemoryDataStreamPtr(new MemoryDataStream(dstream)));
- //       return loadedStreams;
- //   }
-	/****************************************************************************************/
-	// TODO PORT - Loading tex from streams not supported
-	//D3D9Texture::LoadedStreams D3D9Texture::_prepareNormTex()
-	//{
-	//	assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D);
-
-	//	// find & load resource data
-	//	DataStreamPtr dstream = 
-	//		ResourceGroupManager::getSingleton().openResource(
-	//			mName, mGroup, true, this);
-
- //       LoadedStreams loadedStreams = LoadedStreams(new vector<MemoryDataStreamPtr>::type());
- //       loadedStreams->push_back(MemoryDataStreamPtr(new MemoryDataStream(dstream)));
- //       return loadedStreams;
-	//}
-	/****************************************************************************************/
-	void D3D9Texture::unprepareImpl()
-	{		
-		if (mUsage & TU_RENDERTARGET)
-		{
-			return;
-		}   
-	}
-
-	/****************************************************************************************/
-	void D3D9Texture::postLoadImpl(void)
-	{
-		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
-		// TODO PORT - Loading tex from streams not supported
-		//mLoadedStreams.setNull();
-	}	
 
 	/****************************************************************************************/
 	void D3D9Texture::freeInternalResources(void)
@@ -425,11 +302,11 @@ namespace CamelotEngine
 	{				
 		D3D9_DEVICE_ACCESS_CRITICAL_SECTION
 			
-		prepareImpl();		
+			/*		prepareImpl();		
 
-		loadImpl(d3d9Device);
+			loadImpl(d3d9Device);
 
-		postLoadImpl();				
+			postLoadImpl();	*/			
 	}
 
 	/****************************************************************************************/
@@ -715,146 +592,145 @@ namespace CamelotEngine
 		//}
 //    }
 	/****************************************************************************************/
-// TODO PORT - Loading tex from streams not supported
-//	void D3D9Texture::_loadNormTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams)
-//	{
-		// TODO PORT - Loading tex from streams not supported
-		//assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D);
-		//// DDS load?
-		//if (getSourceFileType() == "dds")
-		//{
-		//	// Use D3DX
-  //          assert(loadedStreams->size()==1);
-	
-		//	DWORD usage = 0;
-		//	UINT numMips;
-
-		//	if (mNumRequestedMipmaps == MIP_UNLIMITED)
-		//		numMips = D3DX_DEFAULT;
-		//	else if (mNumRequestedMipmaps == 0)			
-		//		numMips = D3DX_FROM_FILE;
-		//	else
-		//		numMips = static_cast<UINT>(mNumRequestedMipmaps + 1);
-		//		
-		//	D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
-		//	const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();			
-
-
-		//	// check if mip map volume textures are supported
-		//	if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
-		//	{
-		//		// no mip map support for this kind of textures :(
-		//		mNumMipmaps = 0;
-		//		numMips = 1;
-		//	}
-
-  //          // Determine D3D pool to use
-  //          D3DPOOL pool;
-  //          if (useDefaultPool())
-  //          {
-  //              pool = D3DPOOL_DEFAULT;
-  //          }
-  //          else
-  //          {
-  //              pool = D3DPOOL_MANAGED;
-  //          }
-		//				
-		//	TextureResources* textureResources;			
-		//	
-		//	// Get or create new texture resources structure.
-		//	textureResources = getTextureResources(d3d9Device);
-		//	if (textureResources != NULL)
-		//		freeTextureResources(d3d9Device, textureResources);
-		//	else
-		//		textureResources = allocateTextureResources(d3d9Device);
-
-		//	HRESULT hr;
-
-		//	hr = D3DXCreateTextureFromFileInMemoryEx(
-		//		d3d9Device,
-		//		(*loadedStreams)[0]->getPtr(),
-		//		static_cast<UINT>((*loadedStreams)[0]->size()),
-		//		D3DX_DEFAULT, D3DX_DEFAULT, // dims
-		//		numMips,
-		//		usage,
-		//		D3DFMT_UNKNOWN,
-		//		pool,
-		//		D3DX_DEFAULT,
-		//		D3DX_DEFAULT,
-		//		0,  // colour key
-		//		NULL, // src box
-		//		NULL, // palette
-		//		&textureResources->pNormTex); 
-	
-		//	if (FAILED(hr))
-		//	{
-		//		OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
-		//			"Unable to load texture from :" + String(DXGetErrorDescription(hr)),
-		//			"D3D9Texture::_loadNormTex");
-		//	}
-	
-		//	hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
-	
-		//	if (FAILED(hr))
-		//	{
-		//		freeInternalResources();
-		//		OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), 
-		//			"D3D9Texture::_loadNormTex" );
-		//	}
-	
-		//	D3DSURFACE_DESC texDesc;
-		//	textureResources->pNormTex->GetLevelDesc(0, &texDesc);
-  //          mD3DPool = texDesc.Pool;
-		//	// set src and dest attributes to the same, we can't know
-		//	_setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
-		//	_setFinalAttributes(d3d9Device, textureResources, 
-		//		texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
+ 
+	//void D3D9Texture::_loadNormTex(IDirect3DDevice9* d3d9Device, const vector<DataStreamPtr>::type& imageDataStreams)
+	//{
+	//	assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D);
+	//	// DDS load?
+	//	if (getSourceFileType() == "dds")
+	//	{
+	//		// Use D3DX
+ //           assert(imageDataStreams->size()==1);
+	//
+	//		DWORD usage = 0;
+	//		UINT numMips;
+
+	//		if (mNumRequestedMipmaps == MIP_UNLIMITED)
+	//			numMips = D3DX_DEFAULT;
+	//		else if (mNumRequestedMipmaps == 0)			
+	//			numMips = D3DX_FROM_FILE;
+	//		else
+	//			numMips = static_cast<UINT>(mNumRequestedMipmaps + 1);
+	//			
+	//		D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
+	//		const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();			
+
+
+	//		// check if mip map volume textures are supported
+	//		if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
+	//		{
+	//			// no mip map support for this kind of textures :(
+	//			mNumMipmaps = 0;
+	//			numMips = 1;
+	//		}
 
-		//	if( mHwGamma )
-		//	{
-		//		mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage,
-		//																D3DRTYPE_TEXTURE,
-		//																texDesc.Format, false);
-		//	}
-		//	mInternalResourcesCreated = true;
-  //      }
-		//else
-		//{
-		//	Image img;
-  //         	// find & load resource data intro stream to allow resource
-		//	// group changes if required
-  //          assert(loadedStreams->size()==1);
-	
-		//	size_t pos = mName.find_last_of(".");
-		//	String ext; 
-		//	if ( pos != String::npos )
-		//		ext = mName.substr(pos+1);
+ //           // Determine D3D pool to use
+ //           D3DPOOL pool;
+ //           if (useDefaultPool())
+ //           {
+ //               pool = D3DPOOL_DEFAULT;
+ //           }
+ //           else
+ //           {
+ //               pool = D3DPOOL_MANAGED;
+ //           }
+	//					
+	//		TextureResources* textureResources;			
+	//		
+	//		// Get or create new texture resources structure.
+	//		textureResources = getTextureResources(d3d9Device);
+	//		if (textureResources != NULL)
+	//			freeTextureResources(d3d9Device, textureResources);
+	//		else
+	//			textureResources = allocateTextureResources(d3d9Device);
+
+	//		HRESULT hr;
+
+	//		hr = D3DXCreateTextureFromFileInMemoryEx(
+	//			d3d9Device,
+	//			(*loadedStreams)[0]->getPtr(),
+	//			static_cast<UINT>((*loadedStreams)[0]->size()),
+	//			D3DX_DEFAULT, D3DX_DEFAULT, // dims
+	//			numMips,
+	//			usage,
+	//			D3DFMT_UNKNOWN,
+	//			pool,
+	//			D3DX_DEFAULT,
+	//			D3DX_DEFAULT,
+	//			0,  // colour key
+	//			NULL, // src box
+	//			NULL, // palette
+	//			&textureResources->pNormTex); 
+	//
+	//		if (FAILED(hr))
+	//		{
+	//			OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
+	//				"Unable to load texture from :" + String(DXGetErrorDescription(hr)),
+	//				"D3D9Texture::_loadNormTex");
+	//		}
+	//
+	//		hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
+	//
+	//		if (FAILED(hr))
+	//		{
+	//			freeInternalResources();
+	//			OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), 
+	//				"D3D9Texture::_loadNormTex" );
+	//		}
+	//
+	//		D3DSURFACE_DESC texDesc;
+	//		textureResources->pNormTex->GetLevelDesc(0, &texDesc);
+ //           mD3DPool = texDesc.Pool;
+	//		// set src and dest attributes to the same, we can't know
+	//		_setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
+	//		_setFinalAttributes(d3d9Device, textureResources, 
+	//			texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
+
+	//		if( mHwGamma )
+	//		{
+	//			mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage,
+	//																	D3DRTYPE_TEXTURE,
+	//																	texDesc.Format, false);
+	//		}
+	//		mInternalResourcesCreated = true;
+ //       }
+	//	else
+	//	{
+	//		Image img;
+ //          	// find & load resource data intro stream to allow resource
+	//		// group changes if required
+ //           assert(loadedStreams->size()==1);
+	//
+	//		size_t pos = mName.find_last_of(".");
+	//		String ext; 
+	//		if ( pos != String::npos )
+	//			ext = mName.substr(pos+1);
 
-		//	DataStreamPtr stream((*loadedStreams)[0]);
-		//	img.load(stream, ext);
+	//		DataStreamPtr stream((*loadedStreams)[0]);
+	//		img.load(stream, ext);
 
-		//	if (img.getHeight() == 0)
-		//	{
-		//		OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
-		//			"Image height == 0 in " + getName(),
-		//			"D3D9Texture::_loadNormTex");
-		//	}
+	//		if (img.getHeight() == 0)
+	//		{
+	//			OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
+	//				"Image height == 0 in " + getName(),
+	//				"D3D9Texture::_loadNormTex");
+	//		}
 
-		//	if (img.getWidth() == 0)
-		//	{
-		//		OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
-		//			"Image width == 0 in " + getName(),
-		//			"D3D9Texture::_loadNormTex");
-		//	}
+	//		if (img.getWidth() == 0)
+	//		{
+	//			OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
+	//				"Image width == 0 in " + getName(),
+	//				"D3D9Texture::_loadNormTex");
+	//		}
 
-		//	// Call internal _loadImages, not loadImage since that's external and 
-		//	// will determine load status etc again
-		//	ConstImagePtrList imagePtrs;
-		//	imagePtrs.push_back(&img);
-		//	_loadImages( imagePtrs );
-		//}
+	//		// Call internal _loadImages, not loadImage since that's external and 
+	//		// will determine load status etc again
+	//		ConstImagePtrList imagePtrs;
+	//		imagePtrs.push_back(&img);
+	//		_loadImages( imagePtrs );
+	//	}
 
-//	}
+	//}
 
 	/****************************************************************************************/
 	size_t D3D9Texture::calculateSize(void) const

+ 1 - 15
CamelotFreeImgImporter/Include/CmFreeImgImporter.h

@@ -1,7 +1,6 @@
 #include "CmFreeImgPrerequisites.h"
 #include "CmSpecificImporter.h"
 #include "CmImporter.h"
-#include "CmPixelUtil.h"
 
 namespace CamelotEngine
 {
@@ -27,20 +26,7 @@ namespace CamelotEngine
 		std::unordered_map<String, int> mExtensionToFID;
 
 		String magicNumToExtension(const UINT8* magic, UINT32 maxBytes) const;
-		RawImageData importRawImage(DataStream* fileData);
-
-		struct RawImageData
-		{
-			RawImageData()
-				:width(0), height(0), size(0), format(PF_UNKNOWN)
-			{ }
-
-			UINT32 width;
-			UINT32 height;
-			UINT32 size;
-			PixelFormat format;
-			MemoryDataStreamPtr data;
-		};
+		TextureDataPtr importRawImage(DataStream* fileData);
 
 		class InitOnStart
 		{

+ 29 - 29
CamelotFreeImgImporter/Source/CmFreeImgImporter.cpp

@@ -3,6 +3,7 @@
 #include "CmDebug.h"
 #include "CmDataStream.h"
 #include "CmPath.h"
+#include "CmTextureData.h"
 
 #include "FreeImage.h"
 
@@ -125,15 +126,15 @@ namespace CamelotEngine
 
 	ResourcePtr FreeImgImporter::import(DataStream* fileData)
 	{
-		RawImageData imgData = importRawImage(fileData);
-		if(imgData.data == nullptr)
+		TextureDataPtr imgData = importRawImage(fileData);
+		if(imgData == nullptr || imgData->getData() == nullptr)
 			return nullptr;
 
 
 		return nullptr;
 	}
 
-	FreeImgImporter::RawImageData FreeImgImporter::importRawImage(DataStream* fileData)
+	TextureDataPtr FreeImgImporter::importRawImage(DataStream* fileData)
 	{
 		size_t magicLen = std::min(fileData->size(), (size_t)32);
 		UINT8 magicBuf[32];
@@ -165,10 +166,9 @@ namespace CamelotEngine
 			CM_EXCEPT(InternalErrorException, "Error decoding image");
 		}
 
-		RawImageData imageData;
-		imageData.width = FreeImage_GetWidth(fiBitmap);
-		imageData.height = FreeImage_GetHeight(fiBitmap);
-		imageData.format = PF_UNKNOWN;
+		UINT32 width = FreeImage_GetWidth(fiBitmap);
+		UINT32 height = FreeImage_GetHeight(fiBitmap);
+		PixelFormat format = PF_UNKNOWN;
 
 		// Must derive format first, this may perform conversions
 
@@ -216,19 +216,19 @@ namespace CamelotEngine
 			switch(bpp)
 			{
 			case 8:
-				imageData.format = PF_L8;
+				format = PF_L8;
 				break;
 			case 16:
 				// Determine 555 or 565 from green mask
 				// cannot be 16-bit greyscale since that's FIT_UINT16
 				if(FreeImage_GetGreenMask(fiBitmap) == FI16_565_GREEN_MASK)
 				{
-					imageData.format = PF_R5G6B5;
+					format = PF_R5G6B5;
 				}
 				else
 				{
 					// FreeImage doesn't support 4444 format so must be 1555
-					imageData.format = PF_A1R5G5B5;
+					format = PF_A1R5G5B5;
 				}
 				break;
 			case 24:
@@ -236,16 +236,16 @@ namespace CamelotEngine
 				//     PF_BYTE_BGR[A] for little endian (== PF_ARGB native)
 				//     PF_BYTE_RGB[A] for big endian (== PF_RGBA native)
 #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
-				imageData.format = PF_BYTE_RGB;
+				format = PF_BYTE_RGB;
 #else
-				imageData.format = PF_BYTE_BGR;
+				format = PF_BYTE_BGR;
 #endif
 				break;
 			case 32:
 #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
-				imageData.format = PF_BYTE_RGBA;
+				format = PF_BYTE_RGBA;
 #else
-				imageData.format = PF_BYTE_BGRA;
+				format = PF_BYTE_BGRA;
 #endif
 				break;
 
@@ -255,23 +255,23 @@ namespace CamelotEngine
 		case FIT_UINT16:
 		case FIT_INT16:
 			// 16-bit greyscale
-			imageData.format = PF_L16;
+			format = PF_L16;
 			break;
 		case FIT_FLOAT:
 			// Single-component floating point data
-			imageData.format = PF_FLOAT32_R;
+			format = PF_FLOAT32_R;
 			break;
 		case FIT_RGB16:
-			imageData.format = PF_SHORT_RGB;
+			format = PF_SHORT_RGB;
 			break;
 		case FIT_RGBA16:
-			imageData.format = PF_SHORT_RGBA;
+			format = PF_SHORT_RGBA;
 			break;
 		case FIT_RGBF:
-			imageData.format = PF_FLOAT32_RGB;
+			format = PF_FLOAT32_RGB;
 			break;
 		case FIT_RGBAF:
-			imageData.format = PF_FLOAT32_RGBA;
+			format = PF_FLOAT32_RGBA;
 			break;
 
 
@@ -281,16 +281,17 @@ namespace CamelotEngine
 		unsigned srcPitch = FreeImage_GetPitch(fiBitmap);
 
 		// Final data - invert image and trim pitch at the same time
-		size_t dstPitch = imageData.width * PixelUtil::getNumElemBytes(imageData.format);
-		size_t size = dstPitch * imageData.height;
+		size_t dstPitch = width * PixelUtil::getNumElemBytes(format);
+		size_t size = dstPitch * height;
+
 		// Bind output buffer
-		MemoryDataStreamPtr output(new MemoryDataStream(size));
+		UINT8* output = new UINT8[size]; // TextureData frees this when its released
 
 		UINT8* pSrc;
-		UINT8* pDst = output->getPtr();
-		for (size_t y = 0; y < imageData.height; ++y)
+		UINT8* pDst = output;
+		for (size_t y = 0; y < height; ++y)
 		{
-			pSrc = srcData + (imageData.height - y - 1) * srcPitch;
+			pSrc = srcData + (height - y - 1) * srcPitch;
 			memcpy(pDst, pSrc, dstPitch);
 			pDst += dstPitch;
 		}
@@ -298,8 +299,7 @@ namespace CamelotEngine
 		FreeImage_Unload(fiBitmap);
 		FreeImage_CloseMemory(fiMem);
 
-		imageData.data = output;
-
-		return imageData;
+		TextureDataPtr texData(new TextureData(width, height, size, format, output, 1, 0, 1));
+		return texData;
 	}
 }

+ 14 - 4
CamelotRenderer/TODO.txt

@@ -45,11 +45,17 @@ TODO:
  - OpenGL too
 
 TOMORROW:
- Add wrapper around IO methods
+TextureData
+ - Keeps num mips, width, height, depth, format, flags and raw image data that can be used for initializing textures
+ - Will need some methods like getPixelBox, from OgreImage
+ - Cube textures require 6 of these
+ - When serializing this texture, request data from GPU, populate TextureData array and return
+
+Texture
+ - Gets initialized by calling SetData(vector<TextureData). 
+ - Returns TextureData by GetData (retrieves data from GPU)
  Continue working on Importer, Resources (IMPORTANT - AssetDatabase in a single file probably won't work. Multiple people won't be able to work on it. Unless we make it part of a local cache?)
  Try to fully implement free image and maybe FBX importers
- Log class should be able to accept different channels, other than the predetermined ones
- Extend the Path library
   - Less important notes:
     - All of this must be thread safe to allow for background loading
     - Make sure all resources have default resource that will be used before actual resource is loaded
@@ -59,6 +65,8 @@ TOMORROW:
 Other notes:
  - Search for all remaining "TODO PORT" comments and fix them
  - How am I notified on device reset? (When I need to reload my resources)
+ - D3D9Texture::createTextureResources is commented out at the moment. It gets called on device reset, and at that point
+     I should reload texture resources.
  - If possible, make sure GLSL uses EntryPoint and Profile fields I have added to GpuProgram
  - Remove all fixed pipeline methods from D3D9 and OpenGL renderers
  - Make CamelotRenderer a project on its own?
@@ -81,4 +89,6 @@ After everything is polished:
    - Actually I should re-read most of the chapers in the book, or all of it
 
  - OpenGL non-Win32 window files haven't been properly parsed or tested
-   - Since I probably can't compile them, try adding them to VS and see what intellisense says?
+   - Since I probably can't compile them, try adding them to VS and see what intellisense says?
+
+ - Textures and all other buffers keep a copy of their data in system memory. If there are memory constraints we might need a way to avoid this.

+ 4 - 0
CamelotUtility/CamelotUtility.vcxproj

@@ -109,6 +109,10 @@
     <ClInclude Include="Include\CmVector4.h" />
     <ClInclude Include="Include\CmDynLib.h" />
     <ClInclude Include="Include\CmDataStream.h" />
+    <ClInclude Include="Include\CmTextureData.h" />
+    <ClCompile Include="Source\CmTextureData.cpp">
+      <FileType>CppHeader</FileType>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Include\CmAxisAlignedBox.cpp" />

+ 6 - 0
CamelotUtility/CamelotUtility.vcxproj.filters

@@ -123,6 +123,9 @@
     <ClInclude Include="Include\CmDataStream.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmTextureData.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Include\CmAxisAlignedBox.cpp">
@@ -179,5 +182,8 @@
     <ClCompile Include="Source\CmDataStream.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmTextureData.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 8 - 8
CamelotUtility/Include/CmDataStream.h

@@ -371,7 +371,7 @@ namespace CamelotEngine
     /** Common subclass of DataStream for handling data from 
 		std::basic_istream.
 	*/
-	class CM_UTILITY_EXPORT FileStreamDataStream : DataStream
+	class CM_UTILITY_EXPORT FileDataStream : DataStream
 	{
 	protected:
 		/// Reference to source stream (read)
@@ -389,14 +389,14 @@ namespace CamelotEngine
         @param freeOnClose Whether to delete the underlying stream on 
             destruction of this class
         */
-		FileStreamDataStream(std::ifstream* s, 
+		FileDataStream(std::ifstream* s, 
             bool freeOnClose = true);
 		/** Construct a read-write stream from an STL stream
 		@param s Pointer to source stream
 		@param freeOnClose Whether to delete the underlying stream on 
 		destruction of this class
 		*/
-		FileStreamDataStream(std::fstream* s, 
+		FileDataStream(std::fstream* s, 
 			bool freeOnClose = true);
 
 		/** Construct named read-only stream from an STL stream
@@ -405,7 +405,7 @@ namespace CamelotEngine
         @param freeOnClose Whether to delete the underlying stream on 
             destruction of this class
         */
-		FileStreamDataStream(const String& name, 
+		FileDataStream(const String& name, 
             std::ifstream* s, 
             bool freeOnClose = true);
 
@@ -415,7 +415,7 @@ namespace CamelotEngine
 		@param freeOnClose Whether to delete the underlying stream on 
 		destruction of this class
 		*/
-		FileStreamDataStream(const String& name, 
+		FileDataStream(const String& name, 
 			std::fstream* s, 
 			bool freeOnClose = true);
 
@@ -433,7 +433,7 @@ namespace CamelotEngine
 			must ensure that the stream was allocated using OGRE_NEW_T with 
 			MEMCATEGRORY_GENERAL.
         */
-		FileStreamDataStream(const String& name, 
+		FileDataStream(const String& name, 
             std::ifstream* s, 
             size_t size, 
             bool freeOnClose = true);
@@ -452,12 +452,12 @@ namespace CamelotEngine
 		must ensure that the stream was allocated using OGRE_NEW_T with 
 		MEMCATEGRORY_GENERAL.
 		*/
-		FileStreamDataStream(const String& name, 
+		FileDataStream(const String& name, 
 			std::fstream* s, 
 			size_t size, 
 			bool freeOnClose = true);
 
-		~FileStreamDataStream();
+		~FileDataStream();
 
 		/** @copydoc DataStream::read
 		*/

+ 4 - 0
CamelotUtility/Include/CmFwdDeclUtil.h

@@ -24,6 +24,10 @@ namespace CamelotEngine {
 	class DataStream;
 	class MemoryDataStream;
 	class FileDataStream;
+	class TextureData;
 
+	typedef std::shared_ptr<DataStream> DataStreamPtr;
 	typedef std::shared_ptr<MemoryDataStream> MemoryDataStreamPtr;
+	typedef std::shared_ptr<FileDataStream> FileDataStreamPtr;
+	typedef std::shared_ptr<TextureData> TextureDataPtr;
 }

+ 87 - 0
CamelotUtility/Include/CmTextureData.h

@@ -0,0 +1,87 @@
+#pragma once
+
+#include "CmPrerequisitesUtil.h"
+#include "CmPixelUtil.h"
+
+namespace CamelotEngine
+{
+	enum TextureDataFlags
+	{
+		TDF_COMPRESSED = 0x00000001,
+		TDF_CUBEMAP    = 0x00000002,
+		TDF_3D_TEXTURE = 0x00000004
+	};
+
+	class CM_UTILITY_EXPORT TextureData
+	{
+	public:
+		TextureData(UINT32 width, UINT32 height, UINT32 size, 
+			PixelFormat format, UINT8* data, UINT32 depth = 1, INT32 flags = 0, UINT32 numMipmaps = 1);
+		~TextureData();
+
+		/** Returns a pointer to the internal image buffer.
+		@remarks
+			Be careful with this method. You will almost certainly
+			prefer to use getPixels, especially with complex images
+			which include custom mipmaps.
+        */
+        UINT8* getData(void) { return mData; }
+
+        /** Returns a const pointer to the internal image buffer.
+		@remarks
+			Be careful with this method. You will almost certainly
+			prefer to use getPixels, especially with complex images
+			which include custom mipmaps.
+        */
+        const UINT8* getData() const { return mData; } 
+
+        /** Returns the size of the data buffer.
+        */
+		UINT32 getSize() const { return mSize; }
+
+        /** Returns the number of mipmaps contained in the image.
+        */
+		UINT32 getNumMipmaps() const { return mNumMipmaps; }
+
+        /** Returns true if the image has the appropriate flag set.
+        */
+		bool hasFlag(const TextureDataFlags flag) const { return (mFlags & flag); }
+
+        /** Gets the width of the image in pixels.
+        */
+        UINT32 getWidth(void) const { return mWidth; }
+
+        /** Gets the height of the image in pixels.
+        */
+        UINT32 getHeight(void) const { return mHeight; }
+
+        /** Gets the depth of the image.
+        */
+        UINT32 getDepth(void) const { return mDepth; }
+
+        /** Returns the image format.
+        */
+        PixelFormat getFormat() const { return mFormat; }
+
+        /** Returns the number of bits per pixel.
+        */
+        UINT8 getBPP() const { return mBPP; }
+
+        /** Returns true if the image has an alpha component.
+        */
+        bool getHasAlpha() const { return PixelUtil::getFlags(mFormat) & PFF_HASALPHA; }
+
+		PixelData getPixels(UINT32 mip);
+
+	private:
+		UINT32 mNumMipmaps;
+		UINT32 mWidth;
+		UINT32 mHeight;
+		UINT32 mSize;
+		UINT32 mDepth;
+		INT32 mFlags;
+		UINT8 mBPP;
+		PixelFormat mFormat;
+		UINT8* mData;
+	};
+}

+ 16 - 16
CamelotUtility/Source/CmDataStream.cpp

@@ -469,7 +469,7 @@ namespace CamelotEngine
     }
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    FileStreamDataStream::FileStreamDataStream(std::ifstream* s, bool freeOnClose)
+    FileDataStream::FileDataStream(std::ifstream* s, bool freeOnClose)
         : DataStream(), mpInStream(s), mpFStreamRO(s), mpFStream(0), mFreeOnClose(freeOnClose)
     {
         // calculate the size
@@ -479,7 +479,7 @@ namespace CamelotEngine
 		determineAccess();
     }
     //-----------------------------------------------------------------------
-    FileStreamDataStream::FileStreamDataStream(const String& name, 
+    FileDataStream::FileDataStream(const String& name, 
         std::ifstream* s, bool freeOnClose)
         : DataStream(name), mpInStream(s), mpFStreamRO(s), mpFStream(0), mFreeOnClose(freeOnClose)
     {
@@ -490,7 +490,7 @@ namespace CamelotEngine
 		determineAccess();
     }
     //-----------------------------------------------------------------------
-    FileStreamDataStream::FileStreamDataStream(const String& name, 
+    FileDataStream::FileDataStream(const String& name, 
         std::ifstream* s, size_t inSize, bool freeOnClose)
         : DataStream(name), mpInStream(s), mpFStreamRO(s), mpFStream(0), mFreeOnClose(freeOnClose)
     {
@@ -499,7 +499,7 @@ namespace CamelotEngine
 		determineAccess();
     }
 	//---------------------------------------------------------------------
-	FileStreamDataStream::FileStreamDataStream(std::fstream* s, bool freeOnClose)
+	FileDataStream::FileDataStream(std::fstream* s, bool freeOnClose)
 		: DataStream(false), mpInStream(s), mpFStreamRO(0), mpFStream(s), mFreeOnClose(freeOnClose)
 	{
 		// writeable!
@@ -511,7 +511,7 @@ namespace CamelotEngine
 
 	}
 	//-----------------------------------------------------------------------
-	FileStreamDataStream::FileStreamDataStream(const String& name, 
+	FileDataStream::FileDataStream(const String& name, 
 		std::fstream* s, bool freeOnClose)
 		: DataStream(name, false), mpInStream(s), mpFStreamRO(0), mpFStream(s), mFreeOnClose(freeOnClose)
 	{
@@ -523,7 +523,7 @@ namespace CamelotEngine
 		determineAccess();
 	}
 	//-----------------------------------------------------------------------
-	FileStreamDataStream::FileStreamDataStream(const String& name, 
+	FileDataStream::FileDataStream(const String& name, 
 		std::fstream* s, size_t inSize, bool freeOnClose)
 		: DataStream(name, false), mpInStream(s), mpFStreamRO(0), mpFStream(s), mFreeOnClose(freeOnClose)
 	{
@@ -533,7 +533,7 @@ namespace CamelotEngine
 		determineAccess();
 	}
 	//---------------------------------------------------------------------
-	void FileStreamDataStream::determineAccess()
+	void FileDataStream::determineAccess()
 	{
 		mAccess = 0;
 		if (mpInStream)
@@ -542,18 +542,18 @@ namespace CamelotEngine
 			mAccess |= WRITE;
 	}
     //-----------------------------------------------------------------------
-    FileStreamDataStream::~FileStreamDataStream()
+    FileDataStream::~FileDataStream()
     {
         close();
     }
     //-----------------------------------------------------------------------
-    size_t FileStreamDataStream::read(void* buf, size_t count)
+    size_t FileDataStream::read(void* buf, size_t count)
     {
 		mpInStream->read(static_cast<char*>(buf), static_cast<std::streamsize>(count));
         return mpInStream->gcount();
     }
 	//-----------------------------------------------------------------------
-	size_t FileStreamDataStream::write(const void* buf, size_t count)
+	size_t FileDataStream::write(const void* buf, size_t count)
 	{
 		size_t written = 0;
 		if (isWriteable() && mpFStream)
@@ -564,7 +564,7 @@ namespace CamelotEngine
 		return written;
 	}
     //-----------------------------------------------------------------------
-    size_t FileStreamDataStream::readLine(char* buf, size_t maxCount, 
+    size_t FileDataStream::readLine(char* buf, size_t maxCount, 
         const String& delim)
     {
 		if (delim.empty())
@@ -627,7 +627,7 @@ namespace CamelotEngine
 		return ret;
 	}
     //-----------------------------------------------------------------------
-    void FileStreamDataStream::skip(long count)
+    void FileDataStream::skip(long count)
     {
 #if defined(STLPORT)
 		// Workaround for STLport issues: After reached eof of file stream,
@@ -646,24 +646,24 @@ namespace CamelotEngine
 		mpInStream->seekg(static_cast<std::ifstream::pos_type>(count), std::ios::cur);
     }
     //-----------------------------------------------------------------------
-    void FileStreamDataStream::seek( size_t pos )
+    void FileDataStream::seek( size_t pos )
     {
 		mpInStream->clear(); //Clear fail status in case eof was set
 		mpInStream->seekg(static_cast<std::streamoff>(pos), std::ios::beg);
 	}
 	//-----------------------------------------------------------------------
-    size_t FileStreamDataStream::tell(void) const
+    size_t FileDataStream::tell(void) const
 	{
 		mpInStream->clear(); //Clear fail status in case eof was set
 		return (size_t)mpInStream->tellg();
 	}
 	//-----------------------------------------------------------------------
-    bool FileStreamDataStream::eof(void) const
+    bool FileDataStream::eof(void) const
     {
         return mpInStream->eof();
     }
     //-----------------------------------------------------------------------
-    void FileStreamDataStream::close(void)
+    void FileDataStream::close(void)
     {
         if (mpInStream)
         {

+ 55 - 0
CamelotUtility/Source/CmTextureData.cpp

@@ -0,0 +1,55 @@
+#include "CmTextureData.h"
+#include "CmException.h"
+
+namespace CamelotEngine
+{
+	TextureData::TextureData(UINT32 width, UINT32 height, UINT32 size, 
+		PixelFormat format, UINT8* data, UINT32 depth, INT32 flags, UINT32 numMipmaps)
+		:mWidth(width), mHeight(height), mDepth(depth), mSize(size), mFormat(format),
+		mFlags(flags), mNumMipmaps(numMipmaps), mData(data)
+	{
+		mBPP = static_cast<UINT8>(PixelUtil::getNumElemBytes(mFormat)) * 8;
+	}
+
+	TextureData::~TextureData()
+	{
+		if(mData != nullptr)
+			delete[] mData;
+	}
+
+	PixelData TextureData::getPixels(UINT32 mip)
+	{
+		if(mip < 0 || mip >= mNumMipmaps)
+		{
+			CM_EXCEPT(InvalidParametersException, "Mip out of range: " + toString(mip) + ". While maximum available mip is: " + toString((mNumMipmaps)));
+		}
+
+		// Calculate mipmap offset and size
+		UINT8 *offset = const_cast<UINT8*>(getData());
+
+		UINT32 width = getWidth(), height = getHeight(), depth = getDepth();
+		UINT32 numMips = getNumMipmaps();
+
+		// Figure out the offsets 
+		UINT32 finalWidth = 0, finalHeight = 0, finalDepth = 0;
+		for(UINT32 curMip = 0; curMip <= numMips; ++curMip)
+		{
+			if (curMip == mip)
+			{
+				finalWidth = width;
+				finalHeight = height;
+				finalDepth = depth;
+			}
+			offset += PixelUtil::getMemorySize(width, height, depth, getFormat());
+
+			/// Half size in each dimension
+			if(width!=1) width /= 2;
+			if(height!=1) height /= 2;
+			if(depth!=1) depth /= 2;
+		}
+
+		// Return subface as pixelbox
+		PixelData src(finalWidth, finalHeight, finalDepth, getFormat(), offset);
+		return src;
+	}
+}