/*
* Generic Win32 / Win64 WGL basecode
*
* Copyright (C) 2003,2004,2005 Christophe Devine
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <windows.h>
#include <stdio.h>
#include <gl/gl.h>
#pragma comment ( lib, "opengl32.lib" )
#pragma comment ( lib, "glu32.lib" )
char ClassName[] = "opengl demo";
/* external gl data */
extern char *AppTitle;
extern int width, height, font, info;
/* external gl rountines */
extern int gl_data( void );
extern int gl_init( void );
extern void gl_draw( void );
extern void gl_resize( void );
extern void gl_event( int event, int data,
int xpos, int ypos );
/* perror port for Windows */
void WinPerror( const char *function )
{
char *buf1, buf2[128];
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
(LPTSTR) &buf1, 0, NULL );
sprintf( buf2, " Fatal error in %s ", function );
MessageBox( NULL, buf1, buf2, MB_OK | MB_ICONWARNING );
}
/* variables associated with the window */
HDC myDC = NULL;
HGLRC myRC = NULL;
HWND parent = NULL;
HWND self = NULL;
int modeswitch;
int active = 0;
int saver = 0;
int run = 1;
/* declaration of the window procedure function */
LRESULT CALLBACK WindowProc( HWND, UINT, WPARAM, LPARAM );
/* program entry point */
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
MSG msg;
WNDCLASSEX wcx;
int fullscreen = 1;
char *p;
if( gl_data() )
{
SetLastError( 0 );
WinPerror( "gl_data" );
return( 0 );
}
p = GetCommandLine();
if( p[0] == '"' )
{
p++;
while( 1 )
{
if( p[0] == '"' || p[0] == '\0' )
break;
p++;
}
if( p[0] == '"' )
p++;
}
else
{
while( 1 )
{
if( p[0] == ' ' || p[0] == '\0' )
break;
p++;
}
}
if( p[0] == ' ' )
p++;
if( p[0] == '-' || p[0] == '/' )
{
info = 0;
saver = 1;
switch( p[1] )
{
case 'l': case 'L':
case 'p': case 'P':
fullscreen = 0;
parent = (HWND) atol( p + 3 );
break;
case 'c': case 'C':
case 'a': case 'A':
return( 1 );
default :
break;
}
}
wcx.cbSize = sizeof( WNDCLASSEX );
wcx.style = 0;
wcx.lpfnWndProc = (WNDPROC) WindowProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = NULL;
wcx.hCursor = LoadCursor( NULL, IDC_ARROW );
wcx.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
wcx.lpszMenuName = NULL;
wcx.lpszClassName = ClassName;
wcx.hIconSm = NULL;
if( ! RegisterClassEx( &wcx ) )
{
WinPerror( "RegisterClassEx" );
return( 0 );
}
do
{
DWORD dwStyle;
modeswitch = 0;
if( fullscreen )
{
HDC hDC;
if( ! ( hDC = GetDC( NULL ) ) )
{
WinPerror( "GetDC" );
return( 0 );
}
width = GetDeviceCaps( hDC, HORZRES );
height = GetDeviceCaps( hDC, VERTRES );
ReleaseDC( NULL, hDC );
dwStyle = WS_POPUP;
}
else
{
if( parent == NULL )
{
width = 640;
height = 480;
dwStyle = WS_OVERLAPPEDWINDOW;
}
else
{
RECT r;
if( ! GetClientRect( parent, &r ) )
{
WinPerror( "GetClientRect" );
return( 0 );
}
width = r.right;
height = r.bottom;
dwStyle = WS_CHILD;
}
}
if( ! ( self = CreateWindow( ClassName, AppTitle, dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
parent, NULL, hInstance, NULL ) ) )
{
WinPerror( "CreateWindow" );
return( 0 );
}
ShowWindow( self, nCmdShow );
run = 1;
while( run )
{
if( active )
{
gl_draw();
SwapBuffers( myDC );
if( saver )
Sleep( 9 );
}
else
{
GetMessage( &msg, NULL, 0, 0 );
}
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if( msg.message == WM_QUIT )
{
run = 0;
break;
}
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
wglMakeCurrent( NULL, NULL );
if( myDC ) ReleaseDC( self, myDC );
if( myRC ) wglDeleteContext( myRC );
DestroyWindow( self );
fullscreen ^= 1;
}
while( modeswitch );
return( msg.wParam );
}
/* the window procedure itself */
LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam )
{
switch( uMsg )
{
case WM_CREATE:
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof( PIXELFORMATDESCRIPTOR ),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
16,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int pixelformat, font;
if( ! ( myDC = GetDC( hWnd ) ) )
{
WinPerror( "GetDC" );
PostQuitMessage( 0 );
break;
}
if( ! ( pixelformat = ChoosePixelFormat( myDC, &pfd ) ) )
{
WinPerror( "ChoosePixelFormat" );
PostQuitMessage( 0 );
break;
}
if( ! SetPixelFormat( myDC, pixelformat, &pfd ) )
{
WinPerror( "SetPixelFormat" );
PostQuitMessage( 0 );
break;
}
if( ! ( myRC = wglCreateContext( myDC ) ) )
{
WinPerror( "wglCreateContext" );
PostQuitMessage( 0 );
break;
}
if( ! wglMakeCurrent( myDC, myRC