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.

696 lines
17 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: mcdprim.c
  3. *
  4. * These routines process the OpenGL rendering commands that appear in an
  5. * MCDrvDraw() batch. Note that the only OpenGL primitive which is invalid
  6. * is LineLoop. This gets decomposed by the caller into a LineStrip command.
  7. *
  8. * Copyright (c) 1996 Microsoft Corporation
  9. \**************************************************************************/
  10. #include "precomp.h"
  11. #include "mcdhw.h"
  12. #include "mcdutil.h"
  13. #define MEMCHECK_VERTEX(p)\
  14. if (((UCHAR *)p < pRc->pMemMin) ||\
  15. ((UCHAR *)p > pRc->pMemMax)) {\
  16. MCDBG_PRINT("Invalid MCD vertex pointer!");\
  17. return NULL;\
  18. }
  19. ////////////////////////////////////////////////////////////////////////
  20. //
  21. // The functions below are local rendering-helper functions which call
  22. // the real rendering routines in the driver.
  23. //
  24. ////////////////////////////////////////////////////////////////////////
  25. VOID static FASTCALL __MCDRenderPoint(DEVRC *pRc, MCDVERTEX *v)
  26. {
  27. if (v->clipCode == 0)
  28. (*pRc->renderPoint)(pRc, v);
  29. }
  30. VOID static FASTCALL __MCDRenderLine(DEVRC *pRc, MCDVERTEX *v0,
  31. MCDVERTEX *v1, BOOL bResetLine)
  32. {
  33. if (v0->clipCode | v1->clipCode)
  34. {
  35. /*
  36. * The line must be clipped more carefully. Cannot
  37. * trivially accept the lines.
  38. *
  39. * If anding the codes is non-zero then every vertex
  40. * in the line is outside of the same set of clipping
  41. * planes (at least one). Trivially reject the line.
  42. */
  43. if ((v0->clipCode & v1->clipCode) == 0)
  44. (*pRc->clipLine)(pRc, v0, v1, bResetLine);
  45. }
  46. else
  47. {
  48. // Line is trivially accepted so render it
  49. (*pRc->renderLine)(pRc, v0, v1, bResetLine);
  50. }
  51. }
  52. VOID static FASTCALL __MCDRenderTriangle(DEVRC *pRc, MCDVERTEX *v0,
  53. MCDVERTEX *v1, MCDVERTEX *v2)
  54. {
  55. ULONG orCodes;
  56. /* Clip check */
  57. orCodes = v0->clipCode | v1->clipCode | v2->clipCode;
  58. if (orCodes)
  59. {
  60. /* Some kind of clipping is needed.
  61. *
  62. * If anding the codes is non-zero then every vertex
  63. * in the triangle is outside of the same set of
  64. * clipping planes (at least one). Trivially reject
  65. * the triangle.
  66. */
  67. if (!(v0->clipCode & v1->clipCode & v2->clipCode))
  68. (*pRc->clipTri)(pRc, v0, v1, v2, orCodes);
  69. }
  70. else
  71. {
  72. (*pRc->renderTri)(pRc, v0, v1, v2);
  73. }
  74. }
  75. VOID static FASTCALL __MCDRenderQuad(DEVRC *pRc, MCDVERTEX *v0,
  76. MCDVERTEX *v1, MCDVERTEX *v2, MCDVERTEX *v3)
  77. {
  78. // Vertex ordering is important. Line stippling uses it.
  79. ULONG savedTag;
  80. /* Render the quad as two triangles */
  81. savedTag = v2->flags & MCDVERTEX_EDGEFLAG;
  82. v2->flags &= ~MCDVERTEX_EDGEFLAG;
  83. (*pRc->renderTri)(pRc, v0, v1, v2);
  84. v2->flags |= savedTag;
  85. savedTag = v0->flags & MCDVERTEX_EDGEFLAG;
  86. v0->flags &= ~MCDVERTEX_EDGEFLAG;
  87. (*pRc->renderTri)(pRc, v2, v3, v0);
  88. v0->flags |= savedTag;
  89. }
  90. VOID static FASTCALL __MCDRenderClippedQuad(DEVRC *pRc, MCDVERTEX *v0,
  91. MCDVERTEX *v1, MCDVERTEX *v2, MCDVERTEX *v3)
  92. {
  93. ULONG orCodes;
  94. orCodes = v0->clipCode | v1->clipCode | v2->clipCode | v3->clipCode;
  95. if (orCodes)
  96. {
  97. /* Some kind of clipping is needed.
  98. *
  99. * If anding the codes is non-zero then every vertex
  100. * in the quad is outside of the same set of
  101. * clipping planes (at least one). Trivially reject
  102. * the quad.
  103. */
  104. if (!(v0->clipCode & v1->clipCode & v2->clipCode & v3->clipCode))
  105. {
  106. /* Clip the quad as a polygon */
  107. MCDVERTEX *iv[4];
  108. iv[0] = v0;
  109. iv[1] = v1;
  110. iv[2] = v2;
  111. iv[3] = v3;
  112. (pRc->doClippedPoly)(pRc, &iv[0], 4, orCodes);
  113. }
  114. }
  115. else
  116. {
  117. __MCDRenderQuad(pRc, v0, v1, v2, v3);
  118. }
  119. }
  120. ////////////////////////////////////////////////////////////////////////
  121. //
  122. // The functions below handle the processing of all of the primitives
  123. // which may appear in an MCDCOMMAND. This includes all of the OpenGL
  124. // primitives, with the exception of line loops which are handled as
  125. // line strips.
  126. //
  127. ////////////////////////////////////////////////////////////////////////
  128. MCDCOMMAND * FASTCALL __MCDPrimDrawPoints(DEVRC *pRc, MCDCOMMAND *pCmd)
  129. {
  130. LONG i, nIndices;
  131. MCDVERTEX *pv;
  132. VOID (FASTCALL *rp)(DEVRC *pRc, MCDVERTEX *v);
  133. // Index mapping is always identity in Points.
  134. // ASSERTOPENGL(!pa->aIndices, "Index mapping must be identity\n");
  135. if (pCmd->clipCodes)
  136. rp = __MCDRenderPoint;
  137. else
  138. rp = pRc->renderPoint;
  139. (*pRc->beginPointDrawing)(pRc);
  140. // Render the points:
  141. pv = pCmd->pStartVertex;
  142. MEMCHECK_VERTEX(pv);
  143. i = pCmd->numIndices;
  144. MEMCHECK_VERTEX(pv + (i - 1));
  145. for (; i > 0; i--, pv++)
  146. (*rp)(pRc, pv);
  147. return pCmd->pNextCmd;
  148. }
  149. MCDCOMMAND * FASTCALL __MCDPrimDrawLines(DEVRC *pRc, MCDCOMMAND *pCmd)
  150. {
  151. LONG i, iLast2;
  152. UCHAR *pIndices;
  153. MCDVERTEX *pv, *pv0, *pv1;
  154. VOID (FASTCALL *rl)(DEVRC *pRc, MCDVERTEX *pv1, MCDVERTEX *pv2, BOOL bResetLine);
  155. iLast2 = pCmd->numIndices - 2;
  156. pv = pCmd->pStartVertex;
  157. rl = pCmd->clipCodes ? __MCDRenderLine : pRc->renderLine;
  158. (*pRc->beginLineDrawing)(pRc);
  159. if (!(pIndices = pCmd->pIndices))
  160. {
  161. // Identity mapping
  162. MEMCHECK_VERTEX(pv);
  163. MEMCHECK_VERTEX(pv + (iLast2 + 1));
  164. for (i = 0; i <= iLast2; i += 2)
  165. {
  166. /* setup for rendering this line */
  167. pRc->resetLineStipple = TRUE;
  168. (*rl)(pRc, &pv[i], &pv[i+1], TRUE);
  169. }
  170. }
  171. else
  172. {
  173. for (i = 0; i <= iLast2; i += 2)
  174. {
  175. pv0 = &pv[pIndices[i]];
  176. pv1 = &pv[pIndices[i+1]];
  177. MEMCHECK_VERTEX(pv0);
  178. MEMCHECK_VERTEX(pv1);
  179. /* setup for rendering this line */
  180. pRc->resetLineStipple = TRUE;
  181. (*rl)(pRc, pv0, pv1, TRUE);
  182. }
  183. }
  184. (*pRc->endLineDrawing)(pRc);
  185. return pCmd->pNextCmd;
  186. }
  187. MCDCOMMAND * FASTCALL __MCDPrimDrawLineLoop(DEVRC *pRc, MCDCOMMAND *pCmd)
  188. {
  189. // NOTE:
  190. // Line loops are always converted tp line strips at the OpenGL
  191. // API level. This routine is currently not used.
  192. MCDBG_PRINT("MCDPrimLineLoop: Invalid MCD command!");
  193. return pCmd->pNextCmd;
  194. }
  195. MCDCOMMAND * FASTCALL __MCDPrimDrawLineStrip(DEVRC *pRc, MCDCOMMAND *pCmd)
  196. {
  197. LONG i, iLast;
  198. UCHAR *pIndices;
  199. MCDVERTEX *pv, *pv0, *pv1;
  200. MCDVERTEX *vOld;
  201. VOID (FASTCALL *rl)(DEVRC *pRc, MCDVERTEX *pv1, MCDVERTEX *pv2, BOOL bResetLine);
  202. iLast = pCmd->numIndices - 1;
  203. pv = pCmd->pStartVertex;
  204. rl = pCmd->clipCodes ? __MCDRenderLine : pRc->renderLine;
  205. if (iLast <= 0)
  206. return pCmd->pNextCmd;
  207. if (pCmd->flags & MCDCOMMAND_RESET_STIPPLE)
  208. pRc->resetLineStipple = TRUE;
  209. (*pRc->beginLineDrawing)(pRc);
  210. if (!(pIndices = pCmd->pIndices))
  211. {
  212. // Identity mapping
  213. // Add first line segment (NOTE: 0, 1)
  214. MEMCHECK_VERTEX(pv);
  215. MEMCHECK_VERTEX(pv + iLast);
  216. (*rl)(pRc, &pv[0], &pv[1], TRUE);
  217. // Add subsequent line segments (NOTE: i, i+1)
  218. for (i = 1; i < iLast; i++) {
  219. (*rl)(pRc, &pv[i], &pv[i+1], FALSE);
  220. }
  221. }
  222. else
  223. {
  224. // Add first line segment (NOTE: 0, 1)
  225. pv0 = &pv[pIndices[0]];
  226. pv1 = &pv[pIndices[1]];
  227. (*rl)(pRc, pv0, pv1, TRUE);
  228. // Add subsequent line segments (NOTE: i, i+1)
  229. for (i = 1; i < iLast; i++) {
  230. pv0 = pv1;
  231. pv1 = &pv[pIndices[i+1]];
  232. MEMCHECK_VERTEX(pv1);
  233. (*rl)(pRc, pv0, pv1, FALSE);
  234. }
  235. }
  236. (*pRc->endLineDrawing)(pRc);
  237. return pCmd->pNextCmd;
  238. }
  239. MCDCOMMAND * FASTCALL __MCDPrimDrawTriangles(DEVRC *pRc, MCDCOMMAND *pCmd)
  240. {
  241. LONG i, iLast3;
  242. UCHAR *pIndices;
  243. MCDVERTEX *pv, *pv0, *pv1, *pv2;
  244. VOID (FASTCALL *rt)(DEVRC *pRc, MCDVERTEX *v0, MCDVERTEX *v1, MCDVERTEX *v2);
  245. iLast3 = pCmd->numIndices - 3;
  246. pv = pCmd->pStartVertex;
  247. if (pCmd->clipCodes)
  248. rt = __MCDRenderTriangle;
  249. else
  250. rt = pRc->renderTri;
  251. if (!(pIndices = pCmd->pIndices))
  252. {
  253. // Identity mapping
  254. MEMCHECK_VERTEX(pv);
  255. MEMCHECK_VERTEX(pv + (iLast3 + 2));
  256. for (i = 0; i <= iLast3; i += 3)
  257. {
  258. /* setup for rendering this triangle */
  259. pRc->resetLineStipple = TRUE;
  260. pRc->pvProvoking = &pv[i+2];
  261. /* Render the triangle (NOTE: i, i+1, i+2) */
  262. (*rt)(pRc, &pv[i], &pv[i+1], &pv[i+2]);
  263. }
  264. }
  265. else
  266. {
  267. for (i = 0; i <= iLast3; i += 3)
  268. {
  269. /* setup for rendering this triangle */
  270. pv0 = &pv[pIndices[i ]];
  271. pv1 = &pv[pIndices[i+1]];
  272. pv2 = &pv[pIndices[i+2]];
  273. MEMCHECK_VERTEX(pv0);
  274. MEMCHECK_VERTEX(pv1);
  275. MEMCHECK_VERTEX(pv2);
  276. pRc->resetLineStipple = TRUE;
  277. pRc->pvProvoking = pv2;
  278. /* Render the triangle (NOTE: i, i+1, i+2) */
  279. (*rt)(pRc, pv0, pv1, pv2);
  280. }
  281. }
  282. return pCmd->pNextCmd;
  283. }
  284. MCDCOMMAND * FASTCALL __MCDPrimDrawTriangleStrip(DEVRC *pRc, MCDCOMMAND *pCmd)
  285. {
  286. LONG i, iLast3;
  287. UCHAR *pIndices;
  288. MCDVERTEX *pv, *pv0, *pv1, *pv2;
  289. VOID (FASTCALL *rt)(DEVRC *pRc, MCDVERTEX *v0, MCDVERTEX *v1, MCDVERTEX *v2);
  290. iLast3 = pCmd->numIndices - 3;
  291. pv = pCmd->pStartVertex;
  292. if (pCmd->clipCodes)
  293. rt = __MCDRenderTriangle;
  294. else
  295. rt = pRc->renderTri;
  296. if (iLast3 < 0)
  297. return pCmd->pNextCmd;
  298. if (!(pIndices = pCmd->pIndices))
  299. {
  300. // Identity mapping
  301. MEMCHECK_VERTEX(pv);
  302. MEMCHECK_VERTEX(pv + (iLast3 + 2));
  303. pv[0].flags |= MCDVERTEX_EDGEFLAG;
  304. pv[1].flags |= MCDVERTEX_EDGEFLAG;
  305. for (i = 0; i <= iLast3; i++)
  306. {
  307. /* setup for rendering this triangle */
  308. pRc->resetLineStipple = TRUE;
  309. pRc->pvProvoking = &pv[i+2];
  310. pv[i+2].flags |= MCDVERTEX_EDGEFLAG;
  311. /* Render the triangle (NOTE: i, i+1, i+2) */
  312. (*rt)(pRc, &pv[i], &pv[i+1], &pv[i+2]);
  313. if (++i > iLast3)
  314. break;
  315. pRc->resetLineStipple = TRUE;
  316. pRc->pvProvoking = &pv[i+2];
  317. pv[i+2].flags |= MCDVERTEX_EDGEFLAG;
  318. /* Render the triangle (NOTE: i+1, i, i+2) */
  319. (*rt)(pRc, &pv[i+1], &pv[i], &pv[i+2]);
  320. }
  321. }
  322. else
  323. {
  324. pv1 = &pv[pIndices[0]];
  325. MEMCHECK_VERTEX(pv1);
  326. pv1->flags |= MCDVERTEX_EDGEFLAG;
  327. pv2 = &pv[pIndices[1]];
  328. MEMCHECK_VERTEX(pv2);
  329. pv2->flags |= MCDVERTEX_EDGEFLAG;
  330. for (i = 0; i <= iLast3; i++)
  331. {
  332. /* setup for rendering this triangle */
  333. pRc->resetLineStipple = TRUE;
  334. pv0 = pv1;
  335. pv1 = pv2;
  336. pv2 = &pv[pIndices[i+2]];
  337. MEMCHECK_VERTEX(pv2);
  338. pv2->flags |= MCDVERTEX_EDGEFLAG;
  339. pRc->resetLineStipple = TRUE;
  340. pRc->pvProvoking = pv2;
  341. /* Render the triangle (NOTE: i, i+1, i+2) */
  342. (*rt)(pRc, pv0, pv1, pv2);
  343. if (++i > iLast3)
  344. break;
  345. pv0 = pv1;
  346. pv1 = pv2;
  347. pv2 = &pv[pIndices[i+2]];
  348. MEMCHECK_VERTEX(pv2);
  349. pv2->flags |= MCDVERTEX_EDGEFLAG;
  350. /* setup for rendering this triangle */
  351. pRc->resetLineStipple = TRUE;
  352. pRc->pvProvoking = pv2;
  353. /* Render the triangle (NOTE: i+1, i, i+2) */
  354. (*rt)(pRc, pv1, pv0, pv2);
  355. }
  356. }
  357. return pCmd->pNextCmd;
  358. }
  359. MCDCOMMAND * FASTCALL __MCDPrimDrawTriangleFan(DEVRC *pRc, MCDCOMMAND *pCmd)
  360. {
  361. LONG i, iLast2;
  362. UCHAR *pIndices;
  363. MCDVERTEX *pv, *pv0, *pv1, *pv2;
  364. VOID (FASTCALL *rt)(DEVRC *pRc, MCDVERTEX *v0, MCDVERTEX *v1, MCDVERTEX *v2);
  365. iLast2 = pCmd->numIndices - 2;
  366. pv = pCmd->pStartVertex;
  367. if (pCmd->clipCodes)
  368. rt = __MCDRenderTriangle;
  369. else
  370. rt = pRc->renderTri;
  371. if (iLast2 <= 0)
  372. return pCmd->pNextCmd;
  373. if (!(pIndices = pCmd->pIndices))
  374. {
  375. // Identity mapping
  376. MEMCHECK_VERTEX(pv);
  377. MEMCHECK_VERTEX(pv + (iLast2 + 1));
  378. pv[0].flags |= MCDVERTEX_EDGEFLAG;
  379. pv[1].flags |= MCDVERTEX_EDGEFLAG;
  380. for (i = 1; i <= iLast2; i++)
  381. {
  382. /* setup for rendering this triangle */
  383. pRc->resetLineStipple = TRUE;
  384. pRc->pvProvoking = &pv[i+1];
  385. pv[i+1].flags |= MCDVERTEX_EDGEFLAG;
  386. /* Render the triangle (NOTE: 0, i, i+1) */
  387. (*rt)(pRc, &pv[0], &pv[i], &pv[i+1]);
  388. }
  389. }
  390. else
  391. {
  392. // Initialize first 2 vertices so we can start rendering the tfan
  393. // below. The edge flags are not modified by our lower level routines.
  394. pv0 = &pv[pIndices[0]];
  395. MEMCHECK_VERTEX(pv0);
  396. pv0->flags |= MCDVERTEX_EDGEFLAG;
  397. pv2 = &pv[pIndices[1]];
  398. MEMCHECK_VERTEX(pv2);
  399. pv2->flags |= MCDVERTEX_EDGEFLAG;
  400. for (i = 1; i <= iLast2; i++)
  401. {
  402. pv1 = pv2;
  403. pv2 = &pv[pIndices[i+1]];
  404. MEMCHECK_VERTEX(pv2);
  405. pv2->flags |= MCDVERTEX_EDGEFLAG;
  406. /* setup for rendering this triangle */
  407. pRc->resetLineStipple = TRUE;
  408. pRc->pvProvoking = pv2;
  409. /* Render the triangle (NOTE: 0, i, i+1) */
  410. (*rt)(pRc, pv0, pv1, pv2);
  411. }
  412. }
  413. return pCmd->pNextCmd;
  414. }
  415. MCDCOMMAND * FASTCALL __MCDPrimDrawQuads(DEVRC *pRc, MCDCOMMAND *pCmd)
  416. {
  417. LONG i, iLast4;
  418. UCHAR *pIndices;
  419. MCDVERTEX *pv, *pv0, *pv1, *pv2, *pv3;
  420. VOID (FASTCALL *rq)(DEVRC *pRc, MCDVERTEX *v0, MCDVERTEX *v1, MCDVERTEX *v2,
  421. MCDVERTEX *v3);
  422. iLast4 = pCmd->numIndices - 4;
  423. pv = pCmd->pStartVertex;
  424. if (pCmd->clipCodes)
  425. rq = __MCDRenderClippedQuad;
  426. else
  427. rq = __MCDRenderQuad;
  428. if (!(pIndices = pCmd->pIndices))
  429. {
  430. MEMCHECK_VERTEX(pv);
  431. MEMCHECK_VERTEX(pv + (iLast4 + 3));
  432. // Identity mapping
  433. for (i = 0; i <= iLast4; i += 4)
  434. {
  435. pRc->resetLineStipple = TRUE;
  436. pRc->pvProvoking = &pv[i+3];
  437. /* Render the quad (NOTE: i, i+1, i+2, i+3) */
  438. (*rq)(pRc, &pv[i], &pv[i+1], &pv[i+2], &pv[i+3]);
  439. }
  440. }
  441. else
  442. {
  443. for (i = 0; i <= iLast4; i += 4)
  444. {
  445. pv0 = &pv[pIndices[i ]];
  446. pv1 = &pv[pIndices[i+1]];
  447. pv2 = &pv[pIndices[i+2]];
  448. pv3 = &pv[pIndices[i+3]];
  449. MEMCHECK_VERTEX(pv0);
  450. MEMCHECK_VERTEX(pv1);
  451. MEMCHECK_VERTEX(pv2);
  452. MEMCHECK_VERTEX(pv3);
  453. pRc->resetLineStipple = TRUE;
  454. pRc->pvProvoking = pv3;
  455. /* Render the quad (NOTE: i, i+1, i+2, i+3) */
  456. (*rq)(pRc, pv0, pv1, pv2, pv3);
  457. }
  458. }
  459. return pCmd->pNextCmd;
  460. }
  461. MCDCOMMAND * FASTCALL __MCDPrimDrawQuadStrip(DEVRC *pRc, MCDCOMMAND *pCmd)
  462. {
  463. ULONG i, iLast4;
  464. UCHAR *pIndices;
  465. MCDVERTEX *pv, *pv0, *pv1, *pv2, *pv3;
  466. VOID (FASTCALL *rq)(DEVRC *pRc, MCDVERTEX *v0, MCDVERTEX *v1, MCDVERTEX *v2,
  467. MCDVERTEX *v3);
  468. iLast4 = pCmd->numIndices - 4;
  469. pv = pCmd->pStartVertex;
  470. if (pCmd->clipCodes)
  471. rq = __MCDRenderClippedQuad;
  472. else
  473. rq = __MCDRenderQuad;
  474. // Vertex ordering is important. Line stippling uses it.
  475. if (!(pIndices = pCmd->pIndices))
  476. {
  477. // Identity mapping
  478. MEMCHECK_VERTEX(pv);
  479. MEMCHECK_VERTEX(pv + (iLast4 + 3));
  480. pv[0].flags |= MCDVERTEX_EDGEFLAG;
  481. pv[1].flags |= MCDVERTEX_EDGEFLAG;
  482. for (i = 0; i <= iLast4; i += 2)
  483. {
  484. pv[i+2].flags |= MCDVERTEX_EDGEFLAG;
  485. pv[i+3].flags |= MCDVERTEX_EDGEFLAG;
  486. /* setup for rendering this quad */
  487. pRc->pvProvoking = &pv[i+3];
  488. pRc->resetLineStipple = TRUE;
  489. /* Render the quad (NOTE: i, i+1, i+3, i+2) */
  490. (*rq)(pRc, &pv[i], &pv[i+1], &pv[i+3], &pv[i+2]);
  491. }
  492. }
  493. else
  494. {
  495. // Initialize first 2 vertices so we can start rendering the quad
  496. // below. The edge flags are not modified by our lower level routines.
  497. pv2 = &pv[pIndices[0]];
  498. MEMCHECK_VERTEX(pv2);
  499. pv2->flags |= MCDVERTEX_EDGEFLAG;
  500. pv3 = &pv[pIndices[1]];
  501. MEMCHECK_VERTEX(pv3);
  502. pv3->flags |= MCDVERTEX_EDGEFLAG;
  503. for (i = 0; i <= iLast4; i += 2)
  504. {
  505. pv0 = pv2;
  506. pv1 = pv3;
  507. pv2 = &pv[pIndices[i+2]];
  508. MEMCHECK_VERTEX(pv2);
  509. pv2->flags |= MCDVERTEX_EDGEFLAG;
  510. pv3 = &pv[pIndices[i+3]];
  511. MEMCHECK_VERTEX(pv3);
  512. pv3->flags |= MCDVERTEX_EDGEFLAG;
  513. /* setup for rendering this quad */
  514. pRc->resetLineStipple = TRUE;
  515. pRc->pvProvoking = pv3;
  516. /* Render the quad (NOTE: i, i+1, i+3, i+2) */
  517. (*rq)(pRc, pv0, pv1, pv3, pv2);
  518. }
  519. }
  520. return pCmd->pNextCmd;
  521. }
  522. MCDCOMMAND * FASTCALL __MCDPrimDrawPolygon(DEVRC *pRc, MCDCOMMAND *pCmd)
  523. {
  524. // ASSERTOPENGL(!pCmd->pIndices, "Index mapping must be identity\n");
  525. // Reset the line stipple if this is a new polygon:
  526. if (pCmd->flags & MCDCOMMAND_RESET_STIPPLE)
  527. pRc->resetLineStipple = TRUE;
  528. // Note that the provoking vertex is set in clipPolygon:
  529. MEMCHECK_VERTEX(pCmd->pStartVertex);
  530. MEMCHECK_VERTEX(pCmd->pStartVertex + (pCmd->numIndices-1));
  531. (*pRc->clipPoly)(pRc, pCmd->pStartVertex, pCmd->numIndices);
  532. return pCmd->pNextCmd;
  533. }