PDA

View Full Version : depth buffer and lighting



ale211734
02-03-2015, 08:17 AM
Hello, I am trying to understand how work enable depth buffer with glDepthMask(false) and glDepthFunc(GL_GREATER).

I try to render the first frame with a depth buffer enabled and glDepthMask(true)

this generate my depth mask to apply to successive render frame.

the successive frame I translate and update offset variable and translate the object along z negative.
The object translate result behind the initial object (object render at the first frame with zero offset) so I expected that
cause glDepthFunc(GL_GREATER) it should be rendered. But I saw that lighting is incorrect and I don't understand
why? The object without lighting is render as I expected while with light enabled I saw it incorrect. Any idea?



void GLApp::initializeGL()
{
GLint alpha_bits;
glGetIntegerv(GL_ALPHA_BITS, & alpha_bits);

GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 100.0 };
GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 0.0, 0.0, 1.0, 0.0 };
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);

glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glEnable(GL_NORMALIZE);
glEnable(GL_POINT_SMOOTH);
glShadeModel (GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
GLenum err = glewInit();
if (GLEW_OK != err)
{
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
}
glClear(GL_DEPTH_BUFFER_BIT);
makeCurrent();
}


void GLApp::paintGL()
{
static bool first=true;
if (lighting) glEnable(GL_LIGHTING);
else glDisable(GL_LIGHTING);

glClearColor(0.0,0.0,0.0,0.0);
glEnable(GL_DEPTH_TEST);

glClear(GL_COLOR_BUFFER_BIT);
glViewport(0,0, this->width(),this->height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) this->width()/(GLfloat) this->height(), 0.1, farPlane);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0,0,-5);
if (first)
{
glDepthMask(GL_TRUE);
first=false;
glColor3f(1,1,1);
}
else
{
glTranslatef(0,0,offset);
glDepthFunc(GL_GREATER);
glDepthMask(GL_FALSE);
}
glutSolidTeapot(1);

renderText(0,height()-20,QString("offset ")+QString::number(offset));
renderText(0,height()-10,QString("farPlane ")+QString::number(farPlane));
}





Here the result with and without lighting.

Alfonse Reinheart
02-03-2015, 08:43 AM
Hello, I am trying to understand how work enable depth buffer with glDepthMask(false) and glDepthFunc(GL_GREATER).

By passing GL_FALSE to glDepthMask, you're saying that you don't want the fragment's depth to be written. This won't stop the depth test comparison, but it does mean that, even if the test passes, the fragment's depth will not be updated with new values.

That's not necessarily wrong (blending being a useful use-case for this). I just want to make sure that this is what you want to do.

ale211734
02-03-2015, 09:16 AM
ok I use depth in read only when render after the first pass. But I don't understand why the teapot is complete dark, I expected were illuminated.
GLfloat light_position[] = { 0.0, 0.0, 1.0, 0.0 }. What's change in light calculation when I use a depth mask calculate at the first render frame?
Maybe I'm missing something because the calculation of the light on the fragments seems wrong.

GClements
02-03-2015, 02:31 PM
I suspect that the problem is that the back of the teapot (the part farthest from the viewpoint) is being drawn last.

If you render with glDepthMask(GL_FALSE), whichever faces are drawn last will overwrite those which are drawn first, regardless of depth. If the back faces are drawn last, you're looking at the inside of the teapot. Unless you enable two-sided lighting (with glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1)), the inside of the teapot will be dark because the normals are pointing away from the light.

If you disable lighting, there's no difference between front and back faces..

Try glEnable(GL_CULL_FACE) and glCullFace() (the correct argument depends upon how the teapot is constructed) to avoid drawing back faces.

ale211734
02-04-2015, 02:53 AM
I suspect that the problem is that the back of the teapot (the part farthest from the viewpoint) is being drawn last.

If you render with glDepthMask(GL_FALSE), whichever faces are drawn last will overwrite those which are drawn first, regardless of depth. If the back faces are drawn last, you're looking at the inside of the teapot. Unless you enable two-sided lighting (with glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1)), the inside of the teapot will be dark because the normals are pointing away from the light.

If you disable lighting, there's no difference between front and back faces..

Try glEnable(GL_CULL_FACE) and glCullFace() (the correct argument depends upon how the teapot is constructed) to avoid drawing back faces.

I think you are right, although I do not understand why the color of teapot continue to be dark instead of white.



GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 100.0 };
GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_diffuse_back[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat light_position[] = { 0.0, 0.0, 1.0, 0.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

//glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
/*glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
glEnable(GL_NORMALIZE);
glEnable(GL_POINT_SMOOTH);
glShadeModel (GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glMaterialfv ( GL_FRONT_AND_BACK , GL_AMBIENT_AND_DIFFUSE , mat_diffuse );

and this image, left part is with two side model light and the right part I add glEnable(GL_CULL_FACE)1615