Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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