Search code examples
c++opengl-esdepth-bufferdepth-testing

Depth Buffer Not Working With Multiple Shader Programs


I am writing a 3D graphics renderer in C++ using OpenGL-ES for a handheld system and I am utilizing a decal (texture) shader, as well as a color-fill shader. I have two render passes where I use the respective program and use Array/Element buffers to draw data using glDrawElements.

Although I enable GL_DEPTH_TEST in my application, my decal polygons always render in front of my color-filled polygons.

I have tried reworking how my projection/modelView matrices are built and passed to the shaders, I have tried different glDepthFunc parameters but I am not able to get them to render properly.

This is my draw code - I start each frame with

glClearColor(0.25f, 0.25f, 0.25f, 1.f);
glClearDepthf(1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Then I calculate world-space polygon coordinates and arrange it into GLfloat vectors. I draw the decal data first:

GLuint programId = decalProgramId;
glUseProgram(programId);

// All of my uniform params are setup here - omitting to save space

// Set proj/mv matrices
glUniformMatrix4fv(glGetUniformLocation(programId, "uProjection"), 1, GL_TRUE, static_cast<f32*>(gameEngine.proj));
glUniformMatrix4fv(glGetUniformLocation(programId, "uModelView"), 1, GL_TRUE, static_cast<f32*>(gameEngine.modelView));

// Then I prepare the buffer data
glBindBuffer(GL_ARRAY_BUFFER, decalBufferId);
glBufferData(GL_ARRAY_BUFFER, coordSize + texCoordSize, 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, coordSize, &coords[0]);
glBufferSubData(GL_ARRAY_BUFFER, coordSize, texCoordSize, &texCoords[0]);

// And element array buffer data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, decalElementBufferId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, &indices[0], GL_STATIC_DRAW);

// Enable our vertex attributes
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(coordSize));

// Bind my test texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// Draw the elements
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, 0);

The process is then repeated with my color polygons. Followed by SwapBuffer and WaitVSync commands.

Here is my code for creating one of the triangles and the front face of the cube:

// Add polygon directly to the scene object
scene.AddPolygon(polygonBuilder
    .AddVertex(Vector3(0.5f, 0.5f, 0.f), Vector4(0.f, 0.f, 1.f, 1.f))
    .AddVertex(Vector3(0.25f, 0.f, 0.f), Vector4(0.f, 1.f, 0.f, 1.f))
    .AddVertex(Vector3(0.75f, 0.f, 0.f), Vector4(1.f, 0.f, 0.f, 1.f))
    .AddIndex(0).AddIndex(1).AddIndex(2)
    .Build()
);

// Create a polygon within the crate object
crateObject.AddPolygon(polygonBuilder
    .AddVertex(Vector3(-0.25f, 0.25f, 0.f), Vector2(0.f, 0.f))
    .AddVertex(Vector3(-0.25f, -0.25f, 0.f), Vector2(0.f, 1.f))
    .AddVertex(Vector3(0.25f, -0.25f, 0.f), Vector2(1.f, 1.f))
    .AddVertex(Vector3(0.25f, 0.25f, 0.f), Vector2(1.f, 0.f))
    .SetTexture("crate")
    .AddIndex(0).AddIndex(1).AddIndex(3)
    .AddIndex(3).AddIndex(1).AddIndex(2)
    .Build()
);

// Add the crate object as a child within the scene
scene.AddChild(crate);

This screenshot is the current output when I create two colored triangles and one textured cube:

Render Error

The blue arrow indicates a triangle that should have rendered in the front. Any ideas?


Solution

  • I feel really silly now. My color shader was not properly applying the model-view matrix. It was always rendering at a fixed depth.

    I modified my color shader code to apply the matrix the same way as the decal and now it works perfectly.

    Working Render