Major rework of tnl module
[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_CONTEXT(ctx)->vb;
34 SWvertex *verts = SWSETUP_CONTEXT(ctx)->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 if (IND & SS_RGBA_BIT) {
48 SS_COLOR(c[0], v[0]->color);
49 SS_SPEC(s[0], v[0]->specular);
50
51 if (IND & SS_TWOSIDE_BIT) {
52 SS_COLOR(c[1], v[1]->color);
53 SS_COLOR(c[2], v[2]->color);
54
55 SS_SPEC(s[1], v[1]->specular);
56 SS_SPEC(s[2], v[2]->specular);
57 }
58 } else {
59 SS_IND(i[0], v[0]->index);
60
61 if (IND & SS_TWOSIDE_BIT) {
62 SS_IND(i[1], v[1]->index);
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 if (IND & SS_FLAT_BIT) {
85 if (IND & SS_RGBA_BIT) {
86 GLubyte (*vbcolor)[4] = VB->ColorPtr[facing]->data;
87 GLubyte (*vbspec)[4] = VB->SecondaryColorPtr[facing]->data;
88
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 SS_SPEC(v[0]->specular, vbspec[pv]);
94 SS_SPEC(v[1]->specular, vbspec[pv]);
95 SS_SPEC(v[2]->specular, vbspec[pv]);
96 } else {
97 GLuint *vbindex = VB->IndexPtr[facing]->data;
98
99 SS_IND(v[0]->index, vbindex[pv]);
100 SS_IND(v[1]->index, vbindex[pv]);
101 SS_IND(v[2]->index, vbindex[pv]);
102 }
103 } else {
104 if (IND & SS_RGBA_BIT) {
105 GLubyte (*vbcolor)[4] = VB->ColorPtr[facing]->data;
106 GLubyte (*vbspec)[4] = VB->SecondaryColorPtr[facing]->data;
107
108 SS_COLOR(v[0]->color, vbcolor[e0]);
109 SS_COLOR(v[1]->color, vbcolor[e1]);
110 SS_COLOR(v[2]->color, vbcolor[e2]);
111
112 SS_SPEC(v[0]->specular, vbspec[e0]);
113 SS_SPEC(v[1]->specular, vbspec[e1]);
114 SS_SPEC(v[2]->specular, vbspec[e2]);
115 } else {
116 GLuint *vbindex = VB->IndexPtr[facing]->data;
117
118 SS_IND(v[0]->index, vbindex[e0]);
119 SS_IND(v[1]->index, vbindex[e1]);
120 SS_IND(v[2]->index, vbindex[e2]);
121 }
122 }
123 }
124 }
125
126 if (IND & SS_OFFSET_BIT)
127 {
128 offset = ctx->Polygon.OffsetUnits;
129 z[0] = v[0]->win[2];
130 z[1] = v[1]->win[2];
131 z[2] = v[2]->win[2];
132 if (cc * cc > 1e-16) {
133 GLfloat ez = z[0] - z[2];
134 GLfloat fz = z[1] - z[2];
135 GLfloat a = ey*fz - ez*fy;
136 GLfloat b = ez*fx - ex*fz;
137 GLfloat ic = 1.0 / cc;
138 GLfloat ac = a * ic;
139 GLfloat bc = b * ic;
140 if (ac < 0.0f) ac = -ac;
141 if (bc < 0.0f) bc = -bc;
142 offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
143 }
144 }
145 }
146 else if (IND & SS_FLAT_BIT)
147 {
148 if (IND & SS_RGBA_BIT) {
149 GLubyte *color = VB->ColorPtr[0]->data[pv];
150 GLubyte *spec = VB->SecondaryColorPtr[0]->data[pv];
151
152 SS_COLOR(v[0]->color, color);
153 SS_SPEC(v[0]->specular, spec);
154 }
155 else {
156 GLuint index = VB->IndexPtr[0]->data[pv];
157 SS_IND(v[0]->index, index);
158 }
159 }
160
161 if (mode == GL_POINT) {
162 GLubyte *ef = VB->EdgeFlagPtr->data;
163 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) {
164 v[0]->win[2] += offset;
165 v[1]->win[2] += offset;
166 v[2]->win[2] += offset;
167 }
168 if (ef[e0]) _swrast_Point( ctx, v[0] );
169 if (ef[e1]) _swrast_Point( ctx, v[1] );
170 if (ef[e2]) _swrast_Point( ctx, v[2] );
171 } else if (mode == GL_LINE) {
172 GLubyte *ef = VB->EdgeFlagPtr->data;
173 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) {
174 v[0]->win[2] += offset;
175 v[1]->win[2] += offset;
176 v[2]->win[2] += offset;
177 }
178 if (ef[e0]) _swrast_Line( ctx, v[0], v[1] );
179 if (ef[e1]) _swrast_Line( ctx, v[1], v[2] );
180 if (ef[e2]) _swrast_Line( ctx, v[2], v[0] );
181 } else {
182 if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) {
183 v[0]->win[2] += offset;
184 v[1]->win[2] += offset;
185 v[2]->win[2] += offset;
186 }
187 _swrast_Triangle( ctx, v[0], v[1], v[2] );
188 }
189
190 if (IND & SS_OFFSET_BIT) {
191 v[0]->win[2] = z[0];
192 v[1]->win[2] = z[1];
193 v[2]->win[2] = z[2];
194 }
195
196 if (IND & (SS_FLAT_BIT | SS_TWOSIDE_BIT)) {
197 if (IND & SS_RGBA_BIT) {
198 SS_COLOR(v[0]->color, c[0]);
199 SS_SPEC(v[0]->specular, s[0]);
200
201 if (IND & SS_TWOSIDE_BIT) {
202 SS_COLOR(v[1]->color, c[1]);
203 SS_COLOR(v[2]->color, c[2]);
204 SS_SPEC(v[1]->specular, s[1]);
205 SS_SPEC(v[2]->specular, s[2]);
206 }
207 }
208 else {
209 SS_IND(v[0]->index, i[0]);
210
211 if (IND & SS_TWOSIDE_BIT) {
212 SS_IND(v[1]->index, i[1]);
213 SS_IND(v[2]->index, i[2]);
214 }
215 }
216 }
217 }
218
219
220
221 /* Need to do something with edgeflags:
222 */
223 static void TAG(quad)( GLcontext *ctx, GLuint v0,
224 GLuint v1, GLuint v2, GLuint v3,
225 GLuint pv )
226 {
227 if (IND & SS_UNFILLED_BIT) {
228 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
229 GLubyte ef1 = VB->EdgeFlagPtr->data[v1];
230 GLubyte ef3 = VB->EdgeFlagPtr->data[v3];
231 VB->EdgeFlagPtr->data[v1] = 0;
232 TAG(triangle)( ctx, v0, v1, v3, pv );
233 VB->EdgeFlagPtr->data[v1] = ef1;
234 VB->EdgeFlagPtr->data[v3] = 0;
235 TAG(triangle)( ctx, v1, v2, v3, pv );
236 VB->EdgeFlagPtr->data[v3] = ef3;
237 } else {
238 TAG(triangle)( ctx, v0, v1, v3, pv );
239 TAG(triangle)( ctx, v1, v2, v3, pv );
240 }
241 }
242
243
244 static void TAG(line)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
245 {
246 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
247 SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
248 GLubyte c[2][4], s[2][4];
249 GLuint i[2];
250 SWvertex *vert0 = &verts[v0];
251 SWvertex *vert1 = &verts[v1];
252
253
254 if (IND & SS_FLAT_BIT) {
255 if (IND & SS_RGBA_BIT) {
256 GLubyte *color = VB->ColorPtr[0]->data[pv];
257 GLubyte *spec = VB->SecondaryColorPtr[0]->data[pv];
258
259 SS_COLOR(c[0], vert0->color);
260 SS_COLOR(vert0->color, color);
261
262 SS_SPEC(s[0], vert0->specular);
263 SS_SPEC(vert0->specular, spec);
264 }
265 else {
266 GLuint index = VB->IndexPtr[0]->data[pv];
267
268 SS_IND(i[0], vert0->index);
269 SS_IND(vert0->index, index);
270 }
271 }
272
273 _swrast_Line( ctx, vert0, vert1 );
274
275 if (IND & SS_FLAT_BIT) {
276 if (IND & SS_RGBA_BIT) {
277 SS_COLOR(vert0->color, c[0]);
278 SS_SPEC(vert0->specular, s[0]);
279 }
280 else {
281 SS_IND(vert0->index, i[0]);
282 }
283 }
284 }
285
286
287
288 static void TAG(init)( void )
289 {
290 tri_tab[IND] = TAG(triangle);
291 quad_tab[IND] = TAG(quad);
292 line_tab[IND] = TAG(line);
293 }
294
295
296 #undef IND
297 #undef TAG
298
299
300