1 // -*- c++ -*- 2 3 /*========================================================================= 4 5 Program: Visualization Toolkit 6 Module: vtkOpenGLExtensionManager.h 7 8 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 9 All rights reserved. 10 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 11 12 This software is distributed WITHOUT ANY WARRANTY; without even 13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 14 PURPOSE. See the above copyright notice for more information. 15 16 Copyright 2003 Sandia Corporation. 17 Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive 18 license for use of this work by or on behalf of the 19 U.S. Government. Redistribution and use in source and binary forms, with 20 or without modification, are permitted provided that this Notice and any 21 statement of authorship are reproduced on all copies. 22 23 =========================================================================*/ 24 25 // .NAME vtkOpenGLExtensionManager - Interface class for querying and using OpenGL extensions. 26 // 27 // .SECTION Description 28 // 29 // vtkOpenGLExtensionManager acts as an interface to OpenGL extensions. It 30 // provides methods to query OpenGL extensions on the current or a given 31 // render window and to load extension function pointers. Currently does 32 // not support GLU extensions since the GLU library is not linked to VTK. 33 // 34 // Before using vtkOpenGLExtensionManager, an OpenGL context must be created. 35 // This is generally done with a vtkRenderWindow. Note that simply creating 36 // the vtkRenderWindow is not sufficient. Usually you have to call Render 37 // before the actual OpenGL context is created. You can specify the 38 // RenderWindow with the SetRenderWindow method. 39 // \code 40 // vtkOpenGLExtensionManager *extensions = vtkOpenGLExtensionManager::New(); 41 // extensions->SetRenderWindow(renwin); 42 // \endcode 43 // If no vtkRenderWindow is specified, the current OpenGL context (if any) 44 // is used. 45 // 46 // Generally speaking, when using OpenGL extensions, you will need an 47 // vtkOpenGLExtensionManager and the prototypes defined in vtkgl.h. 48 // \code 49 #include "vtkRenderingOpenGLModule.h" // For export macro 50 // #include "vtkOpenGLExtensionManager.h" 51 // #include "vtkgl.h" 52 // \endcode 53 // The vtkgl.h include file contains all the constants and function 54 // pointers required for using OpenGL extensions in a portable and 55 // namespace safe way. vtkgl.h is built from parsed glext.h, glxext.h, and 56 // wglext.h files. Snapshots of these files are distributed with VTK, 57 // but you can also set CMake options to use other files. 58 // 59 // To use an OpenGL extension, you first need to make an instance of 60 // vtkOpenGLExtensionManager and give it a vtkRenderWindow. You can then 61 // query the vtkOpenGLExtensionManager to see if the extension is supported 62 // with the ExtensionSupported method. Valid names for extensions are 63 // given in the OpenGL extension registry at 64 // http://www.opengl.org/registry/ . 65 // You can also grep vtkgl.h (which will be in the binary build directory 66 // if VTK is not installed) for appropriate names. There are also 67 // special extensions GL_VERSION_X_X (where X_X is replaced with a major 68 // and minor version, respectively) which contain all the constants and 69 // functions for OpenGL versions for which the gl.h header file is of an 70 // older version than the driver. 71 // 72 // \code 73 // if ( !extensions->ExtensionSupported("GL_VERSION_1_2") 74 // || !extensions->ExtensionSupported("GL_ARB_multitexture") ) { 75 // { 76 // vtkErrorMacro("Required extensions not supported!"); 77 // } 78 // \endcode 79 // 80 // Once you have verified that the extensions you want exist, before you 81 // use them you have to load them with the LoadExtension method. 82 // 83 // \code 84 // extensions->LoadExtension("GL_VERSION_1_2"); 85 // extensions->LoadExtension("GL_ARB_multitexture"); 86 // \endcode 87 // 88 // Alternatively, you can use the LoadSupportedExtension method, which checks 89 // whether the requested extension is supported and, if so, loads it. The 90 // LoadSupportedExtension method will not raise any errors or warnings if it 91 // fails, so it is important for callers to pay attention to the return value. 92 // 93 // \code 94 // if ( extensions->LoadSupportedExtension("GL_VERSION_1_2") 95 // && extensions->LoadSupportedExtension("GL_ARB_multitexture") ) { 96 // { 97 // vtkgl::ActiveTexture(vtkgl::TEXTURE0_ARB); 98 // } 99 // else 100 // { 101 // vtkErrorMacro("Required extensions could not be loaded!"); 102 // } 103 // \endcode 104 // 105 // Once you have queried and loaded all of the extensions you need, you can 106 // delete the vtkOpenGLExtensionManager. To use a constant of an extension, 107 // simply replace the "GL_" prefix with "vtkgl::". Likewise, replace the 108 // "gl" prefix of functions with "vtkgl::". In rare cases, an extension will 109 // add a type. In this case, add vtkgl:: to the type (i.e. vtkgl::GLchar). 110 // 111 // \code 112 // extensions->Delete(); 113 // ... 114 // vtkgl::ActiveTexture(vtkgl::TEXTURE0_ARB); 115 // \endcode 116 // 117 // For wgl extensions, replace the "WGL_" and "wgl" prefixes with 118 // "vtkwgl::". For glX extensions, replace the "GLX_" and "glX" prefixes 119 // with "vtkglX::". 120 // 121 122 #ifndef vtkOpenGLExtensionManager_h 123 #define vtkOpenGLExtensionManager_h 124 125 #include "vtkObject.h" 126 #include "vtkWeakPointer.h" // needed for vtkWeakPointer. 127 #include <string> // needed for std::string 128 129 class vtkRenderWindow; 130 131 //BTX 132 extern "C" { 133 #ifdef _WIN32 134 #include "vtkOpenGL.h" // Needed for WINAPI 135 typedef int (WINAPI *vtkOpenGLExtensionManagerFunctionPointer)(void); 136 #else 137 typedef void (*vtkOpenGLExtensionManagerFunctionPointer)(void); 138 #endif 139 } 140 //ETX 141 142 class VTKRENDERINGOPENGL_EXPORT vtkOpenGLExtensionManager : public vtkObject 143 { 144 public: 145 vtkTypeMacro(vtkOpenGLExtensionManager, vtkObject); 146 static vtkOpenGLExtensionManager *New(); 147 void PrintSelf(ostream &os, vtkIndent indent); 148 149 // Description: 150 // Set/Get the render window to query extensions on. If set to null, 151 // justs queries the current render window. 152 vtkRenderWindow* GetRenderWindow(); 153 virtual void SetRenderWindow(vtkRenderWindow *renwin); 154 155 // Description: 156 // Updates the extensions string. 157 virtual void Update(); 158 159 // Description: 160 // Returns a string listing all available extensions. Call Update first 161 // to validate this string. 162 vtkGetStringMacro(ExtensionsString); 163 164 // Description: 165 // Returns true if the extension is supported, false otherwise. 166 virtual int ExtensionSupported(const char *name); 167 168 //BTX 169 // Description: 170 // Returns a function pointer to the OpenGL extension function with the 171 // given name. Returns NULL if the function could not be retrieved. 172 virtual vtkOpenGLExtensionManagerFunctionPointer GetProcAddress( 173 const char *fname); 174 //ETX 175 176 // Description: 177 // Loads all the functions associated with the given extension into the 178 // appropriate static members of vtkgl. This method emits a warning if the 179 // requested extension is not supported. It emits an error if the extension 180 // does not load successfully. 181 virtual void LoadExtension(const char *name); 182 183 // Description: 184 // Returns true if the extension is supported and loaded successfully, 185 // false otherwise. This method will "fail silently/gracefully" if the 186 // extension is not supported or does not load properly. It emits neither 187 // warnings nor errors. It is up to the caller to determine if the 188 // extension loaded properly by paying attention to the return value. 189 virtual int LoadSupportedExtension(const char *name); 190 191 192 // Description: 193 // Loads all the functions associated with the given core-promoted extension 194 // into the appropriate static members of vtkgl associated with the OpenGL 195 // version that promoted the extension as a core feature. This method emits a 196 // warning if the requested extension is not supported. It emits an error if 197 // the extension does not load successfully. 198 // 199 // For instance, extension GL_ARB_multitexture was promoted as a core 200 // feature into OpenGL 1.3. An implementation that uses this 201 // feature has to (IN THIS ORDER), check if OpenGL 1.3 is supported 202 // with ExtensionSupported("GL_VERSION_1_3"), if true, load the extension 203 // with LoadExtension("GL_VERSION_1_3"). If false, test for the extension 204 // with ExtensionSupported("GL_ARB_multitexture"),if true load the extension 205 // with this method LoadCorePromotedExtension("GL_ARB_multitexture"). 206 // If any of those loading stage succeeded, use vtgl::ActiveTexture() in 207 // any case, NOT vtgl::ActiveTextureARB(). 208 // This method avoids the use of if statements everywhere in implementations 209 // using core-promoted extensions. 210 // Without this method, the implementation code should look like: 211 // \code 212 // int opengl_1_3=extensions->ExtensionSupported("GL_VERSION_1_3"); 213 // if(opengl_1_3) 214 // { 215 // extensions->LoadExtension("GL_VERSION_1_3"); 216 // } 217 // else 218 // { 219 // if(extensions->ExtensionSupported("GL_ARB_multitexture")) 220 // { 221 // extensions->LoadCorePromotedExtension("GL_ARB_multitexture"); 222 // } 223 // else 224 // { 225 // vtkErrorMacro("Required multitexture feature is not supported!"); 226 // } 227 // } 228 // ... 229 // if(opengl_1_3) 230 // { 231 // vtkgl::ActiveTexture(vtkgl::TEXTURE0) 232 // } 233 // else 234 // { 235 // vtkgl::ActiveTextureARB(vtkgl::TEXTURE0_ARB) 236 // } 237 // \endcode 238 // Thanks to this method, the code looks like: 239 // \code 240 // int opengl_1_3=extensions->ExtensionSupported("GL_VERSION_1_3"); 241 // if(opengl_1_3) 242 // { 243 // extensions->LoadExtension("GL_VERSION_1_3"); 244 // } 245 // else 246 // { 247 // if(extensions->ExtensionSupported("GL_ARB_multitexture")) 248 // { 249 // extensions->LoadCorePromotedExtension("GL_ARB_multitexture"); 250 // } 251 // else 252 // { 253 // vtkErrorMacro("Required multitexture feature is not supported!"); 254 // } 255 // } 256 // ... 257 // vtkgl::ActiveTexture(vtkgl::TEXTURE0); 258 // \endcode 259 virtual void LoadCorePromotedExtension(const char *name); 260 261 // Description: 262 // Similar to LoadCorePromotedExtension(). 263 // It loads an EXT extension into the pointers of its ARB equivalent. 264 virtual void LoadAsARBExtension(const char *name); 265 266 // Description: 267 // Return the driver's version parts. This may be used for 268 // fine grained feature testing. GetDriverVersionMajor()269 virtual int GetDriverVersionMajor(){ return this->DriverVersionMajor; } GetDriverVersionMinor()270 virtual int GetDriverVersionMinor(){ return this->DriverVersionMinor; } GetDriverVersionPatch()271 virtual int GetDriverVersionPatch(){ return this->DriverVersionPatch; } 272 273 // Description: 274 // Get GL API version that the driver provides. This is 275 // often different than the GL version that VTK recognizes 276 // so only use this for identifying a specific driver. GetDriverGLVersionMajor()277 virtual int GetDriverGLVersionMajor(){ return this->DriverGLVersionMajor; } GetDriverGLVersionMinor()278 virtual int GetDriverGLVersionMinor(){ return this->DriverGLVersionMinor; } GetDriverGLVersionPatch()279 virtual int GetDriverGLVersionPatch(){ return this->DriverGLVersionPatch; } 280 281 // Description: 282 // Test's for common implementors of rendering drivers. This may be used for 283 // fine grained feature testing. Note: DriverIsMesa succeeds for OS Mesa, 284 // use DriverGLRendererIsOSMessa to differentiate. 285 virtual bool DriverIsATI(); 286 virtual bool DriverIsNvidia(); 287 virtual bool DriverIsIntel(); 288 virtual bool DriverIsMesa(); 289 virtual bool DriverIsMicrosoft(); 290 291 // Description: 292 // Test for a specific driver version. 293 virtual bool DriverVersionIs(int major); 294 virtual bool DriverVersionIs(int major, int minor); 295 virtual bool DriverVersionIs(int major, int minor, int patch); 296 297 // Description: 298 // Test for driver version greater than or equal 299 // to the named version. 300 virtual bool DriverVersionAtLeast(int major); 301 virtual bool DriverVersionAtLeast(int major, int minor); 302 virtual bool DriverVersionAtLeast(int major, int minor, int patch); 303 304 // Description: 305 // Test for the driver's GL version as reported in 306 // its GL_VERSION string. This is intended for driver 307 // identification only, use ExtensionSuppported 308 // to test for VTK support of a specific GL version. 309 virtual bool DriverGLVersionIs(int major, int minor, int patch); 310 virtual bool DriverGLVersionIs(int major, int minor); 311 312 // Description: 313 // Test for a specific renderer. This could be used 314 // in some cases to identify the graphics card or 315 // specific driver. Use HasToken to prevent false 316 // matches eg. avoid GeForce4 matching GeForce400 317 virtual bool DriverGLRendererIs(const char *str); 318 virtual bool DriverGLRendererHas(const char *str); 319 virtual bool DriverGLRendererHasToken(const char *str); 320 321 // Description: 322 // Test for Mesa's offscreen renderer. 323 virtual bool DriverGLRendererIsOSMesa(); 324 325 // Description: 326 // Get the OpenGL version, vendor and renderer strings. These can 327 // be used to idnetify a specific driver. GetDriverGLVendor()328 virtual const char *GetDriverGLVendor(){ return this->DriverGLVendor.c_str(); } GetDriverGLVersion()329 virtual const char *GetDriverGLVersion(){ return this->DriverGLVersion.c_str(); } GetDriverGLRenderer()330 virtual const char *GetDriverGLRenderer(){ return this->DriverGLRenderer.c_str(); } 331 332 // Description: 333 // When set known driver bugs are ignored during driver feature 334 // detection. This is used to evaluate the status of a new driver 335 // release to see if the bugs have been fixed. The function takes 336 // a description argument which, is sent to VTK's warning stream 337 // when the ignore flag is set. This makes the test output searchable 338 // for tests which have problems with certain drivers. The CMakeLists 339 // variable VTK_IGNORE_GLDRIVER_BUGS can be used to set this at 340 // build time. Default OFF. 341 bool GetIgnoreDriverBugs(const char *description); 342 vtkSetMacro(IgnoreDriverBugs, bool); 343 vtkBooleanMacro(IgnoreDriverBugs, bool); 344 345 //BTX 346 protected: 347 vtkOpenGLExtensionManager(); 348 virtual ~vtkOpenGLExtensionManager(); 349 350 int OwnRenderWindow; 351 char *ExtensionsString; 352 353 vtkTimeStamp BuildTime; 354 355 // driver specific info 356 std::string DriverGLVersion; 357 int DriverGLVersionMajor; 358 int DriverGLVersionMinor; 359 int DriverGLVersionPatch; 360 std::string DriverGLVendor; 361 std::string DriverGLRenderer; 362 int DriverVersionMajor; 363 int DriverVersionMinor; 364 int DriverVersionPatch; 365 enum DriverGLVendorIdType 366 { 367 DRIVER_VENDOR_UNKNOWN=0, 368 DRIVER_VENDOR_ATI, 369 DRIVER_VENDOR_NVIDIA, 370 DRIVER_VENDOR_INTEL, 371 DRIVER_VENDOR_MESA, 372 DRIVER_VENDOR_MICROSOFT 373 }; 374 DriverGLVendorIdType DriverGLVendorId; 375 bool IgnoreDriverBugs; 376 377 virtual void InitializeDriverInformation(); 378 379 virtual void ReadOpenGLExtensions(); 380 381 // Description: 382 // Wrap around the generated vtkgl::LoadExtension to deal with OpenGL 1.2 383 // and its optional part GL_ARB_imaging. Also functions like 384 // glBlendEquation() or glBlendColor() are optional in OpenGL 1.2 or 1.3 and 385 // provided by the GL_ARB_imaging but there are core features in OpenGL 1.4. 386 virtual int SafeLoadExtension(const char *name); 387 388 private: 389 vtkOpenGLExtensionManager(const vtkOpenGLExtensionManager&); // Not implemented 390 void operator=(const vtkOpenGLExtensionManager&); // Not implemented 391 392 vtkWeakPointer<vtkRenderWindow> RenderWindow; 393 //ETX 394 }; 395 396 #endif // vtkOpenGLExtensionManager_h 397