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