xref: /reactos/dll/opengl/mesa/linetemp.h (revision 5f2bebf7)
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