osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarth/Capabilities.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #include <osgEarth/Capabilities>
00020 #include <osg/FragmentProgram>
00021 #include <osg/GraphicsContext>
00022 #include <osg/GL>
00023 #include <osg/GLExtensions>
00024 #include <osg/GL2Extensions>
00025 #include <osg/Texture>
00026 #include <osgViewer/Version>
00027 
00028 using namespace osgEarth;
00029 
00030 #define LC "[Capabilities] "
00031 
00032 // ---------------------------------------------------------------------------
00033 // A custom P-Buffer graphics context that we will use to query for OpenGL 
00034 // extension and hardware support. (Adapted from osgconv in OpenSceneGraph)
00035 
00036 struct MyGraphicsContext
00037 {
00038     MyGraphicsContext()
00039     {
00040         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
00041         traits->x = 0;
00042         traits->y = 0;
00043         traits->width = 1;
00044         traits->height = 1;
00045         traits->windowDecoration = false;
00046         traits->doubleBuffer = false;
00047         traits->sharedContext = 0;
00048         traits->pbuffer = false;
00049 
00050         // Intel graphics adapters dont' support pbuffers, and some of their drivers crash when
00051         // you try to create them. So by default we will only use the unmapped/pbuffer method
00052         // upon special request.
00053         if ( getenv( "OSGEARTH_USE_PBUFFER_TEST" ) )
00054         {
00055             traits->pbuffer = true;
00056             OE_INFO << LC << "Activating pbuffer test for graphics capabilities" << std::endl;
00057             _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
00058             if ( !_gc.valid() )
00059                 OE_WARN << LC << "Failed to create pbuffer" << std::endl;
00060         }
00061 
00062         if (!_gc.valid())
00063         {
00064             // fall back on a mapped window
00065             traits->pbuffer = false;
00066             _gc = osg::GraphicsContext::createGraphicsContext(traits.get());
00067         }
00068 
00069         if (_gc.valid()) 
00070         {
00071             _gc->realize();
00072             _gc->makeCurrent();
00073 
00074             if ( traits->pbuffer == false )
00075             {
00076                 OE_DEBUG << LC << "Realized graphics window for OpenGL operations." << std::endl;
00077             }
00078             else
00079             {
00080                 OE_DEBUG << LC << "Realized pbuffer for OpenGL operations." << std::endl;
00081             }
00082         }
00083         else
00084         {
00085             OE_WARN << LC << "Failed to create graphic window too." << std::endl;
00086         }
00087     }
00088 
00089     bool valid() const { return _gc.valid() && _gc->isRealized(); }
00090 
00091     osg::ref_ptr<osg::GraphicsContext> _gc;
00092 };
00093 
00094 // ---------------------------------------------------------------------------
00095 
00096 #define SAYBOOL(X) (X?"yes":"no")
00097 
00098 Capabilities::Capabilities() :
00099 _maxFFPTextureUnits     ( 1 ),
00100 _maxGPUTextureUnits     ( 1 ),
00101 _maxGPUTextureCoordSets ( 1 ),
00102 _maxTextureSize         ( 256 ),
00103 _maxFastTextureSize     ( 256 ),
00104 _maxLights              ( 1 ),
00105 _supportsGLSL           ( false ),
00106 _GLSLversion            ( 1.0f ),
00107 _supportsTextureArrays  ( false ),
00108 _supportsMultiTexture   ( false ),
00109 _supportsStencilWrap    ( true ),
00110 _supportsTwoSidedStencil( false ),
00111 _supportsTexture2DLod   ( false ),
00112 _supportsMipmappedTextureUpdates( false )
00113 {
00114     // little hack to force the osgViewer library to link so we can create a graphics context
00115     osgViewerGetVersion();
00116 
00117     // check the environment in order to disable ATI workarounds
00118     bool enableATIworkarounds = true;
00119     if ( ::getenv( "OSGEARTH_DISABLE_ATI_WORKAROUNDS" ) != 0L )
00120         enableATIworkarounds = false;
00121 
00122     // create a graphics context so we can query OpenGL support:
00123     MyGraphicsContext mgc;
00124 
00125     if ( mgc.valid() )
00126     {
00127         osg::GraphicsContext* gc = mgc._gc.get();
00128         unsigned int id = gc->getState()->getContextID();
00129         const osg::GL2Extensions* GL2 = osg::GL2Extensions::Get( id, true );
00130 
00131         OE_INFO << LC << "Detected hardware capabilities:" << std::endl;
00132 
00133         _vendor = std::string( reinterpret_cast<const char*>(glGetString(GL_VENDOR)) );
00134         OE_INFO << LC << "  Vendor = " << _vendor << std::endl;
00135 
00136         _renderer = std::string( reinterpret_cast<const char*>(glGetString(GL_RENDERER)) );
00137         OE_INFO << LC << "  Renderer = " << _renderer << std::endl;
00138 
00139         _version = std::string( reinterpret_cast<const char*>(glGetString(GL_VERSION)) );
00140         OE_INFO << LC << "  Version = " << _version << std::endl;
00141 
00142         glGetIntegerv( GL_MAX_TEXTURE_UNITS, &_maxFFPTextureUnits );
00143         OE_INFO << LC << "  Max FFP texture units = " << _maxFFPTextureUnits << std::endl;
00144 
00145         glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &_maxGPUTextureUnits );
00146         OE_INFO << LC << "  Max GPU texture units = " << _maxGPUTextureUnits << std::endl;
00147 
00148         glGetIntegerv( GL_MAX_TEXTURE_COORDS_ARB, &_maxGPUTextureCoordSets );
00149         OE_INFO << LC << "  Max GPU texture coordinate sets = " << _maxGPUTextureCoordSets << std::endl;
00150 
00151         // Use the texture-proxy method to determine the maximum texture size 
00152         glGetIntegerv( GL_MAX_TEXTURE_SIZE, &_maxTextureSize );
00153         for( int s = _maxTextureSize; s > 2; s >>= 1 )
00154         {
00155             glTexImage2D( GL_PROXY_TEXTURE_2D, 0, GL_RGBA8, s, s, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0L );
00156             GLint width = 0;
00157             glGetTexLevelParameteriv( GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width );
00158             if ( width == s )
00159             {
00160                 _maxTextureSize = s;
00161                 break;
00162             }
00163         }
00164         OE_INFO << LC << "  Max texture size = " << _maxTextureSize << std::endl;
00165 
00166         glGetIntegerv( GL_MAX_LIGHTS, &_maxLights );
00167         OE_INFO << LC << "  Max lights = " << _maxLights << std::endl;
00168 
00169         _supportsGLSL = GL2->isGlslSupported();
00170         OE_INFO << LC << "  GLSL = " << SAYBOOL(_supportsGLSL) << std::endl;
00171 
00172         if ( _supportsGLSL )
00173         {
00174             _GLSLversion = GL2->getLanguageVersion();
00175             OE_INFO << LC << "  GLSL Version = " << _GLSLversion << std::endl;
00176         }
00177 
00178         _supportsTextureArrays = 
00179             _supportsGLSL &&
00180             osg::getGLVersionNumber() >= 2.0 && // hopefully this will detect Intel cards
00181             osg::isGLExtensionSupported( id, "GL_EXT_texture_array" );
00182         OE_INFO << LC << "  Texture arrays = " << SAYBOOL(_supportsTextureArrays) << std::endl;
00183 
00184         _supportsTexture3D = osg::isGLExtensionSupported( id, "GL_EXT_texture3D" );
00185         OE_INFO << LC << "  3D textures = " << SAYBOOL(_supportsTexture3D) << std::endl;
00186 
00187         _supportsMultiTexture = 
00188             osg::getGLVersionNumber() >= 1.3 ||
00189             osg::isGLExtensionSupported( id, "GL_ARB_multitexture") ||
00190             osg::isGLExtensionSupported( id, "GL_EXT_multitexture" );
00191         OE_INFO << LC << "  Multitexturing = " << SAYBOOL(_supportsMultiTexture) << std::endl;
00192 
00193         _supportsStencilWrap = osg::isGLExtensionSupported( id, "GL_EXT_stencil_wrap" );
00194         OE_INFO << LC << "  Stencil wrapping = " << SAYBOOL(_supportsStencilWrap) << std::endl;
00195 
00196         _supportsTwoSidedStencil = osg::isGLExtensionSupported( id, "GL_EXT_stencil_two_side" );
00197         OE_INFO << LC << "  2-sided stencils = " << SAYBOOL(_supportsTwoSidedStencil) << std::endl;
00198 
00199         //_supportsTexture2DLod = osg::isGLExtensionSupported( id, "GL_ARB_shader_texture_lod" );
00200         //OE_INFO << LC << "  texture2DLod = " << SAYBOOL(_supportsTexture2DLod) << std::endl;
00201 
00202         // ATI workarounds:
00203         bool isATI = _vendor.find("ATI ") == 0;
00204 
00205         _supportsMipmappedTextureUpdates = isATI && enableATIworkarounds ? false : true;
00206         OE_INFO << LC << "  Mipmapped texture updates = " << SAYBOOL(_supportsMipmappedTextureUpdates) << std::endl;
00207 
00208         // Intel workarounds:
00209         bool isIntel = 
00210             _vendor.find("Intel ")   != std::string::npos ||
00211             _vendor.find("Intel(R)") != std::string::npos;
00212         _maxFastTextureSize = isIntel ? std::min(2048, _maxTextureSize) : _maxTextureSize;
00213         OE_INFO << LC << "Max Fast Texture Size = " << _maxFastTextureSize << std::endl;
00214     }
00215 }
00216 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines