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