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.

790 lines
29 KiB

  1. /*============================ ==============================================;
  2. *
  3. * Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: pvvid.mcp
  6. * Content: The implementation of the geometry inner loop
  7. *
  8. ***************************************************************************/
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. #define DEBUG_PIPELINE
  12. #include "light.h"
  13. #include "clipper.h"
  14. #include "drawprim.hpp"
  15. #include "pvvid.h"
  16. include(`pvvid.mh') dnl
  17. #ifdef DEBUG_PIPELINE
  18. DWORD g_DebugFlags = 0;
  19. #endif // DEBUG_PIPELINE
  20. //--------------------------------------------------------------------------
  21. // Input:
  22. // v - input vertex in the model space
  23. // le - vertex, transformed to the camera space
  24. // Output:
  25. // Alpha component of pv->lighting.outSpecular is set
  26. //
  27. void ComputeFog(LPD3DFE_PROCESSVERTICES pv, D3DVECTOR &v, D3DLIGHTINGELEMENT *le)
  28. {
  29. D3DVALUE dist;
  30. if (pv->lighting.dwLightingFlags & __LIGHT_VERTEXTRANSFORMED)
  31. {
  32. // Vertex is already transformed to the camera space
  33. if (pv->dwDeviceFlags & D3DDEV_RANGEBASEDFOG)
  34. dist = SQRTF(le->dvPosition.x*le->dvPosition.x +
  35. le->dvPosition.y*le->dvPosition.y +
  36. le->dvPosition.z*le->dvPosition.z);
  37. else
  38. dist = le->dvPosition.z;
  39. }
  40. else
  41. if (pv->dwDeviceFlags & D3DDEV_RANGEBASEDFOG)
  42. {
  43. D3DVECTOR veye;
  44. d_TransformVertexToCameraSpace(2, (&v), (&veye));
  45. dist = SQRTF(veye.x*veye.x + veye.y*veye.y + veye.z*veye.z);
  46. }
  47. else
  48. {
  49. if (pv->dwNumVerBlends == 0)
  50. {
  51. dist = v.x*pv->mWV._13 + v.y*pv->mWV._23 + v.z*pv->mWV._33 + pv->mWV._43;
  52. }
  53. else
  54. {
  55. D3DVECTOR veye;
  56. d_TransformVertexToCameraSpace(2, (&v), (&veye));
  57. dist = veye.z;
  58. }
  59. }
  60. ComputeFogFactor(pv, dist, &pv->lighting.outSpecular);
  61. }
  62. //---------------------------------------------------------------------
  63. // Transform 1-dimensional texture
  64. //
  65. void TransformTexture1_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  66. DWORD dwCount,
  67. DWORD dwInpStride,
  68. DWORD dwOutStride)
  69. {
  70. for (; dwCount; dwCount--)
  71. {
  72. pOut[0] = pIn[0] * m->_11 + m->_21;
  73. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  74. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  75. }
  76. }
  77. //---------------------------------------------------------------------
  78. // Transform 1-dimensional texture. Output 2 texture coordinates
  79. //
  80. void TransformTexture1_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  81. DWORD dwCount,
  82. DWORD dwInpStride,
  83. DWORD dwOutStride)
  84. {
  85. for (; dwCount; dwCount--)
  86. {
  87. pOut[0] = pIn[0] * m->_11 + m->_21;
  88. pOut[1] = pIn[0] * m->_12 + m->_22;
  89. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  90. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  91. }
  92. }
  93. //---------------------------------------------------------------------
  94. // Transform 1-dimensional texture. Output 3 texture coordinates
  95. //
  96. void TransformTexture1_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  97. DWORD dwCount,
  98. DWORD dwInpStride,
  99. DWORD dwOutStride)
  100. {
  101. for (; dwCount; dwCount--)
  102. {
  103. pOut[0] = pIn[0] * m->_11 + m->_21;
  104. pOut[1] = pIn[0] * m->_12 + m->_22;
  105. pOut[2] = pIn[0] * m->_13 + m->_23;
  106. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  107. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  108. }
  109. }
  110. //---------------------------------------------------------------------
  111. // Transform 1-dimensional texture. Output 4 texture coordinates
  112. //
  113. void TransformTexture1_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  114. DWORD dwCount,
  115. DWORD dwInpStride,
  116. DWORD dwOutStride)
  117. {
  118. for (; dwCount; dwCount--)
  119. {
  120. pOut[0] = pIn[0] * m->_11 + m->_21;
  121. pOut[1] = pIn[0] * m->_12 + m->_22;
  122. pOut[2] = pIn[0] * m->_13 + m->_23;
  123. pOut[3] = pIn[0] * m->_14 + m->_24;
  124. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  125. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  126. }
  127. }
  128. //---------------------------------------------------------------------
  129. // Transform 2-dimensional texture
  130. //
  131. void TransformTexture2_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  132. DWORD dwCount,
  133. DWORD dwInpStride,
  134. DWORD dwOutStride)
  135. {
  136. for (; dwCount; dwCount--)
  137. {
  138. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  139. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  140. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  141. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  142. }
  143. }
  144. //---------------------------------------------------------------------
  145. // Transform 2-dimensional texture. Output 1 texture coordinate
  146. //
  147. void TransformTexture2_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  148. DWORD dwCount,
  149. DWORD dwInpStride,
  150. DWORD dwOutStride)
  151. {
  152. for (; dwCount; dwCount--)
  153. {
  154. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  155. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  156. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  157. }
  158. }
  159. //---------------------------------------------------------------------
  160. // Transform 2-dimensional texture. Output 3 texture coordinate
  161. //
  162. void TransformTexture2_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  163. DWORD dwCount,
  164. DWORD dwInpStride,
  165. DWORD dwOutStride)
  166. {
  167. for (; dwCount; dwCount--)
  168. {
  169. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  170. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  171. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  172. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  173. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  174. }
  175. }
  176. //---------------------------------------------------------------------
  177. // Transform 2-dimensional texture. Output 4 texture coordinate
  178. //
  179. void TransformTexture2_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  180. DWORD dwCount,
  181. DWORD dwInpStride,
  182. DWORD dwOutStride)
  183. {
  184. for (; dwCount; dwCount--)
  185. {
  186. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  187. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  188. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  189. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + m->_34;
  190. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  191. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  192. }
  193. }
  194. //---------------------------------------------------------------------
  195. // Transform 3-dimensional texture
  196. //
  197. void TransformTexture3_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  198. DWORD dwCount,
  199. DWORD dwInpStride,
  200. DWORD dwOutStride)
  201. {
  202. for (; dwCount; dwCount--)
  203. {
  204. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  205. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  206. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  207. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  208. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  209. }
  210. }
  211. //---------------------------------------------------------------------
  212. // Transform 3-dimensional texture. Output 1 texture coordinate
  213. //
  214. void TransformTexture3_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  215. DWORD dwCount,
  216. DWORD dwInpStride,
  217. DWORD dwOutStride)
  218. {
  219. for (; dwCount; dwCount--)
  220. {
  221. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  222. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  223. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  224. }
  225. }
  226. //---------------------------------------------------------------------
  227. // Transform 3-dimensional texture. Output 2 texture coordinates
  228. //
  229. void TransformTexture3_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  230. DWORD dwCount,
  231. DWORD dwInpStride,
  232. DWORD dwOutStride)
  233. {
  234. for (; dwCount; dwCount--)
  235. {
  236. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  237. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  238. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  239. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  240. }
  241. }
  242. //---------------------------------------------------------------------
  243. // Transform 3-dimensional texture. Output 4 texture coordinates
  244. //
  245. void TransformTexture3_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  246. DWORD dwCount,
  247. DWORD dwInpStride,
  248. DWORD dwOutStride)
  249. {
  250. for (; dwCount; dwCount--)
  251. {
  252. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  253. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  254. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  255. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + m->_44;
  256. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  257. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  258. }
  259. }
  260. //---------------------------------------------------------------------
  261. // Transform 4-dimensional texture
  262. //
  263. void TransformTexture4_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  264. DWORD dwCount,
  265. DWORD dwInpStride,
  266. DWORD dwOutStride)
  267. {
  268. for (; dwCount; dwCount--)
  269. {
  270. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  271. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  272. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  273. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + pIn[3] * m->_44;
  274. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  275. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  276. }
  277. }
  278. //---------------------------------------------------------------------
  279. // Transform 4-dimensional texture. Output 1 texture coordinate
  280. //
  281. void TransformTexture4_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  282. DWORD dwCount,
  283. DWORD dwInpStride,
  284. DWORD dwOutStride)
  285. {
  286. for (; dwCount; dwCount--)
  287. {
  288. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  289. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  290. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  291. }
  292. }
  293. //---------------------------------------------------------------------
  294. // Transform 4-dimensional texture. Output 2 texture coordinates
  295. //
  296. void TransformTexture4_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  297. DWORD dwCount,
  298. DWORD dwInpStride,
  299. DWORD dwOutStride)
  300. {
  301. for (; dwCount; dwCount--)
  302. {
  303. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  304. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  305. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  306. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  307. }
  308. }
  309. //---------------------------------------------------------------------
  310. // Transform 4-dimensional texture. Output 3 texture coordinates
  311. //
  312. void TransformTexture4_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  313. DWORD dwCount,
  314. DWORD dwInpStride,
  315. DWORD dwOutStride)
  316. {
  317. for (; dwCount; dwCount--)
  318. {
  319. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  320. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  321. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  322. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  323. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  324. }
  325. }
  326. //---------------------------------------------------------------------
  327. // Transform 1-dimensional texture.
  328. //
  329. void TransformTexture1_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  330. {
  331. pOut[0] = pIn[0] * m->_11 + m->_21;
  332. }
  333. //---------------------------------------------------------------------
  334. // Transform 1-dimensional texture. Output 2 texture coordinates
  335. //
  336. void TransformTexture1_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  337. {
  338. pOut[0] = pIn[0] * m->_11 + m->_21;
  339. pOut[1] = pIn[0] * m->_12 + m->_22;
  340. }
  341. //---------------------------------------------------------------------
  342. // Transform 1-dimensional texture. Output 3 texture coordinates
  343. //
  344. void TransformTexture1_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  345. {
  346. pOut[0] = pIn[0] * m->_11 + m->_21;
  347. pOut[1] = pIn[0] * m->_12 + m->_22;
  348. pOut[2] = pIn[0] * m->_13 + m->_23;
  349. }
  350. //---------------------------------------------------------------------
  351. // Transform 1-dimensional texture. Output 4 texture coordinates
  352. //
  353. void TransformTexture1_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  354. {
  355. pOut[0] = pIn[0] * m->_11 + m->_21;
  356. pOut[1] = pIn[0] * m->_12 + m->_22;
  357. pOut[2] = pIn[0] * m->_13 + m->_23;
  358. pOut[3] = pIn[0] * m->_14 + m->_24;
  359. }
  360. //---------------------------------------------------------------------
  361. // Transform 2-dimensional texture
  362. //
  363. void TransformTexture2_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  364. {
  365. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  366. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  367. }
  368. //---------------------------------------------------------------------
  369. // Transform 2-dimensional texture. Output 1 texture coordinate
  370. //
  371. void TransformTexture2_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  372. {
  373. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  374. }
  375. //---------------------------------------------------------------------
  376. // Transform 2-dimensional texture. Output 3 texture coordinates
  377. //
  378. void TransformTexture2_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  379. {
  380. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  381. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  382. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  383. }
  384. //---------------------------------------------------------------------
  385. // Transform 2-dimensional texture. Output 4 texture coordinates
  386. //
  387. void TransformTexture2_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  388. {
  389. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  390. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  391. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  392. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + m->_34;
  393. }
  394. //---------------------------------------------------------------------
  395. // Transform 3-dimensional texture. Output 3 texture coordinates
  396. //
  397. void TransformTexture3_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  398. {
  399. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  400. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  401. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  402. }
  403. //---------------------------------------------------------------------
  404. // Transform 3-dimensional texture. Output 1 texture coordinates
  405. //
  406. void TransformTexture3_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  407. {
  408. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  409. }
  410. //---------------------------------------------------------------------
  411. // Transform 3-dimensional texture. Output 2 texture coordinates
  412. //
  413. void TransformTexture3_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  414. {
  415. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  416. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  417. }
  418. //---------------------------------------------------------------------
  419. // Transform 3-dimensional texture. Output 4 texture coordinates
  420. //
  421. void TransformTexture3_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  422. {
  423. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  424. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  425. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  426. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + m->_44;
  427. }
  428. //---------------------------------------------------------------------
  429. // Transform 4-dimensional texture. Output 4 texture coordinates
  430. //
  431. void TransformTexture4_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  432. {
  433. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  434. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  435. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  436. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + pIn[3] * m->_44;
  437. }
  438. //---------------------------------------------------------------------
  439. // Transform 4-dimensional texture. Output 1 texture coordinates
  440. //
  441. void TransformTexture4_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  442. {
  443. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  444. }
  445. //---------------------------------------------------------------------
  446. // Transform 4-dimensional texture. Output 2 texture coordinates
  447. //
  448. void TransformTexture4_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  449. {
  450. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  451. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  452. }
  453. //---------------------------------------------------------------------
  454. // Transform 4-dimensional texture. Output 3 texture coordinates
  455. //
  456. void TransformTexture4_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  457. {
  458. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  459. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  460. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  461. }
  462. //---------------------------------------------------------------------
  463. // Index is:
  464. // bits 0-1 - (number of input texture coordinates - 1)
  465. // bits 2-3 - (number of output texture coordinates - 1)
  466. //
  467. PFN_TEXTURETRANSFORM g_pfnTextureTransform[16] =
  468. {
  469. TransformTexture1_1,
  470. TransformTexture2_1,
  471. TransformTexture3_1,
  472. TransformTexture4_1,
  473. TransformTexture1_2,
  474. TransformTexture2_2,
  475. TransformTexture3_2,
  476. TransformTexture4_2,
  477. TransformTexture1_3,
  478. TransformTexture2_3,
  479. TransformTexture3_3,
  480. TransformTexture4_3,
  481. TransformTexture1_4,
  482. TransformTexture2_4,
  483. TransformTexture3_4,
  484. TransformTexture4_4
  485. };
  486. //---------------------------------------------------------------------
  487. PFN_TEXTURETRANSFORMLOOP g_pfnTextureTransformLoop[16] =
  488. {
  489. TransformTexture1_1Loop,
  490. TransformTexture2_1Loop,
  491. TransformTexture3_1Loop,
  492. TransformTexture4_1Loop,
  493. TransformTexture1_2Loop,
  494. TransformTexture2_2Loop,
  495. TransformTexture3_2Loop,
  496. TransformTexture4_2Loop,
  497. TransformTexture1_3Loop,
  498. TransformTexture2_3Loop,
  499. TransformTexture3_3Loop,
  500. TransformTexture4_3Loop,
  501. TransformTexture1_4Loop,
  502. TransformTexture2_4Loop,
  503. TransformTexture3_4Loop,
  504. TransformTexture4_4Loop
  505. };
  506. //---------------------------------------------------------------------
  507. // This function should be called every time FVF ID is changed
  508. // All pv flags, input and output FVF id should be set before calling the
  509. // function.
  510. static DWORD POSITION_SIZE[16] =
  511. {
  512. 0, 0, 3*4, 0, 4*4, 0, 4*4, 0, 5*4, 0, 6*4, 0, 7*4, 0, 8*4, 0
  513. };
  514. //---------------------------------------------------------------------
  515. // This function is called only when the input FVF is changed
  516. //
  517. void UpdateGeometryLoopData(LPD3DFE_PROCESSVERTICES pv)
  518. {
  519. // Compute input offsets
  520. if (!(pv->dwDeviceFlags & D3DDEV_STRIDE))
  521. {
  522. DWORD i = POSITION_SIZE[pv->dwVIDIn & D3DFVF_POSITION_MASK];
  523. pv->normalOffset = i;
  524. if (pv->dwVIDIn & D3DFVF_NORMAL)
  525. i += sizeof(D3DVECTOR);
  526. if (pv->dwVIDIn & D3DFVF_RESERVED1)
  527. i += sizeof(D3DVALUE);
  528. pv->diffuseOffset = i;
  529. if (pv->dwVIDIn & D3DFVF_DIFFUSE)
  530. i += sizeof(DWORD);
  531. pv->specularOffset = i;
  532. if (pv->dwVIDIn & D3DFVF_SPECULAR)
  533. i += sizeof(DWORD);
  534. pv->texOffset = i;
  535. }
  536. ComputeOutputVertexOffsets(pv);
  537. // For pre-DX6 drivers we have to copy only one texture coordinate index
  538. // to the output
  539. pv->dwDeviceFlags &= ~D3DDEV_NOFVFANDNOTEXTURE;
  540. if (!(pv->dwDeviceFlags & D3DDEV_FVF || pv->dwFlags & D3DPV_VBCALL))
  541. {
  542. if (pv->nTexCoord)
  543. {
  544. for (DWORD k=0; k < pv->dwTextureIndexToCopy; k++)
  545. pv->texOffset += pv->dwInpTextureCoordSize[k];
  546. }
  547. else
  548. {
  549. // For non-FVF drivers we have to fill texture coordinates with
  550. // zeros.
  551. pv->dwDeviceFlags |= D3DDEV_NOFVFANDNOTEXTURE;
  552. }
  553. }
  554. }
  555. //--------------------------------------------------------------------------
  556. // Transforms, lights vertices. Computes clip codes
  557. //
  558. // The following fields from pv are used:
  559. // dwFlags
  560. // dwNumVertices
  561. // all pointer and strides
  562. // position.lpvStrides
  563. // dwVIDIn
  564. // dwVIDOut
  565. // lpvOut
  566. // lpClipFlags
  567. // nTexCoord
  568. // Returns:
  569. // returns dwClipIntersection or 0 (if D3DDEV_DONOTCLIP is set)
  570. // Side effects:
  571. // dwClipUnion, dwClipIntersection are set only if D3DDEV_DONOTCLIP is not set
  572. // rExtents is updated if D3DDEV_DONOTUPDATEEXTENTS is not set
  573. //
  574. #undef DPF_MODNAME
  575. #define DPF_MODNAME "ProcessVerticesGen"
  576. DWORD ProcessVerticesGen(LPD3DFE_PROCESSVERTICES pv)
  577. {
  578. D3DFE_CLIPCODE *hout = pv->lpClipFlags;
  579. D3DTLVERTEX *out = (D3DTLVERTEX*)pv->lpvOut;
  580. D3DMATRIXI *m = &pv->mCTM;
  581. d_Setup()
  582. for (DWORD i = pv->dwNumVertices; i; i--)
  583. {
  584. D3DLIGHTINGELEMENT EyeSpaceData;
  585. float x, y, z, w;
  586. // Transform vertex to the clipping space
  587. d_TransformVertex(2, in, m, x, y, z, w)
  588. if (!(dwDeviceFlags & D3DDEV_DONOTCLIP))
  589. {
  590. DWORD clip;
  591. // Compute clip code
  592. d_ComputeClipCode(3)
  593. if (clip == 0)
  594. {
  595. dwClipIntersection = 0;
  596. *hout++ = 0;
  597. w = D3DVAL(1)/w;
  598. }
  599. else
  600. {
  601. if (dwDeviceFlags & D3DDEV_GUARDBAND)
  602. {
  603. // We do guardband check in the projection space, so
  604. // we transform X and Y of the vertex there
  605. d_ComputeClipCodeGB(5)
  606. if ((clip & ~__D3DCLIP_INGUARDBAND) == 0)
  607. {
  608. // If vertex is inside the guardband we have to compute
  609. // screen coordinates
  610. w = D3DVAL(1)/w;
  611. *hout++ = (D3DFE_CLIPCODE)clip;
  612. dwClipIntersection &= clip;
  613. dwClipUnion |= clip;
  614. goto l_DoScreenCoord;
  615. }
  616. }
  617. if (pv->dwFlags & D3DPV_ONEPASSCLIPPING)
  618. {
  619. pv->dwFirstClippedVertex = pv->dwNumVertices - i;
  620. return 0;
  621. }
  622. dwClipIntersection &= clip;
  623. dwClipUnion |= clip;
  624. *hout++ = (D3DFE_CLIPCODE)clip;
  625. // If vertex is outside the frustum we can not compute screen
  626. // coordinates
  627. out->sx = x;
  628. out->sy = y;
  629. out->sz = z;
  630. out->rhw = w;
  631. goto l_DoLighting;
  632. }
  633. }
  634. else
  635. {
  636. // We have to check this only for DONOTCLIP case, because otherwise
  637. // the vertex with "we = 0" will be clipped and screen coordinates
  638. // will not be computed
  639. // "clip" is not zero, if "w" is zero.
  640. if (!FLOAT_EQZ(w))
  641. w = D3DVAL(1)/w;
  642. else
  643. w = __HUGE_PWR2;
  644. }
  645. l_DoScreenCoord:
  646. d_ComputeScreenCoordinates(2, x, y, z, w, out)
  647. l_DoLighting:
  648. d_DoLightingAndFog(2, in, inNormal, inDiffuse, inSpecular, out);
  649. D3DVALUE *pOutTexture = (D3DVALUE*)((BYTE*)out + pv->texOffsetOut);
  650. d_CopyTextureCoordUpdateInputPointers(2, pOutTexture);
  651. NEXT(out, dwOutVerSize, D3DTLVERTEX);
  652. }
  653. d_UpdateExtents()
  654. pv->dwClipIntersection = dwClipIntersection;
  655. pv->dwClipUnion = dwClipUnion;
  656. return dwClipIntersection;
  657. }
  658. //---------------------------------------------------------------------
  659. extern DWORD ProcessVerticesLoop(D3DFE_PROCESSVERTICES *pv);
  660. //---------------------------------------------------------------------
  661. DWORD D3DFE_PVFUNCS::ProcessVertices(LPD3DFE_PROCESSVERTICES pv)
  662. {
  663. CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
  664. #ifdef DEBUG_PIPELINE
  665. if (g_DebugFlags & __DEBUG_MULTILOOP)
  666. return ProcessVerticesGen(pv);
  667. #endif
  668. if (pv->dwFlags & D3DPV_LIGHTING || pv->dwDeviceFlags & D3DDEV_TEXTURETRANSFORM)
  669. return ProcessVerticesLoop(pv);
  670. else
  671. return ProcessVerticesGen(pv);
  672. }
  673. //---------------------------------------------------------------------
  674. HRESULT D3DFE_PVFUNCS::ProcessPrimitive(LPD3DFE_PROCESSVERTICES pv)
  675. {
  676. CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
  677. #ifdef DEBUG_PIPELINE
  678. if (!(g_DebugFlags & __DEBUG_ONEPASS))
  679. #endif
  680. if (!(pv->dwDeviceFlags & D3DDEV_DONOTCLIP))
  681. { // We can do optimized processing of non-indexed primitives that
  682. // require clipping
  683. switch (pv->primType)
  684. {
  685. case D3DPT_TRIANGLELIST : return ProcessTriangleList(pv);
  686. case D3DPT_TRIANGLESTRIP: return ProcessTriangleStrip(pv);
  687. case D3DPT_TRIANGLEFAN : return ProcessTriangleFan(pv);
  688. case D3DPT_LINELIST : return ProcessLineList(pv);
  689. case D3DPT_LINESTRIP : return ProcessLineStrip(pv);
  690. }
  691. }
  692. this->ProcessVertices(pv);
  693. if (pv->dwClipIntersection)
  694. {
  695. // all vertices were offscreen
  696. return D3D_OK;
  697. }
  698. // This should not be required as we should be able to change
  699. // the parameter of DoDrawPrimtive and all it's children to pv
  700. return (DoDrawPrimitive(pv));
  701. }
  702. //---------------------------------------------------------------------
  703. HRESULT D3DFE_PVFUNCS::ProcessIndexedPrimitive(LPD3DFE_PROCESSVERTICES pv)
  704. {
  705. this->ProcessVertices(pv);
  706. if (pv->dwClipIntersection)
  707. {
  708. // all vertices were offscreen
  709. return D3D_OK;
  710. }
  711. return (DoDrawIndexedPrimitive(pv));
  712. }
  713. //---------------------------------------------------------------------
  714. D3DFE_PROCESSVERTICES::D3DFE_PROCESSVERTICES()
  715. {
  716. for (DWORD i=0; i < D3DDP_MAXTEXCOORD; i++)
  717. {
  718. // Set texture size array to default for pre-DX7 drivers
  719. this->dwTextureCoordSize[i] = 4*2;
  720. }
  721. for (i = 0; i < VER_IN_BATCH-1; i++)
  722. {
  723. clipVer[i].next = &clipVer[i+1];
  724. }
  725. clipVer[VER_IN_BATCH-1].next = clipVer;
  726. this->dwFlags = 0;
  727. this->dwDeviceFlags = 0;
  728. this->dwFlags2 = 0;
  729. this->dwMaxUserClipPlanes = 0;
  730. #ifdef DEBUG_PIPELINE
  731. GetD3DRegValue(REG_DWORD, "DebugFlags", &g_DebugFlags, 4);
  732. #endif
  733. }
  734. //---------------------------------------------------------------------
  735. void DIRECT3DDEVICEI::CheckClipStatus(D3DVALUE * pPositions,
  736. DWORD dwStride,
  737. DWORD dwNumVertices,
  738. DWORD *pdwClipUnion,
  739. DWORD *pdwClipIntersection)
  740. {
  741. #define pv this
  742. D3DVECTOR *p = (D3DVECTOR*)pPositions;
  743. D3DMATRIXI *m = &this->mCTM;
  744. DWORD dwClipUnion = 0;
  745. DWORD dwClipIntersection = ~0;
  746. for (DWORD i = dwNumVertices; i; i--)
  747. {
  748. D3DVALUE x, y, z, w;
  749. DWORD clip;
  750. // Transform vertex to the clipping space
  751. x = p->x*m->_11 + p->y*m->_21 + p->z*m->_31 + m->_41;
  752. y = p->x*m->_12 + p->y*m->_22 + p->z*m->_32 + m->_42;
  753. z = p->x*m->_13 + p->y*m->_23 + p->z*m->_33 + m->_43;
  754. w = p->x*m->_14 + p->y*m->_24 + p->z*m->_34 + m->_44;
  755. d_ComputeClipCode(2)
  756. p = (D3DVECTOR*)((BYTE*)p + dwStride);
  757. dwClipUnion |= clip;
  758. dwClipIntersection &= clip;
  759. }
  760. *pdwClipIntersection = dwClipIntersection;
  761. *pdwClipUnion = dwClipUnion;
  762. #undef pv
  763. }