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.

675 lines
24 KiB

  1. /*
  2. ** Copyright 1991, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. ** $Revision: 1.16 $
  18. ** $Date: 1993/09/23 16:33:23 $
  19. */
  20. #include "precomp.h"
  21. #pragma hdrstop
  22. #include <fixed.h>
  23. /*
  24. ** Clip an input polygon against a clipping plane outputing the new
  25. ** vertex pointers in ov and return the number of them. See the line
  26. ** clipping code for an in depth discussion of how "t" is computed.
  27. **
  28. ** NOTE: In order to handle non-convex polygons here without dying,
  29. ** we count the number of verticies generated by clipping. If the
  30. ** count ever gets to 3, then it must be a non-convex polygon (because
  31. ** it means the polygon crossed the clipping plane three times, which is
  32. ** impossible for a convex polygon).
  33. */
  34. static GLint clipToPlane(__GLcontext *gc, __GLvertex **iv, GLint niv,
  35. __GLvertex **ov, GLuint offs, GLboolean negate)
  36. {
  37. GLint i, nout, generated;
  38. __GLvertex *s, *p, *newVertex, *temp;
  39. __GLfloat pDist, sDist, t;
  40. PFN_VERTEX_CLIP_PROC clip;
  41. #ifdef GL_WIN_phong_shading
  42. GLboolean doNormalize = (gc->state.enables.general &
  43. __GL_NORMALIZE_ENABLE);
  44. #endif //GL_WIN_phong_shading
  45. nout = 0;
  46. generated = 0;
  47. temp = gc->transform.nextClipTemp;
  48. clip = gc->procs.polyClipParam;
  49. s = iv[niv-1];
  50. if (negate)
  51. {
  52. sDist = s->clip.w - *(__GLfloat *)((GLubyte *)s + offs);
  53. }
  54. else
  55. {
  56. sDist = *(__GLfloat *)((GLubyte *)s + offs) + s->clip.w;
  57. }
  58. for (i = 0; i < niv; i++) {
  59. p = iv[i];
  60. if (negate)
  61. {
  62. pDist = p->clip.w - *(__GLfloat *)((GLubyte *)p + offs);
  63. }
  64. else
  65. {
  66. pDist = *(__GLfloat *)((GLubyte *)p + offs) + p->clip.w;
  67. }
  68. if (__GL_FLOAT_GEZ(pDist)) {
  69. /* p is inside the clipping plane half space */
  70. if (__GL_FLOAT_GEZ(sDist)) {
  71. /* s is inside the clipping plane half space */
  72. *ov++ = p;
  73. nout++;
  74. } else {
  75. /* s is outside the clipping plane half space */
  76. t = pDist / (pDist - sDist);
  77. newVertex = temp++;
  78. (*clip)(newVertex, s, p, t);
  79. #ifdef GL_WIN_phong_shading
  80. if (doNormalize) __glNormalize(&newVertex->normal.x,
  81. &newVertex->normal.x);
  82. #endif //GL_WIN_phong_shading
  83. #ifndef NT
  84. // edgeflag is now part of has field.
  85. newVertex->boundaryEdge = s->boundaryEdge;
  86. #endif
  87. newVertex->has = s->has;
  88. newVertex->clipCode = s->clipCode;
  89. ASSERTOPENGL(newVertex->color ==
  90. &newVertex->colors[__GL_FRONTFACE],
  91. "Vertex color pointer wrong\n");
  92. *ov++ = newVertex;
  93. *ov++ = p;
  94. nout += 2;
  95. if (++generated >= 3) {
  96. /* Toss the non-convex polygon */
  97. return 0;
  98. }
  99. }
  100. } else {
  101. /* p is outside the clipping plane half space */
  102. if (__GL_FLOAT_GEZ(sDist)) {
  103. /*
  104. ** s is inside the clipping plane half space
  105. **
  106. ** NOTE: To avoid cracking in polygons with shared
  107. ** clipped edges we always compute "t" from the out
  108. ** vertex to the in vertex. The above clipping code gets
  109. ** this for free (p is in and s is out). In this code p
  110. ** is out and s is in, so we reverse the t computation
  111. ** and the argument order to __glDoClip.
  112. */
  113. t = sDist / (sDist - pDist);
  114. newVertex = temp++;
  115. (*clip)(newVertex, p, s, t);
  116. #ifdef GL_WIN_phong_shading
  117. if (doNormalize) __glNormalize(&newVertex->normal.x,
  118. &newVertex->normal.x);
  119. #endif //GL_WIN_phong_shading
  120. #ifdef NT
  121. // edgeflag is now part of has field.
  122. newVertex->has = s->has | __GL_HAS_EDGEFLAG_BOUNDARY;
  123. newVertex->clipCode = p->clipCode;
  124. #else
  125. newVertex->boundaryEdge = GL_TRUE;
  126. newVertex->has = s->has;
  127. #endif
  128. ASSERTOPENGL(newVertex->color ==
  129. &newVertex->colors[__GL_FRONTFACE],
  130. "Vertex color pointer wrong\n");
  131. *ov++ = newVertex;
  132. nout++;
  133. if (++generated >= 3) {
  134. /* Toss the non-convex polygon */
  135. return 0;
  136. }
  137. } else {
  138. /* both points are outside */
  139. }
  140. }
  141. s = p;
  142. sDist = pDist;
  143. }
  144. gc->transform.nextClipTemp = temp;
  145. return nout;
  146. }
  147. /*
  148. ** Identical to clipToPlane(), except that the clipping is done in eye
  149. ** space.
  150. */
  151. static GLint clipToPlaneEye(__GLcontext *gc, __GLvertex **iv, GLint niv,
  152. __GLvertex **ov, __GLcoord *plane)
  153. {
  154. GLint i, nout, generated;
  155. __GLvertex *s, *p, *newVertex, *temp;
  156. __GLfloat pDist, sDist, t;
  157. PFN_VERTEX_CLIP_PROC clip;
  158. #ifdef GL_WIN_phong_shading
  159. GLboolean doNormalize = (gc->state.enables.general &
  160. __GL_NORMALIZE_ENABLE);
  161. #endif //GL_WIN_phong_shading
  162. nout = 0;
  163. generated = 0;
  164. temp = gc->transform.nextClipTemp;
  165. clip = gc->procs.polyClipParam;
  166. s = iv[niv-1];
  167. sDist = (((POLYDATA *)s)->eye.x * plane->x) +
  168. (((POLYDATA *)s)->eye.y * plane->y) +
  169. (((POLYDATA *)s)->eye.z * plane->z) +
  170. (((POLYDATA *)s)->eye.w * plane->w);
  171. for (i = 0; i < niv; i++) {
  172. p = iv[i];
  173. pDist = (((POLYDATA *)p)->eye.x * plane->x) +
  174. (((POLYDATA *)p)->eye.y * plane->y) +
  175. (((POLYDATA *)p)->eye.z * plane->z) +
  176. (((POLYDATA *)p)->eye.w * plane->w);
  177. if (__GL_FLOAT_GEZ(pDist)) {
  178. /* p is inside the clipping plane half space */
  179. if (__GL_FLOAT_GEZ(sDist)) {
  180. /* s is inside the clipping plane half space */
  181. *ov++ = p;
  182. nout++;
  183. } else {
  184. /* s is outside the clipping plane half space */
  185. t = pDist / (pDist - sDist);
  186. newVertex = temp++;
  187. (*clip)(newVertex, s, p, t);
  188. #ifdef GL_WIN_phong_shading
  189. if (doNormalize) __glNormalize(&newVertex->normal.x,
  190. &newVertex->normal.x);
  191. #endif //GL_WIN_phong_shading
  192. ((POLYDATA *)newVertex)->eye.x =
  193. t*(((POLYDATA *)s)->eye.x - ((POLYDATA *)p)->eye.x) +
  194. ((POLYDATA *)p)->eye.x;
  195. ((POLYDATA *)newVertex)->eye.y =
  196. t*(((POLYDATA *)s)->eye.y - ((POLYDATA *)p)->eye.y) +
  197. ((POLYDATA *)p)->eye.y;
  198. ((POLYDATA *)newVertex)->eye.z =
  199. t*(((POLYDATA *)s)->eye.z - ((POLYDATA *)p)->eye.z) +
  200. ((POLYDATA *)p)->eye.z;
  201. ((POLYDATA *)newVertex)->eye.w =
  202. t*(((POLYDATA *)s)->eye.w - ((POLYDATA *)p)->eye.w) +
  203. ((POLYDATA *)p)->eye.w;
  204. #ifndef NT
  205. // edgeflag is now part of has field.
  206. newVertex->boundaryEdge = s->boundaryEdge;
  207. #endif
  208. newVertex->has = s->has;
  209. newVertex->clipCode = s->clipCode;
  210. ASSERTOPENGL(newVertex->color ==
  211. &newVertex->colors[__GL_FRONTFACE],
  212. "Vertex color pointer wrong\n");
  213. *ov++ = newVertex;
  214. *ov++ = p;
  215. nout += 2;
  216. if (++generated >= 3) {
  217. /* Toss the non-convex polygon */
  218. return 0;
  219. }
  220. }
  221. } else {
  222. /* p is outside the clipping plane half space */
  223. if (__GL_FLOAT_GEZ(sDist)) {
  224. /*
  225. ** s is inside the clipping plane half space
  226. **
  227. ** NOTE: To avoid cracking in polygons with shared
  228. ** clipped edges we always compute "t" from the out
  229. ** vertex to the in vertex. The above clipping code gets
  230. ** this for free (p is in and s is out). In this code p
  231. ** is out and s is in, so we reverse the t computation
  232. ** and the argument order to __glDoClip.
  233. */
  234. t = sDist / (sDist - pDist);
  235. newVertex = temp++;
  236. (*clip)(newVertex, p, s, t);
  237. #ifdef GL_WIN_phong_shading
  238. if (doNormalize) __glNormalize(&newVertex->normal.x,
  239. &newVertex->normal.x);
  240. #endif //GL_WIN_phong_shading
  241. ((POLYDATA *)newVertex)->eye.x =
  242. t*(((POLYDATA *)p)->eye.x - ((POLYDATA *)s)->eye.x) +
  243. ((POLYDATA *)s)->eye.x;
  244. ((POLYDATA *)newVertex)->eye.y =
  245. t*(((POLYDATA *)p)->eye.y - ((POLYDATA *)s)->eye.y) +
  246. ((POLYDATA *)s)->eye.y;
  247. ((POLYDATA *)newVertex)->eye.z =
  248. t*(((POLYDATA *)p)->eye.z - ((POLYDATA *)s)->eye.z) +
  249. ((POLYDATA *)s)->eye.z;
  250. ((POLYDATA *)newVertex)->eye.w =
  251. t*(((POLYDATA *)p)->eye.w - ((POLYDATA *)s)->eye.w) +
  252. ((POLYDATA *)s)->eye.w;
  253. #ifdef NT
  254. // edgeflag is now part of has field.
  255. newVertex->has = s->has | __GL_HAS_EDGEFLAG_BOUNDARY;
  256. newVertex->clipCode = p->clipCode;
  257. #else
  258. newVertex->boundaryEdge = GL_TRUE;
  259. newVertex->has = s->has;
  260. #endif
  261. ASSERTOPENGL(newVertex->color ==
  262. &newVertex->colors[__GL_FRONTFACE],
  263. "Vertex color pointer wrong\n");
  264. *ov++ = newVertex;
  265. nout++;
  266. if (++generated >= 3) {
  267. /* Toss the non-convex polygon */
  268. return 0;
  269. }
  270. } else {
  271. /* both points are outside */
  272. }
  273. }
  274. s = p;
  275. sDist = pDist;
  276. }
  277. gc->transform.nextClipTemp = temp;
  278. return nout;
  279. }
  280. /*
  281. ** Each clipping plane can add at most one vertex to a convex polygon (it may
  282. ** remove up to all of the verticies). The clipping will leave a polygon
  283. ** convex. Because of this the maximum number of verticies output from
  284. ** the clipToPlane procedure will be total number of clip planes (assuming
  285. ** each plane adds one new vertex) plus the original number of verticies
  286. ** (3 since this if for triangles).
  287. */
  288. #ifndef __CLIP_FIX
  289. #define __GL_TOTAL_CLIP_PLANES 20 /*XXX*/
  290. #ifdef NT
  291. #define __GL_MAX_CLIP_VERTEX (__GL_TOTAL_CLIP_PLANES + __GL_MAX_POLYGON_CLIP_SIZE)
  292. #else
  293. #define __GL_MAX_CLIP_VERTEX (__GL_TOTAL_CLIP_PLANES + __GL_NVBUF)
  294. #endif
  295. #endif
  296. void __glDoPolygonClip(__GLcontext *gc, __GLvertex **iv, GLint nout,
  297. GLuint allClipCodes)
  298. {
  299. #ifndef __CLIP_FIX
  300. __GLvertex *ov[__GL_TOTAL_CLIP_PLANES][__GL_MAX_CLIP_VERTEX];
  301. #endif
  302. __GLvertex **ivp;
  303. __GLvertex **ovp;
  304. __GLvertex *p0, *p1, *p2;
  305. __GLcoord *plane;
  306. GLint i;
  307. __GLviewport *vp;
  308. __GLfloat one, vpXScale, vpYScale, vpZScale;
  309. __GLfloat vpXCenter, vpYCenter, vpZCenter;
  310. PFN_RENDER_TRIANGLE rt;
  311. __GLfloat llx, lly, urx, ury;
  312. __GLfloat winx, winy;
  313. GLuint clipCodes;
  314. // We have to turn rounding on. Otherwise, the fast FP-comparison
  315. // routines below can fail:
  316. FPU_SAVE_MODE();
  317. FPU_ROUND_ON_PREC_HI();
  318. /*
  319. ** Reset nextClipTemp pointer for any new verticies that are generated
  320. ** during the clipping.
  321. */
  322. gc->transform.nextClipTemp = gc->transform.clipTemp;
  323. ivp = &iv[0];
  324. /*
  325. ** Check each of the clipping planes by examining the allClipCodes
  326. ** mask. Note that no bits will be set in allClipCodes for clip
  327. ** planes that are not enabled.
  328. */
  329. if (allClipCodes) {
  330. /* Now clip against the clipping planes */
  331. #ifndef __CLIP_FIX
  332. ovp = &ov[0][0];
  333. #else
  334. ovp = &(((__GLGENcontext *)gc)->pwndLocked->buffers->clip_verts[0][0]);
  335. #endif
  336. /*
  337. ** Do user clip planes first, because we will maintain eye coordinates
  338. ** only while doing user clip planes. They are ignored for the
  339. ** frustum clipping planes.
  340. */
  341. clipCodes = allClipCodes >> 6;
  342. if (clipCodes) {
  343. plane = &gc->state.transform.eyeClipPlanes[0];
  344. do {
  345. if (clipCodes & 1) {
  346. nout = clipToPlaneEye(gc, ivp, nout, ovp, plane);
  347. ASSERTOPENGL(nout <= __GL_MAX_CLIP_VERTEX,
  348. "Too many clip vertices\n");
  349. if (nout < 3) {
  350. FPU_RESTORE_MODE();
  351. return;
  352. }
  353. ivp = ovp;
  354. ovp += __GL_MAX_CLIP_VERTEX;
  355. }
  356. clipCodes >>= 1;
  357. plane++;
  358. } while (clipCodes);
  359. }
  360. allClipCodes &= __GL_FRUSTUM_CLIP_MASK;
  361. if (allClipCodes) {
  362. i = 0;
  363. do {
  364. if (allClipCodes & 1) {
  365. nout = clipToPlane(gc, ivp, nout, ovp,
  366. __glFrustumOffsets[i],
  367. (GLboolean)(i & 1));
  368. ASSERTOPENGL(nout <= __GL_MAX_CLIP_VERTEX,
  369. "Too many clip vertices\n");
  370. if (nout < 3) {
  371. FPU_RESTORE_MODE();
  372. return;
  373. }
  374. ivp = ovp;
  375. ovp += __GL_MAX_CLIP_VERTEX;
  376. }
  377. allClipCodes >>= 1;
  378. i++;
  379. } while (allClipCodes);
  380. }
  381. /*
  382. ** Calculate final screen coordinates. Next phase of polygon
  383. ** processing assumes that window coordinates are already computed.
  384. */
  385. vp = &gc->state.viewport;
  386. vpXCenter = vp->xCenter;
  387. vpYCenter = vp->yCenter;
  388. vpZCenter = vp->zCenter;
  389. vpXScale = vp->xScale;
  390. vpYScale = vp->yScale;
  391. vpZScale = vp->zScale;
  392. ovp = ivp;
  393. one = __glOne;
  394. llx = vpXCenter - vpXScale;
  395. urx = vpXCenter + vpXScale;
  396. if (vpYScale > 0) {
  397. lly = vpYCenter - vpYScale;
  398. ury = vpYCenter + vpYScale;
  399. } else {
  400. lly = vpYCenter + vpYScale;
  401. ury = vpYCenter - vpYScale;
  402. }
  403. for (i = nout; --i >= 0; ) {
  404. __GLfloat x, y, z, wInv;
  405. p0 = *ovp++;
  406. // If the clipCode is zero then the window coordinates
  407. // were computed at the time of clipCode determination
  408. // Generated vertices' clipCodes are set to the out vertex
  409. // to ensure that their window coords are computed
  410. if (p0->clipCode != 0)
  411. {
  412. #ifdef NT
  413. /* XXX (mf) prevent divide-by-zero */
  414. if (__GL_FLOAT_EQZ(p0->clip.w))
  415. wInv = __glZero;
  416. else
  417. wInv = one / p0->clip.w;
  418. #else
  419. wInv = one / p0->clip.w;
  420. #endif
  421. x = p0->clip.x; y = p0->clip.y; z = p0->clip.z;
  422. winx = x * vpXScale * wInv + vpXCenter;
  423. winy = y * vpYScale * wInv + vpYCenter;
  424. p0->window.z = z * vpZScale * wInv + vpZCenter;
  425. p0->window.w = wInv;
  426. /*
  427. ** Check if these window coordinates are legal. At this
  428. ** point, it is quite possible that they are not. Trivially
  429. ** pull them into the legal viewport region if necessary.
  430. */
  431. if (winx < llx) winx = llx;
  432. else if (winx > urx) winx = urx;
  433. if (winy < lly) winy = lly;
  434. else if (winy > ury) winy = ury;
  435. p0->window.x = winx;
  436. p0->window.y = winy;
  437. }
  438. }
  439. }
  440. // Restore mode before rendering
  441. FPU_RESTORE_MODE();
  442. #if 0 //def GL_WIN_phong_shading
  443. if (gc->state.light.shadingModel == GL_PHONG_EXT)
  444. {
  445. __GLvertex *minv;
  446. __GLvertex **cv;
  447. GLint j, index;
  448. minv = *ivp; index=0;
  449. //Reorder the vertices so that p0 is the one with the least y and x
  450. for (i=0, cv=ivp; i<nout; i++, cv++)
  451. {
  452. if (__GL_VERTEX_COMPARE((*cv)->window.y, <, minv->window.y))
  453. {
  454. minv = *cv;
  455. index = i;
  456. }
  457. else if (__GL_VERTEX_COMPARE((*cv)->window.y, ==, minv->window.y))
  458. {
  459. if (__GL_VERTEX_COMPARE((*cv)->window.x, <, minv->window.x))
  460. {
  461. minv = *cv;
  462. index = i;
  463. }
  464. }
  465. }
  466. DbgPrint ("MinIndex = %d\n", index);
  467. j = index;
  468. p0 = (__GLvertex *) ivp[j];
  469. p1 = (__GLvertex *) ivp[(++j)%nout];
  470. p2 = (__GLvertex *) ivp[(++j)%nout];
  471. rt = gc->procs.renderTriangle;
  472. if (nout == 3)
  473. {
  474. (*rt)(gc, p0, p1, p2);
  475. }
  476. else
  477. {
  478. for (i = 0; i < nout - 2; i++)
  479. {
  480. GLuint t1, t2;
  481. if (i == 0)
  482. {
  483. /*
  484. ** Third edge of first sub-triangle is always non-boundary
  485. */
  486. // edgeflag is now part of has field.
  487. t1 = p2->has & __GL_HAS_EDGEFLAG_BOUNDARY;
  488. p2->has &= ~__GL_HAS_EDGEFLAG_BOUNDARY;
  489. (*rt)(gc, p0, p1, p2);
  490. p2->has |= t1;
  491. }
  492. else
  493. if (i == nout - 3)
  494. {
  495. /*
  496. ** First edge of last sub-triangle is always
  497. ** non-boundary
  498. */
  499. // edgeflag is now part of has field.
  500. t1 = p0->has & __GL_HAS_EDGEFLAG_BOUNDARY;
  501. p0->has &= ~__GL_HAS_EDGEFLAG_BOUNDARY;
  502. (*rt)(gc, p0, p1, p2);
  503. p0->has |= t1;
  504. }
  505. else
  506. {
  507. /*
  508. ** Interior sub-triangles have the first and last edge
  509. ** marked non-boundary
  510. */
  511. // edgeflag is now part of has field.
  512. t1 = p0->has & __GL_HAS_EDGEFLAG_BOUNDARY;
  513. t2 = p2->has & __GL_HAS_EDGEFLAG_BOUNDARY;
  514. p0->has &= ~__GL_HAS_EDGEFLAG_BOUNDARY;
  515. p2->has &= ~__GL_HAS_EDGEFLAG_BOUNDARY;
  516. (*rt)(gc, p0, p1, p2);
  517. p0->has |= t1;
  518. p2->has |= t2;
  519. }
  520. p1 = p2;
  521. p2 = (__GLvertex *) ivp[(++j)%nout];
  522. }
  523. }
  524. }
  525. else
  526. {
  527. #endif //GL_WIN_phong_shading
  528. /*
  529. ** Subdivide the clipped polygon into triangles. Only convex polys
  530. ** are supported so this is okay to do. Non-convex polys will do
  531. ** something odd here, but thats the clients fault.
  532. */
  533. p0 = *ivp++;
  534. p1 = *ivp++;
  535. p2 = *ivp++;
  536. rt = gc->procs.renderTriangle;
  537. if (nout == 3)
  538. {
  539. (*rt)(gc, p0, p1, p2);
  540. }
  541. else
  542. {
  543. for (i = 0; i < nout - 2; i++)
  544. {
  545. GLuint t1, t2;
  546. if (i == 0)
  547. {
  548. /*
  549. ** Third edge of first sub-triangle is always non-boundary
  550. */
  551. // edgeflag is now part of has field.
  552. t1 = p2->has & __GL_HAS_EDGEFLAG_BOUNDARY;
  553. p2->has &= ~__GL_HAS_EDGEFLAG_BOUNDARY;
  554. (*rt)(gc, p0, p1, p2);
  555. p2->has |= t1;
  556. }
  557. else
  558. if (i == nout - 3)
  559. {
  560. /*
  561. ** First edge of last sub-triangle is always
  562. ** non-boundary
  563. */
  564. // edgeflag is now part of has field.
  565. t1 = p0->has & __GL_HAS_EDGEFLAG_BOUNDARY;
  566. p0->has &= ~__GL_HAS_EDGEFLAG_BOUNDARY;
  567. (*rt)(gc, p0, p1, p2);
  568. p0->has |= t1;
  569. }
  570. else
  571. {
  572. /*
  573. ** Interior sub-triangles have the first and last edge
  574. ** marked non-boundary
  575. */
  576. // edgeflag is now part of has field.
  577. t1 = p0->has & __GL_HAS_EDGEFLAG_BOUNDARY;
  578. t2 = p2->has & __GL_HAS_EDGEFLAG_BOUNDARY;
  579. p0->has &= ~__GL_HAS_EDGEFLAG_BOUNDARY;
  580. p2->has &= ~__GL_HAS_EDGEFLAG_BOUNDARY;
  581. (*rt)(gc, p0, p1, p2);
  582. p0->has |= t1;
  583. p2->has |= t2;
  584. }
  585. p1 = p2;
  586. p2 = (__GLvertex *) *ivp++;
  587. }
  588. }
  589. #if 0 //def GL_WIN_phong_shading
  590. }
  591. #endif //GL_WIN_phong_shading
  592. }
  593. void FASTCALL __glClipPolygon(__GLcontext *gc, __GLvertex *v0, GLint nv)
  594. {
  595. #ifdef NT
  596. __GLvertex *iv[__GL_MAX_POLYGON_CLIP_SIZE];
  597. #else
  598. __GLvertex *iv[__GL_NVBUF];
  599. #endif
  600. __GLvertex **ivp;
  601. GLint i;
  602. GLuint andCodes, orCodes;
  603. gc->vertex.provoking = v0;
  604. /*
  605. ** Generate array of addresses of the verticies. And all the
  606. ** clip codes together while we are at it.
  607. */
  608. ivp = &iv[0];
  609. andCodes = (GLuint)(-1);
  610. orCodes = 0;
  611. for (i = nv; --i >= 0; ) {
  612. andCodes &= v0->clipCode;
  613. orCodes |= v0->clipCode;
  614. *ivp++ = v0++;
  615. }
  616. if (andCodes != 0) {
  617. /*
  618. ** Trivially reject the polygon. If andCodes is non-zero then
  619. ** every vertex in the polygon is outside of the same set of
  620. ** clipping planes (at least one).
  621. */
  622. return;
  623. }
  624. __glDoPolygonClip(gc, &iv[0], nv, orCodes);
  625. }
  626. void FASTCALL __glClipTriangle(__GLcontext *gc, __GLvertex *a, __GLvertex *b,
  627. __GLvertex *c, GLuint orCodes)
  628. {
  629. __GLvertex *iv[3];
  630. iv[0] = a;
  631. iv[1] = b;
  632. iv[2] = c;
  633. __glDoPolygonClip(gc, &iv[0], 3, orCodes);
  634. }