📄 glapp.cpp
字号:
SendMessage( WinData.hWnd, WM_CLOSE, 0, 0 );
}
void Error( const char *error, ... )
{
va_list args;
char output[1024];
va_start( args, error );
vprintf( error, args );
vsprintf( output, error, args );
MessageBox(NULL, output, "ERROR", MB_OK);
WinData.bActive = FALSE;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg)
{
case WM_CHAR:
switch(wParam)
{
case VK_ESCAPE:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
AppChar( wParam );
break;
case WM_KEYDOWN:
AppKey( wParam, true );
break;
case WM_KEYUP:
AppKey( wParam, false );
break;
case WM_ACTIVATE:
if ((LOWORD(wParam) != WA_INACTIVE) && ((HWND)lParam == NULL))
{
ShowWindow(WinData.hWnd, SW_RESTORE);
SetForegroundWindow(WinData.hWnd);
}
else
{
if (WinData.bFullScreen)
{
ShowWindow(WinData.hWnd, SW_MINIMIZE);
}
}
return 0;
case WM_SIZE:
if (WinData.hGLRC)
{
// Redefine the viewing volume and viewport when the window size changes.
WinData.glnWidth = (GLsizei)LOWORD(lParam);
WinData.glnHeight = (GLsizei)HIWORD(lParam);
WinData.gldAspect = (float)((GLdouble)WinData.glnWidth/(GLdouble)WinData.glnHeight);
glViewport( 0, 0, WinData.glnWidth, WinData.glnHeight );
}
return 0;
case WM_SETFOCUS:
WinData.bPaused = FALSE;
MouseCapture();
// if ( WinData.bFullScreen )
// SetVideoMode();
break;
case WM_KILLFOCUS:
WinData.bPaused = TRUE;
MouseRelease();
// if ( WinData.bFullScreen )
// ReleaseVideoMode();
break;
case WM_CLOSE:
ShutdownOpenGL();
WinData.bActive = FALSE;
break;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
// This function builds a list the screen resolutions supported by the display driver
void BuildModeList()
{
DEVMODE dm;
int mode;
mode = 0;
while(EnumDisplaySettings(NULL, mode, &dm))
{
mode++;
}
WinData.pResolutions = (screen_res_t *)malloc(sizeof(screen_res_t)*mode);
mode = 0;
while(EnumDisplaySettings(NULL, mode, &dm))
{
WinData.pResolutions[mode].width = dm.dmPelsWidth;
WinData.pResolutions[mode].height = dm.dmPelsHeight;
WinData.pResolutions[mode].bpp = dm.dmBitsPerPel;
WinData.pResolutions[mode].flags = dm.dmDisplayFlags;
WinData.pResolutions[mode].frequency = dm.dmDisplayFrequency;
mode++;
}
WinData.iResCount = mode;
}
bool SetVideoMode()
{
OSVERSIONINFO vinfo;
int mode;
DEVMODE dm;
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
WinData.bChangeBPP = FALSE;
if ( GetVersionEx( &vinfo) )
{
if ( vinfo.dwMajorVersion > 4 )
{
WinData.bChangeBPP = TRUE;
}
else
if ( vinfo.dwMajorVersion == 4 )
{
if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
WinData.bChangeBPP = TRUE;
}
else
if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
{
if ( LOWORD( vinfo.dwBuildNumber ) >= OSR2_BUILD_NUMBER )
{
WinData.bChangeBPP = TRUE;
}
}
}
}
else
{
MessageBox(NULL, "SetVideoMode - GetVersionEx failed\n", "FATAL ERROR", MB_OK);
return false;
}
if (WinData.bFullScreen)
{
if ((WinData.bpp == DevInfo.bpp) &&
(WinData.width == DevInfo.width) &&
(WinData.height == DevInfo.height))
{
WinData.iVidMode = 0;
return true;
}
if ((WinData.bChangeBPP == FALSE) && (DevInfo.bpp != WinData.bpp))
{
MessageBox(NULL, "This version of Windows cannot change color depth.\n"
"Please request different video mode settings or adjust\n"
"your desktop color depth.", "FATAL ERROR", MB_OK);
return false;
}
for (mode = 0; mode < WinData.iResCount; mode++)
{
if ((WinData.pResolutions[mode].width == WinData.width) &&
(WinData.pResolutions[mode].height == WinData.height) &&
(WinData.pResolutions[mode].bpp == WinData.bpp))
{
WinData.iVidMode = mode;
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
dm.dmPelsWidth = WinData.width;
dm.dmPelsHeight = WinData.height;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
if (WinData.bpp != DevInfo.bpp)
{
dm.dmBitsPerPel = WinData.bpp;
dm.dmFields |= DM_BITSPERPEL;
}
if ( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL )
{
MessageBox(NULL, "SetVideoMode - ChangeDisplaySettings failed.\n"
"Switching to windowed mode.", "WARNING", MB_OK);
WinData.bFullScreen = FALSE;
return true;
}
return true;
}
}
MessageBox(NULL, "Your requested video mode is unavailable.\n"
"Please request different video mode settings.", "FATAL ERROR", MB_OK);
return false;
}
else
{
if (DevInfo.bpp != WinData.bpp)
{
// MessageBox(NULL, "Your requested color depth and desktop do not match.\n"
// "Using your current desktop color depth.", "WARNING", MB_OK);
}
}
return true;
}
void ReleaseVideoMode( void )
{
ChangeDisplaySettings(0, 0);
}
bool InitOpenGL()
{
int pfm; // pixel format
RECT rect;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
16, // 16-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
if ((WinData.hDC = GetDC(WinData.hWnd)) == NULL)
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "GetDC on main window failed", "FATAL ERROR", MB_OK);
return false;
}
if ((pfm = ChoosePixelFormat(WinData.hDC, &pfd)) == 0)
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "ChoosePixelFormat failed\n", "FATAL ERROR", MB_OK);
return false;
}
if (SetPixelFormat(WinData.hDC, pfm, &pfd) == FALSE)
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "SetPixelFormat failed\n", "FATAL ERROR", MB_OK);
return false;
}
DescribePixelFormat(WinData.hDC, pfm, sizeof(pfd), &pfd);
// Accelerated generic or MCD?
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED)) // Not a generic accelerated driver
{
// Check for generic software driver
if ( pfd.dwFlags & PFD_GENERIC_FORMAT )
{
// Software
if (WinData.bAllowSoft == FALSE)
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "OpenGL Driver is not accelerated\n", "FATAL ERROR", MB_OK);
return false;
}
}
// Must be an accelerated ICD
}
if ((WinData.hGLRC = wglCreateContext(WinData.hDC)) == 0)
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "wglCreateContext failed\n", "FATAL ERROR", MB_OK);
goto fail;
}
if (!wglMakeCurrent(WinData.hDC, WinData.hGLRC))
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "wglMakeCurrent failed\n", "FATAL ERROR", MB_OK);
goto fail;
}
GetClientRect(WinData.hWnd, &rect);
WinData.glnWidth= rect.right;
WinData.glnHeight = rect.bottom;
WinData.gldAspect = (float)((GLdouble)WinData.glnWidth/(GLdouble)WinData.glnHeight);
glEnable(GL_TEXTURE_2D);
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
return true;
fail:
if ( WinData.hGLRC )
{
wglDeleteContext( WinData.hGLRC);
WinData.hGLRC = NULL;
}
if ( WinData.hDC )
{
ReleaseDC(WinData.hWnd, WinData.hDC);
WinData.hDC = NULL;
}
return false;
}
void ShutdownOpenGL(void)
{
if (WinData.hGLRC)
{
if ((!wglMakeCurrent(NULL, NULL)) && (!WinData.bFullScreen))
{
MessageBox(NULL, "ShutdownOpenGL - wglMakeCurrent failed\n", "ERROR", MB_OK);
}
if (!wglDeleteContext(WinData.hGLRC))
{
MessageBox(NULL, "ShutdownOpenGL - wglDeleteContext failed\n", "ERROR", MB_OK);
}
WinData.hGLRC = NULL;
}
if (WinData.hDC)
{
if (!ReleaseDC(WinData.hWnd, WinData.hDC))
{
MessageBox(NULL, "ShutdownOpenGL - ReleaseDC failed\n", "ERROR", MB_OK);
}
WinData.hDC = NULL;
}
if (WinData.bFullScreen)
{
ChangeDisplaySettings( 0, 0 );
}
}
void MYgluPerspective( GLdouble fovy, GLdouble aspect,
GLdouble zNear, GLdouble zFar )
{
GLdouble xmin, xmax, ymin, ymax;
ymax = zNear * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
}
/*
====================
CalcFov
====================
*/
float CalcFov (float fov_x, float width, float height)
{
float a;
float x;
if (fov_x < 1 || fov_x > 179)
fov_x = 90; // error, set to 90
x = width/tan(fov_x/360*M_PI);
a = atan (height/x);
a = a*360/M_PI;
return a;
}
unsigned int Sys_Milliseconds( void )
{
__int64 Frequency, Timer;
QueryPerformanceFrequency((LARGE_INTEGER*)&Frequency);
QueryPerformanceCounter((LARGE_INTEGER*)&Timer);
double out = double(Timer)/double(Frequency);
return (unsigned int) ( out * 1000.0 );
}
// Render your scenes through this function
void RenderScene( void )
{
static DWORD lastTime = 0;
POINT cursorPoint;
float deltax = 0, deltay = 0, frametime;
DWORD newTime = Sys_Milliseconds();
DWORD deltaTime = newTime - lastTime;
if ( deltaTime > 1000 )
deltaTime = 0;
lastTime = newTime;
frametime = (float) ((double)deltaTime * 0.001);
g_Time = newTime;
if ( WinData.bPaused )
{
deltax = deltay = 0;
}
else
{
GetCursorPos( &cursorPoint );
SetCursorPos( WinData.centerx, WinData.centery );
deltax = (cursorPoint.x - WinData.centerx) * 0.1f;
deltay = (cursorPoint.y - WinData.centery) * -0.1f;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
MYgluPerspective( CalcFov( WinData.fov, WinData.width, WinData.height ), WinData.gldAspect, WinData.NearClip, WinData.FarClip );
// set up a projection matrix to fill the client window
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
AppRender( frametime, deltax, deltay );
if (!SwapBuffers(WinData.hDC))
{
ChangeDisplaySettings(0, 0);
MessageBox(NULL, "RenderScene - SwapBuffers failed!\n", "FATAL ERROR", MB_OK);
SendMessage(WinData.hWnd, WM_CLOSE, 0, 0);
}
}
void GetScreen( int &width, int &height )
{
width = WinData.width;
height = WinData.height;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -