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