Dabrorius
Dabrorius

Reputation: 1039

OpenGL depth problem

I'm having problem with rendering depth in OpenGL

Following code is a simple example of code in which problem occurs. It renders 2 trapezoids in same place, and one of them rotates. But the rotating one is always displayed on top, even though it should go behind the first trapezoid while rotating.

I guess I messed up something with initializing OpenGL. Also while searching through stackoverflow i found a post where someone suggested to execute following code and see the output.

int depth;
glGetIntegerv(GL_DEPTH_BITS, &depth);
printf("%i bits depth", depth);

well the output is, 0 bits depth, which isn't good I guess :(

I'm developing on a Mac, in xCode with glfw library

#include <GL/glfw.h>
#include <stdlib.h>

int main( void )
{
   int running = GL_TRUE;

   if( !glfwInit() )
   {
      exit( EXIT_FAILURE );
   }

   // Open an OpenGL window
   if( !glfwOpenWindow( 640,480, 0,0,0,0,0,0, GLFW_WINDOW ))
   {
      glfwTerminate();
      exit( EXIT_FAILURE );
   }

   glEnable(GL_DEPTH_TEST);

   float angle = 0;

   // Main loop
   while( running )
   {

      double elapsedTime = glfwGetTime();
      glfwSetTime(0);
      angle += 90 * elapsedTime;

      // OpenGL rendering goes here...
      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();

      glPushMatrix(); //Save the transformations performed thus far
      glColor3f(1.0f, 1.0, 0.0);
      glTranslatef(0.0f, 0.0f, 0.0f); //Move to the center of the trapezoid
      //glRotatef(angle, 0.0f, 1.0f, 0.0f); //Rotate about the y-axis
      glBegin(GL_QUADS);

      //Trapezoid
      glVertex3f(-0.7f, -0.5f, 0.0f);
      glVertex3f(0.7f, -0.5f, 0.0f);
      glVertex3f(0.4f, 0.5f, 0.0f);
      glVertex3f(-0.4f, 0.5f, 0.0f);

      glEnd();

      glPopMatrix();

      glPushMatrix(); //Save the transformations performed thus far
      glColor3f(1.0f, 0.0, 0.0);
      glTranslatef(0.0f, 0.0f, 0.0f); //Move to the center of the trapezoid
      glRotatef(angle, 0.0f, 1.0f, 0.0f); //Rotate about the y-axis
      glBegin(GL_QUADS);

      //Trapezoid
      glVertex3f(-0.7f, -0.5f, 0.0f);
      glVertex3f(0.7f, -0.5f, 0.0f);
      glVertex3f(0.4f, 0.5f, 0.0f);
      glVertex3f(-0.4f, 0.5f, 0.0f);

      glEnd();

      glPopMatrix(); //Undo the move to the center of the trapezoid

      glfwSwapBuffers();

      // Check if ESC key was pressed or window was closed
      running = !glfwGetKey( GLFW_KEY_ESC ) &&
      glfwGetWindowParam( GLFW_OPENED );
   }

   // Close window and terminate GLFW
   glfwTerminate();
   // Exit program
   exit( EXIT_SUCCESS );
}

Upvotes: 4

Views: 2490

Answers (3)

Clemens
Clemens

Reputation: 53

glGetIntegerv( GL_DEPTH_BITS, ..) is deprecated in OpenGL 3

use instead :

int GetDepthBits()
{
  HDC hdc = wglGetCurrentDC();
  int iPixelFormat = GetPixelFormat( hdc);
  int iAttr[] = {WGL_DEPTH_BITS_ARB};
  int iDepthBits;
  wglGetPixelFormatAttribivARB( hdc, iPixelFormat, 0, 1, iAttr, & iDepthBits);
  return iDepthBits;
}

Upvotes: 0

Chris Mennie
Chris Mennie

Reputation: 674

If you are drawing polygons on top of each other you are not guaranteed the order you draw them in will be the order they are rendered. It may work one way on one driver and another way on the next. Same with drivers from different vendors.

You have to either add a tiny depth difference in your glVertex commands or play with glPolygonOffset(). Or do a glFlush() after the first polygon, which is extremely inefficient.

By using a depth buffer you're telling the graphics card that it can render triangles in whatever order it chooses because the depth buffer will sort out what's drawn in front. This is why in some games you'll see polygons flickering through each other (especially things in the distance) when they map to the same depth value.

Upvotes: 2

Nicol Bolas
Nicol Bolas

Reputation: 473537

if( !glfwOpenWindow( 640,480, 0,0,0,0,0,0, GLFW_WINDOW ))

Why do you pass all of those zeros? Those parameters are kind of important. The GLFW reference documentation (pdf) shows that those parameters describe how many bits you want for the colors, depth, and stencil. The next-to-last zero is the number of depth bits. You asked for 0 bits of depth for the framebuffer, so that's what you got.

You can't blame the API for doing what you asked ;)

A more reasonable command would be:

if( !glfwOpenWindow( 640,480, 8, 8, 8, 8, 24, 8, GLFW_WINDOW ))

This gives you 8 bits each for RGBA, 24 for depth, and 8-bits of stencil.

Upvotes: 5

Related Questions