PDA

View Full Version : depth buffer,,,,,,, why and how?



newname
03-14-2001, 12:14 AM
Trouble. I want to obtain the depth information of the current view.
But the result is not what I want.
I use the following codes:

glPixelTransferf(GL_DEPTH_SCALE, 0.1f);
glPixelTransferf(GL_DEPTH_BIAS, 0.5f);
glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT, depthResults);

The result value I got at any pixel is either 0.5 or 0.6, where 0.6 means the pixel is on an object and 0.5 means empty. There are serval balls and boxes in the context.

Why the depth values on the object are all the same? It should be distributed in [0, 1]!
How can I do?

Thanks for any responses.

Bob
03-14-2001, 01:20 AM
Yes, the depthbuffer is usually in the range[0.0 1.0]. But you are using scaling and biasing in your pixeltransfer, so your range is actually [0.5 0.6]. And the depthbuffers is not linear, that means that an object halfway between the near and the far plane does not have the depthvalue 0.5 (as standard).

Maybe your near/far ratio is so big that you loose precision, and therefore you get 0.5 and 0.6 only, and nothing in between.

How do you setup your view frustum, and what coordinates do you use to draw your object?

newname
03-14-2001, 05:19 AM
Thank you very much, Bob.

But it still has problems with that.

I use the following commands to initiate the program:
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,aspect,1.0,50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDrawBuffer(GL_BACK);
glEnable(GL_DEPTH_TEST);

I think gluPerspective has the same function as glFrustum to define the near and far plane. And I also tried the command you mentioned:
glFrustum(0,0,winWidth, winHeight, 1.0, 30.0);

The results are the same, i.e. all depth data on objects are 0.5, and 0.6 in empty area. nothing between 0.5 and 0.6!
P.S. I use 32bit depth buffer.

Bob
03-14-2001, 06:24 AM
Sounds somewhat strange. Try comment out those two glPixelTranslfer-calls and see what happens.

Anyways, with those values for near and far planes, using a 32-bit depthbuffer, you are most likely not to loose any significant depthbuffer precision.

newname
03-14-2001, 09:57 PM
Sigh. It's really strange. I tried to comment them out. However, as you can guess, the result data is 0.0 and 1.0, where 0.0 means object points and 1.0 means empty eara. Still nothing between [0, 1].

Could you give an simple sample program that can read values distributed in [0, 1].

By the way, I am programming in Windows 98 and use MS Visual C++ 6. This will be the reason?

Bob
03-15-2001, 02:21 AM
Sorry, no code. But that looks rather strange. Unless your code is too large, post it and maybe I can try it out.

Development enviromnent/OS make no difference.

newname
03-15-2001, 03:13 AM
Thanks to Bob.

Actually my program is rather complex. But I now make a very simple one for testing. It still fails in my computer. Can you try the following codes:

Please debug into the function copyDepthToColor() to see the depth values (only 0.5 and 0.6). Also you can view them by opening the saved file 512x512x4.dat, in which 4 Bytes per pixel in float type.

//////////////// program begins /////////////
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

GLUquadricObj *quadric;
int stenSize;
int winWidth, winHeight;
GLfloat *depthSave = NULL;

void drawSphere(void)
{
glPushMatrix();
glTranslatef(0,0,-2);
gluSphere(quadric, 1, 30, 20);
glPopMatrix();
}

void resizeBuffers(void)
{
if(depthSave != NULL)
free(depthSave);
depthSave = malloc(winWidth * winHeight * sizeof(GLfloat));
}

void SaveMemData(int w, int h, int eachsize, void *ptr)
{
FILE *file;
char str[256];
sprintf(str, "%dx%dx%d.dat",w,h,eachsize);
file=fopen(str,"wb");
if(file==0)
return;
fwrite(ptr, w*h*eachsize,1,file);
fclose(file);
}

void copyDepthToColor()
{
glPixelTransferf(GL_DEPTH_SCALE, 0.1f);
glPixelTransferf(GL_DEPTH_BIAS, 0.5f);

glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT,
depthSave);

SaveMemData(winWidth, winHeight, sizeof(GLfloat), depthSave);
}


void init(void)
{
glMatrixMode(GL_PROJECTION);
glFrustum(-.33, .33, -.33, .33, .5, 40);

glMatrixMode(GL_MODELVIEW);
gluLookAt(0, 0, 7, 0, 0, 0, 0, 1, 0);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glEnable(GL_NORMALIZE);

quadric = gluNewQuadric();
}

void redrawNoCSG(void)
{
glDisable(GL_STENCIL_TEST);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
// glCullFace(GL_BACK);
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
drawSphere();
copyDepthToColor();
glPopMatrix();

// copyInterest();
glutSwapBuffers();
}

void reshape(int width, int height)
{
glViewport(0, 0, width, height);
//glFrustum(0,0,width,height,0.1,20); //add
winWidth = width;
winHeight = height;
resizeBuffers();
glutPostRedisplay();
}

int main(int argc, char **argv)
{
glutInitWindowSize(512,512);
glutInit(&argc, argv);
glutInitDisplayString("double depth");
glutInitDisplayMode(GLUT_DOUBLE|GLUT_STENCIL|GLUT_ DEPTH|GLUT_RGBA);
(void)glutCreateWindow("depth buffer testing");
glutDisplayFunc(redrawNoCSG);
glutReshapeFunc(reshape);

glGetIntegerv(GL_STENCIL_BITS, &stenSize);
printf("%d bits of stencil available in this visual\n", stenSize);

init();
glutMainLoop();

return 0;
}
//////////////////////////////////////////////////////////


[This message has been edited by newname (edited 03-15-2001).]

[This message has been edited by newname (edited 03-15-2001).]

newname
03-18-2001, 03:44 AM
who can test my above program?

Bob
03-18-2001, 05:30 AM
Tried it, and I get proper depthvalues. If you get wrong values, I suspect your drivers might be wrong. Try update them if possible.

And next time you post some code, please use the code-tag, or else it will look ugly (like it does now).

newname
03-18-2001, 05:00 PM
Hi, Bob,

Thank you very much for testing my codes.
But do you mean that my display card driver might be wrong? Or something drivers?
Did you try it in Windows or Unix.

I cann't run it in Win2K because the program always terminates at calling ChoosePixelFormat(). So I do programming in win98.



[This message has been edited by newname (edited 03-18-2001).]

Bob
03-19-2001, 02:41 AM
Oh, sorry for not saying. I use Win2k, and there was no problem at all.

And yes, I say that your drivers might be a tad buggy. Try update them is you can. Newest drivers are always good.