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.

413 lines
12 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "meshbase.h"
  7. #include "shaderapi_global.h"
  8. // memdbgon must be the last include file in a .cpp file!!!
  9. #include "tier0/memdbgon.h"
  10. //-----------------------------------------------------------------------------
  11. // Helpers with VertexDesc_t...
  12. //-----------------------------------------------------------------------------
  13. // FIXME: add compression-agnostic read-accessors (which decompress and return by value, checking desc.m_CompressionType)
  14. inline Vector &Position( VertexDesc_t const &desc, int vert )
  15. {
  16. return *(Vector*)((unsigned char*)desc.m_pPosition + vert * desc.m_VertexSize_Position );
  17. }
  18. inline float Wrinkle( VertexDesc_t const &desc, int vert )
  19. {
  20. return *(float*)((unsigned char*)desc.m_pWrinkle + vert * desc.m_VertexSize_Wrinkle );
  21. }
  22. inline float *BoneWeight( VertexDesc_t const &desc, int vert )
  23. {
  24. Assert( desc.m_CompressionType == VERTEX_COMPRESSION_NONE );
  25. return (float*)((unsigned char*)desc.m_pBoneWeight + vert * desc.m_VertexSize_BoneWeight );
  26. }
  27. inline unsigned char *BoneIndex( VertexDesc_t const &desc, int vert )
  28. {
  29. return desc.m_pBoneMatrixIndex + vert * desc.m_VertexSize_BoneMatrixIndex;
  30. }
  31. inline Vector &Normal( VertexDesc_t const &desc, int vert )
  32. {
  33. Assert( desc.m_CompressionType == VERTEX_COMPRESSION_NONE );
  34. return *(Vector*)((unsigned char*)desc.m_pNormal + vert * desc.m_VertexSize_Normal );
  35. }
  36. inline unsigned char *Color( VertexDesc_t const &desc, int vert )
  37. {
  38. return desc.m_pColor + vert * desc.m_VertexSize_Color;
  39. }
  40. inline Vector2D &TexCoord( VertexDesc_t const &desc, int vert, int stage )
  41. {
  42. return *(Vector2D*)((unsigned char*)desc.m_pTexCoord[stage] + vert * desc.m_VertexSize_TexCoord[stage] );
  43. }
  44. inline Vector &TangentS( VertexDesc_t const &desc, int vert )
  45. {
  46. return *(Vector*)((unsigned char*)desc.m_pTangentS + vert * desc.m_VertexSize_TangentS );
  47. }
  48. inline Vector &TangentT( VertexDesc_t const &desc, int vert )
  49. {
  50. return *(Vector*)((unsigned char*)desc.m_pTangentT + vert * desc.m_VertexSize_TangentT );
  51. }
  52. //-----------------------------------------------------------------------------
  53. //
  54. // Vertex Buffer implementations begin here
  55. //
  56. //-----------------------------------------------------------------------------
  57. //-----------------------------------------------------------------------------
  58. // constructor, destructor
  59. //-----------------------------------------------------------------------------
  60. CVertexBufferBase::CVertexBufferBase( const char *pBudgetGroupName )
  61. {
  62. m_pBudgetGroupName = pBudgetGroupName;
  63. }
  64. CVertexBufferBase::~CVertexBufferBase()
  65. {
  66. }
  67. //-----------------------------------------------------------------------------
  68. // Displays the vertex format
  69. //-----------------------------------------------------------------------------
  70. void CVertexBufferBase::PrintVertexFormat( VertexFormat_t vertexFormat )
  71. {
  72. VertexCompressionType_t compression = CompressionType( vertexFormat );
  73. if( vertexFormat & VERTEX_POSITION )
  74. {
  75. Msg( "VERTEX_POSITION|" );
  76. }
  77. if( vertexFormat & VERTEX_NORMAL )
  78. {
  79. // FIXME: genericise this stuff using VertexElement_t data tables (so funcs like 'just work' if we make compression changes)
  80. if ( compression == VERTEX_COMPRESSION_ON )
  81. Msg( "VERTEX_NORMAL[COMPRESSED]|" );
  82. else
  83. Msg( "VERTEX_NORMAL|" );
  84. }
  85. if( vertexFormat & VERTEX_COLOR )
  86. {
  87. Msg( "VERTEX_COLOR|" );
  88. }
  89. if( vertexFormat & VERTEX_SPECULAR )
  90. {
  91. Msg( "VERTEX_SPECULAR|" );
  92. }
  93. if( vertexFormat & VERTEX_TANGENT_S )
  94. {
  95. Msg( "VERTEX_TANGENT_S|" );
  96. }
  97. if( vertexFormat & VERTEX_TANGENT_T )
  98. {
  99. Msg( "VERTEX_TANGENT_T|" );
  100. }
  101. if( vertexFormat & VERTEX_BONE_INDEX )
  102. {
  103. Msg( "VERTEX_BONE_INDEX|" );
  104. }
  105. if( NumBoneWeights( vertexFormat ) > 0 )
  106. {
  107. Msg( "VERTEX_BONEWEIGHT(%d)%s|",
  108. NumBoneWeights( vertexFormat ), ( compression ? "[COMPRESSED]" : "" ) );
  109. }
  110. if( UserDataSize( vertexFormat ) > 0 )
  111. {
  112. Msg( "VERTEX_USERDATA_SIZE(%d)|", UserDataSize( vertexFormat ) );
  113. }
  114. int i;
  115. for( i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; i++ )
  116. {
  117. int nDim = TexCoordSize( i, vertexFormat );
  118. if ( nDim == 0 )
  119. continue;
  120. Msg( "VERTEX_TEXCOORD_SIZE(%d,%d)", i, nDim );
  121. }
  122. Msg( "\n" );
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Used to construct vertex data
  126. //-----------------------------------------------------------------------------
  127. void CVertexBufferBase::ComputeVertexDescription( unsigned char *pBuffer,
  128. VertexFormat_t vertexFormat, VertexDesc_t &desc )
  129. {
  130. ComputeVertexDesc< false >( pBuffer, vertexFormat, desc );
  131. }
  132. //-----------------------------------------------------------------------------
  133. // Returns the vertex format size
  134. //-----------------------------------------------------------------------------
  135. int CVertexBufferBase::VertexFormatSize( VertexFormat_t vertexFormat )
  136. {
  137. VertexDesc_t desc;
  138. return ComputeVertexDesc< true >( NULL, vertexFormat, desc );
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Spews the mesh data
  142. //-----------------------------------------------------------------------------
  143. void CVertexBufferBase::Spew( int nVertexCount, const VertexDesc_t &desc )
  144. {
  145. LOCK_SHADERAPI();
  146. char pTempBuf[1024];
  147. Q_snprintf( pTempBuf, sizeof(pTempBuf), "\nVerts %d (First %d, Offset %d) :\n", nVertexCount, desc.m_nFirstVertex, desc.m_nOffset );
  148. Warning( "%s", pTempBuf );
  149. Assert( ( desc.m_NumBoneWeights == 2 ) || ( desc.m_NumBoneWeights == 0 ) );
  150. int nLen = 0;
  151. int nBoneWeightCount = desc.m_NumBoneWeights;
  152. for ( int i = 0; i < nVertexCount; ++i )
  153. {
  154. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "[%4d] ", i + desc.m_nFirstVertex );
  155. if ( desc.m_VertexSize_Position )
  156. {
  157. Vector &pos = Position( desc, i );
  158. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "P %8.2f %8.2f %8.2f ",
  159. pos[0], pos[1], pos[2]);
  160. }
  161. if ( desc.m_VertexSize_Wrinkle )
  162. {
  163. float flWrinkle = Wrinkle( desc, i );
  164. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "Wr %8.2f ",flWrinkle );
  165. }
  166. if ( nBoneWeightCount )
  167. {
  168. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "BW ");
  169. float* pWeight = BoneWeight( desc, i );
  170. for ( int j = 0; j < nBoneWeightCount; ++j )
  171. {
  172. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "%1.2f ", pWeight[j] );
  173. }
  174. }
  175. if ( desc.m_VertexSize_BoneMatrixIndex )
  176. {
  177. unsigned char *pIndex = BoneIndex( desc, i );
  178. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "BI %d %d %d %d ", ( int )pIndex[0], ( int )pIndex[1], ( int )pIndex[2], ( int )pIndex[3] );
  179. Assert( pIndex[0] >= 0 && pIndex[0] < 16 );
  180. Assert( pIndex[1] >= 0 && pIndex[1] < 16 );
  181. Assert( pIndex[2] >= 0 && pIndex[2] < 16 );
  182. Assert( pIndex[3] >= 0 && pIndex[3] < 16 );
  183. }
  184. if ( desc.m_VertexSize_Normal )
  185. {
  186. Vector & normal = Normal( desc, i );
  187. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "N %1.2f %1.2f %1.2f ",
  188. normal[0], normal[1], normal[2]);
  189. }
  190. if ( desc.m_VertexSize_Color )
  191. {
  192. unsigned char* pColor = Color( desc, i );
  193. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "C b %3d g %3d r %3d a %3d ",
  194. pColor[0], pColor[1], pColor[2], pColor[3]);
  195. }
  196. for ( int j = 0; j < VERTEX_MAX_TEXTURE_COORDINATES; ++j )
  197. {
  198. if ( desc.m_VertexSize_TexCoord[j] )
  199. {
  200. Vector2D& texcoord = TexCoord( desc, i, j );
  201. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "T%d %.2f %.2f ", j,texcoord[0], texcoord[1]);
  202. }
  203. }
  204. if ( desc.m_VertexSize_TangentS )
  205. {
  206. Vector& tangentS = TangentS( desc, i );
  207. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "S %1.2f %1.2f %1.2f ",
  208. tangentS[0], tangentS[1], tangentS[2]);
  209. }
  210. if ( desc.m_VertexSize_TangentT )
  211. {
  212. Vector& tangentT = TangentT( desc, i );
  213. nLen += Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "T %1.2f %1.2f %1.2f ",
  214. tangentT[0], tangentT[1], tangentT[2]);
  215. }
  216. Q_snprintf( &pTempBuf[nLen], sizeof(pTempBuf) - nLen, "\n" );
  217. Warning( "%s", pTempBuf );
  218. nLen = 0;
  219. }
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Validates vertex buffer data
  223. //-----------------------------------------------------------------------------
  224. void CVertexBufferBase::ValidateData( int nVertexCount, const VertexDesc_t &spewDesc )
  225. {
  226. LOCK_SHADERAPI();
  227. #ifdef VALIDATE_DEBUG
  228. int i;
  229. // This is needed so buffering can just use this
  230. VertexFormat_t fmt = m_pMaterial->GetVertexUsage();
  231. // Set up the vertex descriptor
  232. VertexDesc_t desc = spewDesc;
  233. int numBoneWeights = NumBoneWeights( fmt );
  234. for ( i = 0; i < nVertexCount; ++i )
  235. {
  236. if( fmt & VERTEX_POSITION )
  237. {
  238. D3DXVECTOR3& pos = Position( desc, i );
  239. Assert( IsFinite( pos[0] ) && IsFinite( pos[1] ) && IsFinite( pos[2] ) );
  240. }
  241. if( fmt & VERTEX_WRINKLE )
  242. {
  243. float flWrinkle = Wrinkle( desc, i );
  244. Assert( IsFinite( flWrinkle ) );
  245. }
  246. if (numBoneWeights > 0)
  247. {
  248. float* pWeight = BoneWeight( desc, i );
  249. for (int j = 0; j < numBoneWeights; ++j)
  250. {
  251. Assert( pWeight[j] >= 0.0f && pWeight[j] <= 1.0f );
  252. }
  253. }
  254. if( fmt & VERTEX_BONE_INDEX )
  255. {
  256. unsigned char *pIndex = BoneIndex( desc, i );
  257. Assert( pIndex[0] >= 0 && pIndex[0] < 16 );
  258. Assert( pIndex[1] >= 0 && pIndex[1] < 16 );
  259. Assert( pIndex[2] >= 0 && pIndex[2] < 16 );
  260. Assert( pIndex[3] >= 0 && pIndex[3] < 16 );
  261. }
  262. if( fmt & VERTEX_NORMAL )
  263. {
  264. D3DXVECTOR3& normal = Normal( desc, i );
  265. Assert( normal[0] >= -1.05f && normal[0] <= 1.05f );
  266. Assert( normal[1] >= -1.05f && normal[1] <= 1.05f );
  267. Assert( normal[2] >= -1.05f && normal[2] <= 1.05f );
  268. }
  269. if (fmt & VERTEX_COLOR)
  270. {
  271. int* pColor = (int*)Color( desc, i );
  272. Assert( *pColor != FLOAT32_NAN_BITS );
  273. }
  274. for (int j = 0; j < VERTEX_MAX_TEXTURE_COORDINATES; ++j)
  275. {
  276. if( TexCoordSize( j, fmt ) > 0)
  277. {
  278. D3DXVECTOR2& texcoord = TexCoord( desc, i, j );
  279. Assert( IsFinite( texcoord[0] ) && IsFinite( texcoord[1] ) );
  280. }
  281. }
  282. if (fmt & VERTEX_TANGENT_S)
  283. {
  284. D3DXVECTOR3& tangentS = TangentS( desc, i );
  285. Assert( IsFinite( tangentS[0] ) && IsFinite( tangentS[1] ) && IsFinite( tangentS[2] ) );
  286. }
  287. if (fmt & VERTEX_TANGENT_T)
  288. {
  289. D3DXVECTOR3& tangentT = TangentT( desc, i );
  290. Assert( IsFinite( tangentT[0] ) && IsFinite( tangentT[1] ) && IsFinite( tangentT[2] ) );
  291. }
  292. }
  293. #endif // _DEBUG
  294. }
  295. //-----------------------------------------------------------------------------
  296. //
  297. // Index Buffer implementations begin here
  298. //
  299. //-----------------------------------------------------------------------------
  300. //-----------------------------------------------------------------------------
  301. // constructor, destructor
  302. //-----------------------------------------------------------------------------
  303. CIndexBufferBase::CIndexBufferBase( const char *pBudgetGroupName ) : m_pBudgetGroupName( pBudgetGroupName )
  304. {
  305. }
  306. //-----------------------------------------------------------------------------
  307. // Spews the mesh data
  308. //-----------------------------------------------------------------------------
  309. void CIndexBufferBase::Spew( int nIndexCount, const IndexDesc_t &indexDesc )
  310. {
  311. LOCK_SHADERAPI();
  312. char pTempBuf[512];
  313. int nLen = 0;
  314. pTempBuf[0] = '\0';
  315. char *pTemp = pTempBuf;
  316. Q_snprintf( pTempBuf, sizeof(pTempBuf), "\nIndices: %d (First %d, Offset %d)\n", nIndexCount, indexDesc.m_nFirstIndex, indexDesc.m_nOffset );
  317. Warning( "%s", pTempBuf );
  318. for ( int i = 0; i < nIndexCount; ++i )
  319. {
  320. nLen += Q_snprintf( pTemp, sizeof(pTempBuf) - nLen - 1, "%d ", ( int )indexDesc.m_pIndices[i] );
  321. pTemp = pTempBuf + nLen;
  322. if ( (i & 0x0F) == 0x0F )
  323. {
  324. Q_snprintf( pTemp, sizeof(pTempBuf) - nLen - 1, "\n" );
  325. Warning( "%s", pTempBuf );
  326. pTempBuf[0] = '\0';
  327. nLen = 0;
  328. pTemp = pTempBuf;
  329. }
  330. }
  331. Q_snprintf( pTemp, sizeof(pTempBuf) - nLen - 1, "\n" );
  332. Warning( "%s", pTempBuf );
  333. }
  334. //-----------------------------------------------------------------------------
  335. // Call this in debug mode to make sure our data is good.
  336. //-----------------------------------------------------------------------------
  337. void CIndexBufferBase::ValidateData( int nIndexCount, const IndexDesc_t& desc )
  338. {
  339. /* FIXME */
  340. // NOTE: Is there anything reasonable to do here at all?
  341. // Or is this a bogus method altogether?
  342. }
  343. //-----------------------------------------------------------------------------
  344. //
  345. // Base mesh
  346. //
  347. //-----------------------------------------------------------------------------
  348. //-----------------------------------------------------------------------------
  349. // constructor, destructor
  350. //-----------------------------------------------------------------------------
  351. CMeshBase::CMeshBase()
  352. {
  353. }
  354. CMeshBase::~CMeshBase()
  355. {
  356. }