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