Torque3D Documentation / _generateds / x86UNIXOGLVideo.client.cpp

x86UNIXOGLVideo.client.cpp

Engine/source/platformX86UNIX/x86UNIXOGLVideo.client.cpp

More...

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