qe_ogl.cpp
C++ source for Polychorons, 245 lines. Raw file
#define WIN32_LEAN_AND_MEAN
#include "vars.h"
#include "qe_ogl.h"
const char *gl_error = NULL;
HWND gl_hWnd;
HDC gl_dc = NULL;
HGLRC gl_rc = NULL;
GLsizei gl_width, gl_height;
char gl_vendor[128], gl_renderer[128], gl_version[128], *gl_extensions;
//
// Implementation
//
// Select and set the best OpenGL pixel format for this application
// in to the specified Device Context.
BOOL GL_SetupPixelFormat (HDC hDC)
{
PIXELFORMATDESCRIPTOR pfd;
int pixelformat, bestformat;
pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE | PFD_SWAP_EXCHANGE;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 16;
pfd.cDepthBits = 16;
pfd.cAccumBits = 0;
pfd.cStencilBits = 0;
pixelformat = ChoosePixelFormat (hDC, &pfd);
if (! pixelformat)
{
// we didn't find a pixel format. search all available pixel formats
// until we get one that supports a double buffer. no other tests
// are performed on the pixel format at this time, but there should
// probably be some sort of test for the depth buffer bits.
bestformat = -1;
for (pixelformat = 1; ; pixelformat++)
{
if (DescribePixelFormat (hDC, pixelformat, sizeof (pfd), &pfd) == 0)
break;
if (pfd.dwFlags & PFD_DOUBLEBUFFER)
{
bestformat = pixelformat;
break;
}
}
if (bestformat == -1)
{
gl_error = "Couldn't find a pixel format.";
return FALSE;
}
pixelformat = bestformat;
}
if (pfd.dwFlags & PFD_NEED_PALETTE)
{
gl_error = "Palettised modes are unsupported.";
return FALSE;
}
if (SetPixelFormat (hDC, pixelformat, &pfd) == FALSE)
{
gl_error = "Failed to select pixel format for Window.";
return FALSE;
}
return TRUE;
}
// Initialise OpenGL with the specified device context.
BOOL GL_InitGL (HWND hWnd, HDC hDC)
{
// store off the device context
gl_dc = hDC;
gl_hWnd = hWnd;
// initialise the pixel format
if (! GL_SetupPixelFormat (gl_dc))
return FALSE;
// create and activate a GL context
gl_rc = wglCreateContext (gl_dc);
if (! gl_rc)
{
gl_error = "Failed to create OpenGL context.";
return FALSE;
}
wglMakeCurrent (gl_dc, gl_rc);
// SelectObject (gl_dc, GetStockObject (SYSTEM_FONT));
// wglUseFontBitmaps(gl_dc, 0, 255, 1000);
// retrieve the driver information
GL_GetDriverInfo ();
return TRUE;
}
// Cleanup all the OpenGL objects
void GL_DoneGL ()
{
int retval;
glFinish();
wglMakeCurrent(gl_dc, NULL);
if (gl_rc)
retval=wglDeleteContext (gl_rc);
if (gl_dc)
ReleaseDC (gl_hWnd, gl_dc);
// if(gl_dc)
// retval=DeleteDC(gl_dc);
gl_dc = NULL;
gl_rc = NULL;
}
// Initialise OpenGL states
void GL_Initialise (GLsizei width, GLsizei height)
{
// enable smooth shading
glShadeModel (GL_SMOOTH);
// enable back face culling - cull counter clock wise
// glEnable (GL_CULL_FACE);
glCullFace (GL_BACK);
glFrontFace (GL_CW);
// set up the viewport dimensions
glViewport (0, 0, width, height);
// load a default projection matrix at 60 degree F.O.V.
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60.0, (GLfloat)width/(GLfloat)height, 1.0, 30000.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
// select to draw to the back buffer
glDrawBuffer (GL_BACK);
// no blending just yet
glDisable (GL_BLEND);
glEnable (GL_DEPTH_TEST);
// clear colour for draw buffer
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
// Retrieves vendor information
void GL_GetDriverInfo (void)
{
strcpy (gl_vendor, (const char *) glGetString (GL_VENDOR));
strcpy (gl_renderer, (const char *) glGetString (GL_RENDERER));
strcpy (gl_version, (const char *) glGetString (GL_VERSION));
}
// Change the screen resolution to that specified
BOOL GL_ChangeResolution (unsigned width, unsigned height, unsigned bits)
{
DEVMODE devmode;
int modeswitch;
int i;
for (i = 0; ; i++)
{
modeswitch = EnumDisplaySettings (NULL, i, &devmode);
if (devmode.dmBitsPerPel == bits && devmode.dmPelsWidth == width
&& devmode.dmPelsHeight == height)
{
break;
}
if (! modeswitch)
break;
}
// if (! modeswitch)
// {
// gl_error = "Screen resolution not supported.";
// return FALSE;
// }
//
// modeswitch = ChangeDisplaySettings (&devmode, 0);
modeswitch = DISP_CHANGE_FAILED;
if (modeswitch != DISP_CHANGE_SUCCESSFUL)
{
// Windows 95 doesn't like the frequency change
devmode.dmBitsPerPel = bits;
devmode.dmPelsWidth = width;
devmode.dmPelsHeight = height;
devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
modeswitch = ChangeDisplaySettings (&devmode, 0);
if (modeswitch != DISP_CHANGE_SUCCESSFUL)
{
if (modeswitch == DISP_CHANGE_RESTART)
{
gl_error = "Mode change would require a restart.";
return FALSE;
}
if (modeswitch == DISP_CHANGE_BADMODE)
{
gl_error = "Screen resolution is not supported.";
return FALSE;
}
if (modeswitch == DISP_CHANGE_FAILED)
{
gl_error = "Failed to change screen mode.";
return FALSE;
}
}
}
return TRUE;
}
/// Restore the screen resolution to the users preferences
void GL_RestoreResolution (void)
{
ChangeDisplaySettings (NULL, 0);
}