Rev 57 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
57 | pj | 1 | /* $Id: s_tritemp.h,v 1.1 2003-02-28 11:49:43 pj 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 | /* $XFree86: xc/extras/Mesa/src/swrast/s_tritemp.h,v 1.2 2002/02/27 21:07:54 tsi Exp $ */ |
||
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 (req's INTERP_RGB) |
||
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_FLOAT_RGBA - if defined, interpolate RGBA with floating point |
||
47 | * INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point |
||
48 | * |
||
49 | * When one can directly address pixels in the color buffer the following |
||
50 | * macros can be defined and used to compute pixel addresses during |
||
51 | * rasterization (see pRow): |
||
52 | * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint) |
||
53 | * BYTES_PER_ROW - number of bytes per row in the color buffer |
||
54 | * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where |
||
55 | * Y==0 at bottom of screen and increases upward. |
||
56 | * |
||
57 | * Similarly, for direct depth buffer access, this type is used for depth |
||
58 | * buffer addressing: |
||
59 | * DEPTH_TYPE - either GLushort or GLuint |
||
60 | * |
||
61 | * Optionally, one may provide one-time setup code per triangle: |
||
62 | * SETUP_CODE - code which is to be executed once per triangle |
||
63 | * CLEANUP_CODE - code to execute at end of triangle |
||
64 | * |
||
65 | * The following macro MUST be defined: |
||
66 | * RENDER_SPAN(span) - code to write a span of pixels. |
||
67 | * |
||
68 | * This code was designed for the origin to be in the lower-left corner. |
||
69 | * |
||
70 | * Inspired by triangle rasterizer code written by Allen Akin. Thanks Allen! |
||
71 | */ |
||
72 | |||
73 | |||
74 | /* |
||
75 | * This is a bit of a hack, but it's a centralized place to enable floating- |
||
76 | * point color interpolation when GLchan is actually floating point. |
||
77 | */ |
||
78 | #if CHAN_TYPE == GL_FLOAT |
||
79 | |||
80 | #if defined(INTERP_RGB) |
||
81 | #undef INTERP_RGB |
||
82 | #undef INTERP_ALPHA |
||
83 | #define INTERP_FLOAT_RGBA |
||
84 | #endif |
||
85 | |||
86 | #if defined(INTERP_SPEC) |
||
87 | #undef INTERP_SPEC |
||
88 | #define INTERP_FLOAT_SPEC |
||
89 | #endif |
||
90 | |||
91 | #endif |
||
92 | |||
93 | |||
94 | /*void triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, SWvertex *v2 )*/ |
||
95 | { |
||
96 | typedef struct { |
||
97 | const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */ |
||
98 | GLfloat dx; /* X(v1) - X(v0) */ |
||
99 | GLfloat dy; /* Y(v1) - Y(v0) */ |
||
100 | GLfixed fdxdy; /* dx/dy in fixed-point */ |
||
101 | GLfixed fsx; /* first sample point x coord */ |
||
102 | GLfixed fsy; |
||
103 | GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */ |
||
104 | GLint lines; /* number of lines to be sampled on this edge */ |
||
105 | GLfixed fx0; /* fixed pt X of lower endpoint */ |
||
106 | } EdgeT; |
||
107 | |||
108 | #ifdef INTERP_Z |
||
109 | const GLint depthBits = ctx->Visual.depthBits; |
||
110 | const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; |
||
111 | const GLfloat maxDepth = ctx->DepthMaxF; |
||
112 | #define FixedToDepth(F) ((F) >> fixedToDepthShift) |
||
113 | #endif |
||
114 | EdgeT eMaj, eTop, eBot; |
||
115 | GLfloat oneOverArea; |
||
116 | const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */ |
||
117 | float bf = SWRAST_CONTEXT(ctx)->_backface_sign; |
||
118 | const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */ |
||
119 | GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; |
||
120 | |||
121 | struct sw_span span; |
||
122 | |||
123 | INIT_SPAN(span, GL_POLYGON, 0, 0, 0); |
||
124 | |||
125 | #ifdef INTERP_Z |
||
126 | (void) fixedToDepthShift; |
||
127 | #endif |
||
128 | |||
129 | /* |
||
130 | printf("%s()\n", __FUNCTION__); |
||
131 | printf(" %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]); |
||
132 | printf(" %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]); |
||
133 | printf(" %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]); |
||
134 | */ |
||
135 | |||
136 | /* Compute fixed point x,y coords w/ half-pixel offsets and snapping. |
||
137 | * And find the order of the 3 vertices along the Y axis. |
||
138 | */ |
||
139 | { |
||
140 | const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask; |
||
141 | const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask; |
||
142 | const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask; |
||
143 | |||
144 | if (fy0 <= fy1) { |
||
145 | if (fy1 <= fy2) { |
||
146 | /* y0 <= y1 <= y2 */ |
||
147 | vMin = v0; vMid = v1; vMax = v2; |
||
148 | vMin_fy = fy0; vMid_fy = fy1; vMax_fy = fy2; |
||
149 | } |
||
150 | else if (fy2 <= fy0) { |
||
151 | /* y2 <= y0 <= y1 */ |
||
152 | vMin = v2; vMid = v0; vMax = v1; |
||
153 | vMin_fy = fy2; vMid_fy = fy0; vMax_fy = fy1; |
||
154 | } |
||
155 | else { |
||
156 | /* y0 <= y2 <= y1 */ |
||
157 | vMin = v0; vMid = v2; vMax = v1; |
||
158 | vMin_fy = fy0; vMid_fy = fy2; vMax_fy = fy1; |
||
159 | bf = -bf; |
||
160 | } |
||
161 | } |
||
162 | else { |
||
163 | if (fy0 <= fy2) { |
||
164 | /* y1 <= y0 <= y2 */ |
||
165 | vMin = v1; vMid = v0; vMax = v2; |
||
166 | vMin_fy = fy1; vMid_fy = fy0; vMax_fy = fy2; |
||
167 | bf = -bf; |
||
168 | } |
||
169 | else if (fy2 <= fy1) { |
||
170 | /* y2 <= y1 <= y0 */ |
||
171 | vMin = v2; vMid = v1; vMax = v0; |
||
172 | vMin_fy = fy2; vMid_fy = fy1; vMax_fy = fy0; |
||
173 | bf = -bf; |
||
174 | } |
||
175 | else { |
||
176 | /* y1 <= y2 <= y0 */ |
||
177 | vMin = v1; vMid = v2; vMax = v0; |
||
178 | vMin_fy = fy1; vMid_fy = fy2; vMax_fy = fy0; |
||
179 | } |
||
180 | } |
||
181 | |||
182 | /* fixed point X coords */ |
||
183 | vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask; |
||
184 | vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask; |
||
185 | vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask; |
||
186 | } |
||
187 | |||
188 | /* vertex/edge relationship */ |
||
189 | eMaj.v0 = vMin; eMaj.v1 = vMax; /*TODO: .v1's not needed */ |
||
190 | eTop.v0 = vMid; eTop.v1 = vMax; |
||
191 | eBot.v0 = vMin; eBot.v1 = vMid; |
||
192 | |||
193 | /* compute deltas for each edge: vertex[upper] - vertex[lower] */ |
||
194 | eMaj.dx = FixedToFloat(vMax_fx - vMin_fx); |
||
195 | eMaj.dy = FixedToFloat(vMax_fy - vMin_fy); |
||
196 | eTop.dx = FixedToFloat(vMax_fx - vMid_fx); |
||
197 | eTop.dy = FixedToFloat(vMax_fy - vMid_fy); |
||
198 | eBot.dx = FixedToFloat(vMid_fx - vMin_fx); |
||
199 | eBot.dy = FixedToFloat(vMid_fy - vMin_fy); |
||
200 | |||
201 | /* compute area, oneOverArea and perform backface culling */ |
||
202 | { |
||
203 | const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; |
||
204 | |||
205 | /* Do backface culling */ |
||
206 | if (area * bf < 0.0) |
||
207 | return; |
||
208 | |||
209 | if (IS_INF_OR_NAN(area) || area == 0.0F) |
||
210 | return; |
||
211 | |||
212 | oneOverArea = 1.0F / area; |
||
213 | } |
||
214 | |||
215 | #ifndef DO_OCCLUSION_TEST |
||
216 | ctx->OcclusionResult = GL_TRUE; |
||
217 | #endif |
||
218 | span.facing = ctx->_Facing; /* for 2-sided stencil test */ |
||
219 | |||
220 | /* Edge setup. For a triangle strip these could be reused... */ |
||
221 | { |
||
222 | eMaj.fsy = FixedCeil(vMin_fy); |
||
223 | eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy)); |
||
224 | if (eMaj.lines > 0) { |
||
225 | GLfloat dxdy = eMaj.dx / eMaj.dy; |
||
226 | eMaj.fdxdy = SignedFloatToFixed(dxdy); |
||
227 | eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */ |
||
228 | eMaj.fx0 = vMin_fx; |
||
229 | eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy); |
||
230 | } |
||
231 | else { |
||
232 | return; /*CULLED*/ |
||
233 | } |
||
234 | |||
235 | eTop.fsy = FixedCeil(vMid_fy); |
||
236 | eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy)); |
||
237 | if (eTop.lines > 0) { |
||
238 | GLfloat dxdy = eTop.dx / eTop.dy; |
||
239 | eTop.fdxdy = SignedFloatToFixed(dxdy); |
||
240 | eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */ |
||
241 | eTop.fx0 = vMid_fx; |
||
242 | eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy); |
||
243 | } |
||
244 | |||
245 | eBot.fsy = FixedCeil(vMin_fy); |
||
246 | eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy)); |
||
247 | if (eBot.lines > 0) { |
||
248 | GLfloat dxdy = eBot.dx / eBot.dy; |
||
249 | eBot.fdxdy = SignedFloatToFixed(dxdy); |
||
250 | eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */ |
||
251 | eBot.fx0 = vMin_fx; |
||
252 | eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy); |
||
253 | } |
||
254 | } |
||
255 | |||
256 | /* |
||
257 | * Conceptually, we view a triangle as two subtriangles |
||
258 | * separated by a perfectly horizontal line. The edge that is |
||
259 | * intersected by this line is one with maximal absolute dy; we |
||
260 | * call it a ``major'' edge. The other two edges are the |
||
261 | * ``top'' edge (for the upper subtriangle) and the ``bottom'' |
||
262 | * edge (for the lower subtriangle). If either of these two |
||
263 | * edges is horizontal or very close to horizontal, the |
||
264 | * corresponding subtriangle might cover zero sample points; |
||
265 | * we take care to handle such cases, for performance as well |
||
266 | * as correctness. |
||
267 | * |
||
268 | * By stepping rasterization parameters along the major edge, |
||
269 | * we can avoid recomputing them at the discontinuity where |
||
270 | * the top and bottom edges meet. However, this forces us to |
||
271 | * be able to scan both left-to-right and right-to-left. |
||
272 | * Also, we must determine whether the major edge is at the |
||
273 | * left or right side of the triangle. We do this by |
||
274 | * computing the magnitude of the cross-product of the major |
||
275 | * and top edges. Since this magnitude depends on the sine of |
||
276 | * the angle between the two edges, its sign tells us whether |
||
277 | * we turn to the left or to the right when travelling along |
||
278 | * the major edge to the top edge, and from this we infer |
||
279 | * whether the major edge is on the left or the right. |
||
280 | * |
||
281 | * Serendipitously, this cross-product magnitude is also a |
||
282 | * value we need to compute the iteration parameter |
||
283 | * derivatives for the triangle, and it can be used to perform |
||
284 | * backface culling because its sign tells us whether the |
||
285 | * triangle is clockwise or counterclockwise. In this code we |
||
286 | * refer to it as ``area'' because it's also proportional to |
||
287 | * the pixel area of the triangle. |
||
288 | */ |
||
289 | |||
290 | { |
||
291 | GLint scan_from_left_to_right; /* true if scanning left-to-right */ |
||
292 | #ifdef INTERP_Z |
||
293 | GLfloat dzdx, dzdy; |
||
294 | #endif |
||
295 | #ifdef INTERP_FOG |
||
296 | GLfloat dfogdy; |
||
297 | #endif |
||
298 | #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA) |
||
299 | GLfloat drdx, drdy; |
||
300 | GLfloat dgdx, dgdy; |
||
301 | GLfloat dbdx, dbdy; |
||
302 | #endif |
||
303 | #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA) |
||
304 | GLfloat dadx, dady; |
||
305 | #endif |
||
306 | #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC) |
||
307 | GLfloat dsrdx, dsrdy; |
||
308 | GLfloat dsgdx, dsgdy; |
||
309 | GLfloat dsbdx, dsbdy; |
||
310 | #endif |
||
311 | #ifdef INTERP_INDEX |
||
312 | GLfloat didx, didy; |
||
313 | #endif |
||
314 | #ifdef INTERP_INT_TEX |
||
315 | GLfloat dsdx, dsdy; |
||
316 | GLfloat dtdx, dtdy; |
||
317 | #endif |
||
318 | #ifdef INTERP_TEX |
||
319 | GLfloat dsdx, dsdy; |
||
320 | GLfloat dtdx, dtdy; |
||
321 | GLfloat dudx, dudy; |
||
322 | GLfloat dvdx, dvdy; |
||
323 | #endif |
||
324 | #ifdef INTERP_MULTITEX |
||
325 | GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS]; |
||
326 | GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS]; |
||
327 | GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS]; |
||
328 | GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS]; |
||
329 | #endif |
||
330 | |||
331 | /* |
||
332 | * Execute user-supplied setup code |
||
333 | */ |
||
334 | #ifdef SETUP_CODE |
||
335 | SETUP_CODE |
||
336 | #endif |
||
337 | |||
338 | scan_from_left_to_right = (oneOverArea < 0.0F); |
||
339 | |||
340 | |||
341 | /* compute d?/dx and d?/dy derivatives */ |
||
342 | #ifdef INTERP_Z |
||
343 | span.interpMask |= SPAN_Z; |
||
344 | { |
||
345 | GLfloat eMaj_dz, eBot_dz; |
||
346 | eMaj_dz = vMax->win[2] - vMin->win[2]; |
||
347 | eBot_dz = vMid->win[2] - vMin->win[2]; |
||
348 | dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); |
||
349 | if (dzdx > maxDepth || dzdx < -maxDepth) { |
||
350 | /* probably a sliver triangle */ |
||
351 | dzdx = 0.0; |
||
352 | dzdy = 0.0; |
||
353 | } |
||
354 | else { |
||
355 | dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); |
||
356 | } |
||
357 | if (depthBits <= 16) |
||
358 | span.zStep = SignedFloatToFixed(dzdx); |
||
359 | else |
||
360 | span.zStep = (GLint) dzdx; |
||
361 | } |
||
362 | #endif |
||
363 | #ifdef INTERP_FOG |
||
364 | span.interpMask |= SPAN_FOG; |
||
365 | { |
||
366 | const GLfloat eMaj_dfog = vMax->fog - vMin->fog; |
||
367 | const GLfloat eBot_dfog = vMid->fog - vMin->fog; |
||
368 | span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); |
||
369 | dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); |
||
370 | } |
||
371 | #endif |
||
372 | #ifdef INTERP_RGB |
||
373 | span.interpMask |= SPAN_RGBA; |
||
374 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
375 | GLfloat eMaj_dr, eBot_dr; |
||
376 | GLfloat eMaj_dg, eBot_dg; |
||
377 | GLfloat eMaj_db, eBot_db; |
||
378 | # ifdef INTERP_ALPHA |
||
379 | GLfloat eMaj_da, eBot_da; |
||
380 | # endif |
||
381 | eMaj_dr = (GLfloat) ((GLint) vMax->color[RCOMP] - |
||
382 | (GLint) vMin->color[RCOMP]); |
||
383 | eBot_dr = (GLfloat) ((GLint) vMid->color[RCOMP] - |
||
384 | (GLint) vMin->color[RCOMP]); |
||
385 | drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); |
||
386 | span.redStep = SignedFloatToFixed(drdx); |
||
387 | drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); |
||
388 | eMaj_dg = (GLfloat) ((GLint) vMax->color[GCOMP] - |
||
389 | (GLint) vMin->color[GCOMP]); |
||
390 | eBot_dg = (GLfloat) ((GLint) vMid->color[GCOMP] - |
||
391 | (GLint) vMin->color[GCOMP]); |
||
392 | dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); |
||
393 | span.greenStep = SignedFloatToFixed(dgdx); |
||
394 | dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); |
||
395 | eMaj_db = (GLfloat) ((GLint) vMax->color[BCOMP] - |
||
396 | (GLint) vMin->color[BCOMP]); |
||
397 | eBot_db = (GLfloat) ((GLint) vMid->color[BCOMP] - |
||
398 | (GLint) vMin->color[BCOMP]); |
||
399 | dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); |
||
400 | span.blueStep = SignedFloatToFixed(dbdx); |
||
401 | dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); |
||
402 | # ifdef INTERP_ALPHA |
||
403 | eMaj_da = (GLfloat) ((GLint) vMax->color[ACOMP] - |
||
404 | (GLint) vMin->color[ACOMP]); |
||
405 | eBot_da = (GLfloat) ((GLint) vMid->color[ACOMP] - |
||
406 | (GLint) vMin->color[ACOMP]); |
||
407 | dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); |
||
408 | span.alphaStep = SignedFloatToFixed(dadx); |
||
409 | dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); |
||
410 | # endif |
||
411 | } |
||
412 | else { |
||
413 | ASSERT (ctx->Light.ShadeModel == GL_FLAT); |
||
414 | span.interpMask |= SPAN_FLAT; |
||
415 | drdx = drdy = 0.0F; |
||
416 | dgdx = dgdy = 0.0F; |
||
417 | dbdx = dbdy = 0.0F; |
||
418 | span.redStep = 0; |
||
419 | span.greenStep = 0; |
||
420 | span.blueStep = 0; |
||
421 | # ifdef INTERP_ALPHA |
||
422 | dadx = dady = 0.0F; |
||
423 | span.alphaStep = 0; |
||
424 | # endif |
||
425 | } |
||
426 | #endif |
||
427 | #ifdef INTERP_FLOAT_RGBA |
||
428 | span.interpMask |= SPAN_RGBA; |
||
429 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
430 | GLfloat eMaj_dr, eBot_dr; |
||
431 | GLfloat eMaj_dg, eBot_dg; |
||
432 | GLfloat eMaj_db, eBot_db; |
||
433 | GLfloat eMaj_da, eBot_da; |
||
434 | eMaj_dr = vMax->color[RCOMP] - vMin->color[RCOMP]; |
||
435 | eBot_dr = vMid->color[RCOMP] - vMin->color[RCOMP]; |
||
436 | drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); |
||
437 | span.redStep = drdx; |
||
438 | drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); |
||
439 | eMaj_dg = vMax->color[GCOMP] - vMin->color[GCOMP]; |
||
440 | eBot_dg = vMid->color[GCOMP] - vMin->color[GCOMP]; |
||
441 | dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); |
||
442 | span.greenStep = dgdx; |
||
443 | dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); |
||
444 | eMaj_db = vMax->color[BCOMP] - vMin->color[BCOMP]; |
||
445 | eBot_db = vMid->color[BCOMP] - vMin->color[BCOMP]; |
||
446 | dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); |
||
447 | span.blueStep = dbdx; |
||
448 | dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); |
||
449 | eMaj_da = vMax->color[ACOMP] - vMin->color[ACOMP]; |
||
450 | eBot_da = vMid->color[ACOMP] - vMin->color[ACOMP]; |
||
451 | dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); |
||
452 | span.alphaStep = dadx; |
||
453 | dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); |
||
454 | } |
||
455 | else { |
||
456 | drdx = drdy = span.redStep = 0.0F; |
||
457 | dgdx = dgdy = span.greenStep = 0.0F; |
||
458 | dbdx = dbdy = span.blueStep = 0.0F; |
||
459 | dadx = dady = span.alphaStep = 0.0F; |
||
460 | } |
||
461 | #endif |
||
462 | #ifdef INTERP_SPEC |
||
463 | span.interpMask |= SPAN_SPEC; |
||
464 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
465 | GLfloat eMaj_dsr, eBot_dsr; |
||
466 | GLfloat eMaj_dsg, eBot_dsg; |
||
467 | GLfloat eMaj_dsb, eBot_dsb; |
||
468 | eMaj_dsr = (GLfloat) ((GLint) vMax->specular[RCOMP] - |
||
469 | (GLint) vMin->specular[RCOMP]); |
||
470 | eBot_dsr = (GLfloat) ((GLint) vMid->specular[RCOMP] - |
||
471 | (GLint) vMin->specular[RCOMP]); |
||
472 | dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); |
||
473 | span.specRedStep = SignedFloatToFixed(dsrdx); |
||
474 | dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); |
||
475 | eMaj_dsg = (GLfloat) ((GLint) vMax->specular[GCOMP] - |
||
476 | (GLint) vMin->specular[GCOMP]); |
||
477 | eBot_dsg = (GLfloat) ((GLint) vMid->specular[GCOMP] - |
||
478 | (GLint) vMin->specular[GCOMP]); |
||
479 | dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); |
||
480 | span.specGreenStep = SignedFloatToFixed(dsgdx); |
||
481 | dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); |
||
482 | eMaj_dsb = (GLfloat) ((GLint) vMax->specular[BCOMP] - |
||
483 | (GLint) vMin->specular[BCOMP]); |
||
484 | eBot_dsb = (GLfloat) ((GLint) vMid->specular[BCOMP] - |
||
485 | (GLint) vMin->specular[BCOMP]); |
||
486 | dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); |
||
487 | span.specBlueStep = SignedFloatToFixed(dsbdx); |
||
488 | dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); |
||
489 | } |
||
490 | else { |
||
491 | dsrdx = dsrdy = 0.0F; |
||
492 | dsgdx = dsgdy = 0.0F; |
||
493 | dsbdx = dsbdy = 0.0F; |
||
494 | span.specRedStep = 0; |
||
495 | span.specGreenStep = 0; |
||
496 | span.specBlueStep = 0; |
||
497 | } |
||
498 | #endif |
||
499 | #ifdef INTERP_FLOAT_SPEC |
||
500 | span.interpMask |= SPAN_SPEC; |
||
501 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
502 | GLfloat eMaj_dsr, eBot_dsr; |
||
503 | GLfloat eMaj_dsg, eBot_dsg; |
||
504 | GLfloat eMaj_dsb, eBot_dsb; |
||
505 | eMaj_dsr = vMax->specular[RCOMP] - vMin->specular[RCOMP]; |
||
506 | eBot_dsr = vMid->specular[RCOMP] - vMin->specular[RCOMP]; |
||
507 | dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); |
||
508 | span.specRedStep = dsrdx; |
||
509 | dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); |
||
510 | eMaj_dsg = vMax->specular[GCOMP] - vMin->specular[GCOMP]; |
||
511 | eBot_dsg = vMid->specular[GCOMP] - vMin->specular[GCOMP]; |
||
512 | dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); |
||
513 | span.specGreenStep = dsgdx; |
||
514 | dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); |
||
515 | eMaj_dsb = vMax->specular[BCOMP] - vMin->specular[BCOMP]; |
||
516 | eBot_dsb = vMid->specular[BCOMP] - vMin->specular[BCOMP]; |
||
517 | dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); |
||
518 | span.specBlueStep = dsbdx; |
||
519 | dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); |
||
520 | } |
||
521 | else { |
||
522 | dsrdx = dsrdy = span.specRedStep = 0; |
||
523 | dsgdx = dsgdy = span.specGreenStep = 0; |
||
524 | dsbdx = dsbdy = span.specBlueStep = 0; |
||
525 | } |
||
526 | #endif |
||
527 | #ifdef INTERP_INDEX |
||
528 | span.interpMask |= SPAN_INDEX; |
||
529 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
530 | GLfloat eMaj_di, eBot_di; |
||
531 | eMaj_di = (GLfloat) ((GLint) vMax->index - (GLint) vMin->index); |
||
532 | eBot_di = (GLfloat) ((GLint) vMid->index - (GLint) vMin->index); |
||
533 | didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di); |
||
534 | span.indexStep = SignedFloatToFixed(didx); |
||
535 | didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx); |
||
536 | } |
||
537 | else { |
||
538 | span.interpMask |= SPAN_FLAT; |
||
539 | didx = didy = 0.0F; |
||
540 | span.indexStep = 0; |
||
541 | } |
||
542 | #endif |
||
543 | #ifdef INTERP_INT_TEX |
||
544 | span.interpMask |= SPAN_INT_TEXTURE; |
||
545 | { |
||
546 | GLfloat eMaj_ds, eBot_ds; |
||
547 | eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; |
||
548 | eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; |
||
549 | dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); |
||
550 | span.intTexStep[0] = SignedFloatToFixed(dsdx); |
||
551 | dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); |
||
552 | } |
||
553 | { |
||
554 | GLfloat eMaj_dt, eBot_dt; |
||
555 | eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; |
||
556 | eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; |
||
557 | dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); |
||
558 | span.intTexStep[1] = SignedFloatToFixed(dtdx); |
||
559 | dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); |
||
560 | } |
||
561 | |||
562 | #endif |
||
563 | #ifdef INTERP_TEX |
||
564 | span.interpMask |= SPAN_TEXTURE; |
||
565 | { |
||
566 | GLfloat wMax = vMax->win[3]; |
||
567 | GLfloat wMin = vMin->win[3]; |
||
568 | GLfloat wMid = vMid->win[3]; |
||
569 | GLfloat eMaj_ds, eBot_ds; |
||
570 | GLfloat eMaj_dt, eBot_dt; |
||
571 | GLfloat eMaj_du, eBot_du; |
||
572 | GLfloat eMaj_dv, eBot_dv; |
||
573 | |||
574 | eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin; |
||
575 | eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin; |
||
576 | dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); |
||
577 | dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); |
||
578 | span.texStepX[0][0] = dsdx; |
||
579 | span.texStepY[0][0] = dsdy; |
||
580 | |||
581 | eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin; |
||
582 | eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin; |
||
583 | dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); |
||
584 | dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); |
||
585 | span.texStepX[0][1] = dtdx; |
||
586 | span.texStepY[0][1] = dtdy; |
||
587 | |||
588 | eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin; |
||
589 | eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin; |
||
590 | dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); |
||
591 | dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); |
||
592 | span.texStepX[0][2] = dudx; |
||
593 | span.texStepY[0][2] = dudy; |
||
594 | |||
595 | eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin; |
||
596 | eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin; |
||
597 | dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); |
||
598 | dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); |
||
599 | span.texStepX[0][3] = dvdx; |
||
600 | span.texStepY[0][3] = dvdy; |
||
601 | } |
||
602 | #endif |
||
603 | #ifdef INTERP_MULTITEX |
||
604 | span.interpMask |= SPAN_TEXTURE; |
||
605 | { |
||
606 | GLfloat wMax = vMax->win[3]; |
||
607 | GLfloat wMin = vMin->win[3]; |
||
608 | GLfloat wMid = vMid->win[3]; |
||
609 | GLuint u; |
||
610 | for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { |
||
611 | if (ctx->Texture.Unit[u]._ReallyEnabled) { |
||
612 | GLfloat eMaj_ds, eBot_ds; |
||
613 | GLfloat eMaj_dt, eBot_dt; |
||
614 | GLfloat eMaj_du, eBot_du; |
||
615 | GLfloat eMaj_dv, eBot_dv; |
||
616 | eMaj_ds = vMax->texcoord[u][0] * wMax |
||
617 | - vMin->texcoord[u][0] * wMin; |
||
618 | eBot_ds = vMid->texcoord[u][0] * wMid |
||
619 | - vMin->texcoord[u][0] * wMin; |
||
620 | dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); |
||
621 | dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); |
||
622 | span.texStepX[u][0] = dsdx[u]; |
||
623 | span.texStepY[u][0] = dsdy[u]; |
||
624 | |||
625 | eMaj_dt = vMax->texcoord[u][1] * wMax |
||
626 | - vMin->texcoord[u][1] * wMin; |
||
627 | eBot_dt = vMid->texcoord[u][1] * wMid |
||
628 | - vMin->texcoord[u][1] * wMin; |
||
629 | dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); |
||
630 | dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); |
||
631 | span.texStepX[u][1] = dtdx[u]; |
||
632 | span.texStepY[u][1] = dtdy[u]; |
||
633 | |||
634 | eMaj_du = vMax->texcoord[u][2] * wMax |
||
635 | - vMin->texcoord[u][2] * wMin; |
||
636 | eBot_du = vMid->texcoord[u][2] * wMid |
||
637 | - vMin->texcoord[u][2] * wMin; |
||
638 | dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); |
||
639 | dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); |
||
640 | span.texStepX[u][2] = dudx[u]; |
||
641 | span.texStepY[u][2] = dudy[u]; |
||
642 | |||
643 | eMaj_dv = vMax->texcoord[u][3] * wMax |
||
644 | - vMin->texcoord[u][3] * wMin; |
||
645 | eBot_dv = vMid->texcoord[u][3] * wMid |
||
646 | - vMin->texcoord[u][3] * wMin; |
||
647 | dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); |
||
648 | dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); |
||
649 | span.texStepX[u][3] = dvdx[u]; |
||
650 | span.texStepY[u][3] = dvdy[u]; |
||
651 | } |
||
652 | } |
||
653 | } |
||
654 | #endif |
||
655 | |||
656 | /* |
||
657 | * We always sample at pixel centers. However, we avoid |
||
658 | * explicit half-pixel offsets in this code by incorporating |
||
659 | * the proper offset in each of x and y during the |
||
660 | * transformation to window coordinates. |
||
661 | * |
||
662 | * We also apply the usual rasterization rules to prevent |
||
663 | * cracks and overlaps. A pixel is considered inside a |
||
664 | * subtriangle if it meets all of four conditions: it is on or |
||
665 | * to the right of the left edge, strictly to the left of the |
||
666 | * right edge, on or below the top edge, and strictly above |
||
667 | * the bottom edge. (Some edges may be degenerate.) |
||
668 | * |
||
669 | * The following discussion assumes left-to-right scanning |
||
670 | * (that is, the major edge is on the left); the right-to-left |
||
671 | * case is a straightforward variation. |
||
672 | * |
||
673 | * We start by finding the half-integral y coordinate that is |
||
674 | * at or below the top of the triangle. This gives us the |
||
675 | * first scan line that could possibly contain pixels that are |
||
676 | * inside the triangle. |
||
677 | * |
||
678 | * Next we creep down the major edge until we reach that y, |
||
679 | * and compute the corresponding x coordinate on the edge. |
||
680 | * Then we find the half-integral x that lies on or just |
||
681 | * inside the edge. This is the first pixel that might lie in |
||
682 | * the interior of the triangle. (We won't know for sure |
||
683 | * until we check the other edges.) |
||
684 | * |
||
685 | * As we rasterize the triangle, we'll step down the major |
||
686 | * edge. For each step in y, we'll move an integer number |
||
687 | * of steps in x. There are two possible x step sizes, which |
||
688 | * we'll call the ``inner'' step (guaranteed to land on the |
||
689 | * edge or inside it) and the ``outer'' step (guaranteed to |
||
690 | * land on the edge or outside it). The inner and outer steps |
||
691 | * differ by one. During rasterization we maintain an error |
||
692 | * term that indicates our distance from the true edge, and |
||
693 | * select either the inner step or the outer step, whichever |
||
694 | * gets us to the first pixel that falls inside the triangle. |
||
695 | * |
||
696 | * All parameters (z, red, etc.) as well as the buffer |
||
697 | * addresses for color and z have inner and outer step values, |
||
698 | * so that we can increment them appropriately. This method |
||
699 | * eliminates the need to adjust parameters by creeping a |
||
700 | * sub-pixel amount into the triangle at each scanline. |
||
701 | */ |
||
702 | |||
703 | { |
||
704 | int subTriangle; |
||
705 | GLfixed fx; |
||
706 | GLfixed fxLeftEdge = 0, fxRightEdge = 0; |
||
707 | GLfixed fdxLeftEdge = 0, fdxRightEdge = 0; |
||
708 | GLfixed fdxOuter; |
||
709 | int idxOuter; |
||
710 | float dxOuter; |
||
711 | GLfixed fError = 0, fdError = 0; |
||
712 | float adjx, adjy; |
||
713 | GLfixed fy; |
||
714 | #ifdef PIXEL_ADDRESS |
||
715 | PIXEL_TYPE *pRow = NULL; |
||
716 | int dPRowOuter = 0, dPRowInner; /* offset in bytes */ |
||
717 | #endif |
||
718 | #ifdef INTERP_Z |
||
719 | # ifdef DEPTH_TYPE |
||
720 | DEPTH_TYPE *zRow = NULL; |
||
721 | int dZRowOuter = 0, dZRowInner; /* offset in bytes */ |
||
722 | # endif |
||
723 | GLfixed fz = 0, fdzOuter = 0, fdzInner; |
||
724 | #endif |
||
725 | #ifdef INTERP_FOG |
||
726 | GLfloat fogLeft = 0, dfogOuter = 0, dfogInner; |
||
727 | #endif |
||
728 | #ifdef INTERP_RGB |
||
729 | GLfixed fr = 0, fdrOuter = 0, fdrInner; |
||
730 | GLfixed fg = 0, fdgOuter = 0, fdgInner; |
||
731 | GLfixed fb = 0, fdbOuter = 0, fdbInner; |
||
732 | #endif |
||
733 | #ifdef INTERP_ALPHA |
||
734 | GLfixed fa = 0, fdaOuter = 0, fdaInner; |
||
735 | #endif |
||
736 | #ifdef INTERP_FLOAT_RGBA |
||
737 | GLfloat fr, fdrOuter, fdrInner; |
||
738 | GLfloat fg, fdgOuter, fdgInner; |
||
739 | GLfloat fb, fdbOuter, fdbInner; |
||
740 | GLfloat fa, fdaOuter, fdaInner; |
||
741 | #endif |
||
742 | #ifdef INTERP_SPEC |
||
743 | GLfixed fsr=0, fdsrOuter=0, fdsrInner; |
||
744 | GLfixed fsg=0, fdsgOuter=0, fdsgInner; |
||
745 | GLfixed fsb=0, fdsbOuter=0, fdsbInner; |
||
746 | #endif |
||
747 | #ifdef INTERP_FLOAT_SPEC |
||
748 | GLfloat fsr=0, fdsrOuter=0, fdsrInner; |
||
749 | GLfloat fsg=0, fdsgOuter=0, fdsgInner; |
||
750 | GLfloat fsb=0, fdsbOuter=0, fdsbInner; |
||
751 | #endif |
||
752 | #ifdef INTERP_INDEX |
||
753 | GLfixed fi=0, fdiOuter=0, fdiInner; |
||
754 | #endif |
||
755 | #ifdef INTERP_INT_TEX |
||
756 | GLfixed fs=0, fdsOuter=0, fdsInner; |
||
757 | GLfixed ft=0, fdtOuter=0, fdtInner; |
||
758 | #endif |
||
759 | #ifdef INTERP_TEX |
||
760 | GLfloat sLeft=0, dsOuter=0, dsInner; |
||
761 | GLfloat tLeft=0, dtOuter=0, dtInner; |
||
762 | GLfloat uLeft=0, duOuter=0, duInner; |
||
763 | GLfloat vLeft=0, dvOuter=0, dvInner; |
||
764 | #endif |
||
765 | #ifdef INTERP_MULTITEX |
||
766 | GLfloat sLeft[MAX_TEXTURE_UNITS]; |
||
767 | GLfloat tLeft[MAX_TEXTURE_UNITS]; |
||
768 | GLfloat uLeft[MAX_TEXTURE_UNITS]; |
||
769 | GLfloat vLeft[MAX_TEXTURE_UNITS]; |
||
770 | GLfloat dsOuter[MAX_TEXTURE_UNITS], dsInner[MAX_TEXTURE_UNITS]; |
||
771 | GLfloat dtOuter[MAX_TEXTURE_UNITS], dtInner[MAX_TEXTURE_UNITS]; |
||
772 | GLfloat duOuter[MAX_TEXTURE_UNITS], duInner[MAX_TEXTURE_UNITS]; |
||
773 | GLfloat dvOuter[MAX_TEXTURE_UNITS], dvInner[MAX_TEXTURE_UNITS]; |
||
774 | #endif |
||
775 | |||
776 | for (subTriangle=0; subTriangle<=1; subTriangle++) { |
||
777 | EdgeT *eLeft, *eRight; |
||
778 | int setupLeft, setupRight; |
||
779 | int lines; |
||
780 | |||
781 | if (subTriangle==0) { |
||
782 | /* bottom half */ |
||
783 | if (scan_from_left_to_right) { |
||
784 | eLeft = &eMaj; |
||
785 | eRight = &eBot; |
||
786 | lines = eRight->lines; |
||
787 | setupLeft = 1; |
||
788 | setupRight = 1; |
||
789 | } |
||
790 | else { |
||
791 | eLeft = &eBot; |
||
792 | eRight = &eMaj; |
||
793 | lines = eLeft->lines; |
||
794 | setupLeft = 1; |
||
795 | setupRight = 1; |
||
796 | } |
||
797 | } |
||
798 | else { |
||
799 | /* top half */ |
||
800 | if (scan_from_left_to_right) { |
||
801 | eLeft = &eMaj; |
||
802 | eRight = &eTop; |
||
803 | lines = eRight->lines; |
||
804 | setupLeft = 0; |
||
805 | setupRight = 1; |
||
806 | } |
||
807 | else { |
||
808 | eLeft = &eTop; |
||
809 | eRight = &eMaj; |
||
810 | lines = eLeft->lines; |
||
811 | setupLeft = 1; |
||
812 | setupRight = 0; |
||
813 | } |
||
814 | if (lines == 0) |
||
815 | return; |
||
816 | } |
||
817 | |||
818 | if (setupLeft && eLeft->lines > 0) { |
||
819 | const SWvertex *vLower; |
||
820 | GLfixed fsx = eLeft->fsx; |
||
821 | fx = FixedCeil(fsx); |
||
822 | fError = fx - fsx - FIXED_ONE; |
||
823 | fxLeftEdge = fsx - FIXED_EPSILON; |
||
824 | fdxLeftEdge = eLeft->fdxdy; |
||
825 | fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON); |
||
826 | fdError = fdxOuter - fdxLeftEdge + FIXED_ONE; |
||
827 | idxOuter = FixedToInt(fdxOuter); |
||
828 | dxOuter = (float) idxOuter; |
||
829 | (void) dxOuter; |
||
830 | |||
831 | fy = eLeft->fsy; |
||
832 | span.y = FixedToInt(fy); |
||
833 | |||
834 | adjx = (float)(fx - eLeft->fx0); /* SCALED! */ |
||
835 | adjy = eLeft->adjy; /* SCALED! */ |
||
836 | (void) adjx; /* silence compiler warnings */ |
||
837 | (void) adjy; /* silence compiler warnings */ |
||
838 | |||
839 | vLower = eLeft->v0; |
||
840 | (void) vLower; /* silence compiler warnings */ |
||
841 | |||
842 | #ifdef PIXEL_ADDRESS |
||
843 | { |
||
844 | pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y); |
||
845 | dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE); |
||
846 | /* negative because Y=0 at bottom and increases upward */ |
||
847 | } |
||
848 | #endif |
||
849 | /* |
||
850 | * Now we need the set of parameter (z, color, etc.) values at |
||
851 | * the point (fx, fy). This gives us properly-sampled parameter |
||
852 | * values that we can step from pixel to pixel. Furthermore, |
||
853 | * although we might have intermediate results that overflow |
||
854 | * the normal parameter range when we step temporarily outside |
||
855 | * the triangle, we shouldn't overflow or underflow for any |
||
856 | * pixel that's actually inside the triangle. |
||
857 | */ |
||
858 | |||
859 | #ifdef INTERP_Z |
||
860 | { |
||
861 | GLfloat z0 = vLower->win[2]; |
||
862 | if (depthBits <= 16) { |
||
863 | /* interpolate fixed-pt values */ |
||
864 | GLfloat tmp = (z0 * FIXED_SCALE + |
||
865 | dzdx * adjx + dzdy * adjy) + FIXED_HALF; |
||
866 | if (tmp < MAX_GLUINT / 2) |
||
867 | fz = (GLfixed) tmp; |
||
868 | else |
||
869 | fz = MAX_GLUINT / 2; |
||
870 | fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx); |
||
871 | } |
||
872 | else { |
||
873 | /* interpolate depth values exactly */ |
||
874 | fz = (GLint) (z0 + dzdx * FixedToFloat(adjx) |
||
875 | + dzdy * FixedToFloat(adjy)); |
||
876 | fdzOuter = (GLint) (dzdy + dxOuter * dzdx); |
||
877 | } |
||
878 | # ifdef DEPTH_TYPE |
||
879 | zRow = (DEPTH_TYPE *) |
||
880 | _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), span.y); |
||
881 | dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); |
||
882 | # endif |
||
883 | } |
||
884 | #endif |
||
885 | #ifdef INTERP_FOG |
||
886 | fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy) |
||
887 | * (1.0F/FIXED_SCALE); |
||
888 | dfogOuter = dfogdy + dxOuter * span.fogStep; |
||
889 | #endif |
||
890 | #ifdef INTERP_RGB |
||
891 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
892 | fr = (GLfixed) (ChanToFixed(vLower->color[RCOMP]) |
||
893 | + drdx * adjx + drdy * adjy) + FIXED_HALF; |
||
894 | fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx); |
||
895 | fg = (GLfixed) (ChanToFixed(vLower->color[GCOMP]) |
||
896 | + dgdx * adjx + dgdy * adjy) + FIXED_HALF; |
||
897 | fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx); |
||
898 | fb = (GLfixed) (ChanToFixed(vLower->color[BCOMP]) |
||
899 | + dbdx * adjx + dbdy * adjy) + FIXED_HALF; |
||
900 | fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx); |
||
901 | # ifdef INTERP_ALPHA |
||
902 | fa = (GLfixed) (ChanToFixed(vLower->color[ACOMP]) |
||
903 | + dadx * adjx + dady * adjy) + FIXED_HALF; |
||
904 | fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx); |
||
905 | # endif |
||
906 | } |
||
907 | else { |
||
908 | ASSERT (ctx->Light.ShadeModel == GL_FLAT); |
||
909 | fr = ChanToFixed(v2->color[RCOMP]); |
||
910 | fg = ChanToFixed(v2->color[GCOMP]); |
||
911 | fb = ChanToFixed(v2->color[BCOMP]); |
||
912 | fdrOuter = fdgOuter = fdbOuter = 0; |
||
913 | # ifdef INTERP_ALPHA |
||
914 | fa = ChanToFixed(v2->color[ACOMP]); |
||
915 | fdaOuter = 0; |
||
916 | # endif |
||
917 | } |
||
918 | #endif |
||
919 | #ifdef INTERP_FLOAT_RGBA |
||
920 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
921 | fr = vLower->color[RCOMP] |
||
922 | + (drdx * adjx + drdy * adjy) * (1.0F / FIXED_SCALE); |
||
923 | fdrOuter = drdy + dxOuter * drdx; |
||
924 | fg = vLower->color[GCOMP] |
||
925 | + (dgdx * adjx + dgdy * adjy) * (1.0F / FIXED_SCALE); |
||
926 | fdgOuter = dgdy + dxOuter * dgdx; |
||
927 | fb = vLower->color[BCOMP] |
||
928 | + (dbdx * adjx + dbdy * adjy) * (1.0F / FIXED_SCALE); |
||
929 | fdbOuter = dbdy + dxOuter * dbdx; |
||
930 | fa = vLower->color[ACOMP] |
||
931 | + (dadx * adjx + dady * adjy) * (1.0F / FIXED_SCALE); |
||
932 | fdaOuter = dady + dxOuter * dadx; |
||
933 | } |
||
934 | else { |
||
935 | fr = v2->color[RCOMP]; |
||
936 | fg = v2->color[GCOMP]; |
||
937 | fb = v2->color[BCOMP]; |
||
938 | fa = v2->color[ACOMP]; |
||
939 | fdrOuter = fdgOuter = fdbOuter = fdaOuter = 0.0F; |
||
940 | } |
||
941 | #endif |
||
942 | #ifdef INTERP_SPEC |
||
943 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
944 | fsr = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) |
||
945 | + dsrdx * adjx + dsrdy * adjy) + FIXED_HALF; |
||
946 | fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx); |
||
947 | fsg = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) |
||
948 | + dsgdx * adjx + dsgdy * adjy) + FIXED_HALF; |
||
949 | fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx); |
||
950 | fsb = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) |
||
951 | + dsbdx * adjx + dsbdy * adjy) + FIXED_HALF; |
||
952 | fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx); |
||
953 | } |
||
954 | else { |
||
955 | fsr = ChanToFixed(v2->specular[RCOMP]); |
||
956 | fsg = ChanToFixed(v2->specular[GCOMP]); |
||
957 | fsb = ChanToFixed(v2->specular[BCOMP]); |
||
958 | fdsrOuter = fdsgOuter = fdsbOuter = 0; |
||
959 | } |
||
960 | #endif |
||
961 | #ifdef INTERP_FLOAT_SPEC |
||
962 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
963 | fsr = vLower->specular[RCOMP] |
||
964 | + (dsrdx * adjx + dsrdy * adjy) * (1.0F / FIXED_SCALE); |
||
965 | fdsrOuter = dsrdy + dxOuter * dsrdx; |
||
966 | fsg = vLower->specular[GCOMP] |
||
967 | + (dsgdx * adjx + dsgdy * adjy) * (1.0F / FIXED_SCALE); |
||
968 | fdsgOuter = dsgdy + dxOuter * dsgdx; |
||
969 | fsb = vLower->specular[BCOMP] |
||
970 | + (dsbdx * adjx + dsbdy * adjy) * (1.0F / FIXED_SCALE); |
||
971 | fdsbOuter = dsbdy + dxOuter * dsbdx; |
||
972 | } |
||
973 | else { |
||
974 | fsr = v2->specular[RCOMP]; |
||
975 | fsg = v2->specular[GCOMP]; |
||
976 | fsb = v2->specular[BCOMP]; |
||
977 | fdsrOuter = fdsgOuter = fdsbOuter = 0.0F; |
||
978 | } |
||
979 | #endif |
||
980 | #ifdef INTERP_INDEX |
||
981 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
982 | fi = (GLfixed)(vLower->index * FIXED_SCALE |
||
983 | + didx * adjx + didy * adjy) + FIXED_HALF; |
||
984 | fdiOuter = SignedFloatToFixed(didy + dxOuter * didx); |
||
985 | } |
||
986 | else { |
||
987 | fi = (GLfixed) (v2->index * FIXED_SCALE); |
||
988 | fdiOuter = 0; |
||
989 | } |
||
990 | #endif |
||
991 | #ifdef INTERP_INT_TEX |
||
992 | { |
||
993 | GLfloat s0, t0; |
||
994 | s0 = vLower->texcoord[0][0] * S_SCALE; |
||
995 | fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx |
||
996 | + dsdy * adjy) + FIXED_HALF; |
||
997 | fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx); |
||
998 | |||
999 | t0 = vLower->texcoord[0][1] * T_SCALE; |
||
1000 | ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx |
||
1001 | + dtdy * adjy) + FIXED_HALF; |
||
1002 | fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx); |
||
1003 | } |
||
1004 | #endif |
||
1005 | #ifdef INTERP_TEX |
||
1006 | { |
||
1007 | GLfloat invW = vLower->win[3]; |
||
1008 | GLfloat s0, t0, u0, v0; |
||
1009 | s0 = vLower->texcoord[0][0] * invW; |
||
1010 | sLeft = s0 + (span.texStepX[0][0] * adjx + dsdy * adjy) |
||
1011 | * (1.0F/FIXED_SCALE); |
||
1012 | dsOuter = dsdy + dxOuter * span.texStepX[0][0]; |
||
1013 | t0 = vLower->texcoord[0][1] * invW; |
||
1014 | tLeft = t0 + (span.texStepX[0][1] * adjx + dtdy * adjy) |
||
1015 | * (1.0F/FIXED_SCALE); |
||
1016 | dtOuter = dtdy + dxOuter * span.texStepX[0][1]; |
||
1017 | u0 = vLower->texcoord[0][2] * invW; |
||
1018 | uLeft = u0 + (span.texStepX[0][2] * adjx + dudy * adjy) |
||
1019 | * (1.0F/FIXED_SCALE); |
||
1020 | duOuter = dudy + dxOuter * span.texStepX[0][2]; |
||
1021 | v0 = vLower->texcoord[0][3] * invW; |
||
1022 | vLeft = v0 + (span.texStepX[0][3] * adjx + dvdy * adjy) |
||
1023 | * (1.0F/FIXED_SCALE); |
||
1024 | dvOuter = dvdy + dxOuter * span.texStepX[0][3]; |
||
1025 | } |
||
1026 | #endif |
||
1027 | #ifdef INTERP_MULTITEX |
||
1028 | { |
||
1029 | GLuint u; |
||
1030 | for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { |
||
1031 | if (ctx->Texture.Unit[u]._ReallyEnabled) { |
||
1032 | GLfloat invW = vLower->win[3]; |
||
1033 | GLfloat s0, t0, u0, v0; |
||
1034 | s0 = vLower->texcoord[u][0] * invW; |
||
1035 | sLeft[u] = s0 + (span.texStepX[u][0] * adjx + dsdy[u] |
||
1036 | * adjy) * (1.0F/FIXED_SCALE); |
||
1037 | dsOuter[u] = dsdy[u] + dxOuter * span.texStepX[u][0]; |
||
1038 | t0 = vLower->texcoord[u][1] * invW; |
||
1039 | tLeft[u] = t0 + (span.texStepX[u][1] * adjx + dtdy[u] |
||
1040 | * adjy) * (1.0F/FIXED_SCALE); |
||
1041 | dtOuter[u] = dtdy[u] + dxOuter * span.texStepX[u][1]; |
||
1042 | u0 = vLower->texcoord[u][2] * invW; |
||
1043 | uLeft[u] = u0 + (span.texStepX[u][2] * adjx + dudy[u] |
||
1044 | * adjy) * (1.0F/FIXED_SCALE); |
||
1045 | duOuter[u] = dudy[u] + dxOuter * span.texStepX[u][2]; |
||
1046 | v0 = vLower->texcoord[u][3] * invW; |
||
1047 | vLeft[u] = v0 + (span.texStepX[u][3] * adjx + dvdy[u] |
||
1048 | * adjy) * (1.0F/FIXED_SCALE); |
||
1049 | dvOuter[u] = dvdy[u] + dxOuter * span.texStepX[u][3]; |
||
1050 | } |
||
1051 | } |
||
1052 | } |
||
1053 | #endif |
||
1054 | |||
1055 | } /*if setupLeft*/ |
||
1056 | |||
1057 | |||
1058 | if (setupRight && eRight->lines>0) { |
||
1059 | fxRightEdge = eRight->fsx - FIXED_EPSILON; |
||
1060 | fdxRightEdge = eRight->fdxdy; |
||
1061 | } |
||
1062 | |||
1063 | if (lines==0) { |
||
1064 | continue; |
||
1065 | } |
||
1066 | |||
1067 | |||
1068 | /* Rasterize setup */ |
||
1069 | #ifdef PIXEL_ADDRESS |
||
1070 | dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE); |
||
1071 | #endif |
||
1072 | #ifdef INTERP_Z |
||
1073 | # ifdef DEPTH_TYPE |
||
1074 | dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE); |
||
1075 | # endif |
||
1076 | fdzInner = fdzOuter + span.zStep; |
||
1077 | #endif |
||
1078 | #ifdef INTERP_FOG |
||
1079 | dfogInner = dfogOuter + span.fogStep; |
||
1080 | #endif |
||
1081 | #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA) |
||
1082 | fdrInner = fdrOuter + span.redStep; |
||
1083 | fdgInner = fdgOuter + span.greenStep; |
||
1084 | fdbInner = fdbOuter + span.blueStep; |
||
1085 | #endif |
||
1086 | #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA) |
||
1087 | fdaInner = fdaOuter + span.alphaStep; |
||
1088 | #endif |
||
1089 | #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC) |
||
1090 | fdsrInner = fdsrOuter + span.specRedStep; |
||
1091 | fdsgInner = fdsgOuter + span.specGreenStep; |
||
1092 | fdsbInner = fdsbOuter + span.specBlueStep; |
||
1093 | #endif |
||
1094 | #ifdef INTERP_INDEX |
||
1095 | fdiInner = fdiOuter + span.indexStep; |
||
1096 | #endif |
||
1097 | #ifdef INTERP_INT_TEX |
||
1098 | fdsInner = fdsOuter + span.intTexStep[0]; |
||
1099 | fdtInner = fdtOuter + span.intTexStep[1]; |
||
1100 | #endif |
||
1101 | #ifdef INTERP_TEX |
||
1102 | dsInner = dsOuter + span.texStepX[0][0]; |
||
1103 | dtInner = dtOuter + span.texStepX[0][1]; |
||
1104 | duInner = duOuter + span.texStepX[0][2]; |
||
1105 | dvInner = dvOuter + span.texStepX[0][3]; |
||
1106 | #endif |
||
1107 | #ifdef INTERP_MULTITEX |
||
1108 | { |
||
1109 | GLuint u; |
||
1110 | for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { |
||
1111 | if (ctx->Texture.Unit[u]._ReallyEnabled) { |
||
1112 | dsInner[u] = dsOuter[u] + span.texStepX[u][0]; |
||
1113 | dtInner[u] = dtOuter[u] + span.texStepX[u][1]; |
||
1114 | duInner[u] = duOuter[u] + span.texStepX[u][2]; |
||
1115 | dvInner[u] = dvOuter[u] + span.texStepX[u][3]; |
||
1116 | } |
||
1117 | } |
||
1118 | } |
||
1119 | #endif |
||
1120 | |||
1121 | while (lines > 0) { |
||
1122 | /* initialize the span interpolants to the leftmost value */ |
||
1123 | /* ff = fixed-pt fragment */ |
||
1124 | const GLint right = FixedToInt(fxRightEdge); |
||
1125 | |||
1126 | span.x = FixedToInt(fxLeftEdge); |
||
1127 | |||
1128 | if (right <= span.x) |
||
1129 | span.end = 0; |
||
1130 | else |
||
1131 | span.end = right - span.x; |
||
1132 | |||
1133 | #ifdef INTERP_Z |
||
1134 | span.z = fz; |
||
1135 | #endif |
||
1136 | #ifdef INTERP_FOG |
||
1137 | span.fog = fogLeft; |
||
1138 | #endif |
||
1139 | #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA) |
||
1140 | span.red = fr; |
||
1141 | span.green = fg; |
||
1142 | span.blue = fb; |
||
1143 | #endif |
||
1144 | #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA) |
||
1145 | span.alpha = fa; |
||
1146 | #endif |
||
1147 | #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC) |
||
1148 | span.specRed = fsr; |
||
1149 | span.specGreen = fsg; |
||
1150 | span.specBlue = fsb; |
||
1151 | #endif |
||
1152 | #ifdef INTERP_INDEX |
||
1153 | span.index = fi; |
||
1154 | #endif |
||
1155 | #ifdef INTERP_INT_TEX |
||
1156 | span.intTex[0] = fs; |
||
1157 | span.intTex[1] = ft; |
||
1158 | #endif |
||
1159 | |||
1160 | #ifdef INTERP_TEX |
||
1161 | span.tex[0][0] = sLeft; |
||
1162 | span.tex[0][1] = tLeft; |
||
1163 | span.tex[0][2] = uLeft; |
||
1164 | span.tex[0][3] = vLeft; |
||
1165 | #endif |
||
1166 | |||
1167 | #ifdef INTERP_MULTITEX |
||
1168 | { |
||
1169 | GLuint u; |
||
1170 | for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { |
||
1171 | if (ctx->Texture.Unit[u]._ReallyEnabled) { |
||
1172 | span.tex[u][0] = sLeft[u]; |
||
1173 | span.tex[u][1] = tLeft[u]; |
||
1174 | span.tex[u][2] = uLeft[u]; |
||
1175 | span.tex[u][3] = vLeft[u]; |
||
1176 | } |
||
1177 | } |
||
1178 | } |
||
1179 | #endif |
||
1180 | |||
1181 | #ifdef INTERP_RGB |
||
1182 | { |
||
1183 | /* need this to accomodate round-off errors */ |
||
1184 | const GLint len = right - span.x - 1; |
||
1185 | GLfixed ffrend = span.red + len * span.redStep; |
||
1186 | GLfixed ffgend = span.green + len * span.greenStep; |
||
1187 | GLfixed ffbend = span.blue + len * span.blueStep; |
||
1188 | if (ffrend < 0) { |
||
1189 | span.red -= ffrend; |
||
1190 | if (span.red < 0) |
||
1191 | span.red = 0; |
||
1192 | } |
||
1193 | if (ffgend < 0) { |
||
1194 | span.green -= ffgend; |
||
1195 | if (span.green < 0) |
||
1196 | span.green = 0; |
||
1197 | } |
||
1198 | if (ffbend < 0) { |
||
1199 | span.blue -= ffbend; |
||
1200 | if (span.blue < 0) |
||
1201 | span.blue = 0; |
||
1202 | } |
||
1203 | } |
||
1204 | #endif |
||
1205 | #ifdef INTERP_ALPHA |
||
1206 | { |
||
1207 | const GLint len = right - span.x - 1; |
||
1208 | GLfixed ffaend = span.alpha + len * span.alphaStep; |
||
1209 | if (ffaend < 0) { |
||
1210 | span.alpha -= ffaend; |
||
1211 | if (span.alpha < 0) |
||
1212 | span.alpha = 0; |
||
1213 | } |
||
1214 | } |
||
1215 | #endif |
||
1216 | #ifdef INTERP_SPEC |
||
1217 | { |
||
1218 | /* need this to accomodate round-off errors */ |
||
1219 | const GLint len = right - span.x - 1; |
||
1220 | GLfixed ffsrend = span.specRed + len * span.specRedStep; |
||
1221 | GLfixed ffsgend = span.specGreen + len * span.specGreenStep; |
||
1222 | GLfixed ffsbend = span.specBlue + len * span.specBlueStep; |
||
1223 | if (ffsrend < 0) { |
||
1224 | span.specRed -= ffsrend; |
||
1225 | if (span.specRed < 0) |
||
1226 | span.specRed = 0; |
||
1227 | } |
||
1228 | if (ffsgend < 0) { |
||
1229 | span.specGreen -= ffsgend; |
||
1230 | if (span.specGreen < 0) |
||
1231 | span.specGreen = 0; |
||
1232 | } |
||
1233 | if (ffsbend < 0) { |
||
1234 | span.specBlue -= ffsbend; |
||
1235 | if (span.specBlue < 0) |
||
1236 | span.specBlue = 0; |
||
1237 | } |
||
1238 | } |
||
1239 | #endif |
||
1240 | #ifdef INTERP_INDEX |
||
1241 | if (span.index < 0) span.index = 0; |
||
1242 | #endif |
||
1243 | |||
1244 | /* This is where we actually generate fragments */ |
||
1245 | if (span.end > 0) { |
||
1246 | RENDER_SPAN( span ); |
||
1247 | } |
||
1248 | |||
1249 | /* |
||
1250 | * Advance to the next scan line. Compute the |
||
1251 | * new edge coordinates, and adjust the |
||
1252 | * pixel-center x coordinate so that it stays |
||
1253 | * on or inside the major edge. |
||
1254 | */ |
||
1255 | (span.y)++; |
||
1256 | lines--; |
||
1257 | |||
1258 | fxLeftEdge += fdxLeftEdge; |
||
1259 | fxRightEdge += fdxRightEdge; |
||
1260 | |||
1261 | |||
1262 | fError += fdError; |
||
1263 | if (fError >= 0) { |
||
1264 | fError -= FIXED_ONE; |
||
1265 | #ifdef PIXEL_ADDRESS |
||
1266 | pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); |
||
1267 | #endif |
||
1268 | #ifdef INTERP_Z |
||
1269 | # ifdef DEPTH_TYPE |
||
1270 | zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter); |
||
1271 | # endif |
||
1272 | fz += fdzOuter; |
||
1273 | #endif |
||
1274 | #ifdef INTERP_FOG |
||
1275 | fogLeft += dfogOuter; |
||
1276 | #endif |
||
1277 | #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA) |
||
1278 | fr += fdrOuter; |
||
1279 | fg += fdgOuter; |
||
1280 | fb += fdbOuter; |
||
1281 | #endif |
||
1282 | #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA) |
||
1283 | fa += fdaOuter; |
||
1284 | #endif |
||
1285 | #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC) |
||
1286 | fsr += fdsrOuter; |
||
1287 | fsg += fdsgOuter; |
||
1288 | fsb += fdsbOuter; |
||
1289 | #endif |
||
1290 | #ifdef INTERP_INDEX |
||
1291 | fi += fdiOuter; |
||
1292 | #endif |
||
1293 | #ifdef INTERP_INT_TEX |
||
1294 | fs += fdsOuter; |
||
1295 | ft += fdtOuter; |
||
1296 | #endif |
||
1297 | #ifdef INTERP_TEX |
||
1298 | sLeft += dsOuter; |
||
1299 | tLeft += dtOuter; |
||
1300 | uLeft += duOuter; |
||
1301 | vLeft += dvOuter; |
||
1302 | #endif |
||
1303 | #ifdef INTERP_MULTITEX |
||
1304 | { |
||
1305 | GLuint u; |
||
1306 | for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { |
||
1307 | if (ctx->Texture.Unit[u]._ReallyEnabled) { |
||
1308 | sLeft[u] += dsOuter[u]; |
||
1309 | tLeft[u] += dtOuter[u]; |
||
1310 | uLeft[u] += duOuter[u]; |
||
1311 | vLeft[u] += dvOuter[u]; |
||
1312 | } |
||
1313 | } |
||
1314 | } |
||
1315 | #endif |
||
1316 | } |
||
1317 | else { |
||
1318 | #ifdef PIXEL_ADDRESS |
||
1319 | pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner); |
||
1320 | #endif |
||
1321 | #ifdef INTERP_Z |
||
1322 | # ifdef DEPTH_TYPE |
||
1323 | zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner); |
||
1324 | # endif |
||
1325 | fz += fdzInner; |
||
1326 | #endif |
||
1327 | #ifdef INTERP_FOG |
||
1328 | fogLeft += dfogInner; |
||
1329 | #endif |
||
1330 | #if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA) |
||
1331 | fr += fdrInner; |
||
1332 | fg += fdgInner; |
||
1333 | fb += fdbInner; |
||
1334 | #endif |
||
1335 | #if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA) |
||
1336 | fa += fdaInner; |
||
1337 | #endif |
||
1338 | #if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC) |
||
1339 | fsr += fdsrInner; |
||
1340 | fsg += fdsgInner; |
||
1341 | fsb += fdsbInner; |
||
1342 | #endif |
||
1343 | #ifdef INTERP_INDEX |
||
1344 | fi += fdiInner; |
||
1345 | #endif |
||
1346 | #ifdef INTERP_INT_TEX |
||
1347 | fs += fdsInner; |
||
1348 | ft += fdtInner; |
||
1349 | #endif |
||
1350 | #ifdef INTERP_TEX |
||
1351 | sLeft += dsInner; |
||
1352 | tLeft += dtInner; |
||
1353 | uLeft += duInner; |
||
1354 | vLeft += dvInner; |
||
1355 | #endif |
||
1356 | #ifdef INTERP_MULTITEX |
||
1357 | { |
||
1358 | GLuint u; |
||
1359 | for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { |
||
1360 | if (ctx->Texture.Unit[u]._ReallyEnabled) { |
||
1361 | sLeft[u] += dsInner[u]; |
||
1362 | tLeft[u] += dtInner[u]; |
||
1363 | uLeft[u] += duInner[u]; |
||
1364 | vLeft[u] += dvInner[u]; |
||
1365 | } |
||
1366 | } |
||
1367 | } |
||
1368 | #endif |
||
1369 | } |
||
1370 | } /*while lines>0*/ |
||
1371 | |||
1372 | } /* for subTriangle */ |
||
1373 | |||
1374 | } |
||
1375 | #ifdef CLEANUP_CODE |
||
1376 | CLEANUP_CODE |
||
1377 | #endif |
||
1378 | } |
||
1379 | } |
||
1380 | |||
1381 | #undef SETUP_CODE |
||
1382 | #undef CLEANUP_CODE |
||
1383 | #undef RENDER_SPAN |
||
1384 | |||
1385 | #undef PIXEL_TYPE |
||
1386 | #undef BYTES_PER_ROW |
||
1387 | #undef PIXEL_ADDRESS |
||
1388 | |||
1389 | #undef INTERP_Z |
||
1390 | #undef INTERP_FOG |
||
1391 | #undef INTERP_RGB |
||
1392 | #undef INTERP_ALPHA |
||
1393 | #undef INTERP_SPEC |
||
1394 | #undef INTERP_INDEX |
||
1395 | #undef INTERP_INT_TEX |
||
1396 | #undef INTERP_TEX |
||
1397 | #undef INTERP_MULTITEX |
||
1398 | #undef INTERP_FLOAT_RGBA |
||
1399 | #undef INTERP_FLOAT_SPEC |
||
1400 | |||
1401 | #undef S_SCALE |
||
1402 | #undef T_SCALE |
||
1403 | |||
1404 | #undef FixedToDepth |
||
1405 | |||
1406 | #undef DO_OCCLUSION_TEST |