Note that there are some explanatory texts on larger screens.

plurals
  1. PODepth test inverted by default in OpenGL, or did I get it wrong?
    primarykey
    data
    text
    <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>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload