Skip to content

Instantly share code, notes, and snippets.

@maxdeliso
Last active October 14, 2015 00:57
Show Gist options
  • Save maxdeliso/4282902 to your computer and use it in GitHub Desktop.
Save maxdeliso/4282902 to your computer and use it in GitHub Desktop.
w32 application template
/*
* basic opengl and windows integration
* see: http://www.opengl.org/archives/resources/faq/technical/gettingstarted.htm
* for the proper link flags
* Max DeLiso
*/
#include <Windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <cassert>
#include <iostream>
#include <fstream>
inline BOOL debugging() {
#ifdef _DEBUG
return true;
#else
return false;
#endif
}
/* class prototype */
class EngineSingleton;
class GFX_Context {
friend class EngineSingleton;
HWND ghWnd;
HDC ghDC;
HGLRC ghRC;
GFX_Context() {
ghWnd = 0;
ghDC = 0;
ghRC = 0;
}
public:
void init(const HWND& hwnd);
};
class WIN_Context {
friend class EngineSingleton;
HINSTANCE hInstance;
WIN_Context(HINSTANCE inst) {
hInstance = inst;
}
public:
void messageLoop();
BOOL registerWindowClass();
BOOL createMainWindow(int nCmdShow, GFX_Context* gfxContextPtr);
BOOL bSetupPixelFormat(HDC hdc);
static LRESULT CALLBACK windowProcedure(HWND hwnd, UINT uint, WPARAM wParam, LPARAM lParam);
static const TCHAR windowClassName[];
static const TCHAR windowTitleName[];
static const int windowInitialWidth;
static const int windowInitialHeight;
};
/* see http://stackoverflow.com/questions/2496918/singleton-pattern-in-c */
class EngineSingleton
{
public:
static EngineSingleton& instance();
int runWithInstance(HINSTANCE hInstance, int nCmdShow);
private:
/* singleton boilerplate */
static void destroy();
EngineSingleton();
~EngineSingleton();
EngineSingleton(EngineSingleton const&) {}
EngineSingleton& operator=(EngineSingleton const&) {}
static EngineSingleton* gInstance;
};
EngineSingleton& EngineSingleton::instance() {
if (gInstance == NULL) { gInstance = new EngineSingleton(); }
return *gInstance;
}
int EngineSingleton::runWithInstance(HINSTANCE hInstance, int nCmdShow) {
GFX_Context* gfxContext = new GFX_Context();
WIN_Context* winContext = new WIN_Context(hInstance);
if( winContext->registerWindowClass() &&
winContext->createMainWindow(nCmdShow, gfxContext) ) {
winContext->messageLoop();
} else {
return EXIT_FAILURE;
}
delete winContext;
delete gfxContext;
return EXIT_SUCCESS;
}
EngineSingleton* EngineSingleton::gInstance = NULL;
EngineSingleton::EngineSingleton() {
atexit(&destroy);
/* TODO: setup global state*/
}
EngineSingleton::~EngineSingleton() {
/* TODO: tear-down global state */
}
void EngineSingleton::destroy() {
delete gInstance;
gInstance = NULL;
}
void GFX_Context::init(const HWND& hwnd) {
ghWnd = hwnd;
ghDC = GetDC(hwnd);
ghRC = wglCreateContext(ghDC);
wglMakeCurrent(ghDC, ghRC);
RECT clientRect;
GetClientRect(hwnd, &clientRect);
const GLubyte* gluVersion = gluGetString(GLU_VERSION);
const GLubyte* gluExtensions = gluGetString(GLU_EXTENSIONS);
}
const TCHAR WIN_Context::windowClassName[] = TEXT("testClass");
const TCHAR WIN_Context::windowTitleName[] = TEXT("testTitle");
const int WIN_Context::windowInitialWidth = 512;
const int WIN_Context::windowInitialHeight = 316;
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
EngineSingleton& engine = EngineSingleton::instance();
if(debugging()) {
BOOL allocOk = AllocConsole();
assert(allocOk);
std::ofstream conOut("con");
conOut << "DEBUGGING: ON";
conOut.close();
}
return engine.runWithInstance(hInstance, nCmdShow);
}
void WIN_Context::messageLoop() {
MSG msg;
BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) {
if( bRet == -1 ) {
/* TODO: signal error */
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
BOOL WIN_Context::registerWindowClass() {
WNDCLASSEX wcx;
wcx.cbSize = sizeof(wcx);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = windowProcedure;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wcx.lpszMenuName = NULL;
wcx.lpszClassName = windowClassName;
wcx.hIconSm = NULL;
return RegisterClassEx(&wcx);
}
BOOL WIN_Context::createMainWindow(
int nCmdShow,
GFX_Context* gfxContextPtr) {
HWND hwnd;
hwnd = CreateWindowEx(
0,
windowClassName,
windowTitleName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
windowInitialWidth,
windowInitialHeight,
(HWND) NULL,
(HMENU) NULL,
hInstance,
(LPVOID) gfxContextPtr);
if (!hwnd) {
return FALSE;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
BOOL WIN_Context::bSetupPixelFormat(HDC hdc) {
PIXELFORMATDESCRIPTOR pfd;
int pixelformat;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags =
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
pfd.dwLayerMask = PFD_MAIN_PLANE;
pfd.iPixelType = PFD_TYPE_COLORINDEX;
pfd.cColorBits = 24;
pfd.cDepthBits = 32;
pfd.cAccumBits = 0;
pfd.cStencilBits = 0;
pixelformat = ChoosePixelFormat(hdc, &pfd);
if ( (pixelformat = ChoosePixelFormat(hdc, &pfd)) == 0 ) {
return FALSE;
}
if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE) {
return FALSE;
}
return TRUE;
}
LRESULT CALLBACK WIN_Context::windowProcedure(
HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
static GFX_Context* gfxContext = NULL;
if(debugging()) {
std::ofstream conOut("con");
conOut << "event " << msg << std::endl;
conOut.close();
}
switch(msg) {
case WM_CREATE:
gfxContext = (GFX_Context*) ((CREATESTRUCT*)lParam)->lpCreateParams;
gfxContext->init(hwnd);
/* initialize opengl projection matrix */
/* initialize data */
/* create widgets */
return DefWindowProc(hwnd, msg, wParam, lParam);
case WM_PAINT:
/* draw widgets */
return DefWindowProc(hwnd, msg, wParam, lParam);
case WM_CLOSE:
if(!DestroyWindow(hwnd)) {
/* TODO: signal error */
} else {
/* destroy data */
PostQuitMessage(EXIT_SUCCESS);
}
return 0;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment