Here's a demo framework for trying out this kind of stuff with OpenGL. You can plug your own code in inside the ogl_draw() function - for example, the little snippets I posted can go in here. Right now it just draws a 10x10 red quad in the top left of the screen. Of course the code is nowhere near as small as the 1Kb OpenGL framework - the idea here is that this is about the minimum neat-and-tidy framework you need to form a fully compliant Windows OpenGL application. I'm going to use it for bug reporting Vista driver problems to ATI and nVidia.
If you need project files, let me know.
Have fun!
//-----------------------------------------------------------------------------------------------------------------
//
// Copyright 2007 Jim Shaw. All Rights Reserved.
//
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <stdio.h>
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
typedef void (APIENTRY *PFNWGLEXTSWAPCONTROLPROC)(int);
static PFNWGLEXTSWAPCONTROLPROC wglSwapIntervalEXT = NULL;
static HWND gameWindow;
static HGLRC gameRC;
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
static int ogl_init(void)
{
PIXELFORMATDESCRIPTOR pixeldesc;
int pixelformat;
HDC hDC;
hDC = GetDC(gameWindow);
memset(&pixeldesc, 0, sizeof pixeldesc);
pixeldesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixeldesc.nVersion = 1;
pixeldesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pixeldesc.iPixelType = PFD_TYPE_RGBA;
pixeldesc.cColorBits = 32;
pixeldesc.cRedBits = 0;
pixeldesc.cGreenBits = 0;
pixeldesc.cBlueBits = 0;
pixeldesc.cAlphaBits = pixeldesc.cAlphaShift = 0;
pixeldesc.cAccumBits = 32;
pixeldesc.cAccumRedBits =
pixeldesc.cAccumGreenBits = pixeldesc.cAccumBlueBits = 0;
pixeldesc.cAccumAlphaBits = 0;
pixeldesc.cDepthBits = 32;
pixeldesc.cStencilBits = 0;
pixeldesc.cAuxBuffers = 0;
pixeldesc.bReserved = 0;
pixeldesc.dwLayerMask = 0;
pixeldesc.dwVisibleMask = 0;
pixeldesc.dwDamageMask = 0;
if ((pixelformat = ChoosePixelFormat(hDC, &pixeldesc)) == 0)
return 0;
if (pixeldesc.dwFlags & PFD_NEED_PALETTE)
return 0;
if (SetPixelFormat(hDC, pixelformat, &pixeldesc) == FALSE)
return 0;
DescribePixelFormat(hDC, pixelformat, sizeof pixeldesc, &pixeldesc);
gameRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, gameRC);
ReleaseDC(gameWindow, hDC);
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
glDepthRange(0.0, 1.0);
glClearDepth(1.0);
glClearColor(0.5,0.5,0,1.0);
glShadeModel(GL_SMOOTH);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glDisable(GL_LIGHTING);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glPixelZoom(1.0, -1.0);
glEnable(GL_TEXTURE_2D);
if (strstr((const char *)glGetString(GL_EXTENSIONS), "WGL_EXT_swap_control"))
{
wglSwapIntervalEXT = (PFNWGLEXTSWAPCONTROLPROC)wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapIntervalEXT)
wglSwapIntervalEXT(1);
}
return 1;
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
static void ogl_shutdown(void)
{
wglMakeCurrent(NULL, NULL);
if (gameRC)
{
wglDeleteContext(gameRC);
gameRC = 0;
}
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
void ogl_flip(void)
{
HDC dc;
GLenum err;
err = glGetError();
if (err != GL_NO_ERROR)
{
char tmp[256];
sprintf(tmp, "GLERROR %08X %d\n", err, err);
OutputDebugString(tmp);
}
dc = GetDC(gameWindow);
SwapBuffers(dc);
ReleaseDC(gameWindow, dc);
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
void ogl_draw(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//hud
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble)SCREEN_WIDTH, (GLdouble)SCREEN_HEIGHT, 0.0, 0.0, 1.0);
glViewport(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
glColor3ub(0xff,0,0);
glBegin(GL_QUADS);
glVertex2f(0,0);
glVertex2f(10,0);
glVertex2f(10,10);
glVertex2f(0,10);
glEnd();
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg )
{
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
break;
case WM_ERASEBKGND:
return 1;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
return 0;
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------------------------------------------
static char GLSampleClass[32] = "GLSampleClass";
int WINAPI WinMain(HINSTANCE this_inst, HINSTANCE prev_inst, LPSTR cmdline, int cmdshow)
{
WNDCLASS wc;
int style, exstyle;
int quit;
RECT rect;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = this_inst;
wc.hIcon = LoadIcon(NULL, (LPCSTR)IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = 0;
wc.lpszMenuName = NULL;
wc.lpszClassName = GLSampleClass;
RegisterClass(&wc);
style = WS_OVERLAPPED|WS_SYSMENU|WS_CAPTION;
exstyle = WS_EX_APPWINDOW;
gameWindow = CreateWindowEx(
0,
GLSampleClass, // class
"OpenGL Sample",
style,
CW_USEDEFAULT,CW_USEDEFAULT, // init. x,y pos
SCREEN_WIDTH,SCREEN_HEIGHT,
NULL, // parent window
NULL, // menu handle
this_inst, // program handle
NULL // create parms
);
GetWindowRect(gameWindow, &rect);
AdjustWindowRectEx(&rect, style, FALSE, exstyle);
SetWindowPos(gameWindow, NULL, 0,0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE);
ShowWindow(gameWindow, cmdshow);
UpdateWindow(gameWindow);
if (ogl_init() == 0)
{
MessageBox(gameWindow, "Failed Initialising OpenGL", "Failed", MB_OK);
return 0;
}
quit = 0;
do
{
MSG msg;
while (PeekMessage(&msg,NULL,0,0, PM_NOREMOVE))
{
if (GetMessage(&msg,NULL,0,0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
quit = 1;
break;
}
}
ogl_draw();
ogl_flip();
} while (!quit);
ogl_shutdown();
return 0;
}
Jim