I haven't looked into this yet...
Dennis Rapaport wrote:
>
> Dear Brian:
>
> There seems to be a problem with glClipPlane behavior (Mesa 3.1beta2,
> Linux on Pentium with X11, egcs-2.91.66).
>
> The clip planes are wrongly located, and their positions seem to depend on
> the arguments supplied to glFrustum (in particular, if the x and y
> arguments are +/- 1, and z_near = 1, so that the 3x3 upper-left part of
> the perspective matrix is diagonal, the results seem ok -- hint?).
>
> I have extracted the relevant parts of the software I have been using and
> included them in the attached test program. Under OpenGL (SGI) there is no
> such problem.
>
> If you require any further details please let me know.
>
> Best wishes,
> Dennis R.
>
> ----------------------------------------------------
> Dennis C. Rapaport
> Department of Physics, Bar-Ilan University
> Ramat-Gan, Israel 52900
> tel: (972) (3) 531-8048 fax: (972) (3) 535-3298
> email: [EMAIL PROTECTED]
> web: http://www.ph.biu.ac.il/~rapaport
> ----------------------------------------------------
/* cliptest.c */
/*
Show clip plane problem.
compile:
gcc -O -o cliptest -I /usr/local/include -L /usr/X11/include \
-L /usr/local/lib -L /usr/X11/lib cliptest.c \
-lMesaGLw -lMesaGL -lXext -lXm -lXt -lX11 -lm
run: cliptest {fov {nClip}}; [fov = aperture angle (def = 110),
nClip = no. of clip planes (def = 6)]; default case is OK,
reduce fov (e.g. 80-100) to see problems
*/
#include <math.h>
#include <stdlib.h>
#include <Xm/Xm.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/GLwDrawA.h>
static XtAppContext app;
static Display *dpy;
static Widget topLevel;
static Widget canvas;
static GLXContext glxContext;
static XVisualInfo *visInfo;
static int glHaveContext = 0, nClip = 6;
static double fov = 110.;
void CbackDAreaExposeGL (Widget, XtPointer, XtPointer);
main (int argc, char **argv)
{
int attribList[30], n;
topLevel = XtVaAppInitialize (&app, "xclient", NULL, 0,
&argc, argv, NULL, NULL);
dpy = XtDisplay (topLevel);
if (argc > 1) fov = atoi (argv[1]);
if (argc > 2) nClip = atoi (argv[2]);
n = 0;
attribList[n ++] = GLX_RGBA;
attribList[n ++] = GLX_DOUBLEBUFFER;
attribList[n ++] = GLX_RED_SIZE; attribList[n ++] = 1;
attribList[n ++] = GLX_GREEN_SIZE; attribList[n ++] = 1;
attribList[n ++] = GLX_BLUE_SIZE; attribList[n ++] = 1;
attribList[n ++] = GLX_DEPTH_SIZE; attribList[n ++] = 1;
attribList[n ++] = None;
visInfo = glXChooseVisual (dpy, DefaultScreen (dpy), attribList);
if (! visInfo) printf ("no visual\n");
canvas = XtVaCreateManagedWidget ("glw",
glwDrawingAreaWidgetClass,
topLevel,
XmNwidth, 500,
XmNheight, 500,
GLwNvisualInfo, visInfo,
GLwNallocateBackground, True,
GLwNinstallBackground, True,
GLwNinstallColormap, True,
NULL);
XtAddCallback (canvas, GLwNexposeCallback, CbackDAreaExposeGL, NULL);
XtRealizeWidget (topLevel);
XtAppMainLoop (app);
}
void CbackDAreaExposeGL (Widget w, XtPointer clientData, XtPointer callData)
{
double xMax, yMax;
Dimension wd, ht;
if (! glHaveContext) glxContext = glXCreateContext (dpy, visInfo, 0, GL_TRUE);
GLwDrawingAreaMakeCurrent (w, glxContext);
if (! glHaveContext) {
glHaveContext = 1;
glClearColor (0.0, 0.0, 0.0, 1.0);
glEnable (GL_DEPTH_TEST);
glDisable (GL_CULL_FACE);
glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable (GL_LIGHT0);
glFrontFace (GL_CCW);
glDisable (GL_NORMALIZE);
glEnable (GL_LIGHTING);
glShadeModel (GL_SMOOTH);
XtVaGetValues (w, XtNwidth, &wd, XtNheight, &ht, NULL);
glViewport (0, 0, (int) wd, (int) ht);
}
if (((XExposeEvent *) ((GLwDrawingAreaCallbackStruct *)
callData)->event)->count == 0) {
glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
yMax = tan (0.5 * fov * M_PI / 180.) / sqrt (2.);
xMax = 1. * yMax;
glFrustum (- xMax, xMax, - yMax, yMax, 1., 100.);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
Render ();
GLwDrawingAreaSwapBuffers (w);
}
}
Render ()
{
double clipC[4], rad;
float rgbaF[] = {0.8, 0.4, 0.4, 1.}, rgbaB[] = {0.3, 0.2, 0.8, 1.};
int k;
rad = 10.;
glPushMatrix ();
glTranslated (0., 0., -5. * rad);
glRotated (30., 0., 1., 0.);
for (k = 0; k < 6; k ++) {
clipC[0] = clipC[1] = clipC[2] = 0.;
clipC[k / 2] = (k % 2) ? -1. : 1.;
clipC[3] = 0.8 * rad;
glClipPlane (GL_CLIP_PLANE0 + k, clipC);
}
for (k = 0; k < nClip; k ++) glEnable (GL_CLIP_PLANE0 + k);
glMaterialfv (GL_FRONT, GL_DIFFUSE, rgbaF);
glMaterialfv (GL_BACK, GL_DIFFUSE, rgbaB);
DrawBall (rad, 32);
for (k = 0; k < nClip; k ++) glDisable (GL_CLIP_PLANE0 + k);
glPopMatrix ();
}
DrawBall (double rad, int nSeg)
{
double v[3], vn[3], theta, phi, sT, cT, sP, cP, sP1, cP1;
int dir, j, k, m;
for (dir = -1; dir <= 1; dir += 2) {
cP1 = 1.; sP1 = 0.;
for (m = 0; m < nSeg / 2; m ++) {
cP = cP1; sP = sP1;
phi = dir * M_PI * (m + 1) / nSeg;
cP1 = cos (phi); sP1 = sin (phi);
glBegin (GL_QUAD_STRIP);
for (j = 0; j <= nSeg; j ++) {
theta = dir * 2. * M_PI * j / nSeg;
cT = cos (theta); sT = sin (theta);
vn[0] = cT * cP1; vn[1] = sT * cP1; vn[2] = sP1;
glNormal3dv (vn);
for (k = 0; k < 3; k ++) v[k] = rad * vn[k];
glVertex3dv (v);
vn[0] = cT * cP; vn[1] = sT * cP; vn[2] = sP;
glNormal3dv (vn);
for (k = 0; k < 3; k ++) v[k] = rad * vn[k];
glVertex3dv (v);
}
glEnd ();
}
}
}