blob: c27131ed476bade41cbd4f60b6cea7a1f0f31d39 [file] [log] [blame]
//
// Book: OpenGL(R) ES 2.0 Programming Guide
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10: 0321502795
// ISBN-13: 9780321502797
// Publisher: Addison-Wesley Professional
// URLs: http://safari.informit.com/9780321563835
// http://www.opengles-book.com
//
// esUtil_win32.c
//
// This file contains the Win32 implementation of the windowing functions.
///
// Includes
//
#include <windows.h>
#include "esUtil.h"
//////////////////////////////////////////////////////////////////
//
// Private Functions
//
//
///
// ESWindowProc()
//
// Main window procedure
//
LRESULT WINAPI ESWindowProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
LRESULT lRet = 1;
switch (uMsg)
{
case WM_CREATE:
break;
case WM_SIZE:
{
ESContext *esContext = (ESContext*)(LONG_PTR) GetWindowLongPtr ( hWnd, GWL_USERDATA );
if ( esContext ) {
esContext->width = LOWORD( lParam );
esContext->height = HIWORD( lParam );
InvalidateRect( esContext->hWnd, NULL, FALSE );
}
}
case WM_PAINT:
{
ESContext *esContext = (ESContext*)(LONG_PTR) GetWindowLongPtr ( hWnd, GWL_USERDATA );
if ( esContext && esContext->drawFunc )
esContext->drawFunc ( esContext );
if ( esContext )
ValidateRect( esContext->hWnd, NULL );
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CHAR:
{
POINT point;
ESContext *esContext = (ESContext*)(LONG_PTR) GetWindowLongPtr ( hWnd, GWL_USERDATA );
GetCursorPos( &point );
if ( esContext && esContext->keyFunc )
esContext->keyFunc ( esContext, (unsigned char) wParam,
(int) point.x, (int) point.y );
}
break;
default:
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
return lRet;
}
//////////////////////////////////////////////////////////////////
//
// Public Functions
//
//
///
// WinCreate()
//
// Create Win32 instance and window
//
GLboolean WinCreate ( ESContext *esContext, LPCTSTR title )
{
WNDCLASS wndclass = {0};
DWORD wStyle = 0;
RECT windowRect;
HINSTANCE hInstance = GetModuleHandle(NULL);
wndclass.style = CS_OWNDC;
wndclass.lpfnWndProc = (WNDPROC)ESWindowProc;
wndclass.hInstance = hInstance;
wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.lpszClassName = TEXT("opengles2.0");
if (!RegisterClass (&wndclass) )
return FALSE;
wStyle = WS_VISIBLE | WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION | WS_SIZEBOX;
// Adjust the window rectangle so that the client area has
// the correct number of pixels
windowRect.left = 0;
windowRect.top = 0;
windowRect.right = esContext->width;
windowRect.bottom = esContext->height;
AdjustWindowRect ( &windowRect, wStyle, FALSE );
esContext->hWnd = CreateWindow(
TEXT("opengles2.0"),
title,
wStyle,
0,
0,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top,
NULL,
NULL,
hInstance,
NULL);
// Set the ESContext* to the GWL_USERDATA so that it is available to the
// ESWindowProc
SetWindowLongPtr ( esContext->hWnd, GWL_USERDATA, (LONG) (LONG_PTR) esContext );
if ( esContext->hWnd == NULL )
return GL_FALSE;
ShowWindow ( esContext->hWnd, TRUE );
return GL_TRUE;
}
///
// winLoop()
//
// Start main windows loop
//
void WinLoop ( ESContext *esContext )
{
MSG msg = { 0 };
int done = 0;
DWORD lastTime = GetTickCount();
while (!done)
{
int gotMsg = (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0);
DWORD curTime = GetTickCount();
float deltaTime = (float)( curTime - lastTime ) / 1000.0f;
lastTime = curTime;
if ( gotMsg )
{
if (msg.message==WM_QUIT)
{
done=1;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
SendMessage( esContext->hWnd, WM_PAINT, 0, 0 );
// Call update function if registered
if ( esContext->updateFunc != NULL )
esContext->updateFunc ( esContext, deltaTime );
}
}