Move the transform and lighting code to two new directories
[mesa.git] / src / mesa / swrast_setup / ss_tritmp.h
1 /*
2 * Mesa 3-D graphics library
3 * Version: 3.5
4 *
5 * Copyright (C) 1999 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 <keithw@valinux.com>
26 */
27
28
29 static void TAG(triangle)(GLcontext *ctx,
30 GLuint e0, GLuint e1, GLuint e2,
31 GLuint pv)
32 {
33 struct vertex_buffer *VB = TNL_VB(ctx);
34 SWvertex *verts = SWSETUP_VB(VB)->verts;
35 SWvertex *v[3];
36 GLfloat offset;
37 GLfloat z[3];
38 GLubyte c[3][4], s[3][4];
39 GLuint i[3];
40 GLenum mode = GL_FILL;
41
42 v[0] = &verts[e0];
43 v[1] = &verts[e1];
44 v[2] = &verts[e2];
45
46 if (IND & (SS_TWOSIDE_BIT | SS_FLAT_BIT)) {
47 SS_COLOR(c[0], v[0]->color);
48
49 if (IND & SS_TWOSIDE_BIT) {
50 SS_COLOR(c[1], v[1]->color);
51 SS_COLOR(c[2], v[2]->color);
52 }
53
54 if (IND & SS_COPY_EXTRAS) {
55 SS_SPEC(s[0], v[0]->specular);
56 SS_IND(i[0], v[0]->index);
57
58 if (IND & SS_TWOSIDE_BIT) {
59 SS_SPEC(s[1], v[1]->specular);
60 SS_IND(i[1], v[1]->index);
61
62 SS_SPEC(s[2], v[2]->specular);
63 SS_IND(i[2], v[2]->index);
64 }
65 }
66 }
67
68 if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT))
69 {
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;
75
76 if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT))
77 {
78 GLuint facing = (cc < 0.0) ^ ctx->Polygon.FrontBit;
79
80 if (IND & SS_UNFILLED_BIT)
81 mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode;
82
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;
87
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]);
92
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]);
97
98 SS_IND(v[0]->index, vbindex[pv]);
99 SS_IND(v[1]->index, vbindex[pv]);
100 SS_IND(v[2]->index, vbindex[pv]);
101 }
102 } else {
103 SS_COLOR(v[0]->color, vbcolor[e0]);
104 SS_COLOR(v[1]->color, vbcolor[e1]);
105 SS_COLOR(v[2]->color, vbcolor[e2]);
106
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]);
111
112 SS_IND(v[0]->index, vbindex[e0]);
113 SS_IND(v[1]->index, vbindex[e1]);
114 SS_IND(v[2]->index, vbindex[e2]);
115 }
116 }
117 }
118 }
119
120 if (IND & SS_OFFSET_BIT)
121 {
122 offset = ctx->Polygon.OffsetUnits;
123 z[0] = v[0]->win[2];
124 z[1] = v[1]->win[2];
125 z[2] = v[2]->win[2];
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;
132 GLfloat ac = a * ic;
133 GLfloat bc = b * ic;
134 if (ac < 0.0f) ac = -ac;
135 if (bc < 0.0f) bc = -bc;
136 offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
137 }
138 }
139 }
140 else if (IND & SS_FLAT_BIT)
141 {
142 GLubyte *color = VB->Color[0]->data[pv];
143 GLubyte *spec = VB->SecondaryColor[0]->data[pv];
144 GLuint index = VB->Index[0]->data[pv];
145
146 SS_COLOR(v[0]->color, color);
147
148 if (IND & SS_COPY_EXTRAS) {
149 SS_SPEC(v[0]->specular, spec);
150 SS_IND(v[0]->index, index);
151 }
152 }
153
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;
160 }
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;
170 }
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] ); }
174 } else {
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;
179 }
180 _swrast_Triangle( ctx, v[0], v[1], v[2] );
181 }
182
183 if (IND & SS_OFFSET_BIT) {
184 v[0]->win[2] = z[0];
185 v[1]->win[2] = z[1];
186 v[2]->win[2] = z[2];
187 }
188
189 if (IND & (SS_FLAT_BIT | SS_TWOSIDE_BIT)) {
190 SS_COLOR(v[0]->color, c[0]);
191
192 if (IND & SS_TWOSIDE_BIT) {
193 SS_COLOR(v[1]->color, c[1]);
194 SS_COLOR(v[2]->color, c[2]);
195 }
196
197 if (IND & SS_COPY_EXTRAS) {
198 SS_SPEC(v[0]->specular, s[0]);
199 SS_IND(v[0]->index, i[0]);
200
201 if (IND & SS_TWOSIDE_BIT) {
202 SS_SPEC(v[1]->specular, s[1]);
203 SS_IND(v[1]->index, i[1]);
204
205 SS_SPEC(v[2]->specular, s[2]);
206 SS_IND(v[2]->index, i[2]);
207 }
208 }
209 }
210 }
211
212
213
214 /* Need to do something with edgeflags:
215 */
216 static void TAG(quad)( GLcontext *ctx, GLuint v0,
217 GLuint v1, GLuint v2, GLuint v3,
218 GLuint pv )
219 {
220 TAG(triangle)( ctx, v0, v1, v3, pv );
221 TAG(triangle)( ctx, v1, v2, v3, pv );
222 }
223
224
225 static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
226 {
227 struct vertex_buffer *VB = TNL_VB(ctx);
228 SWvertex *verts = SWSETUP_VB(VB)->verts;
229 GLubyte c[2][4], s[2][4];
230 GLuint i[2];
231 SWvertex *vert0 = &verts[v0];
232 SWvertex *vert1 = &verts[v1];
233
234
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];
239
240 SS_COLOR(c[0], vert0->color);
241 SS_COLOR(vert0->color, color);
242
243 if (IND & SS_COPY_EXTRAS) {
244 SS_SPEC(s[0], vert0->specular);
245 SS_SPEC(vert0->specular, spec);
246
247 SS_IND(i[0], vert0->index);
248 SS_IND(vert0->index, index);
249 }
250 }
251
252 _swrast_Line( ctx, vert0, vert1 );
253
254 if (IND & SS_FLAT_BIT) {
255 SS_COLOR(vert0->color, c[0]);
256
257 if (IND & SS_COPY_EXTRAS) {
258 SS_SPEC(vert0->specular, s[0]);
259 SS_IND(vert0->index, i[0]);
260 }
261 }
262 }
263
264
265 static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last )
266 {
267 struct vertex_buffer *VB = TNL_VB(ctx);
268 SWvertex *verts = SWSETUP_VB(VB)->verts;
269 int i;
270
271 for(i=first;i<=last;i++)
272 if(VB->ClipMask[i]==0)
273 _swrast_Point( ctx, &verts[i] );
274 }
275
276
277
278
279 static void TAG(init)( void )
280 {
281 tri_tab[IND] = TAG(triangle);
282 quad_tab[IND] = TAG(quad);
283 line_tab[IND] = TAG(line);
284 points_tab[IND] = TAG(points);
285 }
286
287
288 #undef IND
289 #undef TAG
290
291
292