📄 glapp.cpp
字号:
/*
glapp.c - Simple OpenGL shell
There are several options allowed on the command line. They are:
-height : what window/screen height do you want to use?
-width : what window/screen width do you want to use?
-bpp : what color depth do you want to use?
-window : create a rendering window rather than full-screen
-fov : use a field of view other than 90 degrees
*/
#pragma warning(disable:4305)
#pragma warning(disable:4244)
#include "stdafx.h"
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <mmsystem.h>
#include "glapp.h"
#include "mathlib.h"
windata_t WinData;
devinfo_t DevInfo;
#define OSR2_BUILD_NUMBER 1111
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
float fAngle = 0.0f;
char *szFSDesc[] = { "Windowed", "Full Screen" };
// The app needs to define these symbols
// g_szAppName[] -- char array applicaton name
// void AppInit( void ) -- Called at init time
// void AppRender( void ) -- Called each frame (as often as possible)
// void AppExit( void ) -- Called to shut down
// void AppKey( int key, int down ); -- called on each key up/down
// void AppChar( int key ); -- key was pressed & released
extern "C" char g_szAppName[];
extern "C" void AppInit( void );
extern "C" void AppRender( float frametime, float mouseDeltaX, float mouseDeltaY );
extern "C" void AppExit( void );
extern "C" void AppKey( int key, int down );
extern "C" void AppChar( int key );
extern "C" unsigned int g_Time;
unsigned int g_Time = 0;
BOOL CreateMainWindow( int width, int height, int bpp, BOOL fullscreen);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
void MouseCapture( void )
{
SetCapture( WinData.hWnd );
ShowCursor(FALSE);
SetCursorPos( WinData.centerx, WinData.centery );
}
void MouseRelease( void )
{
ShowCursor(TRUE);
ReleaseCapture();
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
MSG msg;
int i;
HDC hdc;
// Not changable by user
WinData.hInstance = hInstance;
WinData.iCmdShow = iCmdShow;
WinData.wndproc = (WNDPROC)WndProc;
WinData.pResolutions = 0;
WinData.NearClip = 8.0f;
WinData.FarClip = 8192.0f;
// User definable
WinData.fov = 90.0f;
WinData.bAllowSoft = FALSE;
WinData.bFullScreen = TRUE;
// Get the current display device info
hdc = GetDC( NULL );
DevInfo.bpp = GetDeviceCaps(hdc, BITSPIXEL);
DevInfo.width = GetSystemMetrics(SM_CXSCREEN);
DevInfo.height = GetSystemMetrics(SM_CYSCREEN);
ReleaseDC(NULL, hdc);
// Parse the command line if there is one
WinData.argc = 0;
if (strlen(szCmdLine) > 0)
{
WinData.szCmdLine = szCmdLine;
GetParameters();
}
// Default to 640 pixels wide
if ((i = FindNumParameter("-width")) != -1)
{
WinData.width = i;
}
else
{
WinData.width = 640;
}
// Default to 480 pixels high
if ((i = FindNumParameter("-height")) != -1)
{
WinData.height = i;
}
else
{
WinData.height = 480;
}
// Default to 16 bits of color per pixel
if ((i = FindNumParameter("-bpp")) != -1)
{
WinData.bpp = i;
}
else
{
WinData.bpp = 16;
}
// Default to a 65 degree field of view
if ((i = FindNumParameter("-fov")) != -1)
{
WinData.fov = (float)i;
}
else
{
WinData.fov = 90.0f;
}
// Check for windowed rendering
WinData.bFullScreen = FALSE;
if (FindParameter("-fullscreen"))
{
WinData.bFullScreen = TRUE;
}
// Build up the video mode list
BuildModeList();
// Set the desired video mode and/or color depth
if (!SetVideoMode())
{
Cleanup();
return 0;
}
// Create the main program window, start up OpenGL and create our viewport
if (CreateMainWindow( WinData.width, WinData.height, WinData.bpp, WinData.bFullScreen) != TRUE)
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "Unable to create main window.\nProgram will now end.", "FATAL ERROR", MB_OK);
Cleanup();
return 0;
}
// Turn the cursor off for full-screen mode
if (WinData.bFullScreen == TRUE)
{ // Probably want to do this all the time anyway
ShowCursor(FALSE);
}
RECT rect;
GetWindowRect( WinData.hWnd, &rect );
if ( rect.top < 0)
rect.top = 0;
if ( rect.left < 0)
rect.left = 0;
if ( rect.bottom >= WinData.height - 1 )
rect.bottom = WinData.height - 1;
if ( rect.right >= WinData.width )
rect.right = WinData.width - 1;
WinData.centerx = ( rect.left + rect.right ) / 2;
WinData.centery = ( rect.top + rect.bottom ) / 2;
// Capture the mouse
MouseCapture();
// We're live now
WinData.bActive = TRUE;
// Define this funciton to init your app
MathLib_Init( true, true, true, 2.2, 2.2, 0, 2 );
AppInit();
// Begin the main program loop
while (WinData.bActive == TRUE)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
if (WinData.hGLRC)
{
RenderScene();
}
}
if (WinData.bFullScreen == TRUE)
{
ShowCursor(TRUE);
}
// Release the parameter and video resolution lists
Cleanup();
AppExit();
return msg.wParam;
}
void GetParameters()
{
int count;
char *s, *tstring;
// Make a copy of the command line to count the parameters - strtok is destructive
tstring = (char *)malloc(sizeof(char)*(strlen(WinData.szCmdLine)+1));
strcpy(tstring, WinData.szCmdLine);
// Count the parameters
s = strtok(tstring, " ");
count = 1;
while (strtok(NULL, " ") != NULL)
{
count++;
}
free(tstring);
// Allocate "pockets" for the parameters
WinData.argv = (char **)malloc(sizeof(char*)*(count+1));
// Copy first parameter into the "pockets"
WinData.argc = 0;
s = strtok(WinData.szCmdLine, " ");
WinData.argv[WinData.argc] = (char *)malloc(sizeof(char)*(strlen(s)+1));
strcpy(WinData.argv[WinData.argc], s);
WinData.argc++;
// Copy the rest of the parameters
do
{
// get the next token
s = strtok(NULL, " ");
if (s != NULL)
{
// add it to the list
WinData.argv[WinData.argc] = (char *)malloc(sizeof(char)*(strlen(s)+1));
strcpy(WinData.argv[WinData.argc], s);
WinData.argc++;
}
}
while (s != NULL);
}
void Cleanup()
{
int i;
// Free the command line holder memory
if (WinData.argc > 0)
{
// Free in reverse order of allocation
for (i = (WinData.argc-1); i >= 0; i--)
{
free(WinData.argv[i]);
}
// Free the parameter "pockets"
free(WinData.argv);
}
// Free the memory that holds the video resolution list
if (WinData.pResolutions)
free(WinData.pResolutions);
}
BOOL isdigits( char *s )
{
int i;
for (i = 0; s[i]; i++)
{
if ((s[i] > '9') || (s[i] < '0'))
{
return FALSE;
}
}
return TRUE;
}
int FindNumParameter(const char *s)
{
int i;
for (i = 0; i < (WinData.argc-1); i++)
{
if (stricmp(WinData.argv[i], s) == 0)
{
if (isdigits(WinData.argv[i+1]) == TRUE)
{
return(atoi(WinData.argv[i+1]));
}
else
{
return -1;
}
}
}
return -1;
}
const char *LastParameter( void )
{
if ( WinData.argc < 1 )
return NULL;
return WinData.argv[WinData.argc-1];
}
bool FindParameter(const char *s)
{
int i;
for (i = 0; i < WinData.argc; i++)
{
if (stricmp(WinData.argv[i], s) == 0)
{
return true;
}
}
return false;
}
const char *FindParameterArg( const char *s )
{
int i;
for (i = 0; i < WinData.argc-1; i++)
{
if (stricmp(WinData.argv[i], s) == 0)
{
return WinData.argv[i+1];
}
}
return NULL;
}
BOOL CreateMainWindow(int width, int height, int bpp, BOOL fullscreen)
{
HWND hwnd;
WNDCLASSEX wndclass;
DWORD dwStyle, dwExStyle;
int x, y, sx, sy, ex, ey, ty;
if ((hwnd = FindWindow(g_szAppName, g_szAppName)) != NULL)
{
SetForegroundWindow(hwnd);
return 0;
}
wndclass.cbSize = sizeof (wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = (WNDPROC)WinData.wndproc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = WinData.hInstance;
wndclass.hIcon = 0;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)COLOR_GRAYTEXT;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = g_szAppName;
wndclass.hIconSm = 0;
if (!RegisterClassEx (&wndclass))
{
MessageBox(NULL, "Window class registration failed.", "FATAL ERROR", MB_OK);
return FALSE;
}
if (fullscreen)
{
dwExStyle = WS_EX_TOPMOST;
dwStyle = WS_POPUP | WS_VISIBLE;
x = y = 0;
sx = WinData.width;
sy = WinData.height;
}
else
{
dwExStyle = 0;
//dwStyle = WS_CAPTION | WS_SYSMENU | WS_THICKFRAME; // Use this if you want a "normal" window
dwStyle = WS_CAPTION;
ex = GetSystemMetrics(SM_CXEDGE);
ey = GetSystemMetrics(SM_CYEDGE);
ty = GetSystemMetrics(SM_CYSIZE);
// Center the window on the screen
x = (DevInfo.width / 2) - ((WinData.width+(2*ex)) / 2);
y = (DevInfo.height / 2) - ((WinData.height+(2*ey)+ty) / 2);
sx = WinData.width+(2*ex);
sy = WinData.height+(2*ey)+ty;
/*
Check to be sure the requested window size fits on the screen and
adjust each dimension to fit if the requested size does not fit.
*/
if (sx >= DevInfo.width)
{
x = 0;
sx = DevInfo.width-(2*ex);
}
if (sy >= DevInfo.height)
{
y = 0;
sy = DevInfo.height-((2*ey)+ty);
}
}
if ((hwnd = CreateWindowEx (dwExStyle,
g_szAppName, // window class name
g_szAppName, // window caption
dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, // window style
x, // initial x position
y, // initial y position
sx, // initial x size
sy, // initial y size
NULL, // parent window handle
NULL, // window menu handle
WinData.hInstance, // program instance handle
NULL)) // creation parameters
== NULL)
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "Window creation failed.", "FATAL ERROR", MB_OK);
return FALSE;
}
WinData.hWnd = hwnd;
if (!InitOpenGL())
{
WinData.hWnd = NULL;
return FALSE;
}
ShowWindow(WinData.hWnd, WinData.iCmdShow);
UpdateWindow(WinData.hWnd);
SetForegroundWindow(WinData.hWnd);
SetFocus(WinData.hWnd);
return TRUE;
}
void GL_AppShutdown( void )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -