Noob has a problem with really simple OpenGL example

Hello forum,

Being the very, very new noob that I am, I’m failing to get the basics functioning as I expect them to in OpenGL.

My simple (very simple) single source file windows program is shown below. In WinMain() during the while loop I’m mapping two textures to two quads.

I’m using “glVertex3f” and “glTexCoord3f” functions, so I’d expect the depths to be honoured. Yet texture #13 is always drawn in front of texture #14 despite its depth being -1.0 compared to texture #13’s depth of -0.5.

If I swap the code blocks for texture #13 and texture #14 around, the Z-order changes, whereas I’d always expect to see texture #13 behind texture #14 regardless of the order of my code blocks. It’s as if the z-buffer doesn’t exist!

Any help gratefully received by this very green newbie.


// Includes
#include <windows.h>
#include <gl/gl.h>

// Function Declarations
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC);
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC);

// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
				   LPSTR lpCmdLine, int iCmdShow)
{
	WNDCLASS wc;
	HWND hWnd;
	HDC hDC;
	HGLRC hRC;
	MSG msg;
	BOOL quit = FALSE;
	float theta = 0.0f;
	
	// register window class
	wc.style = CS_OWNDC;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	wc.hCursor = LoadCursor( NULL, IDC_ARROW );
	wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "GLSample";
	RegisterClass( &wc );
	
	hWnd = CreateWindow( 
		"GLSample", "OpenGL Sample", 
		WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
		0, 0, 1030, 1030,
		NULL, NULL, hInstance, NULL );

	// enable OpenGL for the window
	EnableOpenGL( hWnd, &hDC, &hRC );

	// Initialise random texture ID #13
	const int iImageWidth13 = 64, iImageHeight13 = 64;
	BYTE byImageData13[iImageWidth13 * iImageHeight13 * 3];
	for(int iFill = 0; iFill < (iImageWidth13 * iImageHeight13 * 3); iFill++)
		byImageData13[iFill] = rand() / 128;

	glBindTexture(GL_TEXTURE_2D, 13);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, iImageWidth13, iImageHeight13, 0, GL_RGB, GL_UNSIGNED_BYTE, byImageData13);

	// Initialise random texture ID #14
	const int iImageWidth14 = 64, iImageHeight14 = 64;
	BYTE byImageData14[iImageWidth14 * iImageHeight14 * 3];
	for(int iFill = 0; iFill < (iImageWidth14 * iImageHeight14 * 3); iFill+=3)
		byImageData14[iFill] = iFill / ((iImageWidth14 * iImageHeight14 * 3) / 254);
	for(int iFill = 1; iFill < (iImageWidth14 * iImageHeight14 * 3); iFill+=3)
		byImageData14[iFill] = 255 - iFill / ((iImageWidth14 * iImageHeight14 * 3) / 254);
	for(int iFill = 2; iFill < (iImageWidth14 * iImageHeight14 * 3); iFill+=3)
		byImageData14[iFill] = abs(iFill - (iImageWidth14 * iImageHeight14 * 3) / 2) / ((iImageWidth14 * iImageHeight14 * 3) / (2*254));

	glBindTexture(GL_TEXTURE_2D, 14);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, iImageWidth14, iImageHeight14, 0, GL_RGB, GL_UNSIGNED_BYTE, byImageData14);

	// Enable 2D texture mapping
	glEnable(GL_TEXTURE_2D);
	
	// program main loop
	while ( !quit )
	{
		// check for messages
		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )  )
		{
			// handle or dispatch messages
			if ( msg.message == WM_QUIT ) 
			{
				quit = TRUE;
			} 
			else 
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
		} 
		else 
		{
			// Map texture #14
			glBindTexture (GL_TEXTURE_2D, 14);
			glBegin (GL_QUADS);
			glTexCoord3f (0.0, 0.0, -0.5);
			glVertex3f (-0.75f,-0.75f, -0.5);
			glTexCoord3f (1.0, 0.0, -0.5);
			glVertex3f ( -0.4f, -0.75f, -0.5);
			glTexCoord3f (1.0, 1.0, -0.5);
			glVertex3f ( -0.4f, -0.4f, -0.5);
			glTexCoord3f (0.0, 1.0, -0.5);
			glVertex3f (-0.75f, -0.4f, -0.5);
			glEnd();

			// Map texture #13
			glBindTexture (GL_TEXTURE_2D, 13);
			glBegin (GL_QUADS);
			glTexCoord3f (0.0, 0.0, -1.0);
			glVertex3f (-0.5f,-0.5f, -1.0);
			glTexCoord3f (1.0, 0.0, -1.0);
			glVertex3f ( 0.5f, -0.5f, -1.0);
			glTexCoord3f (1.0, 1.0, -1.0);
			glVertex3f ( 0.5f, 0.5f, -1.0);
			glTexCoord3f (0.0, 1.0, -1.0);
			glVertex3f (-0.5f, 0.5f, -1.0);
			glEnd();

			SwapBuffers( hDC );
		}
	}
	
	// shutdown OpenGL
	DisableOpenGL( hWnd, hDC, hRC );
	// destroy the window explicitly
	DestroyWindow( hWnd );
	return msg.wParam;
}

// Window Procedure

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	
	switch (message)
	{
		case WM_CREATE:
			return 0;
		
		case WM_CLOSE:
			PostQuitMessage( 0 );
			return 0;
		
		case WM_DESTROY:
			return 0;
		
		case WM_KEYDOWN:
			switch ( wParam )
			{
				case VK_ESCAPE:
				PostQuitMessage(0);
				return 0;
			}
			return 0;
	
	default:
		return DefWindowProc( hWnd, message, wParam, lParam );	
	}
}

// Enable OpenGL
void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC)
{
	PIXELFORMATDESCRIPTOR pfd;
	int format;
	
	// get the device context (DC)
	*hDC = GetDC( hWnd );
	
	// set the pixel format for the DC
	ZeroMemory( &pfd, sizeof( pfd ) );
	pfd.nSize = sizeof( pfd );
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.cColorBits = 24;
	pfd.cDepthBits = 16;
	pfd.iLayerType = PFD_MAIN_PLANE;
	format = ChoosePixelFormat( *hDC, &pfd );
	SetPixelFormat( *hDC, format, &pfd );
	
	// create and enable the render context (RC)
	*hRC = wglCreateContext( *hDC );
	wglMakeCurrent( *hDC, *hRC );
}

// Disable OpenGL
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC)
{
	wglMakeCurrent( NULL, NULL );
	wglDeleteContext( hRC );
	ReleaseDC( hWnd, hDC );
}

Have you enabled opengl depth test yet? It seems glEnable(GL_DEPTH_TEST) wasn’t found in your code. Have you also cleared the depth buffer?

Done and done. Thank you very much newbiecow. I’m motoring now and I’m sure I’ll have a few more questions for the forum very soon. Actually, I feel one coming on…