From d37536edf4660f3c46e4876b6d72e9a200549ffe Mon Sep 17 00:00:00 2001 From: tma Date: Wed, 5 Sep 2007 18:17:46 +0000 Subject: * Merge unified-sdl to trunk * Bump Q3_VERSION to 1.35 git-svn-id: svn://svn.icculus.org/quake3/trunk@1161 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/win32/win_glimp.c | 1681 ------------------------------------------------ 1 file changed, 1681 deletions(-) delete mode 100644 code/win32/win_glimp.c (limited to 'code/win32/win_glimp.c') diff --git a/code/win32/win_glimp.c b/code/win32/win_glimp.c deleted file mode 100644 index 54d32a9..0000000 --- a/code/win32/win_glimp.c +++ /dev/null @@ -1,1681 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code 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. - -Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -/* -** WIN_GLIMP.C -** -** This file contains ALL Win32 specific stuff having to do with the -** OpenGL refresh. When a port is being made the following functions -** must be implemented by the port: -** -** GLimp_EndFrame -** GLimp_Init -** GLimp_LogComment -** GLimp_Shutdown -** -** Note that the GLW_xxx functions are Windows specific GL-subsystem -** related functions that are relevant ONLY to win_glimp.c -*/ -#include -#include "../renderer/tr_local.h" -#include "../qcommon/qcommon.h" -#include "resource.h" -#include "glw_win.h" -#include "win_local.h" - -extern void WG_CheckHardwareGamma( void ); -extern void WG_RestoreGamma( void ); - -typedef enum { - RSERR_OK, - - RSERR_INVALID_FULLSCREEN, - RSERR_INVALID_MODE, - - RSERR_UNKNOWN -} rserr_t; - -#define TRY_PFD_SUCCESS 0 -#define TRY_PFD_FAIL_SOFT 1 -#define TRY_PFD_FAIL_HARD 2 - -static void GLW_InitExtensions( void ); -static rserr_t GLW_SetMode( const char *drivername, - int mode, - int colorbits, - qboolean cdsFullscreen ); - -static qboolean s_classRegistered = qfalse; - -// -// function declaration -// -void QGL_EnableLogging( qboolean enable ); -qboolean QGL_Init( const char *dllname ); -void QGL_Shutdown( void ); - -// -// variable declarations -// -glwstate_t glw_state; - -cvar_t *r_allowSoftwareGL; // don't abort out if the pixelformat claims software -cvar_t *r_maskMinidriver; // allow a different dll name to be treated as if it were opengl32.dll - - - -/* -** GLW_StartDriverAndSetMode -*/ -static qboolean GLW_StartDriverAndSetMode( const char *drivername, - int mode, - int colorbits, - qboolean cdsFullscreen ) -{ - rserr_t err; - - err = GLW_SetMode( drivername, r_mode->integer, colorbits, cdsFullscreen ); - - switch ( err ) - { - case RSERR_INVALID_FULLSCREEN: - ri.Printf( PRINT_ALL, "...WARNING: fullscreen unavailable in this mode\n" ); - return qfalse; - case RSERR_INVALID_MODE: - ri.Printf( PRINT_ALL, "...WARNING: could not set the given mode (%d)\n", mode ); - return qfalse; - default: - break; - } - return qtrue; -} - -/* -** ChoosePFD -** -** Helper function that replaces ChoosePixelFormat. -*/ -#define MAX_PFDS 256 - -static int GLW_ChoosePFD( HDC hDC, PIXELFORMATDESCRIPTOR *pPFD ) -{ - PIXELFORMATDESCRIPTOR pfds[MAX_PFDS+1]; - int maxPFD = 0; - int i; - int bestMatch = 0; - - ri.Printf( PRINT_ALL, "...GLW_ChoosePFD( %d, %d, %d )\n", ( int ) pPFD->cColorBits, ( int ) pPFD->cDepthBits, ( int ) pPFD->cStencilBits ); - - // count number of PFDs - if ( glConfig.driverType > GLDRV_ICD ) - { - maxPFD = qwglDescribePixelFormat( hDC, 1, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[0] ); - } - else - { - maxPFD = DescribePixelFormat( hDC, 1, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[0] ); - } - if ( maxPFD > MAX_PFDS ) - { - ri.Printf( PRINT_WARNING, "...numPFDs > MAX_PFDS (%d > %d)\n", maxPFD, MAX_PFDS ); - maxPFD = MAX_PFDS; - } - - ri.Printf( PRINT_ALL, "...%d PFDs found\n", maxPFD - 1 ); - - // grab information - for ( i = 1; i <= maxPFD; i++ ) - { - if ( glConfig.driverType > GLDRV_ICD ) - { - qwglDescribePixelFormat( hDC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[i] ); - } - else - { - DescribePixelFormat( hDC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[i] ); - } - } - - // look for a best match - for ( i = 1; i <= maxPFD; i++ ) - { - // - // make sure this has hardware acceleration - // - if ( ( pfds[i].dwFlags & PFD_GENERIC_FORMAT ) != 0 ) - { - if ( !r_allowSoftwareGL->integer ) - { - if ( r_verbose->integer ) - { - ri.Printf( PRINT_ALL, "...PFD %d rejected, software acceleration\n", i ); - } - continue; - } - } - - // verify pixel type - if ( pfds[i].iPixelType != PFD_TYPE_RGBA ) - { - if ( r_verbose->integer ) - { - ri.Printf( PRINT_ALL, "...PFD %d rejected, not RGBA\n", i ); - } - continue; - } - - // verify proper flags - if ( ( ( pfds[i].dwFlags & pPFD->dwFlags ) & pPFD->dwFlags ) != pPFD->dwFlags ) - { - if ( r_verbose->integer ) - { - ri.Printf( PRINT_ALL, "...PFD %d rejected, improper flags (%x instead of %x)\n", i, pfds[i].dwFlags, pPFD->dwFlags ); - } - continue; - } - - // verify enough bits - if ( pfds[i].cDepthBits < 15 ) - { - continue; - } - if ( ( pfds[i].cStencilBits < 4 ) && ( pPFD->cStencilBits > 0 ) ) - { - continue; - } - - // - // selection criteria (in order of priority): - // - // PFD_STEREO - // colorBits - // depthBits - // stencilBits - // - if ( bestMatch ) - { - // check stereo - if ( ( pfds[i].dwFlags & PFD_STEREO ) && ( !( pfds[bestMatch].dwFlags & PFD_STEREO ) ) && ( pPFD->dwFlags & PFD_STEREO ) ) - { - bestMatch = i; - continue; - } - - if ( !( pfds[i].dwFlags & PFD_STEREO ) && ( pfds[bestMatch].dwFlags & PFD_STEREO ) && ( pPFD->dwFlags & PFD_STEREO ) ) - { - bestMatch = i; - continue; - } - - // check color - if ( pfds[bestMatch].cColorBits != pPFD->cColorBits ) - { - // prefer perfect match - if ( pfds[i].cColorBits == pPFD->cColorBits ) - { - bestMatch = i; - continue; - } - // otherwise if this PFD has more bits than our best, use it - else if ( pfds[i].cColorBits > pfds[bestMatch].cColorBits ) - { - bestMatch = i; - continue; - } - } - - // check depth - if ( pfds[bestMatch].cDepthBits != pPFD->cDepthBits ) - { - // prefer perfect match - if ( pfds[i].cDepthBits == pPFD->cDepthBits ) - { - bestMatch = i; - continue; - } - // otherwise if this PFD has more bits than our best, use it - else if ( pfds[i].cDepthBits > pfds[bestMatch].cDepthBits ) - { - bestMatch = i; - continue; - } - } - - // check stencil - if ( pfds[bestMatch].cStencilBits != pPFD->cStencilBits ) - { - // prefer perfect match - if ( pfds[i].cStencilBits == pPFD->cStencilBits ) - { - bestMatch = i; - continue; - } - // otherwise if this PFD has more bits than our best, use it - else if ( ( pfds[i].cStencilBits > pfds[bestMatch].cStencilBits ) && - ( pPFD->cStencilBits > 0 ) ) - { - bestMatch = i; - continue; - } - } - } - else - { - bestMatch = i; - } - } - - if ( !bestMatch ) - return 0; - - if ( ( pfds[bestMatch].dwFlags & PFD_GENERIC_FORMAT ) != 0 ) - { - if ( !r_allowSoftwareGL->integer ) - { - ri.Printf( PRINT_ALL, "...no hardware acceleration found\n" ); - return 0; - } - else - { - ri.Printf( PRINT_ALL, "...using software emulation\n" ); - } - } - else if ( pfds[bestMatch].dwFlags & PFD_GENERIC_ACCELERATED ) - { - ri.Printf( PRINT_ALL, "...MCD acceleration found\n" ); - } - else - { - ri.Printf( PRINT_ALL, "...hardware acceleration found\n" ); - } - - *pPFD = pfds[bestMatch]; - - return bestMatch; -} - -/* -** void GLW_CreatePFD -** -** Helper function zeros out then fills in a PFD -*/ -static void GLW_CreatePFD( PIXELFORMATDESCRIPTOR *pPFD, int colorbits, int depthbits, int stencilbits, qboolean stereo ) -{ - PIXELFORMATDESCRIPTOR src = - { - 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 - 24, // 24-bit z-buffer - 8, // 8-bit stencil buffer - 0, // no auxiliary buffer - PFD_MAIN_PLANE, // main layer - 0, // reserved - 0, 0, 0 // layer masks ignored - }; - - src.cColorBits = colorbits; - src.cDepthBits = depthbits; - src.cStencilBits = stencilbits; - - if ( stereo ) - { - ri.Printf( PRINT_ALL, "...attempting to use stereo\n" ); - src.dwFlags |= PFD_STEREO; - glConfig.stereoEnabled = qtrue; - } - else - { - glConfig.stereoEnabled = qfalse; - } - - *pPFD = src; -} - -/* -** GLW_MakeContext -*/ -static int GLW_MakeContext( PIXELFORMATDESCRIPTOR *pPFD ) -{ - int pixelformat; - - // - // don't putz around with pixelformat if it's already set (e.g. this is a soft - // reset of the graphics system) - // - if ( !glw_state.pixelFormatSet ) - { - // - // choose, set, and describe our desired pixel format. If we're - // using a minidriver then we need to bypass the GDI functions, - // otherwise use the GDI functions. - // - if ( ( pixelformat = GLW_ChoosePFD( glw_state.hDC, pPFD ) ) == 0 ) - { - ri.Printf( PRINT_ALL, "...GLW_ChoosePFD failed\n"); - return TRY_PFD_FAIL_SOFT; - } - ri.Printf( PRINT_ALL, "...PIXELFORMAT %d selected\n", pixelformat ); - - if ( glConfig.driverType > GLDRV_ICD ) - { - qwglDescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD ); - if ( qwglSetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE ) - { - ri.Printf ( PRINT_ALL, "...qwglSetPixelFormat failed\n"); - return TRY_PFD_FAIL_SOFT; - } - } - else - { - DescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD ); - - if ( SetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE ) - { - ri.Printf (PRINT_ALL, "...SetPixelFormat failed\n", glw_state.hDC ); - return TRY_PFD_FAIL_SOFT; - } - } - - glw_state.pixelFormatSet = qtrue; - } - - // - // startup the OpenGL subsystem by creating a context and making it current - // - if ( !glw_state.hGLRC ) - { - ri.Printf( PRINT_ALL, "...creating GL context: " ); - if ( ( glw_state.hGLRC = qwglCreateContext( glw_state.hDC ) ) == 0 ) - { - ri.Printf (PRINT_ALL, "failed\n"); - - return TRY_PFD_FAIL_HARD; - } - ri.Printf( PRINT_ALL, "succeeded\n" ); - - ri.Printf( PRINT_ALL, "...making context current: " ); - if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) - { - qwglDeleteContext( glw_state.hGLRC ); - glw_state.hGLRC = NULL; - ri.Printf (PRINT_ALL, "failed\n"); - return TRY_PFD_FAIL_HARD; - } - ri.Printf( PRINT_ALL, "succeeded\n" ); - } - - return TRY_PFD_SUCCESS; -} - - -/* -** GLW_InitDriver -** -** - get a DC if one doesn't exist -** - create an HGLRC if one doesn't exist -*/ -static qboolean GLW_InitDriver( const char *drivername, int colorbits ) -{ - int tpfd; - int depthbits, stencilbits; - static PIXELFORMATDESCRIPTOR pfd; // save between frames since 'tr' gets cleared - - ri.Printf( PRINT_ALL, "Initializing OpenGL driver\n" ); - - // - // get a DC for our window if we don't already have one allocated - // - if ( glw_state.hDC == NULL ) - { - ri.Printf( PRINT_ALL, "...getting DC: " ); - - if ( ( glw_state.hDC = GetDC( g_wv.hWnd ) ) == NULL ) - { - ri.Printf( PRINT_ALL, "failed\n" ); - return qfalse; - } - ri.Printf( PRINT_ALL, "succeeded\n" ); - } - - if ( colorbits == 0 ) - { - colorbits = glw_state.desktopBitsPixel; - } - - // - // implicitly assume Z-buffer depth == desktop color depth - // - if ( r_depthbits->integer == 0 ) { - if ( colorbits > 16 ) { - depthbits = 24; - } else { - depthbits = 16; - } - } else { - depthbits = r_depthbits->integer; - } - - // - // do not allow stencil if Z-buffer depth likely won't contain it - // - stencilbits = r_stencilbits->integer; - if ( depthbits < 24 ) - { - stencilbits = 0; - } - - // - // make two attempts to set the PIXELFORMAT - // - - // - // first attempt: r_colorbits, depthbits, and r_stencilbits - // - if ( !glw_state.pixelFormatSet ) - { - GLW_CreatePFD( &pfd, colorbits, depthbits, stencilbits, r_stereo->integer ); - if ( ( tpfd = GLW_MakeContext( &pfd ) ) != TRY_PFD_SUCCESS ) - { - if ( tpfd == TRY_PFD_FAIL_HARD ) - { - ri.Printf( PRINT_WARNING, "...failed hard\n" ); - return qfalse; - } - - // - // punt if we've already tried the desktop bit depth and no stencil bits - // - if ( ( r_colorbits->integer == glw_state.desktopBitsPixel ) && - ( stencilbits == 0 ) ) - { - ReleaseDC( g_wv.hWnd, glw_state.hDC ); - glw_state.hDC = NULL; - - ri.Printf( PRINT_ALL, "...failed to find an appropriate PIXELFORMAT\n" ); - - return qfalse; - } - - // - // second attempt: desktop's color bits and no stencil - // - if ( colorbits > glw_state.desktopBitsPixel ) - { - colorbits = glw_state.desktopBitsPixel; - } - GLW_CreatePFD( &pfd, colorbits, depthbits, 0, r_stereo->integer ); - if ( GLW_MakeContext( &pfd ) != TRY_PFD_SUCCESS ) - { - if ( glw_state.hDC ) - { - ReleaseDC( g_wv.hWnd, glw_state.hDC ); - glw_state.hDC = NULL; - } - - ri.Printf( PRINT_ALL, "...failed to find an appropriate PIXELFORMAT\n" ); - - return qfalse; - } - } - - /* - ** report if stereo is desired but unavailable - */ - 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 = CLIENT_WINDOW_TITLE; - - 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, - CLIENT_WINDOW_TITLE, - CLIENT_WINDOW_TITLE, - 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; - } - } - else - { - ri.Printf( PRINT_ALL, "...ignoring WGL_3DFX_gamma_control\n" ); - } - } - else - { - ri.Printf( PRINT_ALL, "...WGL_3DFX_gamma_control not found\n" ); - } - - textureFilterAnisotropic = qfalse; - if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) ) - { - if ( r_ext_texture_filter_anisotropic->integer ) { - qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy ); - if ( maxAnisotropy <= 0 ) { - ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not properly supported!\n" ); - maxAnisotropy = 0; - } - else - { - ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", maxAnisotropy ); - textureFilterAnisotropic = qtrue; - } - } - else - { - ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" ); - } - } - else - { - ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" ); - } -} - -/* -** GLW_CheckOSVersion -*/ -static qboolean GLW_CheckOSVersion( void ) -{ -#define OSR2_BUILD_NUMBER 1111 - - OSVERSIONINFO vinfo; - - vinfo.dwOSVersionInfoSize = sizeof(vinfo); - - glw_state.allowdisplaydepthchange = qfalse; - - if ( GetVersionEx( &vinfo) ) - { - if ( vinfo.dwMajorVersion > 4 ) - { - glw_state.allowdisplaydepthchange = qtrue; - } - else if ( vinfo.dwMajorVersion == 4 ) - { - if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) - { - glw_state.allowdisplaydepthchange = qtrue; - } - else if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) - { - if ( LOWORD( vinfo.dwBuildNumber ) >= OSR2_BUILD_NUMBER ) - { - glw_state.allowdisplaydepthchange = qtrue; - } - } - } - } - else - { - ri.Printf( PRINT_ALL, "GLW_CheckOSVersion() - GetVersionEx failed\n" ); - return qfalse; - } - - return qtrue; -} - -/* -** GLW_LoadOpenGL -** -** GLimp_win.c internal function that attempts to load and use -** a specific OpenGL DLL. -*/ -static qboolean GLW_LoadOpenGL( const char *drivername ) -{ - char buffer[1024]; - qboolean cdsFullscreen; - - Q_strncpyz( buffer, drivername, sizeof(buffer) ); - Q_strlwr(buffer); - - // - // determine if we're on a standalone driver - // - if ( strstr( buffer, "opengl32" ) != 0 || r_maskMinidriver->integer ) - { - glConfig.driverType = GLDRV_ICD; - } - else - { - glConfig.driverType = GLDRV_STANDALONE; - - ri.Printf( PRINT_ALL, "...assuming '%s' is a standalone driver\n", drivername ); - - if ( strstr( buffer, _3DFX_DRIVER_NAME ) ) - { - glConfig.driverType = GLDRV_VOODOO; - } - } - - // disable the 3Dfx splash screen - _putenv("FX_GLIDE_NO_SPLASH=0"); - - // - // load the driver and bind our function pointers to it - // - if ( QGL_Init( buffer ) ) - { - cdsFullscreen = r_fullscreen->integer; - - // create the window and set up the context - if ( !GLW_StartDriverAndSetMode( drivername, r_mode->integer, r_colorbits->integer, cdsFullscreen ) ) - { - // if we're on a 24/32-bit desktop and we're going fullscreen on an ICD, - // try it again but with a 16-bit desktop - if ( glConfig.driverType == GLDRV_ICD ) - { - if ( r_colorbits->integer != 16 || - cdsFullscreen != qtrue || - r_mode->integer != 3 ) - { - if ( !GLW_StartDriverAndSetMode( drivername, 3, 16, qtrue ) ) - { - goto fail; - } - } - } - else - { - goto fail; - } - } - - if ( glConfig.driverType == GLDRV_VOODOO ) - { - glConfig.isFullscreen = qtrue; - } - - return qtrue; - } -fail: - - QGL_Shutdown(); - - return qfalse; -} - -/* -** GLimp_EndFrame -*/ -void GLimp_EndFrame (void) -{ - // - // swapinterval stuff - // - if ( r_swapInterval->modified ) { - r_swapInterval->modified = qfalse; - - if ( !glConfig.stereoEnabled ) { // why? - if ( qwglSwapIntervalEXT ) { - qwglSwapIntervalEXT( r_swapInterval->integer ); - } - } - } - - - // don't flip if drawing to front buffer - if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 ) - { - if ( glConfig.driverType > GLDRV_ICD ) - { - if ( !qwglSwapBuffers( glw_state.hDC ) ) - { - ri.Error( ERR_FATAL, "GLimp_EndFrame() - SwapBuffers() failed!\n" ); - } - } - else - { - SwapBuffers( glw_state.hDC ); - } - } - - // check logging - QGL_EnableLogging( r_logFile->integer ); -} - -static void GLW_StartOpenGL( void ) -{ - qboolean attemptedOpenGL32 = qfalse; - qboolean attempted3Dfx = qfalse; - - // - // load and initialize the specific OpenGL driver - // - if ( !GLW_LoadOpenGL( r_glDriver->string ) ) - { - if ( !Q_stricmp( r_glDriver->string, OPENGL_DRIVER_NAME ) ) - { - attemptedOpenGL32 = qtrue; - } - else if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) - { - attempted3Dfx = qtrue; - } - - if ( !attempted3Dfx ) - { - attempted3Dfx = qtrue; - if ( GLW_LoadOpenGL( _3DFX_DRIVER_NAME ) ) - { - ri.Cvar_Set( "r_glDriver", _3DFX_DRIVER_NAME ); - r_glDriver->modified = qfalse; - } - else - { - if ( !attemptedOpenGL32 ) - { - if ( !GLW_LoadOpenGL( OPENGL_DRIVER_NAME ) ) - { - ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem\n" ); - } - ri.Cvar_Set( "r_glDriver", OPENGL_DRIVER_NAME ); - r_glDriver->modified = qfalse; - } - else - { - ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem\n" ); - } - } - } - else if ( !attemptedOpenGL32 ) - { - attemptedOpenGL32 = qtrue; - if ( GLW_LoadOpenGL( OPENGL_DRIVER_NAME ) ) - { - ri.Cvar_Set( "r_glDriver", OPENGL_DRIVER_NAME ); - r_glDriver->modified = qfalse; - } - else - { - ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem\n" ); - } - } - } -} - -/* -** GLimp_Init -** -** This is the platform specific OpenGL initialization function. It -** is responsible for loading OpenGL, initializing it, setting -** extensions, creating a window of the appropriate size, doing -** fullscreen manipulations, etc. Its overall responsibility is -** to make sure that a functional OpenGL subsystem is operating -** when it returns to the ref. -*/ -void GLimp_Init( void ) -{ - char buf[1024]; - cvar_t *lastValidRenderer = ri.Cvar_Get( "r_lastValidRenderer", "(uninitialized)", CVAR_ARCHIVE ); - cvar_t *cv; - - ri.Printf( PRINT_ALL, "Initializing OpenGL subsystem\n" ); - - // - // check OS version to see if we can do fullscreen display changes - // - if ( !GLW_CheckOSVersion() ) - { - ri.Error( ERR_FATAL, "GLimp_Init() - incorrect operating system\n" ); - } - - // save off hInstance and wndproc - cv = ri.Cvar_Get( "win_hinstance", "", 0 ); - sscanf( cv->string, "%i", (int *)&g_wv.hInstance ); - - cv = ri.Cvar_Get( "win_wndproc", "", 0 ); - sscanf( cv->string, "%i", (int *)&glw_state.wndproc ); - - r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH ); - r_maskMinidriver = ri.Cvar_Get( "r_maskMinidriver", "0", CVAR_LATCH ); - - // load appropriate DLL and initialize subsystem - GLW_StartOpenGL(); - - // get our config strings - Q_strncpyz( glConfig.vendor_string, qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) ); - Q_strncpyz( glConfig.renderer_string, qglGetString (GL_RENDERER), sizeof( glConfig.renderer_string ) ); - Q_strncpyz( glConfig.version_string, qglGetString (GL_VERSION), sizeof( glConfig.version_string ) ); - Q_strncpyz( glConfig.extensions_string, qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) ); - - // - // chipset specific configuration - // - Q_strncpyz( buf, glConfig.renderer_string, sizeof(buf) ); - Q_strlwr( buf ); - - // - // NOTE: if changing cvars, do it within this block. This allows them - // to be overridden when testing driver fixes, etc. but only sets - // them to their default state when the hardware is first installed/run. - // - if ( Q_stricmp( lastValidRenderer->string, glConfig.renderer_string ) ) - { - glConfig.hardwareType = GLHW_GENERIC; - - ri.Cvar_Set( "r_textureMode", "GL_LINEAR_MIPMAP_NEAREST" ); - - // VOODOO GRAPHICS w/ 2MB - if ( strstr( buf, "voodoo graphics/1 tmu/2 mb" ) ) - { - ri.Cvar_Set( "r_picmip", "2" ); - ri.Cvar_Get( "r_picmip", "1", CVAR_ARCHIVE | CVAR_LATCH ); - } - else - { - ri.Cvar_Set( "r_picmip", "1" ); - - if ( strstr( buf, "rage 128" ) || strstr( buf, "rage128" ) ) - { - ri.Cvar_Set( "r_finish", "0" ); - } - // Savage3D and Savage4 should always have trilinear enabled - else if ( strstr( buf, "savage3d" ) || strstr( buf, "s3 savage4" ) ) - { - ri.Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" ); - } - } - } - - // - // this is where hardware specific workarounds that should be - // detected/initialized every startup should go. - // - if ( strstr( buf, "banshee" ) || strstr( buf, "voodoo3" ) ) - { - glConfig.hardwareType = GLHW_3DFX_2D3D; - } - // VOODOO GRAPHICS w/ 2MB - else if ( strstr( buf, "voodoo graphics/1 tmu/2 mb" ) ) - { - } - else if ( strstr( buf, "glzicd" ) ) - { - } - else if ( strstr( buf, "rage pro" ) || strstr( buf, "Rage Pro" ) || strstr( buf, "ragepro" ) ) - { - glConfig.hardwareType = GLHW_RAGEPRO; - } - else if ( strstr( buf, "rage 128" ) ) - { - } - else if ( strstr( buf, "permedia2" ) ) - { - glConfig.hardwareType = GLHW_PERMEDIA2; - } - else if ( strstr( buf, "riva 128" ) ) - { - glConfig.hardwareType = GLHW_RIVA128; - } - else if ( strstr( buf, "riva tnt " ) ) - { - } - - ri.Cvar_Set( "r_lastValidRenderer", glConfig.renderer_string ); - - GLW_InitExtensions(); - WG_CheckHardwareGamma(); -} - -/* -** GLimp_Shutdown -** -** This routine does all OS specific shutdown procedures for the OpenGL -** subsystem. -*/ -void GLimp_Shutdown( void ) -{ -// const char *strings[] = { "soft", "hard" }; - const char *success[] = { "failed", "success" }; - int retVal; - - // FIXME: Brian, we need better fallbacks from partially initialized failures - if ( !qwglMakeCurrent ) { - return; - } - - ri.Printf( PRINT_ALL, "Shutting down OpenGL subsystem\n" ); - - // restore gamma. We do this first because 3Dfx's extension needs a valid OGL subsystem - WG_RestoreGamma(); - - // set current context to NULL - if ( qwglMakeCurrent ) - { - retVal = qwglMakeCurrent( NULL, NULL ) != 0; - - ri.Printf( PRINT_ALL, "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] ); - } - - // delete HGLRC - if ( glw_state.hGLRC ) - { - retVal = qwglDeleteContext( glw_state.hGLRC ) != 0; - ri.Printf( PRINT_ALL, "...deleting GL context: %s\n", success[retVal] ); - glw_state.hGLRC = NULL; - } - - // release DC - if ( glw_state.hDC ) - { - retVal = ReleaseDC( g_wv.hWnd, glw_state.hDC ) != 0; - ri.Printf( PRINT_ALL, "...releasing DC: %s\n", success[retVal] ); - glw_state.hDC = NULL; - } - - // destroy window - if ( g_wv.hWnd ) - { - ri.Printf( PRINT_ALL, "...destroying window\n" ); - ShowWindow( g_wv.hWnd, SW_HIDE ); - DestroyWindow( g_wv.hWnd ); - g_wv.hWnd = NULL; - glw_state.pixelFormatSet = qfalse; - } - - // close the r_logFile - if ( glw_state.log_fp ) - { - fclose( glw_state.log_fp ); - glw_state.log_fp = 0; - } - - // reset display settings - if ( glw_state.cdsFullscreen ) - { - ri.Printf( PRINT_ALL, "...resetting display\n" ); - ChangeDisplaySettings( 0, 0 ); - glw_state.cdsFullscreen = qfalse; - } - - // shutdown QGL subsystem - QGL_Shutdown(); - - memset( &glConfig, 0, sizeof( glConfig ) ); - memset( &glState, 0, sizeof( glState ) ); -} - -/* -** GLimp_LogComment -*/ -void GLimp_LogComment( char *comment ) -{ - if ( glw_state.log_fp ) { - fprintf( glw_state.log_fp, "%s", comment ); - } -} - - -/* -=========================================================== - -SMP acceleration - -=========================================================== -*/ - -HANDLE renderCommandsEvent; -HANDLE renderCompletedEvent; -HANDLE renderActiveEvent; - -void (*glimpRenderThread)( void ); - -void GLimp_RenderThreadWrapper( void ) { - glimpRenderThread(); - - // unbind the context before we die - qwglMakeCurrent( glw_state.hDC, NULL ); -} - -/* -======================= -GLimp_SpawnRenderThread -======================= -*/ -HANDLE renderThreadHandle; -int renderThreadId; -qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) { - - renderCommandsEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); - renderCompletedEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); - renderActiveEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); - - glimpRenderThread = function; - - renderThreadHandle = CreateThread( - NULL, // LPSECURITY_ATTRIBUTES lpsa, - 0, // DWORD cbStack, - (LPTHREAD_START_ROUTINE)GLimp_RenderThreadWrapper, // LPTHREAD_START_ROUTINE lpStartAddr, - 0, // LPVOID lpvThreadParm, - 0, // DWORD fdwCreate, - (long *)&renderThreadId ); - - if ( !renderThreadHandle ) { - return qfalse; - } - - return qtrue; -} - -static void *smpData; -static int wglErrors; - -void *GLimp_RendererSleep( void ) { - void *data; - - if ( !qwglMakeCurrent( glw_state.hDC, NULL ) ) { - wglErrors++; - } - - // after this, the front end can exit GLimp_FrontEndSleep - SetEvent( renderCompletedEvent ); - - WaitForSingleObject( renderCommandsEvent, INFINITE ); - - ResetEvent( renderActiveEvent ); - - if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) { - wglErrors++; - } - - ResetEvent( renderCompletedEvent ); - ResetEvent( renderCommandsEvent ); - - data = smpData; - - // after this, the main thread can exit GLimp_WakeRenderer - SetEvent( renderActiveEvent ); - - return data; -} - - -void GLimp_FrontEndSleep( void ) { - WaitForSingleObject( renderCompletedEvent, INFINITE ); - - if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) { - wglErrors++; - } -} - - -void GLimp_WakeRenderer( void *data ) { - smpData = data; - - if ( !qwglMakeCurrent( glw_state.hDC, NULL ) ) { - wglErrors++; - } - - // after this, the renderer can continue through GLimp_RendererSleep - SetEvent( renderCommandsEvent ); - - WaitForSingleObject( renderActiveEvent, INFINITE ); -} - -- cgit v1.2.3