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 );
}