patch to import Jon Smirl's work from Bitkeeper
[mesa.git] / src / mesa / tnl_dd / t_dd_rendertmp.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 #ifndef POSTFIX
31 #define POSTFIX
32 #endif
33
34 #ifndef INIT
35 #define INIT(x)
36 #endif
37
38 #ifndef NEED_EDGEFLAG_SETUP
39 #define NEED_EDGEFLAG_SETUP 0
40 #define EDGEFLAG_GET(a) 0
41 #define EDGEFLAG_SET(a,b) (void)b
42 #endif
43
44 #ifndef RESET_STIPPLE
45 #define RESET_STIPPLE
46 #endif
47
48 #ifndef RESET_OCCLUSION
49 #define RESET_OCCLUSION
50 #endif
51
52 #ifndef TEST_PRIM_END
53 #define TEST_PRIM_END(flags) (flags & PRIM_END)
54 #define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
55 #define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
56 #endif
57
58 #ifndef ELT
59 #define ELT(x) x
60 #endif
61
62 #ifndef RENDER_TAB_QUALIFIER
63 #define RENDER_TAB_QUALIFIER static
64 #endif
65
66 static void TAG(render_points)( GLcontext *ctx,
67 GLuint start,
68 GLuint count,
69 GLuint flags )
70 {
71 LOCAL_VARS;
72 (void) flags;
73
74 RESET_OCCLUSION;
75 INIT(GL_POINTS);
76 RENDER_POINTS( start, count );
77 POSTFIX;
78 }
79
80 static void TAG(render_lines)( GLcontext *ctx,
81 GLuint start,
82 GLuint count,
83 GLuint flags )
84 {
85 GLuint j;
86 LOCAL_VARS;
87 (void) flags;
88
89 RESET_OCCLUSION;
90 INIT(GL_LINES);
91 for (j=start+1; j<count; j+=2 ) {
92 RENDER_LINE( ELT(j-1), ELT(j) );
93 RESET_STIPPLE;
94 }
95 POSTFIX;
96 }
97
98
99 static void TAG(render_line_strip)( GLcontext *ctx,
100 GLuint start,
101 GLuint count,
102 GLuint flags )
103 {
104 GLuint j;
105 LOCAL_VARS;
106 (void) flags;
107
108 RESET_OCCLUSION;
109 INIT(GL_LINE_STRIP);
110
111 for (j=start+1; j<count; j++ )
112 RENDER_LINE( ELT(j-1), ELT(j) );
113
114 if (TEST_PRIM_END(flags))
115 RESET_STIPPLE;
116
117 POSTFIX;
118 }
119
120
121 static void TAG(render_line_loop)( GLcontext *ctx,
122 GLuint start,
123 GLuint count,
124 GLuint flags )
125 {
126 GLuint i;
127 LOCAL_VARS;
128
129 (void) flags;
130
131 RESET_OCCLUSION;
132 INIT(GL_LINE_LOOP);
133
134 if (start+1 < count) {
135 if (TEST_PRIM_BEGIN(flags)) {
136 RENDER_LINE( ELT(start), ELT(start+1) );
137 }
138
139 for ( i = start+2 ; i < count ; i++) {
140 RENDER_LINE( ELT(i-1), ELT(i) );
141 }
142
143 if ( TEST_PRIM_END(flags)) {
144 RENDER_LINE( ELT(count-1), ELT(start) );
145 RESET_STIPPLE;
146 }
147 }
148
149 POSTFIX;
150 }
151
152
153 static void TAG(render_triangles)( GLcontext *ctx,
154 GLuint start,
155 GLuint count,
156 GLuint flags )
157 {
158 GLuint j;
159 LOCAL_VARS;
160 (void) flags;
161
162 INIT(GL_TRIANGLES);
163 if (NEED_EDGEFLAG_SETUP) {
164 for (j=start+2; j<count; j+=3) {
165 /* Leave the edgeflags as supplied by the user.
166 */
167 RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
168 RESET_STIPPLE;
169 }
170 } else {
171 for (j=start+2; j<count; j+=3) {
172 RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
173 }
174 }
175 POSTFIX;
176 }
177
178
179
180 static void TAG(render_tri_strip)( GLcontext *ctx,
181 GLuint start,
182 GLuint count,
183 GLuint flags )
184 {
185 GLuint j;
186 GLuint parity = 0;
187 LOCAL_VARS;
188
189 if (TEST_PRIM_PARITY(flags))
190 parity = 1;
191
192 INIT(GL_TRIANGLE_STRIP);
193 if (NEED_EDGEFLAG_SETUP) {
194 for (j=start+2;j<count;j++,parity^=1) {
195 GLuint ej2 = ELT(j-2+parity);
196 GLuint ej1 = ELT(j-1-parity);
197 GLuint ej = ELT(j);
198 GLboolean ef2 = EDGEFLAG_GET( ej2 );
199 GLboolean ef1 = EDGEFLAG_GET( ej1 );
200 GLboolean ef = EDGEFLAG_GET( ej );
201 EDGEFLAG_SET( ej2, GL_TRUE );
202 EDGEFLAG_SET( ej1, GL_TRUE );
203 EDGEFLAG_SET( ej, GL_TRUE );
204 RENDER_TRI( ej2, ej1, ej );
205 EDGEFLAG_SET( ej2, ef2 );
206 EDGEFLAG_SET( ej1, ef1 );
207 EDGEFLAG_SET( ej, ef );
208 RESET_STIPPLE;
209 }
210 } else {
211 for (j=start+2; j<count ; j++, parity^=1) {
212 RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
213 }
214 }
215 POSTFIX;
216 }
217
218
219 static void TAG(render_tri_fan)( GLcontext *ctx,
220 GLuint start,
221 GLuint count,
222 GLuint flags )
223 {
224 GLuint j;
225 LOCAL_VARS;
226 (void) flags;
227
228 INIT(GL_TRIANGLE_FAN);
229 if (NEED_EDGEFLAG_SETUP) {
230 for (j=start+2;j<count;j++) {
231 /* For trifans, all edges are boundary.
232 */
233 GLuint ejs = ELT(start);
234 GLuint ej1 = ELT(j-1);
235 GLuint ej = ELT(j);
236 GLboolean efs = EDGEFLAG_GET( ejs );
237 GLboolean ef1 = EDGEFLAG_GET( ej1 );
238 GLboolean ef = EDGEFLAG_GET( ej );
239 EDGEFLAG_SET( ejs, GL_TRUE );
240 EDGEFLAG_SET( ej1, GL_TRUE );
241 EDGEFLAG_SET( ej, GL_TRUE );
242 RENDER_TRI( ejs, ej1, ej);
243 EDGEFLAG_SET( ejs, efs );
244 EDGEFLAG_SET( ej1, ef1 );
245 EDGEFLAG_SET( ej, ef );
246 RESET_STIPPLE;
247 }
248 } else {
249 for (j=start+2;j<count;j++) {
250 RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
251 }
252 }
253
254 POSTFIX;
255 }
256
257
258 static void TAG(render_poly)( GLcontext *ctx,
259 GLuint start,
260 GLuint count,
261 GLuint flags )
262 {
263 GLuint j = start+2;
264 LOCAL_VARS;
265 (void) flags;
266
267 INIT(GL_POLYGON);
268 if (NEED_EDGEFLAG_SETUP) {
269 GLboolean efstart = EDGEFLAG_GET( ELT(start) );
270 GLboolean efcount = EDGEFLAG_GET( ELT(count-1) );
271
272 /* If the primitive does not begin here, the first edge
273 * is non-boundary.
274 */
275 if (!TEST_PRIM_BEGIN(flags))
276 EDGEFLAG_SET( ELT(start), GL_FALSE );
277
278 /* If the primitive does not end here, the final edge is
279 * non-boundary.
280 */
281 if (!TEST_PRIM_END(flags))
282 EDGEFLAG_SET( ELT(count-1), GL_FALSE );
283
284 /* Draw the first triangles (possibly zero)
285 */
286 if (j<count-1) {
287 GLboolean ef = EDGEFLAG_GET( ELT(j) );
288 EDGEFLAG_SET( ELT(j), GL_FALSE );
289 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
290 EDGEFLAG_SET( ELT(j), ef );
291 j++;
292
293 /* Don't render the first edge again:
294 */
295 EDGEFLAG_SET( ELT(start), GL_FALSE );
296
297 for (;j<count-1;j++) {
298 GLboolean efj = EDGEFLAG_GET( ELT(j) );
299 EDGEFLAG_SET( ELT(j), GL_FALSE );
300 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
301 EDGEFLAG_SET( ELT(j), efj );
302 }
303 }
304
305 /* Draw the last or only triangle
306 */
307 if (j < count)
308 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
309
310 /* Restore the first and last edgeflags:
311 */
312 EDGEFLAG_SET( ELT(count-1), efcount );
313 EDGEFLAG_SET( ELT(start), efstart );
314
315 if (TEST_PRIM_END(flags)) {
316 RESET_STIPPLE;
317 }
318 }
319 else {
320 for (j=start+2;j<count;j++) {
321 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
322 }
323 }
324 POSTFIX;
325 }
326
327 static void TAG(render_quads)( GLcontext *ctx,
328 GLuint start,
329 GLuint count,
330 GLuint flags )
331 {
332 GLuint j;
333 LOCAL_VARS;
334 (void) flags;
335
336 INIT(GL_QUADS);
337 if (NEED_EDGEFLAG_SETUP) {
338 for (j=start+3; j<count; j+=4) {
339 /* Use user-specified edgeflags for quads.
340 */
341 RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
342 RESET_STIPPLE;
343 }
344 } else {
345 for (j=start+3; j<count; j+=4) {
346 RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
347 }
348 }
349 POSTFIX;
350 }
351
352 static void TAG(render_quad_strip)( GLcontext *ctx,
353 GLuint start,
354 GLuint count,
355 GLuint flags )
356 {
357 GLuint j;
358 LOCAL_VARS;
359 (void) flags;
360
361 INIT(GL_QUAD_STRIP);
362 if (NEED_EDGEFLAG_SETUP) {
363 for (j=start+3;j<count;j+=2) {
364 /* All edges are boundary. Set edgeflags to 1, draw the
365 * quad, and restore them to the original values.
366 */
367 GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) );
368 GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) );
369 GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) );
370 GLboolean ef = EDGEFLAG_GET( ELT(j) );
371 EDGEFLAG_SET( ELT(j-3), GL_TRUE );
372 EDGEFLAG_SET( ELT(j-2), GL_TRUE );
373 EDGEFLAG_SET( ELT(j-1), GL_TRUE );
374 EDGEFLAG_SET( ELT(j), GL_TRUE );
375 RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
376 EDGEFLAG_SET( ELT(j-3), ef3 );
377 EDGEFLAG_SET( ELT(j-2), ef2 );
378 EDGEFLAG_SET( ELT(j-1), ef1 );
379 EDGEFLAG_SET( ELT(j), ef );
380 RESET_STIPPLE;
381 }
382 } else {
383 for (j=start+3;j<count;j+=2) {
384 RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
385 }
386 }
387 POSTFIX;
388 }
389
390 static void TAG(render_noop)( GLcontext *ctx,
391 GLuint start,
392 GLuint count,
393 GLuint flags )
394 {
395 (void)(ctx && start && count && flags);
396 }
397
398 RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
399 GLuint,
400 GLuint,
401 GLuint) =
402 {
403 TAG(render_points),
404 TAG(render_lines),
405 TAG(render_line_loop),
406 TAG(render_line_strip),
407 TAG(render_triangles),
408 TAG(render_tri_strip),
409 TAG(render_tri_fan),
410 TAG(render_quads),
411 TAG(render_quad_strip),
412 TAG(render_poly),
413 TAG(render_noop),
414 };
415
416
417
418 #ifndef PRESERVE_VB_DEFS
419 #undef RENDER_TRI
420 #undef RENDER_QUAD
421 #undef RENDER_LINE
422 #undef RENDER_POINTS
423 #undef LOCAL_VARS
424 #undef INIT
425 #undef POSTFIX
426 #undef RESET_STIPPLE
427 #undef DBG
428 #undef ELT
429 #undef RENDER_TAB_QUALIFIER
430 #endif
431
432 #ifndef PRESERVE_TAG
433 #undef TAG
434 #endif
435
436 #undef PRESERVE_VB_DEFS
437 #undef PRESERVE_TAG