CmTexture.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2011 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "CmHardwarePixelBuffer.h"
  25. #include "CmTexture.h"
  26. #include "CmTextureRTTI.h"
  27. #include "CmTextureData.h"
  28. #include "CmDataStream.h"
  29. #include "CmException.h"
  30. #include "CmDebug.h"
  31. namespace CamelotEngine {
  32. //--------------------------------------------------------------------------
  33. Texture::Texture()
  34. : // init defaults; can be overridden before load()
  35. mHeight(512),
  36. mWidth(512),
  37. mDepth(1),
  38. mNumMipmaps(0),
  39. mHwGamma(false),
  40. mFSAA(0),
  41. mTextureType(TEX_TYPE_2D),
  42. mFormat(PF_UNKNOWN),
  43. mUsage(TU_DEFAULT),
  44. mInternalResourcesCreated(false)
  45. {
  46. }
  47. //-------------------------------------------------------------------------
  48. void Texture::initialize(TextureType textureType, size_t width, size_t height, size_t depth, size_t numMipmaps,
  49. PixelFormat format, int usage, bool hwGamma, UINT32 fsaa, const String& fsaaHint)
  50. {
  51. mTextureType = textureType;
  52. mWidth = width;
  53. mHeight = height;
  54. mDepth = depth;
  55. mNumMipmaps = numMipmaps;
  56. mFormat = format;
  57. mUsage = usage;
  58. mHwGamma = hwGamma;
  59. mFSAA = fsaa;
  60. mFSAAHint = fsaaHint;
  61. }
  62. //--------------------------------------------------------------------------
  63. bool Texture::hasAlpha(void) const
  64. {
  65. return PixelUtil::hasAlpha(mFormat);
  66. }
  67. //--------------------------------------------------------------------------
  68. size_t Texture::calculateSize(void) const
  69. {
  70. return getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
  71. }
  72. //--------------------------------------------------------------------------
  73. size_t Texture::getNumFaces(void) const
  74. {
  75. return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
  76. }
  77. //-----------------------------------------------------------------------------
  78. void Texture::createInternalResources(void)
  79. {
  80. if (!mInternalResourcesCreated)
  81. {
  82. createInternalResourcesImpl();
  83. mInternalResourcesCreated = true;
  84. }
  85. }
  86. //-----------------------------------------------------------------------------
  87. void Texture::freeInternalResources(void)
  88. {
  89. if (mInternalResourcesCreated)
  90. {
  91. freeInternalResourcesImpl();
  92. mInternalResourcesCreated = false;
  93. }
  94. }
  95. //-----------------------------------------------------------------------------
  96. TextureDataPtr Texture::getTextureData(UINT32 face)
  97. {
  98. if(face < 0 || face >= getNumFaces())
  99. {
  100. CM_EXCEPT(InvalidParametersException, "Face index out of range: " + toString(face));
  101. }
  102. UINT32 numMips = getNumMipmaps();
  103. UINT32 totalSize = 0;
  104. UINT32 width = getWidth();
  105. UINT32 height = getHeight();
  106. UINT32 depth = getDepth();
  107. for(UINT32 j = 0; j <= numMips; j++)
  108. {
  109. UINT32 currentMipSize = PixelUtil::getMemorySize(
  110. width, height, depth, mFormat);
  111. totalSize += currentMipSize;
  112. if(width != 1) width /= 2;
  113. if(height != 1) height /= 2;
  114. if(depth != 1) depth /= 2;
  115. }
  116. UINT8* buffer = new UINT8[totalSize]; // TextureData frees this
  117. TextureDataPtr texData(new TextureData(getWidth(), getHeight(), totalSize, mFormat, buffer, getDepth(), 0, getNumMipmaps()));
  118. for(UINT32 j = 0; j <= numMips; j++)
  119. {
  120. PixelData pixels = texData->getPixels(j);
  121. getBuffer(face, j)->blitToMemory(pixels);
  122. }
  123. return texData;
  124. }
  125. //-----------------------------------------------------------------------------
  126. void Texture::setTextureData(UINT32 face, TextureDataPtr textureData)
  127. {
  128. if(face < 0 || face >= getNumFaces())
  129. {
  130. CM_EXCEPT(InvalidParametersException, "Face index out of range: " + toString(face));
  131. }
  132. if(mTextureData.size() <= face)
  133. mTextureData.resize(face + 1);
  134. mTextureData[face] = textureData;
  135. }
  136. //-----------------------------------------------------------------------------
  137. void Texture::initializeFromTextureData()
  138. {
  139. if(mTextureData.size() < 1)
  140. CM_EXCEPT(InvalidParametersException, "Cannot load empty vector of images");
  141. if(getTextureType() == TEX_TYPE_CUBE_MAP)
  142. {
  143. if(mTextureData.size() != 6)
  144. CM_EXCEPT(InvalidParametersException, "Cube map textures require six faces.");
  145. }
  146. else
  147. {
  148. if(mTextureData.size() > 1)
  149. {
  150. gDebug().log("Non-cube textures can only have one face. Loading only first face from the provided array.", "D3D9RenderSystem");
  151. }
  152. }
  153. // Set desired texture size and properties from images[0]
  154. mWidth = mTextureData[0]->getWidth();
  155. mHeight = mTextureData[0]->getHeight();
  156. mDepth = mTextureData[0]->getDepth();
  157. // Get source image format and adjust if required
  158. PixelFormat srcFormat = mTextureData[0]->getFormat();
  159. // The custom mipmaps in the image have priority over everything
  160. size_t imageMips = mTextureData[0]->getNumMipmaps();
  161. if(imageMips > 0)
  162. {
  163. mNumMipmaps = mTextureData[0]->getNumMipmaps();
  164. }
  165. // Create the texture
  166. createInternalResources();
  167. // Check if we're loading one image with multiple faces
  168. // or a vector of images representing the faces
  169. size_t faces;
  170. if(mTextureData.size() > 1)
  171. faces = mTextureData.size();
  172. else
  173. faces = 1;
  174. // Check whether number of faces in images exceeds number of faces
  175. // in this texture. If so, clamp it.
  176. if(faces > getNumFaces())
  177. faces = getNumFaces();
  178. // Main loading loop
  179. // imageMips == 0 if the image has no custom mipmaps, otherwise contains the number of custom mips
  180. for(size_t mip = 0; mip<=imageMips; ++mip)
  181. {
  182. for(size_t i = 0; i < faces; ++i)
  183. {
  184. PixelData src = mTextureData[i]->getPixels(mip);
  185. // Sets to treated format in case is difference
  186. src.format = srcFormat;
  187. // Destination: entire texture. blitFromMemory does the scaling to
  188. // a power of two for us when needed
  189. getBuffer(i, mip)->blitFromMemory(src);
  190. }
  191. }
  192. // Update size (the final size, not including temp space)
  193. mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
  194. }
  195. //-----------------------------------------------------------------------------
  196. void Texture::unloadImpl(void)
  197. {
  198. freeInternalResources();
  199. }
  200. //-----------------------------------------------------------------------------
  201. void Texture::copyToTexture( TexturePtr& target )
  202. {
  203. if(target->getNumFaces() != getNumFaces())
  204. {
  205. CM_EXCEPT(InvalidParametersException,
  206. "Texture types must match");
  207. }
  208. size_t numMips = std::min(getNumMipmaps(), target->getNumMipmaps());
  209. for(unsigned int face=0; face<getNumFaces(); face++)
  210. {
  211. for(unsigned int mip=0; mip<=numMips; mip++)
  212. {
  213. target->getBuffer(face, mip)->blit(getBuffer(face, mip));
  214. }
  215. }
  216. }
  217. /************************************************************************/
  218. /* SERIALIZATION */
  219. /************************************************************************/
  220. RTTITypeBase* Texture::getRTTIStatic()
  221. {
  222. return TextureRTTI::instance();
  223. }
  224. RTTITypeBase* Texture::getRTTI() const
  225. {
  226. return Texture::getRTTIStatic();
  227. }
  228. /************************************************************************/
  229. /* STATICS */
  230. /************************************************************************/
  231. TexturePtr Texture::create(TextureType texType, UINT32 width, UINT32 height, UINT32 depth,
  232. int num_mips, PixelFormat format, int usage, bool hwGammaCorrection, UINT32 fsaa, const String& fsaaHint)
  233. {
  234. return TextureManager::instance().create(texType,
  235. width, height, depth, num_mips, format, usage, hwGammaCorrection, fsaa, fsaaHint);
  236. }
  237. TexturePtr Texture::create(TextureType texType, UINT32 width, UINT32 height,
  238. int num_mips, PixelFormat format, int usage, bool hwGammaCorrection, UINT32 fsaa, const String& fsaaHint)
  239. {
  240. return TextureManager::instance().create(texType,
  241. width, height, num_mips, format, usage, hwGammaCorrection, fsaa, fsaaHint);
  242. }
  243. }