2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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 OTHER
22 * DEALINGS IN THE SOFTWARE.
26 #define VERT_SET_IND(v, c) (void)c
27 #define VERT_COPY_IND(v0, v1)
28 #define VERT_SAVE_IND(idx)
29 #define VERT_RESTORE_IND(idx)
31 #define VERT_SET_RGBA(v, c)
34 #define VERT_SET_RGBA(v, c) (void)c
35 #define VERT_COPY_RGBA(v0, v1)
36 #define VERT_SAVE_RGBA(idx)
37 #define VERT_RESTORE_RGBA(idx)
39 #define VERT_SET_IND(v, c)
44 #define VERT_SET_SPEC(v, c) (void)c
45 #define VERT_COPY_SPEC(v0, v1)
46 #define VERT_SAVE_SPEC(idx)
47 #define VERT_RESTORE_SPEC(idx)
49 #define VERT_COPY_SPEC1(v)
53 #define VERT_SET_SPEC(v, c)
58 #define VERT_COPY_SPEC1(v)
59 #define VERT_COPY_IND1(v)
60 #define VERT_COPY_RGBA1(v)
63 #ifndef INSANE_VERTICES
64 #define VERT_SET_Z(v, val) VERT_Z(v) = val
65 #define VERT_Z_ADD(v, val) VERT_Z(v) += val
69 static void TAG(triangle
)(GLcontext
*ctx
, GLuint e0
, GLuint e1
, GLuint e2
)
71 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
75 GLenum mode
= GL_FILL
;
80 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
82 #ifdef PERFORMANCE_MEASURE
83 if (VIA_PERFORMANCE
) P_M
;
86 v
[0] = (VERTEX
*)GET_VERTEX(e0
);
87 v
[1] = (VERTEX
*)GET_VERTEX(e1
);
88 v
[2] = (VERTEX
*)GET_VERTEX(e2
);
90 if (DO_TWOSIDE
|| DO_OFFSET
|| DO_UNFILLED
) {
91 GLfloat ex
= VERT_X(v
[0]) - VERT_X(v
[2]);
92 GLfloat ey
= VERT_Y(v
[0]) - VERT_Y(v
[2]);
93 GLfloat fx
= VERT_X(v
[1]) - VERT_X(v
[2]);
94 GLfloat fy
= VERT_Y(v
[1]) - VERT_Y(v
[2]);
95 GLfloat cc
= ex
* fy
- ey
* fx
;
97 if (DO_TWOSIDE
|| DO_UNFILLED
) {
98 facing
= AREA_IS_CCW(cc
) ^ ctx
->Polygon
._FrontBit
;
102 mode
= ctx
->Polygon
.BackMode
;
103 if (ctx
->Polygon
.CullFlag
&&
104 ctx
->Polygon
.CullFaceMode
!= GL_FRONT
) {
109 mode
= ctx
->Polygon
.FrontMode
;
110 if (ctx
->Polygon
.CullFlag
&&
111 ctx
->Polygon
.CullFaceMode
!= GL_BACK
) {
117 if (DO_TWOSIDE
&& facing
== 1) {
119 if (HAVE_BACK_COLORS
) {
123 VERT_COPY_RGBA1(v
[0]);
124 VERT_COPY_RGBA1(v
[1]);
127 VERT_COPY_RGBA1(v
[2]);
132 VERT_COPY_SPEC1(v
[0]);
133 VERT_COPY_SPEC1(v
[1]);
136 VERT_COPY_SPEC1(v
[2]);
140 GLfloat (*vbcolor
)[4] = VB
->ColorPtr
[1]->data
;
141 ASSERT(VB
->ColorPtr
[1]->stride
== 4*sizeof(GLfloat
));
147 VERT_SET_RGBA(v
[0], vbcolor
[e0
]);
148 VERT_SET_RGBA(v
[1], vbcolor
[e1
]);
151 VERT_SET_RGBA(v
[2], vbcolor
[e2
]);
153 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[1]) {
154 GLfloat (*vbspec
)[4] = VB
->SecondaryColorPtr
[1]->data
;
159 VERT_SET_SPEC(v
[0], vbspec
[e0
]);
160 VERT_SET_SPEC(v
[1], vbspec
[e1
]);
163 VERT_SET_SPEC(v
[2], vbspec
[e2
]);
168 GLfloat
*vbindex
= (GLfloat
*) VB
->IndexPtr
[1]->data
;
172 VERT_SET_IND(v
[0], vbindex
[e0
]);
173 VERT_SET_IND(v
[1], vbindex
[e1
]);
176 VERT_SET_IND(v
[2], vbindex
[e2
]);
182 offset
= ctx
->Polygon
.OffsetUnits
* DEPTH_SCALE
;
186 if (cc
* cc
> 1e-16) {
187 GLfloat ic
= 1.0 / cc
;
188 GLfloat ez
= z
[0] - z
[2];
189 GLfloat fz
= z
[1] - z
[2];
190 GLfloat a
= ey
* fz
- ez
* fy
;
191 GLfloat b
= ez
* fx
- ex
* fz
;
194 if (ac
< 0.0f
) ac
= -ac
;
195 if (bc
< 0.0f
) bc
= -bc
;
196 offset
+= MAX2(ac
, bc
) * ctx
->Polygon
.OffsetFactor
;
206 VERT_COPY_RGBA(v
[0], v
[2]);
207 VERT_COPY_RGBA(v
[1], v
[2]);
208 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
211 VERT_COPY_SPEC(v
[0], v
[2]);
212 VERT_COPY_SPEC(v
[1], v
[2]);
218 VERT_COPY_IND(v
[0], v
[2]);
219 VERT_COPY_IND(v
[1], v
[2]);
223 if (mode
== GL_POINT
) {
224 if (DO_OFFSET
&& ctx
->Polygon
.OffsetPoint
) {
225 VERT_Z_ADD(v
[0], offset
);
226 VERT_Z_ADD(v
[1], offset
);
227 VERT_Z_ADD(v
[2], offset
);
229 UNFILLED_TRI(ctx
, GL_POINT
, e0
, e1
, e2
);
231 else if (mode
== GL_LINE
) {
232 if (DO_OFFSET
&& ctx
->Polygon
.OffsetLine
) {
233 VERT_Z_ADD(v
[0], offset
);
234 VERT_Z_ADD(v
[1], offset
);
235 VERT_Z_ADD(v
[2], offset
);
237 UNFILLED_TRI(ctx
, GL_LINE
, e0
, e1
, e2
);
240 if (DO_OFFSET
&& ctx
->Polygon
.OffsetFill
) {
241 VERT_Z_ADD(v
[0], offset
);
242 VERT_Z_ADD(v
[1], offset
);
243 VERT_Z_ADD(v
[2], offset
);
246 RASTERIZE(GL_TRIANGLES
);
247 TRI(v
[0], v
[1], v
[2]);
251 VERT_SET_Z(v
[0], z
[0]);
252 VERT_SET_Z(v
[1], z
[1]);
253 VERT_SET_Z(v
[2], z
[2]);
256 if (DO_TWOSIDE
&& facing
== 1) {
259 VERT_RESTORE_RGBA(0);
260 VERT_RESTORE_RGBA(1);
262 VERT_RESTORE_RGBA(2);
265 VERT_RESTORE_SPEC(0);
266 VERT_RESTORE_SPEC(1);
268 VERT_RESTORE_SPEC(2);
273 VERT_RESTORE_IND( 0 );
274 VERT_RESTORE_IND( 1 );
276 VERT_RESTORE_IND( 2 );
283 VERT_RESTORE_RGBA(0);
284 VERT_RESTORE_RGBA(1);
285 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
286 VERT_RESTORE_SPEC(0);
287 VERT_RESTORE_SPEC(1);
295 SET_PRIMITIVE_RENDERED
297 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
304 static void TAG(quad
)(GLcontext
*ctx
,
305 GLuint e0
, GLuint e1
, GLuint e2
, GLuint e3
)
307 struct vertex_buffer
*VB
= &TNL_CONTEXT( ctx
)->vb
;
311 GLenum mode
= GL_FILL
;
315 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
317 #ifdef PERFORMANCE_MEASURE
318 if (VIA_PERFORMANCE
) P_M
;
320 v
[0] = (VERTEX
*)GET_VERTEX(e0
);
321 v
[1] = (VERTEX
*)GET_VERTEX(e1
);
322 v
[2] = (VERTEX
*)GET_VERTEX(e2
);
323 v
[3] = (VERTEX
*)GET_VERTEX(e3
);
325 if (DO_TWOSIDE
|| DO_OFFSET
|| DO_UNFILLED
) {
326 GLfloat ex
= VERT_X(v
[2]) - VERT_X(v
[0]);
327 GLfloat ey
= VERT_Y(v
[2]) - VERT_Y(v
[0]);
328 GLfloat fx
= VERT_X(v
[3]) - VERT_X(v
[1]);
329 GLfloat fy
= VERT_Y(v
[3]) - VERT_Y(v
[1]);
330 GLfloat cc
= ex
* fy
- ey
* fx
;
332 if (DO_TWOSIDE
|| DO_UNFILLED
) {
333 facing
= AREA_IS_CCW(cc
) ^ ctx
->Polygon
._FrontBit
;
337 mode
= ctx
->Polygon
.BackMode
;
338 if (ctx
->Polygon
.CullFlag
&&
339 ctx
->Polygon
.CullFaceMode
!= GL_FRONT
) {
344 mode
= ctx
->Polygon
.FrontMode
;
345 if (ctx
->Polygon
.CullFlag
&&
346 ctx
->Polygon
.CullFaceMode
!= GL_BACK
) {
352 if (DO_TWOSIDE
&& facing
== 1) {
354 GLfloat (*vbcolor
)[4] = VB
->ColorPtr
[1]->data
;
357 if (HAVE_BACK_COLORS
) {
362 VERT_COPY_RGBA1(v
[0]);
363 VERT_COPY_RGBA1(v
[1]);
364 VERT_COPY_RGBA1(v
[2]);
367 VERT_COPY_RGBA1(v
[3]);
373 VERT_COPY_SPEC1(v
[0]);
374 VERT_COPY_SPEC1(v
[1]);
375 VERT_COPY_SPEC1(v
[2]);
378 VERT_COPY_SPEC1(v
[3]);
386 VERT_SET_RGBA(v
[0], vbcolor
[e0
]);
387 VERT_SET_RGBA(v
[1], vbcolor
[e1
]);
388 VERT_SET_RGBA(v
[2], vbcolor
[e2
]);
391 VERT_SET_RGBA(v
[3], vbcolor
[e3
]);
393 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[1]) {
394 GLfloat (*vbspec
)[4] = VB
->SecondaryColorPtr
[1]->data
;
395 ASSERT(VB
->SecondaryColorPtr
[1]->stride
==4*sizeof(GLfloat
));
401 VERT_SET_SPEC(v
[0], vbspec
[e0
]);
402 VERT_SET_SPEC(v
[1], vbspec
[e1
]);
403 VERT_SET_SPEC(v
[2], vbspec
[e2
]);
406 VERT_SET_SPEC(v
[3], vbspec
[e3
]);
411 GLfloat
*vbindex
= (GLfloat
*) VB
->IndexPtr
[1]->data
;
416 VERT_SET_IND(v
[0], vbindex
[e0
]);
417 VERT_SET_IND(v
[1], vbindex
[e1
]);
418 VERT_SET_IND(v
[2], vbindex
[e2
]);
421 VERT_SET_IND(v
[3], vbindex
[e3
]);
428 offset
= ctx
->Polygon
.OffsetUnits
* DEPTH_SCALE
;
433 if (cc
* cc
> 1e-16) {
434 GLfloat ez
= z
[2] - z
[0];
435 GLfloat fz
= z
[3] - z
[1];
436 GLfloat a
= ey
* fz
- ez
* fy
;
437 GLfloat b
= ez
* fx
- ex
* fz
;
438 GLfloat ic
= 1.0 / cc
;
441 if ( ac
< 0.0f
) ac
= -ac
;
442 if ( bc
< 0.0f
) bc
= -bc
;
443 offset
+= MAX2(ac
, bc
) * ctx
->Polygon
.OffsetFactor
;
454 VERT_COPY_RGBA(v
[0], v
[3]);
455 VERT_COPY_RGBA(v
[1], v
[3]);
456 VERT_COPY_RGBA(v
[2], v
[3]);
457 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
461 VERT_COPY_SPEC(v
[0], v
[3]);
462 VERT_COPY_SPEC(v
[1], v
[3]);
463 VERT_COPY_SPEC(v
[2], v
[3]);
470 VERT_COPY_IND(v
[0], v
[3]);
471 VERT_COPY_IND(v
[1], v
[3]);
472 VERT_COPY_IND(v
[2], v
[3]);
476 if (mode
== GL_POINT
) {
477 if (( DO_OFFSET
) && ctx
->Polygon
.OffsetPoint
) {
478 VERT_Z_ADD(v
[0], offset
);
479 VERT_Z_ADD(v
[1], offset
);
480 VERT_Z_ADD(v
[2], offset
);
481 VERT_Z_ADD(v
[3], offset
);
483 UNFILLED_QUAD(ctx
, GL_POINT
, e0
, e1
, e2
, e3
);
485 else if (mode
== GL_LINE
) {
486 if (DO_OFFSET
&& ctx
->Polygon
.OffsetLine
) {
487 VERT_Z_ADD(v
[0], offset
);
488 VERT_Z_ADD(v
[1], offset
);
489 VERT_Z_ADD(v
[2], offset
);
490 VERT_Z_ADD(v
[3], offset
);
492 UNFILLED_QUAD(ctx
, GL_LINE
, e0
, e1
, e2
, e3
);
495 if (DO_OFFSET
&& ctx
->Polygon
.OffsetFill
) {
496 VERT_Z_ADD(v
[0], offset
);
497 VERT_Z_ADD(v
[1], offset
);
498 VERT_Z_ADD(v
[2], offset
);
499 VERT_Z_ADD(v
[3], offset
);
501 RASTERIZE(GL_TRIANGLES
);
502 QUAD((v
[0]), (v
[1]), (v
[2]), (v
[3]));
506 VERT_SET_Z(v
[0], z
[0]);
507 VERT_SET_Z(v
[1], z
[1]);
508 VERT_SET_Z(v
[2], z
[2]);
509 VERT_SET_Z(v
[3], z
[3]);
512 if (DO_TWOSIDE
&& facing
== 1) {
515 VERT_RESTORE_RGBA(0);
516 VERT_RESTORE_RGBA(1);
517 VERT_RESTORE_RGBA(2);
519 VERT_RESTORE_RGBA(3);
522 VERT_RESTORE_SPEC(0);
523 VERT_RESTORE_SPEC(1);
524 VERT_RESTORE_SPEC(2);
526 VERT_RESTORE_SPEC(3);
531 VERT_RESTORE_IND( 0 );
532 VERT_RESTORE_IND( 1 );
533 VERT_RESTORE_IND( 2 );
535 VERT_RESTORE_IND( 3 );
541 VERT_RESTORE_RGBA(0);
542 VERT_RESTORE_RGBA(1);
543 VERT_RESTORE_RGBA(2);
544 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
545 VERT_RESTORE_SPEC(0);
546 VERT_RESTORE_SPEC(1);
547 VERT_RESTORE_SPEC(2);
557 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
561 static void TAG(quad
)(GLcontext
*ctx
, GLuint e0
,
562 GLuint e1
, GLuint e2
, GLuint e3
)
565 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
567 #ifdef PERFORMANCE_MEASURE
568 if (VIA_PERFORMANCE
) P_M
;
571 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
572 GLubyte ef1
= VB
->EdgeFlag
[e1
];
573 GLubyte ef3
= VB
->EdgeFlag
[e3
];
574 VB
->EdgeFlag
[e1
] = 0;
575 TAG(triangle
)(ctx
, e0
, e1
, e3
);
576 VB
->EdgeFlag
[e1
] = ef1
;
577 VB
->EdgeFlag
[e3
] = 0;
578 TAG(triangle
)(ctx
, e1
, e2
, e3
);
579 VB
->EdgeFlag
[e3
] = ef3
;
582 TAG(triangle
)(ctx
, e0
, e1
, e3
);
583 TAG(triangle
)(ctx
, e1
, e2
, e3
);
586 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
593 static void TAG(line
)(GLcontext
*ctx
, GLuint e0
, GLuint e1
)
595 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
599 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
601 #ifdef PERFORMANCE_MEASURE
602 if (VIA_PERFORMANCE
) P_M
;
604 v
[0] = (VERTEX
*)GET_VERTEX(e0
);
605 v
[1] = (VERTEX
*)GET_VERTEX(e1
);
610 VERT_COPY_RGBA( v
[0], v
[1] );
611 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
613 VERT_COPY_SPEC(v
[0], v
[1]);
618 VERT_COPY_IND(v
[0], v
[1]);
626 VERT_RESTORE_RGBA(0);
628 if (HAVE_SPEC
&& VB
->SecondaryColorPtr
[0]) {
629 VERT_RESTORE_SPEC(0);
636 SET_PRIMITIVE_RENDERED
638 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
644 static void TAG(points
)(GLcontext
*ctx
, GLuint first
, GLuint last
)
646 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
650 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
652 #ifdef PERFORMANCE_MEASURE
653 if (VIA_PERFORMANCE
) P_M
;
656 for (i
= first
; i
< last
; i
++) {
657 if (VB
->ClipMask
[i
] == 0) {
658 VERTEX
*v
= (VERTEX
*)GET_VERTEX(i
);
660 SET_PRIMITIVE_RENDERED
665 for (i
= first
; i
< last
; i
++) {
666 GLuint e
= VB
->Elts
[i
];
667 if (VB
->ClipMask
[e
] == 0) {
668 VERTEX
*v
= (VERTEX
*)GET_VERTEX(e
);
670 SET_PRIMITIVE_RENDERED
675 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
680 static void TAG(init
)(void)
683 TAB
[IND
].quad
= TAG(quad
);
686 TAB
[IND
].triangle
= TAG(triangle
);
689 TAB
[IND
].line
= TAG(line
);
692 TAB
[IND
].points
= TAG(points
);
703 #undef VERT_RESTORE_IND
709 #undef VERT_COPY_RGBA
710 #undef VERT_SAVE_RGBA
711 #undef VERT_RESTORE_RGBA
719 #undef VERT_COPY_SPEC
720 #undef VERT_SAVE_SPEC
721 #undef VERT_RESTORE_SPEC
723 #undef VERT_COPY_SPEC1
731 #if !HAVE_BACK_COLORS
732 #undef VERT_COPY_SPEC1
733 #undef VERT_COPY_IND1
734 #undef VERT_COPY_RGBA1
737 #ifndef INSANE_VERTICES