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