2

I'm having a strange problem which I cannot figure out for the life of me. I'm loading an OBJ model file from Maya and rendering it an OpenGL environment. This appears to go well and in my independent model viewer, they display correctly. However, when loaded into the game environment (with a somewhat strange projection matrix that I have no control over), the model does NOT display correctly.

The vertices SEEM to be in the correct place in that rotating the model gives the correct sense of 3D. However, depending on the depth function, different parts of the model appear (incorrectly).

For example, in a model of a person, when the person is walking from left to right (e.g. the right side of the model is visible to the camera); if the depth function is set to GL_LEQUAL, you are unable to see the right arm of the person when it is in front of the torso. However, when the mode is set to GL_LESS, you are able to see the left arm through the torso. This is one of those things that are easier to see with pictures so here we go:

GL_LESS or GL_NOTEQUAL:

enter image description here enter image description here

GL_LEQUAL or GL_ALWAYS:

enter image description here enter image description here enter image description here

It should be noted that nothing is displayed with any other depth function. In the first picture of the GL_LEQUAL series, you can just about see the left arm is partially obscured by the torso when it shouldn't be.

Here is the code used to render the model:

gl.glDisable(GL.GL_BLEND);
    gl.glMatrixMode(GL.GL_MODELVIEW);
    gl.glPushMatrix();
    gl.glLoadIdentity();

    layerTextureShader.updateShader(gl, projection, disparityTop, disparityBottom, fieldMask, 1);

    // gl.glDepthFunc(GL.GL_NEVER); // 512
    // gl.glDepthFunc(GL.GL_LESS); // 513
    // gl.glDepthFunc(GL.GL_EQUAL); // 514
    // gl.glDepthFunc(GL.GL_LEQUAL); // 515
    // gl.glDepthFunc(GL.GL_GREATER); // 516
    // gl.glDepthFunc(GL.GL_NOTEQUAL); // 517
    // gl.glDepthFunc(GL.GL_GEQUAL); // 518
    // gl.glDepthFunc(GL.GL_ALWAYS); // 519
    gl.glDepthFunc(currentGlComparison);

    gl.glEnable(GL.GL_DEPTH_TEST);
    gl.glClear(GL.GL_DEPTH_BUFFER_BIT);

    gl.glDepthMask(true);
    gl.glDepthRange(0, 0.01);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getVertexBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 3 * 4, getVertices(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 2 * 4, getTexCoords(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, getIndicesBufferObject());
    gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, getNoOfIndices() * 4, getIndices(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);

    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getColorBufferObject());
    gl.glBufferData(GL.GL_ARRAY_BUFFER, getNoOfVertices() * 4 * 4, getColors(), GL.GL_STREAM_DRAW);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glEnable(GL.GL_TEXTURE_2D);
    gl.glActiveTexture(GL.GL_TEXTURE0);

    layerTextureShader.use(gl);

   gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getVertexBufferObject());
    gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);

    gl.glEnableClientState(GL.GL_COLOR_ARRAY);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, mask ? getMaskColorBufferObject() : getColorBufferObject());
    gl.glColorPointer(4, GL.GL_FLOAT, 0, 0);

    gl.glClientActiveTexture(GL.GL_TEXTURE0);

    gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, getTexCoordBufferObject());
    gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);

    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, getIndicesBufferObject());

    final int count = getNoOfIndices();
    gl.glDrawElements(GL.GL_TRIANGLES, count, GL.GL_UNSIGNED_INT, 0);

    gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
    gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

    gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL.GL_COLOR_ARRAY);
    gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);

    layerTextureShader.release(gl);

    gl.glDisable(GL.GL_TEXTURE_2D);

    gl.glDisable(GL.GL_DEPTH_TEST);
    gl.glEnable(GL.GL_BLEND);
    gl.glPopMatrix();

Thanks to anyone for any help, this has had me stumped for quite a few days now.

unwind
  • 391,730
  • 64
  • 469
  • 606
Sonoman
  • 3,379
  • 9
  • 45
  • 61
  • typically you would use LESS, but from the images, it looks like the projection matrix is "flattening" the model so all vertices are in the same depth. would need more information about how the projection is setup to really answer this – Shezan Baig Jan 25 '11 at 13:20
  • Thanks for the insight, so would you suggest I perform some calculations (e.g. GL_Projection * GL_ModelView * GameProjectionMatrix * PointXYZ) to see what is actually being printed? – Sonoman Jan 25 '11 at 13:51
  • My GL_Projection matrix is an ortho2D matrix set up with a call to `gluOrtho2d(0, 1920, 0, 1080);` and the GameProjection matrix is odd as I mentioned with values `[192, 2807, 7, -2.4e7; -825, 49, -2869, -1.2e7; 0.9, -0.06, -0.29, 68059; 0, 0, 1.49e-8, -0.9]` I'm aware this is odd but it IS neccessary and other elements are displayed correctly using it (i.e. not-model elements. So I am unable to see how this would result in all Z values being flattened, but I hear I am missing something blindingly obvious... – Sonoman Jan 25 '11 at 13:55
  • You know, that you can switch the projection and modelview matrix anytime you want in the rendering process? If you're using those values to make up for and HUD or similar: Just set appropriate projection just for the HUD and use sane values for the model. – datenwolf Jan 25 '11 at 16:49

1 Answers1

2

Looks like the projection matrix is set like this:

gluPerspective ( 90, (GLint)width/ (GLint)height, 0.0, 200.0 );  

See the mistake ? - 0.0 value is not acceptable. Only positive values are good Use something like 0.01 instead of 0.0 as third argument.

Andrew
  • 24,218
  • 13
  • 61
  • 90
  • Thanks for the help. Unfortunately, the matrix is set using glFrustrum using all positive values. `gl.glFrustum(-960, 960, -540, 540, 0.01, 100);` is what I use. – Sonoman Jan 25 '11 at 13:43
  • The near clip plane if far to close to the origin. Also those values in glFrustum make no sense, this would give you an affine field of view of nearly 180°, it's hardly what you want. – datenwolf Jan 25 '11 at 16:46