1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keithw@vmware.com>
26 */
27
28
29 /* Template for building functions to plug into the driver interface
30 * of t_vb_render.c:
31 * ctx->Driver.QuadFunc
32 * ctx->Driver.TriangleFunc
33 * ctx->Driver.LineFunc
34 * ctx->Driver.PointsFunc
35 *
36 * DO_TWOSIDE: Plug back-color values from the VB into backfacing triangles,
37 * and restore vertices afterwards.
38 * DO_OFFSET: Calculate offset for triangles and adjust vertices. Restore
39 * vertices after rendering.
40 * DO_FLAT: For hardware without native flatshading, copy provoking colors
41 * into the other vertices. Restore after rendering.
42 * DO_UNFILLED: Decompose triangles to lines and points where appropriate.
43 * DO_TWOSTENCIL:Gross hack for two-sided stencil.
44 *
45 * HAVE_SPEC: Vertices have secondary rgba values.
46 *
47 * VERT_X(v): Alias for vertex x value.
48 * VERT_Y(v): Alias for vertex y value.
49 * VERT_Z(v): Alias for vertex z value.
50 * DEPTH_SCALE: Scale for constant offset.
51 * REVERSE_DEPTH: Viewport depth range reversed.
52 *
53 * VERTEX: Hardware vertex type.
54 * GET_VERTEX(n): Retreive vertex with index n.
55 * AREA_IS_CCW(a): Return true if triangle with signed area a is ccw.
56 *
57 * VERT_SET_RGBA: Assign vertex rgba from VB color.
58 * VERT_COPY_RGBA: Copy vertex rgba another vertex.
59 * VERT_SAVE_RGBA: Save vertex rgba to a local variable.
60 * VERT_RESTORE_RGBA: Restore vertex rgba from a local variable.
61 * --> Similar for SPEC.
62 *
63 * LOCAL_VARS(n): (At least) define local vars for save/restore rgba.
64 *
65 */
66
67 #if HAVE_BACK_COLORS
68 #define VERT_SET_RGBA( v, c )
69 #endif
70
71 #if !HAVE_SPEC
72 #define VERT_SET_SPEC( v, c ) (void) c
73 #define VERT_COPY_SPEC( v0, v1 )
74 #define VERT_SAVE_SPEC( idx )
75 #define VERT_RESTORE_SPEC( idx )
76 #if HAVE_BACK_COLORS
77 #define VERT_COPY_SPEC1( v )
78 #endif
79 #else
80 #if HAVE_BACK_COLORS
81 #define VERT_SET_SPEC( v, c )
82 #endif
83 #endif
84
85 #if !HAVE_BACK_COLORS
86 #define VERT_COPY_SPEC1( v )
87 #define VERT_COPY_RGBA1( v )
88 #endif
89
90 #ifndef INSANE_VERTICES
91 #define VERT_SET_Z(v,val) VERT_Z(v) = val
92 #define VERT_Z_ADD(v,val) VERT_Z(v) += val
93 #endif
94
95 #ifndef REVERSE_DEPTH
96 #define REVERSE_DEPTH 0
97 #endif
98
99 /* disable twostencil for un-aware drivers */
100 #ifndef HAVE_STENCIL_TWOSIDE
101 #define HAVE_STENCIL_TWOSIDE 0
102 #endif
103 #ifndef DO_TWOSTENCIL
104 #define DO_TWOSTENCIL 0
105 #endif
106 #ifndef SETUP_STENCIL
107 #define SETUP_STENCIL(f)
108 #endif
109 #ifndef UNSET_STENCIL
110 #define UNSET_STENCIL(f)
111 #endif
112
113 #if DO_TRI
TAG(triangle)114 static void TAG(triangle)( struct gl_context *ctx, GLuint e0, GLuint e1, GLuint e2 )
115 {
116 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
117 VERTEX *v[3];
118 GLfloat offset = 0;
119 GLfloat z[3] = { 0 };
120 GLenum mode = GL_FILL;
121 GLuint facing = 0;
122 LOCAL_VARS(3);
123
124 /* fprintf(stderr, "%s\n", __func__); */
125
126 v[0] = (VERTEX *)GET_VERTEX(e0);
127 v[1] = (VERTEX *)GET_VERTEX(e1);
128 v[2] = (VERTEX *)GET_VERTEX(e2);
129
130 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
131 {
132 GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
133 GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
134 GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
135 GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
136 GLfloat cc = ex*fy - ey*fx;
137
138 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
139 {
140 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
141
142 if (DO_UNFILLED) {
143 if (facing) {
144 mode = ctx->Polygon.BackMode;
145 if (ctx->Polygon.CullFlag &&
146 ctx->Polygon.CullFaceMode != GL_FRONT) {
147 return;
148 }
149 } else {
150 mode = ctx->Polygon.FrontMode;
151 if (ctx->Polygon.CullFlag &&
152 ctx->Polygon.CullFaceMode != GL_BACK) {
153 return;
154 }
155 }
156 }
157
158 if (DO_TWOSIDE && facing == 1) {
159 if (HAVE_BACK_COLORS) {
160 if (!DO_FLAT) {
161 VERT_SAVE_RGBA( 0 );
162 VERT_SAVE_RGBA( 1 );
163 VERT_COPY_RGBA1( v[0] );
164 VERT_COPY_RGBA1( v[1] );
165 }
166 VERT_SAVE_RGBA( 2 );
167 VERT_COPY_RGBA1( v[2] );
168 if (HAVE_SPEC) {
169 if (!DO_FLAT) {
170 VERT_SAVE_SPEC( 0 );
171 VERT_SAVE_SPEC( 1 );
172 VERT_COPY_SPEC1( v[0] );
173 VERT_COPY_SPEC1( v[1] );
174 }
175 VERT_SAVE_SPEC( 2 );
176 VERT_COPY_SPEC1( v[2] );
177 }
178 }
179 else {
180 GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
181 (void) vbcolor;
182
183 if (!DO_FLAT) {
184 VERT_SAVE_RGBA( 0 );
185 VERT_SAVE_RGBA( 1 );
186 }
187 VERT_SAVE_RGBA( 2 );
188
189 if (VB->BackfaceColorPtr->stride) {
190 assert(VB->BackfaceColorPtr->stride == 4*sizeof(GLfloat));
191
192 if (!DO_FLAT) {
193 VERT_SET_RGBA( v[0], vbcolor[e0] );
194 VERT_SET_RGBA( v[1], vbcolor[e1] );
195 }
196 VERT_SET_RGBA( v[2], vbcolor[e2] );
197 }
198 else {
199 if (!DO_FLAT) {
200 VERT_SET_RGBA( v[0], vbcolor[0] );
201 VERT_SET_RGBA( v[1], vbcolor[0] );
202 }
203 VERT_SET_RGBA( v[2], vbcolor[0] );
204 }
205
206 if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) {
207 GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
208 assert(VB->BackfaceSecondaryColorPtr->stride == 4*sizeof(GLfloat));
209
210 if (!DO_FLAT) {
211 VERT_SAVE_SPEC( 0 );
212 VERT_SAVE_SPEC( 1 );
213 VERT_SET_SPEC( v[0], vbspec[e0] );
214 VERT_SET_SPEC( v[1], vbspec[e1] );
215 }
216 VERT_SAVE_SPEC( 2 );
217 VERT_SET_SPEC( v[2], vbspec[e2] );
218 }
219 }
220 }
221 }
222
223
224 if (DO_OFFSET)
225 {
226 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
227 z[0] = VERT_Z(v[0]);
228 z[1] = VERT_Z(v[1]);
229 z[2] = VERT_Z(v[2]);
230 if (cc * cc > 1e-16) {
231 GLfloat ic = 1.0 / cc;
232 GLfloat ez = z[0] - z[2];
233 GLfloat fz = z[1] - z[2];
234 GLfloat a = ey*fz - ez*fy;
235 GLfloat b = ez*fx - ex*fz;
236 GLfloat ac = a * ic;
237 GLfloat bc = b * ic;
238 if ( ac < 0.0f ) ac = -ac;
239 if ( bc < 0.0f ) bc = -bc;
240 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD;
241 }
242 offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0);
243 }
244 }
245
246 if (DO_FLAT) {
247 VERT_SAVE_RGBA( 0 );
248 VERT_SAVE_RGBA( 1 );
249 VERT_COPY_RGBA( v[0], v[2] );
250 VERT_COPY_RGBA( v[1], v[2] );
251 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
252 VERT_SAVE_SPEC( 0 );
253 VERT_SAVE_SPEC( 1 );
254 VERT_COPY_SPEC( v[0], v[2] );
255 VERT_COPY_SPEC( v[1], v[2] );
256 }
257 }
258
259 if (mode == GL_POINT) {
260 if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
261 VERT_Z_ADD(v[0], offset);
262 VERT_Z_ADD(v[1], offset);
263 VERT_Z_ADD(v[2], offset);
264 }
265 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
266 SETUP_STENCIL(facing);
267 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
268 UNSET_STENCIL(facing);
269 } else {
270 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
271 }
272 } else if (mode == GL_LINE) {
273 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
274 VERT_Z_ADD(v[0], offset);
275 VERT_Z_ADD(v[1], offset);
276 VERT_Z_ADD(v[2], offset);
277 }
278 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
279 SETUP_STENCIL(facing);
280 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
281 UNSET_STENCIL(facing);
282 } else {
283 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
284 }
285 } else {
286 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
287 VERT_Z_ADD(v[0], offset);
288 VERT_Z_ADD(v[1], offset);
289 VERT_Z_ADD(v[2], offset);
290 }
291 if (DO_UNFILLED) {
292 RASTERIZE( GL_TRIANGLES );
293 }
294 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
295 SETUP_STENCIL(facing);
296 TRI( v[0], v[1], v[2] );
297 UNSET_STENCIL(facing);
298 } else {
299 TRI( v[0], v[1], v[2] );
300 }
301 }
302
303 if (DO_OFFSET)
304 {
305 VERT_SET_Z(v[0], z[0]);
306 VERT_SET_Z(v[1], z[1]);
307 VERT_SET_Z(v[2], z[2]);
308 }
309
310 if (DO_TWOSIDE && facing == 1) {
311 if (!DO_FLAT) {
312 VERT_RESTORE_RGBA( 0 );
313 VERT_RESTORE_RGBA( 1 );
314 }
315 VERT_RESTORE_RGBA( 2 );
316 if (HAVE_SPEC) {
317 if (!DO_FLAT) {
318 VERT_RESTORE_SPEC( 0 );
319 VERT_RESTORE_SPEC( 1 );
320 }
321 VERT_RESTORE_SPEC( 2 );
322 }
323 }
324
325
326 if (DO_FLAT) {
327 VERT_RESTORE_RGBA( 0 );
328 VERT_RESTORE_RGBA( 1 );
329 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
330 VERT_RESTORE_SPEC( 0 );
331 VERT_RESTORE_SPEC( 1 );
332 }
333 }
334 }
335 #endif
336
337 #if DO_QUAD
338 #if DO_FULL_QUAD
TAG(quadr)339 static void TAG(quadr)( struct gl_context *ctx,
340 GLuint e0, GLuint e1, GLuint e2, GLuint e3 )
341 {
342 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
343 VERTEX *v[4];
344 GLfloat offset = 0;
345 GLfloat z[4] = { 0 };
346 GLenum mode = GL_FILL;
347 GLuint facing = 0;
348 LOCAL_VARS(4);
349
350 v[0] = (VERTEX *)GET_VERTEX(e0);
351 v[1] = (VERTEX *)GET_VERTEX(e1);
352 v[2] = (VERTEX *)GET_VERTEX(e2);
353 v[3] = (VERTEX *)GET_VERTEX(e3);
354
355 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
356 {
357 GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
358 GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
359 GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
360 GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
361 GLfloat cc = ex*fy - ey*fx;
362
363 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
364 {
365 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
366
367 if (DO_UNFILLED) {
368 if (facing) {
369 mode = ctx->Polygon.BackMode;
370 if (ctx->Polygon.CullFlag &&
371 ctx->Polygon.CullFaceMode != GL_FRONT) {
372 return;
373 }
374 } else {
375 mode = ctx->Polygon.FrontMode;
376 if (ctx->Polygon.CullFlag &&
377 ctx->Polygon.CullFaceMode != GL_BACK) {
378 return;
379 }
380 }
381 }
382
383 if (DO_TWOSIDE && facing == 1) {
384 GLfloat (*vbcolor)[4] = VB->BackfaceColorPtr->data;
385 (void)vbcolor;
386
387 if (HAVE_BACK_COLORS) {
388 if (!DO_FLAT) {
389 VERT_SAVE_RGBA( 0 );
390 VERT_SAVE_RGBA( 1 );
391 VERT_SAVE_RGBA( 2 );
392 VERT_COPY_RGBA1( v[0] );
393 VERT_COPY_RGBA1( v[1] );
394 VERT_COPY_RGBA1( v[2] );
395 }
396 VERT_SAVE_RGBA( 3 );
397 VERT_COPY_RGBA1( v[3] );
398 if (HAVE_SPEC) {
399 if (!DO_FLAT) {
400 VERT_SAVE_SPEC( 0 );
401 VERT_SAVE_SPEC( 1 );
402 VERT_SAVE_SPEC( 2 );
403 VERT_COPY_SPEC1( v[0] );
404 VERT_COPY_SPEC1( v[1] );
405 VERT_COPY_SPEC1( v[2] );
406 }
407 VERT_SAVE_SPEC( 3 );
408 VERT_COPY_SPEC1( v[3] );
409 }
410 }
411 else {
412 if (!DO_FLAT) {
413 VERT_SAVE_RGBA( 0 );
414 VERT_SAVE_RGBA( 1 );
415 VERT_SAVE_RGBA( 2 );
416 }
417 VERT_SAVE_RGBA( 3 );
418
419 if (VB->BackfaceColorPtr->stride) {
420 if (!DO_FLAT) {
421 VERT_SET_RGBA( v[0], vbcolor[e0] );
422 VERT_SET_RGBA( v[1], vbcolor[e1] );
423 VERT_SET_RGBA( v[2], vbcolor[e2] );
424 }
425 VERT_SET_RGBA( v[3], vbcolor[e3] );
426 }
427 else {
428 if (!DO_FLAT) {
429 VERT_SET_RGBA( v[0], vbcolor[0] );
430 VERT_SET_RGBA( v[1], vbcolor[0] );
431 VERT_SET_RGBA( v[2], vbcolor[0] );
432 }
433 VERT_SET_RGBA( v[3], vbcolor[0] );
434 }
435
436 if (HAVE_SPEC && VB->BackfaceSecondaryColorPtr) {
437 GLfloat (*vbspec)[4] = VB->BackfaceSecondaryColorPtr->data;
438 assert(VB->BackfaceSecondaryColorPtr->stride==4*sizeof(GLfloat));
439
440 if (!DO_FLAT) {
441 VERT_SAVE_SPEC( 0 );
442 VERT_SAVE_SPEC( 1 );
443 VERT_SAVE_SPEC( 2 );
444 VERT_SET_SPEC( v[0], vbspec[e0] );
445 VERT_SET_SPEC( v[1], vbspec[e1] );
446 VERT_SET_SPEC( v[2], vbspec[e2] );
447 }
448 VERT_SAVE_SPEC( 3 );
449 VERT_SET_SPEC( v[3], vbspec[e3] );
450 }
451 }
452 }
453 }
454
455
456 if (DO_OFFSET)
457 {
458 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
459 z[0] = VERT_Z(v[0]);
460 z[1] = VERT_Z(v[1]);
461 z[2] = VERT_Z(v[2]);
462 z[3] = VERT_Z(v[3]);
463 if (cc * cc > 1e-16) {
464 GLfloat ez = z[2] - z[0];
465 GLfloat fz = z[3] - z[1];
466 GLfloat a = ey*fz - ez*fy;
467 GLfloat b = ez*fx - ex*fz;
468 GLfloat ic = 1.0 / cc;
469 GLfloat ac = a * ic;
470 GLfloat bc = b * ic;
471 if ( ac < 0.0f ) ac = -ac;
472 if ( bc < 0.0f ) bc = -bc;
473 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD;
474 }
475 offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0);
476 }
477 }
478
479 if (DO_FLAT) {
480 VERT_SAVE_RGBA( 0 );
481 VERT_SAVE_RGBA( 1 );
482 VERT_SAVE_RGBA( 2 );
483 VERT_COPY_RGBA( v[0], v[3] );
484 VERT_COPY_RGBA( v[1], v[3] );
485 VERT_COPY_RGBA( v[2], v[3] );
486 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
487 VERT_SAVE_SPEC( 0 );
488 VERT_SAVE_SPEC( 1 );
489 VERT_SAVE_SPEC( 2 );
490 VERT_COPY_SPEC( v[0], v[3] );
491 VERT_COPY_SPEC( v[1], v[3] );
492 VERT_COPY_SPEC( v[2], v[3] );
493 }
494 }
495
496 if (mode == GL_POINT) {
497 if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
498 VERT_Z_ADD(v[0], offset);
499 VERT_Z_ADD(v[1], offset);
500 VERT_Z_ADD(v[2], offset);
501 VERT_Z_ADD(v[3], offset);
502 }
503 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
504 SETUP_STENCIL(facing);
505 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
506 UNSET_STENCIL(facing);
507 } else {
508 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
509 }
510 } else if (mode == GL_LINE) {
511 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
512 VERT_Z_ADD(v[0], offset);
513 VERT_Z_ADD(v[1], offset);
514 VERT_Z_ADD(v[2], offset);
515 VERT_Z_ADD(v[3], offset);
516 }
517 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
518 SETUP_STENCIL(facing);
519 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
520 UNSET_STENCIL(facing);
521 } else {
522 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
523 }
524 } else {
525 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
526 VERT_Z_ADD(v[0], offset);
527 VERT_Z_ADD(v[1], offset);
528 VERT_Z_ADD(v[2], offset);
529 VERT_Z_ADD(v[3], offset);
530 }
531 RASTERIZE( GL_QUADS );
532 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
533 SETUP_STENCIL(facing);
534 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
535 UNSET_STENCIL(facing);
536 } else {
537 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
538 }
539 }
540
541 if (DO_OFFSET)
542 {
543 VERT_SET_Z(v[0], z[0]);
544 VERT_SET_Z(v[1], z[1]);
545 VERT_SET_Z(v[2], z[2]);
546 VERT_SET_Z(v[3], z[3]);
547 }
548
549 if (DO_TWOSIDE && facing == 1) {
550 if (!DO_FLAT) {
551 VERT_RESTORE_RGBA( 0 );
552 VERT_RESTORE_RGBA( 1 );
553 VERT_RESTORE_RGBA( 2 );
554 }
555 VERT_RESTORE_RGBA( 3 );
556 if (HAVE_SPEC) {
557 if (!DO_FLAT) {
558 VERT_RESTORE_SPEC( 0 );
559 VERT_RESTORE_SPEC( 1 );
560 VERT_RESTORE_SPEC( 2 );
561 }
562 VERT_RESTORE_SPEC( 3 );
563 }
564 }
565
566
567 if (DO_FLAT) {
568 VERT_RESTORE_RGBA( 0 );
569 VERT_RESTORE_RGBA( 1 );
570 VERT_RESTORE_RGBA( 2 );
571 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
572 VERT_RESTORE_SPEC( 0 );
573 VERT_RESTORE_SPEC( 1 );
574 VERT_RESTORE_SPEC( 2 );
575 }
576 }
577 }
578 #else
TAG(quadr)579 static void TAG(quadr)( struct gl_context *ctx, GLuint e0,
580 GLuint e1, GLuint e2, GLuint e3 )
581 {
582 if (DO_UNFILLED) {
583 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
584 GLubyte ef1 = VB->EdgeFlag[e1];
585 GLubyte ef3 = VB->EdgeFlag[e3];
586 VB->EdgeFlag[e1] = 0;
587 TAG(triangle)( ctx, e0, e1, e3 );
588 VB->EdgeFlag[e1] = ef1;
589 VB->EdgeFlag[e3] = 0;
590 TAG(triangle)( ctx, e1, e2, e3 );
591 VB->EdgeFlag[e3] = ef3;
592 } else {
593 TAG(triangle)( ctx, e0, e1, e3 );
594 TAG(triangle)( ctx, e1, e2, e3 );
595 }
596 }
597 #endif
598 #endif
599
600 #if DO_LINE
TAG(line)601 static void TAG(line)( struct gl_context *ctx, GLuint e0, GLuint e1 )
602 {
603 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
604 VERTEX *v[2];
605 LOCAL_VARS(2);
606
607 v[0] = (VERTEX *)GET_VERTEX(e0);
608 v[1] = (VERTEX *)GET_VERTEX(e1);
609
610 if (DO_FLAT) {
611 VERT_SAVE_RGBA( 0 );
612 VERT_COPY_RGBA( v[0], v[1] );
613 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
614 VERT_SAVE_SPEC( 0 );
615 VERT_COPY_SPEC( v[0], v[1] );
616 }
617 }
618
619 LINE( v[0], v[1] );
620
621 if (DO_FLAT) {
622 VERT_RESTORE_RGBA( 0 );
623
624 if (HAVE_SPEC && VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
625 VERT_RESTORE_SPEC( 0 );
626 }
627 }
628 }
629 #endif
630
631 #if DO_POINTS
TAG(points)632 static void TAG(points)( struct gl_context *ctx, GLuint first, GLuint last )
633 {
634 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
635 GLuint i;
636 LOCAL_VARS(1);
637
638 if (VB->Elts == 0) {
639 for ( i = first ; i < last ; i++ ) {
640 if ( VB->ClipMask[i] == 0 ) {
641 VERTEX *v = (VERTEX *)GET_VERTEX(i);
642 POINT( v );
643 }
644 }
645 } else {
646 for ( i = first ; i < last ; i++ ) {
647 GLuint e = VB->Elts[i];
648 if ( VB->ClipMask[e] == 0 ) {
649 VERTEX *v = (VERTEX *)GET_VERTEX(e);
650 POINT( v );
651 }
652 }
653 }
654 }
655 #endif
656
TAG(init)657 static void TAG(init)( void )
658 {
659 #if DO_QUAD
660 TAB[IND].quad = TAG(quadr);
661 #endif
662 #if DO_TRI
663 TAB[IND].triangle = TAG(triangle);
664 #endif
665 #if DO_LINE
666 TAB[IND].line = TAG(line);
667 #endif
668 #if DO_POINTS
669 TAB[IND].points = TAG(points);
670 #endif
671 }
672
673 #undef IND
674 #undef TAG
675
676 #if HAVE_BACK_COLORS
677 #undef VERT_SET_RGBA
678 #endif
679
680 #if !HAVE_SPEC
681 #undef VERT_SET_SPEC
682 #undef VERT_COPY_SPEC
683 #undef VERT_SAVE_SPEC
684 #undef VERT_RESTORE_SPEC
685 #if HAVE_BACK_COLORS
686 #undef VERT_COPY_SPEC1
687 #endif
688 #else
689 #if HAVE_BACK_COLORS
690 #undef VERT_SET_SPEC
691 #endif
692 #endif
693
694 #if !HAVE_BACK_COLORS
695 #undef VERT_COPY_SPEC1
696 #undef VERT_COPY_RGBA1
697 #endif
698
699 #ifndef INSANE_VERTICES
700 #undef VERT_SET_Z
701 #undef VERT_Z_ADD
702 #endif
703