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