2 * Mesa 3-D graphics library
5 * Copyright (C) 1999 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
25 * Keith Whitwell <keithw@valinux.com>
29 static void TAG(triangle
)(GLcontext
*ctx
,
30 GLuint e0
, GLuint e1
, GLuint e2
,
33 struct vertex_buffer
*VB
= TNL_VB(ctx
);
34 SWvertex
*verts
= SWSETUP_VB(VB
)->verts
;
38 GLubyte c
[3][4], s
[3][4];
40 GLenum mode
= GL_FILL
;
46 if (IND
& (SS_TWOSIDE_BIT
| SS_FLAT_BIT
)) {
47 SS_COLOR(c
[0], v
[0]->color
);
49 if (IND
& SS_TWOSIDE_BIT
) {
50 SS_COLOR(c
[1], v
[1]->color
);
51 SS_COLOR(c
[2], v
[2]->color
);
54 if (IND
& SS_COPY_EXTRAS
) {
55 SS_SPEC(s
[0], v
[0]->specular
);
56 SS_IND(i
[0], v
[0]->index
);
58 if (IND
& SS_TWOSIDE_BIT
) {
59 SS_SPEC(s
[1], v
[1]->specular
);
60 SS_IND(i
[1], v
[1]->index
);
62 SS_SPEC(s
[2], v
[2]->specular
);
63 SS_IND(i
[2], v
[2]->index
);
68 if (IND
& (SS_TWOSIDE_BIT
| SS_OFFSET_BIT
| SS_UNFILLED_BIT
))
70 GLfloat ex
= v
[0]->win
[0] - v
[2]->win
[0];
71 GLfloat ey
= v
[0]->win
[1] - v
[2]->win
[1];
72 GLfloat fx
= v
[1]->win
[0] - v
[2]->win
[0];
73 GLfloat fy
= v
[1]->win
[1] - v
[2]->win
[1];
74 GLfloat cc
= ex
*fy
- ey
*fx
;
76 if (IND
& (SS_TWOSIDE_BIT
| SS_UNFILLED_BIT
))
78 GLuint facing
= (cc
< 0.0) ^ ctx
->Polygon
.FrontBit
;
80 if (IND
& SS_UNFILLED_BIT
)
81 mode
= facing
? ctx
->Polygon
.BackMode
: ctx
->Polygon
.FrontMode
;
83 if (IND
& SS_TWOSIDE_BIT
) {
84 GLubyte (*vbcolor
)[4] = VB
->Color
[facing
]->data
;
85 GLubyte (*vbspec
)[4] = VB
->SecondaryColor
[facing
]->data
;
86 GLuint
*vbindex
= VB
->Index
[facing
]->data
;
88 if (IND
& SS_FLAT_BIT
) {
89 SS_COLOR(v
[0]->color
, vbcolor
[pv
]);
90 SS_COLOR(v
[1]->color
, vbcolor
[pv
]);
91 SS_COLOR(v
[2]->color
, vbcolor
[pv
]);
93 if (IND
& SS_COPY_EXTRAS
) {
94 SS_SPEC(v
[0]->specular
, vbspec
[pv
]);
95 SS_SPEC(v
[1]->specular
, vbspec
[pv
]);
96 SS_SPEC(v
[2]->specular
, vbspec
[pv
]);
98 SS_IND(v
[0]->index
, vbindex
[pv
]);
99 SS_IND(v
[1]->index
, vbindex
[pv
]);
100 SS_IND(v
[2]->index
, vbindex
[pv
]);
103 SS_COLOR(v
[0]->color
, vbcolor
[e0
]);
104 SS_COLOR(v
[1]->color
, vbcolor
[e1
]);
105 SS_COLOR(v
[2]->color
, vbcolor
[e2
]);
107 if (IND
& SS_COPY_EXTRAS
) {
108 SS_SPEC(v
[0]->specular
, vbspec
[e0
]);
109 SS_SPEC(v
[1]->specular
, vbspec
[e1
]);
110 SS_SPEC(v
[2]->specular
, vbspec
[e2
]);
112 SS_IND(v
[0]->index
, vbindex
[e0
]);
113 SS_IND(v
[1]->index
, vbindex
[e1
]);
114 SS_IND(v
[2]->index
, vbindex
[e2
]);
120 if (IND
& SS_OFFSET_BIT
)
122 offset
= ctx
->Polygon
.OffsetUnits
;
126 if (cc
* cc
> 1e-16) {
127 GLfloat ez
= z
[0] - z
[2];
128 GLfloat fz
= z
[1] - z
[2];
129 GLfloat a
= ey
*fz
- ez
*fy
;
130 GLfloat b
= ez
*fx
- ex
*fz
;
131 GLfloat ic
= 1.0 / cc
;
134 if (ac
< 0.0f
) ac
= -ac
;
135 if (bc
< 0.0f
) bc
= -bc
;
136 offset
+= MAX2(ac
, bc
) * ctx
->Polygon
.OffsetFactor
;
140 else if (IND
& SS_FLAT_BIT
)
142 GLubyte
*color
= VB
->Color
[0]->data
[pv
];
143 GLubyte
*spec
= VB
->SecondaryColor
[0]->data
[pv
];
144 GLuint index
= VB
->Index
[0]->data
[pv
];
146 SS_COLOR(v
[0]->color
, color
);
148 if (IND
& SS_COPY_EXTRAS
) {
149 SS_SPEC(v
[0]->specular
, spec
);
150 SS_IND(v
[0]->index
, index
);
154 if (mode
== GL_POINT
) {
155 GLubyte
*ef
= VB
->EdgeFlagPtr
->data
;
156 if ((IND
& SS_OFFSET_BIT
) && ctx
->Polygon
.OffsetPoint
) {
157 v
[0]->win
[2] += offset
;
158 v
[1]->win
[2] += offset
;
159 v
[2]->win
[2] += offset
;
161 if (ef
[e0
]&0x1) { ef
[e0
] &= ~0x1; _swrast_Point( ctx
, v
[0] ); }
162 if (ef
[e1
]&0x1) { ef
[e1
] &= ~0x1; _swrast_Point( ctx
, v
[1] ); }
163 if (ef
[e2
]&0x2) { ef
[e2
] &= ~0x2; _swrast_Point( ctx
, v
[2] ); }
164 } else if (mode
== GL_LINE
) {
165 GLubyte
*ef
= VB
->EdgeFlagPtr
->data
;
166 if ((IND
& SS_OFFSET_BIT
) && ctx
->Polygon
.OffsetLine
) {
167 v
[0]->win
[2] += offset
;
168 v
[1]->win
[2] += offset
;
169 v
[2]->win
[2] += offset
;
171 if (ef
[e0
]&0x1) { ef
[e0
] &= ~0x1; _swrast_Line( ctx
, v
[0], v
[1] ); }
172 if (ef
[e1
]&0x1) { ef
[e1
] &= ~0x1; _swrast_Line( ctx
, v
[1], v
[2] ); }
173 if (ef
[e2
]&0x2) { ef
[e2
] &= ~0x2; _swrast_Line( ctx
, v
[2], v
[0] ); }
175 if ((IND
& SS_OFFSET_BIT
) && ctx
->Polygon
.OffsetFill
) {
176 v
[0]->win
[2] += offset
;
177 v
[1]->win
[2] += offset
;
178 v
[2]->win
[2] += offset
;
180 _swrast_Triangle( ctx
, v
[0], v
[1], v
[2] );
183 if (IND
& SS_OFFSET_BIT
) {
189 if (IND
& (SS_FLAT_BIT
| SS_TWOSIDE_BIT
)) {
190 SS_COLOR(v
[0]->color
, c
[0]);
192 if (IND
& SS_TWOSIDE_BIT
) {
193 SS_COLOR(v
[1]->color
, c
[1]);
194 SS_COLOR(v
[2]->color
, c
[2]);
197 if (IND
& SS_COPY_EXTRAS
) {
198 SS_SPEC(v
[0]->specular
, s
[0]);
199 SS_IND(v
[0]->index
, i
[0]);
201 if (IND
& SS_TWOSIDE_BIT
) {
202 SS_SPEC(v
[1]->specular
, s
[1]);
203 SS_IND(v
[1]->index
, i
[1]);
205 SS_SPEC(v
[2]->specular
, s
[2]);
206 SS_IND(v
[2]->index
, i
[2]);
214 /* Need to do something with edgeflags:
216 static void TAG(quad
)( GLcontext
*ctx
, GLuint v0
,
217 GLuint v1
, GLuint v2
, GLuint v3
,
220 TAG(triangle
)( ctx
, v0
, v1
, v3
, pv
);
221 TAG(triangle
)( ctx
, v1
, v2
, v3
, pv
);
225 static void TAG(line
)( GLcontext
*ctx
, GLuint v0
, GLuint v1
, GLuint pv
)
227 struct vertex_buffer
*VB
= TNL_VB(ctx
);
228 SWvertex
*verts
= SWSETUP_VB(VB
)->verts
;
229 GLubyte c
[2][4], s
[2][4];
231 SWvertex
*vert0
= &verts
[v0
];
232 SWvertex
*vert1
= &verts
[v1
];
235 if (IND
& SS_FLAT_BIT
) {
236 GLubyte
*color
= VB
->Color
[0]->data
[pv
];
237 GLubyte
*spec
= VB
->SecondaryColor
[0]->data
[pv
];
238 GLuint index
= VB
->Index
[0]->data
[pv
];
240 SS_COLOR(c
[0], vert0
->color
);
241 SS_COLOR(vert0
->color
, color
);
243 if (IND
& SS_COPY_EXTRAS
) {
244 SS_SPEC(s
[0], vert0
->specular
);
245 SS_SPEC(vert0
->specular
, spec
);
247 SS_IND(i
[0], vert0
->index
);
248 SS_IND(vert0
->index
, index
);
252 _swrast_Line( ctx
, vert0
, vert1
);
254 if (IND
& SS_FLAT_BIT
) {
255 SS_COLOR(vert0
->color
, c
[0]);
257 if (IND
& SS_COPY_EXTRAS
) {
258 SS_SPEC(vert0
->specular
, s
[0]);
259 SS_IND(vert0
->index
, i
[0]);
265 static void TAG(points
)( GLcontext
*ctx
, GLuint first
, GLuint last
)
267 struct vertex_buffer
*VB
= TNL_VB(ctx
);
268 SWvertex
*verts
= SWSETUP_VB(VB
)->verts
;
271 for(i
=first
;i
<=last
;i
++)
272 if(VB
->ClipMask
[i
]==0)
273 _swrast_Point( ctx
, &verts
[i
] );
279 static void TAG(init
)( void )
281 tri_tab
[IND
] = TAG(triangle
);
282 quad_tab
[IND
] = TAG(quad
);
283 line_tab
[IND
] = TAG(line
);
284 points_tab
[IND
] = TAG(points
);