3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
26 * Keith Whitwell <keith@tungstengraphics.com>
30 /* Template for building functions to plug into the driver interface
32 * ctx->Driver.QuadFunc
33 * ctx->Driver.TriangleFunc
34 * ctx->Driver.LineFunc
35 * ctx->Driver.PointsFunc
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.
46 * HAVE_RGBA: Vertices have rgba values (otherwise index values).
47 * HAVE_SPEC: Vertices have secondary rgba values.
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.
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.
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.
65 * LOCAL_VARS(n): (At least) define local vars for save/restore 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 )
75 #define VERT_SET_RGBA( v, c )
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 )
83 #define VERT_SET_IND( v, c )
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 )
93 #define VERT_COPY_SPEC1( v )
97 #define VERT_SET_SPEC( v, c )
101 #if !HAVE_BACK_COLORS
102 #define VERT_COPY_SPEC1( v )
103 #define VERT_COPY_IND1( v )
104 #define VERT_COPY_RGBA1( v )
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
112 #ifndef REVERSE_DEPTH
113 #define REVERSE_DEPTH 0
116 /* disable twostencil for un-aware drivers */
117 #ifndef HAVE_STENCIL_TWOSIDE
118 #define HAVE_STENCIL_TWOSIDE 0
120 #ifndef DO_TWOSTENCIL
121 #define DO_TWOSTENCIL 0
123 #ifndef SETUP_STENCIL
124 #define SETUP_STENCIL(f)
126 #ifndef UNSET_STENCIL
127 #define UNSET_STENCIL(f)
131 static void TAG(triangle
)( GLcontext
*ctx
, GLuint e0
, GLuint e1
, GLuint e2
)
133 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
137 GLenum mode
= GL_FILL
;
141 /* fprintf(stderr, "%s\n", __FUNCTION__); */
143 v
[0] = (VERTEX
*)GET_VERTEX(e0
);
144 v
[1] = (VERTEX
*)GET_VERTEX(e1
);
145 v
[2] = (VERTEX
*)GET_VERTEX(e2
);
147 if (DO_TWOSIDE
|| DO_OFFSET
|| DO_UNFILLED
|| DO_TWOSTENCIL
)
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
;
155 if (DO_TWOSIDE
|| DO_UNFILLED
|| DO_TWOSTENCIL
)
157 facing
= AREA_IS_CCW( cc
) ^ ctx
->Polygon
._FrontBit
;
159 if (DO_TWOSTENCIL
&& ctx
->Stencil
.TestTwoSide
) {
160 ctx
->_Facing
= facing
; /* mixed mode rendering: for 2-sided stencil test */
165 mode
= ctx
->Polygon
.BackMode
;
166 if (ctx
->Polygon
.CullFlag
&&
167 ctx
->Polygon
.CullFaceMode
!= GL_FRONT
) {
171 mode
= ctx
->Polygon
.FrontMode
;
172 if (ctx
->Polygon
.CullFlag
&&
173 ctx
->Polygon
.CullFaceMode
!= GL_BACK
) {
179 if (DO_TWOSIDE
&& facing
== 1)
182 if (HAVE_BACK_COLORS
) {
186 VERT_COPY_RGBA1( v
[0] );
187 VERT_COPY_RGBA1( v
[1] );
190 VERT_COPY_RGBA1( v
[2] );
195 VERT_COPY_SPEC1( v
[0] );
196 VERT_COPY_SPEC1( v
[1] );
199 VERT_COPY_SPEC1( v
[2] );
203 GLfloat (*vbcolor
)[4] = VB
->ColorPtr
[1]->data
;
212 if (VB
->ColorPtr
[1]->stride
) {
213 ASSERT(VB
->ColorPtr
[1]->stride
== 4*sizeof(GLfloat
));
216 VERT_SET_RGBA( v
[0], vbcolor
[e0
] );
217 VERT_SET_RGBA( v
[1], vbcolor
[e1
] );
219 VERT_SET_RGBA( v
[2], vbcolor
[e2
] );
223 VERT_SET_RGBA( v
[0], vbcolor
[0] );
224 VERT_SET_RGBA( v
[1], vbcolor
[0] );
226 VERT_SET_RGBA( v
[2], vbcolor
[0] );
229 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[1]) {
230 GLfloat (*vbspec
)[4] = VB
->SecondaryColorPtr
[1]->data
;
231 ASSERT(VB
->SecondaryColorPtr
[1]->stride
== 4*sizeof(GLfloat
));
236 VERT_SET_SPEC( v
[0], vbspec
[e0
] );
237 VERT_SET_SPEC( v
[1], vbspec
[e1
] );
240 VERT_SET_SPEC( v
[2], vbspec
[e2
] );
245 GLfloat (*vbindex
) = (GLfloat
*)VB
->IndexPtr
[1]->data
;
249 VERT_SET_IND( v
[0], vbindex
[e0
] );
250 VERT_SET_IND( v
[1], vbindex
[e1
] );
253 VERT_SET_IND( v
[2], vbindex
[e2
] );
261 offset
= ctx
->Polygon
.OffsetUnits
* DEPTH_SCALE
;
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
;
273 if ( ac
< 0.0f
) ac
= -ac
;
274 if ( bc
< 0.0f
) bc
= -bc
;
275 offset
+= MAX2( ac
, bc
) * ctx
->Polygon
.OffsetFactor
;
277 offset
*= REVERSE_DEPTH
? -ctx
->MRD
: ctx
->MRD
;
285 VERT_COPY_RGBA( v
[0], v
[2] );
286 VERT_COPY_RGBA( v
[1], v
[2] );
287 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
290 VERT_COPY_SPEC( v
[0], v
[2] );
291 VERT_COPY_SPEC( v
[1], v
[2] );
297 VERT_COPY_IND( v
[0], v
[2] );
298 VERT_COPY_IND( v
[1], v
[2] );
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
);
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
);
313 UNFILLED_TRI( ctx
, GL_POINT
, e0
, e1
, e2
);
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
);
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
);
326 UNFILLED_TRI( ctx
, GL_LINE
, e0
, e1
, e2
);
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
);
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
);
341 TRI( v
[0], v
[1], v
[2] );
347 VERT_SET_Z(v
[0], z
[0]);
348 VERT_SET_Z(v
[1], z
[1]);
349 VERT_SET_Z(v
[2], z
[2]);
352 if (DO_TWOSIDE
&& facing
== 1)
356 VERT_RESTORE_RGBA( 0 );
357 VERT_RESTORE_RGBA( 1 );
359 VERT_RESTORE_RGBA( 2 );
362 VERT_RESTORE_SPEC( 0 );
363 VERT_RESTORE_SPEC( 1 );
365 VERT_RESTORE_SPEC( 2 );
370 VERT_RESTORE_IND( 0 );
371 VERT_RESTORE_IND( 1 );
373 VERT_RESTORE_IND( 2 );
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 );
388 VERT_RESTORE_IND( 0 );
389 VERT_RESTORE_IND( 1 );
397 static void TAG(quad
)( GLcontext
*ctx
,
398 GLuint e0
, GLuint e1
, GLuint e2
, GLuint e3
)
400 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
404 GLenum mode
= GL_FILL
;
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
);
413 if (DO_TWOSIDE
|| DO_OFFSET
|| DO_UNFILLED
|| DO_TWOSTENCIL
)
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
;
421 if (DO_TWOSIDE
|| DO_UNFILLED
|| DO_TWOSTENCIL
)
423 facing
= AREA_IS_CCW( cc
) ^ ctx
->Polygon
._FrontBit
;
425 if (DO_TWOSTENCIL
&& ctx
->Stencil
.TestTwoSide
) {
426 ctx
->_Facing
= facing
; /* mixed mode rendering: for 2-sided stencil test */
431 mode
= ctx
->Polygon
.BackMode
;
432 if (ctx
->Polygon
.CullFlag
&&
433 ctx
->Polygon
.CullFaceMode
!= GL_FRONT
) {
437 mode
= ctx
->Polygon
.FrontMode
;
438 if (ctx
->Polygon
.CullFlag
&&
439 ctx
->Polygon
.CullFaceMode
!= GL_BACK
) {
445 if (DO_TWOSIDE
&& facing
== 1)
448 GLfloat (*vbcolor
)[4] = VB
->ColorPtr
[1]->data
;
451 if (HAVE_BACK_COLORS
) {
456 VERT_COPY_RGBA1( v
[0] );
457 VERT_COPY_RGBA1( v
[1] );
458 VERT_COPY_RGBA1( v
[2] );
461 VERT_COPY_RGBA1( v
[3] );
467 VERT_COPY_SPEC1( v
[0] );
468 VERT_COPY_SPEC1( v
[1] );
469 VERT_COPY_SPEC1( v
[2] );
472 VERT_COPY_SPEC1( v
[3] );
483 if (VB
->ColorPtr
[1]->stride
) {
485 VERT_SET_RGBA( v
[0], vbcolor
[e0
] );
486 VERT_SET_RGBA( v
[1], vbcolor
[e1
] );
487 VERT_SET_RGBA( v
[2], vbcolor
[e2
] );
489 VERT_SET_RGBA( v
[3], vbcolor
[e3
] );
493 VERT_SET_RGBA( v
[0], vbcolor
[0] );
494 VERT_SET_RGBA( v
[1], vbcolor
[0] );
495 VERT_SET_RGBA( v
[2], vbcolor
[0] );
497 VERT_SET_RGBA( v
[3], vbcolor
[0] );
500 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[1]) {
501 GLfloat (*vbspec
)[4] = VB
->SecondaryColorPtr
[1]->data
;
502 ASSERT(VB
->SecondaryColorPtr
[1]->stride
==4*sizeof(GLfloat
));
508 VERT_SET_SPEC( v
[0], vbspec
[e0
] );
509 VERT_SET_SPEC( v
[1], vbspec
[e1
] );
510 VERT_SET_SPEC( v
[2], vbspec
[e2
] );
513 VERT_SET_SPEC( v
[3], vbspec
[e3
] );
518 GLfloat
*vbindex
= (GLfloat
*)VB
->IndexPtr
[1]->data
;
523 VERT_SET_IND( v
[0], vbindex
[e0
] );
524 VERT_SET_IND( v
[1], vbindex
[e1
] );
525 VERT_SET_IND( v
[2], vbindex
[e2
] );
528 VERT_SET_IND( v
[3], vbindex
[e3
] );
536 offset
= ctx
->Polygon
.OffsetUnits
* DEPTH_SCALE
;
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
;
549 if ( ac
< 0.0f
) ac
= -ac
;
550 if ( bc
< 0.0f
) bc
= -bc
;
551 offset
+= MAX2( ac
, bc
) * ctx
->Polygon
.OffsetFactor
;
553 offset
*= REVERSE_DEPTH
? -ctx
->MRD
: ctx
->MRD
;
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]) {
569 VERT_COPY_SPEC( v
[0], v
[3] );
570 VERT_COPY_SPEC( v
[1], v
[3] );
571 VERT_COPY_SPEC( v
[2], v
[3] );
578 VERT_COPY_IND( v
[0], v
[3] );
579 VERT_COPY_IND( v
[1], v
[3] );
580 VERT_COPY_IND( v
[2], v
[3] );
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
);
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
);
596 UNFILLED_QUAD( ctx
, GL_POINT
, e0
, e1
, e2
, e3
);
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
);
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
);
610 UNFILLED_QUAD( ctx
, GL_LINE
, e0
, e1
, e2
, e3
);
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
);
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
);
625 QUAD( (v
[0]), (v
[1]), (v
[2]), (v
[3]) );
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]);
637 if (DO_TWOSIDE
&& facing
== 1)
641 VERT_RESTORE_RGBA( 0 );
642 VERT_RESTORE_RGBA( 1 );
643 VERT_RESTORE_RGBA( 2 );
645 VERT_RESTORE_RGBA( 3 );
648 VERT_RESTORE_SPEC( 0 );
649 VERT_RESTORE_SPEC( 1 );
650 VERT_RESTORE_SPEC( 2 );
652 VERT_RESTORE_SPEC( 3 );
657 VERT_RESTORE_IND( 0 );
658 VERT_RESTORE_IND( 1 );
659 VERT_RESTORE_IND( 2 );
661 VERT_RESTORE_IND( 3 );
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 );
678 VERT_RESTORE_IND( 0 );
679 VERT_RESTORE_IND( 1 );
680 VERT_RESTORE_IND( 2 );
685 static void TAG(quad
)( GLcontext
*ctx
, GLuint e0
,
686 GLuint e1
, GLuint e2
, GLuint e3
)
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
;
699 TAG(triangle
)( ctx
, e0
, e1
, e3
);
700 TAG(triangle
)( ctx
, e1
, e2
, e3
);
707 static void TAG(line
)( GLcontext
*ctx
, GLuint e0
, GLuint e1
)
709 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
713 v
[0] = (VERTEX
*)GET_VERTEX(e0
);
714 v
[1] = (VERTEX
*)GET_VERTEX(e1
);
719 VERT_COPY_RGBA( v
[0], v
[1] );
720 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
722 VERT_COPY_SPEC( v
[0], v
[1] );
727 VERT_COPY_IND( v
[0], v
[1] );
735 VERT_RESTORE_RGBA( 0 );
737 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
738 VERT_RESTORE_SPEC( 0 );
742 VERT_RESTORE_IND( 0 );
749 static void TAG(points
)( GLcontext
*ctx
, GLuint first
, GLuint last
)
751 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
756 for ( i
= first
; i
< last
; i
++ ) {
757 if ( VB
->ClipMask
[i
] == 0 ) {
758 VERTEX
*v
= (VERTEX
*)GET_VERTEX(i
);
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
);
774 static void TAG(init
)( void )
777 TAB
[IND
].quad
= TAG(quad
);
780 TAB
[IND
].triangle
= TAG(triangle
);
783 TAB
[IND
].line
= TAG(line
);
786 TAB
[IND
].points
= TAG(points
);
797 #undef VERT_RESTORE_IND
803 #undef VERT_COPY_RGBA
804 #undef VERT_SAVE_RGBA
805 #undef VERT_RESTORE_RGBA
813 #undef VERT_COPY_SPEC
814 #undef VERT_SAVE_SPEC
815 #undef VERT_RESTORE_SPEC
817 #undef VERT_COPY_SPEC1
825 #if !HAVE_BACK_COLORS
826 #undef VERT_COPY_SPEC1
827 #undef VERT_COPY_IND1
828 #undef VERT_COPY_RGBA1
831 #ifndef INSANE_VERTICES