Description of OpenGL Skeleton October 23, 2004 EvilHomer -=EntryLevel Code=- The program entrypoint is at the 'Start:' label. We first get the value of 'hInstance' (by calling GetModuleHandle with NULL as the parameter). Now we call a procedure called 'WinMain', which is the guts of our program. After the call to WinMain returns, we call ExitProcess (passing the returnvalue from WinMain as the parameter). -=WinMain=- We create a MessageBox, asking the User whether they'd like to start in Windowed mode, or in FullScreen mode. We set a boolean flag called 'fullscreen' according to the result. We now pass that flag as a parameter of a call to a proc called CreateGLWindow. This proc returns a success/failure result, which we check. If the call to CreateGLWindow failed, we exit early. Otherwise, we enter the 'Windows MessagePump Loop'. Within the MessagePump, we check for a 'WM_QUIT' message (meaning User wishes to totally kill the application). We then check the 'Message Queue' for pending 'Window Messages', and if there's any, we process one by calling TranslateMessage and DispatchMessage. If there's NO pending WM's (ie application idle time), we would normally call a proc to render the Scene, but we don't in this demo. Now we call a proc named 'SwapBuffers' which switches the back and front 'render buffers'. This has the effect of displaying (onscreen) the last video frame we just rendered. We now check the state of our 'keys array'. This is an array of 256 bytes which are used as flags for the 256 possible ascii keycodes. When the user presses a key, it generates a WM_KEYDOWN message, which is processed like all WM's. Within WndProc (we'll get to that), we watch out for and process the WM_KEYDOWN message, such that when the User presses any key on the keyboard, the appropriate byte in the keys array is signalled. We don't care about all of them, so in our MessagePump, we only check the state of certain flags in the keys array. In our demo, only one is checked, it's the F1 key, used to toggle fullscreen/windowed mode. If the User presses F1, we detect it here, and respond by calling KillGLWindow, toggling the 'fullscreen' flag, and then (once again) calling CreateGLWindow to 'recreate' the window. All the MessagePump code is wrapped in a "while loop" which is waiting for WM_QUIT. Unless we get a WM_QUIT, we jump backwards - thus the name 'MessagePump Loop'. If we get a WM_QUIT, we'll break out of that loop, we'll call KillGLWindow and return from WinMain. -=WndProc=- WndProc checks for any WMs we care enough about to process ourselves. The first of these is WM_ACTIVATE. If we get one, we set a boolean flag called 'active' according to the value in the top 16bits of wParam. We next check for WM_SYSCOMMAND and in particular the submessages SC_SCREENSAVE and SC_MONITORPOWER. We suppress these messages by returning NULL. Next we check for the obvious WM_CLOSE (respond by calling PostQuitMessage and returning NULL). More interesting, we next check for WM_KEYDOWN and WM_KEYUP, sent whenever the user presses or releases any key on the keyboard. We use these to set our flags in the keys array. Finally, we check for WM_SIZE, sent when the User resizes the application window. Our response to that one is to call ReSizeGLScene (with the new window size as parameters) and returning NULL. If we get any WM we don't care enough about to process but don't want to suppress, we pass it as a param to a call to DefWindowProc, the 'default window procedure'. We then return from WndProc.