Source code of Windows XP (NT5)
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.

321 lines
10 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: drawprim.hpp
  6. * Content: DrawPrimitive common defines
  7. *
  8. ***************************************************************************/
  9. #ifndef _DRAWPRIM_H_
  10. #define _DRAWPRIM_H_
  11. #define MAX_DX6_VERTICES ((1<<16) - 1)
  12. #ifdef WIN95
  13. #define LOWVERTICESNUMBER 128
  14. #else
  15. #define LOWVERTICESNUMBER 96
  16. #endif
  17. #define D3D_MAX_TLVBUF_CHANGES 5
  18. // All vertices from lpDevI->lpVout are copied to the output buffer, expanding
  19. // to D3DTLVERTEX.
  20. // The output buffer is lpAddress if it is not NULL, otherwise it is TLVbuf
  21. //
  22. //---------------------------------------------------------------------
  23. #define FVF_TRANSFORMED(dwFVF) ((dwFVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)
  24. #define FVF_TEXCOORD_NUMBER(dwFVF) \
  25. (((dwFVF) & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT)
  26. //---------------------------------------------------------------------
  27. // Computes size in bytes of the position component of a vertex
  28. //
  29. __inline DWORD GetPositionSizeFVF(DWORD fvf)
  30. {
  31. DWORD size = 3 << 2;
  32. switch (fvf & D3DFVF_POSITION_MASK)
  33. {
  34. case D3DFVF_XYZRHW: size += 4; break;
  35. case D3DFVF_XYZB1: size += 1*4; break;
  36. case D3DFVF_XYZB2: size += 2*4; break;
  37. case D3DFVF_XYZB3: size += 3*4; break;
  38. case D3DFVF_XYZB4: size += 4*4; break;
  39. case D3DFVF_XYZB5: size += 5*4; break;
  40. }
  41. return size;
  42. }
  43. //---------------------------------------------------------------------
  44. // Computes vertex size in bytes for a the vertex ID excluding size of
  45. // texture oordinates
  46. //
  47. __inline DWORD GetVertexSizeFVF(DWORD fvf)
  48. {
  49. DWORD size = GetPositionSizeFVF(fvf);
  50. if (fvf & D3DFVF_NORMAL)
  51. size += 3*4;
  52. if (fvf & D3DFVF_PSIZE)
  53. size += 4;
  54. if (fvf & D3DFVF_DIFFUSE)
  55. size+= 4;
  56. if (fvf & D3DFVF_SPECULAR)
  57. size += 4;
  58. if (fvf & D3DFVF_FOG)
  59. size += 4;
  60. return size;
  61. }
  62. //---------------------------------------------------------------------
  63. // Entry is texture count. Clears all texture format bits in the FVF DWORD,
  64. // that correspond to the texture count
  65. // for this count
  66. const DWORD g_TextureFormatMask[9] = {
  67. ~0x0000FFFF,
  68. ~0x0003FFFF,
  69. ~0x000FFFFF,
  70. ~0x003FFFFF,
  71. ~0x00FFFFFF,
  72. ~0x03FFFFFF,
  73. ~0x0FFFFFFF,
  74. ~0x3FFFFFFF,
  75. ~0xFFFFFFFF
  76. };
  77. //---------------------------------------------------------------------
  78. // Computes vertex size in bytes from the vertex ID
  79. //
  80. // Texture formats size 00 01 10 11
  81. const BYTE g_TextureSize[4] = {2*4, 3*4, 4*4, 4};
  82. //---------------------------------------------------------------------
  83. // Index is number of floats in a texture coordinate set.
  84. // Value is texture format bits
  85. //
  86. const DWORD g_dwTextureFormat[5] = {0, 3, 0, 1, 2};
  87. //---------------------------------------------------------------------
  88. // Returns total size of texture coordinates
  89. // Computes dwTextureCoordSize[] array - size of every texture coordinate set
  90. //
  91. inline DWORD ComputeTextureCoordSize(DWORD dwFVF, DWORD *dwTextureCoordSize)
  92. {
  93. DWORD dwNumTexCoord = FVF_TEXCOORD_NUMBER(dwFVF);
  94. DWORD dwTextureCoordSizeTotal;
  95. // Compute texture coordinate size
  96. DWORD dwTextureFormats = dwFVF >> 16;
  97. if (dwTextureFormats == 0)
  98. {
  99. dwTextureCoordSizeTotal = (BYTE)dwNumTexCoord * 2 * 4;
  100. for (DWORD i=0; i < dwNumTexCoord; i++)
  101. {
  102. dwTextureCoordSize[i] = 4*2;
  103. }
  104. }
  105. else
  106. {
  107. DWORD dwOffset = 0;
  108. dwTextureCoordSizeTotal = 0;
  109. for (DWORD i=0; i < dwNumTexCoord; i++)
  110. {
  111. BYTE dwSize = g_TextureSize[dwTextureFormats & 3];
  112. dwTextureCoordSize[i] = dwSize;
  113. dwTextureCoordSizeTotal += dwSize;
  114. dwTextureFormats >>= 2;
  115. }
  116. }
  117. return dwTextureCoordSizeTotal;
  118. }
  119. //---------------------------------------------------------------------
  120. // Computes vertex in bytes for the given FVF
  121. //
  122. inline DWORD ComputeVertexSizeFVF(DWORD dwFVF)
  123. {
  124. DWORD dwTextureFormats = dwFVF >> 16;
  125. DWORD dwNumTexCoord = FVF_TEXCOORD_NUMBER(dwFVF);
  126. DWORD size = GetVertexSizeFVF(dwFVF);
  127. if (dwTextureFormats == 0)
  128. {
  129. size += (BYTE)dwNumTexCoord * 2 * 4;
  130. }
  131. else
  132. {
  133. for (DWORD i=0; i < dwNumTexCoord; i++)
  134. {
  135. size += g_TextureSize[dwTextureFormats & 3];
  136. dwTextureFormats >>= 2;
  137. }
  138. }
  139. return size;
  140. }
  141. //---------------------------------------------------------------------
  142. // Computes the number of primtives and also updates the stats accordingly
  143. // Input: lpDevI->primType
  144. // dwNumVertices
  145. // Output: lpDevI->dwNumPrimitives
  146. // return value = dwNumPrimitives
  147. #undef DPF_MODNAME
  148. #define DPF_MODNAME "GetNumPrim"
  149. inline __declspec(nothrow) void GetNumPrim(LPD3DHAL lpDevI, DWORD dwNumVertices)
  150. {
  151. D3DFE_PROCESSVERTICES* pv = lpDevI->m_pv;
  152. pv->dwNumPrimitives = 0;
  153. switch (pv->primType)
  154. {
  155. case D3DPT_POINTLIST:
  156. pv->dwNumPrimitives = dwNumVertices;
  157. break;
  158. case D3DPT_LINELIST:
  159. pv->dwNumPrimitives = dwNumVertices >> 1;
  160. break;
  161. case D3DPT_LINESTRIP:
  162. if (dwNumVertices < 2)
  163. return;
  164. pv->dwNumPrimitives = dwNumVertices - 1;
  165. break;
  166. case D3DPT_TRIANGLEFAN:
  167. case D3DPT_TRIANGLESTRIP:
  168. if (dwNumVertices < 3)
  169. return;
  170. pv->dwNumPrimitives = dwNumVertices - 2;
  171. break;
  172. case D3DPT_TRIANGLELIST:
  173. #ifdef _X86_
  174. {
  175. DWORD tmp;
  176. __asm
  177. {
  178. mov eax, 0x55555555 // fractional part of 1.0/3.0
  179. mul dwNumVertices
  180. add eax, 0x80000000 // Rounding
  181. adc edx, 0
  182. mov tmp, edx
  183. }
  184. pv->dwNumPrimitives = tmp;
  185. }
  186. #else
  187. pv->dwNumPrimitives = dwNumVertices / 3;
  188. #endif
  189. break;
  190. }
  191. }
  192. //---------------------------------------------------------------------
  193. // Sets front-end flags every time fog state is changed
  194. //
  195. inline void CD3DHal::SetFogFlags(void)
  196. {
  197. // Call ForceFVFRecompute only if fog enable state has been changed
  198. BOOL bFogWasEnabled = m_pv->dwDeviceFlags & D3DDEV_FOG;
  199. if (m_pv->lighting.fog_mode != D3DFOG_NONE &&
  200. this->rstates[D3DRENDERSTATE_FOGENABLE])
  201. {
  202. m_pv->dwDeviceFlags |= D3DDEV_FOG;
  203. if (!bFogWasEnabled)
  204. ForceFVFRecompute();
  205. }
  206. else
  207. {
  208. m_pv->dwDeviceFlags &= ~D3DDEV_FOG;
  209. if (bFogWasEnabled)
  210. ForceFVFRecompute();
  211. }
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Computes dwFlags bits which depend on the output FVF
  215. //
  216. inline void UpdateFlagsForOutputFVF(D3DFE_PROCESSVERTICES* lpDevI)
  217. {
  218. if (lpDevI->dwDeviceFlags & D3DDEV_LIGHTING &&
  219. lpDevI->dwVIDOut & (D3DFVF_DIFFUSE | D3DFVF_SPECULAR))
  220. {
  221. lpDevI->dwFlags |= D3DPV_LIGHTING;
  222. }
  223. if (lpDevI->dwDeviceFlags & D3DDEV_FOG && lpDevI->dwVIDOut & D3DFVF_SPECULAR)
  224. {
  225. lpDevI->dwFlags |= D3DPV_FOG;
  226. }
  227. if (!(lpDevI->dwVIDOut & D3DFVF_DIFFUSE))
  228. lpDevI->dwFlags |= D3DPV_DONOTCOPYDIFFUSE;
  229. if (!(lpDevI->dwVIDOut & D3DFVF_SPECULAR))
  230. lpDevI->dwFlags |= D3DPV_DONOTCOPYSPECULAR;
  231. }
  232. //---------------------------------------------------------------------
  233. // Restore indices in the texture stages which were re-mapped for texture
  234. // transforms
  235. // We have to do restore if
  236. // - Set or Get render state is issued with _WRAP parameter
  237. // - Set or Get texture stage is issued with TEXCOORDINDEX as a parameter
  238. //
  239. extern void RestoreTextureStages(LPD3DHAL pDevI);
  240. //---------------------------------------------------------------------
  241. // the function works when there are texture transforms.
  242. // It computes number of output texture coordinates, texture coordinate size and format.
  243. // It prepares texture stages to re-map texture coordinates
  244. //
  245. void EvalTextureTransforms(LPD3DHAL pDevI, DWORD dwTexTransform,
  246. DWORD *pdwOutTextureSize, DWORD *pdwOutTextureFormat);
  247. //----------------------------------------------------------------------
  248. // Sets texture transform pointer for every input texture coordinate set
  249. //
  250. void SetupTextureTransforms(LPD3DHAL pDevI);
  251. //----------------------------------------------------------------------
  252. inline BOOL TextureTransformEnabled(LPD3DHAL pDevI)
  253. {
  254. return __TEXTURETRANSFORMENABLED(pDevI->m_pv);
  255. }
  256. //-----------------------------------------------------------------------------
  257. // Having primitive type as index, this array returns two coefficients("a" and
  258. // "b") to compute number of vertices as NumPrimitives*a + b
  259. //
  260. extern DWORD g_PrimToVerCount[7][2];
  261. //-----------------------------------------------------------------------------
  262. inline UINT GETVERTEXCOUNT(D3DPRIMITIVETYPE primType, UINT dwNumPrimitives)
  263. {
  264. return g_PrimToVerCount[primType][0] * dwNumPrimitives +
  265. g_PrimToVerCount[primType][1];
  266. }
  267. extern void setIdentity(D3DMATRIXI * m);
  268. extern void MatrixProduct(D3DMATRIXI *d, D3DMATRIXI *a, D3DMATRIXI *b);
  269. extern LIGHT_VERTEX_FUNC_TABLE lightVertexTable;
  270. extern void MatrixProduct(D3DMATRIXI *result, D3DMATRIXI *a, D3DMATRIXI *b);
  271. void D3DFE_UpdateLights(LPD3DHAL lpDevI);
  272. //---------------------------------------------------------------------
  273. // Updates lighting and computes process vertices flags
  274. //
  275. extern void DoUpdateState(LPD3DHAL lpDevI);
  276. //----------------------------------------------------------------------
  277. inline void UpdateClipStatus(CD3DHal* pDev)
  278. {
  279. pDev->m_ClipStatus.ClipUnion |= pDev->m_pv->dwClipUnion;
  280. pDev->m_ClipStatus.ClipIntersection &= pDev->m_pv->dwClipIntersection;
  281. }
  282. //----------------------------------------------------------------------
  283. // This is a list of all rstates that which are for the vertex processing only.
  284. // In the software vertex processing mode these render states are not passed
  285. // to the driver. The are passed when we switch to the hardware vertex processing mode
  286. //
  287. const D3DRENDERSTATETYPE rsVertexProcessingList[] = {
  288. D3DRS_RANGEFOGENABLE,
  289. D3DRS_LIGHTING,
  290. D3DRS_AMBIENT,
  291. D3DRS_FOGVERTEXMODE,
  292. D3DRS_COLORVERTEX,
  293. D3DRS_LOCALVIEWER,
  294. D3DRS_NORMALIZENORMALS,
  295. D3DRS_DIFFUSEMATERIALSOURCE,
  296. D3DRS_SPECULARMATERIALSOURCE,
  297. D3DRS_AMBIENTMATERIALSOURCE,
  298. D3DRS_EMISSIVEMATERIALSOURCE,
  299. D3DRS_VERTEXBLEND,
  300. D3DRS_CLIPPLANEENABLE,
  301. D3DRS_SOFTWAREVERTEXPROCESSING,
  302. D3DRS_POINTSCALEENABLE,
  303. D3DRS_POINTSCALE_A,
  304. D3DRS_POINTSCALE_B,
  305. D3DRS_POINTSCALE_C,
  306. D3DRS_INDEXEDVERTEXBLENDENABLE,
  307. D3DRS_TWEENFACTOR
  308. };
  309. #endif _DRAWPRIM_H_