source: trunk/src/opengl/mesa/3dfx/fxtritmp.h

Last change on this file was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 14.4 KB
Line 
1/* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
28 * terms stated above.
29 *
30 * Thank you for your contribution, David!
31 *
32 * Please make note of the above copyright/license statement. If you
33 * contributed code or bug fixes to this code under the previous (GNU
34 * Library) license and object to the new license, your code will be
35 * removed at your request. Please see the Mesa docs/COPYRIGHT file
36 * for more information.
37 *
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
41 *
42 * See fxapi.h for more revision/author details.
43 */
44
45
46static void TAG(fx_tri)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint e3, GLuint pv)
47{
48 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
49 struct vertex_buffer *VB=ctx->VB;
50 fxVertex *gWin = FX_DRIVER_DATA(VB)->verts;
51 GrVertex *v1 = (GrVertex *)gWin[e1].f;
52 GrVertex *v2 = (GrVertex *)gWin[e2].f;
53 GrVertex *v3 = (GrVertex *)gWin[e3].f;
54
55 (void) fxMesa;
56
57 if (IND & (FX_TWOSIDE|FX_OFFSET))
58 {
59 GLfloat ex = v1->x - v3->x;
60 GLfloat ey = v1->y - v3->y;
61 GLfloat fx = v2->x - v3->x;
62 GLfloat fy = v2->y - v3->y;
63 GLfloat c = ex*fy-ey*fx;
64
65 if (IND & FX_TWOSIDE) {
66 GLuint facing = (c<0.0) ^ ctx->Polygon.FrontBit;
67 GLubyte (*color)[4] = VB->Color[facing]->data;
68 if (IND & FX_FLAT) {
69 FX_VB_COLOR(fxMesa, color[pv]);
70 } else {
71 GOURAUD2(v1,color[e1]);
72 GOURAUD2(v2,color[e2]);
73 GOURAUD2(v3,color[e3]);
74 }
75 }
76
77 /* Should apply a factor to ac to compensate for different x/y
78 * scaling introduced in the Viewport matrix.
79 *
80 * The driver should supply scaling factors for 'factor' and 'units'.
81 */
82 if (IND & FX_OFFSET) {
83 GLfloat offset = ctx->Polygon.OffsetUnits;
84
85 if (c * c > 1e-16) {
86 GLfloat factor = ctx->Polygon.OffsetFactor;
87 GLfloat ez = v1->ooz - v3->ooz;
88 GLfloat fz = v2->ooz - v3->ooz;
89 GLfloat a = ey*fz-ez*fy;
90 GLfloat b = ez*fx-ex*fz;
91 GLfloat ic = 1.0 / c;
92 GLfloat ac = a * ic;
93 GLfloat bc = b * ic;
94 if (ac<0.0F) ac = -ac;
95 if (bc<0.0F) bc = -bc;
96 offset += MAX2( ac, bc ) * factor;
97 }
98 /* Probably a lot quicker just to nudge the z values and put
99 * them back afterwards.
100 */
101 FX_grDepthBiasLevel((int)offset);
102 }
103 }
104 else if (IND & FX_FLAT) {
105 GLubyte (*color)[4] = VB->Color[0]->data;
106 FX_VB_COLOR(fxMesa, color[pv]);
107 }
108
109 if (IND & FX_FRONT_BACK) {
110 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
111 ctx->Color.ColorMask[GCOMP] ||
112 ctx->Color.ColorMask[BCOMP],
113 FXFALSE);
114
115 FX_grDepthMask(FXFALSE);
116 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
117 }
118
119 if (IND & FX_ANTIALIAS)
120 FX_grAADrawTriangle(v1, v2, v3, FXTRUE, FXTRUE, FXTRUE);
121 else
122 FX_grDrawTriangle(v1, v2, v3);
123
124 /* Might be quicker to do two passes, one for each buffer?
125 */
126 if (IND & FX_FRONT_BACK) {
127 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
128 ctx->Color.ColorMask[GCOMP] ||
129 ctx->Color.ColorMask[BCOMP],
130 ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
131
132 if(ctx->Depth.Mask) FX_grDepthMask(FXTRUE);
133
134 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
135
136 if (IND & FX_ANTIALIAS)
137 FX_grAADrawTriangle(v1,v2,v3, FXTRUE,FXTRUE,FXTRUE);
138 else
139 FX_grDrawTriangle(v1, v2, v3);
140 }
141}
142
143
144/* Not worth the space?
145 */
146static void TAG(fx_quad)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint e3,
147 GLuint e4, GLuint pv)
148{
149 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
150 struct vertex_buffer *VB=ctx->VB;
151 fxVertex *gWin = FX_DRIVER_DATA(VB)->verts;
152 GrVertex *v1 = (GrVertex *)gWin[e1].f;
153 GrVertex *v2 = (GrVertex *)gWin[e2].f;
154 GrVertex *v3 = (GrVertex *)gWin[e3].f;
155 GrVertex *v4 = (GrVertex *)gWin[e4].f;
156
157 (void) fxMesa;
158
159 if (IND & (FX_TWOSIDE|FX_OFFSET))
160 {
161 GLfloat ex = v3->x - v1->x;
162 GLfloat ey = v3->y - v1->y;
163 GLfloat fx = v4->x - v2->x;
164 GLfloat fy = v4->y - v2->y;
165 GLfloat c = ex*fy-ey*fx;
166
167 if (IND & FX_TWOSIDE) {
168 GLuint facing = (c<0.0) ^ ctx->Polygon.FrontBit;
169 GLubyte (*color)[4] = VB->Color[facing]->data;
170 if (IND & FX_FLAT) {
171 FX_VB_COLOR(fxMesa, color[pv]);
172 } else {
173 GOURAUD2(v1,color[e1]);
174 GOURAUD2(v2,color[e2]);
175 GOURAUD2(v3,color[e3]);
176 GOURAUD2(v4,color[e4]);
177 }
178 }
179
180 /* Should apply a factor to ac to compensate for different x/y
181 * scaling introduced in the Viewport matrix.
182 *
183 * The driver should supply scaling factors for 'factor' and 'units'.
184 */
185 if (IND & FX_OFFSET) {
186 GLfloat offset = ctx->Polygon.OffsetUnits;
187
188 if (c * c > 1e-16) {
189 GLfloat factor = ctx->Polygon.OffsetFactor;
190 GLfloat ez = v3->ooz - v1->ooz;
191 GLfloat fz = v4->ooz - v2->ooz;
192 GLfloat a = ey*fz-ez*fy;
193 GLfloat b = ez*fx-ex*fz;
194 GLfloat ic = 1.0 / c;
195 GLfloat ac = a * ic;
196 GLfloat bc = b * ic;
197 if (ac<0.0F) ac = -ac;
198 if (bc<0.0F) bc = -bc;
199 offset += MAX2( ac, bc ) * factor;
200 }
201 /* Probably a lot quicker just to nudge the z values and put
202 * them back afterwards.
203 */
204 FX_grDepthBiasLevel((int)offset);
205 }
206 }
207 else if (IND & FX_FLAT) {
208 GLubyte (*color)[4] = VB->Color[0]->data;
209 FX_VB_COLOR(fxMesa, color[pv]);
210 }
211
212 if (IND & FX_FRONT_BACK) {
213 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
214 ctx->Color.ColorMask[GCOMP] ||
215 ctx->Color.ColorMask[BCOMP],
216 FXFALSE);
217
218 FX_grDepthMask(FXFALSE);
219 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
220 }
221
222 if (IND & FX_ANTIALIAS) {
223 FX_grAADrawTriangle(v1, v2, v4, FXTRUE, FXTRUE, FXTRUE);
224 FX_grAADrawTriangle(v2, v3, v4, FXTRUE, FXTRUE, FXTRUE);
225 } else {
226 FX_grDrawTriangle(v1, v2, v4);
227 FX_grDrawTriangle(v2, v3, v4);
228 }
229
230 /* Might be quicker to do two passes, one for each buffer?
231 */
232 if (IND & FX_FRONT_BACK) {
233 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
234 ctx->Color.ColorMask[GCOMP] ||
235 ctx->Color.ColorMask[BCOMP],
236 ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
237
238 if(ctx->Depth.Mask) FX_grDepthMask(FXTRUE);
239
240 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
241
242 if (IND & FX_ANTIALIAS) {
243 FX_grAADrawTriangle(v1, v2, v4, FXTRUE, FXTRUE, FXTRUE);
244 FX_grAADrawTriangle(v2, v3, v4, FXTRUE, FXTRUE, FXTRUE);
245 } else {
246 FX_grDrawTriangle(v1, v2, v4);
247 FX_grDrawTriangle(v2, v3, v4);
248 }
249 }
250}
251
252#define DRAW_LINE(tmp0, tmp1, width) \
253 do { \
254 GrVertex verts[4]; \
255 float dx, dy, wx, wy; \
256 \
257 dx = tmp0->x - tmp1->x; \
258 dy = tmp0->y - tmp1->y; \
259 \
260 if (dx * dx > dy * dy) { \
261 wx = 0; \
262 wy = width; \
263 } else { \
264 wx = width; \
265 wy = 0; \
266 } \
267 \
268 verts[0] = *tmp0; \
269 verts[1] = *tmp0; \
270 verts[2] = *tmp1; \
271 verts[3] = *tmp1; \
272 \
273 verts[0].x = tmp0->x - wx; \
274 verts[0].y = tmp0->y - wy; \
275 \
276 verts[1].x = tmp0->x + wx; \
277 verts[1].y = tmp0->y + wy; \
278 \
279 verts[2].x = tmp1->x + wx; \
280 verts[2].y = tmp1->y + wy; \
281 \
282 verts[3].x = tmp1->x - wx; \
283 verts[3].y = tmp1->y - wy; \
284 \
285 FX_grDrawPolygonVertexList(4, verts); \
286 } while (0)
287
288#if (IND & FX_OFFSET) == 0
289static void TAG(fx_line)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint pv)
290{
291 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
292 struct vertex_buffer *VB=ctx->VB;
293 fxVertex *gWin = FX_DRIVER_DATA(VB)->verts;
294 GLubyte (* const color)[4] = VB->Color[0]->data;
295 GrVertex *v1 = (GrVertex *)gWin[e1].f;
296 GrVertex *v2 = (GrVertex *)gWin[e2].f;
297 GLfloat w = ctx->Line.Width*.5;
298
299 if (IND & FX_FLAT)
300 {
301 FX_VB_COLOR(fxMesa, color[pv]);
302 if (IND & FX_ANTIALIAS)
303#if FX_USE_PARGB
304 {
305 GLuint v1argb = v1->argb;
306 GLuint v2argb = v2->argb;
307 v1->argb = (color[pv][ACOMP] << 24) | (v1argb & 0x00FFFFFF);
308 v2->argb = (color[pv][ACOMP] << 24) | (v2argb & 0x00FFFFFF);
309 }
310#else
311 v1->a = v2->a = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][3]);
312#endif
313 }
314 else if (IND & FX_TWOSIDE)
315 {
316 GOURAUD2(v1,color[e1]);
317 GOURAUD2(v2,color[e2]);
318 }
319
320 if (IND & FX_FRONT_BACK) {
321 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
322 ctx->Color.ColorMask[GCOMP] ||
323 ctx->Color.ColorMask[BCOMP],
324 FXFALSE);
325 FX_grDepthMask(FXFALSE);
326 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
327 }
328
329 if (IND & FX_ANTIALIAS)
330 FX_grAADrawLine(v1,v2);
331 else
332 DRAW_LINE(v1,v2,w);
333
334 if (IND & FX_FRONT_BACK)
335 {
336 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
337 ctx->Color.ColorMask[GCOMP] ||
338 ctx->Color.ColorMask[BCOMP],
339 ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
340
341 if(ctx->Depth.Mask)
342 FX_grDepthMask(FXTRUE);
343
344 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
345
346 if (IND & FX_ANTIALIAS)
347 FX_grAADrawLine(v1,v2);
348 else
349 DRAW_LINE(v1,v2,w);
350 }
351}
352#endif
353
354
355#if (IND & FX_OFFSET) == 0
356
357#if IND & FX_FLAT
358# if IND & FX_ANTIALIAS
359#if FX_USE_PARGB
360# define FLAT_COLOR(x,y) GET_PA(gWin[i].f) = y[3];
361#else
362# define FLAT_COLOR(x,y) gWin[i].f[ACOORD] = y[3]; \
363 FX_VB_COLOR(x, y)
364#endif
365# else
366# define FLAT_COLOR(x,y) FX_VB_COLOR(x, y)
367# endif
368#else
369#define FLAT_COLOR(x,y)
370#endif
371
372
373#define DRAW_POINT(i, sz) \
374 do { \
375 GrVertex verts[4], *tmp; \
376 \
377 tmp = (GrVertex*)gWin[i].f; \
378 verts[0] = *tmp; \
379 verts[1] = *tmp; \
380 verts[2] = *tmp; \
381 verts[3] = *tmp; \
382 verts[0].x = verts[3].x = tmp->x + sz; \
383 verts[0].y = verts[1].y = tmp->y + sz; \
384 verts[2].x = verts[1].x = tmp->x - sz; \
385 verts[2].y = verts[3].y = tmp->y - sz; \
386 \
387 FX_grDrawPolygonVertexList(4, verts); \
388 } while (0)
389
390static void TAG(fx_points)(GLcontext *ctx, GLuint first, GLuint last)
391{
392 fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
393 struct vertex_buffer *VB = ctx->VB;
394 fxVertex *gWin = FX_DRIVER_DATA(VB)->verts;
395 GLubyte (*color)[4] = VB->ColorPtr->data;
396 GLuint i;
397 GLfloat sz = ctx->Point.Size * .5;
398
399 (void) color; (void) fxMesa;
400
401 if (IND & FX_FRONT_BACK) {
402 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
403 ctx->Color.ColorMask[GCOMP] ||
404 ctx->Color.ColorMask[BCOMP],
405 FXFALSE);
406
407 FX_grDepthMask(FXFALSE);
408 FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
409 }
410
411 if(!VB->ClipOrMask) {
412 for(i=first;i<=last;i++) {
413 FLAT_COLOR(fxMesa, color[i]);
414 DRAW_POINT(i, sz);
415 }
416 } else {
417 for(i=first;i<=last;i++) {
418 if(VB->ClipMask[i]==0) {
419 FLAT_COLOR(fxMesa, color[i]);
420 DRAW_POINT(i, sz);
421 }
422 }
423 }
424
425 if (IND & FX_FRONT_BACK) {
426 FX_grColorMask(ctx->Color.ColorMask[RCOMP] ||
427 ctx->Color.ColorMask[GCOMP] ||
428 ctx->Color.ColorMask[BCOMP],
429 ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
430 if(ctx->Depth.Mask)
431 FX_grDepthMask(FXTRUE);
432 FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
433
434
435 if(!VB->ClipOrMask) {
436 for(i=first;i<=last;i++) {
437 FLAT_COLOR(fxMesa, color[i]);
438 DRAW_POINT(i, sz);
439 }
440 } else {
441 for(i=first;i<=last;i++) {
442 if(VB->ClipMask[i]==0) {
443 FLAT_COLOR(fxMesa, color[i]);
444 DRAW_POINT(i, sz);
445 }
446 }
447 }
448 }
449}
450
451#endif
452
453
454
455static void TAG(init)( void )
456{
457 tri_tab[IND] = TAG(fx_tri);
458 quad_tab[IND] = TAG(fx_quad);
459
460#if ((IND & FX_OFFSET) == 0)
461 line_tab[IND] = TAG(fx_line);
462 points_tab[IND] = TAG(fx_points);
463#else
464 line_tab[IND] = line_tab[IND & ~FX_OFFSET];
465 points_tab[IND] = points_tab[IND & ~FX_OFFSET];
466#endif
467}
468
469#undef IND
470#undef TAG
471#undef FLAT_COLOR
472#undef DRAW_POINT
Note: See TracBrowser for help on using the repository browser.