My last attempt to fix polygon offsets with the reversed viewport depth
[mesa.git] / src / mesa / tnl_dd / t_dd_tritmp.h
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 3.5
5 *
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29
30 /* Template for building functions to plug into the driver interface
31 * of t_vb_render.c:
32 * ctx->Driver.QuadFunc
33 * ctx->Driver.TriangleFunc
34 * ctx->Driver.LineFunc
35 * ctx->Driver.PointsFunc
36 *
37 * DO_TWOSIDE: Plug back-color values from the VB into backfacing triangles,
38 * and restore vertices afterwards.
39 * DO_OFFSET: Calculate offset for triangles and adjust vertices. Restore
40 * vertices after rendering.
41 * DO_FLAT: For hardware without native flatshading, copy provoking colors
42 * into the other vertices. Restore after rendering.
43 * DO_UNFILLED: Decompose triangles to lines and points where appropriate.
44 * DO_TWOSTENCIL:Gross hack for two-sided stencil.
45 *
46 * HAVE_RGBA: Vertices have rgba values (otherwise index values).
47 * HAVE_SPEC: Vertices have secondary rgba values.
48 *
49 * VERT_X(v): Alias for vertex x value.
50 * VERT_Y(v): Alias for vertex y value.
51 * VERT_Z(v): Alias for vertex z value.
52 * DEPTH_SCALE: Scale for constant offset.
53 * REVERSE_DEPTH: Viewport depth range reversed.
54 *
55 * VERTEX: Hardware vertex type.
56 * GET_VERTEX(n): Retreive vertex with index n.
57 * AREA_IS_CCW(a): Return true if triangle with signed area a is ccw.
58 *
59 * VERT_SET_RGBA: Assign vertex rgba from VB color.
60 * VERT_COPY_RGBA: Copy vertex rgba another vertex.
61 * VERT_SAVE_RGBA: Save vertex rgba to a local variable.
62 * VERT_RESTORE_RGBA: Restore vertex rgba from a local variable.
63 * --> Similar for IND and SPEC.
64 *
65 * LOCAL_VARS(n): (At least) define local vars for save/restore rgba.
66 *
67 */
68
69 #if HAVE_RGBA
70 #define VERT_SET_IND( v, c ) (void) c
71 #define VERT_COPY_IND( v0, v1 )
72 #define VERT_SAVE_IND( idx )
73 #define VERT_RESTORE_IND( idx )
74 #if HAVE_BACK_COLORS
75 #define VERT_SET_RGBA( v, c )
76 #endif
77 #else
78 #define VERT_SET_RGBA( v, c ) (void) c
79 #define VERT_COPY_RGBA( v0, v1 )
80 #define VERT_SAVE_RGBA( idx )
81 #define VERT_RESTORE_RGBA( idx )
82 #if HAVE_BACK_COLORS
83 #define VERT_SET_IND( v, c )
84 #endif
85 #endif
86
87 #if !HAVE_SPEC
88 #define VERT_SET_SPEC( v, c ) (void) c
89 #define VERT_COPY_SPEC( v0, v1 )
90 #define VERT_SAVE_SPEC( idx )
91 #define VERT_RESTORE_SPEC( idx )
92 #if HAVE_BACK_COLORS
93 #define VERT_COPY_SPEC1( v )
94 #endif
95 #else
96 #if HAVE_BACK_COLORS
97 #define VERT_SET_SPEC( v, c )
98 #endif
99 #endif
100
101 #if !HAVE_BACK_COLORS
102 #define VERT_COPY_SPEC1( v )
103 #define VERT_COPY_IND1( v )
104 #define VERT_COPY_RGBA1( v )
105 #endif
106
107 #ifndef INSANE_VERTICES
108 #define VERT_SET_Z(v,val) VERT_Z(v) = val
109 #define VERT_Z_ADD(v,val) VERT_Z(v) += val
110 #endif
111
112 #ifndef REVERSE_DEPTH
113 #define REVERSE_DEPTH 0
114 #endif
115
116 /* disable twostencil for un-aware drivers */
117 #ifndef HAVE_STENCIL_TWOSIDE
118 #define HAVE_STENCIL_TWOSIDE 0
119 #endif
120 #ifndef DO_TWOSTENCIL
121 #define DO_TWOSTENCIL 0
122 #endif
123 #ifndef SETUP_STENCIL
124 #define SETUP_STENCIL(f)
125 #endif
126 #ifndef UNSET_STENCIL
127 #define UNSET_STENCIL(f)
128 #endif
129
130 #if DO_TRI
131 static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
132 {
133 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
134 VERTEX *v[3];
135 GLfloat offset;
136 GLfloat z[3];
137 GLenum mode = GL_FILL;
138 GLuint facing;
139 LOCAL_VARS(3);
140
141 /* fprintf(stderr, "%s\n", __FUNCTION__); */
142
143 v[0] = (VERTEX *)GET_VERTEX(e0);
144 v[1] = (VERTEX *)GET_VERTEX(e1);
145 v[2] = (VERTEX *)GET_VERTEX(e2);
146
147 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
148 {
149 GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
150 GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
151 GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
152 GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
153 GLfloat cc = ex*fy - ey*fx;
154
155 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
156 {
157 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
158
159 if (DO_TWOSTENCIL && ctx->Stencil.TestTwoSide) {
160 ctx->_Facing = facing; /* mixed mode rendering: for 2-sided stencil test */
161 }
162
163 if (DO_UNFILLED) {
164 if (facing) {
165 mode = ctx->Polygon.BackMode;
166 if (ctx->Polygon.CullFlag &&
167 ctx->Polygon.CullFaceMode != GL_FRONT) {
168 return;
169 }
170 } else {
171 mode = ctx->Polygon.FrontMode;
172 if (ctx->Polygon.CullFlag &&
173 ctx->Polygon.CullFaceMode != GL_BACK) {
174 return;
175 }
176 }
177 }
178
179 if (DO_TWOSIDE && facing == 1)
180 {
181 if (HAVE_RGBA) {
182 if (HAVE_BACK_COLORS) {
183 if (!DO_FLAT) {
184 VERT_SAVE_RGBA( 0 );
185 VERT_SAVE_RGBA( 1 );
186 VERT_COPY_RGBA1( v[0] );
187 VERT_COPY_RGBA1( v[1] );
188 }
189 VERT_SAVE_RGBA( 2 );
190 VERT_COPY_RGBA1( v[2] );
191 if (HAVE_SPEC) {
192 if (!DO_FLAT) {
193 VERT_SAVE_SPEC( 0 );
194 VERT_SAVE_SPEC( 1 );
195 VERT_COPY_SPEC1( v[0] );
196 VERT_COPY_SPEC1( v[1] );
197 }
198 VERT_SAVE_SPEC( 2 );
199 VERT_COPY_SPEC1( v[2] );
200 }
201 }
202 else {
203 GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
204 (void) vbcolor;
205
206 if (!DO_FLAT) {
207 VERT_SAVE_RGBA( 0 );
208 VERT_SAVE_RGBA( 1 );
209 }
210 VERT_SAVE_RGBA( 2 );
211
212 if (VB->ColorPtr[1]->stride) {
213 ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
214
215 if (!DO_FLAT) {
216 VERT_SET_RGBA( v[0], vbcolor[e0] );
217 VERT_SET_RGBA( v[1], vbcolor[e1] );
218 }
219 VERT_SET_RGBA( v[2], vbcolor[e2] );
220 }
221 else {
222 if (!DO_FLAT) {
223 VERT_SET_RGBA( v[0], vbcolor[0] );
224 VERT_SET_RGBA( v[1], vbcolor[0] );
225 }
226 VERT_SET_RGBA( v[2], vbcolor[0] );
227 }
228
229 if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
230 GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
231 ASSERT(VB->SecondaryColorPtr[1]->stride == 4*sizeof(GLfloat));
232
233 if (!DO_FLAT) {
234 VERT_SAVE_SPEC( 0 );
235 VERT_SAVE_SPEC( 1 );
236 VERT_SET_SPEC( v[0], vbspec[e0] );
237 VERT_SET_SPEC( v[1], vbspec[e1] );
238 }
239 VERT_SAVE_SPEC( 2 );
240 VERT_SET_SPEC( v[2], vbspec[e2] );
241 }
242 }
243 }
244 else {
245 GLfloat (*vbindex) = (GLfloat *)VB->IndexPtr[1]->data;
246 if (!DO_FLAT) {
247 VERT_SAVE_IND( 0 );
248 VERT_SAVE_IND( 1 );
249 VERT_SET_IND( v[0], vbindex[e0] );
250 VERT_SET_IND( v[1], vbindex[e1] );
251 }
252 VERT_SAVE_IND( 2 );
253 VERT_SET_IND( v[2], vbindex[e2] );
254 }
255 }
256 }
257
258
259 if (DO_OFFSET)
260 {
261 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
262 z[0] = VERT_Z(v[0]);
263 z[1] = VERT_Z(v[1]);
264 z[2] = VERT_Z(v[2]);
265 if (cc * cc > 1e-16) {
266 GLfloat ic = 1.0 / cc;
267 GLfloat ez = z[0] - z[2];
268 GLfloat fz = z[1] - z[2];
269 GLfloat a = ey*fz - ez*fy;
270 GLfloat b = ez*fx - ex*fz;
271 GLfloat ac = a * ic;
272 GLfloat bc = b * ic;
273 if ( ac < 0.0f ) ac = -ac;
274 if ( bc < 0.0f ) bc = -bc;
275 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor;
276 }
277 offset *= REVERSE_DEPTH ? -ctx->MRD : ctx->MRD;
278 }
279 }
280
281 if (DO_FLAT) {
282 if (HAVE_RGBA) {
283 VERT_SAVE_RGBA( 0 );
284 VERT_SAVE_RGBA( 1 );
285 VERT_COPY_RGBA( v[0], v[2] );
286 VERT_COPY_RGBA( v[1], v[2] );
287 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
288 VERT_SAVE_SPEC( 0 );
289 VERT_SAVE_SPEC( 1 );
290 VERT_COPY_SPEC( v[0], v[2] );
291 VERT_COPY_SPEC( v[1], v[2] );
292 }
293 }
294 else {
295 VERT_SAVE_IND( 0 );
296 VERT_SAVE_IND( 1 );
297 VERT_COPY_IND( v[0], v[2] );
298 VERT_COPY_IND( v[1], v[2] );
299 }
300 }
301
302 if (mode == GL_POINT) {
303 if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
304 VERT_Z_ADD(v[0], offset);
305 VERT_Z_ADD(v[1], offset);
306 VERT_Z_ADD(v[2], offset);
307 }
308 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
309 SETUP_STENCIL(facing);
310 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
311 UNSET_STENCIL(facing);
312 } else {
313 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
314 }
315 } else if (mode == GL_LINE) {
316 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
317 VERT_Z_ADD(v[0], offset);
318 VERT_Z_ADD(v[1], offset);
319 VERT_Z_ADD(v[2], offset);
320 }
321 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
322 SETUP_STENCIL(facing);
323 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
324 UNSET_STENCIL(facing);
325 } else {
326 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
327 }
328 } else {
329 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
330 VERT_Z_ADD(v[0], offset);
331 VERT_Z_ADD(v[1], offset);
332 VERT_Z_ADD(v[2], offset);
333 }
334 if (DO_UNFILLED)
335 RASTERIZE( GL_TRIANGLES );
336 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
337 SETUP_STENCIL(facing);
338 TRI( v[0], v[1], v[2] );
339 UNSET_STENCIL(facing);
340 } else {
341 TRI( v[0], v[1], v[2] );
342 }
343 }
344
345 if (DO_OFFSET)
346 {
347 VERT_SET_Z(v[0], z[0]);
348 VERT_SET_Z(v[1], z[1]);
349 VERT_SET_Z(v[2], z[2]);
350 }
351
352 if (DO_TWOSIDE && facing == 1)
353 {
354 if (HAVE_RGBA) {
355 if (!DO_FLAT) {
356 VERT_RESTORE_RGBA( 0 );
357 VERT_RESTORE_RGBA( 1 );
358 }
359 VERT_RESTORE_RGBA( 2 );
360 if (HAVE_SPEC) {
361 if (!DO_FLAT) {
362 VERT_RESTORE_SPEC( 0 );
363 VERT_RESTORE_SPEC( 1 );
364 }
365 VERT_RESTORE_SPEC( 2 );
366 }
367 }
368 else {
369 if (!DO_FLAT) {
370 VERT_RESTORE_IND( 0 );
371 VERT_RESTORE_IND( 1 );
372 }
373 VERT_RESTORE_IND( 2 );
374 }
375 }
376
377
378 if (DO_FLAT) {
379 if (HAVE_RGBA) {
380 VERT_RESTORE_RGBA( 0 );
381 VERT_RESTORE_RGBA( 1 );
382 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
383 VERT_RESTORE_SPEC( 0 );
384 VERT_RESTORE_SPEC( 1 );
385 }
386 }
387 else {
388 VERT_RESTORE_IND( 0 );
389 VERT_RESTORE_IND( 1 );
390 }
391 }
392 }
393 #endif
394
395 #if DO_QUAD
396 #if DO_FULL_QUAD
397 static void TAG(quad)( GLcontext *ctx,
398 GLuint e0, GLuint e1, GLuint e2, GLuint e3 )
399 {
400 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
401 VERTEX *v[4];
402 GLfloat offset;
403 GLfloat z[4];
404 GLenum mode = GL_FILL;
405 GLuint facing;
406 LOCAL_VARS(4);
407
408 v[0] = (VERTEX *)GET_VERTEX(e0);
409 v[1] = (VERTEX *)GET_VERTEX(e1);
410 v[2] = (VERTEX *)GET_VERTEX(e2);
411 v[3] = (VERTEX *)GET_VERTEX(e3);
412
413 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
414 {
415 GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
416 GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
417 GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
418 GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
419 GLfloat cc = ex*fy - ey*fx;
420
421 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
422 {
423 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
424
425 if (DO_TWOSTENCIL && ctx->Stencil.TestTwoSide) {
426 ctx->_Facing = facing; /* mixed mode rendering: for 2-sided stencil test */
427 }
428
429 if (DO_UNFILLED) {
430 if (facing) {
431 mode = ctx->Polygon.BackMode;
432 if (ctx->Polygon.CullFlag &&
433 ctx->Polygon.CullFaceMode != GL_FRONT) {
434 return;
435 }
436 } else {
437 mode = ctx->Polygon.FrontMode;
438 if (ctx->Polygon.CullFlag &&
439 ctx->Polygon.CullFaceMode != GL_BACK) {
440 return;
441 }
442 }
443 }
444
445 if (DO_TWOSIDE && facing == 1)
446 {
447 if (HAVE_RGBA) {
448 GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
449 (void)vbcolor;
450
451 if (HAVE_BACK_COLORS) {
452 if (!DO_FLAT) {
453 VERT_SAVE_RGBA( 0 );
454 VERT_SAVE_RGBA( 1 );
455 VERT_SAVE_RGBA( 2 );
456 VERT_COPY_RGBA1( v[0] );
457 VERT_COPY_RGBA1( v[1] );
458 VERT_COPY_RGBA1( v[2] );
459 }
460 VERT_SAVE_RGBA( 3 );
461 VERT_COPY_RGBA1( v[3] );
462 if (HAVE_SPEC) {
463 if (!DO_FLAT) {
464 VERT_SAVE_SPEC( 0 );
465 VERT_SAVE_SPEC( 1 );
466 VERT_SAVE_SPEC( 2 );
467 VERT_COPY_SPEC1( v[0] );
468 VERT_COPY_SPEC1( v[1] );
469 VERT_COPY_SPEC1( v[2] );
470 }
471 VERT_SAVE_SPEC( 3 );
472 VERT_COPY_SPEC1( v[3] );
473 }
474 }
475 else {
476 if (!DO_FLAT) {
477 VERT_SAVE_RGBA( 0 );
478 VERT_SAVE_RGBA( 1 );
479 VERT_SAVE_RGBA( 2 );
480 }
481 VERT_SAVE_RGBA( 3 );
482
483 if (VB->ColorPtr[1]->stride) {
484 if (!DO_FLAT) {
485 VERT_SET_RGBA( v[0], vbcolor[e0] );
486 VERT_SET_RGBA( v[1], vbcolor[e1] );
487 VERT_SET_RGBA( v[2], vbcolor[e2] );
488 }
489 VERT_SET_RGBA( v[3], vbcolor[e3] );
490 }
491 else {
492 if (!DO_FLAT) {
493 VERT_SET_RGBA( v[0], vbcolor[0] );
494 VERT_SET_RGBA( v[1], vbcolor[0] );
495 VERT_SET_RGBA( v[2], vbcolor[0] );
496 }
497 VERT_SET_RGBA( v[3], vbcolor[0] );
498 }
499
500 if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
501 GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
502 ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
503
504 if (!DO_FLAT) {
505 VERT_SAVE_SPEC( 0 );
506 VERT_SAVE_SPEC( 1 );
507 VERT_SAVE_SPEC( 2 );
508 VERT_SET_SPEC( v[0], vbspec[e0] );
509 VERT_SET_SPEC( v[1], vbspec[e1] );
510 VERT_SET_SPEC( v[2], vbspec[e2] );
511 }
512 VERT_SAVE_SPEC( 3 );
513 VERT_SET_SPEC( v[3], vbspec[e3] );
514 }
515 }
516 }
517 else {
518 GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
519 if (!DO_FLAT) {
520 VERT_SAVE_IND( 0 );
521 VERT_SAVE_IND( 1 );
522 VERT_SAVE_IND( 2 );
523 VERT_SET_IND( v[0], vbindex[e0] );
524 VERT_SET_IND( v[1], vbindex[e1] );
525 VERT_SET_IND( v[2], vbindex[e2] );
526 }
527 VERT_SAVE_IND( 3 );
528 VERT_SET_IND( v[3], vbindex[e3] );
529 }
530 }
531 }
532
533
534 if (DO_OFFSET)
535 {
536 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
537 z[0] = VERT_Z(v[0]);
538 z[1] = VERT_Z(v[1]);
539 z[2] = VERT_Z(v[2]);
540 z[3] = VERT_Z(v[3]);
541 if (cc * cc > 1e-16) {
542 GLfloat ez = z[2] - z[0];
543 GLfloat fz = z[3] - z[1];
544 GLfloat a = ey*fz - ez*fy;
545 GLfloat b = ez*fx - ex*fz;
546 GLfloat ic = 1.0 / cc;
547 GLfloat ac = a * ic;
548 GLfloat bc = b * ic;
549 if ( ac < 0.0f ) ac = -ac;
550 if ( bc < 0.0f ) bc = -bc;
551 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor;
552 }
553 offset *= REVERSE_DEPTH ? -ctx->MRD : ctx->MRD;
554 }
555 }
556
557 if (DO_FLAT) {
558 if (HAVE_RGBA) {
559 VERT_SAVE_RGBA( 0 );
560 VERT_SAVE_RGBA( 1 );
561 VERT_SAVE_RGBA( 2 );
562 VERT_COPY_RGBA( v[0], v[3] );
563 VERT_COPY_RGBA( v[1], v[3] );
564 VERT_COPY_RGBA( v[2], v[3] );
565 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
566 VERT_SAVE_SPEC( 0 );
567 VERT_SAVE_SPEC( 1 );
568 VERT_SAVE_SPEC( 2 );
569 VERT_COPY_SPEC( v[0], v[3] );
570 VERT_COPY_SPEC( v[1], v[3] );
571 VERT_COPY_SPEC( v[2], v[3] );
572 }
573 }
574 else {
575 VERT_SAVE_IND( 0 );
576 VERT_SAVE_IND( 1 );
577 VERT_SAVE_IND( 2 );
578 VERT_COPY_IND( v[0], v[3] );
579 VERT_COPY_IND( v[1], v[3] );
580 VERT_COPY_IND( v[2], v[3] );
581 }
582 }
583
584 if (mode == GL_POINT) {
585 if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
586 VERT_Z_ADD(v[0], offset);
587 VERT_Z_ADD(v[1], offset);
588 VERT_Z_ADD(v[2], offset);
589 VERT_Z_ADD(v[3], offset);
590 }
591 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
592 SETUP_STENCIL(facing);
593 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
594 UNSET_STENCIL(facing);
595 } else {
596 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
597 }
598 } else if (mode == GL_LINE) {
599 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
600 VERT_Z_ADD(v[0], offset);
601 VERT_Z_ADD(v[1], offset);
602 VERT_Z_ADD(v[2], offset);
603 VERT_Z_ADD(v[3], offset);
604 }
605 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
606 SETUP_STENCIL(facing);
607 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
608 UNSET_STENCIL(facing);
609 } else {
610 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
611 }
612 } else {
613 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
614 VERT_Z_ADD(v[0], offset);
615 VERT_Z_ADD(v[1], offset);
616 VERT_Z_ADD(v[2], offset);
617 VERT_Z_ADD(v[3], offset);
618 }
619 RASTERIZE( GL_QUADS );
620 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
621 SETUP_STENCIL(facing);
622 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
623 UNSET_STENCIL(facing);
624 } else {
625 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
626 }
627 }
628
629 if (DO_OFFSET)
630 {
631 VERT_SET_Z(v[0], z[0]);
632 VERT_SET_Z(v[1], z[1]);
633 VERT_SET_Z(v[2], z[2]);
634 VERT_SET_Z(v[3], z[3]);
635 }
636
637 if (DO_TWOSIDE && facing == 1)
638 {
639 if (HAVE_RGBA) {
640 if (!DO_FLAT) {
641 VERT_RESTORE_RGBA( 0 );
642 VERT_RESTORE_RGBA( 1 );
643 VERT_RESTORE_RGBA( 2 );
644 }
645 VERT_RESTORE_RGBA( 3 );
646 if (HAVE_SPEC) {
647 if (!DO_FLAT) {
648 VERT_RESTORE_SPEC( 0 );
649 VERT_RESTORE_SPEC( 1 );
650 VERT_RESTORE_SPEC( 2 );
651 }
652 VERT_RESTORE_SPEC( 3 );
653 }
654 }
655 else {
656 if (!DO_FLAT) {
657 VERT_RESTORE_IND( 0 );
658 VERT_RESTORE_IND( 1 );
659 VERT_RESTORE_IND( 2 );
660 }
661 VERT_RESTORE_IND( 3 );
662 }
663 }
664
665
666 if (DO_FLAT) {
667 if (HAVE_RGBA) {
668 VERT_RESTORE_RGBA( 0 );
669 VERT_RESTORE_RGBA( 1 );
670 VERT_RESTORE_RGBA( 2 );
671 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
672 VERT_RESTORE_SPEC( 0 );
673 VERT_RESTORE_SPEC( 1 );
674 VERT_RESTORE_SPEC( 2 );
675 }
676 }
677 else {
678 VERT_RESTORE_IND( 0 );
679 VERT_RESTORE_IND( 1 );
680 VERT_RESTORE_IND( 2 );
681 }
682 }
683 }
684 #else
685 static void TAG(quad)( GLcontext *ctx, GLuint e0,
686 GLuint e1, GLuint e2, GLuint e3 )
687 {
688 if (DO_UNFILLED) {
689 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
690 GLubyte ef1 = VB->EdgeFlag[e1];
691 GLubyte ef3 = VB->EdgeFlag[e3];
692 VB->EdgeFlag[e1] = 0;
693 TAG(triangle)( ctx, e0, e1, e3 );
694 VB->EdgeFlag[e1] = ef1;
695 VB->EdgeFlag[e3] = 0;
696 TAG(triangle)( ctx, e1, e2, e3 );
697 VB->EdgeFlag[e3] = ef3;
698 } else {
699 TAG(triangle)( ctx, e0, e1, e3 );
700 TAG(triangle)( ctx, e1, e2, e3 );
701 }
702 }
703 #endif
704 #endif
705
706 #if DO_LINE
707 static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1 )
708 {
709 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
710 VERTEX *v[2];
711 LOCAL_VARS(2);
712
713 v[0] = (VERTEX *)GET_VERTEX(e0);
714 v[1] = (VERTEX *)GET_VERTEX(e1);
715
716 if (DO_FLAT) {
717 if (HAVE_RGBA) {
718 VERT_SAVE_RGBA( 0 );
719 VERT_COPY_RGBA( v[0], v[1] );
720 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
721 VERT_SAVE_SPEC( 0 );
722 VERT_COPY_SPEC( v[0], v[1] );
723 }
724 }
725 else {
726 VERT_SAVE_IND( 0 );
727 VERT_COPY_IND( v[0], v[1] );
728 }
729 }
730
731 LINE( v[0], v[1] );
732
733 if (DO_FLAT) {
734 if (HAVE_RGBA) {
735 VERT_RESTORE_RGBA( 0 );
736
737 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
738 VERT_RESTORE_SPEC( 0 );
739 }
740 }
741 else {
742 VERT_RESTORE_IND( 0 );
743 }
744 }
745 }
746 #endif
747
748 #if DO_POINTS
749 static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
750 {
751 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
752 int i;
753 LOCAL_VARS(1);
754
755 if (VB->Elts == 0) {
756 for ( i = first ; i < last ; i++ ) {
757 if ( VB->ClipMask[i] == 0 ) {
758 VERTEX *v = (VERTEX *)GET_VERTEX(i);
759 POINT( v );
760 }
761 }
762 } else {
763 for ( i = first ; i < last ; i++ ) {
764 GLuint e = VB->Elts[i];
765 if ( VB->ClipMask[e] == 0 ) {
766 VERTEX *v = (VERTEX *)GET_VERTEX(e);
767 POINT( v );
768 }
769 }
770 }
771 }
772 #endif
773
774 static void TAG(init)( void )
775 {
776 #if DO_QUAD
777 TAB[IND].quad = TAG(quad);
778 #endif
779 #if DO_TRI
780 TAB[IND].triangle = TAG(triangle);
781 #endif
782 #if DO_LINE
783 TAB[IND].line = TAG(line);
784 #endif
785 #if DO_POINTS
786 TAB[IND].points = TAG(points);
787 #endif
788 }
789
790 #undef IND
791 #undef TAG
792
793 #if HAVE_RGBA
794 #undef VERT_SET_IND
795 #undef VERT_COPY_IND
796 #undef VERT_SAVE_IND
797 #undef VERT_RESTORE_IND
798 #if HAVE_BACK_COLORS
799 #undef VERT_SET_RGBA
800 #endif
801 #else
802 #undef VERT_SET_RGBA
803 #undef VERT_COPY_RGBA
804 #undef VERT_SAVE_RGBA
805 #undef VERT_RESTORE_RGBA
806 #if HAVE_BACK_COLORS
807 #undef VERT_SET_IND
808 #endif
809 #endif
810
811 #if !HAVE_SPEC
812 #undef VERT_SET_SPEC
813 #undef VERT_COPY_SPEC
814 #undef VERT_SAVE_SPEC
815 #undef VERT_RESTORE_SPEC
816 #if HAVE_BACK_COLORS
817 #undef VERT_COPY_SPEC1
818 #endif
819 #else
820 #if HAVE_BACK_COLORS
821 #undef VERT_SET_SPEC
822 #endif
823 #endif
824
825 #if !HAVE_BACK_COLORS
826 #undef VERT_COPY_SPEC1
827 #undef VERT_COPY_IND1
828 #undef VERT_COPY_RGBA1
829 #endif
830
831 #ifndef INSANE_VERTICES
832 #undef VERT_SET_Z
833 #undef VERT_Z_ADD
834 #endif