1 /* $Id: linetemp.h,v 1.4 1998/01/16 03:46:07 brianp Exp $ */
4 * Mesa 3-D graphics library
6 * Copyright (C) 1995-1997 Brian Paul
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.
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.
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.
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)
29 * Revision 1.3 1997/06/20 02:49:53 brianp
30 * changed color components from GLfixed to GLubyte
32 * Revision 1.2 1997/05/16 01:54:54 brianp
33 * zPtrYstep calculation was negated!
35 * Revision 1.1 1997/03/16 02:07:56 brianp
42 * Line Rasterizer Template
44 * This file is #include'd to generate custom line rasterizers.
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)
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.
67 * Optionally, one may provide one-time setup code
68 * SETUP_CODE - code which is to be executed once per line
70 * To enable line stippling define STIPPLE = 1
71 * To enable wide lines define WIDE = 1
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:
78 * color = pack_rgb( FixedToInt(r0), FixedToInt(g0),
80 * put_pixel( X, Y, color );
83 * This code was designed for the origin to be in the lower-left corner.
88 /*void line( GLcontext *ctx, GLuint vert0, GLuint vert1, GLuint pvert )*/
90 struct vertex_buffer
*VB
= ctx
->VB
;
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;
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];
102 GLint z0
, z1
, dz
, zPtrXstep
, zPtrYstep
;
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
;
114 GLfixed a0
= IntToFixed(VB
->Color
[vert0
][3]);
115 GLfixed da
= IntToFixed(VB
->Color
[vert1
][3]) - a0
;
118 GLint i0
= VB
->Index
[vert0
] << 8, di
= (GLint
) (VB
->Index
[vert1
] << 8)-i0
;
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
;
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
;
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
;
136 PIXEL_TYPE
*pixelPtr
;
137 GLint pixelXstep
, pixelYstep
;
141 GLint width
, min
, max
;
142 width
= (GLint
) CLAMP( ctx
->Line
.Width
, MIN_LINE_WIDTH
, MAX_LINE_WIDTH
);
144 max
= min
+ width
- 1;
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
156 GLint w
= ctx
->Buffer
->Width
;
157 GLint h
= ctx
->Buffer
->Height
;
158 if ((x0
==w
) | (x1
==w
)) {
159 if ((x0
==w
) & (x1
==w
))
164 if ((y0
==h
) | (y1
==h
)) {
165 if ((y0
==h
) & (y1
==h
))
174 if (dx
==0 && dy
==0) {
186 zPtr
= Z_ADDRESS(ctx
,x0
,y0
);
187 z0
= (int) VB
->Win
[vert0
][2];
188 z1
= (int) VB
->Win
[vert1
][2];
191 pixelPtr
= (PIXEL_TYPE
*) PIXEL_ADDRESS(x0
,y0
);
195 dx
= -dx
; /* make positive */
200 zPtrXstep
= -((GLint
)sizeof(GLdepth
));
203 pixelXstep
= -sizeof(PIXEL_TYPE
);
211 zPtrXstep
= sizeof(GLdepth
);
214 pixelXstep
= sizeof(PIXEL_TYPE
);
219 dy
= -dy
; /* make positive */
224 zPtrYstep
= -ctx
->Buffer
->Width
* sizeof(GLdepth
);
227 pixelYstep
= BYTES_PER_ROW
;
235 zPtrYstep
= ctx
->Buffer
->Width
* sizeof(GLdepth
);
238 pixelYstep
= -(BYTES_PER_ROW
);
251 GLint errorInc
= dy
+dy
;
252 GLint error
= errorInc
-dx
;
253 GLint errorDec
= error
-dx
;
258 dr
/= dx
; /* convert from whole line delta to per-pixel delta */
274 GLfloat fdxinv
= 1.0F
/ (GLfloat
) dx
;
287 m
= 1 << ((ctx
->StippleCounter
/ctx
->Line
.StippleFactor
) & 0xf);
288 if (ctx
->Line
.StipplePattern
& m
) {
298 GLint ymin
= y0
+ min
;
299 GLint ymax
= y0
+ max
;
300 for (yy
=ymin
;yy
<=ymax
;yy
++) {
305 XMAJOR_PLOT( x0
, y0
);
312 ctx
->StippleCounter
++;
318 zPtr
= (GLdepth
*) ((GLubyte
*) zPtr
+ zPtrXstep
);
346 pixelPtr
= (PIXEL_TYPE
*) ((GLubyte
*) pixelPtr
+ pixelXstep
);
357 zPtr
= (GLdepth
*) ((GLubyte
*) zPtr
+ zPtrYstep
);
360 pixelPtr
= (PIXEL_TYPE
*) ((GLubyte
*) pixelPtr
+ pixelYstep
);
370 GLint errorInc
= dx
+dx
;
371 GLint error
= errorInc
-dy
;
372 GLint errorDec
= error
-dy
;
377 dr
/= dy
; /* convert from whole line delta to per-pixel delta */
393 GLfloat fdyinv
= 1.0F
/ (GLfloat
) dy
;
406 m
= 1 << ((ctx
->StippleCounter
/ctx
->Line
.StippleFactor
) & 0xf);
407 if (ctx
->Line
.StipplePattern
& m
) {
417 GLint xmin
= x0
+ min
;
418 GLint xmax
= x0
+ max
;
419 for (xx
=xmin
;xx
<=xmax
;xx
++) {
424 YMAJOR_PLOT( x0
, y0
);
431 ctx
->StippleCounter
++;
437 zPtr
= (GLdepth
*) ((GLubyte
*) zPtr
+ zPtrYstep
);
465 pixelPtr
= (PIXEL_TYPE
*) ((GLubyte
*) pixelPtr
+ pixelYstep
);
476 zPtr
= (GLdepth
*) ((GLubyte
*) zPtr
+ zPtrXstep
);
479 pixelPtr
= (PIXEL_TYPE
*) ((GLubyte
*) pixelPtr
+ pixelXstep
);