浏览代码

shared_ptr serialization tested

Marko Pintera 13 年之前
父节点
当前提交
ffa3f60dcb

+ 7 - 0
CamelotClient/TestingGround.cpp

@@ -2,6 +2,7 @@
 
 #include "CmFileSerializer.h"
 #include "CmResource.h"
+#include "CmTextureData.h"
 #include "CmTextureManager.h"
 
 using namespace CamelotEngine;
@@ -24,4 +25,10 @@ void test()
 
 	TexturePtr emptyTexture = TextureManager::instance().create(TEX_TYPE_2D, 512, 512, 1, PF_UNKNOWN);
 	fs.decode(emptyTexture, "C:\\DbgTexture.tex");
+
+
+	TextureDataPtr data = emptyTexture->mTextureData[0];
+	UINT32 size2 = data->getSize();
+
+	int a = 5;
 }

+ 20 - 8
CamelotRenderer/Include/CmTexture.h

@@ -335,11 +335,22 @@ namespace CamelotEngine {
 
 		/**
 		 * @brief	Retrieves the texture data from the GPU, loads it into system memory
-		 * 			and returns it in the form of TextureData for each face.
+		 * 			and returns it in the form of TextureData for the specified.
 		 *
-		 * @return	The texture data.
+		 * @return	Texture data for the wanted face.
 		 */
-		vector<TextureDataPtr>::type getTextureData();
+		TextureDataPtr getTextureData(int face);
+
+		/**
+		 * @brief	Sets the texture data that will be used for initializing the texture.
+		 * 			You must call loadFromTextureData after setting the data for all faces. 
+		 * 			Texture data array will be cleared after the texture is fully loaded.
+		 *
+		 * @param	face	  	The face index. Cubemaps have six faces in this order:
+		 * 						+X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5)
+		 * @param	textureData	Texture data for the face.
+		 */
+		void setTextureData(int face, TextureDataPtr textureData);
 
     protected:
         size_t mHeight;
@@ -367,10 +378,12 @@ namespace CamelotEngine {
 
 		bool mInternalResourcesCreated;
 
+		public:
+		vector<TextureDataPtr>::type mTextureData;
+		protected:
 		/// @copydoc Resource::calculateSize
 		size_t calculateSize(void) const;
 		
-
 		/** Implementation of creating internal texture resources 
 		*/
 		virtual void createInternalResourcesImpl(void) = 0;
@@ -380,13 +393,12 @@ namespace CamelotEngine {
 		virtual void freeInternalResourcesImpl(void) = 0;
 
 		/**
-		 * @brief	Loads the texture from TextureData array. Each entry in the array represents a single
-		 * 			face of the texture. For cubemaps there need be six faces in this order:
-		 * 			+X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5)
+		 * @brief	Initializes the texture from texture data array that was previously populated using
+		 * 			setTextureData. Array is cleared after this method finished.
 		 *
 		 * @param	textureData	Array with texture data for each face of the texture.
 		 */
-		virtual void loadFromTextureData(const vector<TextureDataPtr>::type& textureData);
+		virtual void initializeFromTextureData();
 
 		/** Default implementation of unload which calls freeInternalResources */
 		void unloadImpl(void);

+ 23 - 0
CamelotRenderer/Include/CmTextureST.h

@@ -30,6 +30,26 @@ namespace CamelotEngine
 		CM_SETGET_MEMBER(mDesiredIntegerBitDepth, UINT16, Texture)
 		CM_SETGET_MEMBER(mDesiredFloatBitDepth, UINT16, Texture)
 
+		std::shared_ptr<TextureData> getTextureData(Texture* obj, UINT32 face)
+		{
+			return obj->getTextureData(face);
+		}
+
+		void setTextureData(Texture* obj, UINT32 face, TextureDataPtr data)
+		{
+			return obj->setTextureData(face, data);
+		}
+
+		UINT32 getTextureDataArraySize(Texture* obj)
+		{
+			return obj->getNumFaces();
+		}
+
+		void setTextureDataArraySize(Texture* obj, UINT32 size)
+		{
+			// Not allowed to change size this way
+		}
+
 		//ManagedDataBlock getFaceData(Texture* obj)
 		//{
 		//	UINT32 totalSize = 0;
@@ -76,6 +96,9 @@ namespace CamelotEngine
 			CM_ADD_PLAINFIELD(mDesiredFormat, 15, TextureST)
 			CM_ADD_PLAINFIELD(mDesiredIntegerBitDepth, 16, TextureST)
 			CM_ADD_PLAINFIELD(mDesiredFloatBitDepth, 17, TextureST)
+
+			addReflectablePtrArrayField("mTextureData", 18, &TextureST::getTextureData, &TextureST::getTextureDataArraySize, 
+				&TextureST::setTextureData, &TextureST::setTextureDataArraySize);
 		}
 	};
 }

+ 52 - 40
CamelotRenderer/Source/CmTexture.cpp

@@ -127,72 +127,82 @@ namespace CamelotEngine {
 		}
 	}
 	//-----------------------------------------------------------------------------
-	vector<TextureDataPtr>::type Texture::getTextureData()
+	TextureDataPtr Texture::getTextureData(int face)
 	{
-		vector<TextureDataPtr>::type output;
+		if(face < 0 || face >= getNumFaces())
+		{
+			CM_EXCEPT(InvalidParametersException, "Face index out of range: " + toString(face));
+		}
 
-		UINT32 numFaces = getNumFaces();
 		UINT32 numMips = getNumMipmaps();
 
-		for(int i = 0; i < numFaces; i++)
-		{
-			UINT32 totalSize = 0;
-			UINT32 width = getWidth();
-			UINT32 height = getHeight();
-			UINT32 depth = getDepth();
+		UINT32 totalSize = 0;
+		UINT32 width = getWidth();
+		UINT32 height = getHeight();
+		UINT32 depth = getDepth();
 
-			for(int j = 0; j < numMips; j++)
-			{
-				UINT32 currentMipSize = PixelUtil::getMemorySize(
-						width, height, depth, mFormat);
+		for(int j = 0; j < numMips; j++)
+		{
+			UINT32 currentMipSize = PixelUtil::getMemorySize(
+					width, height, depth, mFormat);
 
-				totalSize += currentMipSize;
+			totalSize += currentMipSize;
 
-				if(width != 1) width /= 2;
-				if(height != 1) height /= 2;
-				if(depth != 1) depth /= 2;
-			}
+			if(width != 1) width /= 2;
+			if(height != 1) height /= 2;
+			if(depth != 1) depth /= 2;
+		}
 
-			UINT8* buffer = new UINT8[totalSize]; // TextureData frees this
-			TextureDataPtr texData(new TextureData(getWidth(), getHeight(), totalSize, mFormat, buffer, getDepth(), 0, getNumMipmaps()));
+		UINT8* buffer = new UINT8[totalSize]; // TextureData frees this
+		TextureDataPtr texData(new TextureData(getWidth(), getHeight(), totalSize, mFormat, buffer, getDepth(), 0, getNumMipmaps()));
 
-			for(int j = 0; j < numMips; j++)
-			{
-				PixelData pixels = texData->getPixels(j);
-				getBuffer(i, j)->blitToMemory(pixels);
-			}
+		for(int j = 0; j < numMips; j++)
+		{
+			PixelData pixels = texData->getPixels(j);
+			getBuffer(face, j)->blitToMemory(pixels);
+		}
 
-			output.push_back(texData);
+		return texData;
+	}
+	//-----------------------------------------------------------------------------
+	void Texture::setTextureData(int face, TextureDataPtr textureData)
+	{
+		if(face < 0 || face >= getNumFaces())
+		{
+			CM_EXCEPT(InvalidParametersException, "Face index out of range: " + toString(face));
 		}
 
-		return output;
+		if(mTextureData.size() <= face)
+			mTextureData.resize(face + 1);
+
+		mTextureData[face] = textureData;
 	}
 	//-----------------------------------------------------------------------------
-	void Texture::loadFromTextureData(const vector<TextureDataPtr>::type& textureData)
+	void Texture::initializeFromTextureData()
 	{
-		if(textureData.size() < 1)
+		if(mTextureData.size() < 1)
 			CM_EXCEPT(InvalidParametersException, "Cannot load empty vector of images");
 
 		if(getTextureType() == TEX_TYPE_CUBE_MAP)
 		{
-			if(textureData.size() != 6)
+			if(mTextureData.size() != 6)
 				CM_EXCEPT(InvalidParametersException, "Cube map textures require six faces.");
 		}
 		else
 		{
-			if(textureData.size() > 1)
+			if(mTextureData.size() > 1)
 			{
 				gDebug().log("Non-cube textures can only have one face. Loading only first face from the provided array.", "D3D9RenderSystem");
 			}
 		}
 
 		// Set desired texture size and properties from images[0]
-		mSrcWidth = mWidth = textureData[0]->getWidth();
-		mSrcHeight = mHeight = textureData[0]->getHeight();
-		mSrcDepth = mDepth = textureData[0]->getDepth();
+		mSrcWidth = mWidth = mTextureData[0]->getWidth();
+		mSrcHeight = mHeight = mTextureData[0]->getHeight();
+		mSrcDepth = mDepth = mTextureData[0]->getDepth();
 
 		// Get source image format and adjust if required
-		mSrcFormat = textureData[0]->getFormat();
+		mSrcFormat = mTextureData[0]->getFormat();
 
 		if (mDesiredFormat != PF_UNKNOWN)
 		{
@@ -206,11 +216,11 @@ namespace CamelotEngine {
 		}
 
 		// The custom mipmaps in the image have priority over everything
-		size_t imageMips = textureData[0]->getNumMipmaps();
+		size_t imageMips = mTextureData[0]->getNumMipmaps();
 
 		if(imageMips > 0)
 		{
-			mNumMipmaps = mNumRequestedMipmaps = textureData[0]->getNumMipmaps();
+			mNumMipmaps = mNumRequestedMipmaps = mTextureData[0]->getNumMipmaps();
 			// Disable flag for auto mip generation
 			mUsage &= ~TU_AUTOMIPMAP;
 		}
@@ -220,8 +230,8 @@ namespace CamelotEngine {
 		// Check if we're loading one image with multiple faces
 		// or a vector of images representing the faces
 		size_t faces;
-		if(textureData.size() > 1)
-			faces = textureData.size();
+		if(mTextureData.size() > 1)
+			faces = mTextureData.size();
 		else
 			faces = 1;
 
@@ -236,7 +246,7 @@ namespace CamelotEngine {
 		{
 			for(size_t i = 0; i < faces; ++i)
 			{
-				PixelData src = textureData[i]->getPixels(mip);
+				PixelData src = mTextureData[i]->getPixels(mip);
 
 				// Sets to treated format in case is difference
 				src.format = mSrcFormat;
@@ -269,6 +279,8 @@ namespace CamelotEngine {
 		}
 		// Update size (the final size, not including temp space)
 		mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
+
+		mTextureData.clear();
 	}
 	//-----------------------------------------------------------------------------
 	void Texture::unloadImpl(void)

+ 1 - 1
CamelotUtility/Include/CmRTTIReflectablePtrField.h

@@ -111,7 +111,7 @@ namespace CamelotEngine
 			}
 
 			ObjectType* castObjType = static_cast<ObjectType*>(object);
-			std::shared_ptr<DataType> castDataObj = static_pointer_cast<DataType>(value);
+			std::shared_ptr<DataType> castDataObj = std::static_pointer_cast<DataType>(value);
 			boost::function<void(ObjectType*, UINT32, std::shared_ptr<DataType>)> f = boost::any_cast<boost::function<void(ObjectType*, UINT32, std::shared_ptr<DataType>)>>(valueSetter);
 			f(castObjType, index, castDataObj);
 		}

+ 3 - 1
CamelotUtility/Source/CmTextureData.cpp

@@ -27,6 +27,7 @@ namespace CamelotEngine
 
 		// Calculate mipmap offset and size
 		UINT8 *offset = const_cast<UINT8*>(getData());
+		UINT8 offsetSoFar = 0;
 
 		UINT32 width = getWidth(), height = getHeight(), depth = getDepth();
 		UINT32 numMips = getNumMipmaps();
@@ -37,11 +38,12 @@ namespace CamelotEngine
 		{
 			if (curMip == mip)
 			{
+				offset += offsetSoFar;
 				finalWidth = width;
 				finalHeight = height;
 				finalDepth = depth;
 			}
-			offset += PixelUtil::getMemorySize(width, height, depth, getFormat());
+			offsetSoFar += PixelUtil::getMemorySize(width, height, depth, getFormat());
 
 			/// Half size in each dimension
 			if(width!=1) width /= 2;