wip hack for EXT_stencil_two_side
[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 offset.
53 *
54 * VERTEX: Hardware vertex type.
55 * GET_VERTEX(n): Retreive vertex with index n.
56 * AREA_IS_CCW(a): Return true if triangle with signed area a is ccw.
57 *
58 * VERT_SET_RGBA: Assign vertex rgba from VB color.
59 * VERT_COPY_RGBA: Copy vertex rgba another vertex.
60 * VERT_SAVE_RGBA: Save vertex rgba to a local variable.
61 * VERT_RESTORE_RGBA: Restore vertex rgba from a local variable.
62 * --> Similar for IND and SPEC.
63 *
64 * LOCAL_VARS(n): (At least) define local vars for save/restore rgba.
65 *
66 */
67
68 #if HAVE_RGBA
69 #define VERT_SET_IND( v, c ) (void) c
70 #define VERT_COPY_IND( v0, v1 )
71 #define VERT_SAVE_IND( idx )
72 #define VERT_RESTORE_IND( idx )
73 #if HAVE_BACK_COLORS
74 #define VERT_SET_RGBA( v, c )
75 #endif
76 #else
77 #define VERT_SET_RGBA( v, c ) (void) c
78 #define VERT_COPY_RGBA( v0, v1 )
79 #define VERT_SAVE_RGBA( idx )
80 #define VERT_RESTORE_RGBA( idx )
81 #if HAVE_BACK_COLORS
82 #define VERT_SET_IND( v, c )
83 #endif
84 #endif
85
86 #if !HAVE_SPEC
87 #define VERT_SET_SPEC( v, c ) (void) c
88 #define VERT_COPY_SPEC( v0, v1 )
89 #define VERT_SAVE_SPEC( idx )
90 #define VERT_RESTORE_SPEC( idx )
91 #if HAVE_BACK_COLORS
92 #define VERT_COPY_SPEC1( v )
93 #endif
94 #else
95 #if HAVE_BACK_COLORS
96 #define VERT_SET_SPEC( v, c )
97 #endif
98 #endif
99
100 #if !HAVE_BACK_COLORS
101 #define VERT_COPY_SPEC1( v )
102 #define VERT_COPY_IND1( v )
103 #define VERT_COPY_RGBA1( v )
104 #endif
105
106 #ifndef INSANE_VERTICES
107 #define VERT_SET_Z(v,val) VERT_Z(v) = val
108 #define VERT_Z_ADD(v,val) VERT_Z(v) += val
109 #endif
110
111 /* disable twostencil for un-aware drivers */
112 #ifndef HAVE_STENCIL_TWOSIDE
113 #define HAVE_STENCIL_TWOSIDE 0
114 #endif
115 #ifndef DO_TWOSTENCIL
116 #define DO_TWOSTENCIL 0
117 #endif
118 #ifndef SETUP_STENCIL
119 #define SETUP_STENCIL(f)
120 #endif
121 #ifndef UNSET_STENCIL
122 #define UNSET_STENCIL(f)
123 #endif
124
125 #if DO_TRI
126 static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
127 {
128 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
129 VERTEX *v[3];
130 GLfloat offset;
131 GLfloat z[3];
132 GLenum mode = GL_FILL;
133 GLuint facing;
134 LOCAL_VARS(3);
135
136 /* fprintf(stderr, "%s\n", __FUNCTION__); */
137
138 v[0] = (VERTEX *)GET_VERTEX(e0);
139 v[1] = (VERTEX *)GET_VERTEX(e1);
140 v[2] = (VERTEX *)GET_VERTEX(e2);
141
142 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
143 {
144 GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
145 GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
146 GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
147 GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
148 GLfloat cc = ex*fy - ey*fx;
149
150 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
151 {
152 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
153
154 if (DO_TWOSTENCIL && ctx->Stencil.TestTwoSide) {
155 ctx->_Facing = facing; /* mixed mode rendering: for 2-sided stencil test */
156 }
157
158 if (DO_UNFILLED) {
159 if (facing) {
160 mode = ctx->Polygon.BackMode;
161 if (ctx->Polygon.CullFlag &&
162 ctx->Polygon.CullFaceMode != GL_FRONT) {
163 return;
164 }
165 } else {
166 mode = ctx->Polygon.FrontMode;
167 if (ctx->Polygon.CullFlag &&
168 ctx->Polygon.CullFaceMode != GL_BACK) {
169 return;
170 }
171 }
172 }
173
174 if (DO_TWOSIDE && facing == 1)
175 {
176 if (HAVE_RGBA) {
177 if (HAVE_BACK_COLORS) {
178 if (!DO_FLAT) {
179 VERT_SAVE_RGBA( 0 );
180 VERT_SAVE_RGBA( 1 );
181 VERT_COPY_RGBA1( v[0] );
182 VERT_COPY_RGBA1( v[1] );
183 }
184 VERT_SAVE_RGBA( 2 );
185 VERT_COPY_RGBA1( v[2] );
186 if (HAVE_SPEC) {
187 if (!DO_FLAT) {
188 VERT_SAVE_SPEC( 0 );
189 VERT_SAVE_SPEC( 1 );
190 VERT_COPY_SPEC1( v[0] );
191 VERT_COPY_SPEC1( v[1] );
192 }
193 VERT_SAVE_SPEC( 2 );
194 VERT_COPY_SPEC1( v[2] );
195 }
196 }
197 else {
198 GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
199 ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
200 (void) vbcolor;
201
202 if (!DO_FLAT) {
203 VERT_SAVE_RGBA( 0 );
204 VERT_SAVE_RGBA( 1 );
205 VERT_SET_RGBA( v[0], vbcolor[e0] );
206 VERT_SET_RGBA( v[1], vbcolor[e1] );
207 }
208 VERT_SAVE_RGBA( 2 );
209 VERT_SET_RGBA( v[2], vbcolor[e2] );
210
211 if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
212 GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
213
214 if (!DO_FLAT) {
215 VERT_SAVE_SPEC( 0 );
216 VERT_SAVE_SPEC( 1 );
217 VERT_SET_SPEC( v[0], vbspec[e0] );
218 VERT_SET_SPEC( v[1], vbspec[e1] );
219 }
220 VERT_SAVE_SPEC( 2 );
221 VERT_SET_SPEC( v[2], vbspec[e2] );
222 }
223 }
224 }
225 else {
226 GLfloat (*vbindex) = (GLfloat *)VB->IndexPtr[1]->data;
227 if (!DO_FLAT) {
228 VERT_SAVE_IND( 0 );
229 VERT_SAVE_IND( 1 );
230 VERT_SET_IND( v[0], vbindex[e0] );
231 VERT_SET_IND( v[1], vbindex[e1] );
232 }
233 VERT_SAVE_IND( 2 );
234 VERT_SET_IND( v[2], vbindex[e2] );
235 }
236 }
237 }
238
239
240 if (DO_OFFSET)
241 {
242 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
243 z[0] = VERT_Z(v[0]);
244 z[1] = VERT_Z(v[1]);
245 z[2] = VERT_Z(v[2]);
246 if (cc * cc > 1e-16) {
247 GLfloat ic = 1.0 / cc;
248 GLfloat ez = z[0] - z[2];
249 GLfloat fz = z[1] - z[2];
250 GLfloat a = ey*fz - ez*fy;
251 GLfloat b = ez*fx - ex*fz;
252 GLfloat ac = a * ic;
253 GLfloat bc = b * ic;
254 if ( ac < 0.0f ) ac = -ac;
255 if ( bc < 0.0f ) bc = -bc;
256 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor;
257 }
258 offset *= ctx->MRD;
259 }
260 }
261
262 if (DO_FLAT) {
263 if (HAVE_RGBA) {
264 VERT_SAVE_RGBA( 0 );
265 VERT_SAVE_RGBA( 1 );
266 VERT_COPY_RGBA( v[0], v[2] );
267 VERT_COPY_RGBA( v[1], v[2] );
268 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
269 VERT_SAVE_SPEC( 0 );
270 VERT_SAVE_SPEC( 1 );
271 VERT_COPY_SPEC( v[0], v[2] );
272 VERT_COPY_SPEC( v[1], v[2] );
273 }
274 }
275 else {
276 VERT_SAVE_IND( 0 );
277 VERT_SAVE_IND( 1 );
278 VERT_COPY_IND( v[0], v[2] );
279 VERT_COPY_IND( v[1], v[2] );
280 }
281 }
282
283 if (mode == GL_POINT) {
284 if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
285 VERT_Z_ADD(v[0], offset);
286 VERT_Z_ADD(v[1], offset);
287 VERT_Z_ADD(v[2], offset);
288 }
289 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
290 SETUP_STENCIL(facing);
291 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
292 UNSET_STENCIL(facing);
293 } else {
294 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
295 }
296 } else if (mode == GL_LINE) {
297 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
298 VERT_Z_ADD(v[0], offset);
299 VERT_Z_ADD(v[1], offset);
300 VERT_Z_ADD(v[2], offset);
301 }
302 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
303 SETUP_STENCIL(facing);
304 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
305 UNSET_STENCIL(facing);
306 } else {
307 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
308 }
309 } else {
310 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
311 VERT_Z_ADD(v[0], offset);
312 VERT_Z_ADD(v[1], offset);
313 VERT_Z_ADD(v[2], offset);
314 }
315 if (DO_UNFILLED)
316 RASTERIZE( GL_TRIANGLES );
317 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
318 SETUP_STENCIL(facing);
319 TRI( v[0], v[1], v[2] );
320 UNSET_STENCIL(facing);
321 } else {
322 TRI( v[0], v[1], v[2] );
323 }
324 }
325
326 if (DO_OFFSET)
327 {
328 VERT_SET_Z(v[0], z[0]);
329 VERT_SET_Z(v[1], z[1]);
330 VERT_SET_Z(v[2], z[2]);
331 }
332
333 if (DO_TWOSIDE && facing == 1)
334 {
335 if (HAVE_RGBA) {
336 if (!DO_FLAT) {
337 VERT_RESTORE_RGBA( 0 );
338 VERT_RESTORE_RGBA( 1 );
339 }
340 VERT_RESTORE_RGBA( 2 );
341 if (HAVE_SPEC) {
342 if (!DO_FLAT) {
343 VERT_RESTORE_SPEC( 0 );
344 VERT_RESTORE_SPEC( 1 );
345 }
346 VERT_RESTORE_SPEC( 2 );
347 }
348 }
349 else {
350 if (!DO_FLAT) {
351 VERT_RESTORE_IND( 0 );
352 VERT_RESTORE_IND( 1 );
353 }
354 VERT_RESTORE_IND( 2 );
355 }
356 }
357
358
359 if (DO_FLAT) {
360 if (HAVE_RGBA) {
361 VERT_RESTORE_RGBA( 0 );
362 VERT_RESTORE_RGBA( 1 );
363 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
364 VERT_RESTORE_SPEC( 0 );
365 VERT_RESTORE_SPEC( 1 );
366 }
367 }
368 else {
369 VERT_RESTORE_IND( 0 );
370 VERT_RESTORE_IND( 1 );
371 }
372 }
373 }
374 #endif
375
376 #if DO_QUAD
377 #if DO_FULL_QUAD
378 static void TAG(quad)( GLcontext *ctx,
379 GLuint e0, GLuint e1, GLuint e2, GLuint e3 )
380 {
381 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
382 VERTEX *v[4];
383 GLfloat offset;
384 GLfloat z[4];
385 GLenum mode = GL_FILL;
386 GLuint facing;
387 LOCAL_VARS(4);
388
389 v[0] = (VERTEX *)GET_VERTEX(e0);
390 v[1] = (VERTEX *)GET_VERTEX(e1);
391 v[2] = (VERTEX *)GET_VERTEX(e2);
392 v[3] = (VERTEX *)GET_VERTEX(e3);
393
394 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
395 {
396 GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
397 GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
398 GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
399 GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
400 GLfloat cc = ex*fy - ey*fx;
401
402 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
403 {
404 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
405
406 if (DO_TWOSTENCIL && ctx->Stencil.TestTwoSide) {
407 ctx->_Facing = facing; /* mixed mode rendering: for 2-sided stencil test */
408 }
409
410 if (DO_UNFILLED) {
411 if (facing) {
412 mode = ctx->Polygon.BackMode;
413 if (ctx->Polygon.CullFlag &&
414 ctx->Polygon.CullFaceMode != GL_FRONT) {
415 return;
416 }
417 } else {
418 mode = ctx->Polygon.FrontMode;
419 if (ctx->Polygon.CullFlag &&
420 ctx->Polygon.CullFaceMode != GL_BACK) {
421 return;
422 }
423 }
424 }
425
426 if (DO_TWOSIDE && facing == 1)
427 {
428 if (HAVE_RGBA) {
429 GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
430 (void)vbcolor;
431
432 if (HAVE_BACK_COLORS) {
433 if (!DO_FLAT) {
434 VERT_SAVE_RGBA( 0 );
435 VERT_SAVE_RGBA( 1 );
436 VERT_SAVE_RGBA( 2 );
437 VERT_COPY_RGBA1( v[0] );
438 VERT_COPY_RGBA1( v[1] );
439 VERT_COPY_RGBA1( v[2] );
440 }
441 VERT_SAVE_RGBA( 3 );
442 VERT_COPY_RGBA1( v[3] );
443 if (HAVE_SPEC) {
444 if (!DO_FLAT) {
445 VERT_SAVE_SPEC( 0 );
446 VERT_SAVE_SPEC( 1 );
447 VERT_SAVE_SPEC( 2 );
448 VERT_COPY_SPEC1( v[0] );
449 VERT_COPY_SPEC1( v[1] );
450 VERT_COPY_SPEC1( v[2] );
451 }
452 VERT_SAVE_SPEC( 3 );
453 VERT_COPY_SPEC1( v[3] );
454 }
455 }
456 else {
457 if (!DO_FLAT) {
458 VERT_SAVE_RGBA( 0 );
459 VERT_SAVE_RGBA( 1 );
460 VERT_SAVE_RGBA( 2 );
461 VERT_SET_RGBA( v[0], vbcolor[e0] );
462 VERT_SET_RGBA( v[1], vbcolor[e1] );
463 VERT_SET_RGBA( v[2], vbcolor[e2] );
464 }
465 VERT_SAVE_RGBA( 3 );
466 VERT_SET_RGBA( v[3], vbcolor[e3] );
467
468 if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
469 GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
470 ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
471
472 if (!DO_FLAT) {
473 VERT_SAVE_SPEC( 0 );
474 VERT_SAVE_SPEC( 1 );
475 VERT_SAVE_SPEC( 2 );
476 VERT_SET_SPEC( v[0], vbspec[e0] );
477 VERT_SET_SPEC( v[1], vbspec[e1] );
478 VERT_SET_SPEC( v[2], vbspec[e2] );
479 }
480 VERT_SAVE_SPEC( 3 );
481 VERT_SET_SPEC( v[3], vbspec[e3] );
482 }
483 }
484 }
485 else {
486 GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
487 if (!DO_FLAT) {
488 VERT_SAVE_IND( 0 );
489 VERT_SAVE_IND( 1 );
490 VERT_SAVE_IND( 2 );
491 VERT_SET_IND( v[0], vbindex[e0] );
492 VERT_SET_IND( v[1], vbindex[e1] );
493 VERT_SET_IND( v[2], vbindex[e2] );
494 }
495 VERT_SAVE_IND( 3 );
496 VERT_SET_IND( v[3], vbindex[e3] );
497 }
498 }
499 }
500
501
502 if (DO_OFFSET)
503 {
504 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
505 z[0] = VERT_Z(v[0]);
506 z[1] = VERT_Z(v[1]);
507 z[2] = VERT_Z(v[2]);
508 z[3] = VERT_Z(v[3]);
509 if (cc * cc > 1e-16) {
510 GLfloat ez = z[2] - z[0];
511 GLfloat fz = z[3] - z[1];
512 GLfloat a = ey*fz - ez*fy;
513 GLfloat b = ez*fx - ex*fz;
514 GLfloat ic = 1.0 / cc;
515 GLfloat ac = a * ic;
516 GLfloat bc = b * ic;
517 if ( ac < 0.0f ) ac = -ac;
518 if ( bc < 0.0f ) bc = -bc;
519 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor;
520 }
521 offset *= ctx->MRD;
522 }
523 }
524
525 if (DO_FLAT) {
526 if (HAVE_RGBA) {
527 VERT_SAVE_RGBA( 0 );
528 VERT_SAVE_RGBA( 1 );
529 VERT_SAVE_RGBA( 2 );
530 VERT_COPY_RGBA( v[0], v[3] );
531 VERT_COPY_RGBA( v[1], v[3] );
532 VERT_COPY_RGBA( v[2], v[3] );
533 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
534 VERT_SAVE_SPEC( 0 );
535 VERT_SAVE_SPEC( 1 );
536 VERT_SAVE_SPEC( 2 );
537 VERT_COPY_SPEC( v[0], v[3] );
538 VERT_COPY_SPEC( v[1], v[3] );
539 VERT_COPY_SPEC( v[2], v[3] );
540 }
541 }
542 else {
543 VERT_SAVE_IND( 0 );
544 VERT_SAVE_IND( 1 );
545 VERT_SAVE_IND( 2 );
546 VERT_COPY_IND( v[0], v[3] );
547 VERT_COPY_IND( v[1], v[3] );
548 VERT_COPY_IND( v[2], v[3] );
549 }
550 }
551
552 if (mode == GL_POINT) {
553 if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
554 VERT_Z_ADD(v[0], offset);
555 VERT_Z_ADD(v[1], offset);
556 VERT_Z_ADD(v[2], offset);
557 VERT_Z_ADD(v[3], offset);
558 }
559 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
560 SETUP_STENCIL(facing);
561 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
562 UNSET_STENCIL(facing);
563 } else {
564 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
565 }
566 } else if (mode == GL_LINE) {
567 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
568 VERT_Z_ADD(v[0], offset);
569 VERT_Z_ADD(v[1], offset);
570 VERT_Z_ADD(v[2], offset);
571 VERT_Z_ADD(v[3], offset);
572 }
573 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
574 SETUP_STENCIL(facing);
575 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
576 UNSET_STENCIL(facing);
577 } else {
578 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
579 }
580 } else {
581 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
582 VERT_Z_ADD(v[0], offset);
583 VERT_Z_ADD(v[1], offset);
584 VERT_Z_ADD(v[2], offset);
585 VERT_Z_ADD(v[3], offset);
586 }
587 RASTERIZE( GL_TRIANGLES );
588 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
589 SETUP_STENCIL(facing);
590 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
591 UNSET_STENCIL(facing);
592 } else {
593 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
594 }
595 }
596
597 if (DO_OFFSET)
598 {
599 VERT_SET_Z(v[0], z[0]);
600 VERT_SET_Z(v[1], z[1]);
601 VERT_SET_Z(v[2], z[2]);
602 VERT_SET_Z(v[3], z[3]);
603 }
604
605 if (DO_TWOSIDE && facing == 1)
606 {
607 if (HAVE_RGBA) {
608 if (!DO_FLAT) {
609 VERT_RESTORE_RGBA( 0 );
610 VERT_RESTORE_RGBA( 1 );
611 VERT_RESTORE_RGBA( 2 );
612 }
613 VERT_RESTORE_RGBA( 3 );
614 if (HAVE_SPEC) {
615 if (!DO_FLAT) {
616 VERT_RESTORE_SPEC( 0 );
617 VERT_RESTORE_SPEC( 1 );
618 VERT_RESTORE_SPEC( 2 );
619 }
620 VERT_RESTORE_SPEC( 3 );
621 }
622 }
623 else {
624 if (!DO_FLAT) {
625 VERT_RESTORE_IND( 0 );
626 VERT_RESTORE_IND( 1 );
627 VERT_RESTORE_IND( 2 );
628 }
629 VERT_RESTORE_IND( 3 );
630 }
631 }
632
633
634 if (DO_FLAT) {
635 if (HAVE_RGBA) {
636 VERT_RESTORE_RGBA( 0 );
637 VERT_RESTORE_RGBA( 1 );
638 VERT_RESTORE_RGBA( 2 );
639 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
640 VERT_RESTORE_SPEC( 0 );
641 VERT_RESTORE_SPEC( 1 );
642 VERT_RESTORE_SPEC( 2 );
643 }
644 }
645 else {
646 VERT_RESTORE_IND( 0 );
647 VERT_RESTORE_IND( 1 );
648 VERT_RESTORE_IND( 2 );
649 }
650 }
651 }
652 #else
653 static void TAG(quad)( GLcontext *ctx, GLuint e0,
654 GLuint e1, GLuint e2, GLuint e3 )
655 {
656 if (DO_UNFILLED) {
657 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
658 GLubyte ef1 = VB->EdgeFlag[e1];
659 GLubyte ef3 = VB->EdgeFlag[e3];
660 VB->EdgeFlag[e1] = 0;
661 TAG(triangle)( ctx, e0, e1, e3 );
662 VB->EdgeFlag[e1] = ef1;
663 VB->EdgeFlag[e3] = 0;
664 TAG(triangle)( ctx, e1, e2, e3 );
665 VB->EdgeFlag[e3] = ef3;
666 } else {
667 TAG(triangle)( ctx, e0, e1, e3 );
668 TAG(triangle)( ctx, e1, e2, e3 );
669 }
670 }
671 #endif
672 #endif
673
674 #if DO_LINE
675 static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1 )
676 {
677 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
678 VERTEX *v[2];
679 LOCAL_VARS(2);
680
681 v[0] = (VERTEX *)GET_VERTEX(e0);
682 v[1] = (VERTEX *)GET_VERTEX(e1);
683
684 if (DO_FLAT) {
685 if (HAVE_RGBA) {
686 VERT_SAVE_RGBA( 0 );
687 VERT_COPY_RGBA( v[0], v[1] );
688 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
689 VERT_SAVE_SPEC( 0 );
690 VERT_COPY_SPEC( v[0], v[1] );
691 }
692 }
693 else {
694 VERT_SAVE_IND( 0 );
695 VERT_COPY_IND( v[0], v[1] );
696 }
697 }
698
699 LINE( v[0], v[1] );
700
701 if (DO_FLAT) {
702 if (HAVE_RGBA) {
703 VERT_RESTORE_RGBA( 0 );
704
705 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
706 VERT_RESTORE_SPEC( 0 );
707 }
708 }
709 else {
710 VERT_RESTORE_IND( 0 );
711 }
712 }
713 }
714 #endif
715
716 #if DO_POINTS
717 static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
718 {
719 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
720 int i;
721 LOCAL_VARS(1);
722
723 if (VB->Elts == 0) {
724 for ( i = first ; i < last ; i++ ) {
725 if ( VB->ClipMask[i] == 0 ) {
726 VERTEX *v = (VERTEX *)GET_VERTEX(i);
727 POINT( v );
728 }
729 }
730 } else {
731 for ( i = first ; i < last ; i++ ) {
732 GLuint e = VB->Elts[i];
733 if ( VB->ClipMask[e] == 0 ) {
734 VERTEX *v = (VERTEX *)GET_VERTEX(e);
735 POINT( v );
736 }
737 }
738 }
739 }
740 #endif
741
742 static void TAG(init)( void )
743 {
744 #if DO_QUAD
745 TAB[IND].quad = TAG(quad);
746 #endif
747 #if DO_TRI
748 TAB[IND].triangle = TAG(triangle);
749 #endif
750 #if DO_LINE
751 TAB[IND].line = TAG(line);
752 #endif
753 #if DO_POINTS
754 TAB[IND].points = TAG(points);
755 #endif
756 }
757
758 #undef IND
759 #undef TAG
760
761 #if HAVE_RGBA
762 #undef VERT_SET_IND
763 #undef VERT_COPY_IND
764 #undef VERT_SAVE_IND
765 #undef VERT_RESTORE_IND
766 #if HAVE_BACK_COLORS
767 #undef VERT_SET_RGBA
768 #endif
769 #else
770 #undef VERT_SET_RGBA
771 #undef VERT_COPY_RGBA
772 #undef VERT_SAVE_RGBA
773 #undef VERT_RESTORE_RGBA
774 #if HAVE_BACK_COLORS
775 #undef VERT_SET_IND
776 #endif
777 #endif
778
779 #if !HAVE_SPEC
780 #undef VERT_SET_SPEC
781 #undef VERT_COPY_SPEC
782 #undef VERT_SAVE_SPEC
783 #undef VERT_RESTORE_SPEC
784 #if HAVE_BACK_COLORS
785 #undef VERT_COPY_SPEC1
786 #endif
787 #else
788 #if HAVE_BACK_COLORS
789 #undef VERT_SET_SPEC
790 #endif
791 #endif
792
793 #if !HAVE_BACK_COLORS
794 #undef VERT_COPY_SPEC1
795 #undef VERT_COPY_IND1
796 #undef VERT_COPY_RGBA1
797 #endif
798
799 #ifndef INSANE_VERTICES
800 #undef VERT_SET_Z
801 #undef VERT_Z_ADD
802 #endif