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.

664 lines
27 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #ifndef IMATERIAL_H
  9. #define IMATERIAL_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "bitmap/imageformat.h"
  14. #include "materialsystem/imaterialsystem.h"
  15. //-----------------------------------------------------------------------------
  16. // Forward declarations
  17. //-----------------------------------------------------------------------------
  18. class IMaterialVar;
  19. class ITexture;
  20. class IMaterialProxy;
  21. class Vector;
  22. //-----------------------------------------------------------------------------
  23. // Flags for GetVertexFormat
  24. //-----------------------------------------------------------------------------
  25. #define VERTEX_POSITION 0x0001
  26. #define VERTEX_NORMAL 0x0002
  27. #define VERTEX_COLOR 0x0004
  28. #define VERTEX_SPECULAR 0x0008
  29. #define VERTEX_TANGENT_S 0x0010
  30. #define VERTEX_TANGENT_T 0x0020
  31. #define VERTEX_TANGENT_SPACE ( VERTEX_TANGENT_S | VERTEX_TANGENT_T )
  32. // Indicates we're using wrinkle
  33. #define VERTEX_WRINKLE 0x0040
  34. // Indicates we're using bone indices
  35. #define VERTEX_BONE_INDEX 0x0080
  36. // Indicates this expects a color stream on stream 1
  37. #define VERTEX_COLOR_STREAM_1 0x0100
  38. // Indicates this format shouldn't be bloated to cache align it
  39. // (only used for VertexUsage)
  40. #define VERTEX_FORMAT_USE_EXACT_FORMAT 0x0200
  41. // Indicates that compressed vertex elements are to be used (see also VertexCompressionType_t)
  42. #define VERTEX_FORMAT_COMPRESSED 0x400
  43. // Position or normal (if present) should be 4D not 3D
  44. #define VERTEX_FORMAT_PAD_POS_NORM 0x800
  45. // Update this if you add or remove bits...
  46. #define VERTEX_LAST_BIT 11
  47. #define VERTEX_BONE_WEIGHT_BIT (VERTEX_LAST_BIT + 1)
  48. #define USER_DATA_SIZE_BIT (VERTEX_LAST_BIT + 4)
  49. #define TEX_COORD_SIZE_BIT (VERTEX_LAST_BIT + 7)
  50. #define VERTEX_BONE_WEIGHT_MASK ( 0x7 << VERTEX_BONE_WEIGHT_BIT )
  51. #define USER_DATA_SIZE_MASK ( 0x7 << USER_DATA_SIZE_BIT )
  52. #define VERTEX_FORMAT_FIELD_MASK 0x0FF
  53. // If everything is off, it's an unknown vertex format
  54. #define VERTEX_FORMAT_UNKNOWN 0
  55. //-----------------------------------------------------------------------------
  56. // Macros for construction..
  57. //-----------------------------------------------------------------------------
  58. #define VERTEX_BONEWEIGHT( _n ) ((_n) << VERTEX_BONE_WEIGHT_BIT)
  59. #define VERTEX_USERDATA_SIZE( _n ) ((_n) << USER_DATA_SIZE_BIT)
  60. #define VERTEX_TEXCOORD_MASK( _coord ) (( 0x7ULL ) << ( TEX_COORD_SIZE_BIT + 3 * (_coord) ))
  61. inline VertexFormat_t VERTEX_TEXCOORD_SIZE( int nIndex, int nNumCoords )
  62. {
  63. uint64 n64=nNumCoords;
  64. uint64 nShift=TEX_COORD_SIZE_BIT + (3*nIndex);
  65. return n64 << nShift;
  66. }
  67. //-----------------------------------------------------------------------------
  68. // Gets at various vertex format info...
  69. //-----------------------------------------------------------------------------
  70. inline int VertexFlags( VertexFormat_t vertexFormat )
  71. {
  72. return static_cast<int> ( vertexFormat & ( (1 << (VERTEX_LAST_BIT+1)) - 1 ) );
  73. }
  74. inline int NumBoneWeights( VertexFormat_t vertexFormat )
  75. {
  76. return static_cast<int> ( (vertexFormat >> VERTEX_BONE_WEIGHT_BIT) & 0x7 );
  77. }
  78. inline int UserDataSize( VertexFormat_t vertexFormat )
  79. {
  80. return static_cast<int> ( (vertexFormat >> USER_DATA_SIZE_BIT) & 0x7 );
  81. }
  82. inline int TexCoordSize( int nTexCoordIndex, VertexFormat_t vertexFormat )
  83. {
  84. return static_cast<int> ( (vertexFormat >> (TEX_COORD_SIZE_BIT + 3*nTexCoordIndex) ) & 0x7 );
  85. }
  86. inline VertexCompressionType_t CompressionType( VertexFormat_t vertexFormat )
  87. {
  88. // This is trivial now, but we may add multiple flavors of compressed vertex later on
  89. if ( vertexFormat & VERTEX_FORMAT_COMPRESSED )
  90. return VERTEX_COMPRESSION_ON;
  91. else
  92. return VERTEX_COMPRESSION_NONE;
  93. }
  94. //-----------------------------------------------------------------------------
  95. // VertexElement_t (enumerates all usable vertex elements)
  96. //-----------------------------------------------------------------------------
  97. // FIXME: unify this with VertexFormat_t (i.e. construct the lower bits of VertexFormat_t with "1 << (VertexElement_t)element")
  98. enum VertexElement_t
  99. {
  100. VERTEX_ELEMENT_NONE = -1,
  101. // Deliberately explicitly numbered so it's a pain in the ass to change, so you read this:
  102. // #!#!#NOTE#!#!# update GetVertexElementSize, VertexElementToDeclType and
  103. // CVBAllocTracker (elementTable) when you update this!
  104. VERTEX_ELEMENT_POSITION = 0,
  105. VERTEX_ELEMENT_POSITION4D = 1,
  106. VERTEX_ELEMENT_NORMAL = 2,
  107. VERTEX_ELEMENT_NORMAL4D = 3,
  108. VERTEX_ELEMENT_COLOR = 4,
  109. VERTEX_ELEMENT_SPECULAR = 5,
  110. VERTEX_ELEMENT_TANGENT_S = 6,
  111. VERTEX_ELEMENT_TANGENT_T = 7,
  112. VERTEX_ELEMENT_WRINKLE = 8,
  113. VERTEX_ELEMENT_BONEINDEX = 9,
  114. VERTEX_ELEMENT_BONEWEIGHTS1 = 10,
  115. VERTEX_ELEMENT_BONEWEIGHTS2 = 11,
  116. VERTEX_ELEMENT_BONEWEIGHTS3 = 12,
  117. VERTEX_ELEMENT_BONEWEIGHTS4 = 13,
  118. VERTEX_ELEMENT_USERDATA1 = 14,
  119. VERTEX_ELEMENT_USERDATA2 = 15,
  120. VERTEX_ELEMENT_USERDATA3 = 16,
  121. VERTEX_ELEMENT_USERDATA4 = 17,
  122. VERTEX_ELEMENT_TEXCOORD1D_0 = 18,
  123. VERTEX_ELEMENT_TEXCOORD1D_1 = 19,
  124. VERTEX_ELEMENT_TEXCOORD1D_2 = 20,
  125. VERTEX_ELEMENT_TEXCOORD1D_3 = 21,
  126. VERTEX_ELEMENT_TEXCOORD1D_4 = 22,
  127. VERTEX_ELEMENT_TEXCOORD1D_5 = 23,
  128. VERTEX_ELEMENT_TEXCOORD1D_6 = 24,
  129. VERTEX_ELEMENT_TEXCOORD1D_7 = 25,
  130. VERTEX_ELEMENT_TEXCOORD2D_0 = 26,
  131. VERTEX_ELEMENT_TEXCOORD2D_1 = 27,
  132. VERTEX_ELEMENT_TEXCOORD2D_2 = 28,
  133. VERTEX_ELEMENT_TEXCOORD2D_3 = 29,
  134. VERTEX_ELEMENT_TEXCOORD2D_4 = 30,
  135. VERTEX_ELEMENT_TEXCOORD2D_5 = 31,
  136. VERTEX_ELEMENT_TEXCOORD2D_6 = 32,
  137. VERTEX_ELEMENT_TEXCOORD2D_7 = 33,
  138. VERTEX_ELEMENT_TEXCOORD3D_0 = 34,
  139. VERTEX_ELEMENT_TEXCOORD3D_1 = 35,
  140. VERTEX_ELEMENT_TEXCOORD3D_2 = 36,
  141. VERTEX_ELEMENT_TEXCOORD3D_3 = 37,
  142. VERTEX_ELEMENT_TEXCOORD3D_4 = 38,
  143. VERTEX_ELEMENT_TEXCOORD3D_5 = 39,
  144. VERTEX_ELEMENT_TEXCOORD3D_6 = 40,
  145. VERTEX_ELEMENT_TEXCOORD3D_7 = 41,
  146. VERTEX_ELEMENT_TEXCOORD4D_0 = 42,
  147. VERTEX_ELEMENT_TEXCOORD4D_1 = 43,
  148. VERTEX_ELEMENT_TEXCOORD4D_2 = 44,
  149. VERTEX_ELEMENT_TEXCOORD4D_3 = 45,
  150. VERTEX_ELEMENT_TEXCOORD4D_4 = 46,
  151. VERTEX_ELEMENT_TEXCOORD4D_5 = 47,
  152. VERTEX_ELEMENT_TEXCOORD4D_6 = 48,
  153. VERTEX_ELEMENT_TEXCOORD4D_7 = 49,
  154. VERTEX_ELEMENT_NUMELEMENTS = 50
  155. };
  156. inline void Detect_VertexElement_t_Changes( VertexElement_t element ) // GREPs for VertexElement_t will hit this
  157. {
  158. // Make it harder for someone to change VertexElement_t without noticing that dependent code
  159. // (GetVertexElementSize, VertexElementToDeclType, CVBAllocTracker) needs updating
  160. Assert( VERTEX_ELEMENT_NUMELEMENTS == 50 );
  161. switch ( element )
  162. {
  163. case VERTEX_ELEMENT_POSITION: Assert( VERTEX_ELEMENT_POSITION == 0 ); break;
  164. case VERTEX_ELEMENT_POSITION4D: Assert( VERTEX_ELEMENT_POSITION4D == 1 ); break;
  165. case VERTEX_ELEMENT_NORMAL: Assert( VERTEX_ELEMENT_NORMAL == 2 ); break;
  166. case VERTEX_ELEMENT_NORMAL4D: Assert( VERTEX_ELEMENT_NORMAL4D == 3 ); break;
  167. case VERTEX_ELEMENT_COLOR: Assert( VERTEX_ELEMENT_COLOR == 4 ); break;
  168. case VERTEX_ELEMENT_SPECULAR: Assert( VERTEX_ELEMENT_SPECULAR == 5 ); break;
  169. case VERTEX_ELEMENT_TANGENT_S: Assert( VERTEX_ELEMENT_TANGENT_S == 6 ); break;
  170. case VERTEX_ELEMENT_TANGENT_T: Assert( VERTEX_ELEMENT_TANGENT_T == 7 ); break;
  171. case VERTEX_ELEMENT_WRINKLE: Assert( VERTEX_ELEMENT_WRINKLE == 8 ); break;
  172. case VERTEX_ELEMENT_BONEINDEX: Assert( VERTEX_ELEMENT_BONEINDEX == 9 ); break;
  173. case VERTEX_ELEMENT_BONEWEIGHTS1: Assert( VERTEX_ELEMENT_BONEWEIGHTS1 == 10 ); break;
  174. case VERTEX_ELEMENT_BONEWEIGHTS2: Assert( VERTEX_ELEMENT_BONEWEIGHTS2 == 11 ); break;
  175. case VERTEX_ELEMENT_BONEWEIGHTS3: Assert( VERTEX_ELEMENT_BONEWEIGHTS3 == 12 ); break;
  176. case VERTEX_ELEMENT_BONEWEIGHTS4: Assert( VERTEX_ELEMENT_BONEWEIGHTS4 == 13 ); break;
  177. case VERTEX_ELEMENT_USERDATA1: Assert( VERTEX_ELEMENT_USERDATA1 == 14 ); break;
  178. case VERTEX_ELEMENT_USERDATA2: Assert( VERTEX_ELEMENT_USERDATA2 == 15 ); break;
  179. case VERTEX_ELEMENT_USERDATA3: Assert( VERTEX_ELEMENT_USERDATA3 == 16 ); break;
  180. case VERTEX_ELEMENT_USERDATA4: Assert( VERTEX_ELEMENT_USERDATA4 == 17 ); break;
  181. case VERTEX_ELEMENT_TEXCOORD1D_0: Assert( VERTEX_ELEMENT_TEXCOORD1D_0 == 18 ); break;
  182. case VERTEX_ELEMENT_TEXCOORD1D_1: Assert( VERTEX_ELEMENT_TEXCOORD1D_1 == 19 ); break;
  183. case VERTEX_ELEMENT_TEXCOORD1D_2: Assert( VERTEX_ELEMENT_TEXCOORD1D_2 == 20 ); break;
  184. case VERTEX_ELEMENT_TEXCOORD1D_3: Assert( VERTEX_ELEMENT_TEXCOORD1D_3 == 21 ); break;
  185. case VERTEX_ELEMENT_TEXCOORD1D_4: Assert( VERTEX_ELEMENT_TEXCOORD1D_4 == 22 ); break;
  186. case VERTEX_ELEMENT_TEXCOORD1D_5: Assert( VERTEX_ELEMENT_TEXCOORD1D_5 == 23 ); break;
  187. case VERTEX_ELEMENT_TEXCOORD1D_6: Assert( VERTEX_ELEMENT_TEXCOORD1D_6 == 24 ); break;
  188. case VERTEX_ELEMENT_TEXCOORD1D_7: Assert( VERTEX_ELEMENT_TEXCOORD1D_7 == 25 ); break;
  189. case VERTEX_ELEMENT_TEXCOORD2D_0: Assert( VERTEX_ELEMENT_TEXCOORD2D_0 == 26 ); break;
  190. case VERTEX_ELEMENT_TEXCOORD2D_1: Assert( VERTEX_ELEMENT_TEXCOORD2D_1 == 27 ); break;
  191. case VERTEX_ELEMENT_TEXCOORD2D_2: Assert( VERTEX_ELEMENT_TEXCOORD2D_2 == 28 ); break;
  192. case VERTEX_ELEMENT_TEXCOORD2D_3: Assert( VERTEX_ELEMENT_TEXCOORD2D_3 == 29 ); break;
  193. case VERTEX_ELEMENT_TEXCOORD2D_4: Assert( VERTEX_ELEMENT_TEXCOORD2D_4 == 30 ); break;
  194. case VERTEX_ELEMENT_TEXCOORD2D_5: Assert( VERTEX_ELEMENT_TEXCOORD2D_5 == 31 ); break;
  195. case VERTEX_ELEMENT_TEXCOORD2D_6: Assert( VERTEX_ELEMENT_TEXCOORD2D_6 == 32 ); break;
  196. case VERTEX_ELEMENT_TEXCOORD2D_7: Assert( VERTEX_ELEMENT_TEXCOORD2D_7 == 33 ); break;
  197. case VERTEX_ELEMENT_TEXCOORD3D_0: Assert( VERTEX_ELEMENT_TEXCOORD3D_0 == 34 ); break;
  198. case VERTEX_ELEMENT_TEXCOORD3D_1: Assert( VERTEX_ELEMENT_TEXCOORD3D_1 == 35 ); break;
  199. case VERTEX_ELEMENT_TEXCOORD3D_2: Assert( VERTEX_ELEMENT_TEXCOORD3D_2 == 36 ); break;
  200. case VERTEX_ELEMENT_TEXCOORD3D_3: Assert( VERTEX_ELEMENT_TEXCOORD3D_3 == 37 ); break;
  201. case VERTEX_ELEMENT_TEXCOORD3D_4: Assert( VERTEX_ELEMENT_TEXCOORD3D_4 == 38 ); break;
  202. case VERTEX_ELEMENT_TEXCOORD3D_5: Assert( VERTEX_ELEMENT_TEXCOORD3D_5 == 39 ); break;
  203. case VERTEX_ELEMENT_TEXCOORD3D_6: Assert( VERTEX_ELEMENT_TEXCOORD3D_6 == 40 ); break;
  204. case VERTEX_ELEMENT_TEXCOORD3D_7: Assert( VERTEX_ELEMENT_TEXCOORD3D_7 == 41 ); break;
  205. case VERTEX_ELEMENT_TEXCOORD4D_0: Assert( VERTEX_ELEMENT_TEXCOORD4D_0 == 42 ); break;
  206. case VERTEX_ELEMENT_TEXCOORD4D_1: Assert( VERTEX_ELEMENT_TEXCOORD4D_1 == 43 ); break;
  207. case VERTEX_ELEMENT_TEXCOORD4D_2: Assert( VERTEX_ELEMENT_TEXCOORD4D_2 == 44 ); break;
  208. case VERTEX_ELEMENT_TEXCOORD4D_3: Assert( VERTEX_ELEMENT_TEXCOORD4D_3 == 45 ); break;
  209. case VERTEX_ELEMENT_TEXCOORD4D_4: Assert( VERTEX_ELEMENT_TEXCOORD4D_4 == 46 ); break;
  210. case VERTEX_ELEMENT_TEXCOORD4D_5: Assert( VERTEX_ELEMENT_TEXCOORD4D_5 == 47 ); break;
  211. case VERTEX_ELEMENT_TEXCOORD4D_6: Assert( VERTEX_ELEMENT_TEXCOORD4D_6 == 48 ); break;
  212. case VERTEX_ELEMENT_TEXCOORD4D_7: Assert( VERTEX_ELEMENT_TEXCOORD4D_7 == 49 ); break;
  213. default:
  214. Assert( 0 ); // Invalid input or VertexElement_t has definitely changed
  215. break;
  216. }
  217. }
  218. // We're testing 2 normal compression methods
  219. // One compressed normals+tangents into a SHORT2 each (8 bytes total)
  220. // The other compresses them together, into a single UBYTE4 (4 bytes total)
  221. // FIXME: pick one or the other, compare lighting quality in important cases
  222. #define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0
  223. #define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1
  224. //#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2
  225. #define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4
  226. inline int GetVertexElementSize( VertexElement_t element, VertexCompressionType_t compressionType )
  227. {
  228. Detect_VertexElement_t_Changes( element );
  229. if ( compressionType == VERTEX_COMPRESSION_ON )
  230. {
  231. // Compressed-vertex element sizes
  232. switch ( element )
  233. {
  234. #if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 )
  235. case VERTEX_ELEMENT_NORMAL:
  236. return ( 2 * sizeof( short ) );
  237. case VERTEX_ELEMENT_USERDATA4:
  238. return ( 2 * sizeof( short ) );
  239. #else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 )
  240. // Normals and tangents (userdata4) are combined into a single UBYTE4 vertex element
  241. case VERTEX_ELEMENT_NORMAL:
  242. return ( 4 * sizeof( unsigned char ) );
  243. case VERTEX_ELEMENT_USERDATA4:
  244. return ( 0 );
  245. #endif
  246. // Compressed bone weights use a SHORT2 vertex element:
  247. case VERTEX_ELEMENT_BONEWEIGHTS1:
  248. case VERTEX_ELEMENT_BONEWEIGHTS2:
  249. return ( 2 * sizeof( short ) );
  250. default:
  251. break;
  252. }
  253. }
  254. // Uncompressed-vertex element sizes
  255. switch ( element )
  256. {
  257. case VERTEX_ELEMENT_POSITION: return ( 3 * sizeof( float ) );
  258. case VERTEX_ELEMENT_POSITION4D: return ( 4 * sizeof( float ) );
  259. case VERTEX_ELEMENT_NORMAL: return ( 3 * sizeof( float ) );
  260. case VERTEX_ELEMENT_NORMAL4D: return ( 4 * sizeof( float ) );
  261. case VERTEX_ELEMENT_COLOR: return ( 4 * sizeof( unsigned char ) );
  262. case VERTEX_ELEMENT_SPECULAR: return ( 4 * sizeof( unsigned char ) );
  263. case VERTEX_ELEMENT_TANGENT_S: return ( 3 * sizeof( float ) );
  264. case VERTEX_ELEMENT_TANGENT_T: return ( 3 * sizeof( float ) );
  265. case VERTEX_ELEMENT_WRINKLE: return ( 1 * sizeof( float ) ); // Packed into Position.W
  266. case VERTEX_ELEMENT_BONEINDEX: return ( 4 * sizeof( unsigned char ) );
  267. case VERTEX_ELEMENT_BONEWEIGHTS1: return ( 1 * sizeof( float ) );
  268. case VERTEX_ELEMENT_BONEWEIGHTS2: return ( 2 * sizeof( float ) );
  269. case VERTEX_ELEMENT_BONEWEIGHTS3: return ( 3 * sizeof( float ) );
  270. case VERTEX_ELEMENT_BONEWEIGHTS4: return ( 4 * sizeof( float ) );
  271. case VERTEX_ELEMENT_USERDATA1: return ( 1 * sizeof( float ) );
  272. case VERTEX_ELEMENT_USERDATA2: return ( 2 * sizeof( float ) );
  273. case VERTEX_ELEMENT_USERDATA3: return ( 3 * sizeof( float ) );
  274. case VERTEX_ELEMENT_USERDATA4: return ( 4 * sizeof( float ) );
  275. case VERTEX_ELEMENT_TEXCOORD1D_0: return ( 1 * sizeof( float ) );
  276. case VERTEX_ELEMENT_TEXCOORD1D_1: return ( 1 * sizeof( float ) );
  277. case VERTEX_ELEMENT_TEXCOORD1D_2: return ( 1 * sizeof( float ) );
  278. case VERTEX_ELEMENT_TEXCOORD1D_3: return ( 1 * sizeof( float ) );
  279. case VERTEX_ELEMENT_TEXCOORD1D_4: return ( 1 * sizeof( float ) );
  280. case VERTEX_ELEMENT_TEXCOORD1D_5: return ( 1 * sizeof( float ) );
  281. case VERTEX_ELEMENT_TEXCOORD1D_6: return ( 1 * sizeof( float ) );
  282. case VERTEX_ELEMENT_TEXCOORD1D_7: return ( 1 * sizeof( float ) );
  283. case VERTEX_ELEMENT_TEXCOORD2D_0: return ( 2 * sizeof( float ) );
  284. case VERTEX_ELEMENT_TEXCOORD2D_1: return ( 2 * sizeof( float ) );
  285. case VERTEX_ELEMENT_TEXCOORD2D_2: return ( 2 * sizeof( float ) );
  286. case VERTEX_ELEMENT_TEXCOORD2D_3: return ( 2 * sizeof( float ) );
  287. case VERTEX_ELEMENT_TEXCOORD2D_4: return ( 2 * sizeof( float ) );
  288. case VERTEX_ELEMENT_TEXCOORD2D_5: return ( 2 * sizeof( float ) );
  289. case VERTEX_ELEMENT_TEXCOORD2D_6: return ( 2 * sizeof( float ) );
  290. case VERTEX_ELEMENT_TEXCOORD2D_7: return ( 2 * sizeof( float ) );
  291. case VERTEX_ELEMENT_TEXCOORD3D_0: return ( 3 * sizeof( float ) );
  292. case VERTEX_ELEMENT_TEXCOORD3D_1: return ( 3 * sizeof( float ) );
  293. case VERTEX_ELEMENT_TEXCOORD3D_2: return ( 3 * sizeof( float ) );
  294. case VERTEX_ELEMENT_TEXCOORD3D_3: return ( 3 * sizeof( float ) );
  295. case VERTEX_ELEMENT_TEXCOORD3D_4: return ( 3 * sizeof( float ) );
  296. case VERTEX_ELEMENT_TEXCOORD3D_5: return ( 3 * sizeof( float ) );
  297. case VERTEX_ELEMENT_TEXCOORD3D_6: return ( 3 * sizeof( float ) );
  298. case VERTEX_ELEMENT_TEXCOORD3D_7: return ( 3 * sizeof( float ) );
  299. case VERTEX_ELEMENT_TEXCOORD4D_0: return ( 4 * sizeof( float ) );
  300. case VERTEX_ELEMENT_TEXCOORD4D_1: return ( 4 * sizeof( float ) );
  301. case VERTEX_ELEMENT_TEXCOORD4D_2: return ( 4 * sizeof( float ) );
  302. case VERTEX_ELEMENT_TEXCOORD4D_3: return ( 4 * sizeof( float ) );
  303. case VERTEX_ELEMENT_TEXCOORD4D_4: return ( 4 * sizeof( float ) );
  304. case VERTEX_ELEMENT_TEXCOORD4D_5: return ( 4 * sizeof( float ) );
  305. case VERTEX_ELEMENT_TEXCOORD4D_6: return ( 4 * sizeof( float ) );
  306. case VERTEX_ELEMENT_TEXCOORD4D_7: return ( 4 * sizeof( float ) );
  307. default:
  308. Assert(0);
  309. return 0;
  310. };
  311. }
  312. //-----------------------------------------------------------------------------
  313. // Shader state flags can be read from the FLAGS materialvar
  314. // Also can be read or written to with the Set/GetMaterialVarFlags() call
  315. // Also make sure you add/remove a string associated with each flag below to CShaderSystem::ShaderStateString in ShaderSystem.cpp
  316. //-----------------------------------------------------------------------------
  317. enum MaterialVarFlags_t
  318. {
  319. MATERIAL_VAR_DEBUG = (1 << 0),
  320. MATERIAL_VAR_NO_DEBUG_OVERRIDE = (1 << 1),
  321. MATERIAL_VAR_NO_DRAW = (1 << 2),
  322. MATERIAL_VAR_USE_IN_FILLRATE_MODE = (1 << 3),
  323. MATERIAL_VAR_VERTEXCOLOR = (1 << 4),
  324. MATERIAL_VAR_VERTEXALPHA = (1 << 5),
  325. MATERIAL_VAR_SELFILLUM = (1 << 6),
  326. MATERIAL_VAR_ADDITIVE = (1 << 7),
  327. MATERIAL_VAR_ALPHATEST = (1 << 8),
  328. MATERIAL_VAR_PSEUDO_TRANSLUCENT = (1 << 9), // used to mark water materials for rendering after opaques but before translucents (with alpha blending but also with depth writes)
  329. MATERIAL_VAR_ZNEARER = (1 << 10),
  330. MATERIAL_VAR_MODEL = (1 << 11),
  331. MATERIAL_VAR_FLAT = (1 << 12),
  332. MATERIAL_VAR_NOCULL = (1 << 13),
  333. MATERIAL_VAR_NOFOG = (1 << 14),
  334. MATERIAL_VAR_IGNOREZ = (1 << 15),
  335. MATERIAL_VAR_DECAL = (1 << 16),
  336. MATERIAL_VAR_ENVMAPSPHERE = (1 << 17), // OBSOLETE
  337. MATERIAL_VAR_AOPREPASS = (1 << 18),
  338. MATERIAL_VAR_ENVMAPCAMERASPACE = (1 << 19), // OBSOLETE
  339. MATERIAL_VAR_BASEALPHAENVMAPMASK = (1 << 20),
  340. MATERIAL_VAR_TRANSLUCENT = (1 << 21),
  341. MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK = (1 << 22),
  342. MATERIAL_VAR_NEEDS_SOFTWARE_SKINNING = (1 << 23), // OBSOLETE
  343. MATERIAL_VAR_OPAQUETEXTURE = (1 << 24),
  344. MATERIAL_VAR_MULTIPLY = (1 << 25),
  345. MATERIAL_VAR_SUPPRESS_DECALS = (1 << 26),
  346. MATERIAL_VAR_HALFLAMBERT = (1 << 27),
  347. MATERIAL_VAR_WIREFRAME = (1 << 28),
  348. MATERIAL_VAR_ALLOWALPHATOCOVERAGE = (1 << 29),
  349. MATERIAL_VAR_ALPHA_MODIFIED_BY_PROXY = (1 << 30),
  350. MATERIAL_VAR_VERTEXFOG = (1 << 31),
  351. // NOTE: Only add flags here that either should be read from
  352. // .vmts or can be set directly from client code. Other, internal
  353. // flags should to into the flag enum in IMaterialInternal.h
  354. };
  355. //-----------------------------------------------------------------------------
  356. // Internal flags not accessible from outside the material system. Stored in Flags2
  357. //-----------------------------------------------------------------------------
  358. enum MaterialVarFlags2_t
  359. {
  360. // NOTE: These are for $flags2!!!!!
  361. // UNUSED = (1 << 0),
  362. MATERIAL_VAR2_LIGHTING_UNLIT = 0,
  363. MATERIAL_VAR2_LIGHTING_VERTEX_LIT = (1 << 1),
  364. MATERIAL_VAR2_LIGHTING_LIGHTMAP = (1 << 2),
  365. MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP = (1 << 3),
  366. MATERIAL_VAR2_LIGHTING_MASK =
  367. ( MATERIAL_VAR2_LIGHTING_VERTEX_LIT |
  368. MATERIAL_VAR2_LIGHTING_LIGHTMAP |
  369. MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ),
  370. // FIXME: Should this be a part of the above lighting enums?
  371. MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL = (1 << 4),
  372. MATERIAL_VAR2_USES_ENV_CUBEMAP = (1 << 5),
  373. MATERIAL_VAR2_NEEDS_TANGENT_SPACES = (1 << 6),
  374. MATERIAL_VAR2_NEEDS_SOFTWARE_LIGHTING = (1 << 7),
  375. // GR - HDR path puts lightmap alpha in separate texture...
  376. MATERIAL_VAR2_BLEND_WITH_LIGHTMAP_ALPHA = (1 << 8),
  377. MATERIAL_VAR2_USE_FLASHLIGHT = (1 << 10),
  378. MATERIAL_VAR2_USE_PAINT = (1 << 11),
  379. MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT = (1 << 12),
  380. MATERIAL_VAR2_USE_EDITOR = (1 << 13),
  381. MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE = (1 << 14),
  382. MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE = (1 << 15),
  383. MATERIAL_VAR2_IS_SPRITECARD = (1 << 16),
  384. MATERIAL_VAR2_USES_VERTEXID = (1 << 17),
  385. MATERIAL_VAR2_SUPPORTS_HW_SKINNING = (1 << 18),
  386. MATERIAL_VAR2_SUPPORTS_FLASHLIGHT = (1 << 19),
  387. MATERIAL_VAR2_USE_GBUFFER0 = (1 << 20),
  388. MATERIAL_VAR2_USE_GBUFFER1 = (1 << 21),
  389. MATERIAL_VAR2_SELFILLUMMASK = (1 << 22),
  390. MATERIAL_VAR2_SUPPORTS_TESSELLATION = (1 << 23)
  391. };
  392. //-----------------------------------------------------------------------------
  393. // Preview image return values
  394. //-----------------------------------------------------------------------------
  395. enum PreviewImageRetVal_t
  396. {
  397. MATERIAL_PREVIEW_IMAGE_BAD = 0,
  398. MATERIAL_PREVIEW_IMAGE_OK,
  399. MATERIAL_NO_PREVIEW_IMAGE,
  400. };
  401. //-----------------------------------------------------------------------------
  402. // material interface
  403. //-----------------------------------------------------------------------------
  404. abstract_class IMaterial
  405. {
  406. public:
  407. // Get the name of the material. This is a full path to
  408. // the vmt file starting from "hl2/materials" (or equivalent) without
  409. // a file extension.
  410. virtual const char * GetName() const = 0;
  411. virtual const char * GetTextureGroupName() const = 0;
  412. // Get the preferred size/bitDepth of a preview image of a material.
  413. // This is the sort of image that you would use for a thumbnail view
  414. // of a material, or in WorldCraft until it uses materials to render.
  415. // separate this for the tools maybe
  416. virtual PreviewImageRetVal_t GetPreviewImageProperties( int *width, int *height,
  417. ImageFormat *imageFormat, bool* isTranslucent ) const = 0;
  418. // Get a preview image at the specified width/height and bitDepth.
  419. // Will do resampling if necessary.(not yet!!! :) )
  420. // Will do color format conversion. (works now.)
  421. virtual PreviewImageRetVal_t GetPreviewImage( unsigned char *data,
  422. int width, int height,
  423. ImageFormat imageFormat ) const = 0;
  424. //
  425. virtual int GetMappingWidth( ) = 0;
  426. virtual int GetMappingHeight( ) = 0;
  427. virtual int GetNumAnimationFrames( ) = 0;
  428. // For material subrects (material pages). Offset(u,v) and scale(u,v) are normalized to texture.
  429. virtual bool InMaterialPage( void ) = 0;
  430. virtual void GetMaterialOffset( float *pOffset ) = 0;
  431. virtual void GetMaterialScale( float *pScale ) = 0;
  432. virtual IMaterial *GetMaterialPage( void ) = 0;
  433. // find a vmt variable.
  434. // This is how game code affects how a material is rendered.
  435. // The game code must know about the params that are used by
  436. // the shader for the material that it is trying to affect.
  437. virtual IMaterialVar * FindVar( const char *varName, bool *found, bool complain = true ) = 0;
  438. // The user never allocates or deallocates materials. Reference counting is
  439. // used instead. Garbage collection is done upon a call to
  440. // IMaterialSystem::UncacheUnusedMaterials.
  441. virtual void IncrementReferenceCount( void ) = 0;
  442. virtual void DecrementReferenceCount( void ) = 0;
  443. inline void AddRef() { IncrementReferenceCount(); }
  444. inline void Release() { DecrementReferenceCount(); }
  445. // Each material is assigned a number that groups it with like materials
  446. // for sorting in the application.
  447. virtual int GetEnumerationID( void ) const = 0;
  448. virtual void GetLowResColorSample( float s, float t, float *color ) const = 0;
  449. // This computes the state snapshots for this material
  450. virtual void RecomputeStateSnapshots() = 0;
  451. // Are we translucent?
  452. virtual bool IsTranslucent() = 0;
  453. // Are we alphatested?
  454. virtual bool IsAlphaTested() = 0;
  455. // Are we vertex lit?
  456. virtual bool IsVertexLit() = 0;
  457. // Gets the vertex format
  458. virtual VertexFormat_t GetVertexFormat() const = 0;
  459. // returns true if this material uses a material proxy
  460. virtual bool HasProxy( void ) const = 0;
  461. virtual bool UsesEnvCubemap( void ) = 0;
  462. virtual bool NeedsTangentSpace( void ) = 0;
  463. virtual bool NeedsPowerOfTwoFrameBufferTexture( bool bCheckSpecificToThisFrame = true ) = 0;
  464. virtual bool NeedsFullFrameBufferTexture( bool bCheckSpecificToThisFrame = true ) = 0;
  465. // returns true if the shader doesn't do skinning itself and requires
  466. // the data that is sent to it to be preskinned.
  467. virtual bool NeedsSoftwareSkinning( void ) = 0;
  468. // Apply constant color or alpha modulation
  469. virtual void AlphaModulate( float alpha ) = 0;
  470. virtual void ColorModulate( float r, float g, float b ) = 0;
  471. // Material Var flags...
  472. virtual void SetMaterialVarFlag( MaterialVarFlags_t flag, bool on ) = 0;
  473. virtual bool GetMaterialVarFlag( MaterialVarFlags_t flag ) const = 0;
  474. // Gets material reflectivity
  475. virtual void GetReflectivity( Vector& reflect ) = 0;
  476. // Gets material property flags
  477. virtual bool GetPropertyFlag( MaterialPropertyTypes_t type ) = 0;
  478. // Is the material visible from both sides?
  479. virtual bool IsTwoSided() = 0;
  480. // Sets the shader associated with the material
  481. virtual void SetShader( const char *pShaderName ) = 0;
  482. // Can't be const because the material might have to precache itself.
  483. virtual int GetNumPasses( void ) = 0;
  484. // Can't be const because the material might have to precache itself.
  485. virtual int GetTextureMemoryBytes( void ) = 0;
  486. // Meant to be used with materials created using CreateMaterial
  487. // It updates the materials to reflect the current values stored in the material vars
  488. virtual void Refresh() = 0;
  489. // GR - returns true is material uses lightmap alpha for blending
  490. virtual bool NeedsLightmapBlendAlpha( void ) = 0;
  491. // returns true if the shader doesn't do lighting itself and requires
  492. // the data that is sent to it to be prelighted
  493. virtual bool NeedsSoftwareLighting( void ) = 0;
  494. // Gets at the shader parameters
  495. virtual int ShaderParamCount() const = 0;
  496. virtual IMaterialVar **GetShaderParams( void ) = 0;
  497. // Returns true if this is the error material you get back from IMaterialSystem::FindMaterial if
  498. // the material can't be found.
  499. virtual bool IsErrorMaterial() const = 0;
  500. // Don't want to mess with the vtable layout
  501. virtual void Unused( ) {}
  502. // Gets the current alpha modulation
  503. virtual float GetAlphaModulation() = 0;
  504. virtual void GetColorModulation( float *r, float *g, float *b ) = 0;
  505. // Is this translucent given a particular alpha modulation?
  506. virtual bool IsTranslucentUnderModulation( float fAlphaModulation = 1.0f ) const = 0;
  507. // fast find that stores the index of the found var in the string table in local cache
  508. virtual IMaterialVar * FindVarFast( char const *pVarName, unsigned int *pToken ) = 0;
  509. // Sets new VMT shader parameters for the material
  510. virtual void SetShaderAndParams( KeyValues *pKeyValues ) = 0;
  511. virtual const char * GetShaderName() const = 0;
  512. virtual void DeleteIfUnreferenced() = 0;
  513. virtual bool IsSpriteCard() = 0;
  514. virtual void CallBindProxy( void *proxyData, ICallQueue *pCallQueue ) = 0;
  515. virtual void RefreshPreservingMaterialVars() = 0;
  516. virtual bool WasReloadedFromWhitelist() = 0;
  517. // when enabled, 0 will be a pure exclude, otherwise the desired maxmip
  518. virtual bool SetTempExcluded( bool bSet, int nExcludedDimensionLimit = 0 ) = 0;
  519. virtual int GetReferenceCount() const = 0;
  520. };
  521. inline bool IsErrorMaterial( IMaterial *pMat )
  522. {
  523. return !pMat || pMat->IsErrorMaterial();
  524. }
  525. //
  526. // Vertex stream specifications
  527. //
  528. struct VertexStreamSpec_t
  529. {
  530. enum StreamSpec_t
  531. {
  532. STREAM_DEFAULT, // stream 0: with position, normal, etc.
  533. STREAM_SPECULAR1, // stream 1: following specular vhv lighting
  534. STREAM_FLEXDELTA, // stream 2: flex deltas
  535. STREAM_MORPH, // stream 3: morph
  536. STREAM_UNIQUE_A, // unique stream 4
  537. STREAM_UNIQUE_B, // unique stream 5
  538. STREAM_UNIQUE_C, // unique stream 6
  539. STREAM_UNIQUE_D, // unique stream 7
  540. STREAM_SUBDQUADS, // stream 8: quad buffer for subd's
  541. };
  542. enum
  543. {
  544. MAX_UNIQUE_STREAMS = 4
  545. };
  546. VertexFormat_t iVertexDataElement;
  547. StreamSpec_t iStreamSpec;
  548. };
  549. inline VertexStreamSpec_t * FindVertexStreamSpec( VertexFormat_t iElement, VertexStreamSpec_t *arrVertexStreamSpec )
  550. {
  551. for ( ; arrVertexStreamSpec &&
  552. arrVertexStreamSpec->iVertexDataElement != VERTEX_FORMAT_UNKNOWN ;
  553. ++ arrVertexStreamSpec )
  554. {
  555. if ( arrVertexStreamSpec->iVertexDataElement == iElement )
  556. return arrVertexStreamSpec;
  557. }
  558. return NULL;
  559. }
  560. #endif // IMATERIAL_H