1*5f2bebf7SJérôme Gardou /* $Id: clip.c,v 1.16 1998/02/03 23:45:36 brianp Exp $ */
2*5f2bebf7SJérôme Gardou
3*5f2bebf7SJérôme Gardou /*
4*5f2bebf7SJérôme Gardou * Mesa 3-D graphics library
5*5f2bebf7SJérôme Gardou * Version: 2.6
6*5f2bebf7SJérôme Gardou * Copyright (C) 1995-1997 Brian Paul
7*5f2bebf7SJérôme Gardou *
8*5f2bebf7SJérôme Gardou * This library is free software; you can redistribute it and/or
9*5f2bebf7SJérôme Gardou * modify it under the terms of the GNU Library General Public
10*5f2bebf7SJérôme Gardou * License as published by the Free Software Foundation; either
11*5f2bebf7SJérôme Gardou * version 2 of the License, or (at your option) any later version.
12*5f2bebf7SJérôme Gardou *
13*5f2bebf7SJérôme Gardou * This library is distributed in the hope that it will be useful,
14*5f2bebf7SJérôme Gardou * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*5f2bebf7SJérôme Gardou * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16*5f2bebf7SJérôme Gardou * Library General Public License for more details.
17*5f2bebf7SJérôme Gardou *
18*5f2bebf7SJérôme Gardou * You should have received a copy of the GNU Library General Public
19*5f2bebf7SJérôme Gardou * License along with this library; if not, write to the Free
20*5f2bebf7SJérôme Gardou * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*5f2bebf7SJérôme Gardou */
22*5f2bebf7SJérôme Gardou
23*5f2bebf7SJérôme Gardou
24*5f2bebf7SJérôme Gardou /*
25*5f2bebf7SJérôme Gardou * $Log: clip.c,v $
26*5f2bebf7SJérôme Gardou * Revision 1.16 1998/02/03 23:45:36 brianp
27*5f2bebf7SJérôme Gardou * added space parameter to clip interpolation functions
28*5f2bebf7SJérôme Gardou *
29*5f2bebf7SJérôme Gardou * Revision 1.15 1998/01/06 02:40:52 brianp
30*5f2bebf7SJérôme Gardou * added DavidB's clipping interpolation optimization
31*5f2bebf7SJérôme Gardou *
32*5f2bebf7SJérôme Gardou * Revision 1.14 1997/07/24 01:24:45 brianp
33*5f2bebf7SJérôme Gardou * changed precompiled header symbol from PCH to PC_HEADER
34*5f2bebf7SJérôme Gardou *
35*5f2bebf7SJérôme Gardou * Revision 1.13 1997/05/28 03:23:48 brianp
36*5f2bebf7SJérôme Gardou * added precompiled header (PCH) support
37*5f2bebf7SJérôme Gardou *
38*5f2bebf7SJérôme Gardou * Revision 1.12 1997/04/02 03:10:06 brianp
39*5f2bebf7SJérôme Gardou * call gl_analyze_modelview_matrix instead of gl_compute_modelview_inverse
40*5f2bebf7SJérôme Gardou *
41*5f2bebf7SJérôme Gardou * Revision 1.11 1997/02/13 21:16:09 brianp
42*5f2bebf7SJérôme Gardou * if too many vertices in polygon return VB_SIZE-1, not VB_SIZE
43*5f2bebf7SJérôme Gardou *
44*5f2bebf7SJérôme Gardou * Revision 1.10 1997/02/10 21:16:12 brianp
45*5f2bebf7SJérôme Gardou * added checks in polygon clippers to prevent array overflows
46*5f2bebf7SJérôme Gardou *
47*5f2bebf7SJérôme Gardou * Revision 1.9 1997/02/04 19:39:39 brianp
48*5f2bebf7SJérôme Gardou * changed size of vlist2[] arrays to VB_SIZE per Randy Frank
49*5f2bebf7SJérôme Gardou *
50*5f2bebf7SJérôme Gardou * Revision 1.8 1996/12/02 20:10:07 brianp
51*5f2bebf7SJérôme Gardou * changed the macros in gl_viewclip_polygon() to be like gl_viewclip_line()
52*5f2bebf7SJérôme Gardou *
53*5f2bebf7SJérôme Gardou * Revision 1.7 1996/10/29 02:55:02 brianp
54*5f2bebf7SJérôme Gardou * fixed duplicate vertex bug in gl_viewclip_polygon()
55*5f2bebf7SJérôme Gardou *
56*5f2bebf7SJérôme Gardou * Revision 1.6 1996/10/07 23:48:33 brianp
57*5f2bebf7SJérôme Gardou * changed temporaries to GLdouble in gl_viewclip_polygon()
58*5f2bebf7SJérôme Gardou *
59*5f2bebf7SJérôme Gardou * Revision 1.5 1996/10/03 01:43:45 brianp
60*5f2bebf7SJérôme Gardou * changed INSIDE() macro in gl_viewclip_polygon() to work like other macros
61*5f2bebf7SJérôme Gardou *
62*5f2bebf7SJérôme Gardou * Revision 1.4 1996/10/03 01:36:33 brianp
63*5f2bebf7SJérôme Gardou * changed COMPUTE_INTERSECTION macros in gl_viewclip_polygon to avoid
64*5f2bebf7SJérôme Gardou * potential roundoff errors
65*5f2bebf7SJérôme Gardou *
66*5f2bebf7SJérôme Gardou * Revision 1.3 1996/09/27 01:24:23 brianp
67*5f2bebf7SJérôme Gardou * removed unused variables
68*5f2bebf7SJérôme Gardou *
69*5f2bebf7SJérôme Gardou * Revision 1.2 1996/09/15 01:48:58 brianp
70*5f2bebf7SJérôme Gardou * removed #define NULL 0
71*5f2bebf7SJérôme Gardou *
72*5f2bebf7SJérôme Gardou * Revision 1.1 1996/09/13 01:38:16 brianp
73*5f2bebf7SJérôme Gardou * Initial revision
74*5f2bebf7SJérôme Gardou *
75*5f2bebf7SJérôme Gardou */
76*5f2bebf7SJérôme Gardou
77*5f2bebf7SJérôme Gardou
78*5f2bebf7SJérôme Gardou #ifdef PC_HEADER
79*5f2bebf7SJérôme Gardou #include "all.h"
80*5f2bebf7SJérôme Gardou #else
81*5f2bebf7SJérôme Gardou #include <string.h>
82*5f2bebf7SJérôme Gardou #include "clip.h"
83*5f2bebf7SJérôme Gardou #include "context.h"
84*5f2bebf7SJérôme Gardou #include "dlist.h"
85*5f2bebf7SJérôme Gardou #include "macros.h"
86*5f2bebf7SJérôme Gardou #include "matrix.h"
87*5f2bebf7SJérôme Gardou #include "types.h"
88*5f2bebf7SJérôme Gardou #include "vb.h"
89*5f2bebf7SJérôme Gardou #include "xform.h"
90*5f2bebf7SJérôme Gardou #endif
91*5f2bebf7SJérôme Gardou
92*5f2bebf7SJérôme Gardou
93*5f2bebf7SJérôme Gardou
94*5f2bebf7SJérôme Gardou
95*5f2bebf7SJérôme Gardou /* Linear interpolation between A and B: */
96*5f2bebf7SJérôme Gardou #define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) )
97*5f2bebf7SJérôme Gardou
98*5f2bebf7SJérôme Gardou
99*5f2bebf7SJérôme Gardou /* Clipping coordinate spaces */
100*5f2bebf7SJérôme Gardou #define EYE_SPACE 1
101*5f2bebf7SJérôme Gardou #define CLIP_SPACE 2
102*5f2bebf7SJérôme Gardou
103*5f2bebf7SJérôme Gardou
104*5f2bebf7SJérôme Gardou
105*5f2bebf7SJérôme Gardou /*
106*5f2bebf7SJérôme Gardou * This function is used to interpolate colors, indexes, and texture
107*5f2bebf7SJérôme Gardou * coordinates when clipping has to be done. In general, we compute
108*5f2bebf7SJérôme Gardou * aux[dst] = aux[in] + t * (aux[out] - aux[in])
109*5f2bebf7SJérôme Gardou * where aux is the quantity to be interpolated.
110*5f2bebf7SJérôme Gardou * Input: space - either EYE_SPACE or CLIP_SPACE
111*5f2bebf7SJérôme Gardou * dst - index of array position to store interpolated value
112*5f2bebf7SJérôme Gardou * t - a value in [0,1]
113*5f2bebf7SJérôme Gardou * in - index of array position corresponding to 'inside' vertex
114*5f2bebf7SJérôme Gardou * out - index of array position corresponding to 'outside' vertex
115*5f2bebf7SJérôme Gardou */
interpolate_aux(GLcontext * ctx,GLuint space,GLuint dst,GLfloat t,GLuint in,GLuint out)116*5f2bebf7SJérôme Gardou void interpolate_aux( GLcontext* ctx, GLuint space,
117*5f2bebf7SJérôme Gardou GLuint dst, GLfloat t, GLuint in, GLuint out )
118*5f2bebf7SJérôme Gardou {
119*5f2bebf7SJérôme Gardou struct vertex_buffer* VB = ctx->VB;
120*5f2bebf7SJérôme Gardou
121*5f2bebf7SJérôme Gardou if (ctx->ClipMask & CLIP_FCOLOR_BIT) {
122*5f2bebf7SJérôme Gardou VB->Fcolor[dst][0] = LINTERP( t, VB->Fcolor[in][0], VB->Fcolor[out][0] );
123*5f2bebf7SJérôme Gardou VB->Fcolor[dst][1] = LINTERP( t, VB->Fcolor[in][1], VB->Fcolor[out][1] );
124*5f2bebf7SJérôme Gardou VB->Fcolor[dst][2] = LINTERP( t, VB->Fcolor[in][2], VB->Fcolor[out][2] );
125*5f2bebf7SJérôme Gardou VB->Fcolor[dst][3] = LINTERP( t, VB->Fcolor[in][3], VB->Fcolor[out][3] );
126*5f2bebf7SJérôme Gardou }
127*5f2bebf7SJérôme Gardou else if (ctx->ClipMask & CLIP_FINDEX_BIT) {
128*5f2bebf7SJérôme Gardou VB->Findex[dst] = (GLuint) (GLint) LINTERP( t, (GLfloat) VB->Findex[in],
129*5f2bebf7SJérôme Gardou (GLfloat) VB->Findex[out] );
130*5f2bebf7SJérôme Gardou }
131*5f2bebf7SJérôme Gardou
132*5f2bebf7SJérôme Gardou if (ctx->ClipMask & CLIP_BCOLOR_BIT) {
133*5f2bebf7SJérôme Gardou VB->Bcolor[dst][0] = LINTERP( t, VB->Bcolor[in][0], VB->Bcolor[out][0] );
134*5f2bebf7SJérôme Gardou VB->Bcolor[dst][1] = LINTERP( t, VB->Bcolor[in][1], VB->Bcolor[out][1] );
135*5f2bebf7SJérôme Gardou VB->Bcolor[dst][2] = LINTERP( t, VB->Bcolor[in][2], VB->Bcolor[out][2] );
136*5f2bebf7SJérôme Gardou VB->Bcolor[dst][3] = LINTERP( t, VB->Bcolor[in][3], VB->Bcolor[out][3] );
137*5f2bebf7SJérôme Gardou }
138*5f2bebf7SJérôme Gardou else if (ctx->ClipMask & CLIP_BINDEX_BIT) {
139*5f2bebf7SJérôme Gardou VB->Bindex[dst] = (GLuint) (GLint) LINTERP( t, (GLfloat) VB->Bindex[in],
140*5f2bebf7SJérôme Gardou (GLfloat) VB->Bindex[out] );
141*5f2bebf7SJérôme Gardou }
142*5f2bebf7SJérôme Gardou
143*5f2bebf7SJérôme Gardou if (ctx->ClipMask & CLIP_TEXTURE_BIT) {
144*5f2bebf7SJérôme Gardou /* TODO: is more sophisticated texture coord interpolation needed?? */
145*5f2bebf7SJérôme Gardou if (space==CLIP_SPACE) {
146*5f2bebf7SJérôme Gardou /* also interpolate eye Z component */
147*5f2bebf7SJérôme Gardou VB->Eye[dst][2] = LINTERP( t, VB->Eye[in][2], VB->Eye[out][2] );
148*5f2bebf7SJérôme Gardou }
149*5f2bebf7SJérôme Gardou VB->TexCoord[dst][0] = LINTERP(t,VB->TexCoord[in][0],VB->TexCoord[out][0]);
150*5f2bebf7SJérôme Gardou VB->TexCoord[dst][1] = LINTERP(t,VB->TexCoord[in][1],VB->TexCoord[out][1]);
151*5f2bebf7SJérôme Gardou VB->TexCoord[dst][2] = LINTERP(t,VB->TexCoord[in][2],VB->TexCoord[out][2]);
152*5f2bebf7SJérôme Gardou VB->TexCoord[dst][3] = LINTERP(t,VB->TexCoord[in][3],VB->TexCoord[out][3]);
153*5f2bebf7SJérôme Gardou }
154*5f2bebf7SJérôme Gardou
155*5f2bebf7SJérôme Gardou }
156*5f2bebf7SJérôme Gardou
157*5f2bebf7SJérôme Gardou
158*5f2bebf7SJérôme Gardou /*
159*5f2bebf7SJérôme Gardou * Some specialized version of the interpolate_aux
160*5f2bebf7SJérôme Gardou *
161*5f2bebf7SJérôme Gardou */
162*5f2bebf7SJérôme Gardou
interpolate_aux_color_tex2(GLcontext * ctx,GLuint space,GLuint dst,GLfloat t,GLuint in,GLuint out)163*5f2bebf7SJérôme Gardou void interpolate_aux_color_tex2( GLcontext* ctx, GLuint space,
164*5f2bebf7SJérôme Gardou GLuint dst, GLfloat t, GLuint in, GLuint out )
165*5f2bebf7SJérôme Gardou {
166*5f2bebf7SJérôme Gardou struct vertex_buffer* VB = ctx->VB;
167*5f2bebf7SJérôme Gardou
168*5f2bebf7SJérôme Gardou VB->Fcolor[dst][0] = LINTERP( t, VB->Fcolor[in][0], VB->Fcolor[out][0] );
169*5f2bebf7SJérôme Gardou VB->Fcolor[dst][1] = LINTERP( t, VB->Fcolor[in][1], VB->Fcolor[out][1] );
170*5f2bebf7SJérôme Gardou VB->Fcolor[dst][2] = LINTERP( t, VB->Fcolor[in][2], VB->Fcolor[out][2] );
171*5f2bebf7SJérôme Gardou VB->Fcolor[dst][3] = LINTERP( t, VB->Fcolor[in][3], VB->Fcolor[out][3] );
172*5f2bebf7SJérôme Gardou
173*5f2bebf7SJérôme Gardou VB->Eye[dst][2] = LINTERP( t, VB->Eye[in][2], VB->Eye[out][2] );
174*5f2bebf7SJérôme Gardou VB->TexCoord[dst][0] = LINTERP(t,VB->TexCoord[in][0],VB->TexCoord[out][0]);
175*5f2bebf7SJérôme Gardou VB->TexCoord[dst][1] = LINTERP(t,VB->TexCoord[in][1],VB->TexCoord[out][1]);
176*5f2bebf7SJérôme Gardou }
177*5f2bebf7SJérôme Gardou
178*5f2bebf7SJérôme Gardou
interpolate_aux_tex2(GLcontext * ctx,GLuint space,GLuint dst,GLfloat t,GLuint in,GLuint out)179*5f2bebf7SJérôme Gardou void interpolate_aux_tex2( GLcontext* ctx, GLuint space,
180*5f2bebf7SJérôme Gardou GLuint dst, GLfloat t, GLuint in, GLuint out )
181*5f2bebf7SJérôme Gardou {
182*5f2bebf7SJérôme Gardou struct vertex_buffer* VB = ctx->VB;
183*5f2bebf7SJérôme Gardou
184*5f2bebf7SJérôme Gardou VB->Eye[dst][2] = LINTERP( t, VB->Eye[in][2], VB->Eye[out][2] );
185*5f2bebf7SJérôme Gardou VB->TexCoord[dst][0] = LINTERP(t,VB->TexCoord[in][0],VB->TexCoord[out][0]);
186*5f2bebf7SJérôme Gardou VB->TexCoord[dst][1] = LINTERP(t,VB->TexCoord[in][1],VB->TexCoord[out][1]);
187*5f2bebf7SJérôme Gardou }
188*5f2bebf7SJérôme Gardou
189*5f2bebf7SJérôme Gardou
interpolate_aux_color(GLcontext * ctx,GLuint space,GLuint dst,GLfloat t,GLuint in,GLuint out)190*5f2bebf7SJérôme Gardou void interpolate_aux_color( GLcontext* ctx, GLuint space,
191*5f2bebf7SJérôme Gardou GLuint dst, GLfloat t, GLuint in, GLuint out )
192*5f2bebf7SJérôme Gardou {
193*5f2bebf7SJérôme Gardou struct vertex_buffer* VB = ctx->VB;
194*5f2bebf7SJérôme Gardou
195*5f2bebf7SJérôme Gardou VB->Fcolor[dst][0] = LINTERP( t, VB->Fcolor[in][0], VB->Fcolor[out][0] );
196*5f2bebf7SJérôme Gardou VB->Fcolor[dst][1] = LINTERP( t, VB->Fcolor[in][1], VB->Fcolor[out][1] );
197*5f2bebf7SJérôme Gardou VB->Fcolor[dst][2] = LINTERP( t, VB->Fcolor[in][2], VB->Fcolor[out][2] );
198*5f2bebf7SJérôme Gardou VB->Fcolor[dst][3] = LINTERP( t, VB->Fcolor[in][3], VB->Fcolor[out][3] );
199*5f2bebf7SJérôme Gardou }
200*5f2bebf7SJérôme Gardou
201*5f2bebf7SJérôme Gardou
202*5f2bebf7SJérôme Gardou
203*5f2bebf7SJérôme Gardou
gl_ClipPlane(GLcontext * ctx,GLenum plane,const GLfloat * equation)204*5f2bebf7SJérôme Gardou void gl_ClipPlane( GLcontext* ctx, GLenum plane, const GLfloat *equation )
205*5f2bebf7SJérôme Gardou {
206*5f2bebf7SJérôme Gardou GLint p;
207*5f2bebf7SJérôme Gardou
208*5f2bebf7SJérôme Gardou p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
209*5f2bebf7SJérôme Gardou if (p<0 || p>=MAX_CLIP_PLANES) {
210*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_ENUM, "glClipPlane" );
211*5f2bebf7SJérôme Gardou return;
212*5f2bebf7SJérôme Gardou }
213*5f2bebf7SJérôme Gardou
214*5f2bebf7SJérôme Gardou /*
215*5f2bebf7SJérôme Gardou * The equation is transformed by the transpose of the inverse of the
216*5f2bebf7SJérôme Gardou * current modelview matrix and stored in the resulting eye coordinates.
217*5f2bebf7SJérôme Gardou */
218*5f2bebf7SJérôme Gardou if (ctx->NewModelViewMatrix) {
219*5f2bebf7SJérôme Gardou gl_analyze_modelview_matrix(ctx);
220*5f2bebf7SJérôme Gardou }
221*5f2bebf7SJérôme Gardou gl_transform_vector( ctx->Transform.ClipEquation[p], equation,
222*5f2bebf7SJérôme Gardou ctx->ModelViewInv );
223*5f2bebf7SJérôme Gardou }
224*5f2bebf7SJérôme Gardou
225*5f2bebf7SJérôme Gardou
226*5f2bebf7SJérôme Gardou
gl_GetClipPlane(GLcontext * ctx,GLenum plane,GLdouble * equation)227*5f2bebf7SJérôme Gardou void gl_GetClipPlane( GLcontext* ctx, GLenum plane, GLdouble *equation )
228*5f2bebf7SJérôme Gardou {
229*5f2bebf7SJérôme Gardou GLint p;
230*5f2bebf7SJérôme Gardou
231*5f2bebf7SJérôme Gardou if (INSIDE_BEGIN_END(ctx)) {
232*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_OPERATION, "glGetClipPlane" );
233*5f2bebf7SJérôme Gardou return;
234*5f2bebf7SJérôme Gardou }
235*5f2bebf7SJérôme Gardou
236*5f2bebf7SJérôme Gardou p = (GLint) (plane - GL_CLIP_PLANE0);
237*5f2bebf7SJérôme Gardou if (p<0 || p>=MAX_CLIP_PLANES) {
238*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_ENUM, "glGetClipPlane" );
239*5f2bebf7SJérôme Gardou return;
240*5f2bebf7SJérôme Gardou }
241*5f2bebf7SJérôme Gardou
242*5f2bebf7SJérôme Gardou equation[0] = (GLdouble) ctx->Transform.ClipEquation[p][0];
243*5f2bebf7SJérôme Gardou equation[1] = (GLdouble) ctx->Transform.ClipEquation[p][1];
244*5f2bebf7SJérôme Gardou equation[2] = (GLdouble) ctx->Transform.ClipEquation[p][2];
245*5f2bebf7SJérôme Gardou equation[3] = (GLdouble) ctx->Transform.ClipEquation[p][3];
246*5f2bebf7SJérôme Gardou }
247*5f2bebf7SJérôme Gardou
248*5f2bebf7SJérôme Gardou
249*5f2bebf7SJérôme Gardou
250*5f2bebf7SJérôme Gardou
251*5f2bebf7SJérôme Gardou /**********************************************************************/
252*5f2bebf7SJérôme Gardou /* View volume clipping. */
253*5f2bebf7SJérôme Gardou /**********************************************************************/
254*5f2bebf7SJérôme Gardou
255*5f2bebf7SJérôme Gardou
256*5f2bebf7SJérôme Gardou /*
257*5f2bebf7SJérôme Gardou * Clip a point against the view volume.
258*5f2bebf7SJérôme Gardou * Input: v - vertex-vector describing the point to clip
259*5f2bebf7SJérôme Gardou * Return: 0 = outside view volume
260*5f2bebf7SJérôme Gardou * 1 = inside view volume
261*5f2bebf7SJérôme Gardou */
gl_viewclip_point(const GLfloat v[])262*5f2bebf7SJérôme Gardou GLuint gl_viewclip_point( const GLfloat v[] )
263*5f2bebf7SJérôme Gardou {
264*5f2bebf7SJérôme Gardou if ( v[0] > v[3] || v[0] < -v[3]
265*5f2bebf7SJérôme Gardou || v[1] > v[3] || v[1] < -v[3]
266*5f2bebf7SJérôme Gardou || v[2] > v[3] || v[2] < -v[3] ) {
267*5f2bebf7SJérôme Gardou return 0;
268*5f2bebf7SJérôme Gardou }
269*5f2bebf7SJérôme Gardou else {
270*5f2bebf7SJérôme Gardou return 1;
271*5f2bebf7SJérôme Gardou }
272*5f2bebf7SJérôme Gardou }
273*5f2bebf7SJérôme Gardou
274*5f2bebf7SJérôme Gardou
275*5f2bebf7SJérôme Gardou
276*5f2bebf7SJérôme Gardou
277*5f2bebf7SJérôme Gardou /*
278*5f2bebf7SJérôme Gardou * Clip a line segment against the view volume defined by -w<=x,y,z<=w.
279*5f2bebf7SJérôme Gardou * Input: i, j - indexes into VB->V* of endpoints of the line
280*5f2bebf7SJérôme Gardou * Return: 0 = line completely outside of view
281*5f2bebf7SJérôme Gardou * 1 = line is inside view.
282*5f2bebf7SJérôme Gardou */
gl_viewclip_line(GLcontext * ctx,GLuint * i,GLuint * j)283*5f2bebf7SJérôme Gardou GLuint gl_viewclip_line( GLcontext* ctx, GLuint *i, GLuint *j )
284*5f2bebf7SJérôme Gardou {
285*5f2bebf7SJérôme Gardou struct vertex_buffer* VB = ctx->VB;
286*5f2bebf7SJérôme Gardou GLfloat (*coord)[4] = VB->Clip;
287*5f2bebf7SJérôme Gardou
288*5f2bebf7SJérôme Gardou GLfloat t, dx, dy, dz, dw;
289*5f2bebf7SJérôme Gardou register GLuint ii, jj;
290*5f2bebf7SJérôme Gardou
291*5f2bebf7SJérôme Gardou ii = *i;
292*5f2bebf7SJérôme Gardou jj = *j;
293*5f2bebf7SJérôme Gardou
294*5f2bebf7SJérôme Gardou /*
295*5f2bebf7SJérôme Gardou * We use 6 instances of this code to clip agains the 6 planes.
296*5f2bebf7SJérôme Gardou * For each plane, we define the OUTSIDE and COMPUTE_INTERSECTION
297*5f2bebf7SJérôme Gardou * macros apprpriately.
298*5f2bebf7SJérôme Gardou */
299*5f2bebf7SJérôme Gardou #define GENERAL_CLIP \
300*5f2bebf7SJérôme Gardou if (OUTSIDE(ii)) { \
301*5f2bebf7SJérôme Gardou if (OUTSIDE(jj)) { \
302*5f2bebf7SJérôme Gardou /* both verts are outside ==> return 0 */ \
303*5f2bebf7SJérôme Gardou return 0; \
304*5f2bebf7SJérôme Gardou } \
305*5f2bebf7SJérôme Gardou else { \
306*5f2bebf7SJérôme Gardou /* ii is outside, jj is inside ==> clip */ \
307*5f2bebf7SJérôme Gardou /* new vertex put in position VB->Free */ \
308*5f2bebf7SJérôme Gardou COMPUTE_INTERSECTION( VB->Free, jj, ii ) \
309*5f2bebf7SJérôme Gardou if (ctx->ClipMask) \
310*5f2bebf7SJérôme Gardou ctx->ClipInterpAuxFunc( ctx, CLIP_SPACE, VB->Free, t, jj, ii );\
311*5f2bebf7SJérôme Gardou ii = VB->Free; \
312*5f2bebf7SJérôme Gardou VB->Free++; \
313*5f2bebf7SJérôme Gardou if (VB->Free==VB_SIZE) VB->Free = 1; \
314*5f2bebf7SJérôme Gardou } \
315*5f2bebf7SJérôme Gardou } \
316*5f2bebf7SJérôme Gardou else { \
317*5f2bebf7SJérôme Gardou if (OUTSIDE(jj)) { \
318*5f2bebf7SJérôme Gardou /* ii is inside, jj is outside ==> clip */ \
319*5f2bebf7SJérôme Gardou /* new vertex put in position VB->Free */ \
320*5f2bebf7SJérôme Gardou COMPUTE_INTERSECTION( VB->Free, ii, jj ); \
321*5f2bebf7SJérôme Gardou if (ctx->ClipMask) \
322*5f2bebf7SJérôme Gardou ctx->ClipInterpAuxFunc( ctx, CLIP_SPACE, VB->Free, t, ii, jj );\
323*5f2bebf7SJérôme Gardou jj = VB->Free; \
324*5f2bebf7SJérôme Gardou VB->Free++; \
325*5f2bebf7SJérôme Gardou if (VB->Free==VB_SIZE) VB->Free = 1; \
326*5f2bebf7SJérôme Gardou } \
327*5f2bebf7SJérôme Gardou /* else both verts are inside ==> do nothing */ \
328*5f2bebf7SJérôme Gardou }
329*5f2bebf7SJérôme Gardou
330*5f2bebf7SJérôme Gardou
331*5f2bebf7SJérôme Gardou #define X(I) coord[I][0]
332*5f2bebf7SJérôme Gardou #define Y(I) coord[I][1]
333*5f2bebf7SJérôme Gardou #define Z(I) coord[I][2]
334*5f2bebf7SJérôme Gardou #define W(I) coord[I][3]
335*5f2bebf7SJérôme Gardou
336*5f2bebf7SJérôme Gardou /*
337*5f2bebf7SJérôme Gardou * Begin clipping
338*5f2bebf7SJérôme Gardou */
339*5f2bebf7SJérôme Gardou
340*5f2bebf7SJérôme Gardou /*** Clip against +X side ***/
341*5f2bebf7SJérôme Gardou #define OUTSIDE(K) (X(K) > W(K))
342*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( new, in, out ) \
343*5f2bebf7SJérôme Gardou dx = X(out) - X(in); \
344*5f2bebf7SJérôme Gardou dw = W(out) - W(in); \
345*5f2bebf7SJérôme Gardou t = (X(in) - W(in)) / (dw-dx); \
346*5f2bebf7SJérôme Gardou X(new) = X(in) + t * dx; \
347*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * (Y(out) - Y(in)); \
348*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * (Z(out) - Z(in)); \
349*5f2bebf7SJérôme Gardou W(new) = W(in) + t * dw;
350*5f2bebf7SJérôme Gardou
351*5f2bebf7SJérôme Gardou GENERAL_CLIP
352*5f2bebf7SJérôme Gardou
353*5f2bebf7SJérôme Gardou #undef OUTSIDE
354*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
355*5f2bebf7SJérôme Gardou
356*5f2bebf7SJérôme Gardou
357*5f2bebf7SJérôme Gardou /*** Clip against -X side ***/
358*5f2bebf7SJérôme Gardou #define OUTSIDE(K) (X(K) < -W(K))
359*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( new, in, out ) \
360*5f2bebf7SJérôme Gardou dx = X(out) - X(in); \
361*5f2bebf7SJérôme Gardou dw = W(out) - W(in); \
362*5f2bebf7SJérôme Gardou t = -(X(in) + W(in)) / (dw+dx); \
363*5f2bebf7SJérôme Gardou X(new) = X(in) + t * dx; \
364*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * (Y(out) - Y(in)); \
365*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * (Z(out) - Z(in)); \
366*5f2bebf7SJérôme Gardou W(new) = W(in) + t * dw;
367*5f2bebf7SJérôme Gardou
368*5f2bebf7SJérôme Gardou GENERAL_CLIP
369*5f2bebf7SJérôme Gardou
370*5f2bebf7SJérôme Gardou #undef OUTSIDE
371*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
372*5f2bebf7SJérôme Gardou
373*5f2bebf7SJérôme Gardou
374*5f2bebf7SJérôme Gardou /*** Clip against +Y side ***/
375*5f2bebf7SJérôme Gardou #define OUTSIDE(K) (Y(K) > W(K))
376*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( new, in, out ) \
377*5f2bebf7SJérôme Gardou dy = Y(out) - Y(in); \
378*5f2bebf7SJérôme Gardou dw = W(out) - W(in); \
379*5f2bebf7SJérôme Gardou t = (Y(in) - W(in)) / (dw-dy); \
380*5f2bebf7SJérôme Gardou X(new) = X(in) + t * (X(out) - X(in)); \
381*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * dy; \
382*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * (Z(out) - Z(in)); \
383*5f2bebf7SJérôme Gardou W(new) = W(in) + t * dw;
384*5f2bebf7SJérôme Gardou
385*5f2bebf7SJérôme Gardou GENERAL_CLIP
386*5f2bebf7SJérôme Gardou
387*5f2bebf7SJérôme Gardou #undef OUTSIDE
388*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
389*5f2bebf7SJérôme Gardou
390*5f2bebf7SJérôme Gardou
391*5f2bebf7SJérôme Gardou /*** Clip against -Y side ***/
392*5f2bebf7SJérôme Gardou #define OUTSIDE(K) (Y(K) < -W(K))
393*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( new, in, out ) \
394*5f2bebf7SJérôme Gardou dy = Y(out) - Y(in); \
395*5f2bebf7SJérôme Gardou dw = W(out) - W(in); \
396*5f2bebf7SJérôme Gardou t = -(Y(in) + W(in)) / (dw+dy); \
397*5f2bebf7SJérôme Gardou X(new) = X(in) + t * (X(out) - X(in)); \
398*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * dy; \
399*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * (Z(out) - Z(in)); \
400*5f2bebf7SJérôme Gardou W(new) = W(in) + t * dw;
401*5f2bebf7SJérôme Gardou
402*5f2bebf7SJérôme Gardou GENERAL_CLIP
403*5f2bebf7SJérôme Gardou
404*5f2bebf7SJérôme Gardou #undef OUTSIDE
405*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
406*5f2bebf7SJérôme Gardou
407*5f2bebf7SJérôme Gardou
408*5f2bebf7SJérôme Gardou /*** Clip against +Z side ***/
409*5f2bebf7SJérôme Gardou #define OUTSIDE(K) (Z(K) > W(K))
410*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( new, in, out ) \
411*5f2bebf7SJérôme Gardou dz = Z(out) - Z(in); \
412*5f2bebf7SJérôme Gardou dw = W(out) - W(in); \
413*5f2bebf7SJérôme Gardou t = (Z(in) - W(in)) / (dw-dz); \
414*5f2bebf7SJérôme Gardou X(new) = X(in) + t * (X(out) - X(in)); \
415*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * (Y(out) - Y(in)); \
416*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * dz; \
417*5f2bebf7SJérôme Gardou W(new) = W(in) + t * dw;
418*5f2bebf7SJérôme Gardou
419*5f2bebf7SJérôme Gardou GENERAL_CLIP
420*5f2bebf7SJérôme Gardou
421*5f2bebf7SJérôme Gardou #undef OUTSIDE
422*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
423*5f2bebf7SJérôme Gardou
424*5f2bebf7SJérôme Gardou
425*5f2bebf7SJérôme Gardou /*** Clip against -Z side ***/
426*5f2bebf7SJérôme Gardou #define OUTSIDE(K) (Z(K) < -W(K))
427*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( new, in, out ) \
428*5f2bebf7SJérôme Gardou dz = Z(out) - Z(in); \
429*5f2bebf7SJérôme Gardou dw = W(out) - W(in); \
430*5f2bebf7SJérôme Gardou t = -(Z(in) + W(in)) / (dw+dz); \
431*5f2bebf7SJérôme Gardou X(new) = X(in) + t * (X(out) - X(in)); \
432*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * (Y(out) - Y(in)); \
433*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * dz; \
434*5f2bebf7SJérôme Gardou W(new) = W(in) + t * dw;
435*5f2bebf7SJérôme Gardou
436*5f2bebf7SJérôme Gardou GENERAL_CLIP
437*5f2bebf7SJérôme Gardou
438*5f2bebf7SJérôme Gardou #undef OUTSIDE
439*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
440*5f2bebf7SJérôme Gardou
441*5f2bebf7SJérôme Gardou #undef GENERAL_CLIP
442*5f2bebf7SJérôme Gardou
443*5f2bebf7SJérôme Gardou *i = ii;
444*5f2bebf7SJérôme Gardou *j = jj;
445*5f2bebf7SJérôme Gardou return 1;
446*5f2bebf7SJérôme Gardou }
447*5f2bebf7SJérôme Gardou
448*5f2bebf7SJérôme Gardou
449*5f2bebf7SJérôme Gardou
450*5f2bebf7SJérôme Gardou
451*5f2bebf7SJérôme Gardou /*
452*5f2bebf7SJérôme Gardou * Clip a polygon against the view volume defined by -w<=x,y,z<=w.
453*5f2bebf7SJérôme Gardou * Input: n - number of vertices in input polygon.
454*5f2bebf7SJérôme Gardou * vlist - list of indexes into VB->V* of polygon to clip.
455*5f2bebf7SJérôme Gardou * Output: vlist - modified list of vertex indexes
456*5f2bebf7SJérôme Gardou * Return: number of vertices in resulting polygon
457*5f2bebf7SJérôme Gardou */
gl_viewclip_polygon(GLcontext * ctx,GLuint n,GLuint vlist[])458*5f2bebf7SJérôme Gardou GLuint gl_viewclip_polygon( GLcontext* ctx, GLuint n, GLuint vlist[] )
459*5f2bebf7SJérôme Gardou
460*5f2bebf7SJérôme Gardou {
461*5f2bebf7SJérôme Gardou struct vertex_buffer* VB = ctx->VB;
462*5f2bebf7SJérôme Gardou GLfloat (*coord)[4] = VB->Clip;
463*5f2bebf7SJérôme Gardou
464*5f2bebf7SJérôme Gardou GLuint previ, prevj;
465*5f2bebf7SJérôme Gardou GLuint curri, currj;
466*5f2bebf7SJérôme Gardou GLuint vlist2[VB_SIZE];
467*5f2bebf7SJérôme Gardou GLuint n2;
468*5f2bebf7SJérôme Gardou GLdouble dx, dy, dz, dw, t, neww;
469*5f2bebf7SJérôme Gardou
470*5f2bebf7SJérôme Gardou /*
471*5f2bebf7SJérôme Gardou * We use 6 instances of this code to implement clipping against the
472*5f2bebf7SJérôme Gardou * 6 sides of the view volume. Prior to each we define the macros:
473*5f2bebf7SJérôme Gardou * INLIST = array which lists input vertices
474*5f2bebf7SJérôme Gardou * OUTLIST = array which lists output vertices
475*5f2bebf7SJérôme Gardou * INCOUNT = variable which is the number of vertices in INLIST[]
476*5f2bebf7SJérôme Gardou * OUTCOUNT = variable which is the number of vertices in OUTLIST[]
477*5f2bebf7SJérôme Gardou * INSIDE(i) = test if vertex v[i] is inside the view volume
478*5f2bebf7SJérôme Gardou * COMPUTE_INTERSECTION(in,out,new) = compute intersection of line
479*5f2bebf7SJérôme Gardou * from v[in] to v[out] with the clipping plane and store
480*5f2bebf7SJérôme Gardou * the result in v[new]
481*5f2bebf7SJérôme Gardou */
482*5f2bebf7SJérôme Gardou
483*5f2bebf7SJérôme Gardou #define GENERAL_CLIP \
484*5f2bebf7SJérôme Gardou if (INCOUNT<3) return 0; \
485*5f2bebf7SJérôme Gardou previ = INCOUNT-1; /* let previous = last vertex */ \
486*5f2bebf7SJérôme Gardou prevj = INLIST[previ]; \
487*5f2bebf7SJérôme Gardou OUTCOUNT = 0; \
488*5f2bebf7SJérôme Gardou for (curri=0;curri<INCOUNT;curri++) { \
489*5f2bebf7SJérôme Gardou currj = INLIST[curri]; \
490*5f2bebf7SJérôme Gardou if (INSIDE(currj)) { \
491*5f2bebf7SJérôme Gardou if (INSIDE(prevj)) { \
492*5f2bebf7SJérôme Gardou /* both verts are inside ==> copy current to outlist */ \
493*5f2bebf7SJérôme Gardou OUTLIST[OUTCOUNT] = currj; \
494*5f2bebf7SJérôme Gardou OUTCOUNT++; \
495*5f2bebf7SJérôme Gardou } \
496*5f2bebf7SJérôme Gardou else { \
497*5f2bebf7SJérôme Gardou /* current is inside and previous is outside ==> clip */ \
498*5f2bebf7SJérôme Gardou COMPUTE_INTERSECTION( currj, prevj, VB->Free ) \
499*5f2bebf7SJérôme Gardou /* if new point not coincident with previous point... */ \
500*5f2bebf7SJérôme Gardou if (t>0.0) { \
501*5f2bebf7SJérôme Gardou /* interpolate aux info using the value of t */ \
502*5f2bebf7SJérôme Gardou if (ctx->ClipMask) \
503*5f2bebf7SJérôme Gardou ctx->ClipInterpAuxFunc( ctx, CLIP_SPACE, VB->Free, t, currj, prevj ); \
504*5f2bebf7SJérôme Gardou VB->Edgeflag[VB->Free] = VB->Edgeflag[prevj]; \
505*5f2bebf7SJérôme Gardou /* output new point */ \
506*5f2bebf7SJérôme Gardou OUTLIST[OUTCOUNT] = VB->Free; \
507*5f2bebf7SJérôme Gardou VB->Free++; \
508*5f2bebf7SJérôme Gardou if (VB->Free==VB_SIZE) VB->Free = 1; \
509*5f2bebf7SJérôme Gardou OUTCOUNT++; \
510*5f2bebf7SJérôme Gardou } \
511*5f2bebf7SJérôme Gardou /* Output current */ \
512*5f2bebf7SJérôme Gardou OUTLIST[OUTCOUNT] = currj; \
513*5f2bebf7SJérôme Gardou OUTCOUNT++; \
514*5f2bebf7SJérôme Gardou } \
515*5f2bebf7SJérôme Gardou } \
516*5f2bebf7SJérôme Gardou else { \
517*5f2bebf7SJérôme Gardou if (INSIDE(prevj)) { \
518*5f2bebf7SJérôme Gardou /* current is outside and previous is inside ==> clip */ \
519*5f2bebf7SJérôme Gardou COMPUTE_INTERSECTION( prevj, currj, VB->Free ) \
520*5f2bebf7SJérôme Gardou /* if new point not coincident with previous point... */ \
521*5f2bebf7SJérôme Gardou if (t>0.0) { \
522*5f2bebf7SJérôme Gardou /* interpolate aux info using the value of t */ \
523*5f2bebf7SJérôme Gardou if (ctx->ClipMask) \
524*5f2bebf7SJérôme Gardou ctx->ClipInterpAuxFunc( ctx, CLIP_SPACE, VB->Free, t, prevj, currj ); \
525*5f2bebf7SJérôme Gardou VB->Edgeflag[VB->Free] = VB->Edgeflag[prevj]; \
526*5f2bebf7SJérôme Gardou /* output new point */ \
527*5f2bebf7SJérôme Gardou OUTLIST[OUTCOUNT] = VB->Free; \
528*5f2bebf7SJérôme Gardou VB->Free++; \
529*5f2bebf7SJérôme Gardou if (VB->Free==VB_SIZE) VB->Free = 1; \
530*5f2bebf7SJérôme Gardou OUTCOUNT++; \
531*5f2bebf7SJérôme Gardou } \
532*5f2bebf7SJérôme Gardou } \
533*5f2bebf7SJérôme Gardou /* else both verts are outside ==> do nothing */ \
534*5f2bebf7SJérôme Gardou } \
535*5f2bebf7SJérôme Gardou /* let previous = current */ \
536*5f2bebf7SJérôme Gardou previ = curri; \
537*5f2bebf7SJérôme Gardou prevj = currj; \
538*5f2bebf7SJérôme Gardou /* check for overflowing vertex buffer */ \
539*5f2bebf7SJérôme Gardou if (OUTCOUNT>=VB_SIZE-1) { \
540*5f2bebf7SJérôme Gardou /* Too many vertices */ \
541*5f2bebf7SJérôme Gardou if (OUTLIST==vlist2) { \
542*5f2bebf7SJérôme Gardou /* copy OUTLIST[] to vlist[] */ \
543*5f2bebf7SJérôme Gardou int i; \
544*5f2bebf7SJérôme Gardou for (i=0;i<VB_SIZE;i++) { \
545*5f2bebf7SJérôme Gardou vlist[i] = OUTLIST[i]; \
546*5f2bebf7SJérôme Gardou } \
547*5f2bebf7SJérôme Gardou } \
548*5f2bebf7SJérôme Gardou return VB_SIZE-1; \
549*5f2bebf7SJérôme Gardou } \
550*5f2bebf7SJérôme Gardou }
551*5f2bebf7SJérôme Gardou
552*5f2bebf7SJérôme Gardou
553*5f2bebf7SJérôme Gardou #define X(I) coord[I][0]
554*5f2bebf7SJérôme Gardou #define Y(I) coord[I][1]
555*5f2bebf7SJérôme Gardou #define Z(I) coord[I][2]
556*5f2bebf7SJérôme Gardou #define W(I) coord[I][3]
557*5f2bebf7SJérôme Gardou
558*5f2bebf7SJérôme Gardou /*
559*5f2bebf7SJérôme Gardou * Clip against +X
560*5f2bebf7SJérôme Gardou */
561*5f2bebf7SJérôme Gardou #define INCOUNT n
562*5f2bebf7SJérôme Gardou #define OUTCOUNT n2
563*5f2bebf7SJérôme Gardou #define INLIST vlist
564*5f2bebf7SJérôme Gardou #define OUTLIST vlist2
565*5f2bebf7SJérôme Gardou #define INSIDE(K) (X(K) <= W(K))
566*5f2bebf7SJérôme Gardou
567*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( in, out, new ) \
568*5f2bebf7SJérôme Gardou dx = X(out) - X(in); \
569*5f2bebf7SJérôme Gardou dw = W(out) - W(in); \
570*5f2bebf7SJérôme Gardou t = (X(in)-W(in)) / (dw-dx); \
571*5f2bebf7SJérôme Gardou neww = W(in) + t * dw; \
572*5f2bebf7SJérôme Gardou X(new) = neww; \
573*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * (Y(out) - Y(in)); \
574*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * (Z(out) - Z(in)); \
575*5f2bebf7SJérôme Gardou W(new) = neww;
576*5f2bebf7SJérôme Gardou
577*5f2bebf7SJérôme Gardou GENERAL_CLIP
578*5f2bebf7SJérôme Gardou
579*5f2bebf7SJérôme Gardou #undef INCOUNT
580*5f2bebf7SJérôme Gardou #undef OUTCOUNT
581*5f2bebf7SJérôme Gardou #undef INLIST
582*5f2bebf7SJérôme Gardou #undef OUTLIST
583*5f2bebf7SJérôme Gardou #undef INSIDE
584*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
585*5f2bebf7SJérôme Gardou
586*5f2bebf7SJérôme Gardou
587*5f2bebf7SJérôme Gardou /*
588*5f2bebf7SJérôme Gardou * Clip against -X
589*5f2bebf7SJérôme Gardou */
590*5f2bebf7SJérôme Gardou #define INCOUNT n2
591*5f2bebf7SJérôme Gardou #define OUTCOUNT n
592*5f2bebf7SJérôme Gardou #define INLIST vlist2
593*5f2bebf7SJérôme Gardou #define OUTLIST vlist
594*5f2bebf7SJérôme Gardou #define INSIDE(K) (X(K) >= -W(K))
595*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( in, out, new ) \
596*5f2bebf7SJérôme Gardou dx = X(out)-X(in); \
597*5f2bebf7SJérôme Gardou dw = W(out)-W(in); \
598*5f2bebf7SJérôme Gardou t = -(X(in)+W(in)) / (dw+dx); \
599*5f2bebf7SJérôme Gardou neww = W(in) + t * dw; \
600*5f2bebf7SJérôme Gardou X(new) = -neww; \
601*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * (Y(out) - Y(in)); \
602*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * (Z(out) - Z(in)); \
603*5f2bebf7SJérôme Gardou W(new) = neww;
604*5f2bebf7SJérôme Gardou
605*5f2bebf7SJérôme Gardou GENERAL_CLIP
606*5f2bebf7SJérôme Gardou
607*5f2bebf7SJérôme Gardou #undef INCOUNT
608*5f2bebf7SJérôme Gardou #undef OUTCOUNT
609*5f2bebf7SJérôme Gardou #undef INLIST
610*5f2bebf7SJérôme Gardou #undef OUTLIST
611*5f2bebf7SJérôme Gardou #undef INSIDE
612*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
613*5f2bebf7SJérôme Gardou
614*5f2bebf7SJérôme Gardou
615*5f2bebf7SJérôme Gardou /*
616*5f2bebf7SJérôme Gardou * Clip against +Y
617*5f2bebf7SJérôme Gardou */
618*5f2bebf7SJérôme Gardou #define INCOUNT n
619*5f2bebf7SJérôme Gardou #define OUTCOUNT n2
620*5f2bebf7SJérôme Gardou #define INLIST vlist
621*5f2bebf7SJérôme Gardou #define OUTLIST vlist2
622*5f2bebf7SJérôme Gardou #define INSIDE(K) (Y(K) <= W(K))
623*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( in, out, new ) \
624*5f2bebf7SJérôme Gardou dy = Y(out)-Y(in); \
625*5f2bebf7SJérôme Gardou dw = W(out)-W(in); \
626*5f2bebf7SJérôme Gardou t = (Y(in)-W(in)) / (dw-dy); \
627*5f2bebf7SJérôme Gardou neww = W(in) + t * dw; \
628*5f2bebf7SJérôme Gardou X(new) = X(in) + t * (X(out) - X(in)); \
629*5f2bebf7SJérôme Gardou Y(new) = neww; \
630*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * (Z(out) - Z(in)); \
631*5f2bebf7SJérôme Gardou W(new) = neww;
632*5f2bebf7SJérôme Gardou
633*5f2bebf7SJérôme Gardou GENERAL_CLIP
634*5f2bebf7SJérôme Gardou
635*5f2bebf7SJérôme Gardou #undef INCOUNT
636*5f2bebf7SJérôme Gardou #undef OUTCOUNT
637*5f2bebf7SJérôme Gardou #undef INLIST
638*5f2bebf7SJérôme Gardou #undef OUTLIST
639*5f2bebf7SJérôme Gardou #undef INSIDE
640*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
641*5f2bebf7SJérôme Gardou
642*5f2bebf7SJérôme Gardou
643*5f2bebf7SJérôme Gardou /*
644*5f2bebf7SJérôme Gardou * Clip against -Y
645*5f2bebf7SJérôme Gardou */
646*5f2bebf7SJérôme Gardou #define INCOUNT n2
647*5f2bebf7SJérôme Gardou #define OUTCOUNT n
648*5f2bebf7SJérôme Gardou #define INLIST vlist2
649*5f2bebf7SJérôme Gardou #define OUTLIST vlist
650*5f2bebf7SJérôme Gardou #define INSIDE(K) (Y(K) >= -W(K))
651*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( in, out, new ) \
652*5f2bebf7SJérôme Gardou dy = Y(out)-Y(in); \
653*5f2bebf7SJérôme Gardou dw = W(out)-W(in); \
654*5f2bebf7SJérôme Gardou t = -(Y(in)+W(in)) / (dw+dy); \
655*5f2bebf7SJérôme Gardou neww = W(in) + t * dw; \
656*5f2bebf7SJérôme Gardou X(new) = X(in) + t * (X(out) - X(in)); \
657*5f2bebf7SJérôme Gardou Y(new) = -neww; \
658*5f2bebf7SJérôme Gardou Z(new) = Z(in) + t * (Z(out) - Z(in)); \
659*5f2bebf7SJérôme Gardou W(new) = neww;
660*5f2bebf7SJérôme Gardou
661*5f2bebf7SJérôme Gardou GENERAL_CLIP
662*5f2bebf7SJérôme Gardou
663*5f2bebf7SJérôme Gardou #undef INCOUNT
664*5f2bebf7SJérôme Gardou #undef OUTCOUNT
665*5f2bebf7SJérôme Gardou #undef INLIST
666*5f2bebf7SJérôme Gardou #undef OUTLIST
667*5f2bebf7SJérôme Gardou #undef INSIDE
668*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
669*5f2bebf7SJérôme Gardou
670*5f2bebf7SJérôme Gardou
671*5f2bebf7SJérôme Gardou
672*5f2bebf7SJérôme Gardou /*
673*5f2bebf7SJérôme Gardou * Clip against +Z
674*5f2bebf7SJérôme Gardou */
675*5f2bebf7SJérôme Gardou #define INCOUNT n
676*5f2bebf7SJérôme Gardou #define OUTCOUNT n2
677*5f2bebf7SJérôme Gardou #define INLIST vlist
678*5f2bebf7SJérôme Gardou #define OUTLIST vlist2
679*5f2bebf7SJérôme Gardou #define INSIDE(K) (Z(K) <= W(K))
680*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( in, out, new ) \
681*5f2bebf7SJérôme Gardou dz = Z(out)-Z(in); \
682*5f2bebf7SJérôme Gardou dw = W(out)-W(in); \
683*5f2bebf7SJérôme Gardou t = (Z(in)-W(in)) / (dw-dz); \
684*5f2bebf7SJérôme Gardou neww = W(in) + t * dw; \
685*5f2bebf7SJérôme Gardou X(new) = X(in) + t * (X(out) - X(in)); \
686*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * (Y(out) - Y(in)); \
687*5f2bebf7SJérôme Gardou Z(new) = neww; \
688*5f2bebf7SJérôme Gardou W(new) = neww;
689*5f2bebf7SJérôme Gardou
690*5f2bebf7SJérôme Gardou GENERAL_CLIP
691*5f2bebf7SJérôme Gardou
692*5f2bebf7SJérôme Gardou #undef INCOUNT
693*5f2bebf7SJérôme Gardou #undef OUTCOUNT
694*5f2bebf7SJérôme Gardou #undef INLIST
695*5f2bebf7SJérôme Gardou #undef OUTLIST
696*5f2bebf7SJérôme Gardou #undef INSIDE
697*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
698*5f2bebf7SJérôme Gardou
699*5f2bebf7SJérôme Gardou
700*5f2bebf7SJérôme Gardou /*
701*5f2bebf7SJérôme Gardou * Clip against -Z
702*5f2bebf7SJérôme Gardou */
703*5f2bebf7SJérôme Gardou #define INCOUNT n2
704*5f2bebf7SJérôme Gardou #define OUTCOUNT n
705*5f2bebf7SJérôme Gardou #define INLIST vlist2
706*5f2bebf7SJérôme Gardou #define OUTLIST vlist
707*5f2bebf7SJérôme Gardou #define INSIDE(K) (Z(K) >= -W(K))
708*5f2bebf7SJérôme Gardou #define COMPUTE_INTERSECTION( in, out, new ) \
709*5f2bebf7SJérôme Gardou dz = Z(out)-Z(in); \
710*5f2bebf7SJérôme Gardou dw = W(out)-W(in); \
711*5f2bebf7SJérôme Gardou t = -(Z(in)+W(in)) / (dw+dz); \
712*5f2bebf7SJérôme Gardou neww = W(in) + t * dw; \
713*5f2bebf7SJérôme Gardou X(new) = X(in) + t * (X(out) - X(in)); \
714*5f2bebf7SJérôme Gardou Y(new) = Y(in) + t * (Y(out) - Y(in)); \
715*5f2bebf7SJérôme Gardou Z(new) = -neww; \
716*5f2bebf7SJérôme Gardou W(new) = neww;
717*5f2bebf7SJérôme Gardou
718*5f2bebf7SJérôme Gardou GENERAL_CLIP
719*5f2bebf7SJérôme Gardou
720*5f2bebf7SJérôme Gardou #undef INCOUNT
721*5f2bebf7SJérôme Gardou #undef INLIST
722*5f2bebf7SJérôme Gardou #undef OUTLIST
723*5f2bebf7SJérôme Gardou #undef INSIDE
724*5f2bebf7SJérôme Gardou #undef COMPUTE_INTERSECTION
725*5f2bebf7SJérôme Gardou
726*5f2bebf7SJérôme Gardou /* 'OUTCOUNT' clipped vertices are now back in v[] */
727*5f2bebf7SJérôme Gardou return OUTCOUNT;
728*5f2bebf7SJérôme Gardou
729*5f2bebf7SJérôme Gardou #undef GENERAL_CLIP
730*5f2bebf7SJérôme Gardou #undef OUTCOUNT
731*5f2bebf7SJérôme Gardou }
732*5f2bebf7SJérôme Gardou
733*5f2bebf7SJérôme Gardou
734*5f2bebf7SJérôme Gardou
735*5f2bebf7SJérôme Gardou
736*5f2bebf7SJérôme Gardou /**********************************************************************/
737*5f2bebf7SJérôme Gardou /* Clipping against user-defined clipping planes. */
738*5f2bebf7SJérôme Gardou /**********************************************************************/
739*5f2bebf7SJérôme Gardou
740*5f2bebf7SJérôme Gardou
741*5f2bebf7SJérôme Gardou
742*5f2bebf7SJérôme Gardou /*
743*5f2bebf7SJérôme Gardou * If the dot product of the eye coordinates of a vertex with the
744*5f2bebf7SJérôme Gardou * stored plane equation components is positive or zero, the vertex
745*5f2bebf7SJérôme Gardou * is in with respect to that clipping plane, otherwise it is out.
746*5f2bebf7SJérôme Gardou */
747*5f2bebf7SJérôme Gardou
748*5f2bebf7SJérôme Gardou
749*5f2bebf7SJérôme Gardou
750*5f2bebf7SJérôme Gardou /*
751*5f2bebf7SJérôme Gardou * Clip a point against the user clipping planes.
752*5f2bebf7SJérôme Gardou * Input: v - vertex-vector describing the point to clip.
753*5f2bebf7SJérôme Gardou * Return: 0 = point was clipped
754*5f2bebf7SJérôme Gardou * 1 = point not clipped
755*5f2bebf7SJérôme Gardou */
gl_userclip_point(GLcontext * ctx,const GLfloat v[])756*5f2bebf7SJérôme Gardou GLuint gl_userclip_point( GLcontext* ctx, const GLfloat v[] )
757*5f2bebf7SJérôme Gardou {
758*5f2bebf7SJérôme Gardou GLuint p;
759*5f2bebf7SJérôme Gardou
760*5f2bebf7SJérôme Gardou for (p=0;p<MAX_CLIP_PLANES;p++) {
761*5f2bebf7SJérôme Gardou if (ctx->Transform.ClipEnabled[p]) {
762*5f2bebf7SJérôme Gardou GLfloat dot = v[0] * ctx->Transform.ClipEquation[p][0]
763*5f2bebf7SJérôme Gardou + v[1] * ctx->Transform.ClipEquation[p][1]
764*5f2bebf7SJérôme Gardou + v[2] * ctx->Transform.ClipEquation[p][2]
765*5f2bebf7SJérôme Gardou + v[3] * ctx->Transform.ClipEquation[p][3];
766*5f2bebf7SJérôme Gardou if (dot < 0.0F) {
767*5f2bebf7SJérôme Gardou return 0;
768*5f2bebf7SJérôme Gardou }
769*5f2bebf7SJérôme Gardou }
770*5f2bebf7SJérôme Gardou }
771*5f2bebf7SJérôme Gardou
772*5f2bebf7SJérôme Gardou return 1;
773*5f2bebf7SJérôme Gardou }
774*5f2bebf7SJérôme Gardou
775*5f2bebf7SJérôme Gardou
776*5f2bebf7SJérôme Gardou #define MAGIC_NUMBER -0.8e-03F
777*5f2bebf7SJérôme Gardou
778*5f2bebf7SJérôme Gardou
779*5f2bebf7SJérôme Gardou /* Test if VB->Eye[J] is inside the clipping plane defined by A,B,C,D */
780*5f2bebf7SJérôme Gardou #define INSIDE( J, A, B, C, D ) \
781*5f2bebf7SJérôme Gardou ( (VB->Eye[J][0] * A + VB->Eye[J][1] * B \
782*5f2bebf7SJérôme Gardou + VB->Eye[J][2] * C + VB->Eye[J][3] * D) >= MAGIC_NUMBER )
783*5f2bebf7SJérôme Gardou
784*5f2bebf7SJérôme Gardou
785*5f2bebf7SJérôme Gardou /* Test if VB->Eye[J] is outside the clipping plane defined by A,B,C,D */
786*5f2bebf7SJérôme Gardou #define OUTSIDE( J, A, B, C, D ) \
787*5f2bebf7SJérôme Gardou ( (VB->Eye[J][0] * A + VB->Eye[J][1] * B \
788*5f2bebf7SJérôme Gardou + VB->Eye[J][2] * C + VB->Eye[J][3] * D) < MAGIC_NUMBER )
789*5f2bebf7SJérôme Gardou
790*5f2bebf7SJérôme Gardou
791*5f2bebf7SJérôme Gardou /*
792*5f2bebf7SJérôme Gardou * Clip a line against the user clipping planes.
793*5f2bebf7SJérôme Gardou * Input: i, j - indexes into VB->V*[] of endpoints
794*5f2bebf7SJérôme Gardou * Output: i, j - indexes into VB->V*[] of (possibly clipped) endpoints
795*5f2bebf7SJérôme Gardou * Return: 0 = line completely clipped
796*5f2bebf7SJérôme Gardou * 1 = line is visible
797*5f2bebf7SJérôme Gardou */
gl_userclip_line(GLcontext * ctx,GLuint * i,GLuint * j)798*5f2bebf7SJérôme Gardou GLuint gl_userclip_line( GLcontext* ctx, GLuint *i, GLuint *j )
799*5f2bebf7SJérôme Gardou {
800*5f2bebf7SJérôme Gardou struct vertex_buffer* VB = ctx->VB;
801*5f2bebf7SJérôme Gardou
802*5f2bebf7SJérôme Gardou GLuint p, ii, jj;
803*5f2bebf7SJérôme Gardou
804*5f2bebf7SJérôme Gardou ii = *i;
805*5f2bebf7SJérôme Gardou jj = *j;
806*5f2bebf7SJérôme Gardou
807*5f2bebf7SJérôme Gardou for (p=0;p<MAX_CLIP_PLANES;p++) {
808*5f2bebf7SJérôme Gardou if (ctx->Transform.ClipEnabled[p]) {
809*5f2bebf7SJérôme Gardou register GLfloat a, b, c, d;
810*5f2bebf7SJérôme Gardou a = ctx->Transform.ClipEquation[p][0];
811*5f2bebf7SJérôme Gardou b = ctx->Transform.ClipEquation[p][1];
812*5f2bebf7SJérôme Gardou c = ctx->Transform.ClipEquation[p][2];
813*5f2bebf7SJérôme Gardou d = ctx->Transform.ClipEquation[p][3];
814*5f2bebf7SJérôme Gardou
815*5f2bebf7SJérôme Gardou if (OUTSIDE( ii, a,b,c,d )) {
816*5f2bebf7SJérôme Gardou if (OUTSIDE( jj, a,b,c,d )) {
817*5f2bebf7SJérôme Gardou /* ii and jj outside ==> quit */
818*5f2bebf7SJérôme Gardou return 0;
819*5f2bebf7SJérôme Gardou }
820*5f2bebf7SJérôme Gardou else {
821*5f2bebf7SJérôme Gardou /* ii is outside, jj is inside ==> clip */
822*5f2bebf7SJérôme Gardou GLfloat dx, dy, dz, dw, t, denom;
823*5f2bebf7SJérôme Gardou dx = VB->Eye[ii][0] - VB->Eye[jj][0];
824*5f2bebf7SJérôme Gardou dy = VB->Eye[ii][1] - VB->Eye[jj][1];
825*5f2bebf7SJérôme Gardou dz = VB->Eye[ii][2] - VB->Eye[jj][2];
826*5f2bebf7SJérôme Gardou dw = VB->Eye[ii][3] - VB->Eye[jj][3];
827*5f2bebf7SJérôme Gardou denom = dx*a + dy*b + dz*c + dw*d;
828*5f2bebf7SJérôme Gardou if (denom==0.0) {
829*5f2bebf7SJérôme Gardou t = 0.0;
830*5f2bebf7SJérôme Gardou }
831*5f2bebf7SJérôme Gardou else {
832*5f2bebf7SJérôme Gardou t = -(VB->Eye[jj][0]*a+VB->Eye[jj][1]*b
833*5f2bebf7SJérôme Gardou +VB->Eye[jj][2]*c+VB->Eye[jj][3]*d) / denom;
834*5f2bebf7SJérôme Gardou if (t>1.0F) t = 1.0F;
835*5f2bebf7SJérôme Gardou }
836*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][0] = VB->Eye[jj][0] + t * dx;
837*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][1] = VB->Eye[jj][1] + t * dy;
838*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][2] = VB->Eye[jj][2] + t * dz;
839*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][3] = VB->Eye[jj][3] + t * dw;
840*5f2bebf7SJérôme Gardou
841*5f2bebf7SJérôme Gardou /* Interpolate colors, indexes, and/or texture coords */
842*5f2bebf7SJérôme Gardou if (ctx->ClipMask)
843*5f2bebf7SJérôme Gardou interpolate_aux( ctx, EYE_SPACE, VB->Free, t, jj, ii );
844*5f2bebf7SJérôme Gardou
845*5f2bebf7SJérôme Gardou ii = VB->Free;
846*5f2bebf7SJérôme Gardou VB->Free++;
847*5f2bebf7SJérôme Gardou if (VB->Free==VB_SIZE) VB->Free = 1;
848*5f2bebf7SJérôme Gardou }
849*5f2bebf7SJérôme Gardou }
850*5f2bebf7SJérôme Gardou else {
851*5f2bebf7SJérôme Gardou if (OUTSIDE( jj, a,b,c,d )) {
852*5f2bebf7SJérôme Gardou /* ii is inside, jj is outside ==> clip */
853*5f2bebf7SJérôme Gardou GLfloat dx, dy, dz, dw, t, denom;
854*5f2bebf7SJérôme Gardou dx = VB->Eye[jj][0] - VB->Eye[ii][0];
855*5f2bebf7SJérôme Gardou dy = VB->Eye[jj][1] - VB->Eye[ii][1];
856*5f2bebf7SJérôme Gardou dz = VB->Eye[jj][2] - VB->Eye[ii][2];
857*5f2bebf7SJérôme Gardou dw = VB->Eye[jj][3] - VB->Eye[ii][3];
858*5f2bebf7SJérôme Gardou denom = dx*a + dy*b + dz*c + dw*d;
859*5f2bebf7SJérôme Gardou if (denom==0.0) {
860*5f2bebf7SJérôme Gardou t = 0.0;
861*5f2bebf7SJérôme Gardou }
862*5f2bebf7SJérôme Gardou else {
863*5f2bebf7SJérôme Gardou t = -(VB->Eye[ii][0]*a+VB->Eye[ii][1]*b
864*5f2bebf7SJérôme Gardou +VB->Eye[ii][2]*c+VB->Eye[ii][3]*d) / denom;
865*5f2bebf7SJérôme Gardou if (t>1.0F) t = 1.0F;
866*5f2bebf7SJérôme Gardou }
867*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][0] = VB->Eye[ii][0] + t * dx;
868*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][1] = VB->Eye[ii][1] + t * dy;
869*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][2] = VB->Eye[ii][2] + t * dz;
870*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][3] = VB->Eye[ii][3] + t * dw;
871*5f2bebf7SJérôme Gardou
872*5f2bebf7SJérôme Gardou /* Interpolate colors, indexes, and/or texture coords */
873*5f2bebf7SJérôme Gardou if (ctx->ClipMask)
874*5f2bebf7SJérôme Gardou interpolate_aux( ctx, EYE_SPACE, VB->Free, t, ii, jj );
875*5f2bebf7SJérôme Gardou
876*5f2bebf7SJérôme Gardou jj = VB->Free;
877*5f2bebf7SJérôme Gardou VB->Free++;
878*5f2bebf7SJérôme Gardou if (VB->Free==VB_SIZE) VB->Free = 1;
879*5f2bebf7SJérôme Gardou }
880*5f2bebf7SJérôme Gardou else {
881*5f2bebf7SJérôme Gardou /* ii and jj inside ==> do nothing */
882*5f2bebf7SJérôme Gardou }
883*5f2bebf7SJérôme Gardou }
884*5f2bebf7SJérôme Gardou }
885*5f2bebf7SJérôme Gardou }
886*5f2bebf7SJérôme Gardou
887*5f2bebf7SJérôme Gardou *i = ii;
888*5f2bebf7SJérôme Gardou *j = jj;
889*5f2bebf7SJérôme Gardou return 1;
890*5f2bebf7SJérôme Gardou }
891*5f2bebf7SJérôme Gardou
892*5f2bebf7SJérôme Gardou
893*5f2bebf7SJérôme Gardou
894*5f2bebf7SJérôme Gardou
895*5f2bebf7SJérôme Gardou /*
896*5f2bebf7SJérôme Gardou * Clip a polygon against the user clipping planes defined in eye coordinates.
897*5f2bebf7SJérôme Gardou * Input: n - number of vertices.
898*5f2bebf7SJérôme Gardou * vlist - list of vertices in input polygon.
899*5f2bebf7SJérôme Gardou * Output: vlist - list of vertices in output polygon.
900*5f2bebf7SJérôme Gardou * Return: number of vertices after clipping.
901*5f2bebf7SJérôme Gardou */
gl_userclip_polygon(GLcontext * ctx,GLuint n,GLuint vlist[])902*5f2bebf7SJérôme Gardou GLuint gl_userclip_polygon( GLcontext* ctx, GLuint n, GLuint vlist[] )
903*5f2bebf7SJérôme Gardou {
904*5f2bebf7SJérôme Gardou struct vertex_buffer* VB = ctx->VB;
905*5f2bebf7SJérôme Gardou
906*5f2bebf7SJérôme Gardou GLuint vlist2[VB_SIZE];
907*5f2bebf7SJérôme Gardou GLuint *inlist, *outlist;
908*5f2bebf7SJérôme Gardou GLuint incount, outcount;
909*5f2bebf7SJérôme Gardou GLuint curri, currj;
910*5f2bebf7SJérôme Gardou GLuint previ, prevj;
911*5f2bebf7SJérôme Gardou GLuint p;
912*5f2bebf7SJérôme Gardou
913*5f2bebf7SJérôme Gardou /* initialize input vertex list */
914*5f2bebf7SJérôme Gardou incount = n;
915*5f2bebf7SJérôme Gardou inlist = vlist;
916*5f2bebf7SJérôme Gardou outlist = vlist2;
917*5f2bebf7SJérôme Gardou
918*5f2bebf7SJérôme Gardou for (p=0;p<MAX_CLIP_PLANES;p++) {
919*5f2bebf7SJérôme Gardou if (ctx->Transform.ClipEnabled[p]) {
920*5f2bebf7SJérôme Gardou register float a = ctx->Transform.ClipEquation[p][0];
921*5f2bebf7SJérôme Gardou register float b = ctx->Transform.ClipEquation[p][1];
922*5f2bebf7SJérôme Gardou register float c = ctx->Transform.ClipEquation[p][2];
923*5f2bebf7SJérôme Gardou register float d = ctx->Transform.ClipEquation[p][3];
924*5f2bebf7SJérôme Gardou
925*5f2bebf7SJérôme Gardou if (incount<3) return 0;
926*5f2bebf7SJérôme Gardou
927*5f2bebf7SJérôme Gardou /* initialize prev to be last in the input list */
928*5f2bebf7SJérôme Gardou previ = incount - 1;
929*5f2bebf7SJérôme Gardou prevj = inlist[previ];
930*5f2bebf7SJérôme Gardou
931*5f2bebf7SJérôme Gardou outcount = 0;
932*5f2bebf7SJérôme Gardou
933*5f2bebf7SJérôme Gardou for (curri=0;curri<incount;curri++) {
934*5f2bebf7SJérôme Gardou currj = inlist[curri];
935*5f2bebf7SJérôme Gardou
936*5f2bebf7SJérôme Gardou if (INSIDE(currj, a,b,c,d)) {
937*5f2bebf7SJérôme Gardou if (INSIDE(prevj, a,b,c,d)) {
938*5f2bebf7SJérôme Gardou /* both verts are inside ==> copy current to outlist */
939*5f2bebf7SJérôme Gardou outlist[outcount++] = currj;
940*5f2bebf7SJérôme Gardou }
941*5f2bebf7SJérôme Gardou else {
942*5f2bebf7SJérôme Gardou /* current is inside and previous is outside ==> clip */
943*5f2bebf7SJérôme Gardou GLfloat dx, dy, dz, dw, t, denom;
944*5f2bebf7SJérôme Gardou /* compute t */
945*5f2bebf7SJérôme Gardou dx = VB->Eye[prevj][0] - VB->Eye[currj][0];
946*5f2bebf7SJérôme Gardou dy = VB->Eye[prevj][1] - VB->Eye[currj][1];
947*5f2bebf7SJérôme Gardou dz = VB->Eye[prevj][2] - VB->Eye[currj][2];
948*5f2bebf7SJérôme Gardou dw = VB->Eye[prevj][3] - VB->Eye[currj][3];
949*5f2bebf7SJérôme Gardou denom = dx*a + dy*b + dz*c + dw*d;
950*5f2bebf7SJérôme Gardou if (denom==0.0) {
951*5f2bebf7SJérôme Gardou t = 0.0;
952*5f2bebf7SJérôme Gardou }
953*5f2bebf7SJérôme Gardou else {
954*5f2bebf7SJérôme Gardou t = -(VB->Eye[currj][0]*a+VB->Eye[currj][1]*b
955*5f2bebf7SJérôme Gardou +VB->Eye[currj][2]*c+VB->Eye[currj][3]*d) / denom;
956*5f2bebf7SJérôme Gardou if (t>1.0F) {
957*5f2bebf7SJérôme Gardou t = 1.0F;
958*5f2bebf7SJérôme Gardou }
959*5f2bebf7SJérôme Gardou }
960*5f2bebf7SJérôme Gardou /* interpolate new vertex position */
961*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][0] = VB->Eye[currj][0] + t*dx;
962*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][1] = VB->Eye[currj][1] + t*dy;
963*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][2] = VB->Eye[currj][2] + t*dz;
964*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][3] = VB->Eye[currj][3] + t*dw;
965*5f2bebf7SJérôme Gardou
966*5f2bebf7SJérôme Gardou /* interpolate color, index, and/or texture coord */
967*5f2bebf7SJérôme Gardou if (ctx->ClipMask) {
968*5f2bebf7SJérôme Gardou interpolate_aux( ctx, EYE_SPACE, VB->Free, t, currj, prevj);
969*5f2bebf7SJérôme Gardou }
970*5f2bebf7SJérôme Gardou VB->Edgeflag[VB->Free] = VB->Edgeflag[prevj];
971*5f2bebf7SJérôme Gardou
972*5f2bebf7SJérôme Gardou /* output new vertex */
973*5f2bebf7SJérôme Gardou outlist[outcount++] = VB->Free;
974*5f2bebf7SJérôme Gardou VB->Free++;
975*5f2bebf7SJérôme Gardou if (VB->Free==VB_SIZE) VB->Free = 1;
976*5f2bebf7SJérôme Gardou /* output current vertex */
977*5f2bebf7SJérôme Gardou outlist[outcount++] = currj;
978*5f2bebf7SJérôme Gardou }
979*5f2bebf7SJérôme Gardou }
980*5f2bebf7SJérôme Gardou else {
981*5f2bebf7SJérôme Gardou if (INSIDE(prevj, a,b,c,d)) {
982*5f2bebf7SJérôme Gardou /* current is outside and previous is inside ==> clip */
983*5f2bebf7SJérôme Gardou GLfloat dx, dy, dz, dw, t, denom;
984*5f2bebf7SJérôme Gardou /* compute t */
985*5f2bebf7SJérôme Gardou dx = VB->Eye[currj][0]-VB->Eye[prevj][0];
986*5f2bebf7SJérôme Gardou dy = VB->Eye[currj][1]-VB->Eye[prevj][1];
987*5f2bebf7SJérôme Gardou dz = VB->Eye[currj][2]-VB->Eye[prevj][2];
988*5f2bebf7SJérôme Gardou dw = VB->Eye[currj][3]-VB->Eye[prevj][3];
989*5f2bebf7SJérôme Gardou denom = dx*a + dy*b + dz*c + dw*d;
990*5f2bebf7SJérôme Gardou if (denom==0.0) {
991*5f2bebf7SJérôme Gardou t = 0.0;
992*5f2bebf7SJérôme Gardou }
993*5f2bebf7SJérôme Gardou else {
994*5f2bebf7SJérôme Gardou t = -(VB->Eye[prevj][0]*a+VB->Eye[prevj][1]*b
995*5f2bebf7SJérôme Gardou +VB->Eye[prevj][2]*c+VB->Eye[prevj][3]*d) / denom;
996*5f2bebf7SJérôme Gardou if (t>1.0F) {
997*5f2bebf7SJérôme Gardou t = 1.0F;
998*5f2bebf7SJérôme Gardou }
999*5f2bebf7SJérôme Gardou }
1000*5f2bebf7SJérôme Gardou /* interpolate new vertex position */
1001*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][0] = VB->Eye[prevj][0] + t*dx;
1002*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][1] = VB->Eye[prevj][1] + t*dy;
1003*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][2] = VB->Eye[prevj][2] + t*dz;
1004*5f2bebf7SJérôme Gardou VB->Eye[VB->Free][3] = VB->Eye[prevj][3] + t*dw;
1005*5f2bebf7SJérôme Gardou
1006*5f2bebf7SJérôme Gardou /* interpolate color, index, and/or texture coord */
1007*5f2bebf7SJérôme Gardou if (ctx->ClipMask) {
1008*5f2bebf7SJérôme Gardou interpolate_aux( ctx, EYE_SPACE, VB->Free, t, prevj, currj);
1009*5f2bebf7SJérôme Gardou }
1010*5f2bebf7SJérôme Gardou VB->Edgeflag[VB->Free] = VB->Edgeflag[prevj];
1011*5f2bebf7SJérôme Gardou
1012*5f2bebf7SJérôme Gardou /* output new vertex */
1013*5f2bebf7SJérôme Gardou outlist[outcount++] = VB->Free;
1014*5f2bebf7SJérôme Gardou VB->Free++;
1015*5f2bebf7SJérôme Gardou if (VB->Free==VB_SIZE) VB->Free = 1;
1016*5f2bebf7SJérôme Gardou }
1017*5f2bebf7SJérôme Gardou /* else both verts are outside ==> do nothing */
1018*5f2bebf7SJérôme Gardou }
1019*5f2bebf7SJérôme Gardou
1020*5f2bebf7SJérôme Gardou previ = curri;
1021*5f2bebf7SJérôme Gardou prevj = currj;
1022*5f2bebf7SJérôme Gardou
1023*5f2bebf7SJérôme Gardou /* check for overflowing vertex buffer */
1024*5f2bebf7SJérôme Gardou if (outcount>=VB_SIZE-1) {
1025*5f2bebf7SJérôme Gardou /* Too many vertices */
1026*5f2bebf7SJérôme Gardou if (outlist!=vlist2) {
1027*5f2bebf7SJérôme Gardou MEMCPY( vlist, vlist2, outcount * sizeof(GLuint) );
1028*5f2bebf7SJérôme Gardou }
1029*5f2bebf7SJérôme Gardou return VB_SIZE-1;
1030*5f2bebf7SJérôme Gardou }
1031*5f2bebf7SJérôme Gardou
1032*5f2bebf7SJérôme Gardou } /* for i */
1033*5f2bebf7SJérôme Gardou
1034*5f2bebf7SJérôme Gardou /* swap inlist and outlist pointers */
1035*5f2bebf7SJérôme Gardou {
1036*5f2bebf7SJérôme Gardou GLuint *tmp;
1037*5f2bebf7SJérôme Gardou tmp = inlist;
1038*5f2bebf7SJérôme Gardou inlist = outlist;
1039*5f2bebf7SJérôme Gardou outlist = tmp;
1040*5f2bebf7SJérôme Gardou incount = outcount;
1041*5f2bebf7SJérôme Gardou }
1042*5f2bebf7SJérôme Gardou
1043*5f2bebf7SJérôme Gardou } /* if */
1044*5f2bebf7SJérôme Gardou } /* for p */
1045*5f2bebf7SJérôme Gardou
1046*5f2bebf7SJérôme Gardou /* outlist points to the list of vertices resulting from the last */
1047*5f2bebf7SJérôme Gardou /* clipping. If outlist == vlist2 then we have to copy the vertices */
1048*5f2bebf7SJérôme Gardou /* back to vlist */
1049*5f2bebf7SJérôme Gardou if (outlist!=vlist2) {
1050*5f2bebf7SJérôme Gardou MEMCPY( vlist, vlist2, outcount * sizeof(GLuint) );
1051*5f2bebf7SJérôme Gardou }
1052*5f2bebf7SJérôme Gardou
1053*5f2bebf7SJérôme Gardou return outcount;
1054*5f2bebf7SJérôme Gardou }
1055*5f2bebf7SJérôme Gardou
1056