Leaked source code of windows server 2003
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.

267 lines
9.7 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3dtri.c
  8. *
  9. * Content: Direct3D hw triangle rasterization code.
  10. *
  11. * Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "precomp.h"
  15. #include "d3ddelta.h"
  16. #include "d3dhw.h"
  17. #include "d3dcntxt.h"
  18. #if defined(_ALPHA_)
  19. #include <math.h>
  20. #endif
  21. //-----------------------------------------------------------------------------
  22. //
  23. // VOID P2_Draw_FVF_Solid_Tri
  24. //
  25. // Hardware render a single triangle coming from three FVF vertices
  26. //
  27. //-----------------------------------------------------------------------------
  28. VOID
  29. P2_Draw_FVF_Solid_Tri(PERMEDIA_D3DCONTEXT *pContext,
  30. LPD3DTLVERTEX lpV0,
  31. LPD3DTLVERTEX lpV1,
  32. LPD3DTLVERTEX lpV2,
  33. LPP2FVFOFFSETS lpFVFOff)
  34. {
  35. DWORD dwFlags = pContext->Hdr.Flags;
  36. DWORD dwColorOffs,dwSpecularOffs,dwTexOffs;
  37. ULONG ulRenderCmd = pContext->RenderCommand;
  38. D3DCOLOR dwColor0, dwColor1, dwColor2;
  39. D3DCOLOR dwSpec0, dwSpec1, dwSpec2;
  40. D3DVALUE fS0, fS1, fS2, fT0, fT1, fT2, fQ0, fQ1, fQ2;
  41. D3DVALUE fKs0, fKs1, fKs2;
  42. PERMEDIA_DEFS(pContext->ppdev);
  43. DBG_D3D((10,"Entering P2_Draw_FVF_Solid_Tri"));
  44. // Set triangle rendering mode
  45. RENDER_TRAPEZOID(ulRenderCmd);
  46. RESERVEDMAPTR(0x80);
  47. // Get FVF structure offsets
  48. __SetFVFOffsets(&dwColorOffs,&dwSpecularOffs,&dwTexOffs,lpFVFOff);
  49. // Get vertex color value (FVF based)
  50. if (dwColorOffs)
  51. {
  52. dwColor0 = FVFCOLOR(lpV0, dwColorOffs)->color;
  53. dwColor1 = FVFCOLOR(lpV1, dwColorOffs)->color;
  54. dwColor2 = FVFCOLOR(lpV2, dwColorOffs)->color;
  55. if (FAKE_ALPHABLEND_MODULATE & pContext->FakeBlendNum)
  56. {
  57. dwColor0 |= 0xFF000000;
  58. dwColor1 |= 0xFF000000;
  59. dwColor2 |= 0xFF000000;
  60. }
  61. }
  62. else
  63. {
  64. // must set default in case no D3DFVF_DIFFUSE
  65. dwColor0 = 0xFFFFFFFF;
  66. dwColor1 = 0xFFFFFFFF;
  67. dwColor2 = 0xFFFFFFFF;
  68. }
  69. // Get vertex specular value (FVF based) if necessary
  70. if ((dwFlags & (CTXT_HAS_SPECULAR_ENABLED | CTXT_HAS_FOGGING_ENABLED))
  71. && (dwSpecularOffs!=0))
  72. {
  73. dwSpec0 = FVFSPEC(lpV0, dwSpecularOffs)->specular;
  74. dwSpec1 = FVFSPEC(lpV1, dwSpecularOffs)->specular;
  75. dwSpec2 = FVFSPEC(lpV2, dwSpecularOffs)->specular;
  76. }
  77. if ( (dwFlags & CTXT_HAS_TEXTURE_ENABLED) && (dwTexOffs != 0) )
  78. {
  79. // Get s,t texture coordinates (FVF based)
  80. fS0 = FVFTEX(lpV0,dwTexOffs)->tu;
  81. fT0 = FVFTEX(lpV0,dwTexOffs)->tv;
  82. fS1 = FVFTEX(lpV1,dwTexOffs)->tu;
  83. fT1 = FVFTEX(lpV1,dwTexOffs)->tv;
  84. fS2 = FVFTEX(lpV2,dwTexOffs)->tu;
  85. fT2 = FVFTEX(lpV2,dwTexOffs)->tv;
  86. // The hw requires us to keep the texture coordinates centered around 0
  87. // and avoid exceeding the texel wrapping limit.
  88. RECENTER_TEX_COORDS(pContext->MaxTextureXf,
  89. pContext->MaxTextureXi, fS0, fS1, fS2);
  90. RECENTER_TEX_COORDS(pContext->MaxTextureYf,
  91. pContext->MaxTextureYi, fT0, fT1, fT2);
  92. // Wrap texture coordinates if necessary
  93. WRAP(fS,dwFlags & CTXT_HAS_WRAPU_ENABLED);
  94. WRAP(fT,dwFlags & CTXT_HAS_WRAPV_ENABLED);
  95. // Scale s,t coordinate values
  96. fS0 *= pContext->DeltaWidthScale;
  97. fS1 *= pContext->DeltaWidthScale;
  98. fS2 *= pContext->DeltaWidthScale;
  99. fT0 *= pContext->DeltaHeightScale;
  100. fT1 *= pContext->DeltaHeightScale;
  101. fT2 *= pContext->DeltaHeightScale;
  102. // Apply perspective corrections if necessary
  103. if (dwFlags & CTXT_HAS_PERSPECTIVE_ENABLED)
  104. {
  105. fQ0 = lpV0->rhw;
  106. fQ1 = lpV1->rhw;
  107. fQ2 = lpV2->rhw;
  108. fS0 *= fQ0;
  109. fT0 *= fQ0;
  110. fS1 *= fQ1;
  111. fT1 *= fQ1;
  112. fS2 *= fQ2;
  113. fT2 *= fQ2;
  114. }
  115. else
  116. {
  117. fQ0 = fQ1 = fQ2 = 1.0;
  118. }
  119. // Send lines s,t,q,ks (conditionaly),x,y,z values
  120. if ((dwFlags & CTXT_HAS_SPECULAR_ENABLED) && (dwSpecularOffs!=0))
  121. {
  122. fKs0 = RGB256_TO_LUMA(RGB_GETRED(dwSpec0),
  123. RGB_GETGREEN(dwSpec0),
  124. RGB_GETBLUE(dwSpec0));
  125. if (dwFlags & CTXT_HAS_GOURAUD_ENABLED)
  126. {
  127. fKs1 = RGB256_TO_LUMA(RGB_GETRED(dwSpec1),
  128. RGB_GETGREEN(dwSpec1),
  129. RGB_GETBLUE(dwSpec1));
  130. fKs2 = RGB256_TO_LUMA(RGB_GETRED(dwSpec2),
  131. RGB_GETGREEN(dwSpec2),
  132. RGB_GETBLUE(dwSpec2));
  133. }
  134. else
  135. {
  136. fKs2 = fKs1 = fKs0;
  137. }
  138. SEND_VERTEX_STQ_KS_XYZ(__Permedia2TagV0FloatS, fS0, fT0, fQ0, fKs0,
  139. lpV0->sx, lpV0->sy, lpV0->sz);
  140. SEND_VERTEX_STQ_KS_XYZ(__Permedia2TagV1FloatS, fS1, fT1, fQ1, fKs1,
  141. lpV1->sx, lpV1->sy, lpV1->sz);
  142. SEND_VERTEX_STQ_KS_XYZ(__Permedia2TagV2FloatS, fS2, fT2, fQ2, fKs2,
  143. lpV2->sx, lpV2->sy, lpV2->sz);
  144. }
  145. else
  146. {
  147. SEND_VERTEX_STQ_XYZ(__Permedia2TagV0FloatS, fS0, fT0, fQ0,
  148. lpV0->sx, lpV0->sy, lpV0->sz);
  149. SEND_VERTEX_STQ_XYZ(__Permedia2TagV1FloatS, fS1, fT1, fQ1,
  150. lpV1->sx, lpV1->sy, lpV1->sz);
  151. SEND_VERTEX_STQ_XYZ(__Permedia2TagV2FloatS, fS2, fT2, fQ2,
  152. lpV2->sx, lpV2->sy, lpV2->sz);
  153. }
  154. }
  155. else // not textured triangle
  156. {
  157. // If specular is enabled, change the colours
  158. if ((dwFlags & CTXT_HAS_SPECULAR_ENABLED) && (dwSpecularOffs!=0))
  159. {
  160. CLAMP8888(dwColor0, dwColor0, dwSpec0);
  161. CLAMP8888(dwColor1, dwColor1, dwSpec1);
  162. CLAMP8888(dwColor2, dwColor2, dwSpec2);
  163. }
  164. // Send triangles x,y,z values
  165. SEND_VERTEX_XYZ(__Permedia2TagV0FloatS, lpV0->sx, lpV0->sy, lpV0->sz);
  166. SEND_VERTEX_XYZ(__Permedia2TagV1FloatS, lpV1->sx, lpV1->sy, lpV1->sz);
  167. SEND_VERTEX_XYZ(__Permedia2TagV2FloatS, lpV2->sx, lpV2->sy, lpV2->sz);
  168. }
  169. // If fog is set, send the appropriate values
  170. if ((dwFlags & CTXT_HAS_FOGGING_ENABLED) && (dwSpecularOffs!=0))
  171. {
  172. SEND_VERTEX_FOG(__Permedia2TagV0FixedF, RGB_GET_GAMBIT_FOG(dwSpec0));
  173. SEND_VERTEX_FOG(__Permedia2TagV1FixedF, RGB_GET_GAMBIT_FOG(dwSpec1));
  174. SEND_VERTEX_FOG(__Permedia2TagV2FixedF, RGB_GET_GAMBIT_FOG(dwSpec2));
  175. }
  176. // Set alpha stippling if required by context
  177. if (dwFlags & CTXT_HAS_ALPHASTIPPLE_ENABLED)
  178. {
  179. SET_STIPPLED_ALPHA( (RGBA_GETALPHA(lpV0->color) >> 4) );
  180. }
  181. // Send appropriate color depending on Gouraud , Mono, & Alpha
  182. if (dwFlags & CTXT_HAS_GOURAUD_ENABLED)
  183. {
  184. // Gouraud shading
  185. if (RENDER_MONO)
  186. {
  187. SEND_VERTEX_RGB_MONO(__Permedia2TagV0FixedS, dwColor0);
  188. SEND_VERTEX_RGB_MONO(__Permedia2TagV1FixedS, dwColor1);
  189. SEND_VERTEX_RGB_MONO(__Permedia2TagV2FixedS, dwColor2);
  190. }
  191. else
  192. {
  193. if (dwFlags & CTXT_HAS_ALPHABLEND_ENABLED)
  194. {
  195. if (pContext->FakeBlendNum & FAKE_ALPHABLEND_ONE_ONE)
  196. {
  197. dwColor0 &= 0xFFFFFF; // supress color's alpha value
  198. dwColor1 &= 0xFFFFFF;
  199. dwColor2 &= 0xFFFFFF;
  200. }
  201. SEND_VERTEX_RGBA(__Permedia2TagV0FixedS, dwColor0);
  202. SEND_VERTEX_RGBA(__Permedia2TagV1FixedS, dwColor1);
  203. SEND_VERTEX_RGBA(__Permedia2TagV2FixedS, dwColor2);
  204. }
  205. else
  206. {
  207. SEND_VERTEX_RGB(__Permedia2TagV0FixedS, dwColor0);
  208. SEND_VERTEX_RGB(__Permedia2TagV1FixedS, dwColor1);
  209. SEND_VERTEX_RGB(__Permedia2TagV2FixedS, dwColor2);
  210. }
  211. }
  212. }
  213. else // Flat shading
  214. {
  215. if (RENDER_MONO)
  216. {
  217. // Get constant color from the blue channel
  218. DWORD BlueChannel = RGBA_GETBLUE(dwColor0);
  219. SEND_PERMEDIA_DATA( ConstantColor,
  220. RGB_MAKE(BlueChannel, BlueChannel, BlueChannel));
  221. }
  222. else
  223. {
  224. if (pContext->FakeBlendNum & FAKE_ALPHABLEND_ONE_ONE)
  225. {
  226. dwColor0 &= 0xFFFFFF;
  227. }
  228. SEND_PERMEDIA_DATA( ConstantColor,
  229. RGBA_MAKE(RGBA_GETBLUE(dwColor0),
  230. RGBA_GETGREEN(dwColor0),
  231. RGBA_GETRED(dwColor0),
  232. RGBA_GETALPHA(dwColor0)));
  233. }
  234. }
  235. SEND_PERMEDIA_DATA(DrawTriangle, ulRenderCmd);
  236. COMMITDMAPTR();
  237. DBG_D3D((10,"Exiting P2_Draw_FVF_Solid_Tri"));
  238. } // P2_Draw_FVF_Solid_Tri