glPushAttrib ?

Hi,
why does glPushAttrib not work ?


float depth1[1];
float depth2[1];
float depth3[1];

glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

glReadPixels(lMousePos.x,lMousePos.y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,depth1);

glClear(GL_DEPTH_BUFFER_BIT);
glPopAttrib();
glReadPixels(lMousePos.x,lMousePos.y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,depth2);

glReadPixels(lMousePos.x,lMousePos.y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,depth3);

depth1 is between 0 and 1
depth2 and depth3 are 1, mit should be the same as depth1…

I want to render a Model and get the depth of this Model, WITHOUT influence of others. So I must clear the depth buffer, draw my Model, and restore the depth buffer.

But why does the restore not work ? :frowning:

why does glPushAttrib not work ?

Because you apparently misunderstood the PushAttrib function. These are the states that glPushAttrib(GL_DEPTH_BUFFER_BIT) saves:

  • GL_DEPTH_TEST enable bit
  • Depth buffer test function
  • Depth buffer clear value
  • GL_DEPTH_WRITEMASK enable bit

Nothing more. So depth buffer data is not saved. Even if it was, it would require a buffer copy which is expensive. Instead, render your model in a first pass with depth test enabled, read depth values you need. Then clear the depth buffer if necessary and draw the rest of the geometry in a second pass.

So what does that:

glPushAttrib(GL_COLOR_BUFFER_BIT | GL_PIXEL_MODE_BIT); // for GL_DRAW_BUFFER and GL_READ_BUFFER
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK);

But the Model should be rendered “off screen”, a second time. First I want to render it normally, then render it invisible and get the depth values.
How can I achieve that ? Nothing of the methods I tried worked… Even FBO didn’t work:

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);

glClearColor(1,1,1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

m.Display();

glReadPixels(lMousePos.x,lMousePos.y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,depth);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // unbind

Here the depth is also erased :frowning:

why u need to render ur model two times ?
u can render ur model and than do a glReadPixels to get depth component and that u should work . if u want to use fbo contet with depth writing enabled u need to attach a texture or render buffer with GL_DEPTH_ATTACHMENT_EXT

I want to render it a second time cause I don’t know when exactly I need the depth. I want to write a lib for selecting objects.

So I have to get the depth if the mouse is clicked.

mouse click -> function isClicked(Model m)

Then I want to render the object without displaying it and get the depth without writing the depth to the “original” scene.
P.S. the other models should not influence the depth, therefore “glClear(GL_DEPTH_BUFFER_BIT)”

How can I do that ?

the best and fast way to do this, is to render ur object to an fbo with a texture attached to it as GL_DEPTH_ATTACHMENT_EXT, then when the user click you can upload the depth texture to a pbo, and than map ur pbo to host memory and do some cpu work with the depth values .

Have you code for that ? I still don’t understand… :frowning:

DarkShadow44, a simple way to make it work (probably slower than with a depth texture) is to readpixels data before, do your stuff, then drawpixels after with backuped data.

A question, why do you need to restore the depth buffer ?
Just clear, draw model 1, test, clear, draw model 2 test, etc : just do not swapbuffers, so that all happens without being seen.

I want to be able to:

  1. draw visible Models
  2. draw invisible Models + check for depth
  3. draw visible Models

So if I clean the buffer at 2 the first model’s values are deleted… :frowning:

Why can’t I just render the depth into memory ?

@ Abdallah DIB
I don’t know how to implement that :frowning:

EDIT:

I need that for picking. I use gluUnProj, but the depth of other Models influenced the result…

So it would be enough if I know the depth.

EDIT2:
How can I render my Model off-screen and get the depth ?

EDIT3:

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);

glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, rboId);
glReadBuffer (GL_DEPTH_ATTACHMENT_EXT);
glClear( GL_DEPTH_BUFFER_BIT);

m.Display();

glReadPixels(lMousePos.x,lMousePos.y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,(void*) depth);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // unbind

Could there appear problems ?