gfxD3D9Cubemap.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "gfx/D3D9/gfxD3D9Cubemap.h"
  23. #include "gfx/gfxTextureManager.h"
  24. #include "gfx/D3D9/gfxD3D9EnumTranslate.h"
  25. _D3DCUBEMAP_FACES GFXD3D9Cubemap::faceList[6] =
  26. {
  27. D3DCUBEMAP_FACE_POSITIVE_X, D3DCUBEMAP_FACE_NEGATIVE_X,
  28. D3DCUBEMAP_FACE_POSITIVE_Y, D3DCUBEMAP_FACE_NEGATIVE_Y,
  29. D3DCUBEMAP_FACE_POSITIVE_Z, D3DCUBEMAP_FACE_NEGATIVE_Z
  30. };
  31. //-----------------------------------------------------------------------------
  32. // Constructor
  33. //-----------------------------------------------------------------------------
  34. GFXD3D9Cubemap::GFXD3D9Cubemap()
  35. {
  36. mCubeTex = NULL;
  37. mDynamic = false;
  38. mFaceFormat = GFXFormatR8G8B8A8;
  39. }
  40. //-----------------------------------------------------------------------------
  41. // Destructor
  42. //-----------------------------------------------------------------------------
  43. GFXD3D9Cubemap::~GFXD3D9Cubemap()
  44. {
  45. releaseSurfaces();
  46. if ( mDynamic )
  47. GFXTextureManager::removeEventDelegate( this, &GFXD3D9Cubemap::_onTextureEvent );
  48. }
  49. //-----------------------------------------------------------------------------
  50. // Release D3D surfaces
  51. //-----------------------------------------------------------------------------
  52. void GFXD3D9Cubemap::releaseSurfaces()
  53. {
  54. if ( !mCubeTex )
  55. return;
  56. mCubeTex->Release();
  57. mCubeTex = NULL;
  58. }
  59. void GFXD3D9Cubemap::_onTextureEvent( GFXTexCallbackCode code )
  60. {
  61. // Can this happen?
  62. if ( !mDynamic )
  63. return;
  64. if ( code == GFXZombify )
  65. releaseSurfaces();
  66. else if ( code == GFXResurrect )
  67. initDynamic( mTexSize );
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Init Static
  71. //-----------------------------------------------------------------------------
  72. void GFXD3D9Cubemap::initStatic( GFXTexHandle *faces )
  73. {
  74. //if( mCubeTex )
  75. // return;
  76. if( faces )
  77. {
  78. AssertFatal( faces[0], "empty texture passed to CubeMap::create" );
  79. GFXD3D9Device *dev = static_cast<GFXD3D9Device *>(GFX);
  80. D3DPOOL pool = D3DPOOL_MANAGED;
  81. if (dev->isD3D9Ex())
  82. pool = D3DPOOL_DEFAULT;
  83. LPDIRECT3DDEVICE9 D3D9Device = dev->getDevice();
  84. // NOTE - check tex sizes on all faces - they MUST be all same size
  85. mTexSize = faces[0].getWidth();
  86. mFaceFormat = faces[0].getFormat();
  87. U32 levels = faces->getPointer()->getMipLevels();
  88. if (levels >1)
  89. {
  90. D3D9Assert(D3D9Device->CreateCubeTexture(mTexSize, levels, 0, GFXD3D9TextureFormat[mFaceFormat],
  91. pool, &mCubeTex, NULL), NULL);
  92. fillCubeTextures(faces, D3D9Device);
  93. }
  94. else
  95. {
  96. D3D9Assert( D3D9Device->CreateCubeTexture( mTexSize, 0, D3DUSAGE_AUTOGENMIPMAP, GFXD3D9TextureFormat[mFaceFormat],
  97. pool, &mCubeTex, NULL ), NULL );
  98. fillCubeTextures( faces, D3D9Device );
  99. mCubeTex->GenerateMipSubLevels();
  100. }
  101. }
  102. }
  103. void GFXD3D9Cubemap::initStatic( DDSFile *dds )
  104. {
  105. AssertFatal( dds, "GFXD3D9Cubemap::initStatic - Got null DDS file!" );
  106. AssertFatal( dds->isCubemap(), "GFXD3D9Cubemap::initStatic - Got non-cubemap DDS file!" );
  107. AssertFatal( dds->mSurfaces.size() == 6, "GFXD3D9Cubemap::initStatic - DDS has less than 6 surfaces!" );
  108. GFXD3D9Device *dev = static_cast<GFXD3D9Device *>(GFX);
  109. D3DPOOL pool = D3DPOOL_MANAGED;
  110. if (dev->isD3D9Ex())
  111. pool = D3DPOOL_DEFAULT;
  112. LPDIRECT3DDEVICE9 D3D9Device = dev->getDevice();
  113. // NOTE - check tex sizes on all faces - they MUST be all same size
  114. mTexSize = dds->getWidth();
  115. mFaceFormat = dds->getFormat();
  116. U32 levels = dds->getMipLevels();
  117. D3D9Assert( D3D9Device->CreateCubeTexture( mTexSize, levels, 0, GFXD3D9TextureFormat[mFaceFormat],
  118. pool, &mCubeTex, NULL ), NULL );
  119. for( U32 i=0; i < 6; i++ )
  120. {
  121. if ( !dds->mSurfaces[i] )
  122. {
  123. // TODO: The DDS can skip surfaces, but i'm unsure what i should
  124. // do here when creating the cubemap. Ignore it for now.
  125. continue;
  126. }
  127. // Now loop thru the mip levels!
  128. for( U32 l = 0; l < levels; l++ )
  129. {
  130. IDirect3DSurface9 *cubeSurf = NULL;
  131. D3D9Assert( mCubeTex->GetCubeMapSurface( faceList[i], l, &cubeSurf ),
  132. "GFXD3D9Cubemap::initStatic - Get cubemap surface failed!" );
  133. // Lock the dest surface.
  134. D3DLOCKED_RECT lockedRect;
  135. D3D9Assert( cubeSurf->LockRect( &lockedRect, NULL, 0 ),
  136. "GFXD3D9Cubemap::initStatic - Failed to lock surface level for load!" );
  137. dMemcpy( lockedRect.pBits, dds->mSurfaces[i]->mMips[l], dds->getSurfaceSize(l) );
  138. cubeSurf->UnlockRect();
  139. cubeSurf->Release();
  140. }
  141. }
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Init Dynamic
  145. //-----------------------------------------------------------------------------
  146. void GFXD3D9Cubemap::initDynamic( U32 texSize, GFXFormat faceFormat )
  147. {
  148. if ( mCubeTex )
  149. return;
  150. if ( !mDynamic )
  151. GFXTextureManager::addEventDelegate( this, &GFXD3D9Cubemap::_onTextureEvent );
  152. mDynamic = true;
  153. mTexSize = texSize;
  154. mFaceFormat = faceFormat;
  155. LPDIRECT3DDEVICE9 D3D9Device = reinterpret_cast<GFXD3D9Device *>(GFX)->getDevice();
  156. // might want to try this as a 16 bit texture...
  157. D3D9Assert( D3D9Device->CreateCubeTexture( texSize,
  158. 1,
  159. #ifdef TORQUE_OS_XENON
  160. 0,
  161. #else
  162. D3DUSAGE_RENDERTARGET,
  163. #endif
  164. GFXD3D9TextureFormat[faceFormat],
  165. D3DPOOL_DEFAULT,
  166. &mCubeTex,
  167. NULL ), NULL );
  168. }
  169. //-----------------------------------------------------------------------------
  170. // Fills in face textures of cube map from existing textures
  171. //-----------------------------------------------------------------------------
  172. void GFXD3D9Cubemap::fillCubeTextures( GFXTexHandle *faces, LPDIRECT3DDEVICE9 D3DDevice)
  173. {
  174. U32 levels = faces->getPointer()->getMipLevels();
  175. for (U32 mip = 0; mip < levels; mip++)
  176. {
  177. for (U32 i = 0; i < 6; i++)
  178. {
  179. // get cube face surface
  180. IDirect3DSurface9 *cubeSurf = NULL;
  181. D3D9Assert(mCubeTex->GetCubeMapSurface(faceList[i], mip, &cubeSurf), NULL);
  182. // get incoming texture surface
  183. GFXD3D9TextureObject *texObj = dynamic_cast<GFXD3D9TextureObject*>((GFXTextureObject*)faces[i]);
  184. IDirect3DSurface9 *inSurf;
  185. D3D9Assert(texObj->get2DTex()->GetSurfaceLevel(mip, &inSurf), NULL);
  186. // copy incoming texture into cube face
  187. D3D9Assert(GFXD3DX.D3DXLoadSurfaceFromSurface(cubeSurf, NULL, NULL, inSurf, NULL,
  188. NULL, D3DX_FILTER_NONE, 0), NULL);
  189. cubeSurf->Release();
  190. inSurf->Release();
  191. }
  192. }
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Set the cubemap to the specified texture unit num
  196. //-----------------------------------------------------------------------------
  197. void GFXD3D9Cubemap::setToTexUnit( U32 tuNum )
  198. {
  199. static_cast<GFXD3D9Device *>(GFX)->getDevice()->SetTexture( tuNum, mCubeTex );
  200. }
  201. void GFXD3D9Cubemap::zombify()
  202. {
  203. // Static cubemaps are handled by D3D
  204. if( mDynamic )
  205. releaseSurfaces();
  206. }
  207. void GFXD3D9Cubemap::resurrect()
  208. {
  209. // Static cubemaps are handled by D3D
  210. if( mDynamic )
  211. initDynamic( mTexSize, mFaceFormat );
  212. }