source: trunk/src/opengl/mesa/linetemp.h@ 2938

Last change on this file since 2938 was 2938, checked in by sandervl, 25 years ago

created

File size: 15.5 KB
Line 
1/* $Id: linetemp.h,v 1.1 2000-02-29 00:48:32 sandervl Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 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 * Line Rasterizer Template
30 *
31 * This file is #include'd to generate custom line rasterizers.
32 *
33 * The following macros may be defined to indicate what auxillary information
34 * must be interplated along the line:
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_ST - if defined, interpolate integer ST texcoords
41 * (fast, simple 2-D texture mapping)
42 * INTERP_STUV0 - if defined, interpolate unit 0 STU texcoords with
43 * perspective correction
44 * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
45 * INTERP_STUV1 - if defined, interpolate unit 1 STU texcoords
46 *
47 * When one can directly address pixels in the color buffer the following
48 * macros can be defined and used to directly compute pixel addresses during
49 * rasterization (see pixelPtr):
50 * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint)
51 * BYTES_PER_ROW - number of bytes per row in the color buffer
52 * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where
53 * Y==0 at bottom of screen and increases upward.
54 *
55 * Optionally, one may provide one-time setup code
56 * SETUP_CODE - code which is to be executed once per line
57 *
58 * To enable line stippling define STIPPLE = 1
59 * To enable wide lines define WIDE = 1
60 *
61 * To actually "plot" each pixel either the PLOT macro or
62 * (XMAJOR_PLOT and YMAJOR_PLOT macros) must be defined...
63 * PLOT(X,Y) - code to plot a pixel. Example:
64 * if (Z < *zPtr) {
65 * *zPtr = Z;
66 * color = pack_rgb( FixedToInt(r0), FixedToInt(g0),
67 * FixedToInt(b0) );
68 * put_pixel( X, Y, color );
69 * }
70 *
71 * This code was designed for the origin to be in the lower-left corner.
72 *
73 */
74
75
76/*void line( GLcontext *ctx, GLuint vert0, GLuint vert1, GLuint pvert )*/
77{
78 const struct vertex_buffer *VB = ctx->VB;
79 GLint x0 = (GLint) VB->Win.data[vert0][0];
80 GLint x1 = (GLint) VB->Win.data[vert1][0];
81 GLint y0 = (GLint) VB->Win.data[vert0][1];
82 GLint y1 = (GLint) VB->Win.data[vert1][1];
83 GLint dx, dy;
84#if INTERP_XY
85 GLint xstep, ystep;
86#endif
87#if INTERP_Z
88 GLint z0, z1, dz, zPtrXstep, zPtrYstep;
89 GLdepth *zPtr;
90#endif
91#if INTERP_RGB
92 GLfixed r0 = IntToFixed(VB->ColorPtr->data[vert0][0]);
93 GLfixed dr = IntToFixed(VB->ColorPtr->data[vert1][0]) - r0;
94 GLfixed g0 = IntToFixed(VB->ColorPtr->data[vert0][1]);
95 GLfixed dg = IntToFixed(VB->ColorPtr->data[vert1][1]) - g0;
96 GLfixed b0 = IntToFixed(VB->ColorPtr->data[vert0][2]);
97 GLfixed db = IntToFixed(VB->ColorPtr->data[vert1][2]) - b0;
98#endif
99#if INTERP_SPEC
100 GLfixed sr0 = VB->Specular ? IntToFixed(VB->Specular[vert0][0]) : 0;
101 GLfixed dsr = VB->Specular ? IntToFixed(VB->Specular[vert1][0]) - sr0 : 0;
102 GLfixed sg0 = VB->Specular ? IntToFixed(VB->Specular[vert0][1]) : 0;
103 GLfixed dsg = VB->Specular ? IntToFixed(VB->Specular[vert1][1]) - sg0 : 0;
104 GLfixed sb0 = VB->Specular ? IntToFixed(VB->Specular[vert0][2]) : 0;
105 GLfixed dsb = VB->Specular ? IntToFixed(VB->Specular[vert1][2]) - sb0 : 0;
106#endif
107#if INTERP_ALPHA
108 GLfixed a0 = IntToFixed(VB->ColorPtr->data[vert0][3]);
109 GLfixed da = IntToFixed(VB->ColorPtr->data[vert1][3]) - a0;
110#endif
111#if INTERP_INDEX
112 GLint i0 = VB->IndexPtr->data[vert0] << 8;
113 GLint di = (GLint) (VB->IndexPtr->data[vert1] << 8)-i0;
114#endif
115#if INTERP_ST
116 GLfixed s0 = FloatToFixed(VB->TexCoord[vert0][0] * S_SCALE);
117 GLfixed ds = FloatToFixed(VB->TexCoord[vert1][0] * S_SCALE) - s0;
118 GLfixed t0 = FloatToFixed(VB->TexCoord[vert0][1] * T_SCALE);
119 GLfixed dt = FloatToFixed(VB->TexCoord[vert1][1] * T_SCALE) - t0;
120#endif
121#if INTERP_STUV0 || INTERP_STUV1
122 GLfloat invw0 = VB->Win.data[vert0][3];
123 GLfloat invw1 = VB->Win.data[vert1][3];
124#endif
125#if INTERP_STUV0
126 /* h denotes hyperbolic */
127 GLfloat hs0 = invw0 * VB->TexCoordPtr[0]->data[vert0][0];
128 GLfloat dhs = invw1 * VB->TexCoordPtr[0]->data[vert1][0] - hs0;
129 GLfloat ht0 = invw0 * VB->TexCoordPtr[0]->data[vert0][1];
130 GLfloat dht = invw1 * VB->TexCoordPtr[0]->data[vert1][1] - ht0;
131 GLfloat hu0 = 0, dhu = 0;
132 GLfloat hv0 = invw0, dhv = invw1 - invw0;
133#endif
134#if INTERP_STUV1
135 GLfloat hs01 = invw0 * VB->TexCoordPtr[1]->data[vert0][0];
136 GLfloat dhs1 = invw1 * VB->TexCoordPtr[1]->data[vert1][0] - hs01;
137 GLfloat ht01 = invw0 * VB->TexCoordPtr[1]->data[vert0][1];
138 GLfloat dht1 = invw1 * VB->TexCoordPtr[1]->data[vert1][1] - ht01;
139 GLfloat hu01 = 0, dhu1 = 0;
140 GLfloat hv01 = invw0, dhv1 = invw1 - invw0;
141#endif
142#ifdef PIXEL_ADDRESS
143 PIXEL_TYPE *pixelPtr;
144 GLint pixelXstep, pixelYstep;
145#endif
146#if WIDE
147 /* for wide lines, draw all X in [x+min, x+max] or Y in [y+min, y+max] */
148 GLint width, min, max;
149 width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
150 min = (width-1) / -2;
151 max = min + width - 1;
152#endif
153#if INTERP_STUV0
154 if (VB->TexCoordPtr[0]->size > 2) {
155 hu0 = invw0 * VB->TexCoordPtr[0]->data[vert0][2];
156 dhu = invw1 * VB->TexCoordPtr[0]->data[vert1][2] - hu0;
157 if (VB->TexCoordPtr[0]->size > 3) {
158 hv0 = invw0 * VB->TexCoordPtr[0]->data[vert0][3];
159 dhv = invw1 * VB->TexCoordPtr[0]->data[vert1][3] - hv0;
160 }
161 }
162#endif
163#if INTERP_STUV1
164 if (VB->TexCoordPtr[1]->size > 2) {
165 hu01 = invw0 * VB->TexCoordPtr[1]->data[vert0][2];
166 dhu1 = invw1 * VB->TexCoordPtr[1]->data[vert1][2] - hu01;
167 if (VB->TexCoordPtr[1]->size > 3) {
168 hv01 = invw0 * VB->TexCoordPtr[1]->data[vert0][3];
169 dhv1 = invw1 * VB->TexCoordPtr[1]->data[vert1][3] - hv01;
170 }
171 }
172#endif
173
174/*
175 * Despite being clipped to the view volume, the line's window coordinates
176 * may just lie outside the window bounds. That is, if the legal window
177 * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H.
178 * This quick and dirty code nudges the endpoints inside the window if
179 * necessary.
180 */
181#if CLIP_HACK
182 {
183 GLint w = ctx->Buffer->Width;
184 GLint h = ctx->Buffer->Height;
185 if ((x0==w) | (x1==w)) {
186 if ((x0==w) & (x1==w))
187 return;
188 x0 -= x0==w;
189 x1 -= x1==w;
190 }
191 if ((y0==h) | (y1==h)) {
192 if ((y0==h) & (y1==h))
193 return;
194 y0 -= y0==h;
195 y1 -= y1==h;
196 }
197 }
198#endif
199 dx = x1 - x0;
200 dy = y1 - y0;
201 if (dx==0 && dy==0) {
202 return;
203 }
204
205 /*
206 * Setup
207 */
208#ifdef SETUP_CODE
209 SETUP_CODE
210#endif
211
212#if INTERP_Z
213 zPtr = Z_ADDRESS(ctx,x0,y0);
214# if DEPTH_BITS==16
215 z0 = FloatToFixed(VB->Win.data[vert0][2]);
216 z1 = FloatToFixed(VB->Win.data[vert1][2]);
217# else
218 z0 = (int) VB->Win.data[vert0][2];
219 z1 = (int) VB->Win.data[vert1][2];
220# endif
221#endif
222#ifdef PIXEL_ADDRESS
223 pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0);
224#endif
225
226 if (dx<0) {
227 dx = -dx; /* make positive */
228#if INTERP_XY
229 xstep = -1;
230#endif
231#ifdef INTERP_Z
232 zPtrXstep = -((GLint)sizeof(GLdepth));
233#endif
234#ifdef PIXEL_ADDRESS
235 pixelXstep = -((GLint)sizeof(PIXEL_TYPE));
236#endif
237 }
238 else {
239#if INTERP_XY
240 xstep = 1;
241#endif
242#if INTERP_Z
243 zPtrXstep = ((GLint)sizeof(GLdepth));
244#endif
245#ifdef PIXEL_ADDRESS
246 pixelXstep = ((GLint)sizeof(PIXEL_TYPE));
247#endif
248 }
249
250 if (dy<0) {
251 dy = -dy; /* make positive */
252#if INTERP_XY
253 ystep = -1;
254#endif
255#if INTERP_Z
256 zPtrYstep = -ctx->Buffer->Width * ((GLint)sizeof(GLdepth));
257#endif
258#ifdef PIXEL_ADDRESS
259 pixelYstep = BYTES_PER_ROW;
260#endif
261 }
262 else {
263#if INTERP_XY
264 ystep = 1;
265#endif
266#if INTERP_Z
267 zPtrYstep = ctx->Buffer->Width * ((GLint)sizeof(GLdepth));
268#endif
269#ifdef PIXEL_ADDRESS
270 pixelYstep = -(BYTES_PER_ROW);
271#endif
272 }
273
274 /*
275 * Draw
276 */
277
278 if (dx>dy) {
279 /*** X-major line ***/
280 GLint i;
281 GLint errorInc = dy+dy;
282 GLint error = errorInc-dx;
283 GLint errorDec = error-dx;
284#if INTERP_Z
285 dz = (z1-z0) / dx;
286#endif
287#if INTERP_RGB
288 dr /= dx; /* convert from whole line delta to per-pixel delta */
289 dg /= dx;
290 db /= dx;
291#endif
292#if INTERP_SPEC
293 dsr /= dx; /* convert from whole line delta to per-pixel delta */
294 dsg /= dx;
295 dsb /= dx;
296#endif
297#if INTERP_ALPHA
298 da /= dx;
299#endif
300#if INTERP_INDEX
301 di /= dx;
302#endif
303#if INTERP_ST
304 ds /= dx;
305 dt /= dx;
306#endif
307#if INTERP_STUV0
308 {
309 GLfloat invDx = 1.0F / (GLfloat) dx;
310 dhs *= invDx;
311 dht *= invDx;
312 dhu *= invDx;
313 dhv *= invDx;
314 }
315#endif
316#if INTERP_STUV1
317 {
318 GLfloat invDx = 1.0F / (GLfloat) dx;
319 dhs1 *= invDx;
320 dht1 *= invDx;
321 dhu1 *= invDx;
322 dhv1 *= invDx;
323 }
324#endif
325 for (i=0;i<dx;i++) {
326#if STIPPLE
327 GLushort m;
328 m = 1 << ((ctx->StippleCounter/ctx->Line.StippleFactor) & 0xf);
329 if (ctx->Line.StipplePattern & m) {
330#endif
331#if INTERP_Z
332# if DEPTH_BITS==16
333 GLdepth Z = FixedToInt(z0);
334# else
335 GLdepth Z = z0;
336# endif
337#endif
338#if INTERP_INDEX
339 GLint I = i0 >> 8;
340#endif
341#if INTERP_STUV0
342 GLfloat invQ = 1.0F / hv0;
343 GLfloat s = hs0 * invQ;
344 GLfloat t = ht0 * invQ;
345 GLfloat u = hu0 * invQ;
346#endif
347#if INTERP_STUV1
348 GLfloat invQ1 = 1.0F / hv01;
349 GLfloat s1 = hs01 * invQ1;
350 GLfloat t1 = ht01 * invQ1;
351 GLfloat u1 = hu01 * invQ1;
352#endif
353#if WIDE
354 GLint yy;
355 GLint ymin = y0 + min;
356 GLint ymax = y0 + max;
357 for (yy=ymin;yy<=ymax;yy++) {
358 PLOT( x0, yy );
359 }
360#else
361# ifdef XMAJOR_PLOT
362 XMAJOR_PLOT( x0, y0 );
363# else
364 PLOT( x0, y0 );
365# endif
366#endif /*WIDE*/
367#if STIPPLE
368 }
369 ctx->StippleCounter++;
370#endif
371#if INTERP_XY
372 x0 += xstep;
373#endif
374#if INTERP_Z
375 zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrXstep);
376 z0 += dz;
377#endif
378#if INTERP_RGB
379 r0 += dr;
380 g0 += dg;
381 b0 += db;
382#endif
383#if INTERP_SPEC
384 sr0 += dsr;
385 sg0 += dsg;
386 sb0 += dsb;
387#endif
388#if INTERP_ALPHA
389 a0 += da;
390#endif
391#if INTERP_INDEX
392 i0 += di;
393#endif
394#if INTERP_ST
395 s0 += ds;
396 t0 += dt;
397#endif
398#if INTERP_STUV0
399 hs0 += dhs;
400 ht0 += dht;
401 hu0 += dhu;
402 hv0 += dhv;
403#endif
404#if INTERP_STUV1
405 hs01 += dhs1;
406 ht01 += dht1;
407 hu01 += dhu1;
408 hv01 += dhv1;
409#endif
410#ifdef PIXEL_ADDRESS
411 pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
412#endif
413 if (error<0) {
414 error += errorInc;
415 }
416 else {
417 error += errorDec;
418#if INTERP_XY
419 y0 += ystep;
420#endif
421#if INTERP_Z
422 zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrYstep);
423#endif
424#ifdef PIXEL_ADDRESS
425 pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
426#endif
427 }
428 }
429 }
430 else {
431 /*** Y-major line ***/
432 GLint i;
433 GLint errorInc = dx+dx;
434 GLint error = errorInc-dy;
435 GLint errorDec = error-dy;
436#if INTERP_Z
437 dz = (z1-z0) / dy;
438#endif
439#if INTERP_RGB
440 dr /= dy; /* convert from whole line delta to per-pixel delta */
441 dg /= dy;
442 db /= dy;
443#endif
444#if INTERP_SPEC
445 dsr /= dy; /* convert from whole line delta to per-pixel delta */
446 dsg /= dy;
447 dsb /= dy;
448#endif
449#if INTERP_ALPHA
450 da /= dy;
451#endif
452#if INTERP_INDEX
453 di /= dy;
454#endif
455#if INTERP_ST
456 ds /= dy;
457 dt /= dy;
458#endif
459#if INTERP_STUV0
460 {
461 GLfloat invDy = 1.0F / (GLfloat) dy;
462 dhs *= invDy;
463 dht *= invDy;
464 dhu *= invDy;
465 dhv *= invDy;
466 }
467#endif
468#if INTERP_STUV1
469 {
470 GLfloat invDy = 1.0F / (GLfloat) dy;
471 dhs1 *= invDy;
472 dht1 *= invDy;
473 dhu1 *= invDy;
474 dhv1 *= invDy;
475 }
476#endif
477 for (i=0;i<dy;i++) {
478#if STIPPLE
479 GLushort m;
480 m = 1 << ((ctx->StippleCounter/ctx->Line.StippleFactor) & 0xf);
481 if (ctx->Line.StipplePattern & m) {
482#endif
483#if INTERP_Z
484# if DEPTH_BITS==16
485 GLdepth Z = FixedToInt(z0);
486# else
487 GLdepth Z = z0;
488# endif
489#endif
490#if INTERP_INDEX
491 GLint I = i0 >> 8;
492#endif
493#if INTERP_STUV0
494 GLfloat invQ = 1.0F / hv0;
495 GLfloat s = hs0 * invQ;
496 GLfloat t = ht0 * invQ;
497 GLfloat u = hu0 * invQ;
498#endif
499#if INTERP_STUV1
500 GLfloat invQ1 = 1.0F / hv01;
501 GLfloat s1 = hs01 * invQ1;
502 GLfloat t1 = ht01 * invQ1;
503 GLfloat u1 = hu01 * invQ1;
504#endif
505#if WIDE
506 GLint xx;
507 GLint xmin = x0 + min;
508 GLint xmax = x0 + max;
509 for (xx=xmin;xx<=xmax;xx++) {
510 PLOT( xx, y0 );
511 }
512#else
513# ifdef YMAJOR_PLOT
514 YMAJOR_PLOT( x0, y0 );
515# else
516 PLOT( x0, y0 );
517# endif
518#endif /*WIDE*/
519#if STIPPLE
520 }
521 ctx->StippleCounter++;
522#endif
523#if INTERP_XY
524 y0 += ystep;
525#endif
526#if INTERP_Z
527 zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrYstep);
528 z0 += dz;
529#endif
530#if INTERP_RGB
531 r0 += dr;
532 g0 += dg;
533 b0 += db;
534#endif
535#if INTERP_SPEC
536 sr0 += dsr;
537 sg0 += dsg;
538 sb0 += dsb;
539#endif
540#if INTERP_ALPHA
541 a0 += da;
542#endif
543#if INTERP_INDEX
544 i0 += di;
545#endif
546#if INTERP_ST
547 s0 += ds;
548 t0 += dt;
549#endif
550#if INTERP_STUV0
551 hs0 += dhs;
552 ht0 += dht;
553 hu0 += dhu;
554 hv0 += dhv;
555#endif
556#if INTERP_STUV1
557 hs01 += dhs1;
558 ht01 += dht1;
559 hu01 += dhu1;
560 hv01 += dhv1;
561#endif
562#ifdef PIXEL_ADDRESS
563 pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
564#endif
565 if (error<0) {
566 error += errorInc;
567 }
568 else {
569 error += errorDec;
570#if INTERP_XY
571 x0 += xstep;
572#endif
573#if INTERP_Z
574 zPtr = (GLdepth *) ((GLubyte*) zPtr + zPtrXstep);
575#endif
576#ifdef PIXEL_ADDRESS
577 pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
578#endif
579 }
580 }
581 }
582
583}
584
585
586#undef INTERP_XY
587#undef INTERP_Z
588#undef INTERP_RGB
589#undef INTERP_SPEC
590#undef INTERP_ALPHA
591#undef INTERP_STUV0
592#undef INTERP_STUV1
593#undef INTERP_INDEX
594#undef PIXEL_ADDRESS
595#undef PIXEL_TYPE
596#undef BYTES_PER_ROW
597#undef SETUP_CODE
598#undef PLOT
599#undef XMAJOR_PLOT
600#undef YMAJOR_PLOT
601#undef CLIP_HACK
602#undef STIPPLE
603#undef WIDE
Note: See TracBrowser for help on using the repository browser.