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.

873 lines
29 KiB

  1. /*
  2. ** Copyright 1991, 1992, 1993, 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. #include "precomp.h"
  18. #pragma hdrstop
  19. #ifdef GL_WIN_phong_shading
  20. #include "phong.h"
  21. #endif //GL_WIN_phong_shading
  22. /*
  23. ** Normal form of a line: Ax + By + C = 0. When evaluated at a point P,
  24. ** the value is zero when P is on the line. For points off the line,
  25. ** the sign of the value determines which side of the line P is on.
  26. */
  27. typedef struct {
  28. __GLfloat a, b, c;
  29. /*
  30. ** The sign of an edge is determined by plugging the third vertex
  31. ** of the triangle into the line equation. This flag is GL_TRUE when
  32. ** the sign is positive.
  33. */
  34. GLboolean edgeSign;
  35. } __glLineEquation;
  36. /*
  37. ** Machine state for rendering triangles.
  38. */
  39. typedef struct {
  40. __GLfloat dyAB;
  41. __GLfloat dyBC;
  42. __glLineEquation ab;
  43. __glLineEquation bc;
  44. __glLineEquation ca;
  45. __GLfloat area;
  46. GLint areaSign;
  47. } __glTriangleMachine;
  48. /*
  49. ** Plane equation coefficients. One plane equation exists for each of
  50. ** the parameters being computed across the surface of the triangle.
  51. */
  52. typedef struct {
  53. __GLfloat a, b, c, d;
  54. } __glPlaneEquation;
  55. /*
  56. ** Cache for some of the coverage computation constants.
  57. */
  58. typedef struct {
  59. __GLfloat dx, dy;
  60. GLint samples;
  61. GLint samplesSquared;
  62. __GLfloat samplesSquaredInv;
  63. GLboolean lastCoverageWasOne;
  64. __GLfloat leftDelta, rightDelta;
  65. __GLfloat bottomDelta, topDelta;
  66. } __glCoverageStuff;
  67. /*
  68. ** Compute the constants A, B and C for a line equation in the general
  69. ** form: Ax + By + C = 0. A given point at (x,y) can be plugged into
  70. ** the left side of the equation and yield a number which indiates whether
  71. ** or not the point is on the line. If the result is zero, then the point
  72. ** is on the line. The sign of the result determines which side of
  73. ** the line the point is on. To handle tie cases properly we need a way
  74. ** to assign a point on the edge to only one triangle. To do this, we
  75. ** look at the sign of the equation evaluated at "c". For edges whose
  76. ** sign at "c" is positive, we allow points on the edge to be in the
  77. ** triangle.
  78. */
  79. static void FindLineEqation(__glLineEquation *eq, const __GLvertex *a,
  80. const __GLvertex *b, const __GLvertex *c)
  81. {
  82. __GLfloat dy, dx, valueAtC;
  83. /*
  84. ** Sort a,b so that the ordering of the verticies is consistent,
  85. ** regardless of the order given to this procedure.
  86. */
  87. if (b->window.y < a->window.y) {
  88. const __GLvertex *temp = b;
  89. b = a;
  90. a = temp;
  91. } else
  92. if ((b->window.y == a->window.y) && (b->window.x < a->window.x)) {
  93. const __GLvertex *temp = b;
  94. b = a;
  95. a = temp;
  96. }
  97. dy = b->window.y - a->window.y;
  98. dx = b->window.x - a->window.x;
  99. eq->a = -dy;
  100. eq->b = dx;
  101. eq->c = dy * a->window.x - dx * a->window.y;
  102. valueAtC = eq->a * c->window.x + eq->b * c->window.y + eq->c;
  103. if (valueAtC > 0) {
  104. eq->edgeSign = GL_TRUE;
  105. } else {
  106. eq->edgeSign = GL_FALSE;
  107. }
  108. }
  109. /*
  110. ** Given three points in (x,y,p) find the plane equation coeffecients
  111. ** for the plane that contains the three points. First find the cross
  112. ** product of two of the vectors defined by the three points, then
  113. ** use one of the points to find "d".
  114. */
  115. static void FindPlaneEquation(__glPlaneEquation *eq,
  116. const __GLvertex *a, const __GLvertex *b,
  117. const __GLvertex *c, __GLfloat p1,
  118. __GLfloat p2, __GLfloat p3)
  119. {
  120. __GLfloat v1x, v1y, v1p;
  121. __GLfloat v2x, v2y, v2p;
  122. __GLfloat nx, ny, np, k;
  123. /* find vector v1 */
  124. v1x = b->window.x - a->window.x;
  125. v1y = b->window.y - a->window.y;
  126. v1p = p2 - p1;
  127. /* find vector v2 */
  128. v2x = c->window.x - a->window.x;
  129. v2y = c->window.y - a->window.y;
  130. v2p = p3 - p1;
  131. /* find the cross product (== normal) for the plane */
  132. nx = v1y*v2p - v1p*v2y;
  133. ny = v1p*v2x - v1x*v2p;
  134. np = v1x*v2y - v1y*v2x;
  135. /*
  136. ** V dot N = k. Find k. We can use any of the three points on
  137. ** the plane, so we use a.
  138. */
  139. k = a->window.x*nx + a->window.y*ny + p1*np;
  140. /*
  141. ** Finally, setup the plane equation coeffecients. Force c to be one
  142. ** by dividing everything through by c.
  143. */
  144. eq->a = nx / np;
  145. eq->b = ny / np;
  146. eq->c = ((__GLfloat) 1.0);
  147. eq->d = -k / np;
  148. }
  149. /*
  150. ** Solve for p in the plane equation.
  151. */
  152. static __GLfloat FindP(__glPlaneEquation *eq, __GLfloat x, __GLfloat y)
  153. {
  154. return -(eq->a * x + eq->b * y + eq->d);
  155. }
  156. /*
  157. ** See if a given point is on the same side of the edge as the other
  158. ** vertex in the triangle not part of this edge. When the line
  159. ** equation evaluates to zero, make points which are on lines with
  160. ** a negative edge sign (edgeSign GL_FALSE) part of the triangle.
  161. */
  162. #define In(eq,x,y) \
  163. (((eq)->a * (x) + (eq)->b * (y) + (eq)->c > 0) == (eq)->edgeSign)
  164. /*
  165. ** Determine if the point x,y is in or out of the triangle. Evaluate
  166. ** each line equation for the point and compare the sign of the result
  167. ** with the edgeSign flag.
  168. */
  169. #define Inside(tm,x,y) \
  170. (In(&(tm)->ab, x, y) && In(&(tm)->bc, x, y) && In(&(tm)->ca, x, y))
  171. #define FILTER_WIDTH ((__GLfloat) 1.0)
  172. #define FILTER_HEIGHT ((__GLfloat) 1.0)
  173. /*
  174. ** Precompute stuff that is constant for all coverage tests.
  175. */
  176. static void FASTCALL ComputeCoverageStuff(__glCoverageStuff *cs, GLint samples)
  177. {
  178. __GLfloat dx, dy, fs = samples;
  179. __GLfloat half = ((__GLfloat) 0.5);
  180. cs->dx = dx = FILTER_WIDTH / fs;
  181. cs->dy = dy = FILTER_HEIGHT / fs;
  182. cs->leftDelta = -(FILTER_WIDTH / 2) + dx * half;
  183. cs->rightDelta = (FILTER_WIDTH / 2) - dx * half;
  184. cs->bottomDelta = -(FILTER_HEIGHT / 2) + dy * half;
  185. cs->topDelta = (FILTER_HEIGHT / 2) - dy * half;
  186. cs->samplesSquared = samples * samples;
  187. cs->samplesSquaredInv = ((__GLfloat) 1.0) / cs->samplesSquared;
  188. cs->samples = samples;
  189. }
  190. /*
  191. ** Return an estimate of the pixel coverage using sub-sampling.
  192. */
  193. static __GLfloat Coverage(__glTriangleMachine *tm, __GLfloat *xs,
  194. __GLfloat *ys, __glCoverageStuff *cs)
  195. {
  196. GLint xx, yy, hits, samples;
  197. __GLfloat dx, dy, yBottom, px, py;
  198. __GLfloat minX, minY, maxX, maxY;
  199. hits = 0;
  200. samples = cs->samples;
  201. dx = cs->dx;
  202. dy = cs->dy;
  203. px = *xs + cs->leftDelta;
  204. yBottom = *ys + cs->bottomDelta;
  205. /*
  206. ** If the last coverage was one (the pixel to the left in x from us),
  207. ** then if the upper right and lower right sample positions are
  208. ** also in then this entire pixel must be in.
  209. */
  210. if (cs->lastCoverageWasOne) {
  211. __GLfloat urx, ury;
  212. urx = *xs + cs->rightDelta;
  213. ury = *ys + cs->topDelta;
  214. if (Inside(tm, urx, ury) && Inside(tm, urx, yBottom)) {
  215. return ((__GLfloat) 1.0);
  216. }
  217. }
  218. /*
  219. ** Setup minimum and maximum x,y coordinates. The min and max values
  220. ** are used to find a "good" point that is actually within the
  221. ** triangle so that parameter values can be computed correctly.
  222. */
  223. minX = 999999;
  224. maxX = __glMinusOne;
  225. minY = 999999;
  226. maxY = __glMinusOne;
  227. for (xx = 0; xx < samples; xx++) {
  228. py = yBottom;
  229. for (yy = 0; yy < samples; yy++) {
  230. if (Inside(tm, px, py)) {
  231. if (px < minX) minX = px;
  232. if (px > maxX) maxX = px;
  233. if (py < minY) minY = py;
  234. if (py > maxY) maxY = py;
  235. hits++;
  236. }
  237. py += dy;
  238. }
  239. px += dx;
  240. }
  241. if (hits) {
  242. /*
  243. ** Return the average of the two coordinates which is guaranteed
  244. ** to be in the triangle.
  245. */
  246. *xs = (minX + maxX) * ((__GLfloat) 0.5);
  247. *ys = (minY + maxY) * ((__GLfloat) 0.5);
  248. if (hits == cs->samplesSquared) {
  249. /* Keep track when the last coverage was one */
  250. cs->lastCoverageWasOne = GL_TRUE;
  251. return ((__GLfloat) 1.0);
  252. }
  253. }
  254. cs->lastCoverageWasOne = GL_FALSE;
  255. return hits * cs->samplesSquaredInv;
  256. }
  257. /*
  258. ** Force f to have no more precision than the subpixel precision allows.
  259. ** Even though "f" is biased this still works and does not generate an
  260. ** overflow.
  261. */
  262. #define __GL_FIX_PRECISION(f) \
  263. ((__GLfloat) ((GLint) (f * (1 << gc->constants.subpixelBits))) \
  264. / (1 << gc->constants.subpixelBits))
  265. void FASTCALL __glFillAntiAliasedTriangle(__GLcontext *gc, __GLvertex *a,
  266. __GLvertex *b, __GLvertex *c,
  267. GLboolean ccw)
  268. {
  269. __glTriangleMachine tm;
  270. __glCoverageStuff cs;
  271. __GLcolor *ca, *cb, *cc, *flatColor;
  272. GLint x, y, left, right, bottom, top, samples;
  273. __glPlaneEquation qwp, zp, rp, gp, bp, ap, ezp, sp, tp;
  274. __glPlaneEquation fp;
  275. GLboolean rgbMode;
  276. __GLcolorBuffer *cfb = gc->drawBuffer;
  277. __GLfloat zero = __glZero;
  278. __GLfloat area, ax, bx, cx, ay, by, cy;
  279. __GLshade *sh = &gc->polygon.shader;
  280. GLuint modeFlags = gc->polygon.shader.modeFlags;
  281. #ifdef __GL_LINT
  282. ccw = ccw;
  283. #endif
  284. /*
  285. ** Recompute the area of the triangle after constraining the incoming
  286. ** coordinates to the subpixel precision. The viewport bias gives
  287. ** more precision (typically) than the subpixel precision. Because of
  288. ** this the algorithim below can fail to reject an essentially empty
  289. ** triangle and instead fill a large area. The scan converter fill
  290. ** routines (eg polydraw.c) don't have this trouble because of the
  291. ** very nature of edge walking.
  292. **
  293. ** NOTE: Notice that here as in other places, when the area calculation
  294. ** is done we are careful to do it as a series of subtractions followed by
  295. ** multiplications. This is done to guarantee that no overflow will
  296. ** occur (remember that the coordinates are biased by a potentially large
  297. ** number, and that multiplying two biased numbers will square the bias).
  298. */
  299. ax = __GL_FIX_PRECISION(a->window.x);
  300. bx = __GL_FIX_PRECISION(b->window.x);
  301. cx = __GL_FIX_PRECISION(c->window.x);
  302. ay = __GL_FIX_PRECISION(a->window.y);
  303. by = __GL_FIX_PRECISION(b->window.y);
  304. cy = __GL_FIX_PRECISION(c->window.y);
  305. area = (ax - cx) * (by - cy) - (bx - cx) * (ay - cy);
  306. if (area == zero) {
  307. return;
  308. }
  309. ca = a->color;
  310. cb = b->color;
  311. cc = c->color;
  312. flatColor = gc->vertex.provoking->color;
  313. /*
  314. ** Construct plane equations for all of the parameters that are
  315. ** computed for the triangle: z, r, g, b, a, s, t, f
  316. */
  317. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  318. FindPlaneEquation(&zp, a, b, c, a->window.z, b->window.z, c->window.z);
  319. }
  320. if (modeFlags & __GL_SHADE_COMPUTE_FOG)
  321. {
  322. FindPlaneEquation(&ezp, a, b, c, a->eyeZ, b->eyeZ, c->eyeZ);
  323. }
  324. else if (modeFlags & __GL_SHADE_INTERP_FOG)
  325. {
  326. FindPlaneEquation(&fp, a, b, c, a->fog, b->fog, c->fog);
  327. }
  328. if (modeFlags & __GL_SHADE_TEXTURE) {
  329. __GLfloat one = __glOne;
  330. __GLfloat aWInv = a->window.w;
  331. __GLfloat bWInv = b->window.w;
  332. __GLfloat cWInv = c->window.w;
  333. FindPlaneEquation(&qwp, a, b, c, a->texture.w * aWInv,
  334. b->texture.w * bWInv, c->texture.w * cWInv);
  335. FindPlaneEquation(&sp, a, b, c, a->texture.x * aWInv,
  336. b->texture.x * bWInv, c->texture.x * cWInv);
  337. FindPlaneEquation(&tp, a, b, c, a->texture.y * aWInv,
  338. b->texture.y * bWInv, c->texture.y * cWInv);
  339. }
  340. rgbMode = gc->modes.rgbMode;
  341. if (modeFlags & __GL_SHADE_SMOOTH) {
  342. FindPlaneEquation(&rp, a, b, c, ca->r, cb->r, cc->r);
  343. if (rgbMode) {
  344. FindPlaneEquation(&gp, a, b, c, ca->g, cb->g, cc->g);
  345. FindPlaneEquation(&bp, a, b, c, ca->b, cb->b, cc->b);
  346. FindPlaneEquation(&ap, a, b, c, ca->a, cb->a, cc->a);
  347. }
  348. }
  349. /*
  350. ** Compute general form of the line equations for each of the
  351. ** edges of the triangle.
  352. */
  353. FindLineEqation(&tm.ab, a, b, c);
  354. FindLineEqation(&tm.bc, b, c, a);
  355. FindLineEqation(&tm.ca, c, a, b);
  356. /* Compute bounding box of the triangle */
  357. left = (GLint)a->window.x;
  358. if (b->window.x < left) left = (GLint)b->window.x;
  359. if (c->window.x < left) left = (GLint)c->window.x;
  360. right = (GLint)a->window.x;
  361. if (b->window.x > right) right = (GLint)b->window.x;
  362. if (c->window.x > right) right = (GLint)c->window.x;
  363. bottom = (GLint)a->window.y;
  364. if (b->window.y < bottom) bottom = (GLint)b->window.y;
  365. if (c->window.y < bottom) bottom = (GLint)c->window.y;
  366. top = (GLint)a->window.y;
  367. if (b->window.y > top) top = (GLint)b->window.y;
  368. if (c->window.y > top) top = (GLint)c->window.y;
  369. /* Bloat the bounding box when anti aliasing */
  370. left -= (GLint)FILTER_WIDTH;
  371. right += (GLint)FILTER_WIDTH;
  372. bottom -= (GLint)FILTER_HEIGHT;
  373. top += (GLint)FILTER_HEIGHT;
  374. /* Init coverage computations */
  375. samples = (gc->state.hints.polygonSmooth == GL_NICEST) ? 8 : 4;
  376. ComputeCoverageStuff(&cs, samples);
  377. /* Scan over the bounding box of the triangle */
  378. for (y = bottom; y <= top; y++) {
  379. cs.lastCoverageWasOne = GL_FALSE;
  380. for (x = left; x <= right; x++) {
  381. __GLfloat coverage;
  382. __GLfloat xs, ys;
  383. if (modeFlags & __GL_SHADE_STIPPLE) {
  384. /*
  385. ** Check the window coordinate against the stipple and
  386. ** and see if the pixel can be written
  387. */
  388. GLint row = y & 31;
  389. GLint col = x & 31;
  390. if ((gc->polygon.stipple[row] & (1<<col)) == 0) {
  391. /*
  392. ** Stipple bit is clear. Do not render this pixel
  393. ** of the triangle.
  394. */
  395. continue;
  396. }
  397. }
  398. xs = x + __glHalf; /* sample point is at pixel center */
  399. ys = y + __glHalf;
  400. coverage = Coverage(&tm, &xs, &ys, &cs);
  401. if (coverage != zero) {
  402. __GLfragment frag;
  403. /*
  404. ** Fill in fragment for rendering. First compute the color
  405. ** of the fragment.
  406. */
  407. if (modeFlags & __GL_SHADE_SMOOTH) {
  408. frag.color.r = FindP(&rp, xs, ys);
  409. if (rgbMode) {
  410. frag.color.g = FindP(&gp, xs, ys);
  411. frag.color.b = FindP(&bp, xs, ys);
  412. frag.color.a = FindP(&ap, xs, ys);
  413. }
  414. } else {
  415. frag.color.r = flatColor->r;
  416. if (rgbMode) {
  417. frag.color.g = flatColor->g;
  418. frag.color.b = flatColor->b;
  419. frag.color.a = flatColor->a;
  420. }
  421. }
  422. /*
  423. ** Texture the fragment.
  424. */
  425. if (modeFlags & __GL_SHADE_TEXTURE) {
  426. __GLfloat qw, s, t, rho;
  427. qw = FindP(&qwp, xs, ys);
  428. s = FindP(&sp, xs, ys);
  429. t = FindP(&tp, xs, ys);
  430. rho = (*gc->procs.calcPolygonRho)(gc, sh, s, t, qw);
  431. #ifdef NT
  432. if( qw == (__GLfloat) 0.0 )
  433. s = t = (__GLfloat) 0;
  434. else {
  435. s /= qw;
  436. t /= qw;
  437. }
  438. #else
  439. s /= qw;
  440. t /= qw;
  441. #endif
  442. (*gc->procs.texture)(gc, &frag.color, s, t, rho);
  443. }
  444. /*
  445. ** Fog the resulting color.
  446. */
  447. if (modeFlags & __GL_SHADE_COMPUTE_FOG)
  448. {
  449. __GLfloat eyeZ = FindP(&ezp, xs, ys);
  450. __glFogFragmentSlow(gc, &frag, eyeZ);
  451. }
  452. else if (modeFlags & __GL_SHADE_INTERP_FOG)
  453. {
  454. __GLfloat fog = FindP(&fp, xs, ys);
  455. __glFogColorSlow(gc, &(frag.color), &(frag.color), fog);
  456. }
  457. /*
  458. ** Apply anti-aliasing effect
  459. */
  460. if (rgbMode) {
  461. frag.color.a *= coverage;
  462. } else {
  463. frag.color.r =
  464. __glBuildAntiAliasIndex(frag.color.r,
  465. coverage);
  466. }
  467. /*
  468. ** Finally, render the fragment.
  469. */
  470. frag.x = (GLint)xs;
  471. frag.y = (GLint)ys;
  472. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  473. frag.z = (__GLzValue)FindP(&zp, xs, ys);
  474. }
  475. (*gc->procs.store)(cfb, &frag);
  476. }
  477. }
  478. }
  479. }
  480. #ifdef GL_WIN_phong_shading
  481. void FASTCALL __glFillAntiAliasedPhongTriangle(__GLcontext *gc, __GLvertex *a,
  482. __GLvertex *b, __GLvertex *c,
  483. GLboolean ccw)
  484. {
  485. #if 1
  486. __glTriangleMachine tm;
  487. __glCoverageStuff cs;
  488. __GLcolor *ca, *cb, *cc, *flatColor;
  489. GLint x, y, left, right, bottom, top, samples;
  490. __glPlaneEquation qwp, zp, rp, gp, bp, ap, ezp, sp, tp;
  491. __glPlaneEquation exp, eyp, ewp, nxp, nyp, nzp;
  492. __glPlaneEquation fp;
  493. GLboolean rgbMode;
  494. __GLcolorBuffer *cfb = gc->drawBuffer;
  495. __GLfloat zero = __glZero;
  496. __GLfloat area, ax, bx, cx, ay, by, cy;
  497. __GLshade *sh = &gc->polygon.shader;
  498. GLuint modeFlags = gc->polygon.shader.modeFlags;
  499. __GLcoord *na, *nb, *nc, ea, eb, ec;
  500. GLuint msm_colorMaterialChange, flags=0;
  501. GLboolean needColor, needEye;
  502. __GLphongShader *phong = &gc->polygon.shader.phong;
  503. if (gc->polygon.shader.phong.face == __GL_FRONTFACE)
  504. msm_colorMaterialChange = gc->light.back.colorMaterialChange;
  505. else
  506. msm_colorMaterialChange = gc->light.back.colorMaterialChange;
  507. if ((gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE) &&
  508. msm_colorMaterialChange && (modeFlags & __GL_SHADE_RGB))
  509. flags |= __GL_PHONG_NEED_COLOR_XPOLATE;
  510. //Compute Invariant color if possible
  511. if (((!(flags & __GL_PHONG_NEED_COLOR_XPOLATE) ||
  512. !(msm_colorMaterialChange & (__GL_MATERIAL_AMBIENT |
  513. __GL_MATERIAL_EMISSIVE))) &&
  514. (modeFlags & __GL_SHADE_RGB)) &&
  515. !(flags & __GL_PHONG_NEED_EYE_XPOLATE))
  516. {
  517. ComputePhongInvarientRGBColor (gc);
  518. flags |= __GL_PHONG_INV_COLOR_VALID;
  519. }
  520. //Store the flags
  521. gc->polygon.shader.phong.flags |= flags;
  522. needColor = (gc->polygon.shader.phong.flags &
  523. __GL_PHONG_NEED_COLOR_XPOLATE);
  524. needEye = (gc->polygon.shader.phong.flags &
  525. __GL_PHONG_NEED_EYE_XPOLATE);
  526. #ifdef __GL_LINT
  527. ccw = ccw;
  528. #endif
  529. /*
  530. ** Recompute the area of the triangle after constraining the incoming
  531. ** coordinates to the subpixel precision. The viewport bias gives
  532. ** more precision (typically) than the subpixel precision. Because of
  533. ** this the algorithim below can fail to reject an essentially empty
  534. ** triangle and instead fill a large area. The scan converter fill
  535. ** routines (eg polydraw.c) don't have this trouble because of the
  536. ** very nature of edge walking.
  537. **
  538. ** NOTE: Notice that here as in other places, when the area calculation
  539. ** is done we are careful to do it as a series of subtractions followed by
  540. ** multiplications. This is done to guarantee that no overflow will
  541. ** occur (remember that the coordinates are biased by a potentially large
  542. ** number, and that multiplying two biased numbers will square the bias).
  543. */
  544. ax = __GL_FIX_PRECISION(a->window.x);
  545. bx = __GL_FIX_PRECISION(b->window.x);
  546. cx = __GL_FIX_PRECISION(c->window.x);
  547. ay = __GL_FIX_PRECISION(a->window.y);
  548. by = __GL_FIX_PRECISION(b->window.y);
  549. cy = __GL_FIX_PRECISION(c->window.y);
  550. area = (ax - cx) * (by - cy) - (bx - cx) * (ay - cy);
  551. if (area == zero) {
  552. return;
  553. }
  554. na = &a->normal;
  555. nb = &b->normal;
  556. nc = &c->normal;
  557. if (needColor)
  558. {
  559. ca = a->color;
  560. cb = b->color;
  561. cc = c->color;
  562. flatColor = gc->vertex.provoking->color;
  563. }
  564. if (needEye)
  565. {
  566. ea.x = a->eyeX; ea.y = a->eyeY; ea.z = a->eyeZ; ea.w = a->eyeW;
  567. eb.x = b->eyeX; eb.y = b->eyeY; eb.z = b->eyeZ; eb.w = b->eyeW;
  568. ec.x = c->eyeX; ec.y = c->eyeY; ec.z = c->eyeZ; ec.w = c->eyeW;
  569. }
  570. /*
  571. ** Construct plane equations for all of the parameters that are
  572. ** computed for the triangle: z, r, g, b, a, s, t, f
  573. */
  574. if (modeFlags & __GL_SHADE_DEPTH_ITER)
  575. {
  576. FindPlaneEquation(&zp, a, b, c, a->window.z, b->window.z,
  577. c->window.z);
  578. }
  579. #ifdef GL_WIN_specular_fog
  580. if (modeFlags & __GL_SHADE_COMPUTE_FOG)
  581. {
  582. FindPlaneEquation(&ezp, a, b, c, a->eyeZ, b->eyeZ, c->eyeZ);
  583. }
  584. else if (modeFlags & __GL_SHADE_INTERP_FOG)
  585. {
  586. __GLfloat aFog = 1.0f, bFog = 1.0f, cFog = 1.0f;
  587. if (gc->polygon.shader.modeFlags & __GL_SHADE_SPEC_FOG)
  588. {
  589. aFog = ComputeSpecValue (gc, a);
  590. bFog = ComputeSpecValue (gc, b);
  591. cFog = ComputeSpecValue (gc, c);
  592. }
  593. if (gc->polygon.shader.modeFlags & __GL_SHADE_SLOW_FOG)
  594. {
  595. aFog *= a->fog;
  596. bFog *= b->fog;
  597. cFog *= c->fog;
  598. }
  599. FindPlaneEquation(&fp, a, b, c, aFog, bFog, cFog);
  600. }
  601. #else //GL_WIN_specular_fog
  602. if (modeFlags & __GL_SHADE_SLOW_FOG)
  603. {
  604. FindPlaneEquation(&ezp, a, b, c, a->eyeZ, b->eyeZ, c->eyeZ);
  605. }
  606. else if (modeFlags & __GL_SHADE_INTERP_FOG)
  607. {
  608. FindPlaneEquation(&fp, a, b, c, a->fog, b->fog, c->fog);
  609. }
  610. #endif //GL_WIN_specular_fog
  611. if (modeFlags & __GL_SHADE_TEXTURE)
  612. {
  613. __GLfloat one = __glOne;
  614. __GLfloat aWInv = a->window.w;
  615. __GLfloat bWInv = b->window.w;
  616. __GLfloat cWInv = c->window.w;
  617. FindPlaneEquation(&qwp, a, b, c, a->texture.w * aWInv,
  618. b->texture.w * bWInv, c->texture.w * cWInv);
  619. FindPlaneEquation(&sp, a, b, c, a->texture.x * aWInv,
  620. b->texture.x * bWInv, c->texture.x * cWInv);
  621. FindPlaneEquation(&tp, a, b, c, a->texture.y * aWInv,
  622. b->texture.y * bWInv, c->texture.y * cWInv);
  623. }
  624. rgbMode = gc->modes.rgbMode;
  625. if (needColor)
  626. {
  627. if (modeFlags & __GL_SHADE_SMOOTH) {
  628. FindPlaneEquation(&rp, a, b, c, ca->r, cb->r, cc->r);
  629. if (rgbMode) {
  630. FindPlaneEquation(&gp, a, b, c, ca->g, cb->g, cc->g);
  631. FindPlaneEquation(&bp, a, b, c, ca->b, cb->b, cc->b);
  632. FindPlaneEquation(&ap, a, b, c, ca->a, cb->a, cc->a);
  633. }
  634. }
  635. }
  636. if (needEye)
  637. {
  638. FindPlaneEquation(&exp, a, b, c, ea.x, eb.x, ec.x);
  639. FindPlaneEquation(&eyp, a, b, c, ea.y, eb.y, ec.y);
  640. // FindPlaneEquation(&ezp, a, b, c, ea.z, eb.z, ec.z);
  641. FindPlaneEquation(&ewp, a, b, c, ea.w, eb.w, ec.w);
  642. }
  643. FindPlaneEquation(&nxp, a, b, c, na->x, nb->x, nc->x);
  644. FindPlaneEquation(&nyp, a, b, c, na->y, nb->y, nc->y);
  645. FindPlaneEquation(&nzp, a, b, c, na->z, nb->z, nc->z);
  646. /*
  647. ** Compute general form of the line equations for each of the
  648. ** edges of the triangle.
  649. */
  650. FindLineEqation(&tm.ab, a, b, c);
  651. FindLineEqation(&tm.bc, b, c, a);
  652. FindLineEqation(&tm.ca, c, a, b);
  653. /* Compute bounding box of the triangle */
  654. left = (GLint)a->window.x;
  655. if (b->window.x < left) left = (GLint)b->window.x;
  656. if (c->window.x < left) left = (GLint)c->window.x;
  657. right = (GLint)a->window.x;
  658. if (b->window.x > right) right = (GLint)b->window.x;
  659. if (c->window.x > right) right = (GLint)c->window.x;
  660. bottom = (GLint)a->window.y;
  661. if (b->window.y < bottom) bottom = (GLint)b->window.y;
  662. if (c->window.y < bottom) bottom = (GLint)c->window.y;
  663. top = (GLint)a->window.y;
  664. if (b->window.y > top) top = (GLint)b->window.y;
  665. if (c->window.y > top) top = (GLint)c->window.y;
  666. /* Bloat the bounding box when anti aliasing */
  667. left -= (GLint)FILTER_WIDTH;
  668. right += (GLint)FILTER_WIDTH;
  669. bottom -= (GLint)FILTER_HEIGHT;
  670. top += (GLint)FILTER_HEIGHT;
  671. /* Init coverage computations */
  672. samples = (gc->state.hints.polygonSmooth == GL_NICEST) ? 8 : 4;
  673. ComputeCoverageStuff(&cs, samples);
  674. /* Scan over the bounding box of the triangle */
  675. for (y = bottom; y <= top; y++)
  676. {
  677. cs.lastCoverageWasOne = GL_FALSE;
  678. for (x = left; x <= right; x++)
  679. {
  680. __GLfloat coverage;
  681. __GLfloat xs, ys;
  682. if (modeFlags & __GL_SHADE_STIPPLE)
  683. {
  684. /*
  685. ** Check the window coordinate against the stipple and
  686. ** and see if the pixel can be written
  687. */
  688. GLint row = y & 31;
  689. GLint col = x & 31;
  690. if ((gc->polygon.stipple[row] & (1<<col)) == 0)
  691. {
  692. /*
  693. ** Stipple bit is clear. Do not render this pixel
  694. ** of the triangle.
  695. */
  696. continue;
  697. }
  698. }
  699. xs = x + __glHalf; /* sample point is at pixel center */
  700. ys = y + __glHalf;
  701. coverage = Coverage(&tm, &xs, &ys, &cs);
  702. if (coverage != zero)
  703. {
  704. __GLfragment frag;
  705. /*
  706. ** Fill in fragment for rendering. First compute the color
  707. ** of the fragment.
  708. */
  709. phong->nTmp.x = FindP(&nxp, xs, ys);
  710. phong->nTmp.y = FindP(&nyp, xs, ys);
  711. phong->nTmp.z = FindP(&nzp, xs, ys);
  712. if (needColor)
  713. {
  714. phong->tmpColor.r = FindP(&rp, xs, ys);
  715. if (modeFlags & __GL_SHADE_RGB)
  716. {
  717. phong->tmpColor.g = FindP(&gp, xs, ys);
  718. phong->tmpColor.b = FindP(&bp, xs, ys);
  719. phong->tmpColor.a = FindP(&ap, xs, ys);
  720. }
  721. }
  722. if (needEye)
  723. {
  724. phong->eTmp.x = FindP(&exp, xs, ys);
  725. phong->eTmp.y = FindP(&eyp, xs, ys);
  726. phong->eTmp.z = FindP(&ezp, xs, ys);
  727. phong->eTmp.w = FindP(&ewp, xs, ys);
  728. }
  729. if (modeFlags & __GL_SHADE_RGB)
  730. (*gc->procs.phong.ComputeRGBColor) (gc, &(frag.color));
  731. else
  732. (*gc->procs.phong.ComputeCIColor) (gc, &(frag.color));
  733. /*
  734. ** Texture the fragment.
  735. */
  736. if (modeFlags & __GL_SHADE_TEXTURE) {
  737. __GLfloat qw, s, t, rho;
  738. qw = FindP(&qwp, xs, ys);
  739. s = FindP(&sp, xs, ys);
  740. t = FindP(&tp, xs, ys);
  741. rho = (*gc->procs.calcPolygonRho)(gc, sh, s, t, qw);
  742. if( qw == (__GLfloat) 0.0 )
  743. s = t = (__GLfloat) 0;
  744. else {
  745. s /= qw;
  746. t /= qw;
  747. }
  748. (*gc->procs.texture)(gc, &frag.color, s, t, rho);
  749. }
  750. /*
  751. ** Fog the resulting color.
  752. */
  753. if (modeFlags & __GL_SHADE_COMPUTE_FOG)
  754. {
  755. __GLfloat eyeZ = FindP(&ezp, xs, ys);
  756. __glFogFragmentSlow(gc, &frag, eyeZ);
  757. }
  758. else if (modeFlags & __GL_SHADE_INTERP_FOG)
  759. {
  760. __GLfloat fog = FindP(&fp, xs, ys);
  761. __glFogColorSlow(gc, &(frag.color), &(frag.color), fog);
  762. }
  763. /*
  764. ** Apply anti-aliasing effect
  765. */
  766. if (rgbMode) {
  767. frag.color.a *= coverage;
  768. } else {
  769. frag.color.r =
  770. __glBuildAntiAliasIndex(frag.color.r,
  771. coverage);
  772. }
  773. /*
  774. ** Finally, render the fragment.
  775. */
  776. frag.x = (GLint)xs;
  777. frag.y = (GLint)ys;
  778. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  779. frag.z = (__GLzValue)FindP(&zp, xs, ys);
  780. }
  781. (*gc->procs.store)(cfb, &frag);
  782. }
  783. }
  784. }
  785. #endif
  786. }
  787. #endif //GL_WIN_phong_shading