Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

379 lines
12 KiB

  1. //====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "materialobjects/dmeprecompiledtexture.h"
  7. #include "datamodel/dmelementfactoryhelper.h"
  8. #include "materialobjects/dmetexture.h"
  9. //-----------------------------------------------------------------------------
  10. // Expose this class to the scene database
  11. //-----------------------------------------------------------------------------
  12. IMPLEMENT_ELEMENT_FACTORY( DmePrecompiledTexture, CDmePrecompiledTexture );
  13. //-----------------------------------------------------------------------------
  14. // Constructor, destructor
  15. //-----------------------------------------------------------------------------
  16. void CDmePrecompiledTexture::OnConstruction()
  17. {
  18. m_ImageFileName.Init( this, "imageFileName" );
  19. m_Processors.Init( this, "processors" );
  20. m_pSourceTexture.Init( this, "sourceTexture" );
  21. m_nStartFrame.InitAndSet( this, "startFrame", -1 );
  22. m_nEndFrame.InitAndSet( this, "endFrame", -1 );
  23. m_nVolumeTextureDepth.InitAndSet( this, "volumeTextureDepth", 1 );
  24. m_nTextureArraySize.InitAndSet( this, "textureArraySize", 1 );
  25. m_nTextureType.Init( this, "textureType" );
  26. m_flBumpScale.InitAndSet( this, "bumpScale", 1.0f );
  27. m_flPFMScale.InitAndSet( this, "pfmScale", 1.0f );
  28. m_nFilterType.Init( this, "filterType" );
  29. m_bClampS.Init( this, "clamps" );
  30. m_bClampT.Init( this, "clampt" );
  31. m_bClampU.Init( this, "clampu" );
  32. m_bLoadMipLevels.Init( this, "loadMipLevels" );
  33. m_bBorder.Init( this, "border" );
  34. m_bNormalMap.Init( this, "normalMap" );
  35. m_bSSBump.Init( this, "ssBump" );
  36. m_bNoMip.Init( this, "noMip" );
  37. m_bAllMips.Init( this, "allMips" );
  38. m_bNoLod.Init( this, "noLod" );
  39. m_bNoDebugOverride.Init( this, "noDebugOverride" );
  40. m_bNoCompression.Init( this, "noCompression" );
  41. m_bHintDxt5Compression.Init( this, "hintDxt5Compression" );
  42. }
  43. void CDmePrecompiledTexture::OnDestruction()
  44. {
  45. }
  46. //-----------------------------------------------------------------------------
  47. // Ensures all settings are internally consistent
  48. //-----------------------------------------------------------------------------
  49. bool CDmePrecompiledTexture::ValidateValues()
  50. {
  51. if ( ( m_nTextureType == DMETEXTURE_TYPE_CUBEMAP ) && ( m_nTextureArraySize != 1 ) )
  52. {
  53. // Cubemaps are packed into a single texture in a cross shape
  54. Warning( "Specified a cubemap with a texture array size != 1!\n" );
  55. return false;
  56. }
  57. if ( ( m_nVolumeTextureDepth > 1 ) && ( m_nTextureArraySize != 1 ) )
  58. {
  59. Warning( "Specified a volume texture with a texture array size != 1!\n" );
  60. return false;
  61. }
  62. if ( m_bLoadMipLevels )
  63. {
  64. char pBaseName[MAX_PATH];
  65. Q_FileBase( GetName(), pBaseName, sizeof( pBaseName ) );
  66. char pRight[16];
  67. V_StrRight( pBaseName, 5, pRight, sizeof( pRight ) );
  68. if ( !Q_stristr( pRight, "_mip0" ) )
  69. {
  70. Warning( "Invalid texture name (\"%s\") for explicitly loading mip levels - the top mip file should end in '_mip0'\n", GetName() );
  71. }
  72. }
  73. return true;
  74. }
  75. //-----------------------------------------------------------------------------
  76. // Expose this class to the scene database
  77. //-----------------------------------------------------------------------------
  78. IMPLEMENT_ELEMENT( CDmeTextureProcessor );
  79. //-----------------------------------------------------------------------------
  80. // Constructor, destructor
  81. //-----------------------------------------------------------------------------
  82. void CDmeTextureProcessor::OnConstruction()
  83. {
  84. }
  85. void CDmeTextureProcessor::OnDestruction()
  86. {
  87. }
  88. //-----------------------------------------------------------------------------
  89. // Expose this class to the scene database
  90. //-----------------------------------------------------------------------------
  91. IMPLEMENT_ELEMENT_FACTORY( DmeTP_ComputeMipmaps, CDmeTP_ComputeMipmaps );
  92. //-----------------------------------------------------------------------------
  93. // Constructor, destructor
  94. //-----------------------------------------------------------------------------
  95. void CDmeTP_ComputeMipmaps::OnConstruction()
  96. {
  97. m_bNoNiceFiltering.Init( this, "noNiceFiltering" );
  98. m_bAlphaTestDownsampling.Init( this, "alphaTestDownsampling" );
  99. m_flAlphaTestDownsampleThreshhold.Init( this, "alphaTestDownsampleThreshhold" );
  100. m_flAlphaTestDownsampleHiFreqThreshhold.Init( this, "alphaTestDownsampleHiFreqThreshhold" );
  101. }
  102. void CDmeTP_ComputeMipmaps::OnDestruction()
  103. {
  104. }
  105. void CDmeTP_ComputeMipmaps::ProcessTexture( CDmeTexture *pSrcTexture, CDmeTexture *pDstTexture )
  106. {
  107. int nWidth = pSrcTexture->Width();
  108. int nHeight = pSrcTexture->Height();
  109. int nDepth = pSrcTexture->Depth();
  110. int nTotalMipCount = ImageLoader::GetNumMipMapLevels( nWidth, nHeight, nDepth );
  111. pSrcTexture->CopyAttributesTo( pDstTexture, TD_NONE );
  112. // Copying will copy references to src texture frames. Remove them.
  113. pDstTexture->RemoveAllFrames();
  114. DownsampleInfo_t info;
  115. info.m_flAlphaThreshhold = m_flAlphaTestDownsampleThreshhold;
  116. info.m_flAlphaHiFreqThreshhold = m_flAlphaTestDownsampleHiFreqThreshhold;
  117. info.m_nFlags = 0;
  118. if ( pSrcTexture->m_bClampS )
  119. {
  120. info.m_nFlags |= DOWNSAMPLE_CLAMPS;
  121. }
  122. if ( pSrcTexture->m_bClampT )
  123. {
  124. info.m_nFlags |= DOWNSAMPLE_CLAMPT;
  125. }
  126. if ( pSrcTexture->m_bClampU )
  127. {
  128. info.m_nFlags |= DOWNSAMPLE_CLAMPU;
  129. }
  130. if ( m_bAlphaTestDownsampling )
  131. {
  132. info.m_nFlags |= DOWNSAMPLE_ALPHATEST;
  133. }
  134. int nFrameCount = pSrcTexture->FrameCount();
  135. CDmeImage **ppSrcImages = (CDmeImage**)stackalloc( nTotalMipCount * sizeof(CDmeImage*) );
  136. CDmeImage **ppDstImages = (CDmeImage**)stackalloc( nTotalMipCount * sizeof(CDmeImage*) );
  137. for ( int f = 0; f < nFrameCount; ++f )
  138. {
  139. CDmeTextureFrame *pSrcFrame = pSrcTexture->GetFrame( f );
  140. CDmeTextureFrame *pDstFrame = pDstTexture->AddFrame();
  141. // Add mip level 0 for this frame
  142. CDmeImageArray *pSrcArray = pSrcFrame->GetMipLevel( 0 );
  143. if ( !pSrcArray )
  144. continue;
  145. for ( int m = 0; m < nTotalMipCount; ++m )
  146. {
  147. pDstFrame->AddMipLevel();
  148. }
  149. int nImageCount = pSrcFrame->ImageCount();
  150. for ( int i = 0; i < nImageCount; ++i )
  151. {
  152. pSrcTexture->GetImages( f, i, ppSrcImages, nTotalMipCount );
  153. CDmeImage *pSrcImage = ppSrcImages[0];
  154. if ( !pSrcImage )
  155. continue;
  156. int nMipWidth = nWidth;
  157. int nMipHeight = nHeight;
  158. int nMipDepth = nDepth;
  159. for ( int m = 0; m < nTotalMipCount; ++m )
  160. {
  161. CDmeImageArray *pDstArray = pDstFrame->GetMipLevel( m );
  162. CDmeImage *pSrcImage = ppSrcImages[m];
  163. CDmeImage *pDstImage = pDstArray->AddImage();
  164. ppDstImages[m] = pDstImage;
  165. if ( pSrcImage )
  166. {
  167. Assert( pSrcImage->Width() == nMipWidth );
  168. Assert( pSrcImage->Height() == nMipHeight );
  169. Assert( pSrcImage->Depth() == nMipDepth );
  170. // FIXME: Just assign the src image into the dest texture
  171. // and remove it from the src texture
  172. // For mips where we have data, just copy src -> dest.
  173. pDstImage->CopyFrom( pSrcImage );
  174. }
  175. else
  176. {
  177. // For mips where don't have data, generate a mip from the src data of the previous level
  178. Assert( m != 0 && ppDstImages[m-1] );
  179. if ( m_bNoNiceFiltering )
  180. {
  181. pDstImage->QuarterSize( ppDstImages[m-1] );
  182. }
  183. else
  184. {
  185. int nSrcMip = clamp( m-3, 0, nTotalMipCount );
  186. pDstImage->Init( nMipWidth, nMipHeight, nMipDepth, ppDstImages[nSrcMip]->Format(), ppDstImages[nSrcMip]->Gamma() );
  187. pDstImage->DownsampleNiceFiltered( info, ppDstImages[nSrcMip] );
  188. }
  189. }
  190. nMipWidth >>= 1; nMipHeight >>= 1; nMipDepth >>= 1;
  191. nMipWidth = MAX( 1, nMipWidth ); nMipHeight = MAX( 1, nMipHeight ); nMipDepth = MAX( 1, nMipDepth );
  192. }
  193. }
  194. }
  195. }
  196. //-----------------------------------------------------------------------------
  197. // Expose this class to the scene database
  198. //-----------------------------------------------------------------------------
  199. IMPLEMENT_ELEMENT_FACTORY( DmeTP_ChangeColorChannels, CDmeTP_ChangeColorChannels );
  200. //-----------------------------------------------------------------------------
  201. // Constructor, destructor
  202. //-----------------------------------------------------------------------------
  203. void CDmeTP_ChangeColorChannels::OnConstruction()
  204. {
  205. m_nMaxChannels.Init( this, "maxChannels" );
  206. }
  207. void CDmeTP_ChangeColorChannels::OnDestruction()
  208. {
  209. }
  210. static ImageFormat ComputeDestFormat( ImageFormat fmt, int nChannelCount )
  211. {
  212. switch( fmt )
  213. {
  214. case IMAGE_FORMAT_RGBA8888:
  215. case IMAGE_FORMAT_ABGR8888:
  216. case IMAGE_FORMAT_ARGB8888:
  217. case IMAGE_FORMAT_BGRA8888:
  218. Assert( nChannelCount != 2 );
  219. return ( nChannelCount == 3 ) ? IMAGE_FORMAT_RGB888 : IMAGE_FORMAT_I8;
  220. case IMAGE_FORMAT_RGB888:
  221. case IMAGE_FORMAT_BGR888:
  222. case IMAGE_FORMAT_BGRX8888:
  223. case IMAGE_FORMAT_RGBX8888:
  224. Assert( nChannelCount == 1 );
  225. return IMAGE_FORMAT_I8;
  226. case IMAGE_FORMAT_IA88:
  227. Assert( nChannelCount == 1 );
  228. return IMAGE_FORMAT_I8;
  229. case IMAGE_FORMAT_DXT5:
  230. Assert( nChannelCount == 3 );
  231. return IMAGE_FORMAT_DXT1;
  232. case IMAGE_FORMAT_RGBA32323232F:
  233. if ( nChannelCount == 3 )
  234. return IMAGE_FORMAT_RGB323232F;
  235. // fall through
  236. case IMAGE_FORMAT_RGB323232F:
  237. if ( nChannelCount == 2 )
  238. return IMAGE_FORMAT_RG3232F;
  239. // fall through
  240. case IMAGE_FORMAT_RG3232F:
  241. Assert( nChannelCount == 1 );
  242. return IMAGE_FORMAT_R32F;
  243. case IMAGE_FORMAT_RGBA16161616F:
  244. Assert( nChannelCount != 3 );
  245. if ( nChannelCount == 2 )
  246. return IMAGE_FORMAT_RG1616F;
  247. // fall through
  248. case IMAGE_FORMAT_RG1616F:
  249. Assert( nChannelCount == 1 );
  250. return IMAGE_FORMAT_R16F;
  251. default:
  252. Assert( 0 );
  253. break;
  254. }
  255. return fmt;
  256. }
  257. void CDmeTP_ChangeColorChannels::ProcessImage( CDmeImage *pDstImage, CDmeImage *pSrcImage )
  258. {
  259. ImageFormat fmt = pSrcImage->Format();
  260. ImageFormat dstFmt = fmt;
  261. const ImageFormatInfo_t &info = ImageLoader::ImageFormatInfo( fmt );
  262. int nChannelCount = 0;
  263. if ( info.m_nNumRedBits > 0 ) ++nChannelCount;
  264. if ( info.m_nNumGreenBits > 0 ) ++nChannelCount;
  265. if ( info.m_nNumBlueBits > 0 ) ++nChannelCount;
  266. if ( info.m_nNumAlphaBits > 0 ) ++nChannelCount;
  267. if ( nChannelCount > m_nMaxChannels )
  268. {
  269. dstFmt = ComputeDestFormat( fmt, m_nMaxChannels );
  270. }
  271. pDstImage->CopyFrom( pSrcImage, dstFmt );
  272. }
  273. void CDmeTP_ChangeColorChannels::ProcessTexture( CDmeTexture *pSrcTexture, CDmeTexture *pDstTexture )
  274. {
  275. pDstTexture->ProcessTexture( pSrcTexture, this, &CDmeTP_ChangeColorChannels::ProcessImage );
  276. }
  277. /*
  278. class CDmeTP_OneOverMipLevelInAlpha : public CDmeTextureProcessor
  279. {
  280. DEFINE_ELEMENT( CDmeTP_OneOverMipLevelInAlpha, CDmeTextureProcessor );
  281. public:
  282. };
  283. IMPLEMENT_ELEMENT_FACTORY( DmeTP_OneOverMipLevelInAlpha, CDmeTP_OneOverMipLevelInAlpha );
  284. class CDmeTP_PreMultiplyColorByOneOverMipLevel : public CDmeTextureProcessor
  285. {
  286. DEFINE_ELEMENT( CDmeTP_PreMultiplyColorByOneOverMipLevel, CDmeTextureProcessor );
  287. public:
  288. };
  289. IMPLEMENT_ELEMENT_FACTORY( DmeTP_PreMultiplyColorByOneOverMipLevel, CDmeTP_PreMultiplyColorByOneOverMipLevel );
  290. class CDmeTP_NormalToDuDv : public CDmeTextureProcessor
  291. {
  292. DEFINE_ELEMENT( CDmeTP_NormalToDuDv, CDmeTextureProcessor );
  293. public:
  294. };
  295. IMPLEMENT_ELEMENT_FACTORY( DmeTP_NormalToDuDv, CDmeTP_NormalToDuDv );
  296. class CDmeTP_CompressTexture : public CDmeTextureProcessor
  297. {
  298. DEFINE_ELEMENT( CDmeTP_CompressTexture, CDmeTextureProcessor );
  299. public:
  300. CDmaVar< bool > m_bNormalGAMap;
  301. CDmaVar< bool > m_bDXT5; // FIXME: Should nocompress/dxt5 be combined?
  302. CDmaVar< bool > m_bNoCompress;
  303. };
  304. IMPLEMENT_ELEMENT_FACTORY( DmeTP_CompressTexture, CDmeTP_CompressTexture );
  305. class CDmeTP_GenerateMipmaps : public CDmeTextureProcessor
  306. {
  307. DEFINE_ELEMENT( CDmeTP_GenerateMipmaps, CDmeTextureProcessor );
  308. public:
  309. CDmaVar< bool > m_bNoNice;
  310. CDmaVar< bool > m_bAlphaTest;
  311. CDmaVar< float > m_flAlphaThreshhold;
  312. CDmaVar< float > m_flAlphaThreshholdHigh;
  313. };
  314. IMPLEMENT_ELEMENT_FACTORY( DmeTP_GenerateMipmaps, CDmeTP_GenerateMipmaps );
  315. */