Hello! I’m fairly new to OpenGL and experimenting with various aspects of it. Right now, I am simply experimenting with rendering a handful of textured quads and the legendary teapot. However, I noticed that, depending on the order in which the various entities were being rendered, I received undesired results. Here are a few quick screenshots to demonstrate the problem. Clearly, even if the background is being rendered last, the Z-buffer should be sorting it properly regardless of render order. However, that is not happening, and it leads me to believe I have flubbed somewhere.
With Background - Rendered Last
No Background
I’m currently using SFML to assist with a few minor things so that I can focus on specific aspects at the moment.
Here is the InitRendering() function which is called shortly after boot-up. It creates the SFML window and handles general OpenGL setup and image loading.
bool InitRendering()
{
// Create the main window
gp_app = new sf::Window( sf::VideoMode(400, 400, 32), "SFML OpenGL" );
cam_pos = RsdVector3( 0.0f, 0.0f, 0.0f );
// Set color and depth clear value
glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
// Enable Z-buffer read and write
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0f);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Set the blend function
glDepthMask(GL_TRUE);
// Setup a perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.f, 1.f, 500.f);
/// Load and Store Textures
glEnable( GL_TEXTURE_2D );
const sf::Uint8* p_pixels;
/// Teapot Texture
sf::Image img2;
img2.LoadFromFile( "assets/texture/test/checkerboard.png" );
glGenTextures( 1, &teapot_texture_id );
glBindTexture( GL_TEXTURE_2D, teapot_texture_id );
p_pixels = img2.GetPixelsPtr();
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA,
img2.GetWidth(),
img2.GetHeight(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
p_pixels );
/// Plane Texture
sf::Image img3;
img3.LoadFromFile( "assets/texture/test/Plane_XZ.png" );
glGenTextures( 1, &plane_texture_id );
glBindTexture( GL_TEXTURE_2D, plane_texture_id );
p_pixels = img3.GetPixelsPtr();
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA,
img3.GetWidth(),
img3.GetHeight(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
p_pixels );
/// BG Texture
sf::Image img4;
img4.LoadFromFile( "assets/texture/test/StarryBackground.png" );
glGenTextures( 1, &bg_texture_id );
glBindTexture( GL_TEXTURE_2D, bg_texture_id );
p_pixels = img4.GetPixelsPtr();
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA,
img4.GetWidth(),
img4.GetHeight(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
p_pixels );
return true;
}
And this is the RenderScene() function which is called each pass. For the NoBackground screenshot, I simply commented out the code section labelled “///BG Texture”. The glutSolidTeapot function is copy-pasted from GLUT, so GLUT is not actually being used in my code.
void RenderScene()
{
// Set the active window before using OpenGL commands
// It's useless here because active window is always the same,
// but don't forget it if you use multiple windows or controls
gp_app->SetActive();
// Clear color and depth buffer
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
/// Set Rendering Options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/// Switch to Model View mode
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
/// Apply some transformations
glTranslatef( 0.0f, 0.0f, -20.0f );
glTranslatef( -cam_pos.x, -cam_pos.y, -cam_pos.z );
/// Plane Texture
glBindTexture( GL_TEXTURE_2D, plane_texture_id );
glBegin(GL_QUADS);
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -10.f, 0.0f, -10.0f );
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 10.0f, 0.0f, -10.0f);
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 10.f, 0.0f, 10.0f );
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -10.f, 0.0f, 10.0f );
glEnd();
/// Teapot
glBindTexture( GL_TEXTURE_2D, teapot_texture_id );
glFrontFace( GL_CW );
glutSolidTeapot( 10.0f );
glFrontFace( GL_CCW );
/// BG Texture
glBindTexture( GL_TEXTURE_2D, bg_texture_id );
glBegin(GL_QUADS);
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -30.0f, 30.0f, -10.0f );
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 30.0f, 30.0f, -10.0f);
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 30.0f, -30.0f, -10.0f );
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -30.0f, -30.0f, -10.0f );
glEnd();
// Finally, display rendered frame on screen
gp_app->Display();
}
I’m quite certain the issue is something fairly trivial, but I haven’t had any luck searching via Google and on these forums. If you need any additional code, please feel free to ask, but I feel most of the non-GL code should be fairly intuitive. Many thanks for your time and assistance!