21e7ceef5af35a0a60880aee2ffd5c5cfa17ce85
[mesa.git] / src / mesa / swrast / s_tritemp.h
1 /* $Id: s_tritemp.h,v 1.1 2000/10/31 18:00:04 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2000 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_TEX - if defined, interpolate integer ST texcoords
41 * (fast, simple 2-D texture mapping)
42 * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords
43 * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
44 * INTERP_MULTITEX - if defined, interpolate N units of 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.0)
151 return;
152
153 if (area == 0.0F)
154 return;
155
156 /* check for very tiny triangle */
157 if (area * area < 0.0025F) /* square it to ensure positive value */
158 oneOverArea = 1.0F / 0.0025F; /* a close-enough value */
159 else
160 oneOverArea = 1.0F / area;
161 }
162
163 #ifndef DO_OCCLUSION_TEST
164 ctx->OcclusionResult = GL_TRUE;
165 #endif
166
167 /* Edge setup. For a triangle strip these could be reused... */
168 {
169 /* fixed point Y coordinates */
170 GLfixed vMin_fx = FloatToFixed(VB->Win.data[vMin][0] + 0.5F);
171 GLfixed vMin_fy = FloatToFixed(VB->Win.data[vMin][1] - 0.5F);
172 GLfixed vMid_fx = FloatToFixed(VB->Win.data[vMid][0] + 0.5F);
173 GLfixed vMid_fy = FloatToFixed(VB->Win.data[vMid][1] - 0.5F);
174 GLfixed vMax_fy = FloatToFixed(VB->Win.data[vMax][1] - 0.5F);
175
176 eMaj.fsy = FixedCeil(vMin_fy);
177 eMaj.lines = FixedToInt(vMax_fy + FIXED_ONE - FIXED_EPSILON - eMaj.fsy);
178 if (eMaj.lines > 0) {
179 GLfloat dxdy = eMaj.dx / eMaj.dy;
180 eMaj.fdxdy = SignedFloatToFixed(dxdy);
181 eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */
182 eMaj.fx0 = vMin_fx;
183 eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
184 }
185 else {
186 return; /*CULLED*/
187 }
188
189 eTop.fsy = FixedCeil(vMid_fy);
190 eTop.lines = FixedToInt(vMax_fy + FIXED_ONE - FIXED_EPSILON - eTop.fsy);
191 if (eTop.lines > 0) {
192 GLfloat dxdy = eTop.dx / eTop.dy;
193 eTop.fdxdy = SignedFloatToFixed(dxdy);
194 eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
195 eTop.fx0 = vMid_fx;
196 eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
197 }
198
199 eBot.fsy = FixedCeil(vMin_fy);
200 eBot.lines = FixedToInt(vMid_fy + FIXED_ONE - FIXED_EPSILON - eBot.fsy);
201 if (eBot.lines > 0) {
202 GLfloat dxdy = eBot.dx / eBot.dy;
203 eBot.fdxdy = SignedFloatToFixed(dxdy);
204 eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */
205 eBot.fx0 = vMin_fx;
206 eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
207 }
208 }
209
210 /*
211 * Conceptually, we view a triangle as two subtriangles
212 * separated by a perfectly horizontal line. The edge that is
213 * intersected by this line is one with maximal absolute dy; we
214 * call it a ``major'' edge. The other two edges are the
215 * ``top'' edge (for the upper subtriangle) and the ``bottom''
216 * edge (for the lower subtriangle). If either of these two
217 * edges is horizontal or very close to horizontal, the
218 * corresponding subtriangle might cover zero sample points;
219 * we take care to handle such cases, for performance as well
220 * as correctness.
221 *
222 * By stepping rasterization parameters along the major edge,
223 * we can avoid recomputing them at the discontinuity where
224 * the top and bottom edges meet. However, this forces us to
225 * be able to scan both left-to-right and right-to-left.
226 * Also, we must determine whether the major edge is at the
227 * left or right side of the triangle. We do this by
228 * computing the magnitude of the cross-product of the major
229 * and top edges. Since this magnitude depends on the sine of
230 * the angle between the two edges, its sign tells us whether
231 * we turn to the left or to the right when travelling along
232 * the major edge to the top edge, and from this we infer
233 * whether the major edge is on the left or the right.
234 *
235 * Serendipitously, this cross-product magnitude is also a
236 * value we need to compute the iteration parameter
237 * derivatives for the triangle, and it can be used to perform
238 * backface culling because its sign tells us whether the
239 * triangle is clockwise or counterclockwise. In this code we
240 * refer to it as ``area'' because it's also proportional to
241 * the pixel area of the triangle.
242 */
243
244 {
245 GLint ltor; /* true if scanning left-to-right */
246 #ifdef INTERP_Z
247 GLfloat dzdx, dzdy; GLfixed fdzdx;
248 GLfloat dfogdx, dfogdy; GLfixed fdfogdx;
249 #endif
250 #ifdef INTERP_RGB
251 GLfloat drdx, drdy; GLfixed fdrdx;
252 GLfloat dgdx, dgdy; GLfixed fdgdx;
253 GLfloat dbdx, dbdy; GLfixed fdbdx;
254 #endif
255 #ifdef INTERP_SPEC
256 GLfloat dsrdx, dsrdy; GLfixed fdsrdx;
257 GLfloat dsgdx, dsgdy; GLfixed fdsgdx;
258 GLfloat dsbdx, dsbdy; GLfixed fdsbdx;
259 #endif
260 #ifdef INTERP_ALPHA
261 GLfloat dadx, dady; GLfixed fdadx;
262 #endif
263 #ifdef INTERP_INDEX
264 GLfloat didx, didy; GLfixed fdidx;
265 #endif
266 #ifdef INTERP_INT_TEX
267 GLfloat dsdx, dsdy; GLfixed fdsdx;
268 GLfloat dtdx, dtdy; GLfixed fdtdx;
269 #endif
270 #ifdef INTERP_TEX
271 GLfloat dsdx, dsdy;
272 GLfloat dtdx, dtdy;
273 GLfloat dudx, dudy;
274 GLfloat dvdx, dvdy;
275 #endif
276 #ifdef INTERP_MULTITEX
277 GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS];
278 GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS];
279 GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS];
280 GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS];
281 #endif
282
283 /*
284 * Execute user-supplied setup code
285 */
286 #ifdef SETUP_CODE
287 SETUP_CODE
288 #endif
289
290 ltor = (oneOverArea < 0.0F);
291
292 /* compute d?/dx and d?/dy derivatives */
293 #ifdef INTERP_Z
294 {
295 GLfloat eMaj_dz, eBot_dz;
296 eMaj_dz = VB->Win.data[vMax][2] - VB->Win.data[vMin][2];
297 eBot_dz = VB->Win.data[vMid][2] - VB->Win.data[vMin][2];
298 dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
299 if (dzdx > maxDepth || dzdx < -maxDepth) {
300 /* probably a sliver triangle */
301 dzdx = 0.0;
302 dzdy = 0.0;
303 }
304 else {
305 dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
306 }
307 if (depthBits <= 16)
308 fdzdx = SignedFloatToFixed(dzdx);
309 else
310 fdzdx = (GLint) dzdx;
311 }
312 {
313 GLfloat eMaj_dfog, eBot_dfog;
314 eMaj_dfog = (VB->FogCoordPtr->data[vMax] - VB->FogCoordPtr->data[vMin]) * 256;
315 eBot_dfog = (VB->FogCoordPtr->data[vMid] - VB->FogCoordPtr->data[vMin]) * 256;
316 dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
317 fdfogdx = SignedFloatToFixed(dfogdx);
318 dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
319 }
320 #endif
321 #ifdef INTERP_RGB
322 {
323 GLfloat eMaj_dr, eBot_dr;
324 eMaj_dr = (GLint) VB->ColorPtr->data[vMax][0]
325 - (GLint) VB->ColorPtr->data[vMin][0];
326 eBot_dr = (GLint) VB->ColorPtr->data[vMid][0]
327 - (GLint) VB->ColorPtr->data[vMin][0];
328 drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
329 fdrdx = SignedFloatToFixed(drdx);
330 drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
331 }
332 {
333 GLfloat eMaj_dg, eBot_dg;
334 eMaj_dg = (GLint) VB->ColorPtr->data[vMax][1]
335 - (GLint) VB->ColorPtr->data[vMin][1];
336 eBot_dg = (GLint) VB->ColorPtr->data[vMid][1]
337 - (GLint) VB->ColorPtr->data[vMin][1];
338 dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
339 fdgdx = SignedFloatToFixed(dgdx);
340 dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
341 }
342 {
343 GLfloat eMaj_db, eBot_db;
344 eMaj_db = (GLint) VB->ColorPtr->data[vMax][2]
345 - (GLint) VB->ColorPtr->data[vMin][2];
346 eBot_db = (GLint) VB->ColorPtr->data[vMid][2]
347 - (GLint) VB->ColorPtr->data[vMin][2];
348 dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
349 fdbdx = SignedFloatToFixed(dbdx);
350 dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
351 }
352 #endif
353 #ifdef INTERP_SPEC
354 {
355 GLfloat eMaj_dsr, eBot_dsr;
356 eMaj_dsr = (GLint) VB->SecondaryColorPtr->data[vMax][0]
357 - (GLint) VB->SecondaryColorPtr->data[vMin][0];
358 eBot_dsr = (GLint) VB->SecondaryColorPtr->data[vMid][0]
359 - (GLint) VB->SecondaryColorPtr->data[vMin][0];
360 dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
361 fdsrdx = SignedFloatToFixed(dsrdx);
362 dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
363 }
364 {
365 GLfloat eMaj_dsg, eBot_dsg;
366 eMaj_dsg = (GLint) VB->SecondaryColorPtr->data[vMax][1]
367 - (GLint) VB->SecondaryColorPtr->data[vMin][1];
368 eBot_dsg = (GLint) VB->SecondaryColorPtr->data[vMid][1]
369 - (GLint) VB->SecondaryColorPtr->data[vMin][1];
370 dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
371 fdsgdx = SignedFloatToFixed(dsgdx);
372 dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
373 }
374 {
375 GLfloat eMaj_dsb, eBot_dsb;
376 eMaj_dsb = (GLint) VB->SecondaryColorPtr->data[vMax][2]
377 - (GLint) VB->SecondaryColorPtr->data[vMin][2];
378 eBot_dsb = (GLint) VB->SecondaryColorPtr->data[vMid][2]
379 - (GLint) VB->SecondaryColorPtr->data[vMin][2];
380 dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
381 fdsbdx = SignedFloatToFixed(dsbdx);
382 dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
383 }
384 #endif
385 #ifdef INTERP_ALPHA
386 {
387 GLfloat eMaj_da, eBot_da;
388 eMaj_da = (GLint) VB->ColorPtr->data[vMax][3]
389 - (GLint) VB->ColorPtr->data[vMin][3];
390 eBot_da = (GLint) VB->ColorPtr->data[vMid][3]
391 - (GLint) VB->ColorPtr->data[vMin][3];
392 dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
393 fdadx = SignedFloatToFixed(dadx);
394 dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
395 }
396 #endif
397 #ifdef INTERP_INDEX
398 {
399 GLfloat eMaj_di, eBot_di;
400 eMaj_di = (GLint) VB->IndexPtr->data[vMax]
401 - (GLint) VB->IndexPtr->data[vMin];
402 eBot_di = (GLint) VB->IndexPtr->data[vMid]
403 - (GLint) VB->IndexPtr->data[vMin];
404 didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
405 fdidx = SignedFloatToFixed(didx);
406 didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
407 }
408 #endif
409 #ifdef INTERP_INT_TEX
410 {
411 GLfloat eMaj_ds, eBot_ds;
412 eMaj_ds = (VB->TexCoordPtr[0]->data[vMax][0]
413 - VB->TexCoordPtr[0]->data[vMin][0]) * S_SCALE;
414 eBot_ds = (VB->TexCoordPtr[0]->data[vMid][0]
415 - VB->TexCoordPtr[0]->data[vMin][0]) * S_SCALE;
416 dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
417 fdsdx = SignedFloatToFixed(dsdx);
418 dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
419 }
420 if (VB->TexCoordPtr[0]->size > 1) {
421 GLfloat eMaj_dt, eBot_dt;
422 eMaj_dt = (VB->TexCoordPtr[0]->data[vMax][1]
423 - VB->TexCoordPtr[0]->data[vMin][1]) * T_SCALE;
424 eBot_dt = (VB->TexCoordPtr[0]->data[vMid][1]
425 - VB->TexCoordPtr[0]->data[vMin][1]) * T_SCALE;
426 dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
427 fdtdx = SignedFloatToFixed(dtdx);
428 dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
429 }
430 else {
431 dtdx = 0;
432 fdtdx = SignedFloatToFixed(dtdx);
433 dtdy = 0;
434 }
435
436 #endif
437 #ifdef INTERP_TEX
438 {
439 GLfloat wMax = VB->Win.data[vMax][3];
440 GLfloat wMin = VB->Win.data[vMin][3];
441 GLfloat wMid = VB->Win.data[vMid][3];
442 GLfloat eMaj_ds, eBot_ds;
443 GLfloat eMaj_dt, eBot_dt;
444 GLfloat eMaj_du, eBot_du;
445 GLfloat eMaj_dv, eBot_dv;
446
447 eMaj_ds = VB->TexCoordPtr[0]->data[vMax][0] * wMax
448 - VB->TexCoordPtr[0]->data[vMin][0] * wMin;
449 eBot_ds = VB->TexCoordPtr[0]->data[vMid][0] * wMid
450 - VB->TexCoordPtr[0]->data[vMin][0] * wMin;
451 dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
452 dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
453
454
455 if (VB->TexCoordPtr[0]->size > 1) {
456 eMaj_dt = VB->TexCoordPtr[0]->data[vMax][1] * wMax
457 - VB->TexCoordPtr[0]->data[vMin][1] * wMin;
458 eBot_dt = VB->TexCoordPtr[0]->data[vMid][1] * wMid
459 - VB->TexCoordPtr[0]->data[vMin][1] * wMin;
460 dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
461 dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
462 }
463 else {
464 dtdx = 0;
465 dtdy = 0;
466 }
467
468 if (VB->TexCoordPtr[0]->size > 2) {
469 eMaj_du = VB->TexCoordPtr[0]->data[vMax][2] * wMax
470 - VB->TexCoordPtr[0]->data[vMin][2] * wMin;
471 eBot_du = VB->TexCoordPtr[0]->data[vMid][2] * wMid
472 - VB->TexCoordPtr[0]->data[vMin][2] * wMin;
473 dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
474 dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
475 }
476 else {
477 dudx = 0;
478 dudy = 0;
479 }
480
481 if (VB->TexCoordPtr[0]->size > 3) {
482 eMaj_dv = VB->TexCoordPtr[0]->data[vMax][3] * wMax
483 - VB->TexCoordPtr[0]->data[vMin][3] * wMin;
484 eBot_dv = VB->TexCoordPtr[0]->data[vMid][3] * wMid
485 - VB->TexCoordPtr[0]->data[vMin][3] * wMin;
486 dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
487 dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
488 }
489 else {
490 eMaj_dv = wMax - wMin;
491 eBot_dv = wMid - wMin;
492 dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
493 dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
494 }
495 }
496 #endif
497 #ifdef INTERP_MULTITEX
498 {
499 GLfloat wMax = VB->Win.data[vMax][3];
500 GLfloat wMin = VB->Win.data[vMin][3];
501 GLfloat wMid = VB->Win.data[vMid][3];
502 GLuint u;
503 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
504 if (ctx->Texture.Unit[u].ReallyEnabled) {
505 GLfloat eMaj_ds, eBot_ds;
506 GLfloat eMaj_dt, eBot_dt;
507 GLfloat eMaj_du, eBot_du;
508 GLfloat eMaj_dv, eBot_dv;
509 eMaj_ds = VB->TexCoordPtr[u]->data[vMax][0] * wMax
510 - VB->TexCoordPtr[u]->data[vMin][0] * wMin;
511 eBot_ds = VB->TexCoordPtr[u]->data[vMid][0] * wMid
512 - VB->TexCoordPtr[u]->data[vMin][0] * wMin;
513 dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
514 dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
515
516 if (VB->TexCoordPtr[u]->size > 1) {
517 eMaj_dt = VB->TexCoordPtr[u]->data[vMax][1] * wMax
518 - VB->TexCoordPtr[u]->data[vMin][1] * wMin;
519 eBot_dt = VB->TexCoordPtr[u]->data[vMid][1] * wMid
520 - VB->TexCoordPtr[u]->data[vMin][1] * wMin;
521 dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
522 dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
523 }
524 else {
525 dtdx[u] = 0.0;
526 dtdy[u] = 0.0;
527 }
528
529 if (VB->TexCoordPtr[u]->size > 2) {
530 eMaj_du = VB->TexCoordPtr[u]->data[vMax][2] * wMax
531 - VB->TexCoordPtr[u]->data[vMin][2] * wMin;
532 eBot_du = VB->TexCoordPtr[u]->data[vMid][2] * wMid
533 - VB->TexCoordPtr[u]->data[vMin][2] * wMin;
534 dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
535 dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
536 }
537 else {
538 dudx[u] = 0.0;
539 dudy[u] = 0.0;
540 }
541
542 if (VB->TexCoordPtr[u]->size > 3) {
543 eMaj_dv = VB->TexCoordPtr[u]->data[vMax][3] * wMax
544 - VB->TexCoordPtr[u]->data[vMin][3] * wMin;
545 eBot_dv = VB->TexCoordPtr[u]->data[vMid][3] * wMid
546 - VB->TexCoordPtr[u]->data[vMin][3] * wMin;
547 dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
548 dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
549 }
550 else {
551 eMaj_dv = wMax - wMin;
552 eBot_dv = wMid - wMin;
553 dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
554 dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
555 }
556 }
557 }
558 }
559 #endif
560
561 /*
562 * We always sample at pixel centers. However, we avoid
563 * explicit half-pixel offsets in this code by incorporating
564 * the proper offset in each of x and y during the
565 * transformation to window coordinates.
566 *
567 * We also apply the usual rasterization rules to prevent
568 * cracks and overlaps. A pixel is considered inside a
569 * subtriangle if it meets all of four conditions: it is on or
570 * to the right of the left edge, strictly to the left of the
571 * right edge, on or below the top edge, and strictly above
572 * the bottom edge. (Some edges may be degenerate.)
573 *
574 * The following discussion assumes left-to-right scanning
575 * (that is, the major edge is on the left); the right-to-left
576 * case is a straightforward variation.
577 *
578 * We start by finding the half-integral y coordinate that is
579 * at or below the top of the triangle. This gives us the
580 * first scan line that could possibly contain pixels that are
581 * inside the triangle.
582 *
583 * Next we creep down the major edge until we reach that y,
584 * and compute the corresponding x coordinate on the edge.
585 * Then we find the half-integral x that lies on or just
586 * inside the edge. This is the first pixel that might lie in
587 * the interior of the triangle. (We won't know for sure
588 * until we check the other edges.)
589 *
590 * As we rasterize the triangle, we'll step down the major
591 * edge. For each step in y, we'll move an integer number
592 * of steps in x. There are two possible x step sizes, which
593 * we'll call the ``inner'' step (guaranteed to land on the
594 * edge or inside it) and the ``outer'' step (guaranteed to
595 * land on the edge or outside it). The inner and outer steps
596 * differ by one. During rasterization we maintain an error
597 * term that indicates our distance from the true edge, and
598 * select either the inner step or the outer step, whichever
599 * gets us to the first pixel that falls inside the triangle.
600 *
601 * All parameters (z, red, etc.) as well as the buffer
602 * addresses for color and z have inner and outer step values,
603 * so that we can increment them appropriately. This method
604 * eliminates the need to adjust parameters by creeping a
605 * sub-pixel amount into the triangle at each scanline.
606 */
607
608 {
609 int subTriangle;
610 GLfixed fx, fxLeftEdge, fxRightEdge, fdxLeftEdge, fdxRightEdge;
611 GLfixed fdxOuter;
612 int idxOuter;
613 float dxOuter;
614 GLfixed fError, fdError;
615 float adjx, adjy;
616 GLfixed fy;
617 int iy;
618 #ifdef PIXEL_ADDRESS
619 PIXEL_TYPE *pRow;
620 int dPRowOuter, dPRowInner; /* offset in bytes */
621 #endif
622 #ifdef INTERP_Z
623 # ifdef DEPTH_TYPE
624 DEPTH_TYPE *zRow;
625 int dZRowOuter, dZRowInner; /* offset in bytes */
626 # endif
627 GLfixed fz, fdzOuter, fdzInner;
628 GLfixed ffog, fdfogOuter, fdfogInner;
629 #endif
630 #ifdef INTERP_RGB
631 GLfixed fr, fdrOuter, fdrInner;
632 GLfixed fg, fdgOuter, fdgInner;
633 GLfixed fb, fdbOuter, fdbInner;
634 #endif
635 #ifdef INTERP_SPEC
636 GLfixed fsr, fdsrOuter, fdsrInner;
637 GLfixed fsg, fdsgOuter, fdsgInner;
638 GLfixed fsb, fdsbOuter, fdsbInner;
639 #endif
640 #ifdef INTERP_ALPHA
641 GLfixed fa, fdaOuter, fdaInner;
642 #endif
643 #ifdef INTERP_INDEX
644 GLfixed fi, fdiOuter, fdiInner;
645 #endif
646 #ifdef INTERP_INT_TEX
647 GLfixed fs, fdsOuter, fdsInner;
648 GLfixed ft, fdtOuter, fdtInner;
649 #endif
650 #ifdef INTERP_TEX
651 GLfloat sLeft, dsOuter, dsInner;
652 GLfloat tLeft, dtOuter, dtInner;
653 GLfloat uLeft, duOuter, duInner;
654 GLfloat vLeft, dvOuter, dvInner;
655 #endif
656 #ifdef INTERP_MULTITEX
657 GLfloat sLeft[MAX_TEXTURE_UNITS];
658 GLfloat tLeft[MAX_TEXTURE_UNITS];
659 GLfloat uLeft[MAX_TEXTURE_UNITS];
660 GLfloat vLeft[MAX_TEXTURE_UNITS];
661 GLfloat dsOuter[MAX_TEXTURE_UNITS], dsInner[MAX_TEXTURE_UNITS];
662 GLfloat dtOuter[MAX_TEXTURE_UNITS], dtInner[MAX_TEXTURE_UNITS];
663 GLfloat duOuter[MAX_TEXTURE_UNITS], duInner[MAX_TEXTURE_UNITS];
664 GLfloat dvOuter[MAX_TEXTURE_UNITS], dvInner[MAX_TEXTURE_UNITS];
665 #endif
666
667 for (subTriangle=0; subTriangle<=1; subTriangle++) {
668 EdgeT *eLeft, *eRight;
669 int setupLeft, setupRight;
670 int lines;
671
672 if (subTriangle==0) {
673 /* bottom half */
674 if (ltor) {
675 eLeft = &eMaj;
676 eRight = &eBot;
677 lines = eRight->lines;
678 setupLeft = 1;
679 setupRight = 1;
680 }
681 else {
682 eLeft = &eBot;
683 eRight = &eMaj;
684 lines = eLeft->lines;
685 setupLeft = 1;
686 setupRight = 1;
687 }
688 }
689 else {
690 /* top half */
691 if (ltor) {
692 eLeft = &eMaj;
693 eRight = &eTop;
694 lines = eRight->lines;
695 setupLeft = 0;
696 setupRight = 1;
697 }
698 else {
699 eLeft = &eTop;
700 eRight = &eMaj;
701 lines = eLeft->lines;
702 setupLeft = 1;
703 setupRight = 0;
704 }
705 if (lines == 0)
706 return;
707 }
708
709 if (setupLeft && eLeft->lines > 0) {
710 GLint vLower;
711 GLfixed fsx = eLeft->fsx;
712 fx = FixedCeil(fsx);
713 fError = fx - fsx - FIXED_ONE;
714 fxLeftEdge = fsx - FIXED_EPSILON;
715 fdxLeftEdge = eLeft->fdxdy;
716 fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
717 fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
718 idxOuter = FixedToInt(fdxOuter);
719 dxOuter = (float) idxOuter;
720 (void) dxOuter;
721
722 fy = eLeft->fsy;
723 iy = FixedToInt(fy);
724
725 adjx = (float)(fx - eLeft->fx0); /* SCALED! */
726 adjy = eLeft->adjy; /* SCALED! */
727 (void) adjx; /* silence compiler warnings */
728 (void) adjy; /* silence compiler warnings */
729
730 vLower = eLeft->v0;
731 (void) vLower; /* silence compiler warnings */
732
733 #ifdef PIXEL_ADDRESS
734 {
735 pRow = PIXEL_ADDRESS( FixedToInt(fxLeftEdge), iy );
736 dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
737 /* negative because Y=0 at bottom and increases upward */
738 }
739 #endif
740 /*
741 * Now we need the set of parameter (z, color, etc.) values at
742 * the point (fx, fy). This gives us properly-sampled parameter
743 * values that we can step from pixel to pixel. Furthermore,
744 * although we might have intermediate results that overflow
745 * the normal parameter range when we step temporarily outside
746 * the triangle, we shouldn't overflow or underflow for any
747 * pixel that's actually inside the triangle.
748 */
749
750 #ifdef INTERP_Z
751 {
752 GLfloat z0 = VB->Win.data[vLower][2] + ctx->PolygonZoffset;
753 if (depthBits <= 16) {
754 /* interpolate fixed-pt values */
755 GLfloat tmp = (z0 * FIXED_SCALE +
756 dzdx * adjx + dzdy * adjy) + FIXED_HALF;
757 if (tmp < MAX_GLUINT / 2)
758 fz = (GLfixed) tmp;
759 else
760 fz = MAX_GLUINT / 2;
761 fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx);
762 }
763 else {
764 /* interpolate depth values exactly */
765 fz = (GLint) (z0 + dzdx*FixedToFloat(adjx) + dzdy*FixedToFloat(adjy));
766 fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
767 }
768 # ifdef DEPTH_TYPE
769 zRow = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), iy);
770 dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
771 # endif
772 }
773 ffog = FloatToFixed(VB->FogCoordPtr->data[vLower]) * 256 + dfogdx * adjx + dfogdy * adjy + FIXED_HALF;
774 fdfogOuter = SignedFloatToFixed(dfogdy + dxOuter * dfogdx);
775 #endif
776 #ifdef INTERP_RGB
777 fr = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][0])
778 + drdx * adjx + drdy * adjy) + FIXED_HALF;
779 fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx);
780
781 fg = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][1])
782 + dgdx * adjx + dgdy * adjy) + FIXED_HALF;
783 fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx);
784
785 fb = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][2])
786 + dbdx * adjx + dbdy * adjy) + FIXED_HALF;
787 fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx);
788 #endif
789 #ifdef INTERP_SPEC
790 fsr = (GLfixed)(IntToFixed(VB->SecondaryColorPtr->data[vLower][0])
791 + dsrdx * adjx + dsrdy * adjy) + FIXED_HALF;
792 fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx);
793
794 fsg = (GLfixed)(IntToFixed(VB->SecondaryColorPtr->data[vLower][1])
795 + dsgdx * adjx + dsgdy * adjy) + FIXED_HALF;
796 fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx);
797
798 fsb = (GLfixed)(IntToFixed(VB->SecondaryColorPtr->data[vLower][2])
799 + dsbdx * adjx + dsbdy * adjy) + FIXED_HALF;
800 fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx);
801 #endif
802 #ifdef INTERP_ALPHA
803 fa = (GLfixed)(IntToFixed(VB->ColorPtr->data[vLower][3])
804 + dadx * adjx + dady * adjy) + FIXED_HALF;
805 fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx);
806 #endif
807 #ifdef INTERP_INDEX
808 fi = (GLfixed)(VB->IndexPtr->data[vLower] * FIXED_SCALE
809 + didx * adjx + didy * adjy) + FIXED_HALF;
810 fdiOuter = SignedFloatToFixed(didy + dxOuter * didx);
811 #endif
812 #ifdef INTERP_INT_TEX
813 {
814 GLfloat s0, t0;
815 s0 = VB->TexCoordPtr[0]->data[vLower][0] * S_SCALE;
816 fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx + dsdy * adjy) + FIXED_HALF;
817 fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx);
818
819 if (VB->TexCoordPtr[0]->size > 1)
820 {
821 t0 = VB->TexCoordPtr[0]->data[vLower][1] * T_SCALE;
822 ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + dtdy * adjy) + FIXED_HALF;
823 fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx);
824 }
825 else
826 {
827 t0 = 0;
828 ft = (GLfixed) FIXED_HALF;
829 fdtOuter = SignedFloatToFixed(0);
830 }
831 }
832 #endif
833 #ifdef INTERP_TEX
834 {
835 GLfloat invW = VB->Win.data[vLower][3];
836 GLfloat s0, t0, u0, v0;
837 s0 = VB->TexCoordPtr[0]->data[vLower][0] * invW;
838 sLeft = s0 + (dsdx * adjx + dsdy * adjy) * (1.0F/FIXED_SCALE);
839 dsOuter = dsdy + dxOuter * dsdx;
840 if (VB->TexCoordPtr[0]->size > 1) {
841 t0 = VB->TexCoordPtr[0]->data[vLower][1] * invW;
842 tLeft = t0 + (dtdx * adjx + dtdy * adjy) * (1.0F/FIXED_SCALE);
843 dtOuter = dtdy + dxOuter * dtdx;
844 }
845 else {
846 tLeft = dtOuter = 0.0;
847 }
848 if (VB->TexCoordPtr[0]->size > 2) {
849 u0 = VB->TexCoordPtr[0]->data[vLower][2] * invW;
850 uLeft = u0 + (dudx * adjx + dudy * adjy) * (1.0F/FIXED_SCALE);
851 duOuter = dudy + dxOuter * dudx;
852 }
853 else {
854 uLeft = duOuter = 0.0;
855 }
856 if (VB->TexCoordPtr[0]->size > 3) {
857 v0 = VB->TexCoordPtr[0]->data[vLower][3] * invW;
858 }
859 else {
860 v0 = invW;
861 }
862 vLeft = v0 + (dvdx * adjx + dvdy * adjy) * (1.0F/FIXED_SCALE);
863 dvOuter = dvdy + dxOuter * dvdx;
864 }
865 #endif
866 #ifdef INTERP_MULTITEX
867 {
868 GLuint u;
869 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
870 if (ctx->Texture.Unit[u].ReallyEnabled) {
871 GLfloat invW = VB->Win.data[vLower][3];
872 GLfloat s0, t0, u0, v0;
873 s0 = VB->TexCoordPtr[u]->data[vLower][0] * invW;
874 sLeft[u] = s0 + (dsdx[u] * adjx + dsdy[u] * adjy) * (1.0F/FIXED_SCALE);
875 dsOuter[u] = dsdy[u] + dxOuter * dsdx[u];
876 if (VB->TexCoordPtr[u]->size > 1) {
877 t0 = VB->TexCoordPtr[u]->data[vLower][1] * invW;
878 tLeft[u] = t0 + (dtdx[u] * adjx + dtdy[u] * adjy) * (1.0F/FIXED_SCALE);
879 dtOuter[u] = dtdy[u] + dxOuter * dtdx[u];
880 }
881 else {
882 tLeft[u] = dtOuter[u] = 0.0;
883 }
884 if (VB->TexCoordPtr[u]->size > 2) {
885 u0 = VB->TexCoordPtr[u]->data[vLower][2] * invW;
886 uLeft[u] = u0 + (dudx[u] * adjx + dudy[u] * adjy) * (1.0F/FIXED_SCALE);
887 duOuter[u] = dudy[u] + dxOuter * dudx[u];
888 }
889 else {
890 uLeft[u] = duOuter[u] = 0.0;
891 }
892 if (VB->TexCoordPtr[u]->size > 3) {
893 v0 = VB->TexCoordPtr[u]->data[vLower][3] * invW;
894 }
895 else {
896 v0 = invW;
897 }
898 vLeft[u] = v0 + (dvdx[u] * adjx + dvdy[u] * adjy) * (1.0F/FIXED_SCALE);
899 dvOuter[u] = dvdy[u] + dxOuter * dvdx[u];
900 }
901 }
902 }
903 #endif
904
905 } /*if setupLeft*/
906
907
908 if (setupRight && eRight->lines>0) {
909 fxRightEdge = eRight->fsx - FIXED_EPSILON;
910 fdxRightEdge = eRight->fdxdy;
911 }
912
913 if (lines==0) {
914 continue;
915 }
916
917
918 /* Rasterize setup */
919 #ifdef PIXEL_ADDRESS
920 dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
921 #endif
922 #ifdef INTERP_Z
923 # ifdef DEPTH_TYPE
924 dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
925 # endif
926 fdzInner = fdzOuter + fdzdx;
927 fdfogInner = fdfogOuter + fdfogdx;
928 #endif
929 #ifdef INTERP_RGB
930 fdrInner = fdrOuter + fdrdx;
931 fdgInner = fdgOuter + fdgdx;
932 fdbInner = fdbOuter + fdbdx;
933 #endif
934 #ifdef INTERP_SPEC
935 fdsrInner = fdsrOuter + fdsrdx;
936 fdsgInner = fdsgOuter + fdsgdx;
937 fdsbInner = fdsbOuter + fdsbdx;
938 #endif
939 #ifdef INTERP_ALPHA
940 fdaInner = fdaOuter + fdadx;
941 #endif
942 #ifdef INTERP_INDEX
943 fdiInner = fdiOuter + fdidx;
944 #endif
945 #ifdef INTERP_INT_TEX
946 fdsInner = fdsOuter + fdsdx;
947 fdtInner = fdtOuter + fdtdx;
948 #endif
949 #ifdef INTERP_TEX
950 dsInner = dsOuter + dsdx;
951 dtInner = dtOuter + dtdx;
952 duInner = duOuter + dudx;
953 dvInner = dvOuter + dvdx;
954 #endif
955 #ifdef INTERP_MULTITEX
956 {
957 GLuint u;
958 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
959 if (ctx->Texture.Unit[u].ReallyEnabled) {
960 dsInner[u] = dsOuter[u] + dsdx[u];
961 dtInner[u] = dtOuter[u] + dtdx[u];
962 duInner[u] = duOuter[u] + dudx[u];
963 dvInner[u] = dvOuter[u] + dvdx[u];
964 }
965 }
966 }
967 #endif
968
969 while (lines>0) {
970 /* initialize the span interpolants to the leftmost value */
971 /* ff = fixed-pt fragment */
972 GLint left = FixedToInt(fxLeftEdge);
973 GLint right = FixedToInt(fxRightEdge);
974 #ifdef INTERP_Z
975 GLfixed ffz = fz;
976 GLfixed fffog = ffog;
977 #endif
978 #ifdef INTERP_RGB
979 GLfixed ffr = fr, ffg = fg, ffb = fb;
980 #endif
981 #ifdef INTERP_SPEC
982 GLfixed ffsr = fsr, ffsg = fsg, ffsb = fsb;
983 #endif
984 #ifdef INTERP_ALPHA
985 GLfixed ffa = fa;
986 #endif
987 #ifdef INTERP_INDEX
988 GLfixed ffi = fi;
989 #endif
990 #ifdef INTERP_INT_TEX
991 GLfixed ffs = fs, fft = ft;
992 #endif
993 #ifdef INTERP_TEX
994 GLfloat ss = sLeft, tt = tLeft, uu = uLeft, vv = vLeft;
995 #endif
996 #ifdef INTERP_MULTITEX
997 GLfloat ss[MAX_TEXTURE_UNITS];
998 GLfloat tt[MAX_TEXTURE_UNITS];
999 GLfloat uu[MAX_TEXTURE_UNITS];
1000 GLfloat vv[MAX_TEXTURE_UNITS];
1001 {
1002 GLuint u;
1003 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1004 if (ctx->Texture.Unit[u].ReallyEnabled) {
1005 ss[u] = sLeft[u];
1006 tt[u] = tLeft[u];
1007 uu[u] = uLeft[u];
1008 vv[u] = vLeft[u];
1009 }
1010 }
1011 }
1012 #endif
1013
1014 #ifdef INTERP_RGB
1015 {
1016 /* need this to accomodate round-off errors */
1017 GLfixed ffrend = ffr+(right-left-1)*fdrdx;
1018 GLfixed ffgend = ffg+(right-left-1)*fdgdx;
1019 GLfixed ffbend = ffb+(right-left-1)*fdbdx;
1020 if (ffrend<0) ffr -= ffrend;
1021 if (ffgend<0) ffg -= ffgend;
1022 if (ffbend<0) ffb -= ffbend;
1023 if (ffr<0) ffr = 0;
1024 if (ffg<0) ffg = 0;
1025 if (ffb<0) ffb = 0;
1026 }
1027 #endif
1028 #ifdef INTERP_SPEC
1029 {
1030 /* need this to accomodate round-off errors */
1031 GLfixed ffsrend = ffsr+(right-left-1)*fdsrdx;
1032 GLfixed ffsgend = ffsg+(right-left-1)*fdsgdx;
1033 GLfixed ffsbend = ffsb+(right-left-1)*fdsbdx;
1034 if (ffsrend<0) ffsr -= ffsrend;
1035 if (ffsgend<0) ffsg -= ffsgend;
1036 if (ffsbend<0) ffsb -= ffsbend;
1037 if (ffsr<0) ffsr = 0;
1038 if (ffsg<0) ffsg = 0;
1039 if (ffsb<0) ffsb = 0;
1040 }
1041 #endif
1042 #ifdef INTERP_ALPHA
1043 {
1044 GLfixed ffaend = ffa+(right-left-1)*fdadx;
1045 if (ffaend<0) ffa -= ffaend;
1046 if (ffa<0) ffa = 0;
1047 }
1048 #endif
1049 #ifdef INTERP_INDEX
1050 if (ffi<0) ffi = 0;
1051 #endif
1052
1053 INNER_LOOP( left, right, iy );
1054
1055 /*
1056 * Advance to the next scan line. Compute the
1057 * new edge coordinates, and adjust the
1058 * pixel-center x coordinate so that it stays
1059 * on or inside the major edge.
1060 */
1061 iy++;
1062 lines--;
1063
1064 fxLeftEdge += fdxLeftEdge;
1065 fxRightEdge += fdxRightEdge;
1066
1067
1068 fError += fdError;
1069 if (fError >= 0) {
1070 fError -= FIXED_ONE;
1071 #ifdef PIXEL_ADDRESS
1072 pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowOuter);
1073 #endif
1074 #ifdef INTERP_Z
1075 # ifdef DEPTH_TYPE
1076 zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowOuter);
1077 # endif
1078 fz += fdzOuter;
1079 ffog += fdfogOuter;
1080 #endif
1081 #ifdef INTERP_RGB
1082 fr += fdrOuter; fg += fdgOuter; fb += fdbOuter;
1083 #endif
1084 #ifdef INTERP_SPEC
1085 fsr += fdsrOuter; fsg += fdsgOuter; fsb += fdsbOuter;
1086 #endif
1087 #ifdef INTERP_ALPHA
1088 fa += fdaOuter;
1089 #endif
1090 #ifdef INTERP_INDEX
1091 fi += fdiOuter;
1092 #endif
1093 #ifdef INTERP_INT_TEX
1094 fs += fdsOuter; ft += fdtOuter;
1095 #endif
1096 #ifdef INTERP_TEX
1097 sLeft += dsOuter;
1098 tLeft += dtOuter;
1099 uLeft += duOuter;
1100 vLeft += dvOuter;
1101 #endif
1102 #ifdef INTERP_MULTITEX
1103 {
1104 GLuint u;
1105 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1106 if (ctx->Texture.Unit[u].ReallyEnabled) {
1107 sLeft[u] += dsOuter[u];
1108 tLeft[u] += dtOuter[u];
1109 uLeft[u] += duOuter[u];
1110 vLeft[u] += dvOuter[u];
1111 }
1112 }
1113 }
1114 #endif
1115 }
1116 else {
1117 #ifdef PIXEL_ADDRESS
1118 pRow = (PIXEL_TYPE *) ((GLubyte*)pRow + dPRowInner);
1119 #endif
1120 #ifdef INTERP_Z
1121 # ifdef DEPTH_TYPE
1122 zRow = (DEPTH_TYPE *) ((GLubyte*)zRow + dZRowInner);
1123 # endif
1124 fz += fdzInner;
1125 ffog += fdfogInner;
1126 #endif
1127 #ifdef INTERP_RGB
1128 fr += fdrInner; fg += fdgInner; fb += fdbInner;
1129 #endif
1130 #ifdef INTERP_SPEC
1131 fsr += fdsrInner; fsg += fdsgInner; fsb += fdsbInner;
1132 #endif
1133 #ifdef INTERP_ALPHA
1134 fa += fdaInner;
1135 #endif
1136 #ifdef INTERP_INDEX
1137 fi += fdiInner;
1138 #endif
1139 #ifdef INTERP_INT_TEX
1140 fs += fdsInner; ft += fdtInner;
1141 #endif
1142 #ifdef INTERP_TEX
1143 sLeft += dsInner;
1144 tLeft += dtInner;
1145 uLeft += duInner;
1146 vLeft += dvInner;
1147 #endif
1148 #ifdef INTERP_MULTITEX
1149 {
1150 GLuint u;
1151 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
1152 if (ctx->Texture.Unit[u].ReallyEnabled) {
1153 sLeft[u] += dsInner[u];
1154 tLeft[u] += dtInner[u];
1155 uLeft[u] += duInner[u];
1156 vLeft[u] += dvInner[u];
1157 }
1158 }
1159 }
1160 #endif
1161 }
1162 } /*while lines>0*/
1163
1164 } /* for subTriangle */
1165
1166 }
1167 }
1168 }
1169
1170 #undef SETUP_CODE
1171 #undef INNER_LOOP
1172
1173 #undef PIXEL_TYPE
1174 #undef BYTES_PER_ROW
1175 #undef PIXEL_ADDRESS
1176
1177 #undef INTERP_Z
1178 #undef INTERP_RGB
1179 #undef INTERP_SPEC
1180 #undef INTERP_ALPHA
1181 #undef INTERP_INDEX
1182 #undef INTERP_INT_TEX
1183 #undef INTERP_TEX
1184 #undef INTERP_MULTITEX
1185
1186 #undef S_SCALE
1187 #undef T_SCALE
1188
1189 #undef FixedToDepth
1190
1191 #undef DO_OCCLUSION_TEST