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.

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