x86UNIXOGLVideo.client.cpp
Engine/source/platformX86UNIX/x86UNIXOGLVideo.client.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23#if 0 24#include "console/console.h" 25#include "platform/event.h" 26#include "platform/gameInterface.h" 27 28#include "platformX86UNIX/platformX86UNIX.h" 29#include "platformX86UNIX/platformGL.h" 30#include "platformX86UNIX/x86UNIXOGLVideo.h" 31#include "platformX86UNIX/x86UNIXState.h" 32 33#include <SDL/SDL.h> 34#include <SDL/SDL_syswm.h> 35#include <SDL/SDL_version.h> 36 37//------------------------------------------------------------------------------ 38bool InitOpenGL() 39{ 40 DisplayDevice::init(); 41 42 // Get the video settings from the prefs: 43 const char* resString = Con::getVariable( "$pref::Video::resolution" ); 44 dStrlen(resString) + 1; 45 char* tempBuf = new char[tempBufLen]; 46 dStrcpy( tempBuf, resString, tempBufLen ); 47 char* temp = dStrtok( tempBuf, " x\0" ); 48 dAtoi( temp ) : 800 ); 49 temp = NULL, " x\0" ); 50 dAtoi( temp ) : 600 ); 51 temp = NULL, "\0" ); 52 dAtoi( temp ) : 16 ); 53 delete [] tempBuf; 54 55 bool fullScreen = Con::getBoolVariable( "$pref::Video::fullScreen" ); 56 57 // the only supported video device in unix is OpenGL 58 if ( !Video::setDevice( "OpenGL", width, height, bpp, fullScreen ) ) 59 { 60 Con::errorf("Unable to create default OpenGL mode: %d %d %d %d", 61 width, height, bpp, fullScreen); 62 63 // if we can't create the default, attempt to create a "safe" window 64 if ( !Video::setDevice( "OpenGL", 640, 480, 16, true ) ) 65 { 66 DisplayErrorAlert("Could not find a compatible OpenGL display " \ 67 "resolution. Please check your driver configuration."); 68 return false; 69 } 70 } 71 72 return true; 73} 74 75//------------------------------------------------------------------------------ 76bool OpenGLDevice::smCanSwitchBitDepth = false; 77 78//------------------------------------------------------------------------------ 79OpenGLDevice::OpenGLDevice() 80{ 81 initDevice(); 82} 83 84//------------------------------------------------------------------------------ 85OpenGLDevice::~OpenGLDevice() 86{ 87} 88 89//------------------------------------------------------------------------------ 90void OpenGLDevice::addResolution(S32 height, bool check) 91{ 92 getDesktopSize(); 93 getDesktopBpp(); 94 95 // don't allow any resolution under this size 96 if (width < 640 || height < 480) 97 return; 98 99 if (check) 100 { 101 // don't allow resolutions that exceed the current desktop size 102 if (width > desktopSize.y) 103 return; 104 } 105 106 if (smCanSwitchBitDepth) 107 { 108 // add both 16 and 32 bit resolutions 109 mResolutionList.push_back(Resolution(width, height, 16)); 110 mResolutionList.push_back(Resolution(width, height, 32)); 111 } 112 else 113 { 114 // add just the desktop resolution 115 mResolutionList.push_back(Resolution(width, height, desktopBpp)); 116 } 117} 118 119//------------------------------------------------------------------------------ 120void OpenGLDevice::initDevice() 121{ 122 mDeviceName = "OpenGL"; 123 mFullScreenOnly = false; 124} 125 126//------------------------------------------------------------------------------ 127void OpenGLDevice::loadResolutions() 128{ 129 mResolutionList.clear(); 130 131 // X cannot switch bit depths on the fly. In case this feature is 132 // implemented someday, calling this function will let you take 133 // advantage of it 134 if (Con::getBoolVariable("$pref::Unix::CanSwitchBitDepth")) 135 smCanSwitchBitDepth = true; 136 137 // add some default resolutions 138 addResolution(640, 480); 139 addResolution(800, 600); 140 addResolution(1024, 768); 141 addResolution(1152, 864); 142 addResolution(1280, 1024); 143 addResolution(1600, 1200); 144 145 // specifying full screen should give us the resolutions that the 146 // X server allows 147 SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN); 148 if (modes && 149 (modes != (SDL_Rect **)-1)) 150 { 151 for (int i) 152 { 153 // do we already have this mode? 154 bool found = false; 155 for (Vector<Resolution>::iterator iter = mResolutionList.begin(); 156 iter != mResolutionList.end(); 157 ++iter) 158 { 159 if (iter->w == modes[i]->h) 160 { 161 found = true; 162 break; 163 } 164 } 165 if (!found) 166 // don't check these resolutions because they should be OK 167 // (and checking might drop resolutions that are higher than the 168 // current desktop bpp) 169 addResolution(modes[i]->h, false); 170 } 171 } 172} 173 174//------------------------------------------------------------------------------ 175bool U32 bpp, bool fullScreen ) 176{ 177 if (!setScreenMode(width, height, bpp, fullScreen)) 178 { 179 Con::printf("Unable to set screen mode."); 180 return false; 181 } 182 183 // Output some driver info to the console 184 const char* vendorString = (const char*) glGetString( GL_VENDOR ); 185 const char* rendererString = (const char*) glGetString( GL_RENDERER ); 186 const char* versionString = (const char*) glGetString( GL_VERSION ); 187 Con::printf( "OpenGL driver information:" ); 188 if ( vendorString ) 189 Con::printf( " Vendor: %s", vendorString ); 190 if ( rendererString ) 191 Con::printf( " Renderer: %s", rendererString ); 192 if ( versionString ) 193 Con::printf( " Version: %s", versionString ); 194 195 GL_EXT_Init(); 196 197 Con::setVariable( "$pref::Video::displayDevice", mDeviceName ); 198 199 // Do this here because we now know about the extensions: 200 if ( gGLState.suppSwapInterval ) 201 setVerticalSync( 202 !Con::getBoolVariable( "$pref::Video::disableVerticalSync" ) ); 203 Con::setBoolVariable("$pref::OpenGL::allowTexGen", true); 204 205 return true; 206} 207 208 209//------------------------------------------------------------------------------ 210void OpenGLDevice::shutdown() 211{ 212 // Shutdown is deferred to Platform::shutdown() 213} 214 215//------------------------------------------------------------------------------ 216static void PrintGLAttributes() 217{ 218 int doubleBuf; 219 int bufferSize, depthSize, stencilSize; 220 int red, green, blue, alpha; 221 int aRed, aGreen, aBlue, aAlpha; 222 223 SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doubleBuf); 224 SDL_GL_GetAttribute(SDL_GL_BUFFER_SIZE, &bufferSize); 225 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depthSize); 226 SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencilSize); 227 SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &red); 228 SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &green); 229 SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blue); 230 SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha); 231 SDL_GL_GetAttribute(SDL_GL_ACCUM_RED_SIZE, &aRed); 232 SDL_GL_GetAttribute(SDL_GL_ACCUM_GREEN_SIZE, &aGreen); 233 SDL_GL_GetAttribute(SDL_GL_ACCUM_BLUE_SIZE, &aBlue); 234 SDL_GL_GetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, &aAlpha); 235 236 Con::printf("OpenGL Attributes:"); 237 Con::printf(" DoubleBuffer: %d", doubleBuf); 238 Con::printf(" BufferSize: %d, DepthSize: %d, StencilSize: %d", 239 bufferSize, depthSize, stencilSize); 240 Con::printf(" Red: %d, Green: %d, Blue: %d, Alpha: %d", 241 red, green, blue, alpha); 242 Con::printf(" Accum Red: %d, Green: %d, Blue: %d, Alpha: %d", 243 aRed, aGreen, aBlue, aAlpha); 244} 245 246//------------------------------------------------------------------------------ 247bool U32 bpp, 248 bool fullScreen, bool forceIt, bool repaint ) 249{ 250 // load resolutions, this is done lazily so that we can check the setting 251 // of smCanSwitchBitDepth, which may be overridden by console 252 if (mResolutionList.size()==0) 253 loadResolutions(); 254 255 if (mResolutionList.size()==0) 256 { 257 Con::printf("No resolutions available!"); 258 return false; 259 } 260 261 if (bpp == 0) 262 { 263 // bpp comes in as "0" when it is set to "Default" 264 bpp = getDesktopBpp(); 265 } 266 267 if (height == 0 || width == 0) 268 { 269 // paranoia check. set it to the default to prevent crashing 270 width = 800; 271 height = 600; 272 } 273 274 getDesktopBpp(); 275 // if we can't switch bit depths and the requested bpp is not equal to 276 // the desktop bpp, set bpp to the desktop bpp 277 if (!smCanSwitchBitDepth && 278 bpp != desktopDepth) 279 { 280 bpp = desktopDepth; 281 } 282 283 bool IsInList = false; 284 285 Resolution NewResolution( width, height, bpp ); 286 287 // See if the desired resolution is in the list 288 if ( mResolutionList.size() ) 289 { 290 for ( int i++ ) 291 { 292 if ( width == mResolutionList[i].w 293 && height == mResolutionList[i].h 294 && bpp == mResolutionList[i].bpp ) 295 { 296 IsInList = true; 297 break; 298 } 299 } 300 301 if ( !IsInList ) 302 { 303 Con::printf( "Selected resolution not available: %d %d %d", 304 width, height, bpp); 305 return false; 306 } 307 } 308 else 309 { 310 AssertFatal( false, "No resolution list found!!" ); 311 } 312 313 // Here if we found a matching resolution in the list 314 315 bool needResurrect = false; 316 if (windowCreated()) 317 { 318 Con::printf( "Killing the texture manager..." ); 319 Game->textureKill(); 320 needResurrect = true; 321 } 322 323 // Set the desired GL Attributes 324 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 325// JMQ: NVIDIA 2802+ doesn't like this setting for stencil size 326// SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); 327 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); 328 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0); 329 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0); 330 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0); 331 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0); 332// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 333// SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); 334// SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); 335// SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); 336 337 U32 flags = SDL_OPENGL; 338 if (fullScreen) 339 flags |= SDL_FULLSCREEN; 340 341 Con::printf( "Setting screen mode to %dx%dx%d (%s)...", width, height, 342 bpp, ( fullScreen ? "fs" : "w" ) ); 343 344 // set the new video mode 345 if (SDL_SetVideoMode(width, height, bpp, flags) == NULL) 346 { 347 Con::printf("Unable to set SDL Video Mode: %s", SDL_GetError()); 348 return false; 349 } 350 351 PrintGLAttributes(); 352 353 // clear screen here to prevent buffer garbage from being displayed when 354 // video mode is switched 355 glClearColor(0.0, 0.0, 0.0, 0.0); 356 glClear(GL_COLOR_BUFFER_BIT); 357 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 358 359 if ( needResurrect ) 360 { 361 // Reload the textures: 362 Con::printf( "Resurrecting the texture manager..." ); 363 Game->textureResurrect(); 364 } 365 366 if ( gGLState.suppSwapInterval ) 367 Con::getBoolVariable( "$pref::Video::disableVerticalSync" ) ); 368 369 // reset the window in platform state 370 SDL_SysWMinfo sysinfo; 371 SDL_VERSION(&sysinfo.version); 372 if (SDL_GetWMInfo(&sysinfo) == 0) 373 { 374 Con::printf("Unable to set SDL Video Mode: %s", SDL_GetError()); 375 return false; 376 } 377 setWindow(sysinfo.info.x11.window); 378 379 // set various other parameters 380 setWindowCreated(true); 381 smCurrentRes = NewResolution; 382 Platform::setWindowSize ( width, height ); 383 smIsFullScreen = fullScreen; 384 Con::setBoolVariable( "$pref::Video::fullScreen", smIsFullScreen ); 385 char tempBuf[15]; 386 dSprintf( tempBuf, sizeof( tempBuf ), "%d %d %d", 387 smCurrentRes.w, smCurrentRes.h, smCurrentRes.bpp ); 388 Con::setVariable( "$pref::Video::resolution", tempBuf ); 389 390 // post a TORQUE_SETVIDEOMODE user event 391 SDL_Event event; 392 event.type = SDL_USEREVENT; 393 event.user.code = TORQUE_SETVIDEOMODE; 394 event.user.data1 = NULL; 395 event.user.data2 = NULL; 396 SDL_PushEvent(&event); 397 398 // reset the caption 399 SDL_WM_SetCaption(NULL); 400 401 // repaint 402 if ( repaint ) 403 Con::evaluate( "resetCanvas();" ); 404 405 return true; 406} 407 408//------------------------------------------------------------------------------ 409void OpenGLDevice::swapBuffers() 410{ 411 SDL_GL_SwapBuffers(); 412} 413 414//------------------------------------------------------------------------------ 415const char* OpenGLDevice::getDriverInfo() 416{ 417 const char* vendorString = (const char*) glGetString( GL_VENDOR ); 418 const char* rendererString = (const char*) glGetString( GL_RENDERER ); 419 const char* versionString = (const char*) glGetString( GL_VERSION ); 420 const char* extensionsString = (const char*) glGetString( GL_EXTENSIONS ); 421 422 dStrlen( vendorString ) : 0 ) 423 + ( rendererString ? dStrlen( rendererString ) : 0 ) 424 + ( versionString ? dStrlen( versionString ) : 0 ) 425 + ( extensionsString ? dStrlen( extensionsString ) : 0 ) 426 + 4; 427 428 char* returnString = Con::getReturnBuffer( bufferLen ); 429 dSprintf( returnString, bufferLen, "%s\t%s\t%s\t%s", 430 ( vendorString ? vendorString : "" ), 431 ( rendererString ? rendererString : "" ), 432 ( versionString ? versionString : "" ), 433 ( extensionsString ? extensionsString : "" ) ); 434 435 return( returnString ); 436} 437 438//------------------------------------------------------------------------------ 439bool F32 &g) 440{ 441 U16 redtable[256]; 442 U16 greentable[256]; 443 U16 bluetable[256]; 444 445 if (SDL_GetGammaRamp(redtable, greentable, bluetable) == -1) 446 { 447 Con::warnf("getGammaCorrection error: %s", SDL_GetError()); 448 return false; 449 } 450 451 F32 csum = 0.0; 452 U32 ccount = 0; 453 454 for (i) 455 { 456 if (i] != 65535) 457 { 458 i/256.0; 459 i]/65535.0; 460 b)); 461 462 csum += c; 463 ++ccount; 464 } 465 } 466 g = csum/ccount; 467 468 return true; 469} 470 471//------------------------------------------------------------------------------ 472bool F32 g) 473{ 474 U16 redtable[256]; 475 U16 greentable[256]; 476 U16 bluetable[256]; 477 478 for (i) 479 redtable[i/256.0f, g) * 65535.0f); 480 U16)); 481 U16)); 482 483 S32 ok = SDL_SetGammaRamp(redtable, greentable, bluetable); 484 if (ok == -1) 485 Con::warnf("Error setting gamma correction: %s", SDL_GetError()); 486 487 return ok != -1; 488} 489 490//------------------------------------------------------------------------------ 491bool OpenGLDevice::setVerticalSync( bool on ) 492{ 493 Con::printf("WARNING: OpenGLDevice::setVerticalSync is unimplemented %s %d\n", __FILE__, __LINE__); 494 return false; 495#if 0 496 if ( !gGLState.suppSwapInterval ) 497 return( false ); 498 499 return( qwglSwapIntervalEXT( on ? 1 : 0 ) ); 500#endif 501} 502 503//------------------------------------------------------------------------------ 504DisplayDevice* OpenGLDevice::create() 505{ 506 return new OpenGLDevice(); 507} 508 509#endif // 0 510