Fixed conform feedback and drawelements tests.
[mesa.git] / src / mesa / tnl / t_vb_rendertmp.h
1 /* $Id: t_vb_rendertmp.h,v 1.6 2001/01/14 06:14:21 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999 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 * Author:
27 * Keith Whitwell <keithw@valinux.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 RENDER_LINE( ELT(j-1), ELT(j) );
94 RESET_STIPPLE;
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 for (j=start+1; j<count; j++ )
113 RENDER_LINE( ELT(j-1), ELT(j) );
114
115 if (TEST_PRIM_END(flags))
116 RESET_STIPPLE;
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 RENDER_LINE( ELT(start), ELT(start+1) );
138 }
139
140 for ( i = start+2 ; i < count ; i++) {
141 RENDER_LINE( ELT(i-1), ELT(i) );
142 }
143
144 if ( TEST_PRIM_END(flags)) {
145 RENDER_LINE( ELT(count-1), ELT(start) );
146 RESET_STIPPLE;
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 RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) );
169 RESET_STIPPLE;
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 EDGEFLAG_SET( ej2, GL_TRUE );
203 EDGEFLAG_SET( ej1, GL_TRUE );
204 EDGEFLAG_SET( ej, GL_TRUE );
205 RENDER_TRI( ej2, ej1, ej );
206 EDGEFLAG_SET( ej2, ef2 );
207 EDGEFLAG_SET( ej1, ef1 );
208 EDGEFLAG_SET( ej, ef );
209 RESET_STIPPLE;
210 }
211 } else {
212 for (j=start+2; j<count ; j++, parity^=1) {
213 RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) );
214 }
215 }
216 POSTFIX;
217 }
218
219
220 static void TAG(render_tri_fan)( GLcontext *ctx,
221 GLuint start,
222 GLuint count,
223 GLuint flags )
224 {
225 GLuint j;
226 LOCAL_VARS;
227 (void) flags;
228
229 INIT(GL_TRIANGLE_FAN);
230 if (NEED_EDGEFLAG_SETUP) {
231 for (j=start+2;j<count;j++) {
232 /* For trifans, all edges are boundary.
233 */
234 GLuint ejs = ELT(start);
235 GLuint ej1 = ELT(j-1);
236 GLuint ej = ELT(j);
237 GLboolean efs = EDGEFLAG_GET( ejs );
238 GLboolean ef1 = EDGEFLAG_GET( ej1 );
239 GLboolean ef = EDGEFLAG_GET( ej );
240 EDGEFLAG_SET( ejs, GL_TRUE );
241 EDGEFLAG_SET( ej1, GL_TRUE );
242 EDGEFLAG_SET( ej, GL_TRUE );
243 RENDER_TRI( ejs, ej1, ej);
244 EDGEFLAG_SET( ejs, efs );
245 EDGEFLAG_SET( ej1, ef1 );
246 EDGEFLAG_SET( ej, ef );
247 RESET_STIPPLE;
248 }
249 } else {
250 for (j=start+2;j<count;j++) {
251 RENDER_TRI( ELT(start), ELT(j-1), ELT(j) );
252 }
253 }
254
255 POSTFIX;
256 }
257
258
259 static void TAG(render_poly)( GLcontext *ctx,
260 GLuint start,
261 GLuint count,
262 GLuint flags )
263 {
264 GLuint j = start+2;
265 LOCAL_VARS;
266 (void) flags;
267
268 INIT(GL_POLYGON);
269 if (NEED_EDGEFLAG_SETUP) {
270 GLboolean efstart = EDGEFLAG_GET( ELT(start) );
271 GLboolean efcount = EDGEFLAG_GET( ELT(count-1) );
272
273 /* If the primitive does not begin here, the first edge
274 * is non-boundary.
275 */
276 if (!TEST_PRIM_BEGIN(flags))
277 EDGEFLAG_SET( ELT(start), GL_FALSE );
278
279 /* If the primitive does not end here, the final edge is
280 * non-boundary.
281 */
282 if (!TEST_PRIM_END(flags))
283 EDGEFLAG_SET( ELT(count-1), GL_FALSE );
284
285 /* Draw the first triangles (possibly zero)
286 */
287 if (j<count-1) {
288 GLboolean ef = EDGEFLAG_GET( ELT(j) );
289 EDGEFLAG_SET( ELT(j), GL_FALSE );
290 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
291 EDGEFLAG_SET( ELT(j), ef );
292 j++;
293
294 /* Don't render the first edge again:
295 */
296 EDGEFLAG_SET( ELT(start), GL_FALSE );
297
298 for (;j<count-1;j++) {
299 GLboolean efj = EDGEFLAG_GET( ELT(j) );
300 EDGEFLAG_SET( ELT(j), GL_FALSE );
301 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
302 EDGEFLAG_SET( ELT(j), efj );
303 }
304 }
305
306 /* Draw the last or only triangle
307 */
308 if (j < count)
309 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
310
311 /* Restore the first and last edgeflags:
312 */
313 EDGEFLAG_SET( ELT(count-1), efcount );
314 EDGEFLAG_SET( ELT(start), efstart );
315
316 if (TEST_PRIM_END(flags)) {
317 RESET_STIPPLE;
318 }
319 }
320 else {
321 for (j=start+2;j<count;j++) {
322 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) );
323 }
324 }
325 POSTFIX;
326 }
327
328 static void TAG(render_quads)( GLcontext *ctx,
329 GLuint start,
330 GLuint count,
331 GLuint flags )
332 {
333 GLuint j;
334 LOCAL_VARS;
335 (void) flags;
336
337 INIT(GL_QUADS);
338 if (NEED_EDGEFLAG_SETUP) {
339 for (j=start+3; j<count; j+=4) {
340 /* Use user-specified edgeflags for quads.
341 */
342 RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
343 RESET_STIPPLE;
344 }
345 } else {
346 for (j=start+3; j<count; j+=4) {
347 RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) );
348 }
349 }
350 POSTFIX;
351 }
352
353 static void TAG(render_quad_strip)( GLcontext *ctx,
354 GLuint start,
355 GLuint count,
356 GLuint flags )
357 {
358 GLuint j;
359 LOCAL_VARS;
360 (void) flags;
361
362 INIT(GL_QUAD_STRIP);
363 if (NEED_EDGEFLAG_SETUP) {
364 for (j=start+3;j<count;j+=2) {
365 /* All edges are boundary. Set edgeflags to 1, draw the
366 * quad, and restore them to the original values.
367 */
368 GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) );
369 GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) );
370 GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) );
371 GLboolean ef = EDGEFLAG_GET( ELT(j) );
372 EDGEFLAG_SET( ELT(j-3), GL_TRUE );
373 EDGEFLAG_SET( ELT(j-2), GL_TRUE );
374 EDGEFLAG_SET( ELT(j-1), GL_TRUE );
375 EDGEFLAG_SET( ELT(j), GL_TRUE );
376 RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
377 EDGEFLAG_SET( ELT(j-3), ef3 );
378 EDGEFLAG_SET( ELT(j-2), ef2 );
379 EDGEFLAG_SET( ELT(j-1), ef1 );
380 EDGEFLAG_SET( ELT(j), ef );
381 RESET_STIPPLE;
382 }
383 } else {
384 for (j=start+3;j<count;j+=2) {
385 RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) );
386 }
387 }
388 POSTFIX;
389 }
390
391 static void TAG(render_noop)( GLcontext *ctx,
392 GLuint start,
393 GLuint count,
394 GLuint flags )
395 {
396 (void)(ctx && start && count && flags);
397 }
398
399 RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *,
400 GLuint,
401 GLuint,
402 GLuint) =
403 {
404 TAG(render_points),
405 TAG(render_lines),
406 TAG(render_line_loop),
407 TAG(render_line_strip),
408 TAG(render_triangles),
409 TAG(render_tri_strip),
410 TAG(render_tri_fan),
411 TAG(render_quads),
412 TAG(render_quad_strip),
413 TAG(render_poly),
414 TAG(render_noop),
415 };
416
417
418
419 #ifndef PRESERVE_VB_DEFS
420 #undef RENDER_TRI
421 #undef RENDER_QUAD
422 #undef RENDER_LINE
423 #undef RENDER_POINTS
424 #undef LOCAL_VARS
425 #undef INIT
426 #undef POSTFIX
427 #undef RESET_STIPPLE
428 #undef DBG
429 #undef ELT
430 #undef RENDER_TAB_QUALIFIER
431 #endif
432
433 #ifndef PRESERVE_TAG
434 #undef TAG
435 #endif
436
437 #undef PRESERVE_VB_DEFS
438 #undef PRESERVE_TAG
439