1 /* $Id: linetemp.h,v 1.4 1998/01/16 03:46:07 brianp Exp $ */ 2 3 /* 4 * Mesa 3-D graphics library 5 * Version: 2.6 6 * Copyright (C) 1995-1997 Brian Paul 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public 19 * License along with this library; if not, write to the Free 20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 24 /* 25 * $Log: linetemp.h,v $ 26 * Revision 1.4 1998/01/16 03:46:07 brianp 27 * fixed a few Windows compilation warnings (Theodore Jump) 28 * 29 * Revision 1.3 1997/06/20 02:49:53 brianp 30 * changed color components from GLfixed to GLubyte 31 * 32 * Revision 1.2 1997/05/16 01:54:54 brianp 33 * zPtrYstep calculation was negated! 34 * 35 * Revision 1.1 1997/03/16 02:07:56 brianp 36 * Initial revision 37 * 38 */ 39 40 41 /* 42 * Line Rasterizer Template 43 * 44 * This file is #include'd to generate custom line rasterizers. 45 * 46 * The following macros may be defined to indicate what auxillary information 47 * must be interplated along the line: 48 * INTERP_Z - if defined, interpolate Z values 49 * INTERP_RGB - if defined, interpolate RGB values 50 * INTERP_ALPHA - if defined, interpolate Alpha values 51 * INTERP_INDEX - if defined, interpolate color index values 52 * INTERP_ST - if defined, interpolate integer ST texcoords 53 * (fast, simple 2-D texture mapping) 54 * INTERP_STW - if defined, interpolate float ST texcoords and W 55 * (2-D texture maps with perspective correction) 56 * INTERP_UV - if defined, interpolate float UV texcoords too 57 * (for 3-D, 4-D? texture maps) 58 * 59 * When one can directly address pixels in the color buffer the following 60 * macros can be defined and used to directly compute pixel addresses during 61 * rasterization (see pixelPtr): 62 * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint) 63 * BYTES_PER_ROW - number of bytes per row in the color buffer 64 * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where 65 * Y==0 at bottom of screen and increases upward. 66 * 67 * Optionally, one may provide one-time setup code 68 * SETUP_CODE - code which is to be executed once per line 69 * 70 * To enable line stippling define STIPPLE = 1 71 * To enable wide lines define WIDE = 1 72 * 73 * To actually "plot" each pixel either the PLOT macro or 74 * (XMAJOR_PLOT and YMAJOR_PLOT macros) must be defined... 75 * PLOT(X,Y) - code to plot a pixel. Example: 76 * if (Z < *zPtr) { 77 * *zPtr = Z; 78 * color = pack_rgb( FixedToInt(r0), FixedToInt(g0), 79 * FixedToInt(b0) ); 80 * put_pixel( X, Y, color ); 81 * } 82 * 83 * This code was designed for the origin to be in the lower-left corner. 84 * 85 */ 86 87 88 /*void line( GLcontext *ctx, GLuint vert0, GLuint vert1, GLuint pvert )*/ 89 { 90 struct vertex_buffer *VB = ctx->VB; 91 /* 92 GLint x0 = (GLint) VB->Win[vert0][0], dx = (GLint) VB->Win[vert1][0] - x0; 93 GLint y0 = (GLint) VB->Win[vert0][1], dy = (GLint) VB->Win[vert1][1] - y0; 94 */ 95 GLint x0 = (GLint) VB->Win[vert0][0], x1 = (GLint) VB->Win[vert1][0]; 96 GLint y0 = (GLint) VB->Win[vert0][1], y1 = (GLint) VB->Win[vert1][1]; 97 GLint dx, dy; 98 #if INTERP_XY 99 GLint xstep, ystep; 100 #endif 101 #if INTERP_Z 102 GLint z0, z1, dz, zPtrXstep, zPtrYstep; 103 GLdepth *zPtr; 104 #endif 105 #if INTERP_RGB 106 GLfixed r0 = IntToFixed(VB->Color[vert0][0]); 107 GLfixed dr = IntToFixed(VB->Color[vert1][0]) - r0; 108 GLfixed g0 = IntToFixed(VB->Color[vert0][1]); 109 GLfixed dg = IntToFixed(VB->Color[vert1][1]) - g0; 110 GLfixed b0 = IntToFixed(VB->Color[vert0][2]); 111 GLfixed db = IntToFixed(VB->Color[vert1][2]) - b0; 112 #endif 113 #if INTERP_ALPHA 114 GLfixed a0 = IntToFixed(VB->Color[vert0][3]); 115 GLfixed da = IntToFixed(VB->Color[vert1][3]) - a0; 116 #endif 117 #if INTERP_INDEX 118 GLint i0 = VB->Index[vert0] << 8, di = (GLint) (VB->Index[vert1] << 8)-i0; 119 #endif 120 #if INTERP_ST 121 GLfixed s0 = FloatToFixed(VB->TexCoord[vert0][0] * S_SCALE); 122 GLfixed ds = FloatToFixed(VB->TexCoord[vert1][0] * S_SCALE) - s0; 123 GLfixed t0 = FloatToFixed(VB->TexCoord[vert0][1] * T_SCALE); 124 GLfixed dt = FloatToFixed(VB->TexCoord[vert1][1] * T_SCALE) - t0; 125 #endif 126 #if INTERP_STW 127 GLfloat s0 = VB->TexCoord[vert0][0], ds = VB->TexCoord[vert1][0] - s0; 128 GLfloat t0 = VB->TexCoord[vert0][1], dt = VB->TexCoord[vert1][1] - t0; 129 GLfloat w0 = 1.0F / VB->Clip[vert0][3], dw = 1.0F / VB->Clip[vert1][3] - w0; 130 #endif 131 #if INTERP_UV 132 GLfloat u0 = VB->TexCoord[vert0][2], du = VB->TexCoord[vert1][2] - u0; 133 GLfloat v0 = VB->TexCoord[vert0][3], dv = VB->TexCoord[vert1][3] - v0; 134 #endif 135 #ifdef PIXEL_ADDRESS 136 PIXEL_TYPE *pixelPtr; 137 GLint pixelXstep, pixelYstep; 138 #endif 139 140 #if WIDE 141 GLint width, min, max; 142 width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH ); 143 min = -width / 2; 144 max = min + width - 1; 145 #endif 146 147 /* 148 * Despite being clipped to the view volume, the line's window coordinates 149 * may just lie outside the window bounds. That is, if the legal window 150 * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H. 151 * This quick and dirty code nudges the endpoints inside the window if 152 * necessary. 153 */ 154 #if CLIP_HACK 155 { 156 GLint w = ctx->Buffer->Width; 157 GLint h = ctx->Buffer->Height; 158 if ((x0==w) | (x1==w)) { 159 if ((x0==w) & (x1==w)) 160 return; 161 x0 -= x0==w; 162 x1 -= x1==w; 163 } 164 if ((y0==h) | (y1==h)) { 165 if ((y0==h) & (y1==h)) 166 return; 167 y0 -= y0==h; 168 y1 -= y1==h; 169 } 170 } 171 #endif 172 dx = x1 - x0; 173 dy = y1 - y0; 174 if (dx==0 && dy==0) { 175 return; 176 } 177 178 /* 179 * Setup 180 */ 181 #ifdef SETUP_CODE 182 SETUP_CODE 183 #endif 184 185 #if INTERP_Z 186 zPtr = Z_ADDRESS(ctx,x0,y0); 187 z0 = (int) VB->Win[vert0][2]; 188 z1 = (int) VB->Win[vert1][2]; 189 #endif 190 #ifdef PIXEL_ADDRESS 191 pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0); 192 #endif 193 194 if (dx<0) { 195 dx = -dx; /* make positive */ 196 #if INTERP_XY 197 xstep = -1; 198 #endif 199 #ifdef INTERP_Z 200 zPtrXstep = -((GLint)sizeof(GLdepth)); 201 #endif 202 #ifdef PIXEL_ADDRESS 203 pixelXstep = -sizeof(PIXEL_TYPE); 204 #endif 205 } 206 else { 207 #if INTERP_XY 208 xstep = 1; 209 #endif 210 #if INTERP_Z 211 zPtrXstep = sizeof(GLdepth); 212 #endif 213 #ifdef PIXEL_ADDRESS 214 pixelXstep = sizeof(PIXEL_TYPE); 215 #endif 216 } 217 218 if (dy<0) { 219 dy = -dy; /* make positive */ 220 #if INTERP_XY 221 ystep = -1; 222 #endif 223 #if INTERP_Z 224 zPtrYstep = -ctx->Buffer->Width * sizeof(GLdepth); 225 #endif 226 #ifdef PIXEL_ADDRESS 227 pixelYstep = BYTES_PER_ROW; 228 #endif 229 } 230 else { 231 #if INTERP_XY 232 ystep = 1; 233 #endif 234 #if INTERP_Z 235 zPtrYstep = ctx->Buffer->Width * sizeof(GLdepth); 236 #endif 237 #ifdef PIXEL_ADDRESS 238 pixelYstep = -(BYTES_PER_ROW); 239 #endif 240 } 241 242 /* 243 * Draw 244 */ 245 246 if (dx>dy) { 247 /* 248 * X-major line 249 */ 250 GLint i; 251 GLint errorInc = dy+dy; 252 GLint error = errorInc-dx; 253 GLint errorDec = error-dx; 254 #if INTERP_Z 255 dz = (z1-z0) / dx; 256 #endif 257 #if INTERP_RGB 258 dr /= dx; /* convert from whole line delta to per-pixel delta */ 259 dg /= dx; 260 db /= dx; 261 #endif 262 #if INTERP_ALPHA 263 da /= dx; 264 #endif 265 #if INTERP_INDEX 266 di /= dx; 267 #endif 268 #if INTERP_ST 269 ds /= dx; 270 dt /= dx; 271 #endif 272 #if INTERP_STW 273 { 274 GLfloat fdxinv = 1.0F / (GLfloat) dx; 275 ds *= fdxinv; 276 dt *= fdxinv; 277 dw *= fdxinv; 278 #if INTERP_UV 279 du *= fdxinv; 280 dv *= fdxinv; 281 #endif 282 } 283 #endif 284 for (i=0;i<dx;i++) { 285 #if STIPPLE 286 GLushort m; 287 m = 1 << ((ctx->StippleCounter/ctx->Line.StippleFactor) & 0xf); 288 if (ctx->Line.StipplePattern & m) { 289 #endif 290 #if INTERP_Z 291 GLdepth Z = z0; 292 #endif 293 #if INTERP_INDEX 294 GLint I = i0 >> 8; 295 #endif 296 #if WIDE 297 GLint yy; 298 GLint ymin = y0 + min; 299 GLint ymax = y0 + max; 300 for (yy=ymin;yy<=ymax;yy++) { 301 PLOT( x0, yy ); 302 } 303 #else 304 # ifdef XMAJOR_PLOT 305 XMAJOR_PLOT( x0, y0 ); 306 # else 307 PLOT( x0, y0 ); 308 # endif 309 #endif /*WIDE*/ 310 #if STIPPLE 311 } 312 ctx->StippleCounter++; 313 #endif 314 #if INTERP_XY 315 x0 += xstep; 316 #endif 317 #if INTERP_Z 318 zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrXstep); 319 z0 += dz; 320 #endif 321 #if INTERP_RGB 322 r0 += dr; 323 g0 += dg; 324 b0 += db; 325 #endif 326 #if INTERP_ALPHA 327 a0 += da; 328 #endif 329 #if INTERP_INDEX 330 i0 += di; 331 #endif 332 #if INTERP_ST 333 s0 += ds; 334 t0 += dt; 335 #endif 336 #if INTERP_STW 337 s0 += ds; 338 t0 += dt; 339 w0 += dw; 340 #endif 341 #if INTERP_UV 342 u0 += du; 343 v0 += dv; 344 #endif 345 #ifdef PIXEL_ADDRESS 346 pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep); 347 #endif 348 if (error<0) { 349 error += errorInc; 350 } 351 else { 352 error += errorDec; 353 #if INTERP_XY 354 y0 += ystep; 355 #endif 356 #if INTERP_Z 357 zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrYstep); 358 #endif 359 #ifdef PIXEL_ADDRESS 360 pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep); 361 #endif 362 } 363 } 364 } 365 else { 366 /* 367 * Y-major line 368 */ 369 GLint i; 370 GLint errorInc = dx+dx; 371 GLint error = errorInc-dy; 372 GLint errorDec = error-dy; 373 #if INTERP_Z 374 dz = (z1-z0) / dy; 375 #endif 376 #if INTERP_RGB 377 dr /= dy; /* convert from whole line delta to per-pixel delta */ 378 dg /= dy; 379 db /= dy; 380 #endif 381 #if INTERP_ALPHA 382 da /= dy; 383 #endif 384 #if INTERP_INDEX 385 di /= dy; 386 #endif 387 #if INTERP_ST 388 ds /= dy; 389 dt /= dy; 390 #endif 391 #if INTERP_STW 392 { 393 GLfloat fdyinv = 1.0F / (GLfloat) dy; 394 ds *= fdyinv; 395 dt *= fdyinv; 396 dw *= fdyinv; 397 #if INTERP_UV 398 du *= fdyinv; 399 dv *= fdyinv; 400 #endif 401 } 402 #endif 403 for (i=0;i<dy;i++) { 404 #if STIPPLE 405 GLushort m; 406 m = 1 << ((ctx->StippleCounter/ctx->Line.StippleFactor) & 0xf); 407 if (ctx->Line.StipplePattern & m) { 408 #endif 409 #if INTERP_Z 410 GLdepth Z = z0; 411 #endif 412 #if INTERP_INDEX 413 GLint I = i0 >> 8; 414 #endif 415 #if WIDE 416 GLint xx; 417 GLint xmin = x0 + min; 418 GLint xmax = x0 + max; 419 for (xx=xmin;xx<=xmax;xx++) { 420 PLOT( xx, y0 ); 421 } 422 #else 423 # ifdef YMAJOR_PLOT 424 YMAJOR_PLOT( x0, y0 ); 425 # else 426 PLOT( x0, y0 ); 427 # endif 428 #endif /*WIDE*/ 429 #if STIPPLE 430 } 431 ctx->StippleCounter++; 432 #endif 433 #if INTERP_XY 434 y0 += ystep; 435 #endif 436 #if INTERP_Z 437 zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrYstep); 438 z0 += dz; 439 #endif 440 #if INTERP_RGB 441 r0 += dr; 442 g0 += dg; 443 b0 += db; 444 #endif 445 #if INTERP_ALPHA 446 a0 += da; 447 #endif 448 #if INTERP_INDEX 449 i0 += di; 450 #endif 451 #if INTERP_ST 452 s0 += ds; 453 t0 += dt; 454 #endif 455 #if INTERP_STW 456 s0 += ds; 457 t0 += dt; 458 w0 += dw; 459 #endif 460 #if INTERP_UV 461 u0 += du; 462 v0 += dv; 463 #endif 464 #ifdef PIXEL_ADDRESS 465 pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep); 466 #endif 467 if (error<0) { 468 error += errorInc; 469 } 470 else { 471 error += errorDec; 472 #if INTERP_XY 473 x0 += xstep; 474 #endif 475 #if INTERP_Z 476 zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrXstep); 477 #endif 478 #ifdef PIXEL_ADDRESS 479 pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep); 480 #endif 481 } 482 } 483 } 484 485 } 486 487 488 #undef INTERP_XY 489 #undef INTERP_Z 490 #undef INTERP_RGB 491 #undef INTERP_ALPHA 492 #undef INTERP_INDEX 493 #undef PIXEL_ADDRESS 494 #undef PIXEL_TYPE 495 #undef BYTES_PER_ROW 496 #undef SETUP_CODE 497 #undef PLOT 498 #undef XMAJOR_PLOT 499 #undef YMAJOR_PLOT 500 #undef CLIP_HACK 501 #undef STIPPLE 502 #undef WIDE 503