📄 win_glimp.c
字号:
if ( !( pfd.dwFlags & PFD_STEREO ) && ( r_stereo->integer != 0 ) )
{
ri.Printf( PRINT_ALL, "...failed to select stereo pixel format\n" );
glConfig.stereoEnabled = qfalse;
}
}
/*
** store PFD specifics
*/
glConfig.colorBits = ( int ) pfd.cColorBits;
glConfig.depthBits = ( int ) pfd.cDepthBits;
glConfig.stencilBits = ( int ) pfd.cStencilBits;
return qtrue;
}
/*
** GLW_CreateWindow
**
** Responsible for creating the Win32 window and initializing the OpenGL driver.
*/
#define WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE)
static qboolean GLW_CreateWindow( const char *drivername, int width, int height, int colorbits, qboolean cdsFullscreen )
{
RECT r;
cvar_t *vid_xpos, *vid_ypos;
int stylebits;
int x, y, w, h;
int exstyle;
//
// register the window class if necessary
//
if ( !s_classRegistered )
{
WNDCLASS wc;
memset( &wc, 0, sizeof( wc ) );
wc.style = 0;
wc.lpfnWndProc = (WNDPROC) glw_state.wndproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_wv.hInstance;
wc.hIcon = LoadIcon( g_wv.hInstance, MAKEINTRESOURCE(IDI_ICON1));
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = (void *)COLOR_GRAYTEXT;
wc.lpszMenuName = 0;
wc.lpszClassName = WINDOW_CLASS_NAME;
if ( !RegisterClass( &wc ) )
{
ri.Error( ERR_FATAL, "GLW_CreateWindow: could not register window class" );
}
s_classRegistered = qtrue;
ri.Printf( PRINT_ALL, "...registered window class\n" );
}
//
// create the HWND if one does not already exist
//
if ( !g_wv.hWnd )
{
//
// compute width and height
//
r.left = 0;
r.top = 0;
r.right = width;
r.bottom = height;
if ( cdsFullscreen || !Q_stricmp( _3DFX_DRIVER_NAME, drivername ) )
{
exstyle = WS_EX_TOPMOST;
stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU;
}
else
{
exstyle = 0;
stylebits = WINDOW_STYLE|WS_SYSMENU;
AdjustWindowRect (&r, stylebits, FALSE);
}
w = r.right - r.left;
h = r.bottom - r.top;
if ( cdsFullscreen || !Q_stricmp( _3DFX_DRIVER_NAME, drivername ) )
{
x = 0;
y = 0;
}
else
{
vid_xpos = ri.Cvar_Get ("vid_xpos", "", 0);
vid_ypos = ri.Cvar_Get ("vid_ypos", "", 0);
x = vid_xpos->integer;
y = vid_ypos->integer;
// adjust window coordinates if necessary
// so that the window is completely on screen
if ( x < 0 )
x = 0;
if ( y < 0 )
y = 0;
if ( w < glw_state.desktopWidth &&
h < glw_state.desktopHeight )
{
if ( x + w > glw_state.desktopWidth )
x = ( glw_state.desktopWidth - w );
if ( y + h > glw_state.desktopHeight )
y = ( glw_state.desktopHeight - h );
}
}
g_wv.hWnd = CreateWindowEx (
exstyle,
WINDOW_CLASS_NAME,
"Quake 3: Arena",
stylebits,
x, y, w, h,
NULL,
NULL,
g_wv.hInstance,
NULL);
if ( !g_wv.hWnd )
{
ri.Error (ERR_FATAL, "GLW_CreateWindow() - Couldn't create window");
}
ShowWindow( g_wv.hWnd, SW_SHOW );
UpdateWindow( g_wv.hWnd );
ri.Printf( PRINT_ALL, "...created window@%d,%d (%dx%d)\n", x, y, w, h );
}
else
{
ri.Printf( PRINT_ALL, "...window already present, CreateWindowEx skipped\n" );
}
if ( !GLW_InitDriver( drivername, colorbits ) )
{
ShowWindow( g_wv.hWnd, SW_HIDE );
DestroyWindow( g_wv.hWnd );
g_wv.hWnd = NULL;
return qfalse;
}
SetForegroundWindow( g_wv.hWnd );
SetFocus( g_wv.hWnd );
return qtrue;
}
static void PrintCDSError( int value )
{
switch ( value )
{
case DISP_CHANGE_RESTART:
ri.Printf( PRINT_ALL, "restart required\n" );
break;
case DISP_CHANGE_BADPARAM:
ri.Printf( PRINT_ALL, "bad param\n" );
break;
case DISP_CHANGE_BADFLAGS:
ri.Printf( PRINT_ALL, "bad flags\n" );
break;
case DISP_CHANGE_FAILED:
ri.Printf( PRINT_ALL, "DISP_CHANGE_FAILED\n" );
break;
case DISP_CHANGE_BADMODE:
ri.Printf( PRINT_ALL, "bad mode\n" );
break;
case DISP_CHANGE_NOTUPDATED:
ri.Printf( PRINT_ALL, "not updated\n" );
break;
default:
ri.Printf( PRINT_ALL, "unknown error %d\n", value );
break;
}
}
/*
** GLW_SetMode
*/
static rserr_t GLW_SetMode( const char *drivername,
int mode,
int colorbits,
qboolean cdsFullscreen )
{
HDC hDC;
const char *win_fs[] = { "W", "FS" };
int cdsRet;
DEVMODE dm;
//
// print out informational messages
//
ri.Printf( PRINT_ALL, "...setting mode %d:", mode );
if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
{
ri.Printf( PRINT_ALL, " invalid mode\n" );
return RSERR_INVALID_MODE;
}
ri.Printf( PRINT_ALL, " %d %d %s\n", glConfig.vidWidth, glConfig.vidHeight, win_fs[cdsFullscreen] );
//
// check our desktop attributes
//
hDC = GetDC( GetDesktopWindow() );
glw_state.desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
glw_state.desktopWidth = GetDeviceCaps( hDC, HORZRES );
glw_state.desktopHeight = GetDeviceCaps( hDC, VERTRES );
ReleaseDC( GetDesktopWindow(), hDC );
//
// verify desktop bit depth
//
if ( glConfig.driverType != GLDRV_VOODOO )
{
if ( glw_state.desktopBitsPixel < 15 || glw_state.desktopBitsPixel == 24 )
{
if ( colorbits == 0 || ( !cdsFullscreen && colorbits >= 15 ) )
{
if ( MessageBox( NULL,
"It is highly unlikely that a correct\n"
"windowed display can be initialized with\n"
"the current desktop display depth. Select\n"
"'OK' to try anyway. Press 'Cancel' if you\n"
"have a 3Dfx Voodoo, Voodoo-2, or Voodoo Rush\n"
"3D accelerator installed, or if you otherwise\n"
"wish to quit.",
"Low Desktop Color Depth",
MB_OKCANCEL | MB_ICONEXCLAMATION ) != IDOK )
{
return RSERR_INVALID_MODE;
}
}
}
}
// do a CDS if needed
if ( cdsFullscreen )
{
memset( &dm, 0, sizeof( dm ) );
dm.dmSize = sizeof( dm );
dm.dmPelsWidth = glConfig.vidWidth;
dm.dmPelsHeight = glConfig.vidHeight;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
if ( r_displayRefresh->integer != 0 )
{
dm.dmDisplayFrequency = r_displayRefresh->integer;
dm.dmFields |= DM_DISPLAYFREQUENCY;
}
// try to change color depth if possible
if ( colorbits != 0 )
{
if ( glw_state.allowdisplaydepthchange )
{
dm.dmBitsPerPel = colorbits;
dm.dmFields |= DM_BITSPERPEL;
ri.Printf( PRINT_ALL, "...using colorsbits of %d\n", colorbits );
}
else
{
ri.Printf( PRINT_ALL, "WARNING:...changing depth not supported on Win95 < pre-OSR 2.x\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...using desktop display depth of %d\n", glw_state.desktopBitsPixel );
}
//
// if we're already in fullscreen then just create the window
//
if ( glw_state.cdsFullscreen )
{
ri.Printf( PRINT_ALL, "...already fullscreen, avoiding redundant CDS\n" );
if ( !GLW_CreateWindow ( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue ) )
{
ri.Printf( PRINT_ALL, "...restoring display settings\n" );
ChangeDisplaySettings( 0, 0 );
return RSERR_INVALID_MODE;
}
}
//
// need to call CDS
//
else
{
ri.Printf( PRINT_ALL, "...calling CDS: " );
// try setting the exact mode requested, because some drivers don't report
// the low res modes in EnumDisplaySettings, but still work
if ( ( cdsRet = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL )
{
ri.Printf( PRINT_ALL, "ok\n" );
if ( !GLW_CreateWindow ( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue) )
{
ri.Printf( PRINT_ALL, "...restoring display settings\n" );
ChangeDisplaySettings( 0, 0 );
return RSERR_INVALID_MODE;
}
glw_state.cdsFullscreen = qtrue;
}
else
{
//
// the exact mode failed, so scan EnumDisplaySettings for the next largest mode
//
DEVMODE devmode;
int modeNum;
ri.Printf( PRINT_ALL, "failed, " );
PrintCDSError( cdsRet );
ri.Printf( PRINT_ALL, "...trying next higher resolution:" );
// we could do a better matching job here...
for ( modeNum = 0 ; ; modeNum++ ) {
if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) {
modeNum = -1;
break;
}
if ( devmode.dmPelsWidth >= glConfig.vidWidth
&& devmode.dmPelsHeight >= glConfig.vidHeight
&& devmode.dmBitsPerPel >= 15 ) {
break;
}
}
if ( modeNum != -1 && ( cdsRet = ChangeDisplaySettings( &devmode, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL )
{
ri.Printf( PRINT_ALL, " ok\n" );
if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue) )
{
ri.Printf( PRINT_ALL, "...restoring display settings\n" );
ChangeDisplaySettings( 0, 0 );
return RSERR_INVALID_MODE;
}
glw_state.cdsFullscreen = qtrue;
}
else
{
ri.Printf( PRINT_ALL, " failed, " );
PrintCDSError( cdsRet );
ri.Printf( PRINT_ALL, "...restoring display settings\n" );
ChangeDisplaySettings( 0, 0 );
glw_state.cdsFullscreen = qfalse;
glConfig.isFullscreen = qfalse;
if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qfalse) )
{
return RSERR_INVALID_MODE;
}
return RSERR_INVALID_FULLSCREEN;
}
}
}
}
else
{
if ( glw_state.cdsFullscreen )
{
ChangeDisplaySettings( 0, 0 );
}
glw_state.cdsFullscreen = qfalse;
if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qfalse ) )
{
return RSERR_INVALID_MODE;
}
}
//
// success, now check display frequency, although this won't be valid on Voodoo(2)
//
memset( &dm, 0, sizeof( dm ) );
dm.dmSize = sizeof( dm );
if ( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &dm ) )
{
glConfig.displayFrequency = dm.dmDisplayFrequency;
}
// NOTE: this is overridden later on standalone 3Dfx drivers
glConfig.isFullscreen = cdsFullscreen;
return RSERR_OK;
}
/*
** GLW_InitExtensions
*/
static void GLW_InitExtensions( void )
{
if ( !r_allowExtensions->integer )
{
ri.Printf( PRINT_ALL, "*** IGNORING OPENGL EXTENSIONS ***\n" );
return;
}
ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" );
// GL_S3_s3tc
glConfig.textureCompression = TC_NONE;
if ( strstr( glConfig.extensions_string, "GL_S3_s3tc" ) )
{
if ( r_ext_compressed_textures->integer )
{
glConfig.textureCompression = TC_S3TC;
ri.Printf( PRINT_ALL, "...using GL_S3_s3tc\n" );
}
else
{
glConfig.textureCompression = TC_NONE;
ri.Printf( PRINT_ALL, "...ignoring GL_S3_s3tc\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_S3_s3tc not found\n" );
}
// GL_EXT_texture_env_add
glConfig.textureEnvAddAvailable = qfalse;
if ( strstr( glConfig.extensions_string, "EXT_texture_env_add" ) )
{
if ( r_ext_texture_env_add->integer )
{
glConfig.textureEnvAddAvailable = qtrue;
ri.Printf( PRINT_ALL, "...using GL_EXT_texture_env_add\n" );
}
else
{
glConfig.textureEnvAddAvailable = qfalse;
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_env_add\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_texture_env_add not found\n" );
}
// WGL_EXT_swap_control
qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" );
if ( qwglSwapIntervalEXT )
{
ri.Printf( PRINT_ALL, "...using WGL_EXT_swap_control\n" );
r_swapInterval->modified = qtrue; // force a set next frame
}
else
{
ri.Printf( PRINT_ALL, "...WGL_EXT_swap_control not found\n" );
}
// GL_ARB_multitexture
qglMultiTexCoord2fARB = NULL;
qglActiveTextureARB = NULL;
qglClientActiveTextureARB = NULL;
if ( strstr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
{
if ( r_ext_multitexture->integer )
{
qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) qwglGetProcAddress( "glMultiTexCoord2fARB" );
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) qwglGetProcAddress( "glActiveTextureARB" );
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) qwglGetProcAddress( "glClientActiveTextureARB" );
if ( qglActiveTextureARB )
{
qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures );
if ( glConfig.maxActiveTextures > 1 )
{
ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
}
else
{
qglMultiTexCoord2fARB = NULL;
qglActiveTextureARB = NULL;
qglClientActiveTextureARB = NULL;
ri.Printf( PRINT_ALL, "...not using GL_ARB_multitexture, < 2 texture units\n" );
}
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" );
}
// GL_EXT_compiled_vertex_array
qglLockArraysEXT = NULL;
qglUnlockArraysEXT = NULL;
if ( strstr( glConfig.extensions_string, "GL_EXT_compiled_vertex_array" ) && ( glConfig.hardwareType != GLHW_RIVA128 ) )
{
if ( r_ext_compiled_vertex_array->integer )
{
ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" );
qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) qwglGetProcAddress( "glLockArraysEXT" );
qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) qwglGetProcAddress( "glUnlockArraysEXT" );
if (!qglLockArraysEXT || !qglUnlockArraysEXT) {
ri.Error (ERR_FATAL, "bad getprocaddress");
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_compiled_vertex_array\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
}
// WGL_3DFX_gamma_control
qwglGetDeviceGammaRamp3DFX = NULL;
qwglSetDeviceGammaRamp3DFX = NULL;
if ( strstr( glConfig.extensions_string, "WGL_3DFX_gamma_control" ) )
{
if ( !r_ignorehwgamma->integer && r_ext_gamma_control->integer )
{
qwglGetDeviceGammaRamp3DFX = ( BOOL ( WINAPI * )( HDC, LPVOID ) ) qwglGetProcAddress( "wglGetDeviceGammaRamp3DFX" );
qwglSetDeviceGammaRamp3DFX = ( BOOL ( WINAPI * )( HDC, LPVOID ) ) qwglGetProcAddress( "wglSetDeviceGammaRamp3DFX" );
if ( qwglGetDeviceGammaRamp3DFX && qwglSetDeviceGammaRamp3DFX )
{
ri.Printf( PRINT_ALL, "...using WGL_3DFX_gamma_control\n" );
}
else
{
qwglGetDeviceGammaRamp3DFX = NULL;
qwglSetDeviceGammaRamp3DFX = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -