source: trunk/src/opengl/mesa/3dfx/fxclip.c

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

* empty log message *

File size: 19.2 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
46#ifdef HAVE_CONFIG_H
47#include "conf.h"
48#endif
49
50#if defined(FX)
51
52#include "fxdrv.h"
53#include "mmath.h"
54#include "macros.h"
55#include "vector.h"
56#include "types.h"
57
58
59#if 0 && defined(__i386__)
60#define NEGATIVE(f) ((*(int *)&f) < 0)
61#define DIFFERENT_SIGNS(a,b) (((*(int *)&a)^(*(int *)&b)) < 0)
62#else
63#define NEGATIVE(f) (f < 0)
64#define DIFFERENT_SIGNS(a,b) ((a*b) < 0)
65#endif
66
67#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) )
68
69
70#define CLIP(sgn,v) \
71do { \
72 GLuint out = in ^ 1; \
73 GLfloat **indata = inlist[in]; \
74 GrVertex **inverts = vertlist[in]; \
75 GrVertex **outverts = vertlist[out]; \
76 GLfloat **outdata = inlist[in = out]; \
77 GLfloat *J = indata[n-1]; \
78 GLfloat dpJ = (sgn J[v]) + J[3]; \
79 GLuint nr = n; \
80 \
81 for (i = n = 0 ; i < nr ; i++) { \
82 GLfloat *I = indata[i]; \
83 GLfloat dpI = (sgn I[v]) + I[3]; \
84 \
85 if (DIFFERENT_SIGNS(dpI, dpJ)) { \
86 GLuint j; \
87 GLfloat t = dpI / (dpI - dpJ); \
88 outverts[n] = 0; \
89 outdata[n++] = store; \
90 store[3] = LINTERP(t, I[3], J[3]); \
91 store[v] = - sgn store[3]; \
92 if (v != 0) store[0] = LINTERP(t, I[0], J[0]); \
93 if (v != 1) store[1] = LINTERP(t, I[1], J[1]); \
94 if (v != 2) store[2] = LINTERP(t, I[2], J[2]); \
95 store += 4; \
96 for (j = 4 ; j < sz ; j+=4,store+=4) { \
97 store[0] = LINTERP(t, I[j], J[j] ); \
98 store[1] = LINTERP(t, I[j+1], J[j+1] ); \
99 store[2] = LINTERP(t, I[j+2], J[j+2] ); \
100 store[3] = LINTERP(t, I[j+3], J[j+3] ); \
101 } \
102 } \
103 \
104 if (!NEGATIVE(dpI)) { \
105 outverts[n] = inverts[i]; \
106 outdata[n++] = I; \
107 } \
108 \
109 \
110 J = I; \
111 dpJ = dpI; \
112 } \
113 \
114 if (n < 3) return 0; \
115} while (0)
116
117
118/* Originally used this for the viewclip planes as well, as in
119 * CLIP(-1,0,0,1), which was just as fast, but tended to lead to
120 * cracks. I haven't figured out exactly why this is, but the above
121 * code only really differs in the way it sets store[v] to +- w.
122 */
123#define UCLIP(a,b,c,d) \
124do { \
125 GLuint out = in ^ 1; \
126 GLfloat **indata = inlist[in]; \
127 GrVertex **inverts = vertlist[in]; \
128 GrVertex **outverts = vertlist[out]; \
129 GLfloat **outdata = inlist[in = out]; \
130 GLfloat *J = indata[n-1]; \
131 GLfloat dpJ = DOT4V(J,a,b,c,d); \
132 GLuint nr = n; \
133 \
134 for (i = n = 0 ; i < nr ; i++) { \
135 GLfloat *I = indata[i]; \
136 GLfloat dpI = DOT4V(I,a,b,c,d); \
137 \
138 if (DIFFERENT_SIGNS(dpI, dpJ)) { \
139 GLuint j; \
140 GLfloat t = dpI / (dpI - dpJ); \
141 outverts[n] = 0; \
142 outdata[n++] = store; \
143 for (j = 0 ; j < sz ; j+=4,store+=4) { \
144 store[0] = LINTERP(t, I[j], J[j] ); \
145 store[1] = LINTERP(t, I[j+1], J[j+1] ); \
146 store[2] = LINTERP(t, I[j+2], J[j+2] ); \
147 store[3] = LINTERP(t, I[j+3], J[j+3] ); \
148 } \
149 } \
150 \
151 if (!NEGATIVE(dpI)) { \
152 outverts[n] = inverts[i]; \
153 outdata[n++] = I; \
154 } \
155 \
156 \
157 J = I; \
158 dpJ = dpI; \
159 } \
160 \
161 if (n < 3) return 0; \
162} while (0)
163
164
165
166/* Data parameter is organized as 4 clip coordinates followed by an
167 * arbitary number (sz-4) of additional data. The three original
168 * vertices are packed together at the start, and there is room for at
169 * least VB_MAX_CLIPPED_VERTS vertices of the same size in this
170 * storage.
171 *
172 */
173static INLINE GLuint fx_clip_triangle( GLcontext *ctx,
174 GLfloat *inoutlist[],
175 GrVertex **verts,
176 GLuint sz,
177 GLuint mask )
178{
179 GLuint n = 3;
180 GLfloat *store = inoutlist[n-1] + sz;
181 GLfloat *vlist[VB_MAX_CLIPPED_VERTS];
182 GrVertex *verts2[VB_MAX_CLIPPED_VERTS];
183 GLfloat **inlist[2];
184 GrVertex **vertlist[2];
185 GLuint in = 0;
186 GLuint i;
187
188 inlist[0] = inoutlist;
189 inlist[1] = vlist;
190
191 vertlist[0] = verts;
192 vertlist[1] = verts2;
193
194 if (mask & CLIP_ALL_BITS)
195 {
196 if (mask & CLIP_RIGHT_BIT)
197 CLIP(-,0);
198
199 if (mask & CLIP_LEFT_BIT)
200 CLIP(+,0);
201
202 if (mask & CLIP_TOP_BIT)
203 CLIP(-,1);
204
205 if (mask & CLIP_BOTTOM_BIT)
206 CLIP(+,1);
207
208 if (mask & CLIP_FAR_BIT)
209 CLIP(-,2);
210
211 if (mask & CLIP_NEAR_BIT)
212 CLIP(+,2);
213 }
214
215 if (mask & CLIP_USER_BIT) {
216 GLuint bit;
217 GLfloat (*plane)[4] = &ctx->Transform.ClipUserPlane[0];
218 for (bit = 0x100 ; bit < mask ; plane++, bit *= 2) {
219 if (mask & bit) {
220 GLfloat a = plane[0][0];
221 GLfloat b = plane[0][1];
222 GLfloat c = plane[0][2];
223 GLfloat d = plane[0][3];
224 UCLIP(a,b,c,d);
225 }
226 }
227 }
228
229 if (inlist[in] != inoutlist)
230 for (i = 0 ; i < n ; i++) {
231 inoutlist[i] = inlist[in][i];
232 verts[i] = verts2[i];
233 }
234
235 return n;
236}
237
238
239
240static INLINE GLuint fx_view_clip_triangle( GLcontext *ctx,
241 GLfloat *inoutlist[],
242 GrVertex **verts,
243 GLuint sz,
244 GLubyte mask )
245{
246 GLuint n = 3;
247 GLfloat *store = inoutlist[n-1] + sz;
248 GLfloat *vlist[VB_MAX_CLIPPED_VERTS];
249 GrVertex *verts2[VB_MAX_CLIPPED_VERTS];
250 GLfloat **inlist[2];
251 GrVertex **vertlist[2];
252 GLuint in = 0;
253 GLuint i;
254
255 inlist[0] = inoutlist;
256 inlist[1] = vlist;
257
258 vertlist[0] = verts;
259 vertlist[1] = verts2;
260
261 if (mask & CLIP_RIGHT_BIT)
262 CLIP(-,0);
263
264 if (mask & CLIP_LEFT_BIT)
265 CLIP(+,0);
266
267 if (mask & CLIP_TOP_BIT)
268 CLIP(-,1);
269
270 if (mask & CLIP_BOTTOM_BIT)
271 CLIP(+,1);
272
273 if (mask & CLIP_FAR_BIT)
274 CLIP(-,2);
275
276 if (mask & CLIP_NEAR_BIT)
277 CLIP(+,2);
278
279 if (inlist[in] != inoutlist)
280 for (i = 0 ; i < n ; i++) {
281 inoutlist[i] = inlist[in][i];
282 verts[i] = verts2[i];
283 }
284
285 return n;
286}
287
288
289
290#undef CLIP
291
292#define CLIP(x,y,z,w) \
293do { \
294 GLfloat dpI = DOT4V(I,x,y,z,w); \
295 GLfloat dpJ = DOT4V(J,x,y,z,w); \
296 \
297 if (DIFFERENT_SIGNS(dpI, dpJ)) { \
298 GLuint j; \
299 GLfloat t = dpI / (dpI - dpJ); \
300 GLfloat *tmp = store; \
301 \
302 for (j = 0 ; j < sz ; j+=2) { \
303 *store++ = LINTERP(t, I[j], J[j] ); \
304 *store++ = LINTERP(t, I[j+1], J[j+1] ); \
305 } \
306 \
307 if (NEGATIVE(dpI)) \
308 I = tmp; \
309 else \
310 J = tmp; \
311 \
312 } \
313 else if (NEGATIVE(dpI)) \
314 return 0; \
315 \
316} while (0)
317
318
319static GLuint fx_clip_line( GLcontext *ctx,
320 GLfloat *inoutlist[],
321 GLuint sz,
322 GLubyte clipor )
323{
324 GLfloat *I = inoutlist[0];
325 GLfloat *J = inoutlist[1];
326 GLfloat *store = J + sz;
327
328 if (clipor & CLIP_ALL_BITS)
329 {
330 if (clipor & CLIP_LEFT_BIT)
331 CLIP(1,0,0,1);
332
333 if (clipor & CLIP_RIGHT_BIT)
334 CLIP(-1,0,0,1);
335
336 if (clipor & CLIP_TOP_BIT)
337 CLIP(0,-1,0,1);
338
339 if (clipor & CLIP_BOTTOM_BIT)
340 CLIP(0,1,0,1);
341
342 if (clipor & CLIP_FAR_BIT)
343 CLIP(0,0,-1,1);
344
345 if (clipor & CLIP_NEAR_BIT)
346 CLIP(0,0,1,1);
347 }
348
349 if (clipor & CLIP_USER_BIT) {
350 GLuint i;
351 for (i = 0 ; i < MAX_CLIP_PLANES ; i++) {
352 if (ctx->Transform.ClipEnabled[i]) {
353 GLfloat a = ctx->Transform.ClipUserPlane[i][0];
354 GLfloat b = ctx->Transform.ClipUserPlane[i][1];
355 GLfloat c = ctx->Transform.ClipUserPlane[i][2];
356 GLfloat d = ctx->Transform.ClipUserPlane[i][3];
357 CLIP(a,b,c,d);
358 }
359 }
360 }
361
362 inoutlist[0] = I;
363 inoutlist[1] = J;
364
365 return 2;
366}
367
368
369
370
371
372
373#if defined(FX_V2)
374
375#define VARS_XYZW \
376 GLfloat vsx = mat[MAT_SX]; \
377 GLfloat vsy = mat[MAT_SY]; \
378 GLfloat vsz = mat[MAT_SZ]; \
379 GLfloat vtx = mat[MAT_TX]; \
380 GLfloat vty = mat[MAT_TY]; \
381 GLfloat vtz = mat[MAT_TZ];
382
383#define DO_SETUP_XYZW \
384{ \
385 GLfloat oow = 1.0 / data[3]; \
386 v->x = data[0]*oow*vsx + vtx; \
387 v->y = data[1]*oow*vsy + vty; \
388 v->ooz = data[2]*oow*vsz + vtz; \
389 v->oow = oow; \
390}
391#else
392
393#if defined(DRIVERTS)
394
395#define VARS_XYZW \
396 GLfloat vsx = mat[MAT_SX]; \
397 GLfloat vsy = mat[MAT_SY]; \
398 GLfloat vsz = mat[MAT_SZ]; \
399 GLfloat vtx = mat[MAT_TX]+fxMesa->x_offset; \
400 GLfloat vty = mat[MAT_TY]+fxMesa->y_delta; \
401 GLfloat vtz = mat[MAT_TZ];
402
403#define DO_SETUP_XYZW \
404{ \
405 GLfloat oow = 1.0 / data[3]; \
406 v->x = data[0]*oow*vsx + vtx; \
407 v->y = data[1]*oow*vsy + vty; \
408 v->ooz = data[2]*oow*vsz + vtz; \
409 v->oow = oow; \
410}
411
412#else
413#define VARS_XYZW \
414 GLfloat vsx = mat[MAT_SX]; \
415 GLfloat vsy = mat[MAT_SY]; \
416 GLfloat vsz = mat[MAT_SZ]; \
417 const GLfloat snapper = (3L << 18); \
418 GLfloat snap_tx = mat[MAT_TX] + snapper; \
419 GLfloat snap_ty = mat[MAT_TY] + snapper; \
420 GLfloat vtz = mat[MAT_TZ];
421
422#define DO_SETUP_XYZW \
423{ \
424 GLfloat oow = 1.0 / data[3]; \
425 v->x = data[0]*oow*vsx + snap_tx; \
426 v->y = data[1]*oow*vsy + snap_ty; \
427 v->ooz = data[2]*oow*vsz + vtz; \
428 v->oow = oow; \
429 v->x -= snapper; \
430 v->y -= snapper; \
431}
432
433#endif
434#endif
435
436#define COPY_XYZW_STRIDE \
437 { GLfloat *clip = VEC_ELT(VB->ClipPtr, GLfloat, e); \
438 COPY_4FV(out, clip); }
439
440#define VARS_RGBA
441
442#define COPY_RGBA_STRIDE \
443 { GLubyte *color = VEC_ELT(VB->ColorPtr, GLubyte, e); \
444 UBYTE_RGBA_TO_FLOAT_255_RGBA((out+4), color); }
445
446#if FX_USE_PARGB
447#define DO_SETUP_RGBA \
448 GET_PARGB(v) = (((int)data[4+3]) << 24) | \
449 (((int)data[4+0]) << 16) | \
450 (((int)data[4+1]) << 8) | \
451 (((int)data[4+2]) << 0);
452#else
453#define DO_SETUP_RGBA \
454 v->r = data[4+0]; \
455 v->g = data[4+1]; \
456 v->b = data[4+2]; \
457 v->a = data[4+3];
458#endif /* FX_USE_PARGB */
459
460#define VARS_TMU0 \
461 struct gl_texture_unit *t0 = &ctx->Texture.Unit[tmu0_source]; \
462 GLfloat sScale0 = fxTMGetTexInfo(t0->Current)->sScale; \
463 GLfloat tScale0 = fxTMGetTexInfo(t0->Current)->tScale; \
464
465
466#define COPY_TMU0_STRIDE(offset) \
467 { GLfloat *tc0 = VEC_ELT(tc0_vec, GLfloat, e); \
468 COPY_2V((out+offset), tc0); }
469
470
471#define DO_SETUP_TMU0(offset) \
472 v->tmuvtx[0].sow = data[offset+0]*sScale0*v->oow; \
473 v->tmuvtx[0].tow = data[offset+1]*tScale0*v->oow;
474
475#define VARS_TMU1 \
476 struct gl_texture_unit *t1 = &ctx->Texture.Unit[tmu1_source]; \
477 GLfloat sScale1 = fxTMGetTexInfo(t1->Current)->sScale; \
478 GLfloat tScale1 = fxTMGetTexInfo(t1->Current)->tScale;
479
480#define COPY_TMU1_STRIDE(offset) \
481 { GLfloat *tc1 = VEC_ELT(tc1_vec, GLfloat, e); \
482 COPY_2V((out+offset), tc1); }
483
484
485#define DO_SETUP_TMU1(offset) \
486 v->tmuvtx[1].sow = data[offset+0]*sScale1*v->oow; \
487 v->tmuvtx[1].tow = data[offset+1]*tScale1*v->oow;
488
489#define COPY_NIL(offset) ASSIGN_2V((out+offset), 0, 0);
490
491#define IND 0
492#define TAG(x) x##_nil
493#include "fxcliptmp.h"
494
495#define IND SETUP_RGBA
496#define TAG(x) x##_RGBA
497#include "fxcliptmp.h"
498
499#define IND SETUP_TMU0
500#define TAG(x) x##_TMU0
501#include "fxcliptmp.h"
502
503#define IND (SETUP_TMU0|SETUP_TMU1)
504#define TAG(x) x##_TMU0_TMU1
505#include "fxcliptmp.h"
506
507#define IND (SETUP_RGBA|SETUP_TMU0)
508#define TAG(x) x##_RGBA_TMU0
509#include "fxcliptmp.h"
510
511#define IND (SETUP_RGBA|SETUP_TMU0|SETUP_TMU1)
512#define TAG(x) x##_RGBA_TMU0_TMU1
513#include "fxcliptmp.h"
514
515tfxTriViewClipFunc fxTriViewClipTab[0x8];
516tfxTriClipFunc fxTriClipStrideTab[0x8];
517tfxLineClipFunc fxLineClipTab[0x8];
518
519
520void fxDDClipInit()
521{
522 fxTriViewClipTab[0] = fx_tri_view_clip_nil;
523 fxTriViewClipTab[SETUP_RGBA] = fx_tri_view_clip_RGBA;
524 fxTriViewClipTab[SETUP_TMU0] = fx_tri_view_clip_TMU0;
525 fxTriViewClipTab[SETUP_TMU0|SETUP_TMU1] = fx_tri_view_clip_TMU0_TMU1;
526 fxTriViewClipTab[SETUP_RGBA|SETUP_TMU0] = fx_tri_view_clip_RGBA_TMU0;
527 fxTriViewClipTab[SETUP_RGBA|SETUP_TMU0|SETUP_TMU1] = fx_tri_view_clip_RGBA_TMU0_TMU1;
528
529 fxTriClipStrideTab[0] = fx_tri_clip_stride_nil;
530 fxTriClipStrideTab[SETUP_RGBA] = fx_tri_clip_stride_RGBA;
531 fxTriClipStrideTab[SETUP_TMU0] = fx_tri_clip_stride_TMU0;
532 fxTriClipStrideTab[SETUP_TMU0|SETUP_TMU1] = fx_tri_clip_stride_TMU0_TMU1;
533 fxTriClipStrideTab[SETUP_RGBA|SETUP_TMU0] = fx_tri_clip_stride_RGBA_TMU0;
534 fxTriClipStrideTab[SETUP_RGBA|SETUP_TMU0|SETUP_TMU1] = fx_tri_clip_stride_RGBA_TMU0_TMU1;
535
536 fxLineClipTab[0] = fx_line_clip_nil;
537 fxLineClipTab[SETUP_RGBA] = fx_line_clip_RGBA;
538 fxLineClipTab[SETUP_TMU0] = fx_line_clip_TMU0;
539 fxLineClipTab[SETUP_TMU0|SETUP_TMU1] = fx_line_clip_TMU0_TMU1;
540 fxLineClipTab[SETUP_RGBA|SETUP_TMU0] = fx_line_clip_RGBA_TMU0;
541 fxLineClipTab[SETUP_RGBA|SETUP_TMU0|SETUP_TMU1] = fx_line_clip_RGBA_TMU0_TMU1;
542}
543
544#else
545
546/*
547 * Need this to provide at least one external definition.
548 */
549int gl_fxclip_dummy(void)
550{
551 return 0;
552}
553
554#endif
Note: See TracBrowser for help on using the repository browser.