source: trunk/src/opengl/mesa/clip.c@ 3721

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

* empty log message *

File size: 15.5 KB
Line 
1/* $Id: clip.c,v 1.3 2000-05-23 20:40:25 jeroen Exp $ */
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
28
29
30
31#ifdef PC_HEADER
32#include "all.h"
33#else
34#include "glheader.h"
35#include "clip.h"
36#include "types.h"
37#include "context.h"
38#include "macros.h"
39#include "matrix.h"
40#include "mmath.h"
41#include "vb.h"
42#include "xform.h"
43#endif
44
45
46
47
48#define CLIP_RGBA0 0x1
49#define CLIP_RGBA1 0x2
50#define CLIP_TEX0 0x4
51#define CLIP_TEX1 0x8
52#define CLIP_INDEX0 0x10
53#define CLIP_INDEX1 0x20
54#define CLIP_FOG_COORD 0x40
55
56
57/* Linear interpolation between A and B: */
58#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) )
59
60
61
62#define INTERP_SZ( t, vec, to, a, b, sz ) \
63do { \
64 switch (sz) { \
65 case 4: vec[to][3] = LINTERP( t, vec[a][3], vec[b][3] ); \
66 case 3: vec[to][2] = LINTERP( t, vec[a][2], vec[b][2] ); \
67 case 2: vec[to][1] = LINTERP( t, vec[a][1], vec[b][1] ); \
68 case 1: vec[to][0] = LINTERP( t, vec[a][0], vec[b][0] ); \
69 } \
70} while(0)
71
72
73static clip_interp_func clip_interp_tab[0x80];
74
75#define IND 0
76#define NAME clip_nil
77#include "interp_tmp.h"
78
79#define IND (CLIP_RGBA0)
80#define NAME clipRGBA0
81#include "interp_tmp.h"
82
83#define IND (CLIP_RGBA0|CLIP_RGBA1)
84#define NAME clipRGBA0_RGBA1
85#include "interp_tmp.h"
86
87#define IND (CLIP_TEX0|CLIP_RGBA0)
88#define NAME clipTEX0_RGBA0
89#include "interp_tmp.h"
90
91#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1)
92#define NAME clipTEX0_RGBA0_RGBA1
93#include "interp_tmp.h"
94
95#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0)
96#define NAME clipTEX1_TEX0_RGBA0
97#include "interp_tmp.h"
98
99#define IND (CLIP_TEX0)
100#define NAME clipTEX0
101#include "interp_tmp.h"
102
103#define IND (CLIP_TEX1|CLIP_TEX0)
104#define NAME clipTEX1_TEX0
105#include "interp_tmp.h"
106
107#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1)
108#define NAME clipTEX1_TEX0_RGBA0_RGBA1
109#include "interp_tmp.h"
110
111#define IND (CLIP_INDEX0)
112#define NAME clipINDEX0
113#include "interp_tmp.h"
114
115#define IND (CLIP_INDEX0|CLIP_INDEX1)
116#define NAME clipINDEX0_INDEX1
117#include "interp_tmp.h"
118
119#define IND (CLIP_FOG_COORD)
120#define NAME clip_FOG
121#include "interp_tmp.h"
122
123#define IND (CLIP_RGBA0|CLIP_FOG_COORD)
124#define NAME clipRGBA0_FOG
125#include "interp_tmp.h"
126
127#define IND (CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD)
128#define NAME clipRGBA0_RGBA1_FOG
129#include "interp_tmp.h"
130
131#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD)
132#define NAME clipTEX0_RGBA0_FOG
133#include "interp_tmp.h"
134
135#define IND (CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD)
136#define NAME clipTEX0_RGBA0_RGBA1_FOG
137#include "interp_tmp.h"
138
139#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD)
140#define NAME clipTEX1_TEX0_RGBA0_FOG
141#include "interp_tmp.h"
142
143#define IND (CLIP_TEX0|CLIP_FOG_COORD)
144#define NAME clipTEX0_FOG
145#include "interp_tmp.h"
146
147#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_FOG_COORD)
148#define NAME clipTEX1_TEX0_FOG
149#include "interp_tmp.h"
150
151#define IND (CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD)
152#define NAME clipTEX1_TEX0_RGBA0_RGBA1_FOG
153#include "interp_tmp.h"
154
155#define IND (CLIP_INDEX0|CLIP_FOG_COORD)
156#define NAME clipINDEX0_FOG
157#include "interp_tmp.h"
158
159#define IND (CLIP_INDEX0|CLIP_INDEX1|CLIP_FOG_COORD)
160#define NAME clipINDEX0_INDEX1_FOG
161#include "interp_tmp.h"
162
163
164
165
166/**********************************************************************/
167/* Get/Set User clip-planes. */
168/**********************************************************************/
169
170
171
172void
173_mesa_ClipPlane( GLenum plane, const GLdouble *eq )
174{
175 GET_CURRENT_CONTEXT(ctx);
176 GLint p;
177 GLfloat equation[4];
178
179 equation[0] = eq[0];
180 equation[1] = eq[1];
181 equation[2] = eq[2];
182 equation[3] = eq[3];
183
184 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glClipPlane");
185
186 p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
187 if (p<0 || p>=MAX_CLIP_PLANES) {
188 gl_error( ctx, GL_INVALID_ENUM, "glClipPlane" );
189 return;
190 }
191
192 /*
193 * The equation is transformed by the transpose of the inverse of the
194 * current modelview matrix and stored in the resulting eye coordinates.
195 *
196 * KW: Eqn is then transformed to the current clip space, where user
197 * clipping now takes place. The clip-space equations are recalculated
198 * whenever the projection matrix changes.
199 */
200 if (ctx->ModelView.flags & MAT_DIRTY_ALL_OVER) {
201 gl_matrix_analyze( &ctx->ModelView );
202 }
203 gl_transform_vector( ctx->Transform.EyeUserPlane[p], equation,
204 ctx->ModelView.inv );
205
206
207 if (ctx->Transform.ClipEnabled[p]) {
208 ctx->NewState |= NEW_USER_CLIP;
209
210 if (ctx->ProjectionMatrix.flags & MAT_DIRTY_ALL_OVER) {
211 gl_matrix_analyze( &ctx->ProjectionMatrix );
212 }
213 gl_transform_vector( ctx->Transform.ClipUserPlane[p],
214 ctx->Transform.EyeUserPlane[p],
215 ctx->ProjectionMatrix.inv );
216 }
217}
218
219
220void gl_update_userclip( GLcontext *ctx )
221{
222 GLuint p;
223
224 for (p = 0 ; p < MAX_CLIP_PLANES ; p++) {
225 if (ctx->Transform.ClipEnabled[p]) {
226 gl_transform_vector( ctx->Transform.ClipUserPlane[p],
227 ctx->Transform.EyeUserPlane[p],
228 ctx->ProjectionMatrix.inv );
229 }
230 }
231}
232
233void
234_mesa_GetClipPlane( GLenum plane, GLdouble *equation )
235{
236 GET_CURRENT_CONTEXT(ctx);
237 GLint p;
238
239 ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetClipPlane");
240
241
242 p = (GLint) (plane - GL_CLIP_PLANE0);
243 if (p<0 || p>=MAX_CLIP_PLANES) {
244 gl_error( ctx, GL_INVALID_ENUM, "glGetClipPlane" );
245 return;
246 }
247
248 equation[0] = (GLdouble) ctx->Transform.EyeUserPlane[p][0];
249 equation[1] = (GLdouble) ctx->Transform.EyeUserPlane[p][1];
250 equation[2] = (GLdouble) ctx->Transform.EyeUserPlane[p][2];
251 equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3];
252}
253
254
255
256
257/**********************************************************************/
258/* View volume clipping. */
259/**********************************************************************/
260
261
262/*
263 * Clip a point against the view volume.
264 * Input: v - vertex-vector describing the point to clip
265 * Return: 0 = outside view volume
266 * 1 = inside view volume
267 */
268GLuint gl_viewclip_point( const GLfloat v[] )
269{
270 if ( v[0] > v[3] || v[0] < -v[3]
271 || v[1] > v[3] || v[1] < -v[3]
272 || v[2] > v[3] || v[2] < -v[3] ) {
273 return 0;
274 }
275 else {
276 return 1;
277 }
278}
279
280/*
281 * Clip a point against the user clipping planes.
282 * Input: v - vertex-vector describing the point to clip.
283 * Return: 0 = point was clipped
284 * 1 = point not clipped
285 */
286GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] )
287{
288 GLuint p;
289
290 for (p=0;p<MAX_CLIP_PLANES;p++) {
291 if (ctx->Transform.ClipEnabled[p]) {
292 GLfloat dot = v[0] * ctx->Transform.ClipUserPlane[p][0]
293 + v[1] * ctx->Transform.ClipUserPlane[p][1]
294 + v[2] * ctx->Transform.ClipUserPlane[p][2]
295 + v[3] * ctx->Transform.ClipUserPlane[p][3];
296 if (dot < 0.0F) {
297 return 0;
298 }
299 }
300 }
301
302 return 1;
303}
304
305
306
307
308#if defined(__i386__)
309#define NEGATIVE(x) ((*(int *)&x)<0)
310#else
311#define NEGATIVE(x) (x < 0)
312#endif
313
314
315static clip_poly_func gl_poly_clip_tab[2][5];
316static clip_line_func gl_line_clip_tab[2][5];
317
318#define W(i) coord[i][3]
319#define Z(i) coord[i][2]
320#define Y(i) coord[i][1]
321#define X(i) coord[i][0]
322#define SIZE 4
323#define IND 0
324#define TAG(x) x##_4
325#include "clip_funcs.h"
326
327#define W(i) 1.0
328#define Z(i) coord[i][2]
329#define Y(i) coord[i][1]
330#define X(i) coord[i][0]
331#define SIZE 3
332#define IND 0
333#define TAG(x) x##_3
334#include "clip_funcs.h"
335
336#define W(i) 1.0
337#define Z(i) 0.0
338#define Y(i) coord[i][1]
339#define X(i) coord[i][0]
340#define SIZE 2
341#define IND 0
342#define TAG(x) x##_2
343#include "clip_funcs.h"
344
345#define W(i) coord[i][3]
346#define Z(i) coord[i][2]
347#define Y(i) coord[i][1]
348#define X(i) coord[i][0]
349#define SIZE 4
350#define IND CLIP_TAB_EDGEFLAG
351#define TAG(x) x##_4_edgeflag
352#include "clip_funcs.h"
353
354#define W(i) 1.0
355#define Z(i) coord[i][2]
356#define Y(i) coord[i][1]
357#define X(i) coord[i][0]
358#define SIZE 3
359#define IND CLIP_TAB_EDGEFLAG
360#define TAG(x) x##_3_edgeflag
361#include "clip_funcs.h"
362
363#define W(i) 1.0
364#define Z(i) 0.0
365#define Y(i) coord[i][1]
366#define X(i) coord[i][0]
367#define SIZE 2
368#define IND CLIP_TAB_EDGEFLAG
369#define TAG(x) x##_2_edgeflag
370#include "clip_funcs.h"
371
372
373
374
375void gl_update_clipmask( GLcontext *ctx )
376{
377 GLuint mask = 0;
378
379 if (ctx->Visual->RGBAflag)
380 {
381 if (ctx->Light.ShadeModel==GL_SMOOTH)
382 {
383 mask |= CLIP_RGBA0;
384
385 if (ctx->TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_SEPERATE_SPECULAR))
386 mask |= CLIP_RGBA1;
387 }
388
389 if (ctx->Texture.ReallyEnabled & 0xf0)
390 mask |= CLIP_TEX1|CLIP_TEX0;
391
392 if (ctx->Texture.ReallyEnabled & 0xf)
393 mask |= CLIP_TEX0;
394 }
395 else if (ctx->Light.ShadeModel==GL_SMOOTH)
396 {
397 mask |= CLIP_INDEX0;
398
399 if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE)
400 mask |= CLIP_INDEX1;
401 }
402
403 if (ctx->FogMode == FOG_FRAGMENT && (ctx->TriangleCaps & DD_CLIP_FOG_COORD))
404 mask |= CLIP_FOG_COORD;
405
406 ctx->ClipInterpFunc = clip_interp_tab[mask];
407 ctx->poly_clip_tab = gl_poly_clip_tab[0];
408 ctx->line_clip_tab = gl_line_clip_tab[0];
409
410 if (ctx->TriangleCaps & DD_TRI_UNFILLED) {
411 ctx->poly_clip_tab = gl_poly_clip_tab[1];
412 ctx->line_clip_tab = gl_line_clip_tab[0];
413 }
414}
415
416
417#define USER_CLIPTEST(NAME, SZ) \
418static void NAME( struct vertex_buffer *VB ) \
419{ \
420 GLcontext *ctx = VB->ctx; \
421 GLubyte *clipMask = VB->ClipMask; \
422 GLubyte *userClipMask = VB->UserClipMask; \
423 GLuint start = VB->Start; \
424 GLuint count = VB->Count; \
425 GLuint p, i; \
426 GLubyte bit; \
427 \
428 \
429 for (bit = 1, p = 0; p < MAX_CLIP_PLANES ; p++, bit *=2) \
430 if (ctx->Transform.ClipEnabled[p]) { \
431 GLuint nr = 0; \
432 const GLfloat a = ctx->Transform.ClipUserPlane[p][0]; \
433 const GLfloat b = ctx->Transform.ClipUserPlane[p][1]; \
434 const GLfloat c = ctx->Transform.ClipUserPlane[p][2]; \
435 const GLfloat d = ctx->Transform.ClipUserPlane[p][3]; \
436 GLfloat *coord = VB->ClipPtr->start; \
437 GLuint stride = VB->ClipPtr->stride; \
438 \
439 for (i = start ; i < count ; i++, STRIDE_F(coord, stride)) { \
440 GLfloat dp = coord[0] * a + coord[1] * b; \
441 if (SZ > 2) dp += coord[2] * c; \
442 if (SZ > 3) dp += coord[3] * d; else dp += d; \
443 \
444 if (dp < 0) { \
445 clipMask[i] |= CLIP_USER_BIT; \
446 userClipMask[i] |= bit; \
447 nr++; \
448 } \
449 } \
450 \
451 if (nr > 0) { \
452 VB->ClipOrMask |= CLIP_USER_BIT; \
453 VB->CullMode |= CLIP_MASK_ACTIVE; \
454 if (nr == count - start) { \
455 VB->ClipAndMask |= CLIP_USER_BIT; \
456 VB->Culled = 1; \
457 return; \
458 } \
459 } \
460 } \
461}
462
463
464USER_CLIPTEST(userclip2, 2)
465USER_CLIPTEST(userclip3, 3)
466USER_CLIPTEST(userclip4, 4)
467
468static void (*(usercliptab[5]))( struct vertex_buffer * ) = {
469 0,
470 0,
471 userclip2,
472 userclip3,
473 userclip4
474};
475
476void gl_user_cliptest( struct vertex_buffer *VB )
477{
478 usercliptab[VB->ClipPtr->size]( VB );
479}
480
481
482void gl_init_clip(void)
483{
484 init_clip_funcs_4();
485 init_clip_funcs_3();
486 init_clip_funcs_2();
487
488 init_clip_funcs_4_edgeflag();
489 init_clip_funcs_3_edgeflag();
490 init_clip_funcs_2_edgeflag();
491
492 clip_interp_tab[0] = clip_nil;
493 clip_interp_tab[CLIP_RGBA0] = clipRGBA0;
494 clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1] = clipRGBA0_RGBA1;
495 clip_interp_tab[CLIP_TEX0|CLIP_RGBA0] = clipTEX0_RGBA0;
496 clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] = clipTEX0_RGBA0_RGBA1;
497 clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0] = clipTEX1_TEX0_RGBA0;
498 clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1] =
499 clipTEX1_TEX0_RGBA0_RGBA1;
500 clip_interp_tab[CLIP_TEX0] = clipTEX0;
501 clip_interp_tab[CLIP_TEX1|CLIP_TEX0] = clipTEX1_TEX0;
502 clip_interp_tab[CLIP_INDEX0] = clipINDEX0;
503 clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1] = clipINDEX0_INDEX1;
504
505 clip_interp_tab[CLIP_FOG_COORD] = clip_FOG;
506 clip_interp_tab[CLIP_RGBA0|CLIP_FOG_COORD] = clipRGBA0_FOG;
507 clip_interp_tab[CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = clipRGBA0_RGBA1_FOG;
508 clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD] = clipTEX0_RGBA0_FOG;
509 clip_interp_tab[CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] = clipTEX0_RGBA0_RGBA1_FOG;
510 clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_FOG_COORD] = clipTEX1_TEX0_RGBA0_FOG;
511 clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_RGBA0|CLIP_RGBA1|CLIP_FOG_COORD] =
512 clipTEX1_TEX0_RGBA0_RGBA1_FOG;
513 clip_interp_tab[CLIP_TEX0|CLIP_FOG_COORD] = clipTEX0_FOG;
514 clip_interp_tab[CLIP_TEX1|CLIP_TEX0|CLIP_FOG_COORD] = clipTEX1_TEX0_FOG;
515 clip_interp_tab[CLIP_INDEX0|CLIP_FOG_COORD] = clipINDEX0_FOG;
516 clip_interp_tab[CLIP_INDEX0|CLIP_INDEX1|CLIP_FOG_COORD] = clipINDEX0_INDEX1_FOG;
517}
518
Note: See TracBrowser for help on using the repository browser.