I'm trying to render 2D text over a 3D scene. The 2D text is loaded using freetype from a TTF font and uses an orthographic projection to render and the scene uses a perspective projection using my camera. I have modified the code from this Learn OpenGL tutorial for text rendering. I can render the text by itself and the 3D scene separately however the 2D text does not appear when drawing them together.
My render function:
void Engine::render()
{
std::string fpsStr = std::to_string(fps).substr(0, std::to_string(fps).find(".") + 3);
glViewport(0, 0, surface_width, surface_height);
glClearColor(0.53f, 0.8f, 0.92f, 1.0f);
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 3D scene gets rendered here
scene->render(display, surface, deltaTime);
//
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Text gets rendered here
debugText.renderText(fpsStr,25.0f, 25.0f, 1.0f, glm::vec3(0.0, 0.0, 0.0));
//
glDisable(GL_BLEND);
eglSwapBuffers(display, surface);
}
The text projection is a member variable (glm::mat4) that is initialized during creation of the text rendering class like so:
...
projection = glm::ortho(0.0f, static_cast<float>(screenWidth), 0.0f, static_cast<float>(screenHeight));
...
My render text function:
void Font::renderText(std::string text, float x, float y, float scale, glm::vec3 colour)
{
// activate corresponding render state
textShader.use();
textShader.setMat4("projection", projection);
textShader.setVec3("textColor", colour);
glActiveTexture(GL_TEXTURE0);
// iterate through all characters
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++)
{
Character ch = characters[*c];
float xpos = x + ch.bearing.x * scale;
float ypos = y - (ch.size.y - ch.bearing.y) * scale;
float w = ch.size.x * scale;
float h = ch.size.y * scale;
// update VBO for each character
float vertices[6][4] = {
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos, ypos, 0.0f, 1.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos + w, ypos + h, 1.0f, 0.0f }
};
// render glyph texture over quad
glBindTexture(GL_TEXTURE_2D, ch.textureID);
// update content of VBO memory
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// render quad
glDrawArrays(GL_TRIANGLES, 0, 6);
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
x += (ch.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64)
}
glBindTexture(GL_TEXTURE_2D, 0);
}
Here are two images, in this one I'm only rendering the text and in this one I've enabled both the 3D scene and the text, however only the 3D scene is displayed.
How can I overlay this 2D perspective over the 3D scene so they both get rendered?
You have said that rendering them (the 2D quad and 3D scene) separately works fine but rendering them together works causes the 2D quad not to render. Hmmm, try checking your rendering order of the objects; make sure you are binding and unbinding your shaders correctly. Is there a particular reason you have disabled depth testing for the text (try enabling it and see if that fixes the problem) ?