Culling or Geometry Problems

My understanding of Culling is that if something opaque is in front of something else, whatever is in the back will not be drawn. If this is correct, I’m having problems with the triangle fan. It can be seen through some shapes, but not through others. I’ve shown the drawing code below, and linked to the full code (which includes rotation via the arrow keys, and reset with the space bar) here: http://www.theouterrim.net/Test1.java Would someone please tell me what I’m missing in the geometry here? Thanks.


    protected boolean drawGLScene(float frameTime)
    {
        /* Clear The Screen And The Depth Buffer */
        gl.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT);
        /* Reset The Current Modelview Matrix */
        gl.loadIdentity();
        
        gl.rotatef(angleRotateX, 1.0f, 0.0f, 0.0f);
        gl.rotatef(angleRotateY, 0.0f, 1.0f, 0.0f);
        gl.polygonMode(GL.FRONT_AND_BACK, GL.LINE);
        gl.enable(GL.CULL_FACE);
        gl.frontFace(GL.CW);
        gl.color3f(0.0f, 0.0f, 1.0f);
        gl.begin(GL.TRIANGLE_FAN);
            gl.vertex3f(20.0f, 30.0f, 200.0f);
            gl.vertex3f(20.0f, 40.0f, 0.0f);
            gl.vertex3f(60.0f, 30.0f, -20.0f);
            gl.vertex3f(40.0f, -20.0f, -10.0f);
            gl.vertex3f(20.0f, 40.0f, 0.0f);
        gl.end();
        
        gl.begin(GL.TRIANGLE_FAN);
            gl.vertex3f(-20.0f, 30.0f, 200.0f);
            gl.vertex3f(-40.0f, -20.0f, -10.0f);
            gl.vertex3f(-60.0f, 30.0f, -20.0f);
            gl.vertex3f(-20.0f, 40.0f, 0.0f);
            gl.vertex3f(-40.0f, -20.0f, -10.0f);
        gl.end();
        
        gl.begin(GL.POLYGON);
            gl.vertex3f(-20.0f, 40.0f, 0.0f);
            gl.vertex3f(-60.0f, 30.0f, -20.0f);
            gl.vertex3f(0.0f, 40.0f, -70.0f);
            gl.vertex3f(60.0f, 30.0f, -20.0f);
            gl.vertex3f(20.0f, 40.0f, 0.0f);
        gl.end();
        
        gl.begin(GL.POLYGON);
            gl.vertex3f(40.0f, -20.0f, -10.0f);
            gl.vertex3f(20.0f, -20.0f, -60.0f);
            gl.vertex3f(-20.0f, -20.0f, -60.0f);
            gl.vertex3f(-40.0f, -20.0f, -10.0f);
            gl.vertex3f(40.0f, -20.0f, -10.0f);
        gl.end();
        
        gl.begin(GL.TRIANGLE_STRIP);
            gl.vertex3f(40.0f, -20.0f, -10.0f);
            gl.vertex3f(60.0f, 30.0f, -20.0f);
            gl.vertex3f(20.0f, -20.0f, -60.0f);
            gl.vertex3f(0.0f, 40.0f, -70.0f);
            gl.vertex3f(-20.0f, -20.0f, -60.0f);
            gl.vertex3f(-60.0f, 30.0f, -20.0f);
            gl.vertex3f(-40.0f, -20.0f, -10.0f);
        gl.end();
        
        gl.begin(GL.POLYGON);
            gl.vertex3f(-20.0f, 40.0f, 0.0f);
            gl.vertex3f(20.0f, 40.0f, 0.0f);
            gl.vertex3f(40.0f, -20.0f, -10.0f);
            gl.vertex3f(-40.0f, -20.0f, -10.0f);
        gl.end();
        
        return true;
    }

Not drawing objects that are obscured by other objects is sometimes called “z-buffering” or “occlusion culling”, but in OpenGL it is called “depth testing”.

The “face culling” methods in OpenGL are a fast way of eliminating polygons that can’t be seen - if a polygon is facing away from the camera it can just be ignored.

As to why the triangle fan isn’t being depth tested correctly, you’re clearing the depth buffer to 1.0f, not the more usual 0.0f and you’re specifying a 0 bit depth buffer (in the GL constructor). If you fix those two, the depth-buffering should work correctly.

Just as a warning, you’re pushing more matrices than you’re popping! :wink: Your resizeGLScene method pushes both the projection and modelling matrices, but nothing in the program pops them again. As the projection matrix stack may only be two deep, calling resizeGLScene twice may cause OpenGL to error. You’re not storing the matrixes for any reason, and just loadIdentity straight after, so it’s probably worth just deleting those lines.

So you’re saying that I should change the line:
gl.clearDepth(1.0f);
to:
gl.clearDepth(0.0f);

What should I change the bit depth buffer, specified in the constructor, to?

If I just change gl.clearDepth(1.0f); to gl.clearDepth(0.0f);, then nothing is drawn.

For the resizeGLScene, could you please give me specific line numbers? When I start changing things, nothing gets drawn. However, if you mean just removing the push statement, I’ve removed those and my program still draws.

Thanks.

[quote]So you’re saying that I should change the line:
gl.clearDepth(1.0f);
to:
gl.clearDepth(0.0f);
[/quote]
Sorry, hang on, I’m going mad… No, 1.0f is the default, you’re quite right. Where did I get that from? ::slight_smile: I’ve got my buffers inside out… :-X

[quote]What should I change the bit depth buffer, specified in the constructor, to?
[/quote]
Anything non-zero really. 8 bits would probably suffice.

[quote]For the resizeGLScene, could you please give me specific line numbers? When I start changing things, nothing gets drawn. However, if you mean just removing the push statement, I’ve removed those and my program still draws.
[/quote]
Whenever you have a pushMatrix statement, there should be a corresponding popMatrix at some point. The matrix stacks aren’t infinitely large, and the projection matrix in particular need only be two deep by the OpenGL spec. You’d usually need to pushMatrix if you were about to do something destructive to the current matrix but want to get the current one back later.

So yep, just remove the pushMatrix calls in the resizeGLScene method. The program will still work as expected, but you save yourself a nasty bug further down the line! :wink:

hmmm… That didn’t solve it. I can still see some of it. Since that is about 1/3rd the polygons, this will have some performance issues. Would you advise switching to plain triangles instead of strips? Because the regular polygons aren’t giving me any trouble.

Now I’m onto curves. Everything draws more or less correctly, except if you run the code I’ve provided, on the right side, the top and the side do not meet. This is strange, since they should be the exact same locations.


gl.translatef(15.0f, 36.5f, -20.0f);
        //gl.polygonMode(GL.FRONT_AND_BACK, GL.FILL);
        gl.begin(GL.POLYGON);
            for(int i=90; i>=0; i--)
            {
                  gl.vertex3f(0.0f, (float)(org.lwjgl.Math.sin(i)*15.0f), (float)(org.lwjgl.Math.cos(i)*(-37.5f)));
            }
            gl.translatef(0.0f, -1.5f, 0.0f);
            for(int i=0; i<=90; i++)
            {
                  gl.vertex3f(0.0f, (float)(org.lwjgl.Math.sin(i)*10.0f), (float)(org.lwjgl.Math.cos(i)*(-30.0f)));
            }
        gl.end();
        
        gl.translatef(-30.0f, 1.5f, 0.0f);
        
        gl.begin(GL.POLYGON);
            for(int i=0; i<=90; i++)
            {
                  gl.vertex3f(0.0f, (float)(org.lwjgl.Math.sin(i)*15.0f), (float)(org.lwjgl.Math.cos(i)*(-37.5f)));
            }
            gl.translatef(0.0f, -1.5f, 0.0f);
            for(int i=90; i>=0; i--)
            {
                  gl.vertex3f(0.0f, (float)(org.lwjgl.Math.sin(i)*10.0f), (float)(org.lwjgl.Math.cos(i)*(-30.0f)));
            }
            
        gl.end();
            
            gl.begin(GL.POLYGON);
                  for(int i=0; i<=90; i++)
                 {
                       gl.vertex3f(0.0f, (float)(org.lwjgl.Math.sin(i)*10.0f), (float)(org.lwjgl.Math.cos(i)*(-30.0f)));
                 }
              //gl.translatef(0.0f, 0.0f, 0.0f);    
                 for(int i=90; i>=0; i--)
                 {
                       gl.vertex3f(30.0f, (float)(org.lwjgl.Math.sin(i)*10.0f), (float)(org.lwjgl.Math.cos(i)*(-30.0f)));
                 }
            gl.end();
            
            gl.translatef(0.0f, 1.5f, 0.0f);
            gl.begin(GL.POLYGON);
                  for(int i=90; i>=0; i--)
                 {
                       gl.vertex3f(0.0f, (float)(org.lwjgl.Math.sin(i)*15.0f), (float)(org.lwjgl.Math.cos(i)*(-37.5f)));
                 }
                 for(int i=0; i<=90; i++)
                 {
                       gl.vertex3f(31.0f, (float)(org.lwjgl.Math.sin(i)*15.0f), (float)(org.lwjgl.Math.cos(i)*(-37.5f)));
                 }
            gl.end();

Edit: Sorry for the wierd tabbing. I can’t get this thing to display it perfectly.

Nevermind, I fixed it. It has something to do with my translate calls. Not sure what, but I removed to translate calls within the gl.begin and gl.end and edited the values. For some reason, that fixed it. Can’t translate calls be put within a gl.begin/gl.end?

[quote]Can’t translate calls be put within a gl.begin/gl.end?
[/quote]
Ah, no. The only commands valid between a glBegin and a glEnd are as follows:

[]glVertex
[]glColor
[]glIndex
[]glNormal
[]glEvalCoord
[]glTexCoord
[]glEdgeFlag
[]glMaterial
[*]glCallList(s)

While within a begin/end pair you’re supposed to be defining vertices to make up an OpenGL primitive of some kind. Anything that isn’t directly concerned with this process or changes the context in which those vertex calls are made is disallowed.

grr… argh… How do I make requests for the next OpenGL specification? j/k ;D