updated email addresses
[mesa.git] / src / mesa / tnl / t_vb_rendertmp.h
1 /* $Id: t_vb_rendertmp.h,v 1.10 2002/10/29 20:29:04 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 *
26 * Authors:
27 * Keith Whitwell <keith@tungstengraphics.com>
28 */
29
30
31 #ifndef POSTFIX
32 #define POSTFIX
33 #endif
34
35 #ifndef INIT
36 #define INIT(x)
37 #endif
38
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
43 #endif
44
45 #ifndef RESET_STIPPLE
46 #define RESET_STIPPLE
47 #endif
48
49 #ifndef RESET_OCCLUSION
50 #define RESET_OCCLUSION
51 #endif
52
53 #ifndef TEST_PRIM_END
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)
57 #endif
58
59 #ifndef ELT
60 #define ELT(x) x
61 #endif
62
63 #ifndef RENDER_TAB_QUALIFIER
64 #define RENDER_TAB_QUALIFIER static
65 #endif
66
67 static void TAG(render_points)( GLcontext *ctx,
68 GLuint start,
69 GLuint count,
70 GLuint flags )
71 {
72 LOCAL_VARS;
73 (void) flags;
74
75 RESET_OCCLUSION;
76 INIT(GL_POINTS);
77 RENDER_POINTS( start, count );
78 POSTFIX;
79 }
80
81 static void TAG(render_lines)( GLcontext *ctx,
82 GLuint start,
83 GLuint count,
84 GLuint flags )
85 {
86 GLuint j;
87 LOCAL_VARS;
88 (void) flags;
89
90 RESET_OCCLUSION;
91 INIT(GL_LINES);
92 for (j=start+1; j<count; j+=2 ) {
93 RESET_STIPPLE;
94 RENDER_LINE( ELT(j-1), ELT(j) );
95 }
96 POSTFIX;
97 }
98
99
100 static void TAG(render_line_strip)( GLcontext *ctx,
101 GLuint start,
102 GLuint count,
103 GLuint flags )
104 {
105 GLuint j;
106 LOCAL_VARS;
107 (void) flags;
108
109 RESET_OCCLUSION;
110 INIT(GL_LINE_STRIP);
111
112 if (TEST_PRIM_BEGIN(flags)) {
113 RESET_STIPPLE;
114 }
115
116 for (j=start+1; j<count; j++ )
117 RENDER_LINE( ELT(j-1), ELT(j) );
118
119 POSTFIX;
120 }
121
122
123 static void TAG(render_line_loop)( GLcontext *ctx,
124 GLuint start,
125 GLuint count,
126 GLuint flags )
127 {
128 GLuint i;
129 LOCAL_VARS;
130
131 (void) flags;
132
133 RESET_OCCLUSION;
134 INIT(GL_LINE_LOOP);
135
136 if (start+1 < count) {
137 if (TEST_PRIM_BEGIN(flags)) {
138 RESET_STIPPLE;
139 RENDER_LINE( ELT(start), ELT(start+1) );
140 }
141
142 for ( i = start+2 ; i < count ; i++) {
143 RENDER_LINE( ELT(i-1), ELT(i) );
144 }
145
146 if ( TEST_PRIM_END(flags)) {
147 RENDER_LINE( ELT(count-1), ELT(start) );
148 }
149 }
150
151 POSTFIX;
152 }
153
154
155 static void TAG(render_triangles)( GLcontext *ctx,
156 GLuint start,
157 GLuint count,
158 GLuint flags )
159 {
160 GLuint j;
161 LOCAL_VARS;
162 (void) flags;
163
164 INIT(GL_TRIANGLES);
165 if (NEED_EDGEFLAG_SETUP) {
166 for (j=start+2; j<count; j+=3) {
167 /* Leave the edgeflags as supplied by the user.
168 */
169 RESET_STIPPLE;
170 RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
171 }
172 } else {
173 for (j=start+2; j<count; j+=3) {
174 RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
175 }
176 }
177 POSTFIX;
178 }
179
180
181
182 static void TAG(render_tri_strip)( GLcontext *ctx,
183 GLuint start,
184 GLuint count,
185 GLuint flags )
186 {
187 GLuint j;
188 GLuint parity = 0;
189 LOCAL_VARS;
190
191 if (TEST_PRIM_PARITY(flags))
192 parity = 1;
193
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);
199 GLuint ej = ELT(j);
200 GLboolean ef2 = EDGEFLAG_GET( ej2 );
201 GLboolean ef1 = EDGEFLAG_GET( ej1 );
202 GLboolean ef = EDGEFLAG_GET( ej );
203 if (TEST_PRIM_BEGIN(flags)) {
204 RESET_STIPPLE;
205 }
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 );
213 }
214 } else {
215 for (j=start+2; j<count ; j++, parity^=1) {
216 RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
217 }
218 }
219 POSTFIX;
220 }
221
222
223 static void TAG(render_tri_fan)( GLcontext *ctx,
224 GLuint start,
225 GLuint count,
226 GLuint flags )
227 {
228 GLuint j;
229 LOCAL_VARS;
230 (void) flags;
231
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.
236 */
237 GLuint ejs = ELT(start);
238 GLuint ej1 = ELT(j-1);
239 GLuint ej = ELT(j);
240 GLboolean efs = EDGEFLAG_GET( ejs );
241 GLboolean ef1 = EDGEFLAG_GET( ej1 );
242 GLboolean ef = EDGEFLAG_GET( ej );
243 if (TEST_PRIM_BEGIN(flags)) {
244 RESET_STIPPLE;
245 }
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 );
253 }
254 } else {
255 for (j=start+2;j<count;j++) {
256 RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
257 }
258 }
259
260 POSTFIX;
261 }
262
263
264 static void TAG(render_poly)( GLcontext *ctx,
265 GLuint start,
266 GLuint count,
267 GLuint flags )
268 {
269 GLuint j = start+2;
270 LOCAL_VARS;
271 (void) flags;
272
273 INIT(GL_POLYGON);
274 if (NEED_EDGEFLAG_SETUP) {
275 GLboolean efstart = EDGEFLAG_GET( ELT(start) );
276 GLboolean efcount = EDGEFLAG_GET( ELT(count-1) );
277
278 /* If the primitive does not begin here, the first edge
279 * is non-boundary.
280 */
281 if (!TEST_PRIM_BEGIN(flags))
282 EDGEFLAG_SET( ELT(start), GL_FALSE );
283 else {
284 RESET_STIPPLE;
285 }
286
287 /* If the primitive does not end here, the final edge is
288 * non-boundary.
289 */
290 if (!TEST_PRIM_END(flags))
291 EDGEFLAG_SET( ELT(count-1), GL_FALSE );
292
293 /* Draw the first triangles (possibly zero)
294 */
295 if (j+1<count) {
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 );
300 j++;
301
302 /* Don't render the first edge again:
303 */
304 EDGEFLAG_SET( ELT(start), GL_FALSE );
305
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 );
311 }
312 }
313
314 /* Draw the last or only triangle
315 */
316 if (j < count)
317 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
318
319 /* Restore the first and last edgeflags:
320 */
321 EDGEFLAG_SET( ELT(count-1), efcount );
322 EDGEFLAG_SET( ELT(start), efstart );
323
324 }
325 else {
326 for (j=start+2;j<count;j++) {
327 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
328 }
329 }
330 POSTFIX;
331 }
332
333 static void TAG(render_quads)( GLcontext *ctx,
334 GLuint start,
335 GLuint count,
336 GLuint flags )
337 {
338 GLuint j;
339 LOCAL_VARS;
340 (void) flags;
341
342 INIT(GL_QUADS);
343 if (NEED_EDGEFLAG_SETUP) {
344 for (j=start+3; j<count; j+=4) {
345 /* Use user-specified edgeflags for quads.
346 */
347 RESET_STIPPLE;
348 RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
349 }
350 } else {
351 for (j=start+3; j<count; j+=4) {
352 RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
353 }
354 }
355 POSTFIX;
356 }
357
358 static void TAG(render_quad_strip)( GLcontext *ctx,
359 GLuint start,
360 GLuint count,
361 GLuint flags )
362 {
363 GLuint j;
364 LOCAL_VARS;
365 (void) flags;
366
367 INIT(GL_QUAD_STRIP);
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.
372 */
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)) {
378 RESET_STIPPLE;
379 }
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 );
389 }
390 } else {
391 for (j=start+3;j<count;j+=2) {
392 RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
393 }
394 }
395 POSTFIX;
396 }
397
398 static void TAG(render_noop)( GLcontext *ctx,
399 GLuint start,
400 GLuint count,
401 GLuint flags )
402 {
403 (void)(ctx && start && count && flags);
404 }
405
406 RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
407 GLuint,
408 GLuint,
409 GLuint) =
410 {
411 TAG(render_points),
412 TAG(render_lines),
413 TAG(render_line_loop),
414 TAG(render_line_strip),
415 TAG(render_triangles),
416 TAG(render_tri_strip),
417 TAG(render_tri_fan),
418 TAG(render_quads),
419 TAG(render_quad_strip),
420 TAG(render_poly),
421 TAG(render_noop),
422 };
423
424
425
426 #ifndef PRESERVE_VB_DEFS
427 #undef RENDER_TRI
428 #undef RENDER_QUAD
429 #undef RENDER_LINE
430 #undef RENDER_POINTS
431 #undef LOCAL_VARS
432 #undef INIT
433 #undef POSTFIX
434 #undef RESET_STIPPLE
435 #undef DBG
436 #undef ELT
437 #undef RENDER_TAB_QUALIFIER
438 #endif
439
440 #ifndef PRESERVE_TAG
441 #undef TAG
442 #endif
443
444 #undef PRESERVE_VB_DEFS
445 #undef PRESERVE_TAG