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