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.

430 lines
12 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // drawprim.cpp
  4. //
  5. // Implements DrawOnePrimitive, DrawOneIndexedPrimitive and
  6. // DrawPrimitives.
  7. //
  8. // Copyright (C) Microsoft Corporation, 1997.
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "pch.cpp"
  12. #pragma hdrstop
  13. HRESULT
  14. RefDev::DrawOnePrimitive( GArrayT<RDVertex>& VtxArray,
  15. DWORD dwStartVertex,
  16. D3DPRIMITIVETYPE PrimType,
  17. UINT cVertices )
  18. {
  19. INT i;
  20. RDVertex* pV0;
  21. RDVertex* pV1;
  22. RDVertex* pV2;
  23. HRESULT hr;
  24. DWORD dwCurrVtx = dwStartVertex;
  25. switch( PrimType )
  26. {
  27. case D3DPT_POINTLIST:
  28. for (i = (INT)cVertices; i > 0; i--)
  29. {
  30. DrawPoint(&VtxArray[dwCurrVtx++]);
  31. }
  32. break;
  33. case D3DPT_LINELIST:
  34. for (i = (INT)cVertices / 2; i > 0; i--)
  35. {
  36. pV0 = &VtxArray[dwCurrVtx++];
  37. pV1 = &VtxArray[dwCurrVtx++];
  38. DrawLine(pV0, pV1);
  39. }
  40. break;
  41. case D3DPT_LINESTRIP:
  42. {
  43. pV1 = &VtxArray[dwCurrVtx];
  44. // Disable last-pixel setting for shared verties and store prestate.
  45. StoreLastPixelState(TRUE);
  46. // Initial pV0.
  47. for (i = (INT)cVertices - 1; i > 1; i--)
  48. {
  49. pV0 = pV1;
  50. dwCurrVtx++;
  51. pV1 = &VtxArray[dwCurrVtx];
  52. DrawLine(pV0, pV1);
  53. }
  54. // Restore last-pixel setting.
  55. StoreLastPixelState(FALSE);
  56. // Draw last line with last-pixel setting from state.
  57. if (i == 1)
  58. {
  59. pV0 = &VtxArray[++dwCurrVtx];
  60. DrawLine(pV1, pV0);
  61. }
  62. }
  63. break;
  64. case D3DPT_TRIANGLELIST:
  65. for (i = (INT)cVertices; i > 0; i -= 3)
  66. {
  67. pV0 = &VtxArray[dwCurrVtx++];
  68. pV1 = &VtxArray[dwCurrVtx++];
  69. pV2 = &VtxArray[dwCurrVtx++];
  70. DrawTriangle(pV0, pV1, pV2);
  71. }
  72. break;
  73. case D3DPT_TRIANGLESTRIP:
  74. {
  75. // Get initial vertex values.
  76. pV1 = &VtxArray[dwCurrVtx++];
  77. pV2 = &VtxArray[dwCurrVtx++];
  78. for (i = (INT)cVertices - 2; i > 1; i -= 2)
  79. {
  80. pV0 = pV1;
  81. pV1 = pV2;
  82. pV2 = &VtxArray[dwCurrVtx++];
  83. DrawTriangle(pV0, pV1, pV2);
  84. pV0 = pV1;
  85. pV1 = pV2;
  86. pV2 = &VtxArray[dwCurrVtx++];
  87. DrawTriangle(pV0, pV2, pV1);
  88. }
  89. if (i > 0)
  90. {
  91. pV0 = pV1;
  92. pV1 = pV2;
  93. pV2 = &VtxArray[dwCurrVtx];
  94. DrawTriangle(pV0, pV1, pV2);
  95. }
  96. }
  97. break;
  98. case D3DPT_TRIANGLEFAN:
  99. {
  100. pV2 = &VtxArray[dwCurrVtx++];
  101. // Preload initial pV0.
  102. pV1 = &VtxArray[dwCurrVtx++];
  103. for (i = (INT)cVertices - 2; i > 0; i--)
  104. {
  105. pV0 = pV1;
  106. pV1 = &VtxArray[dwCurrVtx++];
  107. DrawTriangle(pV0, pV1, pV2);
  108. }
  109. }
  110. break;
  111. default:
  112. DPFERR( "Refrast Error: Unknown or unsupported primitive type "
  113. "requested of DrawOnePrimitive" );
  114. return DDERR_INVALIDPARAMS;
  115. }
  116. return D3D_OK;
  117. }
  118. HRESULT
  119. RefDev::DrawOneIndexedPrimitive( GArrayT<RDVertex>& VtxArray,
  120. int StartVertexIndex,
  121. LPWORD puIndices,
  122. DWORD StartIndex,
  123. UINT cIndices,
  124. D3DPRIMITIVETYPE PrimType )
  125. {
  126. INT i;
  127. RDVertex* pV0;
  128. RDVertex* pV1;
  129. RDVertex* pV2;
  130. HRESULT hr;
  131. LPWORD pIndices = puIndices + StartIndex;
  132. switch( PrimType )
  133. {
  134. case D3DPT_POINTLIST:
  135. for (i = (INT)cIndices; i > 0; i--)
  136. {
  137. pV0 = &VtxArray[StartVertexIndex + (*pIndices++)];
  138. DrawPoint(pV0);
  139. }
  140. break;
  141. case D3DPT_LINELIST:
  142. for (i = (INT)cIndices / 2; i > 0; i--)
  143. {
  144. pV0 = &VtxArray[StartVertexIndex + (*pIndices++)];
  145. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  146. DrawLine(pV0, pV1);
  147. }
  148. break;
  149. case D3DPT_LINESTRIP:
  150. {
  151. // Disable last-pixel setting for shared verties and store prestate.
  152. StoreLastPixelState(TRUE);
  153. // Initial pV1.
  154. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  155. for (i = (INT)cIndices - 1; i > 1; i--)
  156. {
  157. pV0 = pV1;
  158. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  159. DrawLine(pV0, pV1);
  160. }
  161. // Restore last-pixel setting.
  162. StoreLastPixelState(FALSE);
  163. // Draw last line with last-pixel setting from state.
  164. if (i == 1)
  165. {
  166. pV0 = &VtxArray[StartVertexIndex + (*pIndices)];
  167. DrawLine(pV1, pV0);
  168. }
  169. }
  170. break;
  171. case D3DPT_TRIANGLELIST:
  172. for (i = (INT)cIndices; i > 0; i -= 3)
  173. {
  174. pV0 = &VtxArray[StartVertexIndex + (*pIndices++)];
  175. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  176. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  177. DrawTriangle(pV0, pV1, pV2);
  178. }
  179. break;
  180. case D3DPT_TRIANGLESTRIP:
  181. {
  182. // Get initial vertex values.
  183. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  184. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  185. for (i = (INT)cIndices - 2; i > 1; i -= 2)
  186. {
  187. pV0 = pV1;
  188. pV1 = pV2;
  189. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  190. DrawTriangle(pV0, pV1, pV2);
  191. pV0 = pV1;
  192. pV1 = pV2;
  193. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  194. DrawTriangle(pV0, pV2, pV1);
  195. }
  196. if (i > 0)
  197. {
  198. pV0 = pV1;
  199. pV1 = pV2;
  200. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  201. DrawTriangle(pV0, pV1, pV2);
  202. }
  203. }
  204. break;
  205. case D3DPT_TRIANGLEFAN:
  206. {
  207. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  208. // Preload initial pV0.
  209. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  210. for (i = (INT)cIndices - 2; i > 0; i--)
  211. {
  212. pV0 = pV1;
  213. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  214. DrawTriangle(pV0, pV1, pV2);
  215. }
  216. }
  217. break;
  218. default:
  219. DPFERR( "Refrast Error: Unknown or unsupported primitive type "
  220. "requested of DrawOneIndexedPrimitive" );
  221. return DDERR_INVALIDPARAMS;
  222. }
  223. return D3D_OK;
  224. }
  225. // DWORD index version
  226. HRESULT
  227. RefDev::DrawOneIndexedPrimitive( GArrayT<RDVertex>& VtxArray,
  228. int StartVertexIndex,
  229. LPDWORD puIndices,
  230. DWORD StartIndex,
  231. UINT cIndices,
  232. D3DPRIMITIVETYPE PrimType )
  233. {
  234. INT i;
  235. RDVertex* pV0;
  236. RDVertex* pV1;
  237. RDVertex* pV2;
  238. HRESULT hr;
  239. LPDWORD pIndices = puIndices + StartIndex;
  240. switch( PrimType )
  241. {
  242. case D3DPT_POINTLIST:
  243. for (i = (INT)cIndices; i > 0; i--)
  244. {
  245. pV0 = &VtxArray[StartVertexIndex + (*pIndices++)];
  246. DrawPoint(pV0);
  247. }
  248. break;
  249. case D3DPT_LINELIST:
  250. for (i = (INT)cIndices / 2; i > 0; i--)
  251. {
  252. pV0 = &VtxArray[StartVertexIndex + (*pIndices++)];
  253. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  254. DrawLine(pV0, pV1);
  255. }
  256. break;
  257. case D3DPT_LINESTRIP:
  258. {
  259. // Disable last-pixel setting for shared verties and store prestate.
  260. StoreLastPixelState(TRUE);
  261. // Initial pV1.
  262. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  263. for (i = (INT)cIndices - 1; i > 1; i--)
  264. {
  265. pV0 = pV1;
  266. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  267. DrawLine(pV0, pV1);
  268. }
  269. // Restore last-pixel setting.
  270. StoreLastPixelState(FALSE);
  271. // Draw last line with last-pixel setting from state.
  272. if (i == 1)
  273. {
  274. pV0 = &VtxArray[StartVertexIndex + (*pIndices)];
  275. DrawLine(pV1, pV0);
  276. }
  277. }
  278. break;
  279. case D3DPT_TRIANGLELIST:
  280. for (i = (INT)cIndices; i > 0; i -= 3)
  281. {
  282. pV0 = &VtxArray[StartVertexIndex + (*pIndices++)];
  283. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  284. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  285. DrawTriangle(pV0, pV1, pV2);
  286. }
  287. break;
  288. case D3DPT_TRIANGLESTRIP:
  289. {
  290. // Get initial vertex values.
  291. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  292. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  293. for (i = (INT)cIndices - 2; i > 1; i -= 2)
  294. {
  295. pV0 = pV1;
  296. pV1 = pV2;
  297. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  298. DrawTriangle(pV0, pV1, pV2);
  299. pV0 = pV1;
  300. pV1 = pV2;
  301. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  302. DrawTriangle(pV0, pV2, pV1);
  303. }
  304. if (i > 0)
  305. {
  306. pV0 = pV1;
  307. pV1 = pV2;
  308. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  309. DrawTriangle(pV0, pV1, pV2);
  310. }
  311. }
  312. break;
  313. case D3DPT_TRIANGLEFAN:
  314. {
  315. pV2 = &VtxArray[StartVertexIndex + (*pIndices++)];
  316. // Preload initial pV0.
  317. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  318. for (i = (INT)cIndices - 2; i > 0; i--)
  319. {
  320. pV0 = pV1;
  321. pV1 = &VtxArray[StartVertexIndex + (*pIndices++)];
  322. DrawTriangle(pV0, pV1, pV2);
  323. }
  324. }
  325. break;
  326. default:
  327. DPFERR( "Refrast Error: Unknown or unsupported primitive type "
  328. "requested of DrawOneIndexedPrimitive" );
  329. return DDERR_INVALIDPARAMS;
  330. }
  331. return D3D_OK;
  332. }
  333. //----------------------------------------------------------------------------
  334. //
  335. // DoDrawOneEdgeFlagTriangleFan
  336. //
  337. // Draw one list of triangle fans. It's called by both RastDrawOnePrimitive and
  338. // RastDrawPrimitives.
  339. //
  340. //----------------------------------------------------------------------------
  341. HRESULT
  342. RefDev::DrawOneEdgeFlagTriangleFan( GArrayT<RDVertex>& VtxArray,
  343. UINT cVertices,
  344. UINT32 dwEdgeFlags )
  345. {
  346. INT i;
  347. RDVertex* pV0;
  348. RDVertex* pV1;
  349. RDVertex* pV2;
  350. HRESULT hr;
  351. DWORD dwCurrVtx = 0;
  352. pV2 = &VtxArray[dwCurrVtx++];
  353. pV0 = &VtxArray[dwCurrVtx++];
  354. pV1 = &VtxArray[dwCurrVtx++];
  355. WORD wFlags = 0;
  356. if(dwEdgeFlags & 0x2)
  357. wFlags |= D3DTRIFLAG_EDGEENABLE1;
  358. if(dwEdgeFlags & 0x1)
  359. wFlags |= D3DTRIFLAG_EDGEENABLE3;
  360. if(cVertices == 3) {
  361. if(dwEdgeFlags & 0x4)
  362. wFlags |= D3DTRIFLAG_EDGEENABLE2;
  363. DrawTriangle(pV0, pV1, pV2, wFlags);
  364. return D3D_OK;
  365. }
  366. DrawTriangle(pV0, pV1, pV2, wFlags);
  367. UINT32 dwMask = 0x4;
  368. for (i = (INT)cVertices - 4; i > 0; i--)
  369. {
  370. pV0 = pV1;
  371. pV1 = &VtxArray[dwCurrVtx++];
  372. if(dwEdgeFlags & dwMask)
  373. {
  374. DrawTriangle(pV0, pV1, pV2, D3DTRIFLAG_EDGEENABLE1);
  375. }
  376. else
  377. {
  378. DrawTriangle(pV0, pV1, pV2, 0);
  379. }
  380. dwMask <<= 1;
  381. }
  382. pV0 = pV1;
  383. pV1 = &VtxArray[dwCurrVtx++];
  384. wFlags = 0;
  385. if(dwEdgeFlags & dwMask)
  386. wFlags |= D3DTRIFLAG_EDGEENABLE1;
  387. dwMask <<= 1;
  388. if(dwEdgeFlags & dwMask)
  389. wFlags |= D3DTRIFLAG_EDGEENABLE2;
  390. DrawTriangle(pV0, pV1, pV2, wFlags);
  391. return D3D_OK;
  392. }