title: Depth test inverted by default in OpenGL, or did I get it wrong?
body: <p>I've been playing around with OpenGL for a full week or equivalent.
  After 2D I'm now trying 3D. I want to reproduce the 3D scene you can see in the third video on <a href="http://johnnylee.net/projects/wii/" rel="nofollow noreferrer">http://johnnylee.net/projects/wii/</a>.<br>
  I've had a hard time making everything work properly with textures and depth.</p>
  
  <p>I've had recently 2 problems that have somewhat visually the same impact :</p>
  
  <ul>
  <li>One with textures that do not blend well in 3D using the techniques I've found for 2D.</li>
  <li>One with objects appearing bottom above top.
  Like the problem exposed here: <a href="https://stackoverflow.com/questions/1046029/depth-buffer-in-opengl">Depth Buffer in OpenGL</a></li>
  </ul>
  
  <p><strong>I've solved both problem, but I would like to know if I get things right</strong>, <em>especially for the second point</em>.</p>
  
  <p><br/></p>
  
  <p><strong>For the first one</strong>, I think I've got it.
  I have an image of a round target, with alpha for anything outside the disc. It's loaded fine inside OpenGL.
  Some (due to my z-ordering problem) other targets behind it suffered from being hidden by the transparent regions of the naturally square quad I used to paint it.</p>
  
  <p>The reason for that was that every part of the texture is assumed to be full opaque with regard for the depth buffer.
  Using an <code>glEnable(GL_ALPHA_TEST)</code> with an test for <code>glAlphaFunc(GL_GREATER, 0.5f)</code> makes the alpha layer of the texture act as a per pixel (boolean) opacity indicator, and thus makes the blending quite useless (because my image has boolean transparency).</p>
  
  <p>Supplementary question: <em>By the way, is there a mean of specifying a different source for the alpha test than the alpha layer used for blending?</em></p>
  
  <p><br/></p>
  
  <p><strong>Second</strong>, I've found a fix to my problem.
  Before clearing the color and depth buffer I've set the default depth to 0 <code>glClearDepth(0.0f)</code> and and I've make use of "greater" depth function <code>glDepthFunc(GL_GREATER)</code>.</p>
  
  <p>What looks strange to me is that depth is 1.0 and the depth function is "less" <code>GL_LESS</code> by default.
  I'm basically inverting that so that my objects don't get displayed inverted...</p>
  
  <p>I've seen nowhere such a hack, but in the other hand I've seen nowhere objects getting drawn systematically in the wrong order, <em>regardless of which order I draw them</em>!</p>
  
  <p><br/></p>
  
  <p>OK, here's the bit of code (stripped down, not too much I hope) that is <em>now</em> working as I want:</p>
  
  <pre><code>    int main(int argc, char** argv) {
          glutInit(&amp;argc, argv);
          glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
          glutInitWindowSize(600, 600); // Size of the OpenGL window
          glutCreateWindow("OpenGL - 3D Test"); // Creates OpenGL Window
          glutDisplayFunc(display);
          glutReshapeFunc(reshape);
  
          PngImage* pi = new PngImage(); // custom class that reads well PNG with transparency
          pi-&gt;read_from_file("target.png");
          GLuint texs[1];
          glGenTextures(1, texs);
          target_texture = texs[0];
          glBindTexture(GL_TEXTURE_2D, target_texture);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          glTexImage2D(GL_TEXTURE_2D, 0, pi-&gt;getGLInternalFormat(), pi-&gt;getWidth(), pi-&gt;getHeight(), 0, pi-&gt;getGLFormat(), GL_UNSIGNED_BYTE, pi-&gt;getTexels());
  
          glutMainLoop(); // never returns!
          return 0;
      }
  
      void reshape(int w, int h) {
          glViewport(0, 0, (GLsizei) w, (GLsizei) h);
          glMatrixMode(GL_PROJECTION);
          glLoadIdentity();
          gluOrtho2D(-1, 1, -1, 1);
          gluPerspective(45.0, w/(GLdouble)h, 0.5, 10.0);
          glMatrixMode(GL_MODELVIEW);
          glLoadIdentity();
      }
  
      void display(void) {
          // The stared *** lines in this function make the (ugly?) fix for my second problem
          glClearColor(0, 0, 0, 1.00);
          glClearDepth(0);          // ***
          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
          glShadeModel(GL_SMOOTH);
          glEnable(GL_DEPTH_TEST);
          glEnable(GL_DEPTH_FUNC);  // ***
          glDepthFunc(GL_GREATER);  // ***
  
          draw_scene();
  
          glutSwapBuffers();
          glutPostRedisplay();
      }
  
      void draw_scene() {
          glMatrixMode(GL_MODELVIEW);
          glLoadIdentity();
          gluLookAt(1.5, 0, -3, 0, 0, 1, 0, 1, 0);
  
          glColor4f(1.0, 1.0, 1.0, 1.0);
          glEnable(GL_TEXTURE_2D);
          // The following 2 lines fix the first problem
          glEnable(GL_ALPHA_TEST);       // makes highly transparent parts
          glAlphaFunc(GL_GREATER, 0.2f); // as not existent/not drawn
          glBindTexture(GL_TEXTURE_2D, target_texture);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          // Drawing a textured target
          float x = 0, y = 0, z = 0, size = 0.2;
          glBegin(GL_QUADS);
          glTexCoord2f(0.0f, 0.0f);
          glVertex3f(x-size, y-size, z);
          glTexCoord2f(1.0f, 0.0f);
          glVertex3f(x+size, y-size, z);
          glTexCoord2f(1.0f, 1.0f);
          glVertex3f(x+size, y+size, z);
          glTexCoord2f(0.0f, 1.0f);
          glVertex3f(x-size, y+size, z);
          glEnd();
          // Drawing an textured target behind the other (but drawn after)
          float x = 0, y = 0, z = 2, size = 0.2;
          glBegin(GL_QUADS);
          glTexCoord2f(0.0f, 0.0f);
          glVertex3f(x-size, y-size, z);
          glTexCoord2f(1.0f, 0.0f);
          glVertex3f(x+size, y-size, z);
          glTexCoord2f(1.0f, 1.0f);
          glVertex3f(x+size, y+size, z);
          glTexCoord2f(0.0f, 1.0f);
          glVertex3f(x-size, y+size, z);
          glEnd();
      }
  </code></pre>