More changes to cope with color stride == 0
[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 (void) vbcolor;
200
201 if (!DO_FLAT) {
202 VERT_SAVE_RGBA( 0 );
203 VERT_SAVE_RGBA( 1 );
204 }
205 VERT_SAVE_RGBA( 2 );
206
207 if (VB->ColorPtr[1]->stride) {
208 ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
209
210 if (!DO_FLAT) {
211 VERT_SET_RGBA( v[0], vbcolor[e0] );
212 VERT_SET_RGBA( v[1], vbcolor[e1] );
213 }
214 VERT_SET_RGBA( v[2], vbcolor[e2] );
215 }
216 else {
217 if (!DO_FLAT) {
218 VERT_SET_RGBA( v[0], vbcolor[0] );
219 VERT_SET_RGBA( v[1], vbcolor[0] );
220 }
221 VERT_SET_RGBA( v[2], vbcolor[0] );
222 }
223
224 if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
225 GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
226 ASSERT(VB->SecondaryColorPtr[1]->stride == 4*sizeof(GLfloat));
227
228 if (!DO_FLAT) {
229 VERT_SAVE_SPEC( 0 );
230 VERT_SAVE_SPEC( 1 );
231 VERT_SET_SPEC( v[0], vbspec[e0] );
232 VERT_SET_SPEC( v[1], vbspec[e1] );
233 }
234 VERT_SAVE_SPEC( 2 );
235 VERT_SET_SPEC( v[2], vbspec[e2] );
236 }
237 }
238 }
239 else {
240 GLfloat (*vbindex) = (GLfloat *)VB->IndexPtr[1]->data;
241 if (!DO_FLAT) {
242 VERT_SAVE_IND( 0 );
243 VERT_SAVE_IND( 1 );
244 VERT_SET_IND( v[0], vbindex[e0] );
245 VERT_SET_IND( v[1], vbindex[e1] );
246 }
247 VERT_SAVE_IND( 2 );
248 VERT_SET_IND( v[2], vbindex[e2] );
249 }
250 }
251 }
252
253
254 if (DO_OFFSET)
255 {
256 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
257 z[0] = VERT_Z(v[0]);
258 z[1] = VERT_Z(v[1]);
259 z[2] = VERT_Z(v[2]);
260 if (cc * cc > 1e-16) {
261 GLfloat ic = 1.0 / cc;
262 GLfloat ez = z[0] - z[2];
263 GLfloat fz = z[1] - z[2];
264 GLfloat a = ey*fz - ez*fy;
265 GLfloat b = ez*fx - ex*fz;
266 GLfloat ac = a * ic;
267 GLfloat bc = b * ic;
268 if ( ac < 0.0f ) ac = -ac;
269 if ( bc < 0.0f ) bc = -bc;
270 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor;
271 }
272 offset *= ctx->MRD;
273 }
274 }
275
276 if (DO_FLAT) {
277 if (HAVE_RGBA) {
278 VERT_SAVE_RGBA( 0 );
279 VERT_SAVE_RGBA( 1 );
280 VERT_COPY_RGBA( v[0], v[2] );
281 VERT_COPY_RGBA( v[1], v[2] );
282 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
283 VERT_SAVE_SPEC( 0 );
284 VERT_SAVE_SPEC( 1 );
285 VERT_COPY_SPEC( v[0], v[2] );
286 VERT_COPY_SPEC( v[1], v[2] );
287 }
288 }
289 else {
290 VERT_SAVE_IND( 0 );
291 VERT_SAVE_IND( 1 );
292 VERT_COPY_IND( v[0], v[2] );
293 VERT_COPY_IND( v[1], v[2] );
294 }
295 }
296
297 if (mode == GL_POINT) {
298 if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
299 VERT_Z_ADD(v[0], offset);
300 VERT_Z_ADD(v[1], offset);
301 VERT_Z_ADD(v[2], offset);
302 }
303 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
304 SETUP_STENCIL(facing);
305 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
306 UNSET_STENCIL(facing);
307 } else {
308 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
309 }
310 } else if (mode == GL_LINE) {
311 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
312 VERT_Z_ADD(v[0], offset);
313 VERT_Z_ADD(v[1], offset);
314 VERT_Z_ADD(v[2], offset);
315 }
316 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
317 SETUP_STENCIL(facing);
318 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
319 UNSET_STENCIL(facing);
320 } else {
321 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
322 }
323 } else {
324 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
325 VERT_Z_ADD(v[0], offset);
326 VERT_Z_ADD(v[1], offset);
327 VERT_Z_ADD(v[2], offset);
328 }
329 if (DO_UNFILLED)
330 RASTERIZE( GL_TRIANGLES );
331 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
332 SETUP_STENCIL(facing);
333 TRI( v[0], v[1], v[2] );
334 UNSET_STENCIL(facing);
335 } else {
336 TRI( v[0], v[1], v[2] );
337 }
338 }
339
340 if (DO_OFFSET)
341 {
342 VERT_SET_Z(v[0], z[0]);
343 VERT_SET_Z(v[1], z[1]);
344 VERT_SET_Z(v[2], z[2]);
345 }
346
347 if (DO_TWOSIDE && facing == 1)
348 {
349 if (HAVE_RGBA) {
350 if (!DO_FLAT) {
351 VERT_RESTORE_RGBA( 0 );
352 VERT_RESTORE_RGBA( 1 );
353 }
354 VERT_RESTORE_RGBA( 2 );
355 if (HAVE_SPEC) {
356 if (!DO_FLAT) {
357 VERT_RESTORE_SPEC( 0 );
358 VERT_RESTORE_SPEC( 1 );
359 }
360 VERT_RESTORE_SPEC( 2 );
361 }
362 }
363 else {
364 if (!DO_FLAT) {
365 VERT_RESTORE_IND( 0 );
366 VERT_RESTORE_IND( 1 );
367 }
368 VERT_RESTORE_IND( 2 );
369 }
370 }
371
372
373 if (DO_FLAT) {
374 if (HAVE_RGBA) {
375 VERT_RESTORE_RGBA( 0 );
376 VERT_RESTORE_RGBA( 1 );
377 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
378 VERT_RESTORE_SPEC( 0 );
379 VERT_RESTORE_SPEC( 1 );
380 }
381 }
382 else {
383 VERT_RESTORE_IND( 0 );
384 VERT_RESTORE_IND( 1 );
385 }
386 }
387 }
388 #endif
389
390 #if DO_QUAD
391 #if DO_FULL_QUAD
392 static void TAG(quad)( GLcontext *ctx,
393 GLuint e0, GLuint e1, GLuint e2, GLuint e3 )
394 {
395 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
396 VERTEX *v[4];
397 GLfloat offset;
398 GLfloat z[4];
399 GLenum mode = GL_FILL;
400 GLuint facing;
401 LOCAL_VARS(4);
402
403 v[0] = (VERTEX *)GET_VERTEX(e0);
404 v[1] = (VERTEX *)GET_VERTEX(e1);
405 v[2] = (VERTEX *)GET_VERTEX(e2);
406 v[3] = (VERTEX *)GET_VERTEX(e3);
407
408 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
409 {
410 GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
411 GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
412 GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
413 GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
414 GLfloat cc = ex*fy - ey*fx;
415
416 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
417 {
418 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
419
420 if (DO_TWOSTENCIL && ctx->Stencil.TestTwoSide) {
421 ctx->_Facing = facing; /* mixed mode rendering: for 2-sided stencil test */
422 }
423
424 if (DO_UNFILLED) {
425 if (facing) {
426 mode = ctx->Polygon.BackMode;
427 if (ctx->Polygon.CullFlag &&
428 ctx->Polygon.CullFaceMode != GL_FRONT) {
429 return;
430 }
431 } else {
432 mode = ctx->Polygon.FrontMode;
433 if (ctx->Polygon.CullFlag &&
434 ctx->Polygon.CullFaceMode != GL_BACK) {
435 return;
436 }
437 }
438 }
439
440 if (DO_TWOSIDE && facing == 1)
441 {
442 if (HAVE_RGBA) {
443 GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
444 (void)vbcolor;
445
446 if (HAVE_BACK_COLORS) {
447 if (!DO_FLAT) {
448 VERT_SAVE_RGBA( 0 );
449 VERT_SAVE_RGBA( 1 );
450 VERT_SAVE_RGBA( 2 );
451 VERT_COPY_RGBA1( v[0] );
452 VERT_COPY_RGBA1( v[1] );
453 VERT_COPY_RGBA1( v[2] );
454 }
455 VERT_SAVE_RGBA( 3 );
456 VERT_COPY_RGBA1( v[3] );
457 if (HAVE_SPEC) {
458 if (!DO_FLAT) {
459 VERT_SAVE_SPEC( 0 );
460 VERT_SAVE_SPEC( 1 );
461 VERT_SAVE_SPEC( 2 );
462 VERT_COPY_SPEC1( v[0] );
463 VERT_COPY_SPEC1( v[1] );
464 VERT_COPY_SPEC1( v[2] );
465 }
466 VERT_SAVE_SPEC( 3 );
467 VERT_COPY_SPEC1( v[3] );
468 }
469 }
470 else {
471 if (!DO_FLAT) {
472 VERT_SAVE_RGBA( 0 );
473 VERT_SAVE_RGBA( 1 );
474 VERT_SAVE_RGBA( 2 );
475 }
476 VERT_SAVE_RGBA( 3 );
477
478 if (VB->ColorPtr[1]->stride) {
479 if (!DO_FLAT) {
480 VERT_SET_RGBA( v[0], vbcolor[e0] );
481 VERT_SET_RGBA( v[1], vbcolor[e1] );
482 VERT_SET_RGBA( v[2], vbcolor[e2] );
483 }
484 VERT_SET_RGBA( v[3], vbcolor[e3] );
485 }
486 else {
487 if (!DO_FLAT) {
488 VERT_SET_RGBA( v[0], vbcolor[0] );
489 VERT_SET_RGBA( v[1], vbcolor[0] );
490 VERT_SET_RGBA( v[2], vbcolor[0] );
491 }
492 VERT_SET_RGBA( v[3], vbcolor[0] );
493 }
494
495 if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
496 GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
497 ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
498
499 if (!DO_FLAT) {
500 VERT_SAVE_SPEC( 0 );
501 VERT_SAVE_SPEC( 1 );
502 VERT_SAVE_SPEC( 2 );
503 VERT_SET_SPEC( v[0], vbspec[e0] );
504 VERT_SET_SPEC( v[1], vbspec[e1] );
505 VERT_SET_SPEC( v[2], vbspec[e2] );
506 }
507 VERT_SAVE_SPEC( 3 );
508 VERT_SET_SPEC( v[3], vbspec[e3] );
509 }
510 }
511 }
512 else {
513 GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
514 if (!DO_FLAT) {
515 VERT_SAVE_IND( 0 );
516 VERT_SAVE_IND( 1 );
517 VERT_SAVE_IND( 2 );
518 VERT_SET_IND( v[0], vbindex[e0] );
519 VERT_SET_IND( v[1], vbindex[e1] );
520 VERT_SET_IND( v[2], vbindex[e2] );
521 }
522 VERT_SAVE_IND( 3 );
523 VERT_SET_IND( v[3], vbindex[e3] );
524 }
525 }
526 }
527
528
529 if (DO_OFFSET)
530 {
531 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
532 z[0] = VERT_Z(v[0]);
533 z[1] = VERT_Z(v[1]);
534 z[2] = VERT_Z(v[2]);
535 z[3] = VERT_Z(v[3]);
536 if (cc * cc > 1e-16) {
537 GLfloat ez = z[2] - z[0];
538 GLfloat fz = z[3] - z[1];
539 GLfloat a = ey*fz - ez*fy;
540 GLfloat b = ez*fx - ex*fz;
541 GLfloat ic = 1.0 / cc;
542 GLfloat ac = a * ic;
543 GLfloat bc = b * ic;
544 if ( ac < 0.0f ) ac = -ac;
545 if ( bc < 0.0f ) bc = -bc;
546 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor;
547 }
548 offset *= ctx->MRD;
549 }
550 }
551
552 if (DO_FLAT) {
553 if (HAVE_RGBA) {
554 VERT_SAVE_RGBA( 0 );
555 VERT_SAVE_RGBA( 1 );
556 VERT_SAVE_RGBA( 2 );
557 VERT_COPY_RGBA( v[0], v[3] );
558 VERT_COPY_RGBA( v[1], v[3] );
559 VERT_COPY_RGBA( v[2], v[3] );
560 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
561 VERT_SAVE_SPEC( 0 );
562 VERT_SAVE_SPEC( 1 );
563 VERT_SAVE_SPEC( 2 );
564 VERT_COPY_SPEC( v[0], v[3] );
565 VERT_COPY_SPEC( v[1], v[3] );
566 VERT_COPY_SPEC( v[2], v[3] );
567 }
568 }
569 else {
570 VERT_SAVE_IND( 0 );
571 VERT_SAVE_IND( 1 );
572 VERT_SAVE_IND( 2 );
573 VERT_COPY_IND( v[0], v[3] );
574 VERT_COPY_IND( v[1], v[3] );
575 VERT_COPY_IND( v[2], v[3] );
576 }
577 }
578
579 if (mode == GL_POINT) {
580 if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
581 VERT_Z_ADD(v[0], offset);
582 VERT_Z_ADD(v[1], offset);
583 VERT_Z_ADD(v[2], offset);
584 VERT_Z_ADD(v[3], offset);
585 }
586 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
587 SETUP_STENCIL(facing);
588 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
589 UNSET_STENCIL(facing);
590 } else {
591 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
592 }
593 } else if (mode == GL_LINE) {
594 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
595 VERT_Z_ADD(v[0], offset);
596 VERT_Z_ADD(v[1], offset);
597 VERT_Z_ADD(v[2], offset);
598 VERT_Z_ADD(v[3], offset);
599 }
600 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
601 SETUP_STENCIL(facing);
602 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
603 UNSET_STENCIL(facing);
604 } else {
605 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
606 }
607 } else {
608 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
609 VERT_Z_ADD(v[0], offset);
610 VERT_Z_ADD(v[1], offset);
611 VERT_Z_ADD(v[2], offset);
612 VERT_Z_ADD(v[3], offset);
613 }
614 RASTERIZE( GL_QUADS );
615 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
616 SETUP_STENCIL(facing);
617 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
618 UNSET_STENCIL(facing);
619 } else {
620 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
621 }
622 }
623
624 if (DO_OFFSET)
625 {
626 VERT_SET_Z(v[0], z[0]);
627 VERT_SET_Z(v[1], z[1]);
628 VERT_SET_Z(v[2], z[2]);
629 VERT_SET_Z(v[3], z[3]);
630 }
631
632 if (DO_TWOSIDE && facing == 1)
633 {
634 if (HAVE_RGBA) {
635 if (!DO_FLAT) {
636 VERT_RESTORE_RGBA( 0 );
637 VERT_RESTORE_RGBA( 1 );
638 VERT_RESTORE_RGBA( 2 );
639 }
640 VERT_RESTORE_RGBA( 3 );
641 if (HAVE_SPEC) {
642 if (!DO_FLAT) {
643 VERT_RESTORE_SPEC( 0 );
644 VERT_RESTORE_SPEC( 1 );
645 VERT_RESTORE_SPEC( 2 );
646 }
647 VERT_RESTORE_SPEC( 3 );
648 }
649 }
650 else {
651 if (!DO_FLAT) {
652 VERT_RESTORE_IND( 0 );
653 VERT_RESTORE_IND( 1 );
654 VERT_RESTORE_IND( 2 );
655 }
656 VERT_RESTORE_IND( 3 );
657 }
658 }
659
660
661 if (DO_FLAT) {
662 if (HAVE_RGBA) {
663 VERT_RESTORE_RGBA( 0 );
664 VERT_RESTORE_RGBA( 1 );
665 VERT_RESTORE_RGBA( 2 );
666 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
667 VERT_RESTORE_SPEC( 0 );
668 VERT_RESTORE_SPEC( 1 );
669 VERT_RESTORE_SPEC( 2 );
670 }
671 }
672 else {
673 VERT_RESTORE_IND( 0 );
674 VERT_RESTORE_IND( 1 );
675 VERT_RESTORE_IND( 2 );
676 }
677 }
678 }
679 #else
680 static void TAG(quad)( GLcontext *ctx, GLuint e0,
681 GLuint e1, GLuint e2, GLuint e3 )
682 {
683 if (DO_UNFILLED) {
684 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
685 GLubyte ef1 = VB->EdgeFlag[e1];
686 GLubyte ef3 = VB->EdgeFlag[e3];
687 VB->EdgeFlag[e1] = 0;
688 TAG(triangle)( ctx, e0, e1, e3 );
689 VB->EdgeFlag[e1] = ef1;
690 VB->EdgeFlag[e3] = 0;
691 TAG(triangle)( ctx, e1, e2, e3 );
692 VB->EdgeFlag[e3] = ef3;
693 } else {
694 TAG(triangle)( ctx, e0, e1, e3 );
695 TAG(triangle)( ctx, e1, e2, e3 );
696 }
697 }
698 #endif
699 #endif
700
701 #if DO_LINE
702 static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1 )
703 {
704 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
705 VERTEX *v[2];
706 LOCAL_VARS(2);
707
708 v[0] = (VERTEX *)GET_VERTEX(e0);
709 v[1] = (VERTEX *)GET_VERTEX(e1);
710
711 if (DO_FLAT) {
712 if (HAVE_RGBA) {
713 VERT_SAVE_RGBA( 0 );
714 VERT_COPY_RGBA( v[0], v[1] );
715 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
716 VERT_SAVE_SPEC( 0 );
717 VERT_COPY_SPEC( v[0], v[1] );
718 }
719 }
720 else {
721 VERT_SAVE_IND( 0 );
722 VERT_COPY_IND( v[0], v[1] );
723 }
724 }
725
726 LINE( v[0], v[1] );
727
728 if (DO_FLAT) {
729 if (HAVE_RGBA) {
730 VERT_RESTORE_RGBA( 0 );
731
732 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
733 VERT_RESTORE_SPEC( 0 );
734 }
735 }
736 else {
737 VERT_RESTORE_IND( 0 );
738 }
739 }
740 }
741 #endif
742
743 #if DO_POINTS
744 static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
745 {
746 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
747 int i;
748 LOCAL_VARS(1);
749
750 if (VB->Elts == 0) {
751 for ( i = first ; i < last ; i++ ) {
752 if ( VB->ClipMask[i] == 0 ) {
753 VERTEX *v = (VERTEX *)GET_VERTEX(i);
754 POINT( v );
755 }
756 }
757 } else {
758 for ( i = first ; i < last ; i++ ) {
759 GLuint e = VB->Elts[i];
760 if ( VB->ClipMask[e] == 0 ) {
761 VERTEX *v = (VERTEX *)GET_VERTEX(e);
762 POINT( v );
763 }
764 }
765 }
766 }
767 #endif
768
769 static void TAG(init)( void )
770 {
771 #if DO_QUAD
772 TAB[IND].quad = TAG(quad);
773 #endif
774 #if DO_TRI
775 TAB[IND].triangle = TAG(triangle);
776 #endif
777 #if DO_LINE
778 TAB[IND].line = TAG(line);
779 #endif
780 #if DO_POINTS
781 TAB[IND].points = TAG(points);
782 #endif
783 }
784
785 #undef IND
786 #undef TAG
787
788 #if HAVE_RGBA
789 #undef VERT_SET_IND
790 #undef VERT_COPY_IND
791 #undef VERT_SAVE_IND
792 #undef VERT_RESTORE_IND
793 #if HAVE_BACK_COLORS
794 #undef VERT_SET_RGBA
795 #endif
796 #else
797 #undef VERT_SET_RGBA
798 #undef VERT_COPY_RGBA
799 #undef VERT_SAVE_RGBA
800 #undef VERT_RESTORE_RGBA
801 #if HAVE_BACK_COLORS
802 #undef VERT_SET_IND
803 #endif
804 #endif
805
806 #if !HAVE_SPEC
807 #undef VERT_SET_SPEC
808 #undef VERT_COPY_SPEC
809 #undef VERT_SAVE_SPEC
810 #undef VERT_RESTORE_SPEC
811 #if HAVE_BACK_COLORS
812 #undef VERT_COPY_SPEC1
813 #endif
814 #else
815 #if HAVE_BACK_COLORS
816 #undef VERT_SET_SPEC
817 #endif
818 #endif
819
820 #if !HAVE_BACK_COLORS
821 #undef VERT_COPY_SPEC1
822 #undef VERT_COPY_IND1
823 #undef VERT_COPY_RGBA1
824 #endif
825
826 #ifndef INSANE_VERTICES
827 #undef VERT_SET_Z
828 #undef VERT_Z_ADD
829 #endif