Problems reading the z-buffer

New Message Reply Date view Thread view Subject view Author view

Wilfried Zeise (zeise++at++uni-wuppertal.de)
Thu, 26 Mar 1998 18:47:38 +0200


Hi pfAll:

I am using Performer 2.2 on an Onyx i-station with IRIX 6.2. I want to
read the z-buffer values for my currently displayed frame, and save them
as an image file (ppm format), for image processing purposes. But I am
having some troubles with it. To save such an image I modified the file
perfly.C.

First I declared a class:

class image_t {
  public:
    GLfloat red;
    GLfloat green;
    GLfloat blue;
    GLfloat alpha;
};

Then I added a new function to perfly.C:

static void __write_ppm (const char *filename, const size_t width, const
size_t height, const image_t *image)
{
  FILE *fp = NULL;

  if ((NULL == (fp = ::fopen (filename, "wb"))) || (NULL == image) ||
((1 > width) || (1 > height))) {
    // print msg

    return;
  }

  (void) ::fprintf (fp, "P6\n");
  (void) ::fprintf (fp, "%d %d\n", width, height);
  (void) ::fprintf (fp, "255\n");

  for (size_t loop_y = 0; loop_y < height; loop_y++)
    for (size_t loop_x = 0; loop_x < width; loop_x++)
      (void) ::fprintf (fp, "%c%c%c",
                        static_cast<unsigned char> (image[((height -
loop_y - 1) * width) + loop_x].red * 255),
                        static_cast<unsigned char> (image[((height -
loop_y - 1) * width) + loop_x].green * 255),
                        static_cast<unsigned char> (image[((height -
loop_y - 1) * width) + loop_x].blue * 255));

  ::fflush (fp);
  ::fclose (fp);

  return;
}

Then I modified the function snapImage as follows:

static void
snapImage(int snapAlpha)
{
    FILE *fp;
    static char str[80], depth[80], file_name[80];
    static int count = 0;
    pfPipe* cpipe = ViewState->masterChan->getPipe();
    int id = pfGetId(cpipe)*10 + count++;

    GLint viewport[4];

    GLfloat dbias = 0.0;
    GLfloat dbits = 0.0;
    GLfloat drange[2] = {0.0, 0.0};
    GLfloat dscale = 0.0;
    GLboolean dtest = GL_FALSE;

    glGetIntegerv (GL_VIEWPORT, viewport);

    const size_t image_size = viewport[2] * viewport[3];

    image_t *image = new image_t [image_size];

    image = new image_t [image_size];

    GLfloat *dbuffer = new GLfloat [image_size];

    sprintf(str, "perfly.%d.ppm", id);

    if (snapAlpha)
    {
        sprintf(str, "perfly.%d.rgba", id);
        pfNotify(PFNFY_INFO, PFNFY_PRINT, "Saving pipe %d image in file
%s\n",
                 pfGetId(cpipe), str);

        pfuSaveImage(str, 0, 0,
                 ViewState->mouse.winSizeX,
                 ViewState->mouse.winSizeY, 1);
    }
    else
    {
        glReadBuffer (GL_FRONT);

        glReadPixels (viewport[0], viewport[1], viewport[2],
viewport[3], GL_RGBA, GL_FLOAT, image);

        __write_ppm (str, viewport[2], viewport[3], image);
  
    }

// begin save z-buffer

    glGetFloatv (GL_DEPTH_BIAS, &dbias);
    glGetFloatv (GL_DEPTH_BITS, &dbits);
    glGetFloatv (GL_DEPTH_RANGE, drange);
    glGetFloatv (GL_DEPTH_SCALE, &dscale);
    glGetBooleanv (GL_DEPTH_TEST, &dtest);

    sprintf(depth, "frame_snapshot: bias %f, scale %f, bits %f, range
(%f, %f), depth testing %s\n",
                 dbias, dscale, dbits, drange[0], drange[1],
                 ((GL_FALSE == dtest) ? "disabled" : "enabled"));

    pfNotify(PFNFY_INFO, PFNFY_PRINT, depth);

    glReadBuffer (GL_FRONT);

    glReadPixels (viewport[0], viewport[1], viewport[2], viewport[3],
GL_DEPTH_COMPONENT, GL_FLOAT, dbuffer);

    for (size_t loop = 0; loop < image_size; loop++)
      image[loop].red = image[loop].green = image[loop].blue =
image[loop].alpha = dbuffer[loop];

    sprintf (file_name, "depth%d.ppm\0", id);

    __write_ppm (file_name, viewport[2], viewport[3], image);

    delete [] dbuffer;

    delete [] file_name;
    delete [] image;
  

// end save z-buffer

    /* create info file to go with image */
    sprintf(str, "perfly.%d.info", id);
    if (fp = fopen(str,"w"))
    {
        float h, v;
        fprintf(fp, "Viewing parameters for snap %d of tnt3d\n\n", id);
        fprintf(fp, "XYZ: %f %f %f\n",
                ViewState->viewCoord.xyz[0],
                ViewState->viewCoord.xyz[1],
                ViewState->viewCoord.xyz[2]);
        fprintf(fp, "HPR: %f %f %f\n",
                ViewState->viewCoord.hpr[0],
                ViewState->viewCoord.hpr[1],
                ViewState->viewCoord.hpr[2]);
        fprintf(fp, "NEAR/FAR: %f %f \n",
                ViewState->near, ViewState->far);
        ViewState->masterChan->getFOV(&h, &v);
        fprintf(fp, "FOV: horiz=%f vert=%f\n", h, v);
        fclose(fp);
    }

    pfNotify(PFNFY_INFO, PFNFY_PRINT, "Done\n");
}

glReadPixels(...,GL_RGBA,...) works fine.

The GL_DEPTH tests show the following results:

frame_snapshot: bias 0.000000, scale 1.000000, bits 23.000000, range
(0.000000, 1.000000), depth testing enabled

In my opinion, this means glReadPixels(...,GL_DEPTH_COMPONENT,...)
should work. But I get for every pixel the value z=1.0 !!

Any idea why glReadPixels(...,GL_DEPTH_COMPONENT,...) douesn't work in
my application?

Thank you in advance
Wilfried

-- 
Wilfried Zeise			\    phone:+49-202-4392961
University of Wuppertal		 \   FAX: +49-202-4392959
Dept. of Electrical Engineering	  \  mailto:zeise++at++uni-wuppertal.de
Fuhlrottstr. 10			   \
42119 Wuppertal, Germany	    \
=======================================================================
List Archives, FAQ, FTP:  http://www.sgi.com/Technology/Performer/
            Submissions:  info-performer++at++sgi.com
        Admin. requests:  info-performer-request++at++sgi.com

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:57:05 PDT

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