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