Merge commit 'origin/gallium-0.1' into gallium-0.2
[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 * 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 /* 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_RGBA: Vertices have rgba values (otherwise index values).
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 IND and SPEC.
63 *
64 * LOCAL_VARS(n): (At least) define local vars for save/restore rgba.
65 *
66 */
67
68 #if HAVE_RGBA
69 #define VERT_SET_IND( v, c ) (void) c
70 #define VERT_COPY_IND( v0, v1 )
71 #define VERT_SAVE_IND( idx )
72 #define VERT_RESTORE_IND( idx )
73 #if HAVE_BACK_COLORS
74 #define VERT_SET_RGBA( v, c )
75 #endif
76 #else
77 #define VERT_SET_RGBA( v, c ) (void) c
78 #define VERT_COPY_RGBA( v0, v1 )
79 #define VERT_SAVE_RGBA( idx )
80 #define VERT_RESTORE_RGBA( idx )
81 #if HAVE_BACK_COLORS
82 #define VERT_SET_IND( v, c )
83 #endif
84 #endif
85
86 #if !HAVE_SPEC
87 #define VERT_SET_SPEC( v, c ) (void) c
88 #define VERT_COPY_SPEC( v0, v1 )
89 #define VERT_SAVE_SPEC( idx )
90 #define VERT_RESTORE_SPEC( idx )
91 #if HAVE_BACK_COLORS
92 #define VERT_COPY_SPEC1( v )
93 #endif
94 #else
95 #if HAVE_BACK_COLORS
96 #define VERT_SET_SPEC( v, c )
97 #endif
98 #endif
99
100 #if !HAVE_BACK_COLORS
101 #define VERT_COPY_SPEC1( v )
102 #define VERT_COPY_IND1( v )
103 #define VERT_COPY_RGBA1( v )
104 #endif
105
106 #ifndef INSANE_VERTICES
107 #define VERT_SET_Z(v,val) VERT_Z(v) = val
108 #define VERT_Z_ADD(v,val) VERT_Z(v) += val
109 #endif
110
111 #ifndef REVERSE_DEPTH
112 #define REVERSE_DEPTH 0
113 #endif
114
115 /* disable twostencil for un-aware drivers */
116 #ifndef HAVE_STENCIL_TWOSIDE
117 #define HAVE_STENCIL_TWOSIDE 0
118 #endif
119 #ifndef DO_TWOSTENCIL
120 #define DO_TWOSTENCIL 0
121 #endif
122 #ifndef SETUP_STENCIL
123 #define SETUP_STENCIL(f)
124 #endif
125 #ifndef UNSET_STENCIL
126 #define UNSET_STENCIL(f)
127 #endif
128
129 #if DO_TRI
130 static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
131 {
132 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
133 VERTEX *v[3];
134 GLfloat offset = 0;
135 GLfloat z[3];
136 GLenum mode = GL_FILL;
137 GLuint facing = 0;
138 LOCAL_VARS(3);
139
140 /* fprintf(stderr, "%s\n", __FUNCTION__); */
141
142 v[0] = (VERTEX *)GET_VERTEX(e0);
143 v[1] = (VERTEX *)GET_VERTEX(e1);
144 v[2] = (VERTEX *)GET_VERTEX(e2);
145
146 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
147 {
148 GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
149 GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
150 GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
151 GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
152 GLfloat cc = ex*fy - ey*fx;
153
154 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
155 {
156 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
157
158 if (DO_UNFILLED) {
159 if (facing) {
160 mode = ctx->Polygon.BackMode;
161 if (ctx->Polygon.CullFlag &&
162 ctx->Polygon.CullFaceMode != GL_FRONT) {
163 return;
164 }
165 } else {
166 mode = ctx->Polygon.FrontMode;
167 if (ctx->Polygon.CullFlag &&
168 ctx->Polygon.CullFaceMode != GL_BACK) {
169 return;
170 }
171 }
172 }
173
174 if (DO_TWOSIDE && facing == 1)
175 {
176 if (HAVE_RGBA) {
177 if (HAVE_BACK_COLORS) {
178 if (!DO_FLAT) {
179 VERT_SAVE_RGBA( 0 );
180 VERT_SAVE_RGBA( 1 );
181 VERT_COPY_RGBA1( v[0] );
182 VERT_COPY_RGBA1( v[1] );
183 }
184 VERT_SAVE_RGBA( 2 );
185 VERT_COPY_RGBA1( v[2] );
186 if (HAVE_SPEC) {
187 if (!DO_FLAT) {
188 VERT_SAVE_SPEC( 0 );
189 VERT_SAVE_SPEC( 1 );
190 VERT_COPY_SPEC1( v[0] );
191 VERT_COPY_SPEC1( v[1] );
192 }
193 VERT_SAVE_SPEC( 2 );
194 VERT_COPY_SPEC1( v[2] );
195 }
196 }
197 else {
198 GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
199 (void) vbcolor;
200
201 if (!DO_FLAT) {
202 VERT_SAVE_RGBA( 0 );
203 VERT_SAVE_RGBA( 1 );
204 }
205 VERT_SAVE_RGBA( 2 );
206
207 if (VB->ColorPtr[1]->stride) {
208 ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
209
210 if (!DO_FLAT) {
211 VERT_SET_RGBA( v[0], vbcolor[e0] );
212 VERT_SET_RGBA( v[1], vbcolor[e1] );
213 }
214 VERT_SET_RGBA( v[2], vbcolor[e2] );
215 }
216 else {
217 if (!DO_FLAT) {
218 VERT_SET_RGBA( v[0], vbcolor[0] );
219 VERT_SET_RGBA( v[1], vbcolor[0] );
220 }
221 VERT_SET_RGBA( v[2], vbcolor[0] );
222 }
223
224 if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
225 GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
226 ASSERT(VB->SecondaryColorPtr[1]->stride == 4*sizeof(GLfloat));
227
228 if (!DO_FLAT) {
229 VERT_SAVE_SPEC( 0 );
230 VERT_SAVE_SPEC( 1 );
231 VERT_SET_SPEC( v[0], vbspec[e0] );
232 VERT_SET_SPEC( v[1], vbspec[e1] );
233 }
234 VERT_SAVE_SPEC( 2 );
235 VERT_SET_SPEC( v[2], vbspec[e2] );
236 }
237 }
238 }
239 else {
240 GLfloat (*vbindex) = (GLfloat *)VB->IndexPtr[1]->data;
241 if (!DO_FLAT) {
242 VERT_SAVE_IND( 0 );
243 VERT_SAVE_IND( 1 );
244 VERT_SET_IND( v[0], vbindex[e0] );
245 VERT_SET_IND( v[1], vbindex[e1] );
246 }
247 VERT_SAVE_IND( 2 );
248 VERT_SET_IND( v[2], vbindex[e2] );
249 }
250 }
251 }
252
253
254 if (DO_OFFSET)
255 {
256 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
257 z[0] = VERT_Z(v[0]);
258 z[1] = VERT_Z(v[1]);
259 z[2] = VERT_Z(v[2]);
260 if (cc * cc > 1e-16) {
261 GLfloat ic = 1.0 / cc;
262 GLfloat ez = z[0] - z[2];
263 GLfloat fz = z[1] - z[2];
264 GLfloat a = ey*fz - ez*fy;
265 GLfloat b = ez*fx - ex*fz;
266 GLfloat ac = a * ic;
267 GLfloat bc = b * ic;
268 if ( ac < 0.0f ) ac = -ac;
269 if ( bc < 0.0f ) bc = -bc;
270 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD;
271 }
272 offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0);
273 }
274 }
275
276 if (DO_FLAT) {
277 if (HAVE_RGBA) {
278 VERT_SAVE_RGBA( 0 );
279 VERT_SAVE_RGBA( 1 );
280 VERT_COPY_RGBA( v[0], v[2] );
281 VERT_COPY_RGBA( v[1], v[2] );
282 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
283 VERT_SAVE_SPEC( 0 );
284 VERT_SAVE_SPEC( 1 );
285 VERT_COPY_SPEC( v[0], v[2] );
286 VERT_COPY_SPEC( v[1], v[2] );
287 }
288 }
289 else {
290 VERT_SAVE_IND( 0 );
291 VERT_SAVE_IND( 1 );
292 VERT_COPY_IND( v[0], v[2] );
293 VERT_COPY_IND( v[1], v[2] );
294 }
295 }
296
297 if (mode == GL_POINT) {
298 if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
299 VERT_Z_ADD(v[0], offset);
300 VERT_Z_ADD(v[1], offset);
301 VERT_Z_ADD(v[2], offset);
302 }
303 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
304 SETUP_STENCIL(facing);
305 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
306 UNSET_STENCIL(facing);
307 } else {
308 UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 );
309 }
310 } else if (mode == GL_LINE) {
311 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
312 VERT_Z_ADD(v[0], offset);
313 VERT_Z_ADD(v[1], offset);
314 VERT_Z_ADD(v[2], offset);
315 }
316 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
317 SETUP_STENCIL(facing);
318 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
319 UNSET_STENCIL(facing);
320 } else {
321 UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 );
322 }
323 } else {
324 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
325 VERT_Z_ADD(v[0], offset);
326 VERT_Z_ADD(v[1], offset);
327 VERT_Z_ADD(v[2], offset);
328 }
329 if (DO_UNFILLED)
330 RASTERIZE( GL_TRIANGLES );
331 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
332 SETUP_STENCIL(facing);
333 TRI( v[0], v[1], v[2] );
334 UNSET_STENCIL(facing);
335 } else {
336 TRI( v[0], v[1], v[2] );
337 }
338 }
339
340 if (DO_OFFSET)
341 {
342 VERT_SET_Z(v[0], z[0]);
343 VERT_SET_Z(v[1], z[1]);
344 VERT_SET_Z(v[2], z[2]);
345 }
346
347 if (DO_TWOSIDE && facing == 1)
348 {
349 if (HAVE_RGBA) {
350 if (!DO_FLAT) {
351 VERT_RESTORE_RGBA( 0 );
352 VERT_RESTORE_RGBA( 1 );
353 }
354 VERT_RESTORE_RGBA( 2 );
355 if (HAVE_SPEC) {
356 if (!DO_FLAT) {
357 VERT_RESTORE_SPEC( 0 );
358 VERT_RESTORE_SPEC( 1 );
359 }
360 VERT_RESTORE_SPEC( 2 );
361 }
362 }
363 else {
364 if (!DO_FLAT) {
365 VERT_RESTORE_IND( 0 );
366 VERT_RESTORE_IND( 1 );
367 }
368 VERT_RESTORE_IND( 2 );
369 }
370 }
371
372
373 if (DO_FLAT) {
374 if (HAVE_RGBA) {
375 VERT_RESTORE_RGBA( 0 );
376 VERT_RESTORE_RGBA( 1 );
377 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
378 VERT_RESTORE_SPEC( 0 );
379 VERT_RESTORE_SPEC( 1 );
380 }
381 }
382 else {
383 VERT_RESTORE_IND( 0 );
384 VERT_RESTORE_IND( 1 );
385 }
386 }
387 }
388 #endif
389
390 #if DO_QUAD
391 #if DO_FULL_QUAD
392 static void TAG(quadr)( GLcontext *ctx,
393 GLuint e0, GLuint e1, GLuint e2, GLuint e3 )
394 {
395 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
396 VERTEX *v[4];
397 GLfloat offset = 0;
398 GLfloat z[4];
399 GLenum mode = GL_FILL;
400 GLuint facing = 0;
401 LOCAL_VARS(4);
402
403 v[0] = (VERTEX *)GET_VERTEX(e0);
404 v[1] = (VERTEX *)GET_VERTEX(e1);
405 v[2] = (VERTEX *)GET_VERTEX(e2);
406 v[3] = (VERTEX *)GET_VERTEX(e3);
407
408 if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED || DO_TWOSTENCIL)
409 {
410 GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
411 GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
412 GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
413 GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
414 GLfloat cc = ex*fy - ey*fx;
415
416 if (DO_TWOSIDE || DO_UNFILLED || DO_TWOSTENCIL)
417 {
418 facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit;
419
420 if (DO_UNFILLED) {
421 if (facing) {
422 mode = ctx->Polygon.BackMode;
423 if (ctx->Polygon.CullFlag &&
424 ctx->Polygon.CullFaceMode != GL_FRONT) {
425 return;
426 }
427 } else {
428 mode = ctx->Polygon.FrontMode;
429 if (ctx->Polygon.CullFlag &&
430 ctx->Polygon.CullFaceMode != GL_BACK) {
431 return;
432 }
433 }
434 }
435
436 if (DO_TWOSIDE && facing == 1)
437 {
438 if (HAVE_RGBA) {
439 GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
440 (void)vbcolor;
441
442 if (HAVE_BACK_COLORS) {
443 if (!DO_FLAT) {
444 VERT_SAVE_RGBA( 0 );
445 VERT_SAVE_RGBA( 1 );
446 VERT_SAVE_RGBA( 2 );
447 VERT_COPY_RGBA1( v[0] );
448 VERT_COPY_RGBA1( v[1] );
449 VERT_COPY_RGBA1( v[2] );
450 }
451 VERT_SAVE_RGBA( 3 );
452 VERT_COPY_RGBA1( v[3] );
453 if (HAVE_SPEC) {
454 if (!DO_FLAT) {
455 VERT_SAVE_SPEC( 0 );
456 VERT_SAVE_SPEC( 1 );
457 VERT_SAVE_SPEC( 2 );
458 VERT_COPY_SPEC1( v[0] );
459 VERT_COPY_SPEC1( v[1] );
460 VERT_COPY_SPEC1( v[2] );
461 }
462 VERT_SAVE_SPEC( 3 );
463 VERT_COPY_SPEC1( v[3] );
464 }
465 }
466 else {
467 if (!DO_FLAT) {
468 VERT_SAVE_RGBA( 0 );
469 VERT_SAVE_RGBA( 1 );
470 VERT_SAVE_RGBA( 2 );
471 }
472 VERT_SAVE_RGBA( 3 );
473
474 if (VB->ColorPtr[1]->stride) {
475 if (!DO_FLAT) {
476 VERT_SET_RGBA( v[0], vbcolor[e0] );
477 VERT_SET_RGBA( v[1], vbcolor[e1] );
478 VERT_SET_RGBA( v[2], vbcolor[e2] );
479 }
480 VERT_SET_RGBA( v[3], vbcolor[e3] );
481 }
482 else {
483 if (!DO_FLAT) {
484 VERT_SET_RGBA( v[0], vbcolor[0] );
485 VERT_SET_RGBA( v[1], vbcolor[0] );
486 VERT_SET_RGBA( v[2], vbcolor[0] );
487 }
488 VERT_SET_RGBA( v[3], vbcolor[0] );
489 }
490
491 if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
492 GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
493 ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
494
495 if (!DO_FLAT) {
496 VERT_SAVE_SPEC( 0 );
497 VERT_SAVE_SPEC( 1 );
498 VERT_SAVE_SPEC( 2 );
499 VERT_SET_SPEC( v[0], vbspec[e0] );
500 VERT_SET_SPEC( v[1], vbspec[e1] );
501 VERT_SET_SPEC( v[2], vbspec[e2] );
502 }
503 VERT_SAVE_SPEC( 3 );
504 VERT_SET_SPEC( v[3], vbspec[e3] );
505 }
506 }
507 }
508 else {
509 GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
510 if (!DO_FLAT) {
511 VERT_SAVE_IND( 0 );
512 VERT_SAVE_IND( 1 );
513 VERT_SAVE_IND( 2 );
514 VERT_SET_IND( v[0], vbindex[e0] );
515 VERT_SET_IND( v[1], vbindex[e1] );
516 VERT_SET_IND( v[2], vbindex[e2] );
517 }
518 VERT_SAVE_IND( 3 );
519 VERT_SET_IND( v[3], vbindex[e3] );
520 }
521 }
522 }
523
524
525 if (DO_OFFSET)
526 {
527 offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
528 z[0] = VERT_Z(v[0]);
529 z[1] = VERT_Z(v[1]);
530 z[2] = VERT_Z(v[2]);
531 z[3] = VERT_Z(v[3]);
532 if (cc * cc > 1e-16) {
533 GLfloat ez = z[2] - z[0];
534 GLfloat fz = z[3] - z[1];
535 GLfloat a = ey*fz - ez*fy;
536 GLfloat b = ez*fx - ex*fz;
537 GLfloat ic = 1.0 / cc;
538 GLfloat ac = a * ic;
539 GLfloat bc = b * ic;
540 if ( ac < 0.0f ) ac = -ac;
541 if ( bc < 0.0f ) bc = -bc;
542 offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor / ctx->DrawBuffer->_MRD;
543 }
544 offset *= ctx->DrawBuffer->_MRD * (REVERSE_DEPTH ? -1.0 : 1.0);
545 }
546 }
547
548 if (DO_FLAT) {
549 if (HAVE_RGBA) {
550 VERT_SAVE_RGBA( 0 );
551 VERT_SAVE_RGBA( 1 );
552 VERT_SAVE_RGBA( 2 );
553 VERT_COPY_RGBA( v[0], v[3] );
554 VERT_COPY_RGBA( v[1], v[3] );
555 VERT_COPY_RGBA( v[2], v[3] );
556 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
557 VERT_SAVE_SPEC( 0 );
558 VERT_SAVE_SPEC( 1 );
559 VERT_SAVE_SPEC( 2 );
560 VERT_COPY_SPEC( v[0], v[3] );
561 VERT_COPY_SPEC( v[1], v[3] );
562 VERT_COPY_SPEC( v[2], v[3] );
563 }
564 }
565 else {
566 VERT_SAVE_IND( 0 );
567 VERT_SAVE_IND( 1 );
568 VERT_SAVE_IND( 2 );
569 VERT_COPY_IND( v[0], v[3] );
570 VERT_COPY_IND( v[1], v[3] );
571 VERT_COPY_IND( v[2], v[3] );
572 }
573 }
574
575 if (mode == GL_POINT) {
576 if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
577 VERT_Z_ADD(v[0], offset);
578 VERT_Z_ADD(v[1], offset);
579 VERT_Z_ADD(v[2], offset);
580 VERT_Z_ADD(v[3], offset);
581 }
582 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
583 SETUP_STENCIL(facing);
584 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
585 UNSET_STENCIL(facing);
586 } else {
587 UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 );
588 }
589 } else if (mode == GL_LINE) {
590 if (DO_OFFSET && ctx->Polygon.OffsetLine) {
591 VERT_Z_ADD(v[0], offset);
592 VERT_Z_ADD(v[1], offset);
593 VERT_Z_ADD(v[2], offset);
594 VERT_Z_ADD(v[3], offset);
595 }
596 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
597 SETUP_STENCIL(facing);
598 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
599 UNSET_STENCIL(facing);
600 } else {
601 UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 );
602 }
603 } else {
604 if (DO_OFFSET && ctx->Polygon.OffsetFill) {
605 VERT_Z_ADD(v[0], offset);
606 VERT_Z_ADD(v[1], offset);
607 VERT_Z_ADD(v[2], offset);
608 VERT_Z_ADD(v[3], offset);
609 }
610 RASTERIZE( GL_QUADS );
611 if (DO_TWOSTENCIL && !HAVE_STENCIL_TWOSIDE && ctx->Stencil.TestTwoSide) {
612 SETUP_STENCIL(facing);
613 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
614 UNSET_STENCIL(facing);
615 } else {
616 QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
617 }
618 }
619
620 if (DO_OFFSET)
621 {
622 VERT_SET_Z(v[0], z[0]);
623 VERT_SET_Z(v[1], z[1]);
624 VERT_SET_Z(v[2], z[2]);
625 VERT_SET_Z(v[3], z[3]);
626 }
627
628 if (DO_TWOSIDE && facing == 1)
629 {
630 if (HAVE_RGBA) {
631 if (!DO_FLAT) {
632 VERT_RESTORE_RGBA( 0 );
633 VERT_RESTORE_RGBA( 1 );
634 VERT_RESTORE_RGBA( 2 );
635 }
636 VERT_RESTORE_RGBA( 3 );
637 if (HAVE_SPEC) {
638 if (!DO_FLAT) {
639 VERT_RESTORE_SPEC( 0 );
640 VERT_RESTORE_SPEC( 1 );
641 VERT_RESTORE_SPEC( 2 );
642 }
643 VERT_RESTORE_SPEC( 3 );
644 }
645 }
646 else {
647 if (!DO_FLAT) {
648 VERT_RESTORE_IND( 0 );
649 VERT_RESTORE_IND( 1 );
650 VERT_RESTORE_IND( 2 );
651 }
652 VERT_RESTORE_IND( 3 );
653 }
654 }
655
656
657 if (DO_FLAT) {
658 if (HAVE_RGBA) {
659 VERT_RESTORE_RGBA( 0 );
660 VERT_RESTORE_RGBA( 1 );
661 VERT_RESTORE_RGBA( 2 );
662 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
663 VERT_RESTORE_SPEC( 0 );
664 VERT_RESTORE_SPEC( 1 );
665 VERT_RESTORE_SPEC( 2 );
666 }
667 }
668 else {
669 VERT_RESTORE_IND( 0 );
670 VERT_RESTORE_IND( 1 );
671 VERT_RESTORE_IND( 2 );
672 }
673 }
674 }
675 #else
676 static void TAG(quadr)( GLcontext *ctx, GLuint e0,
677 GLuint e1, GLuint e2, GLuint e3 )
678 {
679 if (DO_UNFILLED) {
680 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
681 GLubyte ef1 = VB->EdgeFlag[e1];
682 GLubyte ef3 = VB->EdgeFlag[e3];
683 VB->EdgeFlag[e1] = 0;
684 TAG(triangle)( ctx, e0, e1, e3 );
685 VB->EdgeFlag[e1] = ef1;
686 VB->EdgeFlag[e3] = 0;
687 TAG(triangle)( ctx, e1, e2, e3 );
688 VB->EdgeFlag[e3] = ef3;
689 } else {
690 TAG(triangle)( ctx, e0, e1, e3 );
691 TAG(triangle)( ctx, e1, e2, e3 );
692 }
693 }
694 #endif
695 #endif
696
697 #if DO_LINE
698 static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1 )
699 {
700 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
701 VERTEX *v[2];
702 LOCAL_VARS(2);
703
704 v[0] = (VERTEX *)GET_VERTEX(e0);
705 v[1] = (VERTEX *)GET_VERTEX(e1);
706
707 if (DO_FLAT) {
708 if (HAVE_RGBA) {
709 VERT_SAVE_RGBA( 0 );
710 VERT_COPY_RGBA( v[0], v[1] );
711 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
712 VERT_SAVE_SPEC( 0 );
713 VERT_COPY_SPEC( v[0], v[1] );
714 }
715 }
716 else {
717 VERT_SAVE_IND( 0 );
718 VERT_COPY_IND( v[0], v[1] );
719 }
720 }
721
722 LINE( v[0], v[1] );
723
724 if (DO_FLAT) {
725 if (HAVE_RGBA) {
726 VERT_RESTORE_RGBA( 0 );
727
728 if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
729 VERT_RESTORE_SPEC( 0 );
730 }
731 }
732 else {
733 VERT_RESTORE_IND( 0 );
734 }
735 }
736 }
737 #endif
738
739 #if DO_POINTS
740 static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
741 {
742 struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
743 GLuint i;
744 LOCAL_VARS(1);
745
746 if (VB->Elts == 0) {
747 for ( i = first ; i < last ; i++ ) {
748 if ( VB->ClipMask[i] == 0 ) {
749 VERTEX *v = (VERTEX *)GET_VERTEX(i);
750 POINT( v );
751 }
752 }
753 } else {
754 for ( i = first ; i < last ; i++ ) {
755 GLuint e = VB->Elts[i];
756 if ( VB->ClipMask[e] == 0 ) {
757 VERTEX *v = (VERTEX *)GET_VERTEX(e);
758 POINT( v );
759 }
760 }
761 }
762 }
763 #endif
764
765 static void TAG(init)( void )
766 {
767 #if DO_QUAD
768 TAB[IND].quad = TAG(quadr);
769 #endif
770 #if DO_TRI
771 TAB[IND].triangle = TAG(triangle);
772 #endif
773 #if DO_LINE
774 TAB[IND].line = TAG(line);
775 #endif
776 #if DO_POINTS
777 TAB[IND].points = TAG(points);
778 #endif
779 }
780
781 #undef IND
782 #undef TAG
783
784 #if HAVE_RGBA
785 #undef VERT_SET_IND
786 #undef VERT_COPY_IND
787 #undef VERT_SAVE_IND
788 #undef VERT_RESTORE_IND
789 #if HAVE_BACK_COLORS
790 #undef VERT_SET_RGBA
791 #endif
792 #else
793 #undef VERT_SET_RGBA
794 #undef VERT_COPY_RGBA
795 #undef VERT_SAVE_RGBA
796 #undef VERT_RESTORE_RGBA
797 #if HAVE_BACK_COLORS
798 #undef VERT_SET_IND
799 #endif
800 #endif
801
802 #if !HAVE_SPEC
803 #undef VERT_SET_SPEC
804 #undef VERT_COPY_SPEC
805 #undef VERT_SAVE_SPEC
806 #undef VERT_RESTORE_SPEC
807 #if HAVE_BACK_COLORS
808 #undef VERT_COPY_SPEC1
809 #endif
810 #else
811 #if HAVE_BACK_COLORS
812 #undef VERT_SET_SPEC
813 #endif
814 #endif
815
816 #if !HAVE_BACK_COLORS
817 #undef VERT_COPY_SPEC1
818 #undef VERT_COPY_IND1
819 #undef VERT_COPY_RGBA1
820 #endif
821
822 #ifndef INSANE_VERTICES
823 #undef VERT_SET_Z
824 #undef VERT_Z_ADD
825 #endif