/* =============== RE_Shutdown =============== */ void RE_Shutdown( qboolean destroyWindow ) { ri.Printf( PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow ); ri.Cmd_RemoveCommand ("modellist"); ri.Cmd_RemoveCommand ("screenshotJPEG"); ri.Cmd_RemoveCommand ("screenshot"); ri.Cmd_RemoveCommand ("imagelist"); ri.Cmd_RemoveCommand ("shaderlist"); ri.Cmd_RemoveCommand ("skinlist"); ri.Cmd_RemoveCommand ("gfxinfo"); ri.Cmd_RemoveCommand( "modelist" ); ri.Cmd_RemoveCommand( "shaderstate" ); if ( tr.registered ) { R_SyncRenderThread(); R_ShutdownCommandBuffers(); R_DeleteTextures(); } R_DoneFreeType(); // shut down platform specific OpenGL stuff if ( destroyWindow ) { GLimp_Shutdown(); } tr.registered = qfalse; }
void RE_Shutdown( qboolean destroyWindow ) { ri.Printf( PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow ); ri.Cmd_RemoveCommand ("imagelist"); ri.Cmd_RemoveCommand ("shaderlist"); ri.Cmd_RemoveCommand ("skinlist"); ri.Cmd_RemoveCommand ("modellist"); ri.Cmd_RemoveCommand ("modelist" ); ri.Cmd_RemoveCommand ("screenshot"); ri.Cmd_RemoveCommand ("screenshot_tga"); ri.Cmd_RemoveCommand ("gfxinfo"); ri.Cmd_RemoveCommand ("r_fogDistance"); ri.Cmd_RemoveCommand ("r_fogColor"); ri.Cmd_RemoveCommand ("modelcacheinfo"); ri.Cmd_RemoveCommand ("imagecacheinfo"); R_ShutdownWorldEffects(); R_ShutdownFonts(); if ( tr.registered ) { R_SyncRenderThread(); R_ShutdownCommandBuffers(); if (destroyWindow) { R_DeleteTextures(); // only do this for vid_restart now, not during things like map load } } // shut down platform specific OpenGL stuff if ( destroyWindow ) { GLimp_Shutdown(); } tr.registered = qfalse; }
/* =============== RE_Shutdown =============== */ void RE_Shutdown( qboolean destroyWindow ) { ri.Printf( PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow ); ri.Cmd_RemoveCommand ("modellist"); ri.Cmd_RemoveCommand ("screenshotJPEG"); ri.Cmd_RemoveCommand ("screenshot"); ri.Cmd_RemoveCommand ("imagelist"); ri.Cmd_RemoveCommand ("shaderlist"); ri.Cmd_RemoveCommand ("skinlist"); ri.Cmd_RemoveCommand ("gfxinfo"); ri.Cmd_RemoveCommand("minimize"); ri.Cmd_RemoveCommand( "modelist" ); ri.Cmd_RemoveCommand( "shaderstate" ); if ( tr.registered ) { R_IssuePendingRenderCommands(); R_DeleteTextures(); } R_DoneFreeType(); // shut down platform specific OpenGL stuff if ( destroyWindow ) { GLimp_Shutdown(); Com_Memset( &glConfig, 0, sizeof( glConfig ) ); Com_Memset( &glState, 0, sizeof( glState ) ); } tr.registered = qfalse; }
/* ============= Sys_Error Show the early console as an error dialog ============= */ void Sys_Error( const char *error, ... ) { va_list argptr; char text[4096]; MSG msg; va_start( argptr, error ); vsprintf( text, error, argptr ); va_end( argptr); Conbuf_AppendText( text ); Conbuf_AppendText( "\n" ); Win_SetErrorText( text ); Sys_ShowConsole( 1, true ); timeEndPeriod( 1 ); Sys_ShutdownInput(); GLimp_Shutdown(); // wait for the user to quit while ( 1 ) { if ( !GetMessage( &msg, NULL, 0, 0 ) ) { common->Quit(); } TranslateMessage( &msg ); DispatchMessage( &msg ); } Sys_DestroyConsole(); exit (1); }
/* =============== RE_Shutdown =============== */ void RE_Shutdown(qboolean destroyWindow) { ri.Printf(PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow); ri.Cmd_RemoveCommand("modellist"); ri.Cmd_RemoveCommand("screenshotJPEG"); ri.Cmd_RemoveCommand("screenshot"); ri.Cmd_RemoveCommand("imagelist"); ri.Cmd_RemoveCommand("shaderlist"); ri.Cmd_RemoveCommand("skinlist"); ri.Cmd_RemoveCommand("gfxinfo"); ri.Cmd_RemoveCommand("minimize"); ri.Cmd_RemoveCommand("modelist"); ri.Cmd_RemoveCommand("shaderstate"); ri.Cmd_RemoveCommand("taginfo"); // keep a backup of the current images if possible // clean out any remaining unused media from the last backup R_PurgeCache(); if (r_cache->integer) { if (tr.registered) { if (destroyWindow) { R_IssuePendingRenderCommands(); R_DeleteTextures(); } else { // backup the current media R_BackupModels(); R_BackupShaders(); R_BackupImages(); } } } else if (tr.registered) { R_IssuePendingRenderCommands(); R_DeleteTextures(); } R_DoneFreeType(); // shut down platform specific OpenGL stuff if (destroyWindow) { GLimp_Shutdown(); // release the virtual memory R_Hunk_End(); R_FreeImageBuffer(); ri.Tag_Free(); // wipe all render alloc'd zone memory } tr.registered = qfalse; }
/* =============== RE_Shutdown =============== */ void RE_Shutdown( qbool destroyWindow ) { ST_Printf( PRINT_R_VERBOSE, "R_Shutdown( %i )\n", destroyWindow ); // shut down platform specific OpenGL stuff if ( destroyWindow ) { GLimp_Shutdown(); } }
/* ** GLimp_SetMode */ rserr_t GLimp_SetMode( int x, int y, int width, int height, int displayFrequency, qboolean fullscreen, qboolean wideScreen ) { const char *win_fs[] = { "W", "FS" }; // check whether we can toggle fullscreen without a vid_restart if( glw_state.hWnd ) { if( glConfig.width == width && glConfig.height == height && fullscreen != glConfig.fullScreen ) { glConfig.fullScreen = VID_SetFullscreenMode( displayFrequency, fullscreen ); if( glConfig.fullScreen == fullscreen ) { VID_SetWindowSize( fullscreen ); return rserr_ok; } return rserr_restart_required; } } ri.Com_Printf( "Initializing OpenGL display\n" ); ri.Com_Printf( "...setting mode:" ); // disable fullscreen if rendering to a parent window if( glw_state.parenthWnd ) { RECT parentWindowRect; fullscreen = qfalse; wideScreen = qfalse; GetWindowRect( glw_state.parenthWnd, &parentWindowRect ); width = parentWindowRect.right - parentWindowRect.left; height = parentWindowRect.bottom - parentWindowRect.top; } ri.Com_Printf( " %d %d %s\n", width, height, win_fs[fullscreen] ); // destroy the existing window if( glw_state.hWnd ) { GLimp_Shutdown(); } glw_state.win_x = x; glw_state.win_y = y; glConfig.width = width; glConfig.height = height; glConfig.wideScreen = wideScreen; glConfig.fullScreen = VID_SetFullscreenMode( displayFrequency, fullscreen ); if( !VID_CreateWindow() ) { return rserr_invalid_mode; } return ( fullscreen == glConfig.fullScreen ? rserr_ok : rserr_invalid_fullscreen ); }
/* ** GLimp_SetMode */ rserr_t GLimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen ) { int width, height; const char *win_fs[] = { "W", "FS" }; Com_Printf ( "Initializing OpenGL display\n"); Com_Printf ("...setting mode %d:", mode ); if ( !R_GetModeInfo( &width, &height, mode ) ) { Com_Printf ( " invalid mode\n" ); return rserr_invalid_mode; } Com_Printf ( " %d %d %s\n", width, height, win_fs[fullscreen] ); // destroy the existing window if (glw_state.hWnd) GLimp_Shutdown (); // do a CDS if needed if ( fullscreen ) { if (GLimp_SetFSMode(&width, &height)) { *pwidth = width; *pheight = height; if (!VID_CreateWindow (width, height, true)) { Com_Printf("...restoring display settings\n"); ChangeDisplaySettings( 0, 0 ); gl_state.fullscreen = false; return rserr_invalid_mode; } EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &fullScreenMode); gl_state.fullscreen = true; return rserr_ok; } } *pwidth = width; *pheight = height; Com_Printf ( "...setting windowed mode\n" ); if (gl_state.fullscreen) { ChangeDisplaySettings( 0, 0 ); gl_state.fullscreen = false; } if (!VID_CreateWindow (width, height, false)) return rserr_invalid_mode; return (fullscreen) ? rserr_invalid_fullscreen : rserr_ok; }
static void signal_handler( int sig ) { if ( signalcaught ) { printf( "DOUBLE SIGNAL FAULT: Received signal %d, exiting...\n", sig ); Sys_Exit( 1 ); } signalcaught = qtrue; printf( "Received signal %d, exiting...\n", sig ); GLimp_Shutdown(); Sys_Exit( 0 ); }
static void signal_handler(int sig) // bk010104 - replace this... { if (signalcaught) { printf("DOUBLE SIGNAL FAULT: Received signal %d, exiting...\n", sig); Sys_Exit(1); // bk010104 - abstraction } signalcaught = qtrue; printf("Received signal %d, exiting...\n", sig); GLimp_Shutdown(); // bk010104 - shouldn't this be CL_Shutdown Sys_Exit(1); // bk010104 - abstraction }
static void signal_handler(int sig) {// bk010104 - replace this... (NOTE TTimo huh?) if (signalcaught) { printf("DOUBLE SIGNAL FAULT: Received signal %d, exiting...\n", sig); Sys_Exit(1); // bk010104 - abstraction } signalcaught = qtrue; printf("Received signal %d, exiting...\n", sig); #ifndef DEDICATED GLimp_Shutdown(); // bk010104 - shouldn't this be CL_Shutdown #endif Sys_Exit(0); // bk010104 - abstraction NOTE TTimo send a 0 to avoid DOUBLE SIGNAL FAULT }
/* ** GLimp_SetMode */ rserr_t GLimp_SetMode( int x, int y, int width, int height, int displayFrequency, bool fullscreen, bool stereo, bool borderless ) { const char *win_fs[] = { "W", "FS" }; ri.Com_Printf( "Setting video mode:" ); // disable fullscreen if rendering to a parent window if( glw_state.parenthWnd ) { RECT parentWindowRect; fullscreen = false; GetWindowRect( glw_state.parenthWnd, &parentWindowRect ); width = parentWindowRect.right - parentWindowRect.left; height = parentWindowRect.bottom - parentWindowRect.top; } ri.Com_Printf( " %d %d %s\n", width, height, win_fs[fullscreen] ); // destroy the existing window if( glw_state.hWnd ) { GLimp_Shutdown(); } glw_state.win_x = x; glw_state.win_y = y; glConfig.width = width; glConfig.height = height; glConfig.fullScreen = ( fullscreen ? GLimp_SetFullscreenMode( displayFrequency, fullscreen ) == rserr_ok : false ); glConfig.stereoEnabled = stereo; glConfig.borderless = borderless; GLimp_CreateWindow(); // init all the gl stuff for the window if( !GLimp_InitGL() ) { ri.Com_Printf( "GLimp_CreateWindow() - GLimp_InitGL failed\n" ); return false; } return ( fullscreen == glConfig.fullScreen ? rserr_ok : rserr_invalid_fullscreen ); }
/* ** GLimp_SetMode */ int GLimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen ) { int width, height; GLint attribs[32]; ri.Con_Printf( PRINT_ALL, "Initializing OpenGL display\n"); ri.Con_Printf (PRINT_ALL, "...setting mode %d:", mode ); if ( !ri.Vid_GetModeInfo( &width, &height, mode ) ) { ri.Con_Printf( PRINT_ALL, " invalid mode\n" ); return rserr_invalid_mode; } ri.Con_Printf( PRINT_ALL, " %d %d\n", width, height ); // destroy the existing window GLimp_Shutdown (); // set fx attribs attribs[0] = FXMESA_DOUBLEBUFFER; attribs[1] = FXMESA_ALPHA_SIZE; attribs[2] = 1; attribs[3] = FXMESA_DEPTH_SIZE; attribs[4] = 1; attribs[5] = FXMESA_NONE; fc = qfxMesaCreateContext(0, findres(&width, &height), GR_REFRESH_75Hz, attribs); if (!fc) return rserr_invalid_mode; *pwidth = width; *pheight = height; // let the sound and input subsystems know about the new window ri.Vid_NewWindow (width, height); qfxMesaMakeCurrent(fc); return rserr_ok; }
/** * Set video mode. * @param mode number of the mode to set * @param fullscreen <code>true</code> for a fullscreen mode, * <code>false</code> otherwise */ rserr_t GLimp_SetMode( int x, int y, int width, int height, int displayFrequency, bool fullscreen, bool stereo, bool borderless ) { const char *win_fs[] = {"W", "FS"}; #ifdef __APLE__ if( fullscreen ) { borderless = true; } else { borderless = false; } #endif ri.Com_Printf( "Initializing OpenGL display\n" ); ri.Com_Printf( "...setting mode:" ); ri.Com_Printf( " %d %d %s\n", width, height, win_fs[fullscreen] ); // destroy the existing window if( glw_state.sdl_window ) { GLimp_Shutdown(); } GLimp_CreateWindow( x, y, width, height ); // init all the gl stuff for the window if( !GLimp_InitGL( r_stencilbits->integer, stereo ) ) { ri.Com_Printf( "VID_CreateWindow() - GLimp_InitGL failed\n" ); return rserr_invalid_mode; } glConfig.width = width; glConfig.height = height; glConfig.borderless = borderless; glConfig.fullScreen = fullscreen; if( GLimp_SetFullscreenMode( displayFrequency, fullscreen ) == rserr_ok ) { glConfig.fullScreen = fullscreen; } else { glConfig.fullScreen = !fullscreen; } return glConfig.fullScreen == fullscreen ? rserr_ok : rserr_invalid_fullscreen; }
/* =============== RE_Shutdown =============== */ void RE_Shutdown( qboolean destroyWindow ) { ri.Printf( PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow ); ri.Cmd_RemoveCommand ("modellist"); ri.Cmd_RemoveCommand ("screenshotJPEG"); ri.Cmd_RemoveCommand ("screenshot"); ri.Cmd_RemoveCommand ("imagelist"); ri.Cmd_RemoveCommand ("shaderlist"); ri.Cmd_RemoveCommand ("skinlist"); ri.Cmd_RemoveCommand ("gfxinfo"); ri.Cmd_RemoveCommand ("modelist"); ri.Cmd_RemoveCommand ("shaderstate"); ri.Cmd_RemoveCommand ("r_we"); ri.Cmd_RemoveCommand ("modelcacheinfo"); ri.Cmd_RemoveCommand ("imagecacheinfo"); #ifndef DEDICATED R_ShutdownFonts(); if ( tr.registered ) { R_SyncRenderThread(); R_ShutdownCommandBuffers(); if (destroyWindow) { R_DeleteTextures(); // only do this for vid_restart now, not during things like map load } } // shut down platform specific OpenGL stuff if ( destroyWindow ) { GLimp_Shutdown(); } #endif //!DEDICATED tr.registered = qfalse; #ifdef G2_COLLISION_ENABLED if (G2VertSpaceServer) { delete G2VertSpaceServer; G2VertSpaceServer = 0; } #endif }
/* =============== RE_Shutdown =============== */ void RE_Shutdown( qboolean destroyWindow ) { ri.Printf( PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow ); ri.Cmd_RemoveCommand( "modellist" ); ri.Cmd_RemoveCommand( "screenshotJPEG" ); ri.Cmd_RemoveCommand( "screenshot" ); ri.Cmd_RemoveCommand( "imagelist" ); ri.Cmd_RemoveCommand( "shaderlist" ); ri.Cmd_RemoveCommand( "skinlist" ); ri.Cmd_RemoveCommand( "gfxinfo" ); ri.Cmd_RemoveCommand("minimize"); ri.Cmd_RemoveCommand( "modelist" ); ri.Cmd_RemoveCommand( "shaderstate" ); ri.Cmd_RemoveCommand( "taginfo" ); // Ridah ri.Cmd_RemoveCommand( "cropimages" ); // done. if ( tr.registered ) { R_IssuePendingRenderCommands(); R_DeleteTextures(); } R_DoneFreeType(); // shut down platform specific OpenGL stuff if ( destroyWindow ) { GLimp_Shutdown(); // Ridah, release the virtual memory R_Hunk_End(); R_FreeImageBuffer(); ri.Tag_Free(); // wipe all render alloc'd zone memory } tr.registered = qfalse; }
/** * Set video mode. * @param mode number of the mode to set * @param fullscreen <code>true</code> for a fullscreen mode, * <code>false</code> otherwise */ rserr_t GLimp_SetMode( int x, int y, int width, int height, int displayFrequency, bool fullscreen, bool stereo ) { const char *win_fs[] = {"W", "FS"}; if( width == glConfig.width && height == glConfig.height && glConfig.fullScreen != fullscreen ) { if( GLimp_SetWindowFullscreen( fullscreen ) ) { glConfig.fullScreen = fullscreen; return rserr_ok; } return rserr_restart_required; } ri.Com_Printf( "Initializing OpenGL display\n" ); ri.Com_Printf( "...setting mode:" ); ri.Com_Printf( " %d %d %s\n", width, height, win_fs[fullscreen] ); // destroy the existing window if( glw_state.sdl_window ) { GLimp_Shutdown(); } GLimp_CreateWindow( x, y, width, height ); // init all the gl stuff for the window if( !GLimp_InitGL( r_stencilbits->integer, stereo ) ) { ri.Com_Printf( "VID_CreateWindow() - GLimp_InitGL failed\n" ); return rserr_invalid_mode; } if( fullscreen && !GLimp_SetWindowFullscreen( fullscreen ) ) { return rserr_invalid_fullscreen; } glConfig.width = width; glConfig.height = height; glConfig.fullScreen = fullscreen; return rserr_ok; }
/* * RE_Shutdown */ void RE_Shutdown(qbool destroyWindow) { ri.Printf(PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow); ri.cmdremove ("modellist"); ri.cmdremove ("screenshotJPEG"); ri.cmdremove ("screenshot"); ri.cmdremove ("imagelist"); ri.cmdremove ("shaderlist"); ri.cmdremove ("skinlist"); ri.cmdremove ("gfxinfo"); ri.cmdremove("minimize"); ri.cmdremove("modelist"); ri.cmdremove("shaderstate"); if(tr.registered){ R_SyncRenderThread(); R_ShutdownCommandBuffers(); R_ShutDownQueries(); R_DeleteTextures(); R_ShutdownVBOs(); FBO_Shutdown(); GLSL_ShutdownGPUShaders(); } R_DoneFreeType(); /* shut down platform specific OpenGL stuff */ if(destroyWindow){ GLimp_Shutdown(); } tr.registered = qfalse; }
/* ** GLimp_SetMode */ int GLimp_SetMode( int mode, qboolean fullscreen ) { int width, height; const char *win_fs[] = { "W", "FS" }; qboolean wideScreen; // disable fullscreen if rendering to a parent window if( glw_state.parenthWnd ) { fullscreen = qfalse; } Com_Printf( "Initializing OpenGL display\n" ); Com_Printf( "...setting mode %d:", mode ); if( !VID_GetModeInfo( &width, &height, &wideScreen, mode ) ) { Com_Printf( " invalid mode\n" ); return rserr_invalid_mode; } Com_Printf( " %d %d %s\n", width, height, win_fs[fullscreen] ); // destroy the existing window if( glw_state.hWnd ) { GLimp_Shutdown(); } glState.width = width; glState.height = height; glState.wideScreen = wideScreen; glState.fullScreen = fullscreen; // do a CDS if needed if( fullscreen ) { DEVMODE dm; Com_Printf( "...attempting fullscreen\n" ); memset( &dm, 0, sizeof( dm ) ); dm.dmSize = sizeof( dm ); dm.dmPelsWidth = width; dm.dmPelsHeight = height; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; if( r_colorbits->integer != 0 ) { dm.dmBitsPerPel = r_colorbits->integer; dm.dmFields |= DM_BITSPERPEL; Com_Printf( "...using r_bitdepth of %d\n", dm.dmBitsPerPel ); } else { HDC hdc = GetDC( NULL ); int bitspixel = GetDeviceCaps( hdc, BITSPIXEL ); Com_Printf( "...using desktop display depth of %d\n", bitspixel ); ReleaseDC( 0, hdc ); } if( vid_displayfrequency->integer > 0 ) { dm.dmFields |= DM_DISPLAYFREQUENCY; dm.dmDisplayFrequency = vid_displayfrequency->integer; Com_Printf( "...using display frequency %i\n", dm.dmDisplayFrequency ); } Com_Printf( "...calling CDS: " ); if( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) == DISP_CHANGE_SUCCESSFUL ) { Com_Printf( "ok\n" ); if( !VID_CreateWindow( &glState.width, &glState.height, qtrue ) ) return rserr_invalid_mode; return rserr_ok; } else { Com_Printf( "failed\n" ); Com_Printf( "...calling CDS assuming dual monitors:" ); dm.dmPelsWidth = width * 2; dm.dmPelsHeight = height; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; if( r_colorbits->integer != 0 ) { dm.dmBitsPerPel = r_colorbits->integer; dm.dmFields |= DM_BITSPERPEL; Com_Printf( "...using r_bitdepth of %d\n", dm.dmBitsPerPel ); } if( vid_displayfrequency->integer > 0 ) { dm.dmFields |= DM_DISPLAYFREQUENCY; dm.dmDisplayFrequency = vid_displayfrequency->integer; Com_Printf( "...using display frequency %i\n", dm.dmDisplayFrequency ); } /* ** our first CDS failed, so maybe we're running on some weird dual monitor ** system */ if( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL ) { Com_Printf( " failed\n" ); Com_Printf( "...setting windowed mode\n" ); ChangeDisplaySettings( 0, 0 ); glState.fullScreen = qfalse; if( !VID_CreateWindow( &glState.width, &glState.height, qfalse ) ) return rserr_invalid_mode; return rserr_invalid_fullscreen; } else { Com_Printf( " ok\n" ); if( !VID_CreateWindow( &glState.width, &glState.height, qtrue ) ) return rserr_invalid_mode; return rserr_ok; } } } else { Com_Printf( "...setting windowed mode\n" ); ChangeDisplaySettings( 0, 0 ); if( !VID_CreateWindow( &glState.width, &glState.height, qfalse ) ) return rserr_invalid_mode; } return rserr_ok; }
/* =============== RE_Shutdown =============== */ void RE_Shutdown( qboolean destroyWindow ) { // Com_Printf ("RE_Shutdown( %i )\n", destroyWindow ); Cmd_RemoveCommand ("imagelist"); Cmd_RemoveCommand ("shaderlist"); Cmd_RemoveCommand ("skinlist"); Cmd_RemoveCommand ("fontlist"); Cmd_RemoveCommand ("screenshot"); Cmd_RemoveCommand ("screenshot_tga"); Cmd_RemoveCommand ("gfxinfo"); Cmd_RemoveCommand ("r_atihack"); Cmd_RemoveCommand ("r_we"); Cmd_RemoveCommand ("imagecacheinfo"); Cmd_RemoveCommand ("modellist"); Cmd_RemoveCommand ("modelist"); Cmd_RemoveCommand ("modelcacheinfo"); #ifndef DEDICATED if ( r_DynamicGlow && r_DynamicGlow->integer ) { // Release the Glow Vertex Shader. if ( tr.glowVShader ) { qglDeleteProgramsARB( 1, &tr.glowVShader ); } // Release Pixel Shader. if ( tr.glowPShader ) { if ( qglCombinerParameteriNV ) { // Release the Glow Regcom call list. qglDeleteLists( tr.glowPShader, 1 ); } else if ( qglGenProgramsARB ) { // Release the Glow Fragment Shader. qglDeleteProgramsARB( 1, &tr.glowPShader ); } } // Release the scene glow texture. qglDeleteTextures( 1, &tr.screenGlow ); // Release the scene texture. qglDeleteTextures( 1, &tr.sceneImage ); // Release the blur texture. qglDeleteTextures( 1, &tr.blurImage ); } R_TerrainShutdown(); //rwwRMG - added R_ShutdownFonts(); if ( tr.registered ) { R_SyncRenderThread(); R_ShutdownCommandBuffers(); if (destroyWindow) { R_DeleteTextures(); // only do this for vid_restart now, not during things like map load } } // shut down platform specific OpenGL stuff if ( destroyWindow ) { GLimp_Shutdown(); } #endif //!DEDICATED tr.registered = qfalse; }
/* =================== GLimp_Init This is the platform specific OpenGL initialization function. It is responsible for loading OpenGL, initializing it, 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. If there is any failure, the renderer will revert back to safe parameters and try again. =================== */ bool GLimp_Init( glimpParms_t parms ) { const char* driverName; HDC hDC; cmdSystem->AddCommand( "testSwapBuffers", GLimp_TestSwapBuffers, CMD_FL_SYSTEM, "Times swapbuffer options" ); common->Printf( "Initializing OpenGL subsystem with multisamples:%i stereo:%i fullscreen:%i\n", parms.multiSamples, parms.stereo, parms.fullScreen ); // check our desktop attributes hDC = GetDC( GetDesktopWindow() ); win32.desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL ); win32.desktopWidth = GetDeviceCaps( hDC, HORZRES ); win32.desktopHeight = GetDeviceCaps( hDC, VERTRES ); ReleaseDC( GetDesktopWindow(), hDC ); // we can't run in a window unless it is 32 bpp if( win32.desktopBitsPixel < 32 && parms.fullScreen <= 0 ) { common->Printf( "^3Windowed mode requires 32 bit desktop depth^0\n" ); return false; } // save the hardware gamma so it can be // restored on exit GLimp_SaveGamma(); // create our window classes if we haven't already GLW_CreateWindowClasses(); // this will load the dll and set all our qgl* function pointers, // but doesn't create a window // r_glDriver is only intended for using instrumented OpenGL // dlls. Normal users should never have to use it, and it is // not archived. driverName = r_glDriver.GetString()[0] ? r_glDriver.GetString() : "opengl32"; if( !QGL_Init( driverName ) ) { common->Printf( "^3GLimp_Init() could not load r_glDriver \"%s\"^0\n", driverName ); return false; } // getting the wgl extensions involves creating a fake window to get a context, // which is pretty disgusting, and seems to mess with the AGP VAR allocation GLW_GetWGLExtensionsWithFakeWindow(); // Optionally ChangeDisplaySettings to get a different fullscreen resolution. if( !GLW_ChangeDislaySettingsIfNeeded( parms ) ) { GLimp_Shutdown(); return false; } // try to create a window with the correct pixel format // and init the renderer context if( !GLW_CreateWindow( parms ) ) { GLimp_Shutdown(); return false; } glConfig.isFullscreen = parms.fullScreen; glConfig.isStereoPixelFormat = parms.stereo; glConfig.nativeScreenWidth = parms.width; glConfig.nativeScreenHeight = parms.height; glConfig.multisamples = parms.multiSamples; glConfig.pixelAspect = 1.0f; // FIXME: some monitor modes may be distorted // should side-by-side stereo modes be consider aspect 0.5? // get the screen size, which may not be reliable... // If we use the windowDC, I get my 30" monitor, even though the window is // on a 27" monitor, so get a dedicated DC for the full screen device name. const idStr deviceName = GetDeviceName( Max( 0, parms.fullScreen - 1 ) ); HDC deviceDC = CreateDC( deviceName.c_str(), deviceName.c_str(), NULL, NULL ); const int mmWide = GetDeviceCaps( win32.hDC, HORZSIZE ); DeleteDC( deviceDC ); if( mmWide == 0 ) { glConfig.physicalScreenWidthInCentimeters = 100.0f; } else { glConfig.physicalScreenWidthInCentimeters = 0.1f * mmWide; } // wglSwapinterval, etc GLW_CheckWGLExtensions( win32.hDC ); // check logging GLimp_EnableLogging( ( r_logFile.GetInteger() != 0 ) ); return true; }
/* ** GLimp_SetMode */ rserr_t GLimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen ) { int width, height; const char *win_fs[] = { "W", "FS" }; ri.Con_Printf( PRINT_ALL, "Initializing OpenGL display\n"); ri.Con_Printf (PRINT_ALL, "...setting mode %d:", mode ); if ( !ri.Vid_GetModeInfo( &width, &height, mode ) ) { ri.Con_Printf( PRINT_ALL, " invalid mode\n" ); return rserr_invalid_mode; } ri.Con_Printf( PRINT_ALL, " %d %d %s\n", width, height, win_fs[fullscreen] ); // destroy the existing window if (glw_state.hWnd) { GLimp_Shutdown (); } // do a CDS if needed if ( fullscreen ) { DEVMODE dm; ri.Con_Printf( PRINT_ALL, "...attempting fullscreen\n" ); memset( &dm, 0, sizeof( dm ) ); dm.dmSize = sizeof( dm ); dm.dmPelsWidth = width; dm.dmPelsHeight = height; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; if ( gl_bitdepth->value != 0 ) { dm.dmBitsPerPel = gl_bitdepth->value; dm.dmFields |= DM_BITSPERPEL; ri.Con_Printf( PRINT_ALL, "...using gl_bitdepth of %d\n", ( int ) gl_bitdepth->value ); } else { HDC hdc = GetDC( NULL ); int bitspixel = GetDeviceCaps( hdc, BITSPIXEL ); ri.Con_Printf( PRINT_ALL, "...using desktop display depth of %d\n", bitspixel ); ReleaseDC( 0, hdc ); } ri.Con_Printf( PRINT_ALL, "...calling CDS: " ); if ( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) == DISP_CHANGE_SUCCESSFUL ) { *pwidth = width; *pheight = height; gl_state.fullscreen = true; ri.Con_Printf( PRINT_ALL, "ok\n" ); if ( !VID_CreateWindow (width, height, true) ) return rserr_invalid_mode; return rserr_ok; } else { *pwidth = width; *pheight = height; ri.Con_Printf( PRINT_ALL, "failed\n" ); ri.Con_Printf( PRINT_ALL, "...calling CDS assuming dual monitors:" ); dm.dmPelsWidth = width * 2; dm.dmPelsHeight = height; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; if ( gl_bitdepth->value != 0 ) { dm.dmBitsPerPel = gl_bitdepth->value; dm.dmFields |= DM_BITSPERPEL; } /* ** our first CDS failed, so maybe we're running on some weird dual monitor ** system */ if ( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL ) { ri.Con_Printf( PRINT_ALL, " failed\n" ); ri.Con_Printf( PRINT_ALL, "...setting windowed mode\n" ); ChangeDisplaySettings( 0, 0 ); *pwidth = width; *pheight = height; gl_state.fullscreen = false; if ( !VID_CreateWindow (width, height, false) ) return rserr_invalid_mode; return rserr_invalid_fullscreen; } else { ri.Con_Printf( PRINT_ALL, " ok\n" ); if ( !VID_CreateWindow (width, height, true) ) return rserr_invalid_mode; gl_state.fullscreen = true; return rserr_ok; } } } else { ri.Con_Printf( PRINT_ALL, "...setting windowed mode\n" ); ChangeDisplaySettings( 0, 0 ); *pwidth = width; *pheight = height; gl_state.fullscreen = false; if ( !VID_CreateWindow (width, height, false) ) return rserr_invalid_mode; } return rserr_ok; }
/* =============== RE_Shutdown =============== */ void RE_Shutdown( qboolean destroyWindow ) { ri.Printf( PRINT_ALL, "RE_Shutdown( %i )\n", destroyWindow ); ri.Cmd_RemoveCommand ("modellist"); ri.Cmd_RemoveCommand ("screenshotJPEG"); ri.Cmd_RemoveCommand ("screenshot"); ri.Cmd_RemoveCommand ("imagelist"); ri.Cmd_RemoveCommand ("shaderlist"); ri.Cmd_RemoveCommand ("skinlist"); ri.Cmd_RemoveCommand ("gfxinfo"); ri.Cmd_RemoveCommand ("modelist"); ri.Cmd_RemoveCommand ("shaderstate"); ri.Cmd_RemoveCommand ("r_we"); ri.Cmd_RemoveCommand ("modelcacheinfo"); ri.Cmd_RemoveCommand ("imagecacheinfo"); #ifndef DEDICATED if ( r_DynamicGlow && r_DynamicGlow->integer ) { // Release the Glow Vertex Shader. if ( tr.glowVShader ) { qglDeleteProgramsARB( 1, &tr.glowVShader ); } // Release Pixel Shader. if ( tr.glowPShader ) { if ( qglCombinerParameteriNV ) { // Release the Glow Regcom call list. qglDeleteLists( tr.glowPShader, 1 ); } else if ( qglGenProgramsARB ) { // Release the Glow Fragment Shader. qglDeleteProgramsARB( 1, &tr.glowPShader ); } } // Release the scene glow texture. qglDeleteTextures( 1, &tr.screenGlow ); // Release the scene texture. qglDeleteTextures( 1, &tr.sceneImage ); // Release the blur texture. qglDeleteTextures( 1, &tr.blurImage ); } // gamma correction if (tr.gammaPixelShader) { qglDeleteProgramsARB(1, &tr.gammaPixelShader); } if (tr.gammaVertexShader) { qglDeleteProgramsARB(1, &tr.gammaVertexShader); } if (tr.gammaLUTImage) { qglDeleteTextures(1, &tr.gammaLUTImage); } // -------- R_ShutdownFonts(); if ( tr.registered ) { R_SyncRenderThread(); R_ShutdownCommandBuffers(); if (destroyWindow) { R_DeleteTextures(); // only do this for vid_restart now, not during things like map load } } // shut down platform specific OpenGL stuff if ( destroyWindow ) { GLimp_Shutdown(); } #endif //!DEDICATED tr.registered = qfalse; #ifdef G2_COLLISION_ENABLED if (G2VertSpaceServer) { delete G2VertSpaceServer; G2VertSpaceServer = 0; } #endif }
/* ** GLW_SetMode */ int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) { int attrib[] = { GLX_RGBA, // 0 GLX_RED_SIZE, 4, // 1, 2 GLX_GREEN_SIZE, 4, // 3, 4 GLX_BLUE_SIZE, 4, // 5, 6 GLX_DOUBLEBUFFER, // 7 GLX_DEPTH_SIZE, 1, // 8, 9 GLX_STENCIL_SIZE, 1, // 10, 11 None }; // these match in the array #define ATTR_RED_IDX 2 #define ATTR_GREEN_IDX 4 #define ATTR_BLUE_IDX 6 #define ATTR_DEPTH_IDX 9 #define ATTR_STENCIL_IDX 11 Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; unsigned long mask; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int MajorVersion, MinorVersion; int actualWidth, actualHeight; int i; const char* glstring; // bk001130 - from cvs1.17 (mkv) ri.Printf( PRINT_ALL, "Initializing OpenGL display\n"); 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\n", glConfig.vidWidth, glConfig.vidHeight); if (!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, "Error couldn't open the X display\n"); return RSERR_INVALID_MODE; } scrnum = DefaultScreen(dpy); root = RootWindow(dpy, scrnum); actualWidth = glConfig.vidWidth; actualHeight = glConfig.vidHeight; // Get video mode list MajorVersion = MinorVersion = 0; if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { vidmode_ext = qfalse; } else { ri.Printf(PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion); vidmode_ext = qtrue; } // Check for DGA if (in_dgamouse->value) { if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) { // unable to query, probalby not supported ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" ); ri.Cvar_Set( "in_dgamouse", "0" ); } else { ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n", MajorVersion, MinorVersion); } } if (vidmode_ext) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); // Are we going fullscreen? If so, let's change video mode if (fullscreen) { best_dist = 9999999; best_fit = -1; for (i = 0; i < num_vidmodes; i++) { if (glConfig.vidWidth > vidmodes[i]->hdisplay || glConfig.vidHeight > vidmodes[i]->vdisplay) continue; x = glConfig.vidWidth - vidmodes[i]->hdisplay; y = glConfig.vidHeight - vidmodes[i]->vdisplay; dist = (x * x) + (y * y); if (dist < best_dist) { best_dist = dist; best_fit = i; } } if (best_fit != -1) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); vidmode_active = qtrue; // Move the viewport to top left XF86VidModeSetViewPort(dpy, scrnum, 0, 0); ri.Printf(PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight); } else { fullscreen = 0; ri.Printf(PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n"); } } else { ri.Printf(PRINT_ALL, "XFree86-VidModeExtension: Ignored on non-fullscreen/Voodoo\n"); } } if (!r_colorbits->value) colorbits = 24; else colorbits = r_colorbits->value; if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) colorbits = 16; if (!r_depthbits->value) depthbits = 24; else depthbits = r_depthbits->value; stencilbits = r_stencilbits->value; for (i = 0; i < 16; i++) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ((i % 4) == 0 && i) { // one pass, reduce switch (i / 4) { case 2 : if (colorbits == 24) colorbits = 16; break; case 1 : if (depthbits == 24) depthbits = 16; else if (depthbits == 16) depthbits = 8; case 3 : if (stencilbits == 24) stencilbits = 16; else if (stencilbits == 16) stencilbits = 8; } } tcolorbits = colorbits; tdepthbits = depthbits; tstencilbits = stencilbits; if ((i % 4) == 3) { // reduce colorbits if (tcolorbits == 24) tcolorbits = 16; } if ((i % 4) == 2) { // reduce depthbits if (tdepthbits == 24) tdepthbits = 16; else if (tdepthbits == 16) tdepthbits = 8; } if ((i % 4) == 1) { // reduce stencilbits if (tstencilbits == 24) tstencilbits = 16; else if (tstencilbits == 16) tstencilbits = 8; else tstencilbits = 0; } if (tcolorbits == 24) { attrib[ATTR_RED_IDX] = 8; attrib[ATTR_GREEN_IDX] = 8; attrib[ATTR_BLUE_IDX] = 8; } else { // must be 16 bit attrib[ATTR_RED_IDX] = 4; attrib[ATTR_GREEN_IDX] = 4; attrib[ATTR_BLUE_IDX] = 4; } attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth attrib[ATTR_STENCIL_IDX] = tstencilbits; visinfo = qglXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { continue; } ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if (!visinfo) { ri.Printf( PRINT_ALL, "Couldn't get a visual\n" ); return RSERR_INVALID_MODE; } /* window attributes */ attr.background_pixel = BlackPixel(dpy, scrnum); attr.border_pixel = 0; attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); attr.event_mask = X_MASK; if (vidmode_active) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow(dpy, root, 0, 0, actualWidth, actualHeight, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr); XStoreName( dpy, win, WINDOW_CLASS_NAME ); XMapWindow( dpy, win ); if (vidmode_active) XMoveWindow(dpy, win, 0, 0); XFlush(dpy); XSync(dpy,False); // bk001130 - from cvs1.17 (mkv) ctx = qglXCreateContext(dpy, visinfo, NULL, True); XSync(dpy,False); // bk001130 - from cvs1.17 (mkv) qglXMakeCurrent(dpy, win, ctx); // bk001130 - from cvs1.17 (mkv) glstring = qglGetString (GL_RENDERER); ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring ); // bk010122 - new software token (Indirect) if ( !Q_stricmp( glstring, "Mesa X11") || !Q_stricmp( glstring, "Mesa GLX Indirect") ) { if ( !r_allowSoftwareGL->integer ) { ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" ); ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)! \n" ); ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername ); ri.Printf( PRINT_ALL, " If this is intentional, add\n" ); ri.Printf( PRINT_ALL, " \"+set r_allowSoftwareGL 1\"\n" ); ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" ); ri.Printf( PRINT_ALL, "***********************************************************\n"); GLimp_Shutdown( ); return RSERR_INVALID_MODE; } else { ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" ); } } return RSERR_OK; }
/* ** GLW_SetMode */ int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) { #ifdef HAVE_GLES glConfig.vidWidth = 800; glConfig.vidHeight = 480; // glConfig.windowAspect = 800.0 / 480.0; long event_mask=X_MASK; dpy = XOpenDisplay(0); if(!dpy) { ri.Printf( PRINT_ALL, "couldn't open display\n"); return qfalse; } scrnum = DefaultScreen(dpy); ri.Printf( PRINT_ALL, "using default screen %d\n", scrnum); ri.Printf( PRINT_ALL, "setting up EGL window\n"); XSetWindowAttributes attr = { 0 }; attr.event_mask = event_mask; // attr.colormap = colormap; attr.override_redirect = qtrue; win = XCreateWindow(dpy, RootWindow(dpy, scrnum), 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &attr); if(!win) { return qfalse; } Atom wmState = XInternAtom(dpy, "_NET_WM_STATE", False); Atom wmFullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); XChangeProperty(dpy, win, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); XMapRaised(dpy, win); g_EGLWindow = (NativeWindowType)win; #ifdef PANDORA g_EGLDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); #else g_EGLDisplay = eglGetDisplay((EGLNativeDisplayType)dpy); #endif if(g_EGLDisplay == EGL_NO_DISPLAY) { ri.Printf( PRINT_ALL, "error getting EGL display\n"); return qfalse; } if(!eglInitialize(g_EGLDisplay, NULL, NULL)) { ri.Printf( PRINT_ALL, "error initializing EGL"); return 0; } const EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT, EGL_DEPTH_SIZE, 16, EGL_NONE, 0, }; EGLint configs = 0; eglChooseConfig(g_EGLDisplay, attribs, &g_EGLConfig, 1, &configs); if(!configs) { static const EGLint eglAttrWinLowColor[] = { EGL_NONE }; ri.Printf( PRINT_ALL, "falling back to lowest color config\n"); eglChooseConfig(g_EGLDisplay, eglAttrWinLowColor, &g_EGLConfig, 1, &configs); if(!configs) { ri.Printf( PRINT_ALL, "no valid EGL configs found\n"); return qfalse; } } #ifdef PANDORA g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig, NULL, NULL); #else g_EGLWindowSurface = eglCreateWindowSurface(g_EGLDisplay, g_EGLConfig, g_EGLWindow, NULL); #endif if(g_EGLWindowSurface == EGL_NO_SURFACE) { ri.Printf( PRINT_ALL, "error creating window surface: 0x%X\n", (int)eglGetError()); return qfalse; } EGLint ctxAttr[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; g_EGLContext = eglCreateContext(g_EGLDisplay, g_EGLConfig, EGL_NO_CONTEXT, ctxAttr); if(g_EGLContext == EGL_NO_CONTEXT) { ri.Printf( PRINT_ALL, "error creating context: 0x%X\n", (int)eglGetError()); return qfalse; } eglMakeCurrent(g_EGLDisplay, g_EGLWindowSurface, g_EGLWindowSurface, g_EGLContext); { EGLint width, height, color, depth, stencil; eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_WIDTH, &width); eglQuerySurface(g_EGLDisplay, g_EGLWindowSurface, EGL_HEIGHT, &height); ri.Printf(PRINT_ALL, "Window size: %dx%d\n", width, height); eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_BUFFER_SIZE, &color); eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_DEPTH_SIZE, &depth); eglGetConfigAttrib(g_EGLDisplay, g_EGLConfig, EGL_STENCIL_SIZE, &stencil); /* glConfig.vidWidth = width; glConfig.vidHeight = height;*/ glConfig.colorBits = color; glConfig.depthBits = depth; glConfig.stencilBits = stencil; } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); #else int attrib[] = { GLX_RGBA, // 0 GLX_RED_SIZE, 4, // 1, 2 GLX_GREEN_SIZE, 4, // 3, 4 GLX_BLUE_SIZE, 4, // 5, 6 GLX_DOUBLEBUFFER, // 7 GLX_DEPTH_SIZE, 1, // 8, 9 GLX_STENCIL_SIZE, 1, // 10, 11 None }; // these match in the array #define ATTR_RED_IDX 2 #define ATTR_GREEN_IDX 4 #define ATTR_BLUE_IDX 6 #define ATTR_DEPTH_IDX 9 #define ATTR_STENCIL_IDX 11 Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; unsigned long mask; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int dga_MajorVersion, dga_MinorVersion; int actualWidth, actualHeight; int i; const char* glstring; // bk001130 - from cvs1.17 (mkv) ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" ); 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\n", glConfig.vidWidth, glConfig.vidHeight ); if ( !( dpy = XOpenDisplay( NULL ) ) ) { fprintf( stderr, "Error couldn't open the X display\n" ); return RSERR_INVALID_MODE; } scrnum = DefaultScreen( dpy ); root = RootWindow( dpy, scrnum ); actualWidth = glConfig.vidWidth; actualHeight = glConfig.vidHeight; // Get video mode list if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) ) { vidmode_ext = qfalse; } else { ri.Printf( PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n", vidmode_MajorVersion, vidmode_MinorVersion ); vidmode_ext = qtrue; } // Check for DGA dga_MajorVersion = 0, dga_MinorVersion = 0; if ( in_dgamouse->value ) { if ( !XF86DGAQueryVersion( dpy, &dga_MajorVersion, &dga_MinorVersion ) ) { // unable to query, probalby not supported ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" ); ri.Cvar_Set( "in_dgamouse", "0" ); } else { ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n", dga_MajorVersion, dga_MinorVersion ); } } if ( vidmode_ext ) { int best_fit, best_dist, dist, x, y; XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes ); // Are we going fullscreen? If so, let's change video mode if ( fullscreen ) { best_dist = 9999999; best_fit = -1; for ( i = 0; i < num_vidmodes; i++ ) { if ( glConfig.vidWidth > vidmodes[i]->hdisplay || glConfig.vidHeight > vidmodes[i]->vdisplay ) { continue; } x = glConfig.vidWidth - vidmodes[i]->hdisplay; y = glConfig.vidHeight - vidmodes[i]->vdisplay; dist = ( x * x ) + ( y * y ); if ( dist < best_dist ) { best_dist = dist; best_fit = i; } } if ( best_fit != -1 ) { actualWidth = vidmodes[best_fit]->hdisplay; actualHeight = vidmodes[best_fit]->vdisplay; // change to the mode XF86VidModeSwitchToMode( dpy, scrnum, vidmodes[best_fit] ); vidmode_active = qtrue; // Move the viewport to top left XF86VidModeSetViewPort( dpy, scrnum, 0, 0 ); ri.Printf( PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight ); } else { fullscreen = 0; ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n" ); } } else { ri.Printf( PRINT_ALL, "XFree86-VidModeExtension: Ignored on non-fullscreen/Voodoo\n" ); } } if ( !r_colorbits->value ) { colorbits = 24; } else { colorbits = r_colorbits->value; } if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) { colorbits = 16; } if ( !r_depthbits->value ) { depthbits = 24; } else { depthbits = r_depthbits->value; } stencilbits = r_stencilbits->value; for ( i = 0; i < 16; i++ ) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ( ( i % 4 ) == 0 && i ) { // one pass, reduce switch ( i / 4 ) { case 2: if ( colorbits == 24 ) { colorbits = 16; } break; case 1: if ( depthbits == 24 ) { depthbits = 16; } else if ( depthbits == 16 ) { depthbits = 8; } case 3: if ( stencilbits == 24 ) { stencilbits = 16; } else if ( stencilbits == 16 ) { stencilbits = 8; } } } tcolorbits = colorbits; tdepthbits = depthbits; tstencilbits = stencilbits; if ( ( i % 4 ) == 3 ) { // reduce colorbits if ( tcolorbits == 24 ) { tcolorbits = 16; } } if ( ( i % 4 ) == 2 ) { // reduce depthbits if ( tdepthbits == 24 ) { tdepthbits = 16; } else if ( tdepthbits == 16 ) { tdepthbits = 8; } } if ( ( i % 4 ) == 1 ) { // reduce stencilbits if ( tstencilbits == 24 ) { tstencilbits = 16; } else if ( tstencilbits == 16 ) { tstencilbits = 8; } else { tstencilbits = 0; } } if ( tcolorbits == 24 ) { attrib[ATTR_RED_IDX] = 8; attrib[ATTR_GREEN_IDX] = 8; attrib[ATTR_BLUE_IDX] = 8; } else { // must be 16 bit attrib[ATTR_RED_IDX] = 4; attrib[ATTR_GREEN_IDX] = 4; attrib[ATTR_BLUE_IDX] = 4; } attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth attrib[ATTR_STENCIL_IDX] = tstencilbits; visinfo = qglXChooseVisual( dpy, scrnum, attrib ); if ( !visinfo ) { continue; } ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX], attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX] ); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if ( !visinfo ) { ri.Printf( PRINT_ALL, "Couldn't get a visual\n" ); return RSERR_INVALID_MODE; } /* window attributes */ attr.background_pixel = BlackPixel( dpy, scrnum ); attr.border_pixel = 0; attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone ); attr.event_mask = X_MASK; if ( vidmode_active ) { mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect; attr.override_redirect = True; attr.backing_store = NotUseful; attr.save_under = False; } else { mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; } win = XCreateWindow( dpy, root, 0, 0, actualWidth, actualHeight, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); XStoreName( dpy, win, WINDOW_CLASS_NAME ); XMapWindow( dpy, win ); if ( vidmode_active ) { XMoveWindow( dpy, win, 0, 0 ); } XFlush( dpy ); XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv) ctx = qglXCreateContext( dpy, visinfo, NULL, True ); XSync( dpy,False ); // bk001130 - from cvs1.17 (mkv) qglXMakeCurrent( dpy, win, ctx ); // bk001130 - from cvs1.17 (mkv) glstring = qglGetString( GL_RENDERER ); ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring ); // bk010122 - new software token (Indirect) if ( !Q_stricmp( glstring, "Mesa X11" ) || !Q_stricmp( glstring, "Mesa GLX Indirect" ) ) { if ( !r_allowSoftwareGL->integer ) { ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" ); ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)! \n" ); ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername ); ri.Printf( PRINT_ALL, " If this is intentional, add\n" ); ri.Printf( PRINT_ALL, " \"+set r_allowSoftwareGL 1\"\n" ); ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" ); ri.Printf( PRINT_ALL, "***********************************************************\n" ); GLimp_Shutdown(); return RSERR_INVALID_MODE; } else { ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" ); } } #endif //HAVE_GLES return RSERR_OK; }
/* ** GLW_SetMode */ static int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen ) { const char* glstring; // bk001130 - from cvs1.17 (mkv) int sdlcolorbits; int colorbits, depthbits, stencilbits; int tcolorbits, tdepthbits, tstencilbits; int i = 0; SDL_Surface *vidscreen = NULL; ri.Printf( PRINT_ALL, "Initializing OpenGL display\n"); 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\n", glConfig.vidWidth, glConfig.vidHeight); Uint32 flags = SDL_OPENGL; if (fullscreen) { flags |= SDL_FULLSCREEN; glConfig.isFullscreen = qtrue; } else glConfig.isFullscreen = qfalse; if (!r_colorbits->value) colorbits = 24; else colorbits = r_colorbits->value; if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) colorbits = 16; if (!r_depthbits->value) depthbits = 24; else depthbits = r_depthbits->value; stencilbits = r_stencilbits->value; for (i = 0; i < 16; i++) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ((i % 4) == 0 && i) { // one pass, reduce switch (i / 4) { case 2 : if (colorbits == 24) colorbits = 16; break; case 1 : if (depthbits == 24) depthbits = 16; else if (depthbits == 16) depthbits = 8; case 3 : if (stencilbits == 24) stencilbits = 16; else if (stencilbits == 16) stencilbits = 8; } } tcolorbits = colorbits; tdepthbits = depthbits; tstencilbits = stencilbits; if ((i % 4) == 3) { // reduce colorbits if (tcolorbits == 24) tcolorbits = 16; } if ((i % 4) == 2) { // reduce depthbits if (tdepthbits == 24) tdepthbits = 16; else if (tdepthbits == 16) tdepthbits = 8; } if ((i % 4) == 1) { // reduce stencilbits if (tstencilbits == 24) tstencilbits = 16; else if (tstencilbits == 16) tstencilbits = 8; else tstencilbits = 0; } sdlcolorbits = 4; if (tcolorbits == 24) sdlcolorbits = 8; SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits ); SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); #if SDL_VERSION_ATLEAST( 1, 2, 10 ) if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer ) ) ri.Printf( PRINT_ALL, "r_swapInterval requires libSDL >= 1.2.10\n" ); #else #warning libSDL >= 1.2.10 required for r_swapInterval support #endif // SDL_GL_SWAP_CONTROL SDL_WM_SetCaption(CLIENT_WINDOW_TITLE, CLIENT_WINDOW_ICON); SDL_ShowCursor(0); SDL_EnableUNICODE(1); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); sdlrepeatenabled = qtrue; if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags))) { fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError()); continue; } opengl_context = GLimp_GetCurrentContext(); ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n", sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; break; } if (!vidscreen) { ri.Printf( PRINT_ALL, "Couldn't get a visual\n" ); return RSERR_INVALID_MODE; } screen = vidscreen; // bk001130 - from cvs1.17 (mkv) glstring = (char *) qglGetString (GL_RENDERER); ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring ); // bk010122 - new software token (Indirect) if ( !Q_stricmp( glstring, "Mesa X11") || !Q_stricmp( glstring, "Mesa GLX Indirect") ) { if ( !r_allowSoftwareGL->integer ) { ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" ); ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)! \n" ); ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername ); ri.Printf( PRINT_ALL, " If this is intentional, add\n" ); ri.Printf( PRINT_ALL, " \"+set r_allowSoftwareGL 1\"\n" ); ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" ); ri.Printf( PRINT_ALL, "***********************************************************\n"); GLimp_Shutdown( ); return RSERR_INVALID_MODE; } else { ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" ); } } return RSERR_OK; }
static void HandleEvents( void ) { int b; int key; XEvent event; qboolean dowarp = qfalse; char *p; int dx, dy; int t; if ( !dpy ) { return; } while ( XPending( dpy ) ) { XNextEvent( dpy, &event ); switch ( event.type ) { case KeyPress: p = XLateKey( &event.xkey, &key ); if ( key ) { Sys_QueEvent( 0, SE_KEY, key, qtrue, 0, NULL ); } if ( p ) { while ( *p ) { Sys_QueEvent( 0, SE_CHAR, *p++, 0, 0, NULL ); } } break; case KeyRelease: // bk001206 - handle key repeat w/o XAutRepatOn/Off // also: not done if console/menu is active. // From Ryan's Fakk2. // see game/q_shared.h, KEYCATCH_* . 0 == in 3d game. if ( cls.keyCatchers == 0 ) { // FIXME: KEYCATCH_NONE if ( repeated_press( &event ) == qtrue ) { continue; } } // if XLateKey( &event.xkey, &key ); Sys_QueEvent( 0, SE_KEY, key, qfalse, 0, NULL ); break; case MotionNotify: if ( mouse_active ) { #ifdef PANDORA //broken on Pandora if (0) { #else if ( dgamouse ) { #endif if ( abs( event.xmotion.x_root ) > 1 ) { mx += event.xmotion.x_root * 2; } else { mx += event.xmotion.x_root; } if ( abs( event.xmotion.y_root ) > 1 ) { my += event.xmotion.y_root * 2; } else { my += event.xmotion.y_root; } t = Sys_Milliseconds(); if ( t - mouseResetTime > MOUSE_RESET_DELAY ) { Sys_QueEvent( t, SE_MOUSE, mx, my, 0, NULL ); } mx = my = 0; } else { // If it's a center motion, we've just returned from our warp if ( event.xmotion.x == glConfig.vidWidth / 2 && event.xmotion.y == glConfig.vidHeight / 2 ) { mwx = glConfig.vidWidth / 2; mwy = glConfig.vidHeight / 2; t = Sys_Milliseconds(); if ( t - mouseResetTime > MOUSE_RESET_DELAY ) { Sys_QueEvent( t, SE_MOUSE, mx, my, 0, NULL ); } mx = my = 0; break; } dx = ( (int)event.xmotion.x - mwx ); dy = ( (int)event.xmotion.y - mwy ); if ( abs( dx ) > 1 ) { mx += dx * 2; } else { mx += dx; } if ( abs( dy ) > 1 ) { my += dy * 2; } else { my += dy; } mwx = event.xmotion.x; mwy = event.xmotion.y; dowarp = qtrue; } } break; case ButtonPress: if ( event.xbutton.button == 4 ) { Sys_QueEvent( 0, SE_KEY, K_MWHEELUP, qtrue, 0, NULL ); } else if ( event.xbutton.button == 5 ) { Sys_QueEvent( 0, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL ); } else { // NOTE TTimo there seems to be a weird mapping for K_MOUSE1 K_MOUSE2 K_MOUSE3 .. b = -1; if ( event.xbutton.button == 1 ) { b = 0; // K_MOUSE1 } else if ( event.xbutton.button == 2 ) { b = 2; // K_MOUSE3 } else if ( event.xbutton.button == 3 ) { b = 1; // K_MOUSE2 } else if ( event.xbutton.button == 6 ) { b = 3; // K_MOUSE4 } else if ( event.xbutton.button == 7 ) { b = 4; // K_MOUSE5 } ; Sys_QueEvent( 0, SE_KEY, K_MOUSE1 + b, qtrue, 0, NULL ); } break; case ButtonRelease: if ( event.xbutton.button == 4 ) { Sys_QueEvent( 0, SE_KEY, K_MWHEELUP, qfalse, 0, NULL ); } else if ( event.xbutton.button == 5 ) { Sys_QueEvent( 0, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL ); } else { b = -1; if ( event.xbutton.button == 1 ) { b = 0; } else if ( event.xbutton.button == 2 ) { b = 2; } else if ( event.xbutton.button == 3 ) { b = 1; } else if ( event.xbutton.button == 6 ) { b = 3; // K_MOUSE4 } else if ( event.xbutton.button == 7 ) { b = 4; // K_MOUSE5 } ; Sys_QueEvent( 0, SE_KEY, K_MOUSE1 + b, qfalse, 0, NULL ); } break; case CreateNotify: win_x = event.xcreatewindow.x; win_y = event.xcreatewindow.y; break; case ConfigureNotify: win_x = event.xconfigure.x; win_y = event.xconfigure.y; break; } } if ( dowarp ) { XWarpPointer( dpy,None,win,0,0,0,0, ( glConfig.vidWidth / 2 ),( glConfig.vidHeight / 2 ) ); } } void IN_ActivateMouse( void ) { if ( !mouse_avail || !dpy || !win ) { return; } if ( !mouse_active ) { install_grabs(); mouse_active = qtrue; } } void IN_DeactivateMouse( void ) { if ( !mouse_avail || !dpy || !win ) { return; } if ( mouse_active ) { uninstall_grabs(); mouse_active = qfalse; } } /*****************************************************************************/ static qboolean signalcaught = qfalse;; void Sys_Exit( int ); // bk010104 - abstraction static void signal_handler( int sig ) { // bk010104 - replace this... (NOTE TTimo huh?) if ( signalcaught ) { printf( "DOUBLE SIGNAL FAULT: Received signal %d, exiting...\n", sig ); Sys_Exit( 1 ); // bk010104 - abstraction } signalcaught = qtrue; printf( "Received signal %d, exiting...\n", sig ); GLimp_Shutdown(); // bk010104 - shouldn't this be CL_Shutdown Sys_Exit( 0 ); // bk010104 - abstraction NOTE TTimo send a 0 to avoid DOUBLE SIGNAL FAULT } static void InitSig( void ) { signal( SIGHUP, signal_handler ); signal( SIGQUIT, signal_handler ); signal( SIGILL, signal_handler ); signal( SIGTRAP, signal_handler ); signal( SIGIOT, signal_handler ); signal( SIGBUS, signal_handler ); signal( SIGFPE, signal_handler ); signal( SIGSEGV, signal_handler ); signal( SIGTERM, signal_handler ); }
static void signal_handler(int sig) { printf("Received signal %d, exiting...\n", sig); GLimp_Shutdown(); _exit(0); }
void GLRB_Shutdown( void ) { GLimp_Shutdown(); glState.initialized = qfalse; }
bool GLimp_SetMode(unsigned *pwidth, unsigned *pheight, int mode, bool fullscreen) { int width, height, colorBits; if (!Vid_GetModeInfo(&width, &height, mode)) { appWPrintf("Invalid mode: %d\n", mode); return false; } appPrintf("Mode %d: %dx%d (%s)\n", mode, width, height, fullscreen ? "fullscreen" : "windowed"); // destroy the existing window if (gl_hWnd) GLimp_Shutdown(false); colorBits = gl_bitdepth->integer; gl_bitdepth->modified = false; // do a CDS if needed if (fullscreen) { DEVMODE dm; memset(&dm, 0, sizeof(dm)); dm.dmSize = sizeof(dm); dm.dmPelsWidth = width; dm.dmPelsHeight = height; dm.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT; if (colorBits) { dm.dmBitsPerPel = colorBits; dm.dmFields |= DM_BITSPERPEL; appPrintf("...using color depth of %d\n", colorBits); } else { HDC hdc = GetDC(NULL); int bitspixel = GetDeviceCaps(hdc, BITSPIXEL); ReleaseDC(0, hdc); appPrintf("...using desktop color depth of %d\n", bitspixel); } MSGLOG(("CDS(%dx%d, FS)\n", dm.dmPelsWidth, dm.dmPelsHeight)); if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { appWPrintf("...fullscreen unavailable in this mode\n"); appPrintf("...setting windowed mode\n"); fullscreen = false; MSGLOG(("CDS(NULL)\n")); ChangeDisplaySettings(NULL, 0); } } else // not fullscreen { appPrintf("...setting windowed mode\n"); MSGLOG(("CDS(NULL)\n")); ChangeDisplaySettings(NULL, 0); } *pwidth = width; *pheight = height; gl_config.fullscreen = fullscreen; gl_hWnd = (HWND) Vid_CreateWindow(width, height, fullscreen); if (!gl_hWnd) return false; if (!GLimp_InitGL()) return false; //?? may try to DestroyWindow(force) + CreateWindow() again // init gamma ReadGamma(); appPrintf("Gamma: %s\n", gammaStored ? "hardware" : "software"); return true; }