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 ();
    }
  }
}

Reply via email to