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

Last change on this file since 3598 was 3597, checked in by jeroen, 25 years ago

* empty log message *

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