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.

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