Question

I'm using Assimp to render 3D models with OpenGL ES 2.0. I'm currently having a strange problem in which some parts of the model are not visible, even when they should be. It's easy to see it in these pictures:

Textured model

In this second image I rendered (a linearized version of) the z-buffer into screen to see if it could be a z-buffer problem. Black pixels are near the camera:

zbuffer render

I tried to change values for z-near and z-far without any effect. Right now I do that on initialisation:

glEnable(GL_CULL_FACE);// Cull back facing polygons
glEnable(GL_DEPTH_TEST);

And I'm also doing that for every frame:

glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

I thought it could be a face winding problem, so I tried to disable GL_CULL_FACE, but it didn't work. I'm pretty sure the model is fine, since Blender can render it correctly.

I'm using these shaders right now:

// vertex shader
uniform mat4 u_ModelMatrix; // A constant representing the model matrix.
uniform mat4 u_ViewMatrix; // A constant representing the view matrix.
uniform mat4 u_ProjectionMatrix; // A constant representing the projection matrix.

attribute vec4 a_Position; // Per-vertex position information we will pass in.
attribute vec3 a_Normal; // Per-vertex normal information we will pass in.
attribute vec2 a_TexCoordinate; // Per-vertex texture coordinate information we will pass in.

varying vec3 v_Position; // This will be passed into the fragment shader.
varying vec3 v_Normal; // This will be passed into the fragment shader.
varying vec2 v_TexCoordinate; // This will be passed into the fragment shader.


void main()
{
    // Transform the vertex into eye space.
    mat4 u_ModelViewMatrix = u_ViewMatrix * u_ModelMatrix;
    v_Position = vec3(u_ModelViewMatrix * a_Position);

    // Pass through the texture coordinate.
    v_TexCoordinate = a_TexCoordinate;

    // Transform the normal's orientation into eye space.
    v_Normal = vec3(u_ModelViewMatrix * vec4(a_Normal, 0.0));

    // gl_Position is a special variable used to store the final position.
    // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
    gl_Position = u_ProjectionMatrix * u_ModelViewMatrix * a_Position;
}

And this is the fragment shader:

// fragment shader
uniform sampler2D u_Texture; // The input texture.
uniform int u_TexCount;

varying vec3 v_Position; // Interpolated position for this fragment.
varying vec3 v_Normal; // Interpolated normal for this fragment.
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.

// The entry point for our fragment shader.
void main()
{
    vec3 u_LightPos = vec3(1.0);
    // Will be used for attenuation.
    float distance = length(u_LightPos - v_Position);

    // Get a lighting direction vector from the light to the vertex.
    vec3 lightVector = normalize(u_LightPos - v_Position);

    // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
    // pointing in the same direction then it will get max illumination.
    float diffuse = max(dot(v_Normal, lightVector), 0.0);

    // Add attenuation.
    diffuse = diffuse * (1.0 / distance);

    // Add ambient lighting
    diffuse = diffuse + 0.2;
    diffuse = 1.0;

    //gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));// Textured version

    float d = (2.0 * 0.1) / (100.0 + 0.1 - gl_FragCoord.z * (100.0 - 0.1));
    gl_FragColor = vec4(d, d, d, 1.0);// z-buffer render
}

I'm using VBO with indices to load the geometry and stuff.

Of course I can paste some other code you think it may be relevant, but for now I'm happy to get some ideas of what can cause this strange behavior, or some possible tests I can do.

Was it helpful?

Solution

Ok, I solved the problem. I post the solution since it may be useful to future googlers.

Basically I didn't request a Depth Buffer. I'm doing all the render stuff in native code, but all the Open GL context initialization is done in the Java side. I used one of the Android samples (GL2JNIActivity) as a starting point, but they didn't request any depth buffer and I didn't notice that.

I solved it setting the depth buffer size to 24 when setting the ConfigChooser:

setEGLConfigChooser( translucent ?
                         new ConfigChooser(8, 8, 8, 8, 24 /*depth*/, 0) :
                         new ConfigChooser(5, 6, 5, 0, 24 /*depth*/, 0 );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top