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.

986 lines
35 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. #include "light.h"
  12. #include "clipper.h"
  13. #include "pvvid.h"
  14. include(`pvvid.mh') dnl
  15. #ifdef DEBUG_PIPELINE
  16. DWORD g_DebugFlags = 0;
  17. #endif // DEBUG_PIPELINE
  18. #if DBG
  19. #include "rtdmon.hpp"
  20. #endif
  21. //-----------------------------------------------------------------------------
  22. // Input:
  23. // v - input vertex in the model space
  24. // pCoord - vertex, transformed to the camera space
  25. // pWeights- vertex weights
  26. // Output:
  27. // Alpha component of pv->lighting.outSpecular is set
  28. //
  29. void ComputeFog(LPD3DFE_PROCESSVERTICES pv, D3DVECTOR &v, D3DVECTOR* pCoord,
  30. D3DVALUE* pWeights, BYTE* pMatrixIndices)
  31. {
  32. D3DVALUE dist;
  33. // Vertex is already transformed to the camera space
  34. if (pv->dwDeviceFlags & D3DDEV_RANGEBASEDFOG)
  35. dist = SQRTF(pCoord->x*pCoord->x +
  36. pCoord->y*pCoord->y +
  37. pCoord->z*pCoord->z);
  38. else
  39. dist = ABSF(pCoord->z);
  40. ComputeFogFactor(pv, dist, &pv->lighting.outSpecular);
  41. }
  42. //---------------------------------------------------------------------
  43. // Transform 1-dimensional texture
  44. //
  45. void TransformTexture1_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  46. DWORD dwCount,
  47. DWORD dwInpStride,
  48. DWORD dwOutStride)
  49. {
  50. for (; dwCount; dwCount--)
  51. {
  52. pOut[0] = pIn[0] * m->_11 + m->_21;
  53. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  54. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  55. }
  56. }
  57. //---------------------------------------------------------------------
  58. // Transform 1-dimensional texture. Output 2 texture coordinates
  59. //
  60. void TransformTexture1_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  61. DWORD dwCount,
  62. DWORD dwInpStride,
  63. DWORD dwOutStride)
  64. {
  65. for (; dwCount; dwCount--)
  66. {
  67. pOut[0] = pIn[0] * m->_11 + m->_21;
  68. pOut[1] = pIn[0] * m->_12 + m->_22;
  69. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  70. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  71. }
  72. }
  73. //---------------------------------------------------------------------
  74. // Transform 1-dimensional texture. Output 3 texture coordinates
  75. //
  76. void TransformTexture1_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  77. DWORD dwCount,
  78. DWORD dwInpStride,
  79. DWORD dwOutStride)
  80. {
  81. for (; dwCount; dwCount--)
  82. {
  83. pOut[0] = pIn[0] * m->_11 + m->_21;
  84. pOut[1] = pIn[0] * m->_12 + m->_22;
  85. pOut[2] = pIn[0] * m->_13 + m->_23;
  86. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  87. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  88. }
  89. }
  90. //---------------------------------------------------------------------
  91. // Transform 1-dimensional texture. Output 4 texture coordinates
  92. //
  93. void TransformTexture1_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  94. DWORD dwCount,
  95. DWORD dwInpStride,
  96. DWORD dwOutStride)
  97. {
  98. for (; dwCount; dwCount--)
  99. {
  100. pOut[0] = pIn[0] * m->_11 + m->_21;
  101. pOut[1] = pIn[0] * m->_12 + m->_22;
  102. pOut[2] = pIn[0] * m->_13 + m->_23;
  103. pOut[3] = pIn[0] * m->_14 + m->_24;
  104. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  105. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  106. }
  107. }
  108. //---------------------------------------------------------------------
  109. // Transform 2-dimensional texture
  110. //
  111. void TransformTexture2_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  112. DWORD dwCount,
  113. DWORD dwInpStride,
  114. DWORD dwOutStride)
  115. {
  116. for (; dwCount; dwCount--)
  117. {
  118. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  119. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  120. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  121. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  122. }
  123. }
  124. //---------------------------------------------------------------------
  125. // Transform 2-dimensional texture. Output 1 texture coordinate
  126. //
  127. void TransformTexture2_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  128. DWORD dwCount,
  129. DWORD dwInpStride,
  130. DWORD dwOutStride)
  131. {
  132. for (; dwCount; dwCount--)
  133. {
  134. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  135. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  136. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  137. }
  138. }
  139. //---------------------------------------------------------------------
  140. // Transform 2-dimensional texture. Output 3 texture coordinate
  141. //
  142. void TransformTexture2_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  143. DWORD dwCount,
  144. DWORD dwInpStride,
  145. DWORD dwOutStride)
  146. {
  147. for (; dwCount; dwCount--)
  148. {
  149. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  150. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  151. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  152. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  153. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  154. }
  155. }
  156. //---------------------------------------------------------------------
  157. // Transform 2-dimensional texture. Output 4 texture coordinate
  158. //
  159. void TransformTexture2_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  160. DWORD dwCount,
  161. DWORD dwInpStride,
  162. DWORD dwOutStride)
  163. {
  164. for (; dwCount; dwCount--)
  165. {
  166. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  167. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  168. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  169. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + m->_34;
  170. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  171. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  172. }
  173. }
  174. //---------------------------------------------------------------------
  175. // Transform 3-dimensional texture
  176. //
  177. void TransformTexture3_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  178. DWORD dwCount,
  179. DWORD dwInpStride,
  180. DWORD dwOutStride)
  181. {
  182. for (; dwCount; dwCount--)
  183. {
  184. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  185. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  186. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  187. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  188. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  189. }
  190. }
  191. //---------------------------------------------------------------------
  192. // Transform 3-dimensional texture. Output 1 texture coordinate
  193. //
  194. void TransformTexture3_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  195. DWORD dwCount,
  196. DWORD dwInpStride,
  197. DWORD dwOutStride)
  198. {
  199. for (; dwCount; dwCount--)
  200. {
  201. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  202. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  203. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  204. }
  205. }
  206. //---------------------------------------------------------------------
  207. // Transform 3-dimensional texture. Output 2 texture coordinates
  208. //
  209. void TransformTexture3_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  210. DWORD dwCount,
  211. DWORD dwInpStride,
  212. DWORD dwOutStride)
  213. {
  214. for (; dwCount; dwCount--)
  215. {
  216. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  217. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  218. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  219. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  220. }
  221. }
  222. //---------------------------------------------------------------------
  223. // Transform 3-dimensional texture. Output 4 texture coordinates
  224. //
  225. void TransformTexture3_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  226. DWORD dwCount,
  227. DWORD dwInpStride,
  228. DWORD dwOutStride)
  229. {
  230. for (; dwCount; dwCount--)
  231. {
  232. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  233. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  234. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  235. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + m->_44;
  236. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  237. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  238. }
  239. }
  240. //---------------------------------------------------------------------
  241. // Transform 4-dimensional texture
  242. //
  243. void TransformTexture4_4Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  244. DWORD dwCount,
  245. DWORD dwInpStride,
  246. DWORD dwOutStride)
  247. {
  248. for (; dwCount; dwCount--)
  249. {
  250. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  251. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  252. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  253. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + pIn[3] * m->_44;
  254. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  255. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  256. }
  257. }
  258. //---------------------------------------------------------------------
  259. // Transform 4-dimensional texture. Output 1 texture coordinate
  260. //
  261. void TransformTexture4_1Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  262. DWORD dwCount,
  263. DWORD dwInpStride,
  264. DWORD dwOutStride)
  265. {
  266. for (; dwCount; dwCount--)
  267. {
  268. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  269. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  270. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  271. }
  272. }
  273. //---------------------------------------------------------------------
  274. // Transform 4-dimensional texture. Output 2 texture coordinates
  275. //
  276. void TransformTexture4_2Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  277. DWORD dwCount,
  278. DWORD dwInpStride,
  279. DWORD dwOutStride)
  280. {
  281. for (; dwCount; dwCount--)
  282. {
  283. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  284. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  285. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  286. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  287. }
  288. }
  289. //---------------------------------------------------------------------
  290. // Transform 4-dimensional texture. Output 3 texture coordinates
  291. //
  292. void TransformTexture4_3Loop(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m,
  293. DWORD dwCount,
  294. DWORD dwInpStride,
  295. DWORD dwOutStride)
  296. {
  297. for (; dwCount; dwCount--)
  298. {
  299. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  300. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  301. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  302. pIn = (D3DVALUE*)((BYTE*)pIn + dwInpStride);
  303. pOut = (D3DVALUE*)((BYTE*)pOut + dwOutStride);
  304. }
  305. }
  306. //---------------------------------------------------------------------
  307. // Transform 1-dimensional texture.
  308. //
  309. void TransformTexture1_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  310. {
  311. pOut[0] = pIn[0] * m->_11 + m->_21;
  312. }
  313. //---------------------------------------------------------------------
  314. // Transform 1-dimensional texture. Output 2 texture coordinates
  315. //
  316. void TransformTexture1_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  317. {
  318. pOut[0] = pIn[0] * m->_11 + m->_21;
  319. pOut[1] = pIn[0] * m->_12 + m->_22;
  320. }
  321. //---------------------------------------------------------------------
  322. // Transform 1-dimensional texture. Output 3 texture coordinates
  323. //
  324. void TransformTexture1_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  325. {
  326. pOut[0] = pIn[0] * m->_11 + m->_21;
  327. pOut[1] = pIn[0] * m->_12 + m->_22;
  328. pOut[2] = pIn[0] * m->_13 + m->_23;
  329. }
  330. //---------------------------------------------------------------------
  331. // Transform 1-dimensional texture. Output 4 texture coordinates
  332. //
  333. void TransformTexture1_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  334. {
  335. pOut[0] = pIn[0] * m->_11 + m->_21;
  336. pOut[1] = pIn[0] * m->_12 + m->_22;
  337. pOut[2] = pIn[0] * m->_13 + m->_23;
  338. pOut[3] = pIn[0] * m->_14 + m->_24;
  339. }
  340. //---------------------------------------------------------------------
  341. // Transform 2-dimensional texture
  342. //
  343. void TransformTexture2_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  344. {
  345. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  346. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  347. }
  348. //---------------------------------------------------------------------
  349. // Transform 2-dimensional texture. Output 1 texture coordinate
  350. //
  351. void TransformTexture2_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  352. {
  353. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  354. }
  355. //---------------------------------------------------------------------
  356. // Transform 2-dimensional texture. Output 3 texture coordinates
  357. //
  358. void TransformTexture2_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  359. {
  360. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  361. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  362. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  363. }
  364. //---------------------------------------------------------------------
  365. // Transform 2-dimensional texture. Output 4 texture coordinates
  366. //
  367. void TransformTexture2_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  368. {
  369. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + m->_31;
  370. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + m->_32;
  371. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + m->_33;
  372. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + m->_34;
  373. }
  374. //---------------------------------------------------------------------
  375. // Transform 3-dimensional texture. Output 3 texture coordinates
  376. //
  377. void TransformTexture3_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  378. {
  379. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  380. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  381. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  382. }
  383. //---------------------------------------------------------------------
  384. // Transform 3-dimensional texture. Output 1 texture coordinates
  385. //
  386. void TransformTexture3_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  387. {
  388. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  389. }
  390. //---------------------------------------------------------------------
  391. // Transform 3-dimensional texture. Output 2 texture coordinates
  392. //
  393. void TransformTexture3_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  394. {
  395. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  396. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  397. }
  398. //---------------------------------------------------------------------
  399. // Transform 3-dimensional texture. Output 4 texture coordinates
  400. //
  401. void TransformTexture3_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  402. {
  403. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + m->_41;
  404. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + m->_42;
  405. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + m->_43;
  406. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + m->_44;
  407. }
  408. //---------------------------------------------------------------------
  409. // Transform 4-dimensional texture. Output 4 texture coordinates
  410. //
  411. void TransformTexture4_4(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  412. {
  413. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  414. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  415. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  416. pOut[3] = pIn[0] * m->_14 + pIn[1] * m->_24 + pIn[2] * m->_34 + pIn[3] * m->_44;
  417. }
  418. //---------------------------------------------------------------------
  419. // Transform 4-dimensional texture. Output 1 texture coordinates
  420. //
  421. void TransformTexture4_1(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  422. {
  423. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  424. }
  425. //---------------------------------------------------------------------
  426. // Transform 4-dimensional texture. Output 2 texture coordinates
  427. //
  428. void TransformTexture4_2(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  429. {
  430. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  431. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  432. }
  433. //---------------------------------------------------------------------
  434. // Transform 4-dimensional texture. Output 3 texture coordinates
  435. //
  436. void TransformTexture4_3(D3DVALUE *pIn, D3DVALUE *pOut, D3DMATRIXI *m)
  437. {
  438. pOut[0] = pIn[0] * m->_11 + pIn[1] * m->_21 + pIn[2] * m->_31 + pIn[3] * m->_41;
  439. pOut[1] = pIn[0] * m->_12 + pIn[1] * m->_22 + pIn[2] * m->_32 + pIn[3] * m->_42;
  440. pOut[2] = pIn[0] * m->_13 + pIn[1] * m->_23 + pIn[2] * m->_33 + pIn[3] * m->_43;
  441. }
  442. //---------------------------------------------------------------------
  443. // Index is:
  444. // bits 0-1 - (number of input texture coordinates - 1)
  445. // bits 2-3 - (number of output texture coordinates - 1)
  446. //
  447. PFN_TEXTURETRANSFORM g_pfnTextureTransform[16] =
  448. {
  449. TransformTexture1_1,
  450. TransformTexture2_1,
  451. TransformTexture3_1,
  452. TransformTexture4_1,
  453. TransformTexture1_2,
  454. TransformTexture2_2,
  455. TransformTexture3_2,
  456. TransformTexture4_2,
  457. TransformTexture1_3,
  458. TransformTexture2_3,
  459. TransformTexture3_3,
  460. TransformTexture4_3,
  461. TransformTexture1_4,
  462. TransformTexture2_4,
  463. TransformTexture3_4,
  464. TransformTexture4_4
  465. };
  466. //---------------------------------------------------------------------
  467. PFN_TEXTURETRANSFORMLOOP g_pfnTextureTransformLoop[16] =
  468. {
  469. TransformTexture1_1Loop,
  470. TransformTexture2_1Loop,
  471. TransformTexture3_1Loop,
  472. TransformTexture4_1Loop,
  473. TransformTexture1_2Loop,
  474. TransformTexture2_2Loop,
  475. TransformTexture3_2Loop,
  476. TransformTexture4_2Loop,
  477. TransformTexture1_3Loop,
  478. TransformTexture2_3Loop,
  479. TransformTexture3_3Loop,
  480. TransformTexture4_3Loop,
  481. TransformTexture1_4Loop,
  482. TransformTexture2_4Loop,
  483. TransformTexture3_4Loop,
  484. TransformTexture4_4Loop
  485. };
  486. //---------------------------------------------------------------------
  487. // This function should be called every time FVF ID is changed
  488. // All pv flags, input and output FVF id should be set before calling the
  489. // function.
  490. static DWORD POSITION_SIZE[16] =
  491. {
  492. 0, 0, 3*4, 0, 4*4, 0, 4*4, 0, 5*4, 0, 6*4, 0, 7*4, 0, 8*4, 0
  493. };
  494. //---------------------------------------------------------------------
  495. void SetupStrides(D3DFE_PROCESSVERTICES* pv, UINT stride)
  496. {
  497. pv->position.dwStride = stride;
  498. pv->weights.dwStride =
  499. pv->normal.dwStride =
  500. pv->diffuse.dwStride =
  501. pv->specular.dwStride =
  502. pv->psize.dwStride =
  503. pv->matrixIndices.dwStride = stride;
  504. pv->textures[0].dwStride = stride;
  505. pv->textures[1].dwStride = stride;
  506. pv->textures[2].dwStride = stride;
  507. pv->textures[3].dwStride = stride;
  508. pv->textures[4].dwStride = stride;
  509. pv->textures[5].dwStride = stride;
  510. pv->textures[6].dwStride = stride;
  511. pv->textures[7].dwStride = stride;
  512. }
  513. //---------------------------------------------------------------------
  514. // This function is called only when the input FVF is changed
  515. //
  516. void UpdateGeometryLoopData(LPD3DFE_PROCESSVERTICES pv)
  517. {
  518. // Compute input offsets
  519. if (!(pv->dwDeviceFlags & D3DDEV_STRIDE))
  520. {
  521. DWORD i = POSITION_SIZE[pv->dwVIDIn & D3DFVF_POSITION_MASK];
  522. pv->normalOffset = i;
  523. if (pv->dwVIDIn & D3DFVF_NORMAL)
  524. i += sizeof(D3DVECTOR);
  525. pv->pointSizeOffset = i;
  526. if (pv->dwVIDIn & D3DFVF_PSIZE)
  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. }
  537. //-----------------------------------------------------------------------------
  538. inline DWORD GetColorComponent(float color)
  539. {
  540. if (FLOAT_LTZ(color))
  541. return 0;
  542. else
  543. if (FLOAT_CMP_PONE(color, >))
  544. return 255;
  545. else
  546. return (DWORD)FTOI(color * 255.0f);
  547. }
  548. //-----------------------------------------------------------------------------
  549. inline DWORD ComputeColor(VVM_WORD* color)
  550. {
  551. DWORD r = GetColorComponent(color->x);
  552. DWORD g = GetColorComponent(color->y);
  553. DWORD b = GetColorComponent(color->z);
  554. DWORD a = GetColorComponent(color->w);
  555. return (a<<24) + (r<<16) + (g<<8) + b;
  556. }
  557. //-----------------------------------------------------------------------------
  558. // Executes vertex shader and computes clip codes.
  559. // Vertices are processed in batches
  560. //
  561. // The following fields from pv are used:
  562. // dwFlags
  563. // dwNumVertices
  564. // all pointer and strides
  565. // dwVIDIn
  566. // dwVIDOut
  567. // lpvOut
  568. // lpClipFlags
  569. // nTexCoord
  570. // Returns:
  571. // returns dwClipIntersection or 0 (if D3DDEV_DONOTCLIP is set)
  572. // Side effects:
  573. // dwClipUnion, dwClipIntersection are set only if D3DDEV_DONOTCLIP is not set
  574. //
  575. #undef DPF_MODNAME
  576. #define DPF_MODNAME "ProcessVerticesVVM"
  577. DWORD D3DFE_PVFUNCSI::ProcessVerticesVVM(LPD3DFE_PROCESSVERTICES pv)
  578. {
  579. D3DFE_CLIPCODE* hout = pv->lpClipFlags;
  580. D3DTLVERTEX* out = (D3DTLVERTEX*)pv->lpvOut;
  581. VVM_REGISTERS* pRegisters = m_VertexVM.GetRegisters();
  582. DWORD dwDeviceFlags = pv->dwDeviceFlags;
  583. DWORD dwClipIntersection = 0;
  584. DWORD dwClipUnion = 0;
  585. DWORD dwOutVerSize = pv->dwOutputSize;
  586. CVShaderCode* shader = m_VertexVM.GetActiveShader();
  587. DWORD dwOutRegs = shader->m_dwOutRegs;
  588. UINT dwNumVertices = pv->dwNumVertices;
  589. // When ProcessVertices is used, output FVF could have a field VVM does not
  590. // modify. In this case we prevent writing to the output field
  591. BOOL bWritePSize = dwOutRegs & CPSGPShader_PSIZE &&
  592. pv->dwVIDOut & D3DFVF_PSIZE;
  593. BOOL bWriteDiffuse = dwOutRegs & CPSGPShader_DIFFUSE &&
  594. pv->dwVIDOut & D3DFVF_DIFFUSE;
  595. BOOL bWriteSpecular = (dwOutRegs & CPSGPShader_SPECULAR ||
  596. (dwOutRegs & CPSGPShader_FOG && !(pv->dwVIDOut & D3DFVF_FOG))) &&
  597. pv->dwVIDOut & D3DFVF_SPECULAR;
  598. BOOL bWriteFog = pv->dwVIDOut & D3DFVF_FOG &&
  599. dwOutRegs & CPSGPShader_FOG;
  600. if (!(dwDeviceFlags & D3DDEV_DONOTCLIP))
  601. dwClipIntersection = ~0;
  602. UINT iVertex = 0; // Vertex index
  603. while (dwNumVertices)
  604. {
  605. UINT count = min(dwNumVertices, VVMVERTEXBATCH);
  606. #ifndef PSGPDLL
  607. #if DBG
  608. if (pv->pDbgMon && pv->pDbgMon->MonitorConnected())
  609. count = 1;
  610. #endif
  611. #endif // PSGPDLL
  612. dwNumVertices -= count;
  613. // Copy vertex elements to the input vertex registers
  614. CVertexDesc* pVD = pv->VertexDesc;
  615. for (DWORD k = pv->dwNumUsedVertexDescs; k; k--)
  616. {
  617. (*(PFN_D3DCOPYELEMENT)pVD->pfnCopy)
  618. ((BYTE*)pVD->pMemory +
  619. iVertex * pVD->dwStride, pVD->dwStride, count,
  620. pRegisters->m_v[pVD->dwRegister]);
  621. pVD++;
  622. }
  623. #ifndef PSGPDLL
  624. #if DBG
  625. if (pv->pDbgMon) pv->pDbgMon->NextEvent(D3DDM_EVENT_VERTEX);
  626. #endif
  627. #endif // PSGPDLL
  628. m_VertexVM.ExecuteShader(pv, count);
  629. // Get the result from the output VVM registers
  630. for (UINT i=0; i < count; i++)
  631. {
  632. float x, y, z, w;
  633. w = pRegisters->m_output[D3DSRO_POSITION][i].w;
  634. z = pRegisters->m_output[D3DSRO_POSITION][i].z;
  635. // Make clipping rules 0 < x < w; 0 < y < w
  636. x = (pRegisters->m_output[D3DSRO_POSITION][i].x + w) * 0.5f;
  637. y = (pRegisters->m_output[D3DSRO_POSITION][i].y + w) * 0.5f;
  638. if (!(dwDeviceFlags & D3DDEV_DONOTCLIP))
  639. {
  640. DWORD clip;
  641. // Compute clip code
  642. d_ComputeClipCode(4)
  643. if (clip == 0)
  644. {
  645. dwClipIntersection = 0;
  646. *hout++ = 0;
  647. w = D3DVAL(1)/w;
  648. }
  649. else
  650. {
  651. if (dwDeviceFlags & D3DDEV_GUARDBAND)
  652. {
  653. // We do guardband check in the projection space, so
  654. // we transform X and Y of the vertex there
  655. d_ComputeClipCodeGB(6)
  656. if ((clip & ~__D3DCS_INGUARDBAND) == 0)
  657. {
  658. // If vertex is inside the guardband we have to compute
  659. // screen coordinates
  660. w = D3DVAL(1)/w;
  661. *hout++ = (D3DFE_CLIPCODE)clip;
  662. dwClipIntersection &= clip;
  663. dwClipUnion |= clip;
  664. goto l_DoScreenCoord;
  665. }
  666. }
  667. dwClipIntersection &= clip;
  668. dwClipUnion |= clip;
  669. *hout++ = (D3DFE_CLIPCODE)clip;
  670. // If vertex is outside the frustum we can not compute screen
  671. // coordinates
  672. out->sx = x;
  673. out->sy = y;
  674. out->sz = z;
  675. out->rhw = w;
  676. goto l_DoLighting;
  677. }
  678. }
  679. else
  680. {
  681. // We have to check this only for DONOTCLIP case, because otherwise
  682. // the vertex with "we = 0" will be clipped and screen coordinates
  683. // will not be computed
  684. // "clip" is not zero, if "w" is zero.
  685. if (!FLOAT_EQZ(w))
  686. w = D3DVAL(1)/w;
  687. else
  688. w = __HUGE_PWR2;
  689. }
  690. l_DoScreenCoord:
  691. d_ComputeScreenCoordinates(3, x, y, z, w, out)
  692. l_DoLighting:
  693. if (bWritePSize)
  694. {
  695. float* p = (float*)((BYTE*)out + pv->pointSizeOffsetOut);
  696. *p = pRegisters->m_output[D3DSRO_POINT_SIZE][i].x;
  697. }
  698. if (bWriteDiffuse)
  699. {
  700. DWORD* p = (DWORD*)((BYTE*)out + pv->diffuseOffsetOut);
  701. *p = ComputeColor(&pRegisters->m_color[0][i]);
  702. }
  703. else
  704. if (!(pv->dwFlags & D3DPV_DONOTCOPYDIFFUSE))
  705. {
  706. *(DWORD*)((BYTE*)out + pv->diffuseOffsetOut) = __DEFAULT_DIFFUSE;
  707. }
  708. if (bWriteSpecular)
  709. {
  710. DWORD color = __DEFAULT_SPECULAR;
  711. DWORD* p = (DWORD*)((BYTE*)out + pv->specularOffsetOut);
  712. if (dwOutRegs & CPSGPShader_SPECULAR)
  713. {
  714. color = ComputeColor(&pRegisters->m_color[1][i]);
  715. }
  716. // We need to clear specular ALPHA, because it should be taken
  717. // from the FOG register even if the shader does not write to it
  718. color &= 0x00FFFFFF;
  719. if (dwOutRegs & CPSGPShader_FOG && !bWriteFog)
  720. {
  721. DWORD a = GetColorComponent(pRegisters->m_output[D3DSRO_FOG][i].x);
  722. ((BYTE*)&color)[3] = (BYTE)a;
  723. }
  724. *p = color;
  725. }
  726. else
  727. if (!(pv->dwFlags & D3DPV_DONOTCOPYSPECULAR))
  728. {
  729. *(DWORD*)((BYTE*)out + pv->specularOffsetOut) = __DEFAULT_SPECULAR;
  730. }
  731. if (bWriteFog)
  732. {
  733. float a = pRegisters->m_output[D3DSRO_FOG][i].x;
  734. if (FLOAT_LTZ(a))
  735. *(float*)((BYTE*)out + pv->fogOffsetOut) = 0.0f;
  736. else
  737. if (FLOAT_CMP_PONE(a, >))
  738. *(float*)((BYTE*)out + pv->fogOffsetOut) = 1.0f;
  739. else
  740. *(float*)((BYTE*)out + pv->fogOffsetOut) = a;
  741. }
  742. D3DVALUE *pOutTexture = (D3DVALUE*)((BYTE*)out + pv->texOffsetOut);
  743. for (DWORD k=0; k < pv->nOutTexCoord; k++)
  744. {
  745. DWORD dwSize = pv->dwTextureCoordSize[k];
  746. memcpy(pOutTexture, &pRegisters->m_texture[k][i], dwSize);
  747. NEXT(pOutTexture, dwSize, D3DVALUE);
  748. }
  749. NEXT(out, dwOutVerSize, D3DTLVERTEX);
  750. }
  751. iVertex += count;
  752. }
  753. pv->dwClipIntersection = dwClipIntersection;
  754. pv->dwClipUnion = dwClipUnion;
  755. return dwClipIntersection;
  756. }
  757. //-----------------------------------------------------------------------------
  758. extern DWORD ProcessVerticesLoop(D3DFE_PROCESSVERTICES *pv);
  759. //-----------------------------------------------------------------------------
  760. DWORD D3DFE_PVFUNCSI::ProcessVertices(LPD3DFE_PROCESSVERTICES pv)
  761. {
  762. CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
  763. if (pv->dwDeviceFlags & D3DDEV_VERTEXSHADERS)
  764. return ProcessVerticesVVM(pv);
  765. else
  766. return ProcessVerticesLoop(pv);
  767. }
  768. //-----------------------------------------------------------------------------
  769. HRESULT D3DFE_PVFUNCSI::ProcessPrimitive(LPD3DFE_PROCESSVERTICES pv)
  770. {
  771. CD3DFPstate D3DFPstate; // Sets optimal FPU state for D3D.
  772. #ifdef DEBUG_PIPELINE
  773. if (!(g_DebugFlags & __DEBUG_ONEPASS))
  774. #endif
  775. if (DoOnePassPrimProcessing(pv))
  776. { // We can do optimized processing of non-indexed primitives that
  777. // require clipping
  778. switch (pv->primType)
  779. {
  780. case D3DPT_TRIANGLELIST : return ProcessTriangleList(pv);
  781. case D3DPT_TRIANGLESTRIP: return ProcessTriangleStrip(pv);
  782. case D3DPT_TRIANGLEFAN : return ProcessTriangleFan(pv);
  783. case D3DPT_LINELIST : return ProcessLineList(pv);
  784. case D3DPT_LINESTRIP : return ProcessLineStrip(pv);
  785. }
  786. }
  787. pv->pGeometryFuncs->ProcessVertices(pv);
  788. if (pv->dwClipIntersection)
  789. {
  790. // all vertices were offscreen
  791. return D3D_OK;
  792. }
  793. return (DoDrawPrimitive(pv));
  794. }
  795. //-----------------------------------------------------------------------------
  796. HRESULT D3DFE_PVFUNCSI::ProcessIndexedPrimitive(LPD3DFE_PROCESSVERTICES pv)
  797. {
  798. pv->pGeometryFuncs->ProcessVertices(pv);
  799. if (pv->dwClipIntersection)
  800. {
  801. // all vertices were offscreen
  802. return D3D_OK;
  803. }
  804. HRESULT hr = DoDrawIndexedPrimitive(pv);
  805. return hr;
  806. }
  807. //-----------------------------------------------------------------------------
  808. D3DFE_PROCESSVERTICES::D3DFE_PROCESSVERTICES()
  809. {
  810. for (DWORD i=0; i < D3DDP_MAXTEXCOORD; i++)
  811. {
  812. // Set texture size array to default for pre-DX7 drivers
  813. this->dwTextureCoordSize[i] = 4*2;
  814. }
  815. for (i = 0; i < VER_IN_BATCH-1; i++)
  816. {
  817. clipVer[i].next = &clipVer[i+1];
  818. }
  819. clipVer[VER_IN_BATCH-1].next = clipVer;
  820. this->dwFlags = 0;
  821. this->dwDeviceFlags = 0;
  822. this->dwFlags2 = 0;
  823. this->dwMaxUserClipPlanes = 0;
  824. this->ClipperState.clipBuf = new BYTE[MAX_CLIP_VERTICES*__MAX_VERTEX_SIZE];
  825. // Set a defaul value for matrix indices in vertices
  826. this->MatrixIndices[0] = 0;
  827. this->MatrixIndices[1] = 1;
  828. this->MatrixIndices[2] = 2;
  829. this->MatrixIndices[3] = 3;
  830. #ifdef DEBUG_PIPELINE
  831. GetD3DRegValue(REG_DWORD, "DebugFlags", &g_DebugFlags, 4);
  832. DWORD dwDisableRendering = 0;
  833. GetD3DRegValue(REG_DWORD, "DisableRendering", &dwDisableRendering, 4);
  834. if (dwDisableRendering)
  835. g_DebugFlags |= __DEBUG_NORENDERING;
  836. #endif
  837. this->pDDI = NULL;
  838. for (i=0; i < __MAXWORLDMATRICES; i++)
  839. {
  840. CTMCount[i] = 0;
  841. WVCount[i] = 0;
  842. WVICount[i] = 0;
  843. }
  844. MatrixStateCount = 1; // To force setting matrices for the first time
  845. }
  846. //-----------------------------------------------------------------------------
  847. D3DFE_PROCESSVERTICES::~D3DFE_PROCESSVERTICES()
  848. {
  849. delete [] this->ClipperState.clipBuf;
  850. }
  851. //---------------------------------------------------------------------
  852. #undef DPF_MODNAME
  853. #define DPF_MODNAME "DoDrawPrimitive"
  854. HRESULT D3DFE_PVFUNCSI::DoDrawPrimitive(LPD3DFE_PROCESSVERTICES pv)
  855. {
  856. HRESULT ret;
  857. if (!CheckIfNeedClipping(pv))
  858. {
  859. try
  860. {
  861. pv->pDDI->DrawPrim(pv);
  862. return S_OK;
  863. }
  864. catch( HRESULT hr )
  865. {
  866. return hr;
  867. }
  868. }
  869. // Preserve primitive type for large begin-end primitives
  870. // Primitive type could be changed by the clipper
  871. D3DPRIMITIVETYPE oldPrimType = pv->primType;
  872. switch (pv->primType)
  873. {
  874. case D3DPT_POINTLIST:
  875. ret = ProcessClippedPoints(pv);
  876. break;
  877. case D3DPT_LINELIST:
  878. ret = ProcessClippedLine(pv);
  879. break;
  880. case D3DPT_LINESTRIP:
  881. ret = ProcessClippedLine(pv);
  882. break;
  883. case D3DPT_TRIANGLELIST:
  884. ret = ProcessClippedTriangleList(pv);
  885. break;
  886. case D3DPT_TRIANGLESTRIP:
  887. ret = ProcessClippedTriangleStrip(pv);
  888. break;
  889. case D3DPT_TRIANGLEFAN:
  890. ret = ProcessClippedTriangleFan(pv);
  891. break;
  892. default:
  893. D3D_ERR( "Unknown primitive type in DrawPrimitive" );
  894. ret = D3DERR_INVALIDCALL;
  895. break;
  896. }
  897. pv->primType = oldPrimType;
  898. return ret;
  899. }
  900. //---------------------------------------------------------------------
  901. #undef DPF_MODNAME
  902. #define DPF_MODNAME "DoDrawIndexedPrimitive"
  903. HRESULT D3DFE_PVFUNCSI::DoDrawIndexedPrimitive(LPD3DFE_PROCESSVERTICES pv)
  904. {
  905. HRESULT ret = S_OK;
  906. if (!CheckIfNeedClipping(pv))
  907. {
  908. try
  909. {
  910. pv->pDDI->DrawIndexPrim(pv);
  911. return S_OK;
  912. }
  913. catch( HRESULT hr )
  914. {
  915. return hr;
  916. }
  917. }
  918. // Preserve primitive type for large begin-end primitives
  919. // Primitive type could be changed by the clipper
  920. D3DPRIMITIVETYPE oldPrimType = pv->primType;
  921. switch (pv->primType)
  922. {
  923. case D3DPT_POINTLIST:
  924. ret = ProcessClippedIndexedPoints(pv);
  925. break;
  926. case D3DPT_LINELIST:
  927. ret = ProcessClippedIndexedLine(pv);
  928. break;
  929. case D3DPT_LINESTRIP:
  930. ret = ProcessClippedIndexedLine(pv);
  931. break;
  932. case D3DPT_TRIANGLELIST:
  933. ret = ProcessClippedIndexedTriangleList(pv);
  934. break;
  935. case D3DPT_TRIANGLEFAN:
  936. ret = ProcessClippedIndexedTriangleFan(pv);
  937. break;
  938. case D3DPT_TRIANGLESTRIP:
  939. ret = ProcessClippedIndexedTriangleStrip(pv);
  940. break;
  941. default:
  942. break;
  943. }
  944. pv->primType = oldPrimType;
  945. return ret;
  946. }