2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * Keith Whitwell <keith@tungstengraphics.com>
29 /* Template for building functions to plug into the driver interface
31 * ctx->Driver.QuadFunc
32 * ctx->Driver.TriangleFunc
33 * ctx->Driver.LineFunc
34 * ctx->Driver.PointsFunc
36 * DO_TWOSIDE: Plug back-color values from the VB into backfacing triangles,
37 * and restore vertices afterwards.
38 * DO_OFFSET: Calculate offset for triangles and adjust vertices. Restore
39 * vertices after rendering.
40 * DO_FLAT: For hardware without native flatshading, copy provoking colors
41 * into the other vertices. Restore after rendering.
42 * DO_UNFILLED: Decompose triangles to lines and points where appropriate.
43 * DO_TWOSTENCIL:Gross hack for two-sided stencil.
45 * HAVE_RGBA: Vertices have rgba values (otherwise index values).
46 * HAVE_SPEC: Vertices have secondary rgba values.
48 * VERT_X(v): Alias for vertex x value.
49 * VERT_Y(v): Alias for vertex y value.
50 * VERT_Z(v): Alias for vertex z value.
51 * DEPTH_SCALE: Scale for constant offset.
52 * REVERSE_DEPTH: Viewport depth range reversed.
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.
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.
64 * LOCAL_VARS(n): (At least) define local vars for save/restore 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 )
74 #define VERT_SET_RGBA( v, c )
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 )
82 #define VERT_SET_IND( v, c )
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 )
92 #define VERT_COPY_SPEC1( v )
96 #define VERT_SET_SPEC( v, c )
100 #if !HAVE_BACK_COLORS
101 #define VERT_COPY_SPEC1( v )
102 #define VERT_COPY_IND1( v )
103 #define VERT_COPY_RGBA1( v )
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
111 #ifndef REVERSE_DEPTH
112 #define REVERSE_DEPTH 0
115 /* disable twostencil for un-aware drivers */
116 #ifndef HAVE_STENCIL_TWOSIDE
117 #define HAVE_STENCIL_TWOSIDE 0
119 #ifndef DO_TWOSTENCIL
120 #define DO_TWOSTENCIL 0
122 #ifndef SETUP_STENCIL
123 #define SETUP_STENCIL(f)
125 #ifndef UNSET_STENCIL
126 #define UNSET_STENCIL(f)
130 static void TAG(triangle
)( GLcontext
*ctx
, GLuint e0
, GLuint e1
, GLuint e2
)
132 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
136 GLenum mode
= GL_FILL
;
140 /* fprintf(stderr, "%s\n", __FUNCTION__); */
142 v
[0] = (VERTEX
*)GET_VERTEX(e0
);
143 v
[1] = (VERTEX
*)GET_VERTEX(e1
);
144 v
[2] = (VERTEX
*)GET_VERTEX(e2
);
146 if (DO_TWOSIDE
|| DO_OFFSET
|| DO_UNFILLED
|| DO_TWOSTENCIL
)
148 GLfloat ex
= VERT_X(v
[0]) - VERT_X(v
[2]);
149 GLfloat ey
= VERT_Y(v
[0]) - VERT_Y(v
[2]);
150 GLfloat fx
= VERT_X(v
[1]) - VERT_X(v
[2]);
151 GLfloat fy
= VERT_Y(v
[1]) - VERT_Y(v
[2]);
152 GLfloat cc
= ex
*fy
- ey
*fx
;
154 if (DO_TWOSIDE
|| DO_UNFILLED
|| DO_TWOSTENCIL
)
156 facing
= AREA_IS_CCW( cc
) ^ ctx
->Polygon
._FrontBit
;
158 if (DO_TWOSTENCIL
&& ctx
->Stencil
.TestTwoSide
) {
159 ctx
->_Facing
= facing
; /* mixed mode rendering: for 2-sided stencil test */
164 mode
= ctx
->Polygon
.BackMode
;
165 if (ctx
->Polygon
.CullFlag
&&
166 ctx
->Polygon
.CullFaceMode
!= GL_FRONT
) {
170 mode
= ctx
->Polygon
.FrontMode
;
171 if (ctx
->Polygon
.CullFlag
&&
172 ctx
->Polygon
.CullFaceMode
!= GL_BACK
) {
178 if (DO_TWOSIDE
&& facing
== 1)
181 if (HAVE_BACK_COLORS
) {
185 VERT_COPY_RGBA1( v
[0] );
186 VERT_COPY_RGBA1( v
[1] );
189 VERT_COPY_RGBA1( v
[2] );
194 VERT_COPY_SPEC1( v
[0] );
195 VERT_COPY_SPEC1( v
[1] );
198 VERT_COPY_SPEC1( v
[2] );
202 GLfloat (*vbcolor
)[4] = VB
->ColorPtr
[1]->data
;
211 if (VB
->ColorPtr
[1]->stride
) {
212 ASSERT(VB
->ColorPtr
[1]->stride
== 4*sizeof(GLfloat
));
215 VERT_SET_RGBA( v
[0], vbcolor
[e0
] );
216 VERT_SET_RGBA( v
[1], vbcolor
[e1
] );
218 VERT_SET_RGBA( v
[2], vbcolor
[e2
] );
222 VERT_SET_RGBA( v
[0], vbcolor
[0] );
223 VERT_SET_RGBA( v
[1], vbcolor
[0] );
225 VERT_SET_RGBA( v
[2], vbcolor
[0] );
228 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[1]) {
229 GLfloat (*vbspec
)[4] = VB
->SecondaryColorPtr
[1]->data
;
230 ASSERT(VB
->SecondaryColorPtr
[1]->stride
== 4*sizeof(GLfloat
));
235 VERT_SET_SPEC( v
[0], vbspec
[e0
] );
236 VERT_SET_SPEC( v
[1], vbspec
[e1
] );
239 VERT_SET_SPEC( v
[2], vbspec
[e2
] );
244 GLfloat (*vbindex
) = (GLfloat
*)VB
->IndexPtr
[1]->data
;
248 VERT_SET_IND( v
[0], vbindex
[e0
] );
249 VERT_SET_IND( v
[1], vbindex
[e1
] );
252 VERT_SET_IND( v
[2], vbindex
[e2
] );
260 offset
= ctx
->Polygon
.OffsetUnits
* DEPTH_SCALE
;
264 if (cc
* cc
> 1e-16) {
265 GLfloat ic
= 1.0 / cc
;
266 GLfloat ez
= z
[0] - z
[2];
267 GLfloat fz
= z
[1] - z
[2];
268 GLfloat a
= ey
*fz
- ez
*fy
;
269 GLfloat b
= ez
*fx
- ex
*fz
;
272 if ( ac
< 0.0f
) ac
= -ac
;
273 if ( bc
< 0.0f
) bc
= -bc
;
274 offset
+= MAX2( ac
, bc
) * ctx
->Polygon
.OffsetFactor
;
276 offset
*= ctx
->DrawBuffer
->_MRD
* (REVERSE_DEPTH
? -1.0 : 1.0);
284 VERT_COPY_RGBA( v
[0], v
[2] );
285 VERT_COPY_RGBA( v
[1], v
[2] );
286 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
289 VERT_COPY_SPEC( v
[0], v
[2] );
290 VERT_COPY_SPEC( v
[1], v
[2] );
296 VERT_COPY_IND( v
[0], v
[2] );
297 VERT_COPY_IND( v
[1], v
[2] );
301 if (mode
== GL_POINT
) {
302 if (DO_OFFSET
&& ctx
->Polygon
.OffsetPoint
) {
303 VERT_Z_ADD(v
[0], offset
);
304 VERT_Z_ADD(v
[1], offset
);
305 VERT_Z_ADD(v
[2], offset
);
307 if (DO_TWOSTENCIL
&& !HAVE_STENCIL_TWOSIDE
&& ctx
->Stencil
.TestTwoSide
) {
308 SETUP_STENCIL(facing
);
309 UNFILLED_TRI( ctx
, GL_POINT
, e0
, e1
, e2
);
310 UNSET_STENCIL(facing
);
312 UNFILLED_TRI( ctx
, GL_POINT
, e0
, e1
, e2
);
314 } else if (mode
== GL_LINE
) {
315 if (DO_OFFSET
&& ctx
->Polygon
.OffsetLine
) {
316 VERT_Z_ADD(v
[0], offset
);
317 VERT_Z_ADD(v
[1], offset
);
318 VERT_Z_ADD(v
[2], offset
);
320 if (DO_TWOSTENCIL
&& !HAVE_STENCIL_TWOSIDE
&& ctx
->Stencil
.TestTwoSide
) {
321 SETUP_STENCIL(facing
);
322 UNFILLED_TRI( ctx
, GL_LINE
, e0
, e1
, e2
);
323 UNSET_STENCIL(facing
);
325 UNFILLED_TRI( ctx
, GL_LINE
, e0
, e1
, e2
);
328 if (DO_OFFSET
&& ctx
->Polygon
.OffsetFill
) {
329 VERT_Z_ADD(v
[0], offset
);
330 VERT_Z_ADD(v
[1], offset
);
331 VERT_Z_ADD(v
[2], offset
);
334 RASTERIZE( GL_TRIANGLES
);
335 if (DO_TWOSTENCIL
&& !HAVE_STENCIL_TWOSIDE
&& ctx
->Stencil
.TestTwoSide
) {
336 SETUP_STENCIL(facing
);
337 TRI( v
[0], v
[1], v
[2] );
338 UNSET_STENCIL(facing
);
340 TRI( v
[0], v
[1], v
[2] );
346 VERT_SET_Z(v
[0], z
[0]);
347 VERT_SET_Z(v
[1], z
[1]);
348 VERT_SET_Z(v
[2], z
[2]);
351 if (DO_TWOSIDE
&& facing
== 1)
355 VERT_RESTORE_RGBA( 0 );
356 VERT_RESTORE_RGBA( 1 );
358 VERT_RESTORE_RGBA( 2 );
361 VERT_RESTORE_SPEC( 0 );
362 VERT_RESTORE_SPEC( 1 );
364 VERT_RESTORE_SPEC( 2 );
369 VERT_RESTORE_IND( 0 );
370 VERT_RESTORE_IND( 1 );
372 VERT_RESTORE_IND( 2 );
379 VERT_RESTORE_RGBA( 0 );
380 VERT_RESTORE_RGBA( 1 );
381 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
382 VERT_RESTORE_SPEC( 0 );
383 VERT_RESTORE_SPEC( 1 );
387 VERT_RESTORE_IND( 0 );
388 VERT_RESTORE_IND( 1 );
396 static void TAG(quad
)( GLcontext
*ctx
,
397 GLuint e0
, GLuint e1
, GLuint e2
, GLuint e3
)
399 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
403 GLenum mode
= GL_FILL
;
407 v
[0] = (VERTEX
*)GET_VERTEX(e0
);
408 v
[1] = (VERTEX
*)GET_VERTEX(e1
);
409 v
[2] = (VERTEX
*)GET_VERTEX(e2
);
410 v
[3] = (VERTEX
*)GET_VERTEX(e3
);
412 if (DO_TWOSIDE
|| DO_OFFSET
|| DO_UNFILLED
|| DO_TWOSTENCIL
)
414 GLfloat ex
= VERT_X(v
[2]) - VERT_X(v
[0]);
415 GLfloat ey
= VERT_Y(v
[2]) - VERT_Y(v
[0]);
416 GLfloat fx
= VERT_X(v
[3]) - VERT_X(v
[1]);
417 GLfloat fy
= VERT_Y(v
[3]) - VERT_Y(v
[1]);
418 GLfloat cc
= ex
*fy
- ey
*fx
;
420 if (DO_TWOSIDE
|| DO_UNFILLED
|| DO_TWOSTENCIL
)
422 facing
= AREA_IS_CCW( cc
) ^ ctx
->Polygon
._FrontBit
;
424 if (DO_TWOSTENCIL
&& ctx
->Stencil
.TestTwoSide
) {
425 ctx
->_Facing
= facing
; /* mixed mode rendering: for 2-sided stencil test */
430 mode
= ctx
->Polygon
.BackMode
;
431 if (ctx
->Polygon
.CullFlag
&&
432 ctx
->Polygon
.CullFaceMode
!= GL_FRONT
) {
436 mode
= ctx
->Polygon
.FrontMode
;
437 if (ctx
->Polygon
.CullFlag
&&
438 ctx
->Polygon
.CullFaceMode
!= GL_BACK
) {
444 if (DO_TWOSIDE
&& facing
== 1)
447 GLfloat (*vbcolor
)[4] = VB
->ColorPtr
[1]->data
;
450 if (HAVE_BACK_COLORS
) {
455 VERT_COPY_RGBA1( v
[0] );
456 VERT_COPY_RGBA1( v
[1] );
457 VERT_COPY_RGBA1( v
[2] );
460 VERT_COPY_RGBA1( v
[3] );
466 VERT_COPY_SPEC1( v
[0] );
467 VERT_COPY_SPEC1( v
[1] );
468 VERT_COPY_SPEC1( v
[2] );
471 VERT_COPY_SPEC1( v
[3] );
482 if (VB
->ColorPtr
[1]->stride
) {
484 VERT_SET_RGBA( v
[0], vbcolor
[e0
] );
485 VERT_SET_RGBA( v
[1], vbcolor
[e1
] );
486 VERT_SET_RGBA( v
[2], vbcolor
[e2
] );
488 VERT_SET_RGBA( v
[3], vbcolor
[e3
] );
492 VERT_SET_RGBA( v
[0], vbcolor
[0] );
493 VERT_SET_RGBA( v
[1], vbcolor
[0] );
494 VERT_SET_RGBA( v
[2], vbcolor
[0] );
496 VERT_SET_RGBA( v
[3], vbcolor
[0] );
499 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[1]) {
500 GLfloat (*vbspec
)[4] = VB
->SecondaryColorPtr
[1]->data
;
501 ASSERT(VB
->SecondaryColorPtr
[1]->stride
==4*sizeof(GLfloat
));
507 VERT_SET_SPEC( v
[0], vbspec
[e0
] );
508 VERT_SET_SPEC( v
[1], vbspec
[e1
] );
509 VERT_SET_SPEC( v
[2], vbspec
[e2
] );
512 VERT_SET_SPEC( v
[3], vbspec
[e3
] );
517 GLfloat
*vbindex
= (GLfloat
*)VB
->IndexPtr
[1]->data
;
522 VERT_SET_IND( v
[0], vbindex
[e0
] );
523 VERT_SET_IND( v
[1], vbindex
[e1
] );
524 VERT_SET_IND( v
[2], vbindex
[e2
] );
527 VERT_SET_IND( v
[3], vbindex
[e3
] );
535 offset
= ctx
->Polygon
.OffsetUnits
* DEPTH_SCALE
;
540 if (cc
* cc
> 1e-16) {
541 GLfloat ez
= z
[2] - z
[0];
542 GLfloat fz
= z
[3] - z
[1];
543 GLfloat a
= ey
*fz
- ez
*fy
;
544 GLfloat b
= ez
*fx
- ex
*fz
;
545 GLfloat ic
= 1.0 / cc
;
548 if ( ac
< 0.0f
) ac
= -ac
;
549 if ( bc
< 0.0f
) bc
= -bc
;
550 offset
+= MAX2( ac
, bc
) * ctx
->Polygon
.OffsetFactor
;
552 offset
*= ctx
->DrawBuffer
->_MRD
* (REVERSE_DEPTH
? -1.0 : 1.0);
561 VERT_COPY_RGBA( v
[0], v
[3] );
562 VERT_COPY_RGBA( v
[1], v
[3] );
563 VERT_COPY_RGBA( v
[2], v
[3] );
564 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
568 VERT_COPY_SPEC( v
[0], v
[3] );
569 VERT_COPY_SPEC( v
[1], v
[3] );
570 VERT_COPY_SPEC( v
[2], v
[3] );
577 VERT_COPY_IND( v
[0], v
[3] );
578 VERT_COPY_IND( v
[1], v
[3] );
579 VERT_COPY_IND( v
[2], v
[3] );
583 if (mode
== GL_POINT
) {
584 if (( DO_OFFSET
) && ctx
->Polygon
.OffsetPoint
) {
585 VERT_Z_ADD(v
[0], offset
);
586 VERT_Z_ADD(v
[1], offset
);
587 VERT_Z_ADD(v
[2], offset
);
588 VERT_Z_ADD(v
[3], offset
);
590 if (DO_TWOSTENCIL
&& !HAVE_STENCIL_TWOSIDE
&& ctx
->Stencil
.TestTwoSide
) {
591 SETUP_STENCIL(facing
);
592 UNFILLED_QUAD( ctx
, GL_POINT
, e0
, e1
, e2
, e3
);
593 UNSET_STENCIL(facing
);
595 UNFILLED_QUAD( ctx
, GL_POINT
, e0
, e1
, e2
, e3
);
597 } else if (mode
== GL_LINE
) {
598 if (DO_OFFSET
&& ctx
->Polygon
.OffsetLine
) {
599 VERT_Z_ADD(v
[0], offset
);
600 VERT_Z_ADD(v
[1], offset
);
601 VERT_Z_ADD(v
[2], offset
);
602 VERT_Z_ADD(v
[3], offset
);
604 if (DO_TWOSTENCIL
&& !HAVE_STENCIL_TWOSIDE
&& ctx
->Stencil
.TestTwoSide
) {
605 SETUP_STENCIL(facing
);
606 UNFILLED_QUAD( ctx
, GL_LINE
, e0
, e1
, e2
, e3
);
607 UNSET_STENCIL(facing
);
609 UNFILLED_QUAD( ctx
, GL_LINE
, e0
, e1
, e2
, e3
);
612 if (DO_OFFSET
&& ctx
->Polygon
.OffsetFill
) {
613 VERT_Z_ADD(v
[0], offset
);
614 VERT_Z_ADD(v
[1], offset
);
615 VERT_Z_ADD(v
[2], offset
);
616 VERT_Z_ADD(v
[3], offset
);
618 RASTERIZE( GL_QUADS
);
619 if (DO_TWOSTENCIL
&& !HAVE_STENCIL_TWOSIDE
&& ctx
->Stencil
.TestTwoSide
) {
620 SETUP_STENCIL(facing
);
621 QUAD( (v
[0]), (v
[1]), (v
[2]), (v
[3]) );
622 UNSET_STENCIL(facing
);
624 QUAD( (v
[0]), (v
[1]), (v
[2]), (v
[3]) );
630 VERT_SET_Z(v
[0], z
[0]);
631 VERT_SET_Z(v
[1], z
[1]);
632 VERT_SET_Z(v
[2], z
[2]);
633 VERT_SET_Z(v
[3], z
[3]);
636 if (DO_TWOSIDE
&& facing
== 1)
640 VERT_RESTORE_RGBA( 0 );
641 VERT_RESTORE_RGBA( 1 );
642 VERT_RESTORE_RGBA( 2 );
644 VERT_RESTORE_RGBA( 3 );
647 VERT_RESTORE_SPEC( 0 );
648 VERT_RESTORE_SPEC( 1 );
649 VERT_RESTORE_SPEC( 2 );
651 VERT_RESTORE_SPEC( 3 );
656 VERT_RESTORE_IND( 0 );
657 VERT_RESTORE_IND( 1 );
658 VERT_RESTORE_IND( 2 );
660 VERT_RESTORE_IND( 3 );
667 VERT_RESTORE_RGBA( 0 );
668 VERT_RESTORE_RGBA( 1 );
669 VERT_RESTORE_RGBA( 2 );
670 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
671 VERT_RESTORE_SPEC( 0 );
672 VERT_RESTORE_SPEC( 1 );
673 VERT_RESTORE_SPEC( 2 );
677 VERT_RESTORE_IND( 0 );
678 VERT_RESTORE_IND( 1 );
679 VERT_RESTORE_IND( 2 );
684 static void TAG(quad
)( GLcontext
*ctx
, GLuint e0
,
685 GLuint e1
, GLuint e2
, GLuint e3
)
688 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
689 GLubyte ef1
= VB
->EdgeFlag
[e1
];
690 GLubyte ef3
= VB
->EdgeFlag
[e3
];
691 VB
->EdgeFlag
[e1
] = 0;
692 TAG(triangle
)( ctx
, e0
, e1
, e3
);
693 VB
->EdgeFlag
[e1
] = ef1
;
694 VB
->EdgeFlag
[e3
] = 0;
695 TAG(triangle
)( ctx
, e1
, e2
, e3
);
696 VB
->EdgeFlag
[e3
] = ef3
;
698 TAG(triangle
)( ctx
, e0
, e1
, e3
);
699 TAG(triangle
)( ctx
, e1
, e2
, e3
);
706 static void TAG(line
)( GLcontext
*ctx
, GLuint e0
, GLuint e1
)
708 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
712 v
[0] = (VERTEX
*)GET_VERTEX(e0
);
713 v
[1] = (VERTEX
*)GET_VERTEX(e1
);
718 VERT_COPY_RGBA( v
[0], v
[1] );
719 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
721 VERT_COPY_SPEC( v
[0], v
[1] );
726 VERT_COPY_IND( v
[0], v
[1] );
734 VERT_RESTORE_RGBA( 0 );
736 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
737 VERT_RESTORE_SPEC( 0 );
741 VERT_RESTORE_IND( 0 );
748 static void TAG(points
)( GLcontext
*ctx
, GLuint first
, GLuint last
)
750 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
755 for ( i
= first
; i
< last
; i
++ ) {
756 if ( VB
->ClipMask
[i
] == 0 ) {
757 VERTEX
*v
= (VERTEX
*)GET_VERTEX(i
);
762 for ( i
= first
; i
< last
; i
++ ) {
763 GLuint e
= VB
->Elts
[i
];
764 if ( VB
->ClipMask
[e
] == 0 ) {
765 VERTEX
*v
= (VERTEX
*)GET_VERTEX(e
);
773 static void TAG(init
)( void )
776 TAB
[IND
].quad
= TAG(quad
);
779 TAB
[IND
].triangle
= TAG(triangle
);
782 TAB
[IND
].line
= TAG(line
);
785 TAB
[IND
].points
= TAG(points
);
796 #undef VERT_RESTORE_IND
802 #undef VERT_COPY_RGBA
803 #undef VERT_SAVE_RGBA
804 #undef VERT_RESTORE_RGBA
812 #undef VERT_COPY_SPEC
813 #undef VERT_SAVE_SPEC
814 #undef VERT_RESTORE_SPEC
816 #undef VERT_COPY_SPEC1
824 #if !HAVE_BACK_COLORS
825 #undef VERT_COPY_SPEC1
826 #undef VERT_COPY_IND1
827 #undef VERT_COPY_RGBA1
830 #ifndef INSANE_VERTICES