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.

404 lines
16 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: helxfrm.c
  6. * Content: Direct3D front-end transform and process vertices
  7. *
  8. ***************************************************************************/
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. #include "light.h"
  12. void MatrixProduct2(D3DMATRIXI *result, D3DMATRIXI *a, D3DMATRIXI *b);
  13. D3DFE_PVFUNCS GeometryFuncsGuaranteed; // Our implementation
  14. DWORD debugFlags = 0;
  15. void SetDebugRenderState(DWORD value)
  16. {
  17. debugFlags = value;
  18. }
  19. //---------------------------------------------------------------------
  20. void setIdentity(D3DMATRIXI * m)
  21. {
  22. m->type = D3DIMatrixIdentity;
  23. m->_11 = D3DVAL(1.0); m->_12 = D3DVAL(0.0); m->_13 = D3DVAL(0.0); m->_14 = D3DVAL(0.0);
  24. m->_21 = D3DVAL(0.0); m->_22 = D3DVAL(1.0); m->_23 = D3DVAL(0.0); m->_24 = D3DVAL(0.0);
  25. m->_31 = D3DVAL(0.0); m->_32 = D3DVAL(0.0); m->_33 = D3DVAL(1.0); m->_34 = D3DVAL(0.0);
  26. m->_41 = D3DVAL(0.0); m->_42 = D3DVAL(0.0); m->_43 = D3DVAL(0.0); m->_44 = D3DVAL(1.0);
  27. }
  28. //---------------------------------------------------------------------
  29. HRESULT D3DFE_InitTransform(LPDIRECT3DDEVICEI lpDevI)
  30. {
  31. D3DFE_TRANSFORM *transform = &lpDevI->transform;
  32. LIST_INITIALIZE(&transform->matrices);
  33. lpDevI->rExtents.x1 = 0;
  34. lpDevI->rExtents.y1 = 0;
  35. lpDevI->rExtents.x2 = 0;
  36. lpDevI->rExtents.y2 = 0;
  37. setIdentity(&lpDevI->mCTM);
  38. setIdentity(&transform->proj);
  39. setIdentity(&transform->world);
  40. setIdentity(&transform->view);
  41. STATESET_INIT(lpDevI->transformstate_overrides);
  42. return (D3D_OK);
  43. }
  44. //---------------------------------------------------------------------
  45. void D3DFE_DestroyTransform(LPDIRECT3DDEVICEI lpDevI)
  46. {
  47. D3DFE_TRANSFORM *transform = &lpDevI->transform;
  48. while (LIST_FIRST(&transform->matrices)) {
  49. LPD3DMATRIXI lpMat;
  50. lpMat = LIST_FIRST(&transform->matrices);
  51. LIST_DELETE(lpMat, link);
  52. D3DFree(lpMat);
  53. }
  54. }
  55. //---------------------------------------------------------------------
  56. /*
  57. * Combine all matrices.
  58. */
  59. void updateTransform(LPDIRECT3DDEVICEI lpDevI)
  60. {
  61. D3DFE_VIEWPORTCACHE& VPORT = lpDevI->vcache;
  62. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  63. if (lpDevI->dwFEFlags & (D3DFE_VIEWPORT_DIRTY | D3DFE_PROJMATRIX_DIRTY))
  64. { // Update Mproj*Mclip
  65. if (lpDevI->dwFEFlags & D3DFE_PROJ_PERSPECTIVE)
  66. {
  67. TRANSFORM.mPC._11 = TRANSFORM.proj._11*VPORT.mclip11;
  68. TRANSFORM.mPC._12 = D3DVAL(0);
  69. TRANSFORM.mPC._13 = D3DVAL(0);
  70. TRANSFORM.mPC._14 = D3DVAL(0);
  71. TRANSFORM.mPC._21 = D3DVAL(0);
  72. TRANSFORM.mPC._22 = TRANSFORM.proj._22*VPORT.mclip22;
  73. TRANSFORM.mPC._23 = D3DVAL(0);
  74. TRANSFORM.mPC._24 = D3DVAL(0);
  75. TRANSFORM.mPC._31 = VPORT.mclip41;
  76. TRANSFORM.mPC._32 = VPORT.mclip42;
  77. TRANSFORM.mPC._33 = TRANSFORM.proj._33*VPORT.mclip33 +
  78. TRANSFORM.proj._34*VPORT.mclip43;
  79. TRANSFORM.mPC._34 = D3DVAL(1);
  80. TRANSFORM.mPC._41 = TRANSFORM.proj._41*VPORT.mclip11;
  81. TRANSFORM.mPC._42 = TRANSFORM.proj._42*VPORT.mclip22;
  82. TRANSFORM.mPC._43 = TRANSFORM.proj._43*VPORT.mclip33;
  83. TRANSFORM.mPC._44 = TRANSFORM.proj._44;
  84. }
  85. else
  86. {
  87. TRANSFORM.mPC._11 = TRANSFORM.proj._11*VPORT.mclip11 +
  88. TRANSFORM.proj._14*VPORT.mclip41;
  89. TRANSFORM.mPC._12 = TRANSFORM.proj._12*VPORT.mclip22 +
  90. TRANSFORM.proj._14*VPORT.mclip42;
  91. TRANSFORM.mPC._13 = TRANSFORM.proj._13*VPORT.mclip33 +
  92. TRANSFORM.proj._14*VPORT.mclip43;
  93. TRANSFORM.mPC._14 = TRANSFORM.proj._14;
  94. TRANSFORM.mPC._21 = TRANSFORM.proj._21*VPORT.mclip11 +
  95. TRANSFORM.proj._24*VPORT.mclip41;
  96. TRANSFORM.mPC._22 = TRANSFORM.proj._22*VPORT.mclip22 +
  97. TRANSFORM.proj._24*VPORT.mclip42;
  98. TRANSFORM.mPC._23 = TRANSFORM.proj._23*VPORT.mclip33 +
  99. TRANSFORM.proj._24*VPORT.mclip43;
  100. TRANSFORM.mPC._24 = TRANSFORM.proj._24;
  101. TRANSFORM.mPC._31 = TRANSFORM.proj._31*VPORT.mclip11 +
  102. TRANSFORM.proj._34*VPORT.mclip41;
  103. TRANSFORM.mPC._32 = TRANSFORM.proj._32*VPORT.mclip22 +
  104. TRANSFORM.proj._34*VPORT.mclip42;
  105. TRANSFORM.mPC._33 = TRANSFORM.proj._33*VPORT.mclip33 +
  106. TRANSFORM.proj._34*VPORT.mclip43;
  107. TRANSFORM.mPC._34 = TRANSFORM.proj._34;
  108. TRANSFORM.mPC._41 = TRANSFORM.proj._41*VPORT.mclip11 +
  109. TRANSFORM.proj._44*VPORT.mclip41;
  110. TRANSFORM.mPC._42 = TRANSFORM.proj._42*VPORT.mclip22 +
  111. TRANSFORM.proj._44*VPORT.mclip42;
  112. TRANSFORM.mPC._43 = TRANSFORM.proj._43*VPORT.mclip33 +
  113. TRANSFORM.proj._44*VPORT.mclip43;
  114. TRANSFORM.mPC._44 = TRANSFORM.proj._44;
  115. }
  116. }
  117. if (lpDevI->dwFEFlags & (D3DFE_VIEWMATRIX_DIRTY |
  118. D3DFE_VIEWPORT_DIRTY |
  119. D3DFE_PROJMATRIX_DIRTY))
  120. { // Update Mview*Mproj*Mclip
  121. MatrixProduct(&TRANSFORM.mVPC, &TRANSFORM.view, &TRANSFORM.mPC);
  122. }
  123. MatrixProduct(&lpDevI->mCTM, &TRANSFORM.world, &TRANSFORM.mVPC);
  124. if ((lpDevI->dwFEFlags & (D3DFE_AFFINE_WORLD | D3DFE_AFFINE_VIEW)) ==
  125. (D3DFE_AFFINE_WORLD | D3DFE_AFFINE_VIEW))
  126. lpDevI->dwFEFlags |= D3DFE_AFFINE_WORLD_VIEW;
  127. else
  128. lpDevI->dwFEFlags &= ~D3DFE_AFFINE_WORLD_VIEW;
  129. // Set dirty bit for world*view matrix (needed for fog)
  130. if (lpDevI->dwFEFlags & (D3DFE_VIEWMATRIX_DIRTY |
  131. D3DFE_WORLDMATRIX_DIRTY))
  132. lpDevI->dwFEFlags |= D3DFE_WORLDVIEWMATRIX_DIRTY;
  133. // All matrices are set up
  134. lpDevI->dwFEFlags &= ~D3DFE_TRANSFORM_DIRTY;
  135. // Set dirty bit for lighting
  136. lpDevI->dwFEFlags |= D3DFE_NEED_TRANSFORM_LIGHTS |
  137. D3DFE_INVERSEMCLIP_DIRTY |
  138. D3DFE_FRUSTUMPLANES_DIRTY;
  139. lpDevI->dwFlags |= D3DPV_TRANSFORMDIRTY;
  140. lpDevI->dwDeviceFlags |= D3DDEV_TRANSFORMDIRTY;
  141. }
  142. //---------------------------------------------------------------------
  143. void UpdateMatrixProj(LPDIRECT3DDEVICEI lpDevI)
  144. {
  145. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  146. lpDevI->dwFEFlags &= ~D3DFE_PROJ_PERSPECTIVE;
  147. if (FLOAT_EQZ(TRANSFORM.proj._12) &&
  148. FLOAT_EQZ(TRANSFORM.proj._13) &&
  149. FLOAT_EQZ(TRANSFORM.proj._14) &&
  150. FLOAT_EQZ(TRANSFORM.proj._21) &&
  151. FLOAT_EQZ(TRANSFORM.proj._23) &&
  152. FLOAT_EQZ(TRANSFORM.proj._24) &&
  153. FLOAT_EQZ(TRANSFORM.proj._31) &&
  154. FLOAT_EQZ(TRANSFORM.proj._32) &&
  155. FLOAT_CMP_PONE(TRANSFORM.proj._34, ==))
  156. {
  157. lpDevI->dwFEFlags |= D3DFE_PROJ_PERSPECTIVE;
  158. }
  159. lpDevI->dwFEFlags |= D3DFE_PROJMATRIX_DIRTY;
  160. }
  161. //---------------------------------------------------------------------
  162. void UpdateMatrixView(LPDIRECT3DDEVICEI lpDevI)
  163. {
  164. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  165. lpDevI->dwFEFlags &= ~D3DFE_AFFINE_VIEW;
  166. if (FLOAT_EQZ(TRANSFORM.view._14) &&
  167. FLOAT_EQZ(TRANSFORM.view._24) &&
  168. FLOAT_EQZ(TRANSFORM.view._34) &&
  169. FLOAT_CMP_PONE(TRANSFORM.view._44, ==))
  170. {
  171. lpDevI->dwFEFlags |= D3DFE_AFFINE_VIEW;
  172. }
  173. lpDevI->dwFEFlags |= D3DFE_VIEWMATRIX_DIRTY;
  174. }
  175. //---------------------------------------------------------------------
  176. void UpdateMatrixWorld(LPDIRECT3DDEVICEI lpDevI)
  177. {
  178. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  179. lpDevI->dwFEFlags &= ~D3DFE_AFFINE_WORLD;
  180. if (FLOAT_EQZ(TRANSFORM.world._14) &&
  181. FLOAT_EQZ(TRANSFORM.world._24) &&
  182. FLOAT_EQZ(TRANSFORM.world._34) &&
  183. FLOAT_CMP_PONE(TRANSFORM.world._44, ==))
  184. {
  185. lpDevI->dwFEFlags |= D3DFE_AFFINE_WORLD;
  186. }
  187. lpDevI->dwFEFlags |= D3DFE_WORLDMATRIX_DIRTY;
  188. }
  189. //---------------------------------------------------------------------
  190. HRESULT D3DFE_SetMatrixProj(LPDIRECT3DDEVICEI lpDevI, D3DMATRIX *mat)
  191. {
  192. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  193. *(D3DMATRIX*)&TRANSFORM.proj = *mat;
  194. UpdateMatrixProj(lpDevI);
  195. return (D3D_OK);
  196. }
  197. //---------------------------------------------------------------------
  198. HRESULT D3DFE_SetMatrixView(LPDIRECT3DDEVICEI lpDevI, D3DMATRIX *mat)
  199. {
  200. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  201. *(D3DMATRIX*)&TRANSFORM.view = *mat;
  202. UpdateMatrixView(lpDevI);
  203. return (D3D_OK);
  204. }
  205. //---------------------------------------------------------------------
  206. HRESULT D3DFE_SetMatrixWorld(LPDIRECT3DDEVICEI lpDevI, D3DMATRIX *mat)
  207. {
  208. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  209. *(D3DMATRIX*)&TRANSFORM.world = *mat;
  210. UpdateMatrixWorld(lpDevI);
  211. return (D3D_OK);
  212. }
  213. //---------------------------------------------------------------------
  214. HRESULT D3DFE_MultMatrixProj(LPDIRECT3DDEVICEI lpDevI, D3DMATRIX *mat)
  215. {
  216. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  217. MatrixProduct(&TRANSFORM.proj, (D3DMATRIXI*)mat, &TRANSFORM.proj);
  218. UpdateMatrixProj(lpDevI);
  219. return (D3D_OK);
  220. }
  221. //---------------------------------------------------------------------
  222. HRESULT D3DFE_MultMatrixView(LPDIRECT3DDEVICEI lpDevI, D3DMATRIX *mat)
  223. {
  224. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  225. MatrixProduct(&TRANSFORM.view, (D3DMATRIXI*)mat, &TRANSFORM.view);
  226. UpdateMatrixView(lpDevI);
  227. return (D3D_OK);
  228. }
  229. //---------------------------------------------------------------------
  230. HRESULT D3DFE_MultMatrixWorld(LPDIRECT3DDEVICEI lpDevI, D3DMATRIX *mat)
  231. {
  232. D3DFE_TRANSFORM& TRANSFORM = lpDevI->transform;
  233. MatrixProduct(&TRANSFORM.world, (D3DMATRIXI*)mat, &TRANSFORM.world);
  234. UpdateMatrixWorld(lpDevI);
  235. return (D3D_OK);
  236. }
  237. //---------------------------------------------------------------------
  238. #define MATRIX_PRODUCT(res, a, b) \
  239. res->_11 = a->_11*b->_11 + a->_12*b->_21 + a->_13*b->_31 + a->_14*b->_41; \
  240. res->_12 = a->_11*b->_12 + a->_12*b->_22 + a->_13*b->_32 + a->_14*b->_42; \
  241. res->_13 = a->_11*b->_13 + a->_12*b->_23 + a->_13*b->_33 + a->_14*b->_43; \
  242. res->_14 = a->_11*b->_14 + a->_12*b->_24 + a->_13*b->_34 + a->_14*b->_44; \
  243. \
  244. res->_21 = a->_21*b->_11 + a->_22*b->_21 + a->_23*b->_31 + a->_24*b->_41; \
  245. res->_22 = a->_21*b->_12 + a->_22*b->_22 + a->_23*b->_32 + a->_24*b->_42; \
  246. res->_23 = a->_21*b->_13 + a->_22*b->_23 + a->_23*b->_33 + a->_24*b->_43; \
  247. res->_24 = a->_21*b->_14 + a->_22*b->_24 + a->_23*b->_34 + a->_24*b->_44; \
  248. \
  249. res->_31 = a->_31*b->_11 + a->_32*b->_21 + a->_33*b->_31 + a->_34*b->_41; \
  250. res->_32 = a->_31*b->_12 + a->_32*b->_22 + a->_33*b->_32 + a->_34*b->_42; \
  251. res->_33 = a->_31*b->_13 + a->_32*b->_23 + a->_33*b->_33 + a->_34*b->_43; \
  252. res->_34 = a->_31*b->_14 + a->_32*b->_24 + a->_33*b->_34 + a->_34*b->_44; \
  253. \
  254. res->_41 = a->_41*b->_11 + a->_42*b->_21 + a->_43*b->_31 + a->_44*b->_41; \
  255. res->_42 = a->_41*b->_12 + a->_42*b->_22 + a->_43*b->_32 + a->_44*b->_42; \
  256. res->_43 = a->_41*b->_13 + a->_42*b->_23 + a->_43*b->_33 + a->_44*b->_43; \
  257. res->_44 = a->_41*b->_14 + a->_42*b->_24 + a->_43*b->_34 + a->_44*b->_44;
  258. //---------------------------------------------------------------------
  259. // result = a*b.
  260. // "result" pointer could be equal to "a" or "b"
  261. //
  262. void MatrixProduct(D3DMATRIXI *result, D3DMATRIXI *a, D3DMATRIXI *b)
  263. {
  264. if (result == a || result == b)
  265. {
  266. MatrixProduct2(result, a, b);
  267. return;
  268. }
  269. MATRIX_PRODUCT(result, a, b);
  270. }
  271. //---------------------------------------------------------------------
  272. // result = a*b
  273. // result is the same as a or b
  274. //
  275. void MatrixProduct2(D3DMATRIXI *result, D3DMATRIXI *a, D3DMATRIXI *b)
  276. {
  277. D3DMATRIX res;
  278. MATRIX_PRODUCT((&res), a, b);
  279. *(D3DMATRIX*)result = res;
  280. }
  281. //--------------------------------------------------------------------------
  282. // Transform vertices for viewport
  283. //
  284. #define _PV_NAME D3DFE_TransformClippedVp
  285. #define _PV_VIEWPORT
  286. #define _PV_CLIP
  287. #define _PV_EXTENT
  288. #include "procver.h"
  289. #undef _PV_NAME
  290. #undef _PV_CLIP
  291. #undef _PV_EXTENT
  292. #undef _PV_VIEWPORT
  293. #define _PV_NAME D3DFE_TransformUnclippedVp
  294. #define _PV_VIEWPORT
  295. #define _PV_EXTENT
  296. #include "procver.h"
  297. #undef _PV_NAME
  298. #undef _PV_EXTENT
  299. #undef _PV_VIEWPORT
  300. //---------------------------------------------------------------------------
  301. void D3DFE_UpdateFog(LPDIRECT3DDEVICEI lpDevI)
  302. {
  303. D3DFE_LIGHTING& LIGHTING = lpDevI->lighting;
  304. if (LIGHTING.fog_end == LIGHTING.fog_start)
  305. {
  306. LIGHTING.fog_factor = D3DVAL(0.0);
  307. LIGHTING.fog_factor_ramp = D3DVAL(0.0);
  308. }
  309. else
  310. {
  311. LIGHTING.fog_factor = D3DVAL(255) / (LIGHTING.fog_end - LIGHTING.fog_start);
  312. if (lpDevI->dwDeviceFlags & D3DDEV_RAMP)
  313. LIGHTING.fog_factor_ramp = D3DVAL(1.0/255.0) * LIGHTING.fog_factor;
  314. }
  315. lpDevI->dwFEFlags &= ~D3DFE_FOG_DIRTY;
  316. }
  317. //----------------------------------------------------------------------------
  318. void UpdateXfrmLight(LPDIRECT3DDEVICEI lpDevI)
  319. {
  320. if (lpDevI->dwFEFlags & D3DFE_TRANSFORM_DIRTY)
  321. updateTransform(lpDevI);
  322. if (lpDevI->dwDeviceFlags & D3DDEV_RAMP)
  323. {
  324. RAMP_RANGE_INFO rampInfo;
  325. CallRampService(lpDevI, RAMP_SERVICE_FIND_LIGHTINGRANGE,
  326. (ULONG_PTR)&rampInfo, 0);
  327. lpDevI->dwRampBase = rampInfo.base;
  328. lpDevI->dvRampScale = D3DVAL(max(min((INT32)rampInfo.size - 1, 0x7fff), 0));
  329. lpDevI->lpvRampTexture = rampInfo.pTexRampMap;
  330. if (rampInfo.specular)
  331. lpDevI->dwFlags |= D3DPV_RAMPSPECULAR;
  332. else
  333. lpDevI->dwFlags &= ~D3DPV_RAMPSPECULAR;
  334. }
  335. if ((lpDevI->dwFlags & D3DPV_LIGHTING) &&
  336. lpDevI->dwFEFlags & (D3DFE_NEED_TRANSFORM_LIGHTS |
  337. D3DFE_LIGHTS_DIRTY |
  338. D3DFE_MATERIAL_DIRTY))
  339. {
  340. D3DFE_UpdateLights(lpDevI);
  341. lpDevI->dwFlags |= D3DPV_LIGHTSDIRTY;
  342. lpDevI->dwDeviceFlags |= D3DDEV_LIGHTSDIRTY;
  343. }
  344. if (lpDevI->dwFEFlags & D3DFE_FOGENABLED)
  345. {
  346. lpDevI->dwFlags |= D3DPV_FOG;
  347. if (lpDevI->rstates[D3DRENDERSTATE_RANGEFOGENABLE])
  348. lpDevI->dwFlags |= D3DPV_RANGEBASEDFOG;
  349. if (lpDevI->dwFEFlags & D3DFE_FOG_DIRTY)
  350. D3DFE_UpdateFog(lpDevI);
  351. if (lpDevI->dwFEFlags & D3DFE_WORLDVIEWMATRIX_DIRTY)
  352. {
  353. MatrixProduct(&lpDevI->mWV, &lpDevI->transform.world,
  354. &lpDevI->transform.view);
  355. lpDevI->dwFEFlags &= ~D3DFE_WORLDVIEWMATRIX_DIRTY;
  356. }
  357. }
  358. }
  359. //---------------------------------------------------------------------
  360. // Convert extents from floating point to integer.
  361. //
  362. #undef DPF_MODNAME
  363. #define DPF_MODNAME "D3DFE_ConvertExtent"
  364. void D3DFE_ConvertExtent(LPDIRECT3DDEVICEI lpDevI, LPD3DRECTV from, LPD3DRECT to)
  365. {
  366. to->x1 = FTOI(from->x1) - 1;
  367. to->y1 = FTOI(from->y1) - 1;
  368. to->x2 = FTOI(from->x2) + 1;
  369. to->y2 = FTOI(from->y2) + 1;
  370. if (to->x1 < lpDevI->vcache.minXi)
  371. to->x1 = lpDevI->vcache.minXi;
  372. if (to->y1 < lpDevI->vcache.minYi)
  373. to->y1 = lpDevI->vcache.minYi;
  374. if (to->x2 > lpDevI->vcache.maxXi)
  375. to->x2 = lpDevI->vcache.maxXi;
  376. if (to->y2 > lpDevI->vcache.maxYi)
  377. to->y2 = lpDevI->vcache.maxYi;
  378. }