Subversion Repositories shark

Rev

Rev 56 | Details | Compare with Previous | Last modification | View Log | RSS feed

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