source: trunk/src/opengl/mesa/tritemp.h@ 3721

Last change on this file since 3721 was 3597, checked in by jeroen, 25 years ago

* empty log message *

File size: 40.0 KB
Line 
1/* $Id: tritemp.h,v 1.2 2000-05-23 20:34:58 jeroen Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28/*
29 * Triangle Rasterizer Template
30 *
31 * This file is #include'd to generate custom triangle rasterizers.
32 *
33 * The following macros may be defined to indicate what auxillary information
34 * must be interplated across the triangle:
35 * INTERP_Z - if defined, interpolate Z values
36 * INTERP_RGB - if defined, interpolate RGB values
37 * INTERP_SPEC - if defined, interpolate specular RGB values
38 * INTERP_ALPHA - if defined, interpolate Alpha values
39 * INTERP_INDEX - if defined, interpolate color index values
40 * INTERP_INT_ST - if defined, interpolate integer ST texcoords
41 * (fast, simple 2-D texture mapping)
42 * INTERP_STUV - if defined, interpolate set 0 float STRQ texcoords
43 * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
44 * INTERP_STUV1 - if defined, interpolate set 1 float STRQ texcoords
45 *
46 * When one can directly address pixels in the color buffer the following
47 * macros can be defined and used to compute pixel addresses during
48 * rasterization (see pRow):
49 * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint)
50 * BYTES_PER_ROW - number of bytes per row in the color buffer
51 * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where
52 * Y==0 at bottom of screen and increases upward.
53 *
54 * Similarly, for direct depth buffer access, this type is used for depth
55 * buffer addressing:
56 * DEPTH_TYPE - either GLushort or GLuint
57 *
58 * Optionally, one may provide one-time setup code per triangle:
59 * SETUP_CODE - code which is to be executed once per triangle
60 *
61 * The following macro MUST be defined:
62 * INNER_LOOP(LEFT,RIGHT,Y) - code to write a span of pixels.
63 * Something like:
64 *
65 * for (x=LEFT; x<RIGHT;x++) {
66 * put_pixel(x,Y);
67 * // increment fixed point interpolants
68 * }
69 *
70 * This code was designed for the origin to be in the lower-left corner.
71 *
72 * Inspired by triangle rasterizer code written by Allen Akin. Thanks Allen!
73 */
74
75
76/*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
77{
78 typedef struct {
79 GLint v0, v1; /* Y(v0) < Y(v1) */
80 GLfloat dx; /* X(v1) - X(v0) */
81 GLfloat dy; /* Y(v1) - Y(v0) */
82 GLfixed fdxdy; /* dx/dy in fixed-point */
83 GLfixed fsx; /* first sample point x coord */
84 GLfixed fsy;
85 GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */
86 GLint lines; /* number of lines to be sampled on this edge */
87 GLfixed fx0; /* fixed pt X of lower endpoint */
88 } EdgeT;
89
90#ifdef INTERP_Z
91 const GLint depthBits = ctx->Visual->DepthBits;
92 const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
93 const GLfloat maxDepth = ctx->Visual->DepthMaxF;
94#define FixedToDepth(F) ((F) >> fixedToDepthShift)
95#endif
96 const struct vertex_buffer *VB = ctx->VB;
97 EdgeT eMaj, eTop, eBot;
98 GLfloat oneOverArea;
99 int vMin, vMid, vMax; /* vertex indexes: Y(vMin)<=Y(vMid)<=Y(vMax) */
100 float bf = ctx->backface_sign;
101
102 /* find the order of the 3 vertices along the Y axis */
103 {
104 GLfloat y0 = VB->Win.data[v0][1];
105 GLfloat y1 = VB->Win.data[v1][1];
106 GLfloat y2 = VB->Win.data[v2][1];
107
108 if (y0<=y1) {
109 if (y1<=y2) {
110 vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */
111 }
112 else if (y2<=y0) {
113 vMin = v2; vMid = v0; vMax = v1; /* y2<=y0<=y1 */
114 }
115 else {
116 vMin = v0; vMid = v2; vMax = v1; bf = -bf; /* y0<=y2<=y1 */
117 }
118 }
119 else {
120 if (y0<=y2) {
121 vMin = v1; vMid = v0; vMax = v2; bf = -bf; /* y1<=y0<=y2 */
122 }
123 else if (y2<=y1) {
124 vMin = v2; vMid = v1; vMax = v0; bf = -bf; /* y2<=y1<=y0 */
125 }
126 else {
127 vMin = v1; vMid = v2; vMax = v0; /* y1<=y2<=y0 */
128 }
129 }
130 }
131
132 /* vertex/edge relationship */
133 eMaj.v0 = vMin; eMaj.v1 = vMax; /*TODO: .v1's not needed */
134 eTop.v0 = vMid; eTop.v1 = vMax;
135 eBot.v0 = vMin; eBot.v1 = vMid;
136
137 /* compute deltas for each edge: vertex[v1] - vertex[v0] */
138 eMaj.dx = VB->Win.data[vMax][0] - VB->Win.data[vMin][0];
139 eMaj.dy = VB->Win.data[vMax][1] - VB->Win.data[vMin][1];
140 eTop.dx = VB->Win.data[vMax][0] - VB->Win.data[vMid][0];
141 eTop.dy = VB->Win.data[vMax][1] - VB->Win.data[vMid][1];
142 eBot.dx = VB->Win.data[vMid][0] - VB->Win.data[vMin][0];
143 eBot.dy = VB->Win.data[vMid][1] - VB->Win.data[vMin][1];
144
145 /* compute oneOverArea */
146 {
147 const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
148
149 /* Do backface culling */
150 if (area * bf < 0 || area * area < .0025)
151 return;
152
153 oneOverArea = 1.0F / area;
154 }
155
156 /* Edge setup. For a triangle strip these could be reused... */
157 {
158 /* fixed point Y coordinates */
159 GLfixed vMin_fx = FloatToFixed(VB->Win.data[vMin][0] + 0.5F);
160 GLfixed vMin_fy = FloatToFixed(VB->Win.data[vMin][1] - 0.5F);
161 GLfixed vMid_fx = FloatToFixed(VB->Win.data[vMid][0] + 0.5F);
162 GLfixed vMid_fy = FloatToFixed(VB->Win.data[vMid][1] - 0.5F);
163 GLfixed vMax_fy = FloatToFixed(VB->Win.data[vMax][1] - 0.5F);
164
165 eMaj.fsy = FixedCeil(vMin_fy);
166 eMaj.lines = FixedToInt(vMax_fy + FIXED_ONE - FIXED_EPSILON - eMaj.fsy);
167 if (eMaj.lines > 0) {
168 GLfloat dxdy = eMaj.dx / eMaj.dy;
169 eMaj.fdxdy = SignedFloatToFixed(dxdy);
170 eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */
171 eMaj.fx0 = vMin_fx;
172 eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
173 }
174 else {
175 return; /*CULLED*/
176 }
177
178 eTop.fsy = FixedCeil(vMid_fy);
179 eTop.lines = FixedToInt(vMax_fy + FIXED_ONE - FIXED_EPSILON - eTop.fsy);
180 if (eTop.lines > 0) {
181 GLfloat dxdy = eTop.dx / eTop.dy;
182 eTop.fdxdy = SignedFloatToFixed(dxdy);
183 eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
184 eTop.fx0 = vMid_fx;
185 eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
186 }
187
188 eBot.fsy = FixedCeil(vMin_fy);
189 eBot.lines = FixedToInt(vMid_fy + FIXED_ONE - FIXED_EPSILON - eBot.fsy);
190 if (eBot.lines > 0) {
191 GLfloat dxdy = eBot.dx / eBot.dy;
192 eBot.fdxdy = SignedFloatToFixed(dxdy);
193 eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */
194 eBot.fx0 = vMin_fx;
195 eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
196 }
197 }
198
199 /*
200 * Conceptually, we view a triangle as two subtriangles
201 * separated by a perfectly horizontal line. The edge that is
202 * intersected by this line is one with maximal absolute dy; we
203 * call it a ``major'' edge. The other two edges are the
204 * ``top'' edge (for the upper subtriangle) and the ``bottom''
205 * edge (for the lower subtriangle). If either of these two
206 * edges is horizontal or very close to horizontal, the
207 * corresponding subtriangle might cover zero sample points;
208 * we take care to handle such cases, for performance as well
209 * as correctness.
210 *
211 * By stepping rasterization parameters along the major edge,
212 * we can avoid recomputing them at the discontinuity where
213 * the top and bottom edges meet. However, this forces us to
214 * be able to scan both left-to-right and right-to-left.
215 * Also, we must determine whether the major edge is at the
216 * left or right side of the triangle. We do this by
217 * computing the magnitude of the cross-product of the major
218 * and top edges. Since this magnitude depends on the sine of
219 * the angle between the two edges, its sign tells us whether
220 * we turn to the left or to the right when travelling along
221 * the major edge to the top edge, and from this we infer
222 * whether the major edge is on the left or the right.
223 *
224 * Serendipitously, this cross-product magnitude is also a
225 * value we need to compute the iteration parameter
226 * derivatives for the triangle, and it can be used to perform
227 * backface culling because its sign tells us whether the
228 * triangle is clockwise or counterclockwise. In this code we
229 * refer to it as ``area'' because it's also proportional to
230 * the pixel area of the triangle.
231 */
232
233 {
234 GLint ltor; /* true if scanning left-to-right */
235#ifdef INTERP_Z
236 GLfloat dzdx, dzdy; GLfixed fdzdx;
237#endif
238#ifdef INTERP_RGB
239 GLfloat drdx, drdy; GLfixed fdrdx;
240 GLfloat dgdx, dgdy; GLfixed fdgdx;
241 GLfloat dbdx, dbdy; GLfixed fdbdx;
242#endif
243#ifdef INTERP_SPEC
244 GLfloat dsrdx, dsrdy; GLfixed fdsrdx;
245 GLfloat dsgdx, dsgdy; GLfixed fdsgdx;
246 GLfloat dsbdx, dsbdy; GLfixed fdsbdx;
247#endif
248#ifdef INTERP_ALPHA
249 GLfloat dadx, dady; GLfixed fdadx;
250#endif
251#ifdef INTERP_INDEX
252 GLfloat didx, didy; GLfixed fdidx;
253#endif
254#ifdef INTERP_INT_ST
255 GLfloat dsdx, dsdy; GLfixed fdsdx;
256 GLfloat dtdx, dtdy; GLfixed fdtdx;
257#endif
258#ifdef INTERP_STUV
259 GLfloat dsdx, dsdy;
260 GLfloat dtdx, dtdy;
261 GLfloat dudx, dudy;
262 GLfloat dvdx, dvdy;
263#endif
264#ifdef INTERP_STUV1
265 GLfloat ds1dx, ds1dy;
266 GLfloat dt1dx, dt1dy;
267 GLfloat du1dx, du1dy;
268 GLfloat dv1dx, dv1dy;
269#endif
270
271 /*
272 * Execute user-supplied setup code
273 */
274#ifdef SETUP_CODE
275 SETUP_CODE
276#endif
277
278 ltor = (oneOverArea < 0.0F);
279
280 /* compute d?/dx and d?/dy derivatives */
281#ifdef INTERP_Z
282 {
283 GLfloat eMaj_dz, eBot_dz;
284 eMaj_dz = VB->Win.data[vMax][2] - VB->Win.data[vMin][2];
285 eBot_dz = VB->Win.data[vMid][2] - VB->Win.data[vMin][2];
286 dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
287 if (dzdx > maxDepth || dzdx < -maxDepth) {
288 /* probably a sliver triangle */
289 dzdx = 0.0;
290 dzdy = 0.0;
291 }
292 else {
293 dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
294 }
295 if (depthBits <= 16)
296 fdzdx = SignedFloatToFixed(dzdx);
297 else
298 fdzdx = (GLint) dzdx;
299 }
300#endif
301#ifdef INTERP_RGB
302 {
303 GLfloat eMaj_dr, eBot_dr;
304 eMaj_dr = (GLint) VB->ColorPtr->data[vMax][0] - (GLint) VB->ColorPtr->data[vMin][0];
305 eBot_dr = (GLint) VB->ColorPtr->data[vMid][0] - (GLint) VB->ColorPtr->data[vMin][0];
306 drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
307 fdrdx = SignedFloatToFixed(drdx);
308 drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
309 }
310 {
311 GLfloat eMaj_dg, eBot_dg;
312 eMaj_dg = (GLint) VB->ColorPtr->data[vMax][1] - (GLint) VB->ColorPtr->data[vMin][1];
313 eBot_dg = (GLint) VB->ColorPtr->data[vMid][1] - (GLint) VB->ColorPtr->data[vMin][1];
314 dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
315 fdgdx = SignedFloatToFixed(dgdx);
316 dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
317 }
318 {
319 GLfloat eMaj_db, eBot_db;
320 eMaj_db = (GLint) VB->ColorPtr->data[vMax][2] - (GLint) VB->ColorPtr->data[vMin][2];
321 eBot_db = (GLint) VB->ColorPtr->data[vMid][2] - (GLint) VB->ColorPtr->data[vMin][2];
322 dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
323 fdbdx = SignedFloatToFixed(dbdx);
324 dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
325 }
326#endif
327#ifdef INTERP_SPEC
328 {
329 GLfloat eMaj_dsr, eBot_dsr;
330 eMaj_dsr = (GLint) VB->Specular[vMax][0] - (GLint) VB->Specular[vMin][0];
331 eBot_dsr = (GLint) VB->Specular[vMid][0] - (GLint) VB->Specular[vMin][0];
332 dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
333 fdsrdx = SignedFloatToFixed(dsrdx);
334 dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
335 }
336 {
337 GLfloat eMaj_dsg, eBot_dsg;
338 eMaj_dsg = (GLint) VB->Specular[vMax][1] - (GLint) VB->Specular[vMin][1];
339 eBot_dsg = (GLint) VB->Specular[vMid][1] - (GLint) VB->Specular[vMin][1];
340 dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
341 fdsgdx = SignedFloatToFixed(dsgdx);
342 dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
343 }
344 {
345 GLfloat eMaj_dsb, eBot_dsb;
346 eMaj_dsb = (GLint) VB->Specular[vMax][2] - (GLint) VB->Specular[vMin][2];
347 eBot_dsb = (GLint) VB->Specular[vMid][2] - (GLint) VB->Specular[vMin][2];
348 dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
349 fdsbdx = SignedFloatToFixed(dsbdx);
350 dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
351 }
352#endif
353#ifdef INTERP_ALPHA
354 {
355 GLfloat eMaj_da, eBot_da;
356 eMaj_da = (GLint) VB->ColorPtr->data[vMax][3] - (GLint) VB->ColorPtr->data[vMin][3];
357 eBot_da = (GLint) VB->ColorPtr->data[vMid][3] - (GLint) VB->ColorPtr->data[vMin][3];
358 dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
359 fdadx = SignedFloatToFixed(dadx);
360 dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
361 }
362#endif
363#ifdef INTERP_INDEX
364 {
365 GLfloat eMaj_di, eBot_di;
366 eMaj_di = (GLint) VB->IndexPtr->data[vMax] - (GLint) VB->IndexPtr->data[vMin];
367 eBot_di = (GLint) VB->IndexPtr->data[vMid] - (GLint) VB->IndexPtr->data[vMin];
368 didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
369 fdidx = SignedFloatToFixed(didx);
370 didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
371 }
372#endif
373#ifdef INTERP_INT_ST
374 {
375 GLfloat eMaj_ds, eBot_ds;
376 eMaj_ds = (VB->TexCoordPtr[0]->data[vMax][0] - VB->TexCoordPtr[0]->data[vMin][0]) * S_SCALE;
377 eBot_ds = (VB->TexCoordPtr[0]->data[vMid][0] - VB->TexCoordPtr[0]->data[vMin][0]) * S_SCALE;
378 dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
379 fdsdx = SignedFloatToFixed(dsdx);
380 dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
381 }
382 if (VB->TexCoordPtr[0]->size > 1)
383 {
384 GLfloat eMaj_dt, eBot_dt;
385 eMaj_dt = (VB->TexCoordPtr[0]->data[vMax][1] - VB->TexCoordPtr[0]->data[vMin][1]) * T_SCALE;
386 eBot_dt = (VB->TexCoordPtr[0]->data[vMid][1] - VB->TexCoordPtr[0]->data[vMin][1]) * T_SCALE;
387 dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
388 fdtdx = SignedFloatToFixed(dtdx);
389 dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
390 } else {
391 dtdx = 0;
392 fdtdx = SignedFloatToFixed(dtdx);
393 dtdy = 0;
394 }
395
396#endif
397#ifdef INTERP_STUV
398 {
399 GLfloat wMax = VB->Win.data[vMax][3];
400 GLfloat wMin = VB->Win.data[vMin][3];
401 GLfloat wMid = VB->Win.data[vMid][3];
402 GLfloat eMaj_ds, eBot_ds;
403 GLfloat eMaj_dt, eBot_dt;
404 GLfloat eMaj_du, eBot_du;
405 GLfloat eMaj_dv, eBot_dv;
406
407 eMaj_ds = VB->TexCoordPtr[0]->data[vMax][0]*wMax - VB->TexCoordPtr[0]->data[vMin][0]*wMin;
408 eBot_ds = VB->TexCoordPtr[0]->data[vMid][0]*wMid - VB->TexCoordPtr[0]->data[vMin][0]*wMin;
409 dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
410 dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
411
412
413 if (VB->TexCoordPtr[0]->size > 1)
414 {
415 eMaj_dt = VB->TexCoordPtr[0]->data[vMax][1]*wMax - VB->TexCoordPtr[0]->data[vMin][1]*wMin;
416 eBot_dt = VB->TexCoordPtr[0]->data[vMid][1]*wMid - VB->TexCoordPtr[0]->data[vMin][1]*wMin;
417 dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
418 dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
419 } else {
420 dtdx = 0;
421 dtdy = 0;
422 }
423
424 if (VB->TexCoordPtr[0]->size > 2)
425 {
426 eMaj_du = VB->TexCoordPtr[0]->data[vMax][2]*wMax - VB->TexCoordPtr[0]->data[vMin][2]*wMin;
427 eBot_du = VB->TexCoordPtr[0]->data[vMid][2]*wMid - VB->TexCoordPtr[0]->data[vMin][2]*wMin;
428 dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
429 dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
430 } else {
431 dudx = 0;
432 dudy = 0;
433 }
434
435 if (VB->TexCoordPtr[0]->size > 3)
436 {
437 eMaj_dv = VB->TexCoordPtr[0]->data[vMax][3]*wMax - VB->TexCoordPtr[0]->data[vMin][3]*wMin;
438 eBot_dv = VB->TexCoordPtr[0]->data[vMid][3]*wMid - VB->TexCoordPtr[0]->data[vMin][3]*wMin;
439 dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
440 dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
441 } else {
442 eMaj_dv = wMax - wMin;
443 eBot_dv = wMid - wMin;
444 dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
445 dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
446 }
447 }
448#endif
449#ifdef INTERP_STUV1
450 {
451 GLfloat wMax = VB->Win.data[vMax][3];
452 GLfloat wMin = VB->Win.data[vMin][3];
453 GLfloat wMid = VB->Win.data[vMid][3];
454 GLfloat eMaj_ds, eBot_ds;
455 GLfloat eMaj_dt, eBot_dt;
456 GLfloat eMaj_du, eBot_du;
457 GLfloat eMaj_dv, eBot_dv;
458 eMaj_ds = VB->TexCoordPtr[1]->data[vMax][0]*wMax - VB->TexCoordPtr[1]->data[vMin][0]*wMin;
459 eBot_ds = VB->TexCoordPtr[1]->data[vMid][0]*wMid - VB->TexCoordPtr[1]->data[vMin][0]*wMin;
460 ds1dx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
461 ds1dy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
462
463 if (VB->TexCoordPtr[1]->size > 1)
464 {
465 eMaj_dt = VB->TexCoordPtr[1]->data[vMax][1]*wMax - VB->TexCoordPtr[1]->data[vMin][1]*wMin;
466 eBot_dt = VB->TexCoordPtr[1]->data[vMid][1]*wMid - VB->TexCoordPtr[1]->data[vMin][1]*wMin;
467 dt1dx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
468 dt1dy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
469 }
470 else
471 {
472 dt1dx = 0;
473 dt1dy = 0;
474 }
475
476 if (VB->TexCoordPtr[1]->size > 2)
477 {
478 eMaj_du = VB->TexCoordPtr[1]->data[vMax][2]*wMax - VB->TexCoordPtr[1]->data[vMin][2]*wMin;
479 eBot_du = VB->TexCoordPtr[1]->data[vMid][2]*wMid - VB->TexCoordPtr[1]->data[vMin][2]*wMin;
480 du1dx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
481 du1dy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
482 }
483 else
484 {
485 du1dx = 0;
486 du1dy = 0;
487 }
488
489 if (VB->TexCoordPtr[1]->size > 3)
490 {
491 eMaj_dv = VB->TexCoordPtr[1]->data[vMax][3]*wMax - VB->TexCoordPtr[1]->data[vMin][3]*wMin;
492 eBot_dv = VB->TexCoordPtr[1]->data[vMid][3]*wMid - VB->TexCoordPtr[1]->data[vMin][3]*wMin;
493 dv1dx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
494 dv1dy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
495 }
496 else
497 {
498 eMaj_dv = wMax - wMin;
499 eBot_dv = wMid - wMin;
500 dv1dx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
501 dv1dy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
502 }
503 }
504#endif
505
506 /*
507 * We always sample at pixel centers. However, we avoid
508 * explicit half-pixel offsets in this code by incorporating
509 * the proper offset in each of x and y during the
510 * transformation to window coordinates.
511 *
512 * We also apply the usual rasterization rules to prevent
513 * cracks and overlaps. A pixel is considered inside a
514 * subtriangle if it meets all of four conditions: it is on or
515 * to the right of the left edge, strictly to the left of the
516 * right edge, on or below the top edge, and strictly above
517 * the bottom edge. (Some edges may be degenerate.)
518 *
519 * The following discussion assumes left-to-right scanning
520 * (that is, the major edge is on the left); the right-to-left
521 * case is a straightforward variation.
522 *
523 * We start by finding the half-integral y coordinate that is
524 * at or below the top of the triangle. This gives us the
525 * first scan line that could possibly contain pixels that are
526 * inside the triangle.
527 *
528 * Next we creep down the major edge until we reach that y,
529 * and compute the corresponding x coordinate on the edge.
530 * Then we find the half-integral x that lies on or just
531 * inside the edge. This is the first pixel that might lie in
532 * the interior of the triangle. (We won't know for sure
533 * until we check the other edges.)
534 *
535 * As we rasterize the triangle, we'll step down the major
536 * edge. For each step in y, we'll move an integer number
537 * of steps in x. There are two possible x step sizes, which
538 * we'll call the ``inner'' step (guaranteed to land on the
539 * edge or inside it) and the ``outer'' step (guaranteed to
540 * land on the edge or outside it). The inner and outer steps
541 * differ by one. During rasterization we maintain an error
542 * term that indicates our distance from the true edge, and
543 * select either the inner step or the outer step, whichever
544 * gets us to the first pixel that falls inside the triangle.
545 *
546 * All parameters (z, red, etc.) as well as the buffer
547 * addresses for color and z have inner and outer step values,
548 * so that we can increment them appropriately. This method
549 * eliminates the need to adjust parameters by creeping a
550 * sub-pixel amount into the triangle at each scanline.
551 */
552
553 {
554 int subTriangle;
555 GLfixed fx, fxLeftEdge, fxRightEdge, fdxLeftEdge, fdxRightEdge;
556 GLfixed fdxOuter;
557 int idxOuter;
558 float dxOuter;
559 GLfixed fError, fdError;
560 float adjx, adjy;
561 GLfixed fy;
562 int iy;
563#ifdef PIXEL_ADDRESS
564 PIXEL_TYPE *pRow;
565 int dPRowOuter, dPRowInner; /* offset in bytes */
566#endif
567#ifdef INTERP_Z
568# ifdef DEPTH_TYPE
569 DEPTH_TYPE *zRow;
570 int dZRowOuter, dZRowInner; /* offset in bytes */
571# endif
572 GLfixed fz, fdzOuter, fdzInner;
573#endif
574#ifdef INTERP_RGB
575 GLfixed fr, fdrOuter, fdrInner;
576 GLfixed fg, fdgOuter, fdgInner;
577 GLfixed fb, fdbOuter, fdbInner;
578#endif
579#ifdef INTERP_SPEC
580 GLfixed fsr, fdsrOuter, fdsrInner;
581 GLfixed fsg, fdsgOuter, fdsgInner;
582 GLfixed fsb, fdsbOuter, fdsbInner;
583#endif
584#ifdef INTERP_ALPHA
585 GLfixed fa, fdaOuter, fdaInner;
586#endif
587#ifdef INTERP_INDEX
588 GLfixed fi, fdiOuter, fdiInner;
589#endif
590#ifdef INTERP_INT_ST
591 GLfixed fs, fdsOuter, fdsInner;
592 GLfixed ft, fdtOuter, fdtInner;
593#endif
594#ifdef INTERP_STUV
595 GLfloat sLeft, dsOuter, dsInner;
596 GLfloat tLeft, dtOuter, dtInner;
597 GLfloat uLeft, duOuter, duInner;
598 GLfloat vLeft, dvOuter, dvInner;
599#endif
600#ifdef INTERP_STUV1
601 GLfloat s1Left, ds1Outer, ds1Inner;
602 GLfloat t1Left, dt1Outer, dt1Inner;
603 GLfloat u1Left, du1Outer, du1Inner;
604 GLfloat v1Left, dv1Outer, dv1Inner;
605#endif
606
607 for (subTriangle=0; subTriangle<=1; subTriangle++) {
608 EdgeT *eLeft, *eRight;
609 int setupLeft, setupRight;
610 int lines;
611
612 if (subTriangle==0) {
613 /* bottom half */
614 if (ltor) {
615 eLeft = &eMaj;
616 eRight = &eBot;
617 lines = eRight->lines;
618 setupLeft = 1;
619 setupRight = 1;
620 }
621 else {
622 eLeft = &eBot;
623 eRight = &eMaj;
624 lines = eLeft->lines;
625 setupLeft = 1;
626 setupRight = 1;
627 }
628 }
629 else {
630 /* top half */
631 if (ltor) {
632 eLeft = &eMaj;
633 eRight = &eTop;
634 lines = eRight->lines;
635 setupLeft = 0;
636 setupRight = 1;
637 }
638 else {
639 eLeft = &eTop;
640 eRight = &eMaj;
641 lines = eLeft->lines;
642 setupLeft = 1;
643 setupRight = 0;
644 }
645 if (lines==0) return;
646 }
647
648 if (setupLeft && eLeft->lines>0) {
649 GLint vLower;
650 GLfixed fsx = eLeft->fsx;
651 fx = FixedCeil(fsx);
652 fError = fx - fsx - FIXED_ONE;
653 fxLeftEdge = fsx - FIXED_EPSILON;
654 fdxLeftEdge = eLeft->fdxdy;
655 fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
656 fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
657 idxOuter = FixedToInt(fdxOuter);
658 dxOuter = (float) idxOuter;
659 (void) dxOuter;
660
661 fy = eLeft->fsy;
662 iy = FixedToInt(fy);
663
664 adjx = (float)(fx - eLeft->fx0); /* SCALED! */
665 adjy = eLeft->adjy; /* SCALED! */
666 (void) adjx; /* silence compiler warnings */
667 (void) adjy; /* silence compiler warnings */
668
669 vLower = eLeft->v0;
670 (void) vLower; /* silence compiler warnings */
671
672#ifdef PIXEL_ADDRESS
673 {
674 pRow = (PIXEL_TYPE *)PIXEL_ADDRESS( FixedToInt(fxLeftEdge), iy );
675 dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
676 /* negative because Y=0 at bottom and increases upward */
677 }
678#endif
679 /*
680 * Now we need the set of parameter (z, color, etc.) values at
681 * the point (fx, fy). This gives us properly-sampled parameter
682 * values that we can step from pixel to pixel. Furthermore,
683 * although we might have intermediate results that overflow
684 * the normal parameter range when we step temporarily outside
685 * the triangle, we shouldn't overflow or underflow for any
686 * pixel that's actually inside the triangle.
687 */
688
689#ifdef INTERP_Z
690 {
691 GLfloat z0 = VB->Win.data[vLower][2] + ctx->PolygonZoffset;
692 if (depthBits <= 16) {
693 /* interpolate fixed-pt values */
694 GLfloat tmp = (z0 * FIXED_SCALE + dzdx * adjx + dzdy * adjy) + FIXED_HALF;
695 if (tmp < MAX_GLUINT / 2)
696 fz = (GLfixed) tmp;
697 else
698 fz = MAX_GLUINT / 2;
699 fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx);
700 }
701 else {
702 /* interpolate depth values exactly */
703 fz = (GLint) (z0 + dzdx*FixedToFloat(adjx) + dzdy*FixedToFloat(adjy));
704 fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
705 }
706# ifdef DEPTH_TYPE
707 zRow = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), iy);
708 dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
709# endif
710 }
711#endif
712#ifdef INTERP_RGB
713 fr = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][0]) + drdx * adjx + drdy * adjy)
714 + FIXED_HALF;
715 fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx);
716
717 fg = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][1]) + dgdx * adjx + dgdy * adjy)
718 + FIXED_HALF;
719 fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx);
720
721 fb = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][2]) + dbdx * adjx + dbdy * adjy)
722 + FIXED_HALF;
723 fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx);
724#endif
725#ifdef INTERP_SPEC
726 fsr = (GLfixed)(IntToFixed(VB->Specular[vLower][0]) + dsrdx * adjx + dsrdy * adjy)
727 + FIXED_HALF;
728 fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx);
729
730 fsg = (GLfixed)(IntToFixed(VB->Specular[vLower][1]) + dsgdx * adjx + dsgdy * adjy)
731 + FIXED_HALF;
732 fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx);
733
734 fsb = (GLfixed)(IntToFixed(VB->Specular[vLower][2]) + dsbdx * adjx + dsbdy * adjy)
735 + FIXED_HALF;
736 fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx);
737#endif
738#ifdef INTERP_ALPHA
739 fa = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][3]) + dadx * adjx + dady * adjy)
740 + FIXED_HALF;
741 fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx);
742#endif
743#ifdef INTERP_INDEX
744 fi = (GLfixed)(VB->IndexPtr->data[vLower] * FIXED_SCALE + didx * adjx
745 + didy * adjy) + FIXED_HALF;
746 fdiOuter = SignedFloatToFixed(didy + dxOuter * didx);
747#endif
748#ifdef INTERP_INT_ST
749 {
750 GLfloat s0, t0;
751 s0 = VB->TexCoordPtr[0]->data[vLower][0] * S_SCALE;
752 fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx + dsdy * adjy) + FIXED_HALF;
753 fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx);
754
755 if (VB->TexCoordPtr[0]->size > 1)
756 {
757 t0 = VB->TexCoordPtr[0]->data[vLower][1] * T_SCALE;
758 ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + dtdy * adjy) + FIXED_HALF;
759 fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx);
760 }
761 else
762 {
763 t0 = 0;
764 ft = (GLfixed) FIXED_HALF;
765 fdtOuter = SignedFloatToFixed(0);
766 }
767 }
768#endif
769#ifdef INTERP_STUV
770 {
771 GLfloat invW = VB->Win.data[vLower][3];
772 GLfloat s0, t0, u0, v0;
773 s0 = VB->TexCoordPtr[0]->data[vLower][0] * invW;
774 sLeft = s0 + (dsdx * adjx + dsdy * adjy) * (1.0F/FIXED_SCALE);
775 dsOuter = dsdy + dxOuter * dsdx;
776 if (VB->TexCoordPtr[0]->size > 1)
777 {
778 t0 = VB->TexCoordPtr[0]->data[vLower][1] * invW;
779 tLeft = t0 + (dtdx * adjx + dtdy * adjy) * (1.0F/FIXED_SCALE);
780 dtOuter = dtdy + dxOuter * dtdx;
781 } else {
782 tLeft = dtOuter = 0;
783 }
784 if (VB->TexCoordPtr[0]->size > 2)
785 {
786 u0 = VB->TexCoordPtr[0]->data[vLower][2] * invW;
787 uLeft = u0 + (dudx * adjx + dudy * adjy) * (1.0F/FIXED_SCALE);
788 duOuter = dudy + dxOuter * dudx;
789 } else {
790 uLeft = duOuter = 0;
791 }
792 if (VB->TexCoordPtr[0]->size > 3)
793 {
794 v0 = VB->TexCoordPtr[0]->data[vLower][3] * invW;
795 } else {
796 v0 = invW;
797 }
798 vLeft = v0 + (dvdx * adjx + dvdy * adjy) * (1.0F/FIXED_SCALE);
799 dvOuter = dvdy + dxOuter * dvdx;
800 }
801#endif
802#ifdef INTERP_STUV1
803 {
804 GLfloat invW = VB->Win.data[vLower][3];
805 GLfloat s0, t0, u0, v0;
806 s0 = VB->TexCoordPtr[1]->data[vLower][0] * invW;
807 s1Left = s0 + (ds1dx * adjx + ds1dy * adjy) * (1.0F/FIXED_SCALE);
808 ds1Outer = ds1dy + dxOuter * ds1dx;
809 if (VB->TexCoordPtr[0]->size > 1)
810 {
811 t0 = VB->TexCoordPtr[1]->data[vLower][1] * invW;
812 t1Left = t0 + (dt1dx * adjx + dt1dy * adjy) * (1.0F/FIXED_SCALE);
813 dt1Outer = dt1dy + dxOuter * dt1dx;
814 } else {
815 t1Left = dt1Outer = 0;
816 }
817 if (VB->TexCoordPtr[0]->size > 2)
818 {
819 u0 = VB->TexCoordPtr[1]->data[vLower][2] * invW;
820 u1Left = u0 + (du1dx * adjx + du1dy * adjy) * (1.0F/FIXED_SCALE);
821 du1Outer = du1dy + dxOuter * du1dx;
822 } else {
823 u1Left = du1Outer = 0;
824 }
825 if (VB->TexCoordPtr[0]->size > 3)
826 {
827 v0 = VB->TexCoordPtr[1]->data[vLower][3] * invW;
828 } else {
829 v0 = invW;
830 }
831 v1Left = v0 + (dv1dx * adjx + dv1dy * adjy) * (1.0F/FIXED_SCALE);
832 dv1Outer = dv1dy + dxOuter * dv1dx;
833 }
834#endif
835
836 } /*if setupLeft*/
837
838
839 if (setupRight && eRight->lines>0) {
840 fxRightEdge = eRight->fsx - FIXED_EPSILON;
841 fdxRightEdge = eRight->fdxdy;
842 }
843
844 if (lines==0) {
845 continue;
846 }
847
848
849 /* Rasterize setup */
850#ifdef PIXEL_ADDRESS
851 dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
852#endif
853#ifdef INTERP_Z
854# ifdef DEPTH_TYPE
855 dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
856# endif
857 fdzInner = fdzOuter + fdzdx;
858#endif
859#ifdef INTERP_RGB
860 fdrInner = fdrOuter + fdrdx;
861 fdgInner = fdgOuter + fdgdx;
862 fdbInner = fdbOuter + fdbdx;
863#endif
864#ifdef INTERP_SPEC
865 fdsrInner = fdsrOuter + fdsrdx;
866 fdsgInner = fdsgOuter + fdsgdx;
867 fdsbInner = fdsbOuter + fdsbdx;
868#endif
869#ifdef INTERP_ALPHA
870 fdaInner = fdaOuter + fdadx;
871#endif
872#ifdef INTERP_INDEX
873 fdiInner = fdiOuter + fdidx;
874#endif
875#ifdef INTERP_INT_ST
876 fdsInner = fdsOuter + fdsdx;
877 fdtInner = fdtOuter + fdtdx;
878#endif
879#ifdef INTERP_STUV
880 dsInner = dsOuter + dsdx;
881 dtInner = dtOuter + dtdx;
882 duInner = duOuter + dudx;
883 dvInner = dvOuter + dvdx;
884#endif
885#ifdef INTERP_STUV1
886 ds1Inner = ds1Outer + ds1dx;
887 dt1Inner = dt1Outer + dt1dx;
888 du1Inner = du1Outer + du1dx;
889 dv1Inner = dv1Outer + dv1dx;
890#endif
891
892 while (lines>0) {
893 /* initialize the span interpolants to the leftmost value */
894 /* ff = fixed-pt fragment */
895#ifdef INTERP_Z
896 GLfixed ffz = fz;
897#endif
898#ifdef INTERP_RGB
899 GLfixed ffr = fr, ffg = fg, ffb = fb;
900#endif
901#ifdef INTERP_SPEC
902 GLfixed ffsr = fsr, ffsg = fsg, ffsb = fsb;
903#endif
904#ifdef INTERP_ALPHA
905 GLfixed ffa = fa;
906#endif
907#ifdef INTERP_INDEX
908 GLfixed ffi = fi;
909#endif
910#ifdef INTERP_INT_ST
911 GLfixed ffs = fs, fft = ft;
912#endif
913#ifdef INTERP_STUV
914 GLfloat ss = sLeft, tt = tLeft, uu = uLeft, vv = vLeft;
915#endif
916#ifdef INTERP_STUV1
917 GLfloat ss1 = s1Left, tt1 = t1Left, uu1 = u1Left, vv1 = v1Left;
918#endif
919 GLint left = FixedToInt(fxLeftEdge);
920 GLint right = FixedToInt(fxRightEdge);
921
922#ifdef INTERP_RGB
923 {
924 /* need this to accomodate round-off errors */
925 GLfixed ffrend = ffr+(right-left-1)*fdrdx;
926 GLfixed ffgend = ffg+(right-left-1)*fdgdx;
927 GLfixed ffbend = ffb+(right-left-1)*fdbdx;
928 if (ffrend<0) ffr -= ffrend;
929 if (ffgend<0) ffg -= ffgend;
930 if (ffbend<0) ffb -= ffbend;
931 if (ffr<0) ffr = 0;
932 if (ffg<0) ffg = 0;
933 if (ffb<0) ffb = 0;
934 }
935#endif
936#ifdef INTERP_SPEC
937 {
938 /* need this to accomodate round-off errors */
939 GLfixed ffsrend = ffsr+(right-left-1)*fdsrdx;
940 GLfixed ffsgend = ffsg+(right-left-1)*fdsgdx;
941 GLfixed ffsbend = ffsb+(right-left-1)*fdsbdx;
942 if (ffsrend<0) ffsr -= ffsrend;
943 if (ffsgend<0) ffsg -= ffsgend;
944 if (ffsbend<0) ffsb -= ffsbend;
945 if (ffsr<0) ffsr = 0;
946 if (ffsg<0) ffsg = 0;
947 if (ffsb<0) ffsb = 0;
948 }
949#endif
950#ifdef INTERP_ALPHA
951 {
952 GLfixed ffaend = ffa+(right-left-1)*fdadx;
953 if (ffaend<0) ffa -= ffaend;
954 if (ffa<0) ffa = 0;
955 }
956#endif
957#ifdef INTERP_INDEX
958 if (ffi<0) ffi = 0;
959#endif
960
961 INNER_LOOP( left, right, iy );
962
963 /*
964 * Advance to the next scan line. Compute the
965 * new edge coordinates, and adjust the
966 * pixel-center x coordinate so that it stays
967 * on or inside the major edge.
968 */
969 iy++;
970 lines--;
971
972 fxLeftEdge += fdxLeftEdge;
973 fxRightEdge += fdxRightEdge;
974
975
976 fError += fdError;
977 if (fError >= 0) {
978 fError -= FIXED_ONE;
979#ifdef PIXEL_ADDRESS
980 pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowOuter);
981#endif
982#ifdef INTERP_Z
983# ifdef DEPTH_TYPE
984 zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowOuter);
985# endif
986 fz += fdzOuter;
987#endif
988#ifdef INTERP_RGB
989 fr += fdrOuter; fg += fdgOuter; fb += fdbOuter;
990#endif
991#ifdef INTERP_SPEC
992 fsr += fdsrOuter; fsg += fdsgOuter; fsb += fdsbOuter;
993#endif
994#ifdef INTERP_ALPHA
995 fa += fdaOuter;
996#endif
997#ifdef INTERP_INDEX
998 fi += fdiOuter;
999#endif
1000#ifdef INTERP_INT_ST
1001 fs += fdsOuter; ft += fdtOuter;
1002#endif
1003#ifdef INTERP_STUV
1004 sLeft += dsOuter;
1005 tLeft += dtOuter;
1006 uLeft += duOuter;
1007 vLeft += dvOuter;
1008#endif
1009#ifdef INTERP_STUV1
1010 s1Left += ds1Outer;
1011 t1Left += dt1Outer;
1012 u1Left += du1Outer;
1013 v1Left += dv1Outer;
1014#endif
1015 }
1016 else {
1017#ifdef PIXEL_ADDRESS
1018 pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowInner);
1019#endif
1020#ifdef INTERP_Z
1021# ifdef DEPTH_TYPE
1022 zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowInner);
1023# endif
1024 fz += fdzInner;
1025#endif
1026#ifdef INTERP_RGB
1027 fr += fdrInner; fg += fdgInner; fb += fdbInner;
1028#endif
1029#ifdef INTERP_SPEC
1030 fsr += fdsrInner; fsg += fdsgInner; fsb += fdsbInner;
1031#endif
1032#ifdef INTERP_ALPHA
1033 fa += fdaInner;
1034#endif
1035#ifdef INTERP_INDEX
1036 fi += fdiInner;
1037#endif
1038#ifdef INTERP_INT_ST
1039 fs += fdsInner; ft += fdtInner;
1040#endif
1041#ifdef INTERP_STUV
1042 sLeft += dsInner;
1043 tLeft += dtInner;
1044 uLeft += duInner;
1045 vLeft += dvInner;
1046#endif
1047#ifdef INTERP_STUV1
1048 s1Left += ds1Inner;
1049 t1Left += dt1Inner;
1050 u1Left += du1Inner;
1051 v1Left += dv1Inner;
1052#endif
1053 }
1054 } /*while lines>0*/
1055
1056 } /* for subTriangle */
1057
1058 }
1059 }
1060}
1061
1062#undef SETUP_CODE
1063#undef INNER_LOOP
1064
1065#undef PIXEL_TYPE
1066#undef BYTES_PER_ROW
1067#undef PIXEL_ADDRESS
1068
1069#undef INTERP_Z
1070#undef INTERP_RGB
1071#undef INTERP_SPEC
1072#undef INTERP_ALPHA
1073#undef INTERP_INDEX
1074#undef INTERP_INT_ST
1075#undef INTERP_STUV
1076#undef INTERP_STUV1
1077
1078#undef S_SCALE
1079#undef T_SCALE
1080
1081#undef FixedToDepth
Note: See TracBrowser for help on using the repository browser.