1 /* $Id: t_vb_rendertmp.h,v 1.10 2002/10/29 20:29:04 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Keith Whitwell <keith@tungstengraphics.com>
39 #ifndef NEED_EDGEFLAG_SETUP
40 #define NEED_EDGEFLAG_SETUP 0
41 #define EDGEFLAG_GET(a) 0
42 #define EDGEFLAG_SET(a,b) (void)b
49 #ifndef RESET_OCCLUSION
50 #define RESET_OCCLUSION
54 #define TEST_PRIM_END(flags) (flags & PRIM_END)
55 #define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
56 #define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
63 #ifndef RENDER_TAB_QUALIFIER
64 #define RENDER_TAB_QUALIFIER static
67 static void TAG(render_points
)( GLcontext
*ctx
,
77 RENDER_POINTS( start
, count
);
81 static void TAG(render_lines
)( GLcontext
*ctx
,
92 for (j
=start
+1; j
<count
; j
+=2 ) {
94 RENDER_LINE( ELT(j
-1), ELT(j
) );
100 static void TAG(render_line_strip
)( GLcontext
*ctx
,
112 if (TEST_PRIM_BEGIN(flags
)) {
116 for (j
=start
+1; j
<count
; j
++ )
117 RENDER_LINE( ELT(j
-1), ELT(j
) );
123 static void TAG(render_line_loop
)( GLcontext
*ctx
,
136 if (start
+1 < count
) {
137 if (TEST_PRIM_BEGIN(flags
)) {
139 RENDER_LINE( ELT(start
), ELT(start
+1) );
142 for ( i
= start
+2 ; i
< count
; i
++) {
143 RENDER_LINE( ELT(i
-1), ELT(i
) );
146 if ( TEST_PRIM_END(flags
)) {
147 RENDER_LINE( ELT(count
-1), ELT(start
) );
155 static void TAG(render_triangles
)( GLcontext
*ctx
,
165 if (NEED_EDGEFLAG_SETUP
) {
166 for (j
=start
+2; j
<count
; j
+=3) {
167 /* Leave the edgeflags as supplied by the user.
170 RENDER_TRI( ELT(j
-2), ELT(j
-1), ELT(j
) );
173 for (j
=start
+2; j
<count
; j
+=3) {
174 RENDER_TRI( ELT(j
-2), ELT(j
-1), ELT(j
) );
182 static void TAG(render_tri_strip
)( GLcontext
*ctx
,
191 if (TEST_PRIM_PARITY(flags
))
194 INIT(GL_TRIANGLE_STRIP
);
195 if (NEED_EDGEFLAG_SETUP
) {
196 for (j
=start
+2;j
<count
;j
++,parity
^=1) {
197 GLuint ej2
= ELT(j
-2+parity
);
198 GLuint ej1
= ELT(j
-1-parity
);
200 GLboolean ef2
= EDGEFLAG_GET( ej2
);
201 GLboolean ef1
= EDGEFLAG_GET( ej1
);
202 GLboolean ef
= EDGEFLAG_GET( ej
);
203 if (TEST_PRIM_BEGIN(flags
)) {
206 EDGEFLAG_SET( ej2
, GL_TRUE
);
207 EDGEFLAG_SET( ej1
, GL_TRUE
);
208 EDGEFLAG_SET( ej
, GL_TRUE
);
209 RENDER_TRI( ej2
, ej1
, ej
);
210 EDGEFLAG_SET( ej2
, ef2
);
211 EDGEFLAG_SET( ej1
, ef1
);
212 EDGEFLAG_SET( ej
, ef
);
215 for (j
=start
+2; j
<count
; j
++, parity
^=1) {
216 RENDER_TRI( ELT(j
-2+parity
), ELT(j
-1-parity
), ELT(j
) );
223 static void TAG(render_tri_fan
)( GLcontext
*ctx
,
232 INIT(GL_TRIANGLE_FAN
);
233 if (NEED_EDGEFLAG_SETUP
) {
234 for (j
=start
+2;j
<count
;j
++) {
235 /* For trifans, all edges are boundary.
237 GLuint ejs
= ELT(start
);
238 GLuint ej1
= ELT(j
-1);
240 GLboolean efs
= EDGEFLAG_GET( ejs
);
241 GLboolean ef1
= EDGEFLAG_GET( ej1
);
242 GLboolean ef
= EDGEFLAG_GET( ej
);
243 if (TEST_PRIM_BEGIN(flags
)) {
246 EDGEFLAG_SET( ejs
, GL_TRUE
);
247 EDGEFLAG_SET( ej1
, GL_TRUE
);
248 EDGEFLAG_SET( ej
, GL_TRUE
);
249 RENDER_TRI( ejs
, ej1
, ej
);
250 EDGEFLAG_SET( ejs
, efs
);
251 EDGEFLAG_SET( ej1
, ef1
);
252 EDGEFLAG_SET( ej
, ef
);
255 for (j
=start
+2;j
<count
;j
++) {
256 RENDER_TRI( ELT(start
), ELT(j
-1), ELT(j
) );
264 static void TAG(render_poly
)( GLcontext
*ctx
,
274 if (NEED_EDGEFLAG_SETUP
) {
275 GLboolean efstart
= EDGEFLAG_GET( ELT(start
) );
276 GLboolean efcount
= EDGEFLAG_GET( ELT(count
-1) );
278 /* If the primitive does not begin here, the first edge
281 if (!TEST_PRIM_BEGIN(flags
))
282 EDGEFLAG_SET( ELT(start
), GL_FALSE
);
287 /* If the primitive does not end here, the final edge is
290 if (!TEST_PRIM_END(flags
))
291 EDGEFLAG_SET( ELT(count
-1), GL_FALSE
);
293 /* Draw the first triangles (possibly zero)
296 GLboolean ef
= EDGEFLAG_GET( ELT(j
) );
297 EDGEFLAG_SET( ELT(j
), GL_FALSE
);
298 RENDER_TRI( ELT(j
-1), ELT(j
), ELT(start
) );
299 EDGEFLAG_SET( ELT(j
), ef
);
302 /* Don't render the first edge again:
304 EDGEFLAG_SET( ELT(start
), GL_FALSE
);
306 for (;j
+1<count
;j
++) {
307 GLboolean efj
= EDGEFLAG_GET( ELT(j
) );
308 EDGEFLAG_SET( ELT(j
), GL_FALSE
);
309 RENDER_TRI( ELT(j
-1), ELT(j
), ELT(start
) );
310 EDGEFLAG_SET( ELT(j
), efj
);
314 /* Draw the last or only triangle
317 RENDER_TRI( ELT(j
-1), ELT(j
), ELT(start
) );
319 /* Restore the first and last edgeflags:
321 EDGEFLAG_SET( ELT(count
-1), efcount
);
322 EDGEFLAG_SET( ELT(start
), efstart
);
326 for (j
=start
+2;j
<count
;j
++) {
327 RENDER_TRI( ELT(j
-1), ELT(j
), ELT(start
) );
333 static void TAG(render_quads
)( GLcontext
*ctx
,
343 if (NEED_EDGEFLAG_SETUP
) {
344 for (j
=start
+3; j
<count
; j
+=4) {
345 /* Use user-specified edgeflags for quads.
348 RENDER_QUAD( ELT(j
-3), ELT(j
-2), ELT(j
-1), ELT(j
) );
351 for (j
=start
+3; j
<count
; j
+=4) {
352 RENDER_QUAD( ELT(j
-3), ELT(j
-2), ELT(j
-1), ELT(j
) );
358 static void TAG(render_quad_strip
)( GLcontext
*ctx
,
368 if (NEED_EDGEFLAG_SETUP
) {
369 for (j
=start
+3;j
<count
;j
+=2) {
370 /* All edges are boundary. Set edgeflags to 1, draw the
371 * quad, and restore them to the original values.
373 GLboolean ef3
= EDGEFLAG_GET( ELT(j
-3) );
374 GLboolean ef2
= EDGEFLAG_GET( ELT(j
-2) );
375 GLboolean ef1
= EDGEFLAG_GET( ELT(j
-1) );
376 GLboolean ef
= EDGEFLAG_GET( ELT(j
) );
377 if (TEST_PRIM_BEGIN(flags
)) {
380 EDGEFLAG_SET( ELT(j
-3), GL_TRUE
);
381 EDGEFLAG_SET( ELT(j
-2), GL_TRUE
);
382 EDGEFLAG_SET( ELT(j
-1), GL_TRUE
);
383 EDGEFLAG_SET( ELT(j
), GL_TRUE
);
384 RENDER_QUAD( ELT(j
-1), ELT(j
-3), ELT(j
-2), ELT(j
) );
385 EDGEFLAG_SET( ELT(j
-3), ef3
);
386 EDGEFLAG_SET( ELT(j
-2), ef2
);
387 EDGEFLAG_SET( ELT(j
-1), ef1
);
388 EDGEFLAG_SET( ELT(j
), ef
);
391 for (j
=start
+3;j
<count
;j
+=2) {
392 RENDER_QUAD( ELT(j
-1), ELT(j
-3), ELT(j
-2), ELT(j
) );
398 static void TAG(render_noop
)( GLcontext
*ctx
,
403 (void)(ctx
&& start
&& count
&& flags
);
406 RENDER_TAB_QUALIFIER
void (*TAG(render_tab
)[GL_POLYGON
+2])(GLcontext
*,
413 TAG(render_line_loop
),
414 TAG(render_line_strip
),
415 TAG(render_triangles
),
416 TAG(render_tri_strip
),
419 TAG(render_quad_strip
),
426 #ifndef PRESERVE_VB_DEFS
437 #undef RENDER_TAB_QUALIFIER
444 #undef PRESERVE_VB_DEFS