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