range finding from Z-Buffer values

New Message Reply Date view Thread view Subject view Author view

David Slayton (dslayton++at++nvl.army.mil)
Mon, 12 Dec 94 10:21 EST


I am attempting to write a range-finding routine as a post-pfdraw function
in performer based upon the values contained in the Z-Buffer after pfdraw
has completed. The values my routine is returning are inconsistent and
non-intuitive. I expect to see values appoaching farplane +nearplane at their
largest and nearplane at their smallest, but am not getting anything like this.
When I'm looking at things far away, the range values seem to make sense.
However, when I'm looking at things up close, the values still remain large
(close to the value of farplane).

My algorithm is based upon the premise that the z value for
a given x,y window offset can yield a range to the foremost visible polygon
based upon the following formula:

  range = (((z - zmin)/(zmax -zmin)) * (farplane - nearplane) + nearplane;

The values zmin and zmax are the same as used in the call lsetdepth(zmin,zmax),
the farplane and nearplane values are the same as those used in
pfChanNearFar(ChanID, nearplane, farplane). The zvalue is a value returned
by a call to lrectread(minx, miny, maxx, maxy, parray), where the parray
contains the z values of the requested region. Just prior to calling
lrectread, I'm calling readsource(SRC_ZBUFFER).

The call to lsetdepth is being made in a initGfx callback shortly after a call
to pfInitGfx(). The form of the lsetdepth call is either
         lsetdepth(getgconfig(GC_MS_ZMIN), getgconfig(GC_MS_ZMAX))
                                 or
         lsetdepth(getgconfig(GC_ZMIN), getgconfig(GC_ZMAX)),
depending on whether multisampling is active or not.

Is Performer resetting the gl state such that my gl calls in the post-pfDraw
function are not working as I would expect?

Does anyone already have a range-finding function which already works with
Performer?

Does anyone see something wrong with my rangefinding function listed below.

I'd appreciate any help I can get.

----------------------------------------------------------------------------

void display_range(volatile IoIn *G_input, IoOut *G_output, int X, int Y)
{

  float np = 0.0, fp = 0.0;
  long nz = 0, fz = 0;
  unsigned long parray[1];
  float zdist = 0.0;
  Screencoord minX, minY, maxX, maxY;
  long readcount = 0;

  pfPushState();
  pfBasicState();
  drawmode(NORMALDRAW);

  parray[0] = 0;

  if( ( X < 0 )
|| ( X >= G_input->winSizeX )
|| ( Y < 0 )
|| ( Y >= G_input->winSizeY ))
  {
    pfNotify(PFNFY_WARN, PFNFY_PRINT,
             "Bad Windowps Offsets <%d,%d>passed to display_range(X,Y)\n"
             "The window is only ( %d xpixels, by %d ypixels )\n",
             X, Y, G_input->winSizeX, G_input->winSizeY);
    return;
  }

  /* use the values in the global Output structure as the near and
     far clipping plane values */

  np = G_output->near;
  fp = G_output->far;

  nz = G_output->zmin;
  fz = G_output->zmax;

#ifdef DEBUG
  pfNotify(PFNFY_NOTICE, PFNFY_PRINT,
           "display_range(): \n"
           "near clipping plane = <%f>, far clipping plane = <%f>, \n"
           "minimum z value = <%d>, maximum z value = <%d> \n",

           np, fp, nz, fz);
#endif

  /* set the readsource to read from the Zbuffer */
  readsource(SRC_ZBUFFER);

  if(!(getgdesc(GD_READSOURCE_ZBUFFER)))
  {
    pfNotify(PFNFY_WARN, PFNFY_PRINT,
             "getdesc status indicates that readsource(SRC_ZBUFFER) "
             "is not functional\n");
  }

  /* get the z value at the x,y coordinates specified */
  minX = X;
  minY = Y;
  maxX = X;
  maxY = Y;

  readcount = lrectread(minX,minY,minX,minY,parray);

#ifdef DEBUG
  pfNotify(PFNFY_WARN, PFNFY_PRINT,
           "lrectread obtained <%ld>zvalues for the min<%d,%d>, max<%d,%d> "
           "coordinates passed to display_range(X,Y) "
           "parray[0] = <%ld>\n",
           readcount,minX,minY,maxX,maxY,(long)parray[0]);

#endif

  /* calculate a distance */
  /* distance should be the floating point value between the near and far */
  /* clipping planes represented by the z interval value */

  zdist = np + ( ( ((float)((long)parray[0])) - ((float)nz))
                  / (((float)fz) - ((float)nz))) * (fp -np);

  pfNotify(PFNFY_NOTICE, PFNFY_PRINT,
           "display_range calculated the following value for zdist (%f)\n",
           zdist);

  pfPopState();
}
_____________________________________________________________________________

Thanks,

Dave Slayton

dslayton++at++nvl.army.mil
(703)704-3698


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:50:43 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.