Below is the
setup code I used. It is GL Setup v1.1, unmodified and used with permission from the
author, Scott Franke [druid-]. |
The code for the program
will be examined by parts, consisting of the display setup code, the texture setup code,
and the actual cube code. The code will be further organized in that I have color
coded the OpenGL code directly related to renderin in green and the peripheral and setup code in red.
The setup code consists of:
Setup code of some sort is needed for
every OpenGL application. This is necessary for the OpenGL Rendering Context to be
set up in whatever Display Context or system interface is necessary. This code is
system/platform specific.
The setup code requires some basic
knowledge of Windows programming. This particular GLSetup is more complicated then
necessary, but I used it because it is much more flexible than the basic setup code.
An alternate method to using setup
code is to use GLUT, the OpenGL Utility Toolkit. This was a toolkit written by Mark
Kilgard that simplifies the window and event management and abstracts the programmer from
having to deal with the complex window system. GLUT was originally devloped for
X-Windows, but has since been ported to Win32. |
|
|
#ifndef GLSETUP
#define GLSETUP
#define IDD_SETUP 101
#define IDC_RES512 1000
#define IDC_RES640 1001
#define IDC_RES800 1002
#define IDC_RES1024 1003
#define IDC_COL16 1010
#define IDC_COL24 1011
#define IDC_COL32 1012
#define IDC_ZBUF0 1020
#define IDC_ZBUF16 1021
#define IDC_ZBUF24 1022
#define IDC_FULL 1030
#define IDC_WIN 1031
#define IDC_STATIC -1
static HWND hwnd;
static HGLRC glRC;
static HGLRC hRC;
HDC hDC;
static int iCurrentRes = IDC_RES640,
iCurrentFull = IDC_WIN,
iCurrentCol = IDC_COL16,
iCurrentZbuf = IDC_ZBUF0;
static unsigned int res[4][2] = {
{512, 384}, {640, 480}, {800, 600}, {1024, 768} };
static unsigned int col[3] = {
16, 24, 32 };
static unsigned int zbuf[3] = {
0, 16, 24 };
#endif
/* Need this defined */
LONG WINAPI MainWndProc ( HWND, UINT, WPARAM, LPARAM);
/* gls functions */
BOOL CALLBACK glsSetupDlgProc (HWND, UINT, WPARAM, LPARAM);
int glsDoSetup (HINSTANCE, char[]);
void glsClose (void);
int glsCreateWindow (HWND);
BOOL bSetupPixelFormat(HDC);
void glsPrintError (void);
|
#include
#include "setup.h"
BOOL CALLBACK glsSetupDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int iRes, iFull, iCol, iZbuf;
switch(iMsg)
{
case WM_INITDIALOG:
iRes = iCurrentRes;
iFull = iCurrentFull;
iCol = iCurrentCol;
iZbuf = iCurrentZbuf;
CheckRadioButton (hDlg, IDC_RES512, IDC_RES1024, iRes);
CheckRadioButton (hDlg, IDC_FULL, IDC_WIN, iFull);
CheckRadioButton (hDlg, IDC_COL16, IDC_COL32, iCol);
CheckRadioButton (hDlg, IDC_ZBUF0, IDC_ZBUF24, iZbuf);
SetFocus (GetDlgItem (hDlg, iRes));
return FALSE;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
iCurrentRes = iRes;
iCurrentFull = iFull;
EndDialog (hDlg, TRUE);
return TRUE;
case IDCANCEL:
EndDialog (hDlg, FALSE);
return TRUE;
case IDC_RES512:
case IDC_RES640:
case IDC_RES800:
case IDC_RES1024:
iRes = LOWORD (wParam);
CheckRadioButton (hDlg, IDC_RES512, IDC_RES1024, iRes);
return TRUE;
case IDC_FULL:
case IDC_WIN:
iFull = LOWORD (wParam);
CheckRadioButton (hDlg, IDC_FULL, IDC_WIN, iFull);
return TRUE;
case IDC_COL16:
case IDC_COL24:
case IDC_COL32:
iCol = LOWORD (wParam);
CheckRadioButton (hDlg, IDC_COL16, IDC_COL32, iCol);
return TRUE;
case IDC_ZBUF0:
case IDC_ZBUF16:
case IDC_ZBUF24:
iZbuf = LOWORD (wParam);
CheckRadioButton (hDlg, IDC_ZBUF0, IDC_ZBUF24, iZbuf);
return TRUE;
}
break;
case WM_PAINT:
break;
}
return FALSE;
}
int glsDoSetup (HINSTANCE hInstance, char szAppName[])
{
WNDCLASS wc;
DWORD winStyle;
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (hInstance, "demo");
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = szAppName;
wc.lpszClassName = szAppName;
if ( !RegisterClass( &wc ) ) {
MessageBox (NULL, "Couldn't Register Window Class", "Init", MB_ICONERROR );
return 0;
}
if(!DialogBox (hInstance, "setupDlg", hwnd, glsSetupDlgProc))
return 0;
switch (iCurrentFull)
{
case IDC_FULL:
winStyle = WS_POPUP |
WS_MAXIMIZE;
break;
case IDC_WIN:
winStyle = WS_OVERLAPPEDWINDOW;
break;
}
winStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
hwnd = CreateWindow (szAppName,
szAppName,
winStyle,
0, 0,
res[iCurrentRes-IDC_RES512][0],
res[iCurrentRes-IDC_RES512][1],
NULL,
NULL,
hInstance,
NULL);
if (!hwnd) {
MessageBox (NULL, "Couldn't Create Window", "Init", MB_OK | MB_ICONERROR);
return 0;
}
ShowWindow (hwnd, SW_SHOWDEFAULT );
UpdateWindow (hwnd);
SetFocus (hwnd);
return 1;
}
HGLRC setupGL( void ) {
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW // support window
| PFD_SUPPORT_OPENGL // support OpenGL
| PFD_DOUBLEBUFFER , // double buffered
PFD_TYPE_RGBA, // RGBA type
0, // 16-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
0, // 16-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelFormat;
HGLRC rv = 0;
pfd.cColorBits = col[iCurrentCol-IDC_COL16];
pfd.cDepthBits = zbuf[iCurrentZbuf-IDC_ZBUF0];
pixelFormat = ChoosePixelFormat(hDC, &pfd);
if ( pixelFormat )
{
if ( SetPixelFormat(hDC, pixelFormat, &pfd) )
{
rv = wglCreateContext( hDC );
if ( rv )
{
if ( !wglMakeCurrent( hDC, rv ) )
{
wglDeleteContext( rv );
rv = 0;
}
}
}
}
return rv;
}
int glsCreateWindow(HWND hWnd)
{
// Go to full screen
if(iCurrentFull == IDC_FULL)
{
DEVMODE dmode;
int modenum;
BOOL modeswitch;
LONG changeResult;
modenum = 0;
do
{
modeswitch = !EnumDisplaySettings(NULL, modenum, &dmode );
if ( dmode.dmBitsPerPel == col[iCurrentCol-IDC_COL16] && dmode.dmPelsWidth == res[iCurrentRes-IDC_RES512][0] && dmode.dmPelsHeight == res[iCurrentRes-IDC_RES512][1] ) break;
modenum++;
} while ( !modeswitch );
if ( modeswitch ) // didn't find mode
{
ChangeDisplaySettings (NULL, 0);
MessageBox (NULL, "Didn't find good fullscreen mode", "Error", MB_OK | MB_ICONERROR);
return 0;
}
dmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
changeResult = ChangeDisplaySettings (&dmode, CDS_TEST);
modenum = (changeResult==DISP_CHANGE_SUCCESSFUL);
modenum = (changeResult==DISP_CHANGE_FAILED);
modenum = (changeResult==DISP_CHANGE_BADMODE);
modenum = (changeResult==DISP_CHANGE_RESTART);
switch (changeResult)
{
case DISP_CHANGE_SUCCESSFUL:
ChangeDisplaySettings (&dmode, CDS_FULLSCREEN);
break;
case DISP_CHANGE_FAILED:
MessageBox (NULL, "Failed to change to desired settings", "Error", MB_OK | MB_ICONERROR);
return 0;
case DISP_CHANGE_BADMODE:
MessageBox (NULL, "That fullscreen mode is not supported", "Error", MB_OK | MB_ICONERROR);
return 0;
case DISP_CHANGE_RESTART:
MessageBox (NULL, "Must restart to get that Fullscreen setting", "Error", MB_OK | MB_ICONERROR);
return 0;
}
}
hDC = GetDC (hWnd);
glRC = setupGL ();
if (!glRC)
{
MessageBox (0, "Failed to Create OpenGL Rendering Context.",
"ERROR", MB_ICONERROR);
DestroyWindow( hWnd );
}
return 1;
}
void glsClose (void)
{
if(iCurrentFull == IDC_FULL)
ChangeDisplaySettings(NULL, 0);
}
void glsPrintError (void)
{
DWORD errMess;
char errbuff[30];
errMess = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errMess,
0,
errbuff,
30,
NULL);
MessageBox (NULL, errbuff, "ERROR", MB_OK | MB_ICONERROR);
}