1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version.  The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * OpenSceneGraph Public License for more details.
12 */
13 #include <osg/GLExtensions>
14 #include <osg/GL>
15 #include <osg/Notify>
16 #include <osg/Math>
17 #include <osg/buffered_value>
18 #include <osg/os_utils>
19 #include <osg/ApplicationUsage>
20 
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <float.h>
25 
26 #include <string>
27 #include <set>
28 #include <sstream>
29 
30 #if defined(WIN32)
31     #ifndef WIN32_LEAN_AND_MEAN
32         #define WIN32_LEAN_AND_MEAN
33     #endif // WIN32_LEAN_AND_MEAN
34     #ifndef NOMINMAX
35         #define NOMINMAX
36     #endif // NOMINMAX
37     #include <windows.h>
38 #elif defined(__APPLE__)
39     // The NS*Symbol* stuff found in <mach-o/dyld.h> is deprecated.
40     // Since 10.3 (Panther) OS X has provided the dlopen/dlsym/dlclose
41     // family of functions under <dlfcn.h>. Since 10.4 (Tiger), Apple claimed
42     // the dlfcn family was significantly faster than the NS*Symbol* family.
43     // Since 'deprecated' needs to be taken very seriously with the
44     // coming of 10.5 (Leopard), it makes sense to use the dlfcn family when possible.
45     #include <AvailabilityMacros.h>
46     #if !defined(MAC_OS_X_VERSION_10_3) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3)
47         #define USE_APPLE_LEGACY_NSSYMBOL
48         #include <mach-o/dyld.h>
49     #else
50         #include <dlfcn.h>
51     #endif
52 #elif defined(__EMSCRIPTEN__)
53     // Emscripten ships EGL, which we use to get OpenGL function addresses.
54     #include <EGL/egl.h>
55 #else
56     #include <dlfcn.h>
57 #endif
58 
59 using namespace osg;
60 
61 typedef std::set<std::string>  ExtensionSet;
62 static osg::buffered_object<ExtensionSet> s_glExtensionSetList;
63 static osg::buffered_object<std::string> s_glRendererList;
64 static osg::buffered_value<int> s_glInitializedList;
65 
66 static ApplicationUsageProxy GLEXtension_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE, "OSG_GL_EXTENSION_DISABLE <value>", "Use space deliminarted list of GL extensions to disable associated GL extensions");
67 static ApplicationUsageProxy GLEXtension_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE, "OSG_MAX_TEXTURE_SIZE <value>", "Clamp the maximum GL texture size to specified value.");
68 
getGLVersionNumber()69 float osg::getGLVersionNumber()
70 {
71     // needs to be extended to do proper things with subversions like 1.5.1, etc.
72     char *versionstring   = (char*) glGetString( GL_VERSION );
73     if (!versionstring) return 0.0;
74 
75     return (findAsciiToFloat(versionstring));
76 }
77 
isExtensionInExtensionString(const char * extension,const char * extensionString)78 bool osg::isExtensionInExtensionString(const char *extension, const char *extensionString)
79 {
80     const char *startOfWord = extensionString;
81     const char *endOfWord;
82     while ((endOfWord = strchr(startOfWord,' ')) != 0)
83     {
84         if (strncmp(extension, startOfWord, endOfWord - startOfWord) == 0)
85             return true;
86         startOfWord = endOfWord+1;
87     }
88     if (*startOfWord && strcmp(extension, startOfWord) == 0)
89         return true;
90 
91    return false;
92 }
93 
isGLExtensionSupported(unsigned int contextID,const char * extension)94 bool osg::isGLExtensionSupported(unsigned int contextID, const char *extension)
95 {
96     return osg::isGLExtensionOrVersionSupported(contextID, extension, FLT_MAX);
97 }
98 
isGLExtensionSupported(unsigned int contextID,const char * extension1,const char * extension2)99 bool osg::isGLExtensionSupported(unsigned int contextID, const char *extension1, const char *extension2)
100 {
101     return osg::isGLExtensionOrVersionSupported(contextID, extension1, FLT_MAX) ||
102            osg::isGLExtensionOrVersionSupported(contextID, extension2, FLT_MAX);
103 }
104 
isGLExtensionOrVersionSupported(unsigned int contextID,const char * extension,float requiredGLVersion)105 bool osg::isGLExtensionOrVersionSupported(unsigned int contextID, const char *extension, float requiredGLVersion)
106 {
107     ExtensionSet& extensionSet = s_glExtensionSetList[contextID];
108     std::string& rendererString = s_glRendererList[contextID];
109 
110     // first check to see if GL version number of recent enough.
111     bool result = requiredGLVersion <= osg::getGLVersionNumber();
112 
113     if (!result)
114     {
115         // if not already set up, initialize all the per graphic context values.
116         if (!s_glInitializedList[contextID])
117         {
118             s_glInitializedList[contextID] = 1;
119 
120             // set up the renderer
121             const GLubyte* renderer = glGetString(GL_RENDERER);
122             rendererString = renderer ? (const char*)renderer : "";
123 
124             // get the extension list from OpenGL.
125             GLint numExt = 0;
126             #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE)
127             if( osg::getGLVersionNumber() >= 3.0 )
128             {
129                 // OpenGL 3.0 adds the concept of indexed strings and
130                 // deprecates calls to glGetString( GL_EXTENSIONS ), which
131                 // will now generate GL_INVALID_ENUM.
132 
133                 // Get extensions using new indexed string interface.
134 
135                 typedef const GLubyte * GL_APIENTRY MYGLGETSTRINGIPROC( GLenum, GLuint );
136                 MYGLGETSTRINGIPROC* glGetStringi = 0;
137                 setGLExtensionFuncPtr( glGetStringi, "glGetStringi", true);
138 
139                 if( glGetStringi != NULL )
140                 {
141                     #  ifndef GL_NUM_EXTENSIONS
142                     #    define GL_NUM_EXTENSIONS 0x821D
143                     #  endif
144                     glGetIntegerv( GL_NUM_EXTENSIONS, &numExt );
145                     int idx;
146                     for( idx=0; idx<numExt; idx++ )
147                     {
148                         extensionSet.insert( std::string( (char*)( glGetStringi( GL_EXTENSIONS, idx ) ) ) );
149                     }
150                 }
151                 else
152                 {
153                     OSG_WARN << "isGLExtensionOrVersionSupported: Can't obtain glGetStringi function pointer." << std::endl;
154                 }
155             }
156             #endif
157 
158             // No extensions found so far, so try with glGetString
159             if (numExt == 0)
160             {
161                 // Get extensions using GL1/2 interface.
162 
163                 const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
164                 if (extensions==NULL) return false;
165 
166                 // insert the ' ' delimiated extensions words into the extensionSet.
167                 const char *startOfWord = extensions;
168                 const char *endOfWord;
169                 while ((endOfWord = strchr(startOfWord,' '))!=NULL)
170                 {
171                     extensionSet.insert(std::string(startOfWord,endOfWord));
172                     startOfWord = endOfWord+1;
173                 }
174                 if (*startOfWord!=0) extensionSet.insert(std::string(startOfWord));
175             }
176 
177     #if defined(WIN32) && (defined(OSG_GL1_AVAILABLE) || defined(OSG_GL2_AVAILABLE) || defined(OSG_GL3_AVAILABLE))
178 
179             // add WGL extensions to the list
180 
181             typedef const char* WINAPI WGLGETEXTENSIONSSTRINGARB(HDC);
182             WGLGETEXTENSIONSSTRINGARB* wglGetExtensionsStringARB = 0;
183             setGLExtensionFuncPtr(wglGetExtensionsStringARB, "wglGetExtensionsStringARB");
184 
185             typedef const char* WINAPI WGLGETEXTENSIONSSTRINGEXT();
186             WGLGETEXTENSIONSSTRINGEXT* wglGetExtensionsStringEXT = 0;
187             setGLExtensionFuncPtr(wglGetExtensionsStringEXT, "wglGetExtensionsStringEXT");
188 
189             const char* wglextensions = 0;
190 
191             if (wglGetExtensionsStringARB)
192             {
193                 HDC dc = wglGetCurrentDC();
194                 wglextensions = wglGetExtensionsStringARB(dc);
195             }
196             else if (wglGetExtensionsStringEXT)
197             {
198                 wglextensions = wglGetExtensionsStringEXT();
199             }
200 
201             if (wglextensions)
202             {
203                 const char* startOfWord = wglextensions;
204                 const char* endOfWord;
205                 while ((endOfWord = strchr(startOfWord, ' ')))
206                 {
207                     extensionSet.insert(std::string(startOfWord, endOfWord));
208                     startOfWord = endOfWord+1;
209                 }
210                 if (*startOfWord != 0) extensionSet.insert(std::string(startOfWord));
211             }
212 
213     #endif
214 
215             OSG_NOTIFY(INFO)<<"OpenGL extensions supported by installed OpenGL drivers are:"<<std::endl;
216             for(ExtensionSet::iterator itr=extensionSet.begin();
217                 itr!=extensionSet.end();
218                 ++itr)
219             {
220                 OSG_NOTIFY(INFO)<<"    "<<*itr<<std::endl;
221             }
222 
223         }
224 
225         // true if extension found in extensionSet.
226         result = extensionSet.find(extension)!=extensionSet.end();
227     }
228 
229     // now see if extension is in the extension disabled list
230     bool extensionDisabled = false;
231     if (result)
232     {
233 
234         const std::string& disableString = getGLExtensionDisableString();
235         if (!disableString.empty())
236         {
237 
238             std::string::size_type pos=0;
239             while ( pos!=std::string::npos && (pos=disableString.find(extension,pos))!=std::string::npos )
240             {
241                 std::string::size_type previousColon = disableString.find_last_of(':',pos);
242                 std::string::size_type previousSemiColon = disableString.find_last_of(';',pos);
243 
244                 std::string renderer = "";
245                 if (previousColon!=std::string::npos)
246                 {
247                     if (previousSemiColon==std::string::npos) renderer = disableString.substr(0,previousColon);
248                     else if (previousSemiColon<previousColon) renderer = disableString.substr(previousSemiColon+1,previousColon-previousSemiColon-1);
249                 }
250 
251                 if (!renderer.empty())
252                 {
253 
254                     // remove leading spaces if they exist.
255                     std::string::size_type leadingSpaces = renderer.find_first_not_of(' ');
256                     if (leadingSpaces==std::string::npos) renderer = ""; // nothing but spaces
257                     else if (leadingSpaces!=0) renderer.erase(0,leadingSpaces);
258 
259                     // remove trailing spaces if they exist.
260                     std::string::size_type trailingSpaces = renderer.find_last_not_of(' ');
261                     if (trailingSpaces!=std::string::npos) renderer.erase(trailingSpaces+1,std::string::npos);
262 
263                 }
264 
265                 if (renderer.empty())
266                 {
267                     extensionDisabled = true;
268                     break;
269                 }
270 
271                 if (rendererString.find(renderer)!=std::string::npos)
272                 {
273                     extensionDisabled = true;
274                     break;
275 
276                 }
277 
278                 // move the position in the disable string along so that the same extension is found multiple times
279                 ++pos;
280             }
281 
282         }
283     }
284 
285     if (result)
286     {
287         if (!extensionDisabled)
288         {
289             OSG_NOTIFY(INFO)<<"OpenGL extension '"<<extension<<"' is supported."<<std::endl;
290         }
291         else
292         {
293             OSG_NOTIFY(INFO)<<"OpenGL extension '"<<extension<<"' is supported by OpenGL\ndriver but has been disabled by osg::getGLExtensionDisableString()."<<std::endl;
294         }
295     }
296     else
297     {
298         OSG_NOTIFY(INFO)<<"OpenGL extension '"<<extension<<"' is not supported."<<std::endl;
299     }
300 
301 
302     return result && !extensionDisabled;
303 }
304 
setGLExtensionDisableString(const std::string & disableString)305 void osg::setGLExtensionDisableString(const std::string& disableString)
306 {
307     getGLExtensionDisableString() = disableString;
308 }
309 
getGLExtensionDisableString()310 std::string& osg::getGLExtensionDisableString()
311 {
312     static std::string s_GLExtensionDisableString(getEnvVar("OSG_GL_EXTENSION_DISABLE"));
313 
314     return s_GLExtensionDisableString;
315 }
316 
OSG_INIT_SINGLETON_PROXY(GLExtensionDisableStringInitializationProxy,osg::getGLExtensionDisableString ())317 OSG_INIT_SINGLETON_PROXY(GLExtensionDisableStringInitializationProxy, osg::getGLExtensionDisableString())
318 
319 #ifdef OSG_GL_LIBRARY_STATIC
320 
321     #include "GLStaticLibrary.h"
322 
323     void* osg::getGLExtensionFuncPtr(const char *funcName)
324     {
325         return GLStaticLibrary::getProcAddress(funcName);
326     }
327 
328 #else
329 
330     void* osg::getGLExtensionFuncPtr(const char *funcName)
331     {
332         // OSG_NOTICE<<"osg::getGLExtensionFuncPtr("<<funcName<<")"<<std::endl;
333     #if defined(__ANDROID__)
334         #if defined(OSG_GLES1_AVAILABLE)
335             static void *handle = dlopen("libGLESv1_CM.so", RTLD_NOW);
336         #elif defined(OSG_GLES2_AVAILABLE)
337             static void *handle = dlopen("libGLESv2.so", RTLD_NOW);
338         #elif defined(OSG_GL1_AVAILABLE)
339             static void *handle = dlopen("libGL.so", RTLD_NOW);
340         #endif
341         return dlsym(handle, funcName);
342 
343     #elif defined(WIN32)
344 
345         #if defined(OSG_GLES2_AVAILABLE)
346             static HMODULE hmodule = GetModuleHandle(TEXT("libGLESv2.dll"));
347             return convertPointerType<void*, PROC>(GetProcAddress(hmodule, funcName));
348         #elif defined(OSG_GLES1_AVAILABLE)
349             static HMODULE hmodule = GetModuleHandleA(TEXT("libgles_cm.dll"));
350             return convertPointerType<void*, PROC>(GetProcAddress(hmodule, funcName));
351         #else
352             return convertPointerType<void*, PROC>(wglGetProcAddress(funcName));
353         #endif
354 
355     #elif defined(__APPLE__)
356 
357         #if defined(USE_APPLE_LEGACY_NSSYMBOL)
358             std::string temp( "_" );
359             temp += funcName;    // Mac OS X prepends an underscore on function names
360             if ( NSIsSymbolNameDefined( temp.c_str() ) )
361             {
362                 NSSymbol symbol = NSLookupAndBindSymbol( temp.c_str() );
363                 return NSAddressOfSymbol( symbol );
364             } else
365                 return NULL;
366         #else
367             // I am uncertain of the correct and ideal usage of dlsym here.
368             // On the surface, it would seem that the FreeBSD implementation
369             // would be the ideal one to copy, but ELF and Mach-o are different
370             // and Apple's man page says the following about using RTLD_DEFAULT:
371             // "This can be a costly search and should be avoided."
372             // The documentation mentions nothing about passing in 0 so I must
373             // assume the behavior is undefined.
374             // So I could try copying the Sun method which I think all this
375             // actually originated from.
376 
377             // return dlsym( RTLD_DEFAULT, funcName );
378             static void *handle = dlopen((const char *)0L, RTLD_LAZY);
379             return dlsym(handle, funcName);
380         #endif
381 
382     #elif defined (__sun)
383 
384         static void *handle = dlopen((const char *)0L, RTLD_LAZY);
385         return dlsym(handle, funcName);
386 
387     #elif defined (__sgi)
388 
389         static void *handle = dlopen((const char *)0L, RTLD_LAZY);
390         return dlsym(handle, funcName);
391 
392     #elif defined (__FreeBSD__)
393 
394         return dlsym( RTLD_DEFAULT, funcName );
395 
396     #elif defined (__linux__)
397 
398         return dlsym(0, funcName);
399 
400     #elif defined (__QNX__)
401 
402         return dlsym(RTLD_DEFAULT, funcName);
403 
404     #elif defined(__EMSCRIPTEN__)
405         // Use EGL to get OpenGL function address for Emscripten.
406         return convertPointerType<void*, __eglMustCastToProperFunctionPointerType>(eglGetProcAddress(funcName));
407 
408     #else // all other unixes
409 
410         return dlsym(0, funcName);
411 
412     #endif
413     }
414 #endif
415 
416 ///////////////////////////////////////////////////////////////////////////
417 // Static array of percontext osg::GLExtensions instances
418 
419 typedef osg::buffered_object< osg::ref_ptr<GLExtensions> > BufferedExtensions;
420 static BufferedExtensions s_extensions;
421 
Get(unsigned int in_contextID,bool createIfNotInitalized)422 GLExtensions* GLExtensions::Get(unsigned int in_contextID, bool createIfNotInitalized)
423 {
424     if (!s_extensions[in_contextID] && createIfNotInitalized)
425             s_extensions[in_contextID] = new GLExtensions(in_contextID);
426 
427     return s_extensions[in_contextID].get();
428 }
429 
Set(unsigned int in_contextID,GLExtensions * extensions)430 void GLExtensions::Set(unsigned int in_contextID, GLExtensions* extensions)
431 {
432     s_extensions[in_contextID] = extensions;
433 }
434 
435 ///////////////////////////////////////////////////////////////////////////
436 // Extension function pointers for OpenGL v2.x
437 
438 
GLExtensions(unsigned int in_contextID)439 GLExtensions::GLExtensions(unsigned int in_contextID):
440     contextID(in_contextID)
441 {
442     const char* versionString = (const char*) glGetString( GL_VERSION );
443     bool validContext = versionString!=0;
444     if (!validContext)
445     {
446         OSG_NOTIFY(osg::FATAL)<<"Error: OpenGL version test failed, requires valid graphics context."<<std::endl;
447     }
448 
449     glVersion = validContext ? findAsciiToFloat( versionString ) : 0.0f;
450     glslLanguageVersion = 0.0f;
451 
452     bool shadersBuiltIn = OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES;
453 
454     isShaderObjectsSupported = validContext && (shadersBuiltIn || osg::isGLExtensionSupported(contextID,"GL_ARB_shader_objects"));
455     isVertexShaderSupported = validContext && (shadersBuiltIn || osg::isGLExtensionSupported(contextID,"GL_ARB_vertex_shader"));
456     isFragmentShaderSupported = validContext && (shadersBuiltIn || osg::isGLExtensionSupported(contextID,"GL_ARB_fragment_shader"));
457     isLanguage100Supported = validContext && (shadersBuiltIn || osg::isGLExtensionSupported(contextID,"GL_ARB_shading_language_100"));
458     isGeometryShader4Supported = validContext && (osg::isGLExtensionSupported(contextID,"GL_EXT_geometry_shader4") || osg::isGLExtensionSupported(contextID,"GL_ARB_geometry_shader4"));
459     isGpuShader4Supported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_EXT_gpu_shader4", 3.0f);
460     areTessellationShadersSupported = validContext && (osg::isGLExtensionOrVersionSupported(contextID, "GL_ARB_tessellation_shader", 4.0f) || osg::isGLExtensionSupported(contextID,"GL_OES_tessellation_shader"));
461     isUniformBufferObjectSupported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_uniform_buffer_object", 3.1f);
462     isGetProgramBinarySupported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_get_program_binary", 4.1f);
463     isGpuShaderFp64Supported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_gpu_shader_fp64", 4.0f);
464     isShaderAtomicCountersSupported = validContext && osg::isGLExtensionOrVersionSupported(contextID,"GL_ARB_shader_atomic_counters", 4.2f);
465 
466     isRectangleSupported = validContext &&
467                            (OSG_GL3_FEATURES ||
468                            isGLExtensionSupported(contextID,"GL_ARB_texture_rectangle") ||
469                            isGLExtensionSupported(contextID,"GL_EXT_texture_rectangle") ||
470                            isGLExtensionSupported(contextID,"GL_NV_texture_rectangle"));
471 
472     isCubeMapSupported = validContext &&
473                           (OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES ||
474                           isGLExtensionSupported(contextID,"GL_ARB_texture_cube_map") ||
475                           isGLExtensionSupported(contextID,"GL_EXT_texture_cube_map") ||
476                           (glVersion >= 1.3f));
477 
478     isClipControlSupported = validContext &&
479                              (isGLExtensionSupported(contextID,"GL_ARB_clip_control") ||
480                              (glVersion >= 4.5f));
481 
482 
483     isGlslSupported = validContext &&
484                       (( glVersion >= 2.0f ) ||
485                        (isShaderObjectsSupported &&
486                         isVertexShaderSupported &&
487                         isFragmentShaderSupported &&
488                         isLanguage100Supported ));
489 
490     if( isGlslSupported )
491     {
492         // If glGetString raises an error, assume initial release "1.00"
493         while(glGetError() != GL_NO_ERROR) {}        // reset error flag
494 
495         const char* langVerStr = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
496         if( (glGetError() == GL_NO_ERROR) && langVerStr )
497         {
498             glslLanguageVersion = (findAsciiToFloat(langVerStr));
499         }
500         else
501             glslLanguageVersion = 1.0f;
502     }
503 
504     OSG_INFO
505             << "glVersion=" << glVersion << ", "
506             << "isGlslSupported=" << (isGlslSupported ? "YES" : "NO") << ", "
507             << "glslLanguageVersion=" << glslLanguageVersion
508             << std::endl;
509 
510 
511     setGLExtensionFuncPtr(glDrawBuffers, "glDrawBuffers", "glDrawBuffersARB", validContext);
512     setGLExtensionFuncPtr(glAttachShader, "glAttachShader", "glAttachObjectARB", validContext);
513     setGLExtensionFuncPtr(glBindAttribLocation, "glBindAttribLocation", "glBindAttribLocationARB", validContext);
514     setGLExtensionFuncPtr(glCompileShader, "glCompileShader", "glCompileShaderARB", validContext);
515     setGLExtensionFuncPtr(glCreateProgram, "glCreateProgram", "glCreateProgramObjectARB", validContext);
516     setGLExtensionFuncPtr(glCreateShader, "glCreateShader", "glCreateShaderObjectARB", validContext);
517     setGLExtensionFuncPtr(glDeleteProgram, "glDeleteProgram", validContext);
518     setGLExtensionFuncPtr(glDeleteShader, "glDeleteShader", validContext);
519     setGLExtensionFuncPtr(glDetachShader, "glDetachShader", "glDetachObjectARB", validContext);
520     setGLExtensionFuncPtr(glDisableVertexAttribArray, "glDisableVertexAttribArray", validContext);
521     setGLExtensionFuncPtr(glEnableVertexAttribArray, "glEnableVertexAttribArray", validContext);
522     setGLExtensionFuncPtr(glGetActiveAttrib, "glGetActiveAttrib", "glGetActiveAttribARB", validContext);
523     setGLExtensionFuncPtr(glGetActiveUniform, "glGetActiveUniform", "glGetActiveUniformARB", validContext);
524     setGLExtensionFuncPtr(glGetAttachedShaders, "glGetAttachedShaders", "glGetAttachedObjectsARB", validContext);
525     setGLExtensionFuncPtr(glGetAttribLocation, "glGetAttribLocation", "glGetAttribLocationARB", validContext);
526     setGLExtensionFuncPtr(glGetProgramiv, "glGetProgramiv", validContext);
527     setGLExtensionFuncPtr(glGetProgramInfoLog, "glGetProgramInfoLog", validContext);
528     setGLExtensionFuncPtr(glGetShaderiv, "glGetShaderiv", validContext);
529     setGLExtensionFuncPtr(glGetShaderInfoLog, "glGetShaderInfoLog", validContext);
530     setGLExtensionFuncPtr(glGetShaderSource, "glGetShaderSource", "glGetShaderSourceARB", validContext);
531     setGLExtensionFuncPtr(glGetUniformLocation, "glGetUniformLocation", "glGetUniformLocationARB", validContext);
532     setGLExtensionFuncPtr(glGetUniformfv, "glGetUniformfv", "glGetUniformfvARB", validContext);
533     setGLExtensionFuncPtr(glGetUniformiv, "glGetUniformiv", "glGetUniformivARB", validContext);
534     setGLExtensionFuncPtr(glGetVertexAttribdv, "glGetVertexAttribdv", validContext);
535     setGLExtensionFuncPtr(glGetVertexAttribfv, "glGetVertexAttribfv", validContext);
536     setGLExtensionFuncPtr(glGetVertexAttribiv, "glGetVertexAttribiv", validContext);
537     setGLExtensionFuncPtr(glGetVertexAttribPointerv, "glGetVertexAttribPointerv", validContext);
538     setGLExtensionFuncPtr(glIsProgram, "glIsProgram", validContext);
539     setGLExtensionFuncPtr(glIsShader, "glIsShader", validContext);
540     setGLExtensionFuncPtr(glLinkProgram, "glLinkProgram", "glLinkProgramARB", validContext);
541     setGLExtensionFuncPtr(glShaderSource, "glShaderSource", "glShaderSourceARB", validContext);
542     setGLExtensionFuncPtr(glUseProgram, "glUseProgram", "glUseProgramObjectARB", validContext);
543     setGLExtensionFuncPtr(glUniform1f, "glUniform1f", "glUniform1fARB", validContext);
544     setGLExtensionFuncPtr(glUniform2f, "glUniform2f", "glUniform2fARB", validContext);
545     setGLExtensionFuncPtr(glUniform3f, "glUniform3f", "glUniform3fARB", validContext);
546     setGLExtensionFuncPtr(glUniform4f, "glUniform4f", "glUniform4fARB", validContext);
547     setGLExtensionFuncPtr(glUniform1i, "glUniform1i", "glUniform1iARB", validContext);
548     setGLExtensionFuncPtr(glUniform2i, "glUniform2i", "glUniform2iARB", validContext);
549     setGLExtensionFuncPtr(glUniform3i, "glUniform3i", "glUniform3iARB", validContext);
550     setGLExtensionFuncPtr(glUniform4i, "glUniform4i", "glUniform4iARB", validContext);
551     setGLExtensionFuncPtr(glUniform1fv, "glUniform1fv", "glUniform1fvARB", validContext);
552     setGLExtensionFuncPtr(glUniform2fv, "glUniform2fv", "glUniform2fvARB", validContext);
553     setGLExtensionFuncPtr(glUniform3fv, "glUniform3fv", "glUniform3fvARB", validContext);
554     setGLExtensionFuncPtr(glUniform4fv, "glUniform4fv", "glUniform4fvARB", validContext);
555     setGLExtensionFuncPtr(glUniform1iv, "glUniform1iv", "glUniform1ivARB", validContext);
556     setGLExtensionFuncPtr(glUniform2iv, "glUniform2iv", "glUniform2ivARB", validContext);
557     setGLExtensionFuncPtr(glUniform3iv, "glUniform3iv", "glUniform3ivARB", validContext);
558     setGLExtensionFuncPtr(glUniform4iv, "glUniform4iv", "glUniform4ivARB", validContext);
559     setGLExtensionFuncPtr(glUniformMatrix2fv, "glUniformMatrix2fv", "glUniformMatrix2fvARB", validContext);
560     setGLExtensionFuncPtr(glUniformMatrix3fv, "glUniformMatrix3fv", "glUniformMatrix3fvARB", validContext);
561     setGLExtensionFuncPtr(glUniformMatrix4fv, "glUniformMatrix4fv", "glUniformMatrix4fvARB", validContext);
562     setGLExtensionFuncPtr(glValidateProgram, "glValidateProgram", "glValidateProgramARB", validContext);
563 
564     setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d", "glVertexAttrib1dARB", validContext);
565     setGLExtensionFuncPtr(glVertexAttrib1dv, "glVertexAttrib1dv", validContext);
566     setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f", "glVertexAttrib1fARB", validContext);
567     setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv", "glVertexAttrib1fvARB", validContext);
568     setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s", "glVertexAttrib1sARB", validContext);
569     setGLExtensionFuncPtr(glVertexAttrib1sv, "glVertexAttrib1sv", validContext);
570     setGLExtensionFuncPtr(glVertexAttrib2d, "glVertexAttrib2d", validContext);
571     setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv", "glVertexAttrib2dvARB", validContext);
572     setGLExtensionFuncPtr(glVertexAttrib2f, "glVertexAttrib2f", validContext);
573     setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv", "glVertexAttrib2fvARB", validContext);
574     setGLExtensionFuncPtr(glVertexAttrib2s, "glVertexAttrib2s", validContext);
575     setGLExtensionFuncPtr(glVertexAttrib2sv, "glVertexAttrib2sv", validContext);
576     setGLExtensionFuncPtr(glVertexAttrib3d, "glVertexAttrib3d", validContext);
577     setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv", "glVertexAttrib3dvARB", validContext);
578     setGLExtensionFuncPtr(glVertexAttrib3f, "glVertexAttrib3f", validContext);
579     setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv", "glVertexAttrib3fvARB", validContext);
580     setGLExtensionFuncPtr(glVertexAttrib3s, "glVertexAttrib3s", validContext);
581     setGLExtensionFuncPtr(glVertexAttrib3sv, "glVertexAttrib3sv", validContext);
582     setGLExtensionFuncPtr(glVertexAttrib4Nbv, "glVertexAttrib4Nbv", validContext);
583     setGLExtensionFuncPtr(glVertexAttrib4Niv, "glVertexAttrib4Niv", validContext);
584     setGLExtensionFuncPtr(glVertexAttrib4Nsv, "glVertexAttrib4Nsv", validContext);
585     setGLExtensionFuncPtr(glVertexAttrib4Nub, "glVertexAttrib4Nub", validContext);
586     setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv", "glVertexAttrib4NubvARB", validContext);
587     setGLExtensionFuncPtr(glVertexAttrib4Nuiv, "glVertexAttrib4Nuiv", validContext);
588     setGLExtensionFuncPtr(glVertexAttrib4Nusv, "glVertexAttrib4Nusv", validContext);
589     setGLExtensionFuncPtr(glVertexAttrib4bv, "glVertexAttrib4bv", validContext);
590     setGLExtensionFuncPtr(glVertexAttrib4d, "glVertexAttrib4d", validContext);
591     setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv", "glVertexAttrib4dvARB", validContext);
592     setGLExtensionFuncPtr(glVertexAttrib4f, "glVertexAttrib4f", validContext);
593     setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv", "glVertexAttrib4fvARB", validContext);
594     setGLExtensionFuncPtr(glVertexAttrib4iv, "glVertexAttrib4iv", validContext);
595     setGLExtensionFuncPtr(glVertexAttrib4s, "glVertexAttrib4s", validContext);
596     setGLExtensionFuncPtr(glVertexAttrib4sv, "glVertexAttrib4sv", validContext);
597     setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv", "glVertexAttrib4ubvARB", validContext);
598     setGLExtensionFuncPtr(glVertexAttrib4uiv, "glVertexAttrib4uiv", validContext);
599     setGLExtensionFuncPtr(glVertexAttrib4usv, "glVertexAttrib4usv", validContext);
600 
601     setGLExtensionFuncPtr(glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB", validContext);
602     setGLExtensionFuncPtr(glVertexAttribIPointer, "glVertexAttribIPointer","glVertexAttribIPointerARB", validContext);
603     setGLExtensionFuncPtr(glVertexAttribLPointer, "glVertexAttribLPointer","glVertexAttribLPointerARB", validContext);
604     setGLExtensionFuncPtr(glVertexAttribDivisor, "glVertexAttribDivisor", validContext);
605 
606     // v1.5-only ARB entry points, in case they're needed for fallback
607     setGLExtensionFuncPtr(glGetInfoLogARB, "glGetInfoLogARB", validContext);
608     setGLExtensionFuncPtr(glGetObjectParameterivARB, "glGetObjectParameterivARB", validContext);
609     setGLExtensionFuncPtr(glDeleteObjectARB, "glDeleteObjectARB", validContext);
610     setGLExtensionFuncPtr(glGetHandleARB, "glGetHandleARB", validContext);
611 
612     // GL 2.1
613     setGLExtensionFuncPtr(glUniformMatrix2x3fv, "glUniformMatrix2x3fv", validContext);
614     setGLExtensionFuncPtr(glUniformMatrix3x2fv, "glUniformMatrix3x2fv", validContext);
615     setGLExtensionFuncPtr(glUniformMatrix2x4fv, "glUniformMatrix2x4fv", validContext);
616     setGLExtensionFuncPtr(glUniformMatrix4x2fv, "glUniformMatrix4x2fv", validContext);
617     setGLExtensionFuncPtr(glUniformMatrix3x4fv, "glUniformMatrix3x4fv", validContext);
618     setGLExtensionFuncPtr(glUniformMatrix4x3fv, "glUniformMatrix4x3fv", validContext);
619 
620     // ARB_clip_control
621     setGLExtensionFuncPtr(glClipControl, "glClipControl", validContext);
622 
623     // EXT_geometry_shader4
624     setGLExtensionFuncPtr(glProgramParameteri,  "glProgramParameteri", "glProgramParameteriEXT", validContext);
625 
626     // ARB_tesselation_shader
627     setGLExtensionFuncPtr(glPatchParameteri, "glPatchParameteri", validContext);
628     setGLExtensionFuncPtr(glPatchParameterfv, "glPatchParameterfv", validContext);
629 
630     // EXT_gpu_shader4
631     setGLExtensionFuncPtr(glGetUniformuiv,  "glGetUniformuiv", "glGetUniformuivEXT", validContext);
632     setGLExtensionFuncPtr(glBindFragDataLocation,  "glBindFragDataLocation", "glBindFragDataLocationEXT", validContext);
633     setGLExtensionFuncPtr(glBindFragDataLocationIndexed,  "glBindFragDataLocationIndexed", "glBindFragDataLocationIndexedEXT", validContext);
634     setGLExtensionFuncPtr(glGetFragDataIndex,  "glGetFragDataIndex", "glGetFragDataIndexEXT", validContext);
635     setGLExtensionFuncPtr(glGetFragDataLocation,  "glGetFragDataLocation", "glGetFragDataLocationEXT", validContext);
636     setGLExtensionFuncPtr(glUniform1ui,  "glUniform1ui", "glUniform1uiEXT", validContext);
637     setGLExtensionFuncPtr(glUniform2ui,  "glUniform2ui", "glUniform2uiEXT", validContext);
638     setGLExtensionFuncPtr(glUniform3ui,  "glUniform3ui", "glUniform3uiEXT", validContext);
639     setGLExtensionFuncPtr(glUniform4ui,  "glUniform4ui", "glUniform4uiEXT", validContext);
640     setGLExtensionFuncPtr(glUniform1uiv,  "glUniform1uiv", "glUniform1uivEXT", validContext);
641     setGLExtensionFuncPtr(glUniform2uiv,  "glUniform2uiv", "glUniform2uivEXT", validContext);
642     setGLExtensionFuncPtr(glUniform3uiv,  "glUniform3uiv", "glUniform3uivEXT", validContext);
643     setGLExtensionFuncPtr(glUniform4uiv,  "glUniform4uiv", "glUniform4uivEXT", validContext);
644 
645     // ARB_gpu_shader_int64
646     setGLExtensionFuncPtr(glUniform1i64,  "glUniform1i64",  "glUniform1i64ARB",  validContext);
647     setGLExtensionFuncPtr(glUniform1ui64, "glUniform1ui64", "glUniform1ui64ARB", validContext);
648     setGLExtensionFuncPtr(glUniform2i64,  "glUniform2i64",  "glUniform2i64ARB",  validContext);
649     setGLExtensionFuncPtr(glUniform2ui64, "glUniform2ui64", "glUniform2ui64ARB", validContext);
650     setGLExtensionFuncPtr(glUniform3i64,  "glUniform3i64",  "glUniform3i64ARB",  validContext);
651     setGLExtensionFuncPtr(glUniform3ui64, "glUniform3ui64", "glUniform3ui64ARB", validContext);
652     setGLExtensionFuncPtr(glUniform4i64,  "glUniform4i64",  "glUniform4i64ARB",  validContext);
653     setGLExtensionFuncPtr(glUniform4ui64, "glUniform4ui64", "glUniform4ui64ARB", validContext);
654     setGLExtensionFuncPtr(glUniform1i64v, "glUniform1i64v", "glUniform1i64vARB", validContext);
655     setGLExtensionFuncPtr(glUniform1ui64v,"glUniform1ui64v","glUniform1ui64vARB",validContext);
656     setGLExtensionFuncPtr(glUniform2i64v, "glUniform2i64v", "glUniform2i64vARB", validContext);
657     setGLExtensionFuncPtr(glUniform2ui64v,"glUniform2ui64v","glUniform2ui64vARB",validContext);
658     setGLExtensionFuncPtr(glUniform3i64v, "glUniform3i64v", "glUniform3i64vARB", validContext);
659     setGLExtensionFuncPtr(glUniform3ui64v,"glUniform3ui64v","glUniform3ui64vARB",validContext);
660     setGLExtensionFuncPtr(glUniform4i64v, "glUniform4i64v", "glUniform4i64vARB", validContext);
661     setGLExtensionFuncPtr(glUniform4ui64v,"glUniform4ui64v","glUniform4ui64vARB",validContext);
662 
663     // ARB_uniform_buffer_object
664     setGLExtensionFuncPtr(glGetUniformIndices, "glGetUniformIndices", validContext);
665     setGLExtensionFuncPtr(glGetActiveUniformsiv, "glGetActiveUniformsiv", validContext);
666     setGLExtensionFuncPtr(glGetActiveUniformName, "glGetActiveUniformName", validContext);
667     setGLExtensionFuncPtr(glGetUniformBlockIndex, "glGetUniformBlockIndex", validContext);
668     setGLExtensionFuncPtr(glGetActiveUniformBlockiv, "glGetActiveUniformBlockiv", validContext);
669     setGLExtensionFuncPtr(glGetActiveUniformBlockName, "glGetActiveUniformBlockName", validContext);
670     setGLExtensionFuncPtr(glUniformBlockBinding, "glUniformBlockBinding", validContext);
671 
672     // ARB_get_program_binary
673     setGLExtensionFuncPtr(glGetProgramBinary, "glGetProgramBinary", validContext);
674     setGLExtensionFuncPtr(glProgramBinary, "glProgramBinary", validContext);
675 
676     // ARB_gpu_shader_fp64
677     setGLExtensionFuncPtr(glUniform1d, "glUniform1d" , validContext);
678     setGLExtensionFuncPtr(glUniform2d, "glUniform2d" , validContext);
679     setGLExtensionFuncPtr(glUniform3d, "glUniform3d" , validContext);
680     setGLExtensionFuncPtr(glUniform4d, "glUniform4d" , validContext);
681     setGLExtensionFuncPtr(glUniform1dv, "glUniform1dv" , validContext);
682     setGLExtensionFuncPtr(glUniform2dv, "glUniform2dv" , validContext);
683     setGLExtensionFuncPtr(glUniform3dv, "glUniform3dv" , validContext);
684     setGLExtensionFuncPtr(glUniform4dv, "glUniform4dv" , validContext);
685     setGLExtensionFuncPtr(glUniformMatrix2dv, "glUniformMatrix2dv" , validContext);
686     setGLExtensionFuncPtr(glUniformMatrix3dv, "glUniformMatrix3dv" , validContext);
687     setGLExtensionFuncPtr(glUniformMatrix4dv, "glUniformMatrix4dv" , validContext);
688     setGLExtensionFuncPtr(glUniformMatrix2x3dv,  "glUniformMatrix2x3dv" , validContext);
689     setGLExtensionFuncPtr(glUniformMatrix3x2dv,  "glUniformMatrix3x2dv" , validContext);
690     setGLExtensionFuncPtr(glUniformMatrix2x4dv,  "glUniformMatrix2x4dv" , validContext);
691     setGLExtensionFuncPtr(glUniformMatrix4x2dv,  "glUniformMatrix4x2dv" , validContext);
692     setGLExtensionFuncPtr(glUniformMatrix3x4dv,  "glUniformMatrix3x4dv" , validContext);
693     setGLExtensionFuncPtr(glUniformMatrix4x3dv,  "glUniformMatrix4x3dv" , validContext);
694 
695     // ARB_shader_atomic_counters
696     setGLExtensionFuncPtr(glGetActiveAtomicCounterBufferiv,  "glGetActiveAtomicCounterBufferiv" , validContext);
697 
698     // ARB_compute_shader
699     setGLExtensionFuncPtr(glDispatchCompute,  "glDispatchCompute" , validContext);
700 
701 
702     setGLExtensionFuncPtr(glMemoryBarrier,  "glMemoryBarrier", "glMemoryBarrierEXT" , validContext);
703 
704     // BufferObject extensions
705     setGLExtensionFuncPtr(glGenBuffers, "glGenBuffers","glGenBuffersARB", validContext);
706     setGLExtensionFuncPtr(glBindBuffer, "glBindBuffer","glBindBufferARB", validContext);
707     setGLExtensionFuncPtr(glBufferData, "glBufferData","glBufferDataARB", validContext);
708     setGLExtensionFuncPtr(glBufferSubData, "glBufferSubData","glBufferSubDataARB", validContext);
709     setGLExtensionFuncPtr(glDeleteBuffers, "glDeleteBuffers","glDeleteBuffersARB", validContext);
710     setGLExtensionFuncPtr(glIsBuffer, "glIsBuffer","glIsBufferARB", validContext);
711     setGLExtensionFuncPtr(glGetBufferSubData, "glGetBufferSubData","glGetBufferSubDataARB", validContext);
712     setGLExtensionFuncPtr(glBufferStorage, "glBufferStorage","glBufferStorageARB", validContext);
713     setGLExtensionFuncPtr(glNamedBufferStorage, "glNamedBufferStorage","glNamedBufferStorageARB", validContext);
714     setGLExtensionFuncPtr(glMapBuffer, "glMapBuffer","glMapBufferARB", validContext);
715     setGLExtensionFuncPtr(glMapBufferRange,  "glMapBufferRange", "glMapBufferRangeARB" , validContext);
716     setGLExtensionFuncPtr(glUnmapBuffer, "glUnmapBuffer","glUnmapBufferARB", validContext);
717     setGLExtensionFuncPtr(glGetBufferParameteriv, "glGetBufferParameteriv","glGetBufferParameterivARB", validContext);
718     setGLExtensionFuncPtr(glGetBufferPointerv, "glGetBufferPointerv","glGetBufferPointervARB", validContext);
719     setGLExtensionFuncPtr(glBindBufferRange, "glBindBufferRange", validContext);
720     setGLExtensionFuncPtr(glBindBufferBase,  "glBindBufferBase", "glBindBufferBaseEXT", "glBindBufferBaseNV" , validContext);
721     setGLExtensionFuncPtr(glTexBuffer, "glTexBuffer","glTexBufferARB" , validContext);
722 
723     isVBOSupported = validContext && (OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_vertex_buffer_object"));
724     isPBOSupported = validContext && ((OSG_GLES3_FEATURES && glVersion >= 3.0) || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_pixel_buffer_object"));
725     isTBOSupported = validContext && osg::isGLExtensionSupported(contextID,"GL_ARB_texture_buffer_object");
726     isVAOSupported = validContext && ((OSG_GLES3_FEATURES && glVersion >= 3.0) || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID, "GL_ARB_vertex_array_object", "GL_OES_vertex_array_object"));
727     isTransformFeedbackSupported = validContext && osg::isGLExtensionSupported(contextID, "GL_ARB_transform_feedback2");
728     isBufferObjectSupported = isVBOSupported || isPBOSupported;
729 
730 
731     // BlendFunc extensions
732     isBlendFuncSeparateSupported = validContext &&
733                                     (OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES ||
734                                     osg::isGLExtensionSupported(contextID, "GL_EXT_blend_func_separate") ||
735                                     (glVersion >= 1.4f));
736 
737     setGLExtensionFuncPtr(glBlendFuncSeparate, "glBlendFuncSeparate", "glBlendFuncSeparateEXT", validContext);
738 
739     setGLExtensionFuncPtr(glBlendFunci, "glBlendFunci", "glBlendFunciARB", validContext);
740     setGLExtensionFuncPtr(glBlendFuncSeparatei, "glBlendFuncSeparatei", "glBlendFuncSeparateiARB", validContext);
741 
742 
743     isSecondaryColorSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_secondary_color");
744     isFogCoordSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_fog_coord");
745     isMultiTexSupported = validContext && isGLExtensionSupported(contextID,"GL_ARB_multitexture");
746     isOcclusionQuerySupported = validContext && osg::isGLExtensionSupported(contextID, "GL_NV_occlusion_query");
747     isARBOcclusionQuerySupported = validContext && (OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID, "GL_ARB_occlusion_query"));
748 
749     isTimerQuerySupported = validContext && osg::isGLExtensionSupported(contextID, "GL_EXT_timer_query");
750     isARBTimerQuerySupported = validContext && osg::isGLExtensionSupported(contextID, "GL_ARB_timer_query");
751 
752 
753     setGLExtensionFuncPtr(glDrawArraysInstanced, "glDrawArraysInstanced","glDrawArraysInstancedARB","glDrawArraysInstancedEXT", validContext);
754     setGLExtensionFuncPtr(glDrawElementsInstanced, "glDrawElementsInstanced","glDrawElementsInstancedARB","glDrawElementsInstancedEXT", validContext);
755 
756 
757     setGLExtensionFuncPtr(glFogCoordfv, "glFogCoordfv","glFogCoordfvEXT", validContext);
758     setGLExtensionFuncPtr(glSecondaryColor3ubv, "glSecondaryColor3ubv","glSecondaryColor3ubvEXT", validContext);
759     setGLExtensionFuncPtr(glSecondaryColor3fv, "glSecondaryColor3fv","glSecondaryColor3fvEXT", validContext);
760 
761     setGLExtensionFuncPtr(glMultiTexCoord1f, "glMultiTexCoord1f","glMultiTexCoord1fARB", validContext);
762     setGLExtensionFuncPtr(glMultiTexCoord4f, "glMultiTexCoord4f","glMultiTexCoord4fARB", validContext);
763 
764     setGLExtensionFuncPtr(glMultiTexCoord1fv, "glMultiTexCoord1fv","glMultiTexCoord1fvARB", validContext);
765     setGLExtensionFuncPtr(glMultiTexCoord2fv, "glMultiTexCoord2fv","glMultiTexCoord2fvARB", validContext);
766     setGLExtensionFuncPtr(glMultiTexCoord3fv, "glMultiTexCoord3fv","glMultiTexCoord3fvARB", validContext);
767     setGLExtensionFuncPtr(glMultiTexCoord4fv, "glMultiTexCoord4fv","glMultiTexCoord4fvARB", validContext);
768 
769 
770     setGLExtensionFuncPtr(glMultiTexCoord1d, "glMultiTexCoord1d","glMultiTexCoord1dARB", validContext);
771     setGLExtensionFuncPtr(glMultiTexCoord1dv, "glMultiTexCoord1dv","glMultiTexCoord1dvARB", validContext);
772     setGLExtensionFuncPtr(glMultiTexCoord2dv, "glMultiTexCoord2dv","glMultiTexCoord2dvARB", validContext);
773     setGLExtensionFuncPtr(glMultiTexCoord3dv, "glMultiTexCoord3dv","glMultiTexCoord3dvARB", validContext);
774     setGLExtensionFuncPtr(glMultiTexCoord4dv, "glMultiTexCoord4dv","glMultiTexCoord4dvARB", validContext);
775 
776     setGLExtensionFuncPtr(glGenOcclusionQueries, "glGenOcclusionQueries","glGenOcclusionQueriesNV", validContext);
777     setGLExtensionFuncPtr(glDeleteOcclusionQueries, "glDeleteOcclusionQueries","glDeleteOcclusionQueriesNV", validContext);
778     setGLExtensionFuncPtr(glIsOcclusionQuery, "glIsOcclusionQuery","glIsOcclusionQueryNV", validContext);
779     setGLExtensionFuncPtr(glBeginOcclusionQuery, "glBeginOcclusionQuery","glBeginOcclusionQueryNV", validContext);
780     setGLExtensionFuncPtr(glEndOcclusionQuery, "glEndOcclusionQuery","glEndOcclusionQueryNV", validContext);
781     setGLExtensionFuncPtr(glGetOcclusionQueryiv, "glGetOcclusionQueryiv","glGetOcclusionQueryivNV", validContext);
782     setGLExtensionFuncPtr(glGetOcclusionQueryuiv, "glGetOcclusionQueryuiv","glGetOcclusionQueryuivNV", validContext);
783 
784     setGLExtensionFuncPtr(glGenQueries, "glGenQueries", "glGenQueriesARB", validContext);
785     setGLExtensionFuncPtr(glDeleteQueries, "glDeleteQueries", "glDeleteQueriesARB", validContext);
786     setGLExtensionFuncPtr(glIsQuery, "glIsQuery", "glIsQueryARB", validContext);
787     setGLExtensionFuncPtr(glBeginQuery, "glBeginQuery", "glBeginQueryARB", validContext);
788     setGLExtensionFuncPtr(glEndQuery, "glEndQuery", "glEndQueryARB", validContext);
789     setGLExtensionFuncPtr(glBeginQueryIndexed, "glBeginQueryIndexed", "glBeginQueryIndexedARB", validContext);
790     setGLExtensionFuncPtr(glEndQueryIndexed, "glEndQueryIndexed", "glEndQueryIndexedARB", validContext);
791     setGLExtensionFuncPtr(glGetQueryiv, "glGetQueryiv", "glGetQueryivARB", validContext);
792     setGLExtensionFuncPtr(glGetQueryObjectiv, "glGetQueryObjectiv","glGetQueryObjectivARB", validContext);
793     setGLExtensionFuncPtr(glGetQueryObjectuiv, "glGetQueryObjectuiv","glGetQueryObjectuivARB", validContext);
794     setGLExtensionFuncPtr(glGetQueryObjectui64v, "glGetQueryObjectui64v","glGetQueryObjectui64vEXT", validContext);
795     setGLExtensionFuncPtr(glQueryCounter, "glQueryCounter", validContext);
796     setGLExtensionFuncPtr(glGetInteger64v, "glGetInteger64v", validContext);
797 
798 
799     // SampleMaski functionality
800     isTextureMultisampleSupported = validContext && isGLExtensionSupported(contextID, "GL_ARB_texture_multisample");
801     isOpenGL32upported = (glVersion >= 3.2f);
802 
803     // function pointers
804     setGLExtensionFuncPtr(glSampleMaski, "glSampleMaski", validContext);
805     isSampleMaskiSupported = validContext && (isOpenGL32upported || isGLExtensionSupported(contextID,"ARB_texture_multisample"));
806 
807 
808     // old styple Vertex/Fragment Programs
809     isVertexProgramSupported = validContext && isGLExtensionSupported(contextID,"GL_ARB_vertex_program");
810     isFragmentProgramSupported = validContext && isGLExtensionSupported(contextID,"GL_ARB_fragment_program");
811 
812     setGLExtensionFuncPtr(glBindProgram,"glBindProgramARB", validContext);
813     setGLExtensionFuncPtr(glGenPrograms, "glGenProgramsARB", validContext);
814     setGLExtensionFuncPtr(glDeletePrograms, "glDeleteProgramsARB", validContext);
815     setGLExtensionFuncPtr(glProgramString, "glProgramStringARB", validContext);
816     setGLExtensionFuncPtr(glProgramLocalParameter4fv, "glProgramLocalParameter4fvARB", validContext);
817 
818     // Sample Extensions (OpenGL>=3.3)
819     setGLExtensionFuncPtr(glSamplerParameteri, "glSamplerParameteri", "glSamplerParameteriARB", validContext);
820     setGLExtensionFuncPtr(glSamplerParameterf, "glSamplerParameterf", "glSamplerParameterfARB", validContext);
821     setGLExtensionFuncPtr(glSamplerParameteriv, "glSamplerParameteriv", "glSamplerParameterivARB", validContext);
822     setGLExtensionFuncPtr(glSamplerParameterfv, "glSamplerParameterfv", "glSamplerParameterfvARB", validContext);
823     setGLExtensionFuncPtr(glSamplerParameterIiv, "glSamplerParameterIiv", "glSamplerParameterIivARB", validContext);
824     setGLExtensionFuncPtr(glSamplerParameterIuiv, "glSamplerParameterIuiv", "glSamplerParameterIuivARB", validContext);
825 
826     setGLExtensionFuncPtr(glGetSamplerParameteriv, "glGetSamplerParameteriv", "glGetSamplerParameterivARB", validContext);
827     setGLExtensionFuncPtr(glGetSamplerParameterfv, "glGetSamplerParameterfv", "glGetSamplerParameterfvARB", validContext);
828     setGLExtensionFuncPtr(glGetSamplerParameterIiv, "glGetSamplerParameterIiv", "glGetSamplerParameterIivARB", validContext);
829     setGLExtensionFuncPtr(glGetSamplerParameterIuiv, "glGetSamplerParameterIuiv", "glGetSamplerParameterIuivARB", validContext);
830 
831     setGLExtensionFuncPtr(glGenSamplers, "glGenSamplers", "glGenSamplersARB", validContext);
832     setGLExtensionFuncPtr(glDeleteSamplers, "glDeleteSamplers", "glDeleteSamplersARB", validContext);
833     setGLExtensionFuncPtr(glBindSampler, "glBindSampler", "glBindSamplerARB", validContext);
834     setGLExtensionFuncPtr(glIsSampler, "glIsSampler", "glIsSamplerARB", validContext);
835 
836     // Texture extensions
837     const char* renderer = validContext ? (const char*) glGetString(GL_RENDERER) : 0;
838     std::string rendererString(renderer ? renderer : "");
839 
840     bool radeonHardwareDetected = (rendererString.find("Radeon")!=std::string::npos || rendererString.find("RADEON")!=std::string::npos);
841     bool fireGLHardwareDetected = (rendererString.find("FireGL")!=std::string::npos || rendererString.find("FIREGL")!=std::string::npos);
842 
843     bool builtInSupport = OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES;
844 
845     isMultiTexturingSupported = validContext &&
846                                 (builtInSupport || OSG_GLES1_FEATURES ||
847                                  isGLExtensionOrVersionSupported( contextID,"GL_ARB_multitexture", 1.3f) ||
848                                  isGLExtensionOrVersionSupported(contextID,"GL_EXT_multitexture", 1.3f));
849 
850     isTextureFilterAnisotropicSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_texture_filter_anisotropic");
851     isTextureSwizzleSupported = validContext && isGLExtensionSupported(contextID,"GL_ARB_texture_swizzle");
852     isTextureCompressionARBSupported = validContext && (builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_compression", 1.3f));
853     isTextureCompressionS3TCSupported = validContext && (isGLExtensionSupported(contextID,"GL_EXT_texture_compression_s3tc") || isGLExtensionSupported(contextID, "GL_S3_s3tc"));
854     isTextureCompressionPVRTC2BPPSupported = validContext && isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc");
855     isTextureCompressionPVRTC4BPPSupported = isTextureCompressionPVRTC2BPPSupported;//covered by same extension
856     isTextureCompressionETCSupported = validContext && isGLExtensionSupported(contextID,"GL_OES_compressed_ETC1_RGB8_texture");
857     isTextureCompressionETC2Supported = validContext && isGLExtensionSupported(contextID,"GL_ARB_ES3_compatibility");
858     isTextureCompressionRGTCSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_texture_compression_rgtc");
859     isTextureCompressionPVRTCSupported = validContext && isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc");
860 
861     isTextureMirroredRepeatSupported = validContext &&
862                                        (builtInSupport ||
863                                         isGLExtensionOrVersionSupported(contextID,"GL_IBM_texture_mirrored_repeat", 1.4f) ||
864                                         isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_mirrored_repeat", 1.4f));
865 
866     isTextureEdgeClampSupported = validContext &&
867                                   (builtInSupport ||
868                                    isGLExtensionOrVersionSupported(contextID,"GL_EXT_texture_edge_clamp", 1.2f) ||
869                                    isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2f));
870 
871 
872     isTextureBorderClampSupported = validContext &&
873                                     (OSG_GL3_FEATURES ||
874                                      ((OSG_GL1_FEATURES || OSG_GL2_FEATURES) && isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f)) ||
875                                      ((OSG_GLES2_FEATURES || OSG_GLES3_FEATURES) && isGLExtensionSupported(contextID,"GL_EXT_texture_border_clamp")));
876 
877     isGenerateMipMapSupported = validContext && (builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f));
878     preferGenerateMipmapSGISForPowerOfTwo = (radeonHardwareDetected||fireGLHardwareDetected) ? false : true;
879     isTextureMultisampledSupported = validContext && (isGLExtensionSupported(contextID,"GL_ARB_texture_multisample"));
880     isShadowSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_shadow"));
881     isShadowAmbientSupported = validContext && (isGLExtensionSupported(contextID,"GL_ARB_shadow_ambient"));
882     isClientStorageSupported = validContext && (isGLExtensionSupported(contextID,"GL_APPLE_client_storage"));
883     isNonPowerOfTwoTextureMipMappedSupported = validContext && (builtInSupport || isGLExtensionSupported(contextID, "GL_OES_texture_npot") || isGLExtensionOrVersionSupported(contextID, "GL_ARB_texture_non_power_of_two", 2.0));
884     isNonPowerOfTwoTextureNonMipMappedSupported = validContext && (isNonPowerOfTwoTextureMipMappedSupported || isGLExtensionSupported(contextID, "GL_APPLE_texture_2D_limited_npot"));
885     isTextureIntegerEXTSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_EXT_texture_integer"));
886 
887     if (rendererString.find("GeForce FX")!=std::string::npos)
888     {
889         isNonPowerOfTwoTextureMipMappedSupported = false;
890         OSG_INFO<<"Disabling _isNonPowerOfTwoTextureMipMappedSupported for GeForce FX hardware."<<std::endl;
891     }
892 
893     maxTextureSize=0;
894     if (validContext) glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxTextureSize);
895 
896     GLint osg_max_size = maxTextureSize;
897     if( (getEnvVar("OSG_MAX_TEXTURE_SIZE", osg_max_size)) && osg_max_size<maxTextureSize)
898     {
899         maxTextureSize = osg_max_size;
900     }
901     isTextureMaxLevelSupported = (glVersion >= 1.2f);
902 
903     isTextureStorageEnabled = validContext && ((glVersion >= 4.2f) || isGLExtensionSupported(contextID, "GL_ARB_texture_storage"));
904 
905     if (isTextureStorageEnabled)
906     {
907         std::string value;
908         if (getEnvVar("OSG_GL_TEXTURE_STORAGE", value))
909         {
910             if (value=="OFF" || value=="DISABLE") isTextureStorageEnabled = false;
911             else isTextureStorageEnabled = true;
912         }
913     }
914 
915     setGLExtensionFuncPtr(glTexStorage1D,"glTexStorage1D","glTexStorage1DARB", validContext);
916     setGLExtensionFuncPtr(glTextureStorage1D,"glTextureStorage1D","glTextureStorage1DARB", validContext);
917     setGLExtensionFuncPtr(glTexStorage2D,"glTexStorage2D","glTexStorage2DARB", validContext);
918     setGLExtensionFuncPtr(glTextureStorage2D,"glTextureStorage2D","glTextureStorage2DARB", validContext);
919     setGLExtensionFuncPtr(glTexStorage3D, "glTexStorage3D","glTexStorage3DEXT", validContext);
920     setGLExtensionFuncPtr(glTextureStorage3D, "glTextureStorage3D","glTextureStorage3DEXT", validContext);
921     setGLExtensionFuncPtr(glTexStorage2DMultisample, "glTextureStorage2DMultisample","glTextureStorage2DMultisampleEXT", validContext);
922     setGLExtensionFuncPtr(glTexStorage3DMultisample, "glTextureStorage3DMultisample","glTextureStorage3DMultisampleEXT", validContext);
923     setGLExtensionFuncPtr(glTextureView, "glTextureView","glTextureViewEXT", validContext);
924 
925     setGLExtensionFuncPtr(glCompressedTexImage2D,"glCompressedTexImage2D","glCompressedTexImage2DARB", validContext);
926     setGLExtensionFuncPtr(glCompressedTexSubImage2D,"glCompressedTexSubImage2D","glCompressedTexSubImage2DARB", validContext);
927     setGLExtensionFuncPtr(glGetCompressedTexImage,"glGetCompressedTexImage","glGetCompressedTexImageARB", validContext);;
928     setGLExtensionFuncPtr(glTexImage2DMultisample, "glTexImage2DMultisample", "glTexImage2DMultisampleARB", validContext);
929 
930     setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB", "glTexParameterIivEXT", validContext);
931     setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB", "glTexParameterIuivEXT", validContext);
932 
933     setGLExtensionFuncPtr(glBindImageTexture, "glBindImageTexture", "glBindImageTextureARB", validContext);
934 
935 
936     // Texture3D extensions
937     isTexture3DFast = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D"));
938 
939     if (isTexture3DFast) isTexture3DSupported = true;
940     else isTexture3DSupported = validContext && (glVersion >= 1.2f);
941 
942     maxTexture3DSize = 0;
943     if (validContext) glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxTexture3DSize);
944 
945     setGLExtensionFuncPtr(glTexImage3D, "glTexImage3D","glTexImage3DEXT", validContext);
946     setGLExtensionFuncPtr(glTexSubImage3D, "glTexSubImage3D","glTexSubImage3DEXT", validContext);
947 
948     setGLExtensionFuncPtr(glCompressedTexImage3D, "glCompressedTexImage3D","glCompressedTexImage3DARB", validContext);
949     setGLExtensionFuncPtr(glCompressedTexSubImage3D, "glCompressedTexSubImage3D","glCompressedTexSubImage3DARB", validContext);
950 
951     setGLExtensionFuncPtr(glTexImage3DMultisample, "glTexImage3DMultisample", validContext);
952     setGLExtensionFuncPtr(glGetMultisamplefv, "glGetMultisamplefv", validContext);
953 
954     setGLExtensionFuncPtr(glCopyTexSubImage3D, "glCopyTexSubImage3D","glCopyTexSubImage3DEXT", validContext);
955     setGLExtensionFuncPtr(glBeginConditionalRender, "glBeginConditionalRender", "glBeginConditionalRenderARB");
956     setGLExtensionFuncPtr(glEndConditionalRender, "glEndConditionalRender", "glEndConditionalRenderARB");
957 
958     // Texture2DArray extensions
959     isTexture2DArraySupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture_array"));
960 
961     max2DSize = 0;
962     if (validContext) glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
963     maxLayerCount = 0;
964     if (validContext) glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxLayerCount);
965 
966     // ARB_bindless_texture
967     setGLExtensionFuncPtr(glGetTextureHandle,             "glGetTextureHandle", "glGetTextureHandleARB","glGetTextureHandleNV", validContext);
968     setGLExtensionFuncPtr(glGetTextureSamplerHandle,      "glGetTextureSamplerHandle","glGetTextureSamplerHandleARB", "glGetTextureSamplerHandleNV", validContext);
969     setGLExtensionFuncPtr(glMakeTextureHandleResident,    "glMakeTextureHandleResident", "glMakeTextureHandleResidentARB","glMakeTextureHandleResidentNV", validContext);
970     setGLExtensionFuncPtr(glMakeTextureHandleNonResident, "glMakeTextureHandleNonResident", "glMakeTextureHandleNonResidentARB", "glMakeTextureHandleNonResidentNV",validContext);
971     setGLExtensionFuncPtr(glIsTextureHandleResident,      "glIsTextureHandleResident","glIsTextureHandleResidentARB", "glIsTextureHandleResidentNV", validContext);
972     setGLExtensionFuncPtr(glGetImageHandle,      "glGetImageHandle","glGetImageHandleARB", "glGetImageHandleNV", validContext);
973     setGLExtensionFuncPtr(glMakeImageHandleResident,      "glMakeImageHandleResident","glMakeImageHandleResidentARB", "glMakeImageHandleResidentNV", validContext);
974     setGLExtensionFuncPtr(glMakeImageHandleNonResident,      "glMakeImageHandleNonResident","glMakeImageHandleNonResidentARB", "glMakeImageHandleNonResidentNV", validContext);
975     setGLExtensionFuncPtr(glIsImageHandleResident,      "glIsImageHandleResident","glIsImageHandleResidentARB", "glIsImageHandleResidentNV", validContext);
976     setGLExtensionFuncPtr(glUniformHandleui64,            "glUniformHandleui64", "glUniformHandleui64ARB","glUniformHandleui64NV", validContext);
977     setGLExtensionFuncPtr(glUniformHandleuiv64,      "glUniformHandleuiv64","glUniformHandleuiv64ARB", "glUniformHandleuiv64NV", validContext);
978     setGLExtensionFuncPtr(glProgramUniformHandleui64,      "glProgramUniformHandleui64","glProgramUniformHandleui64ARB", "glProgramUniformHandleui64NV", validContext);
979     setGLExtensionFuncPtr(glProgramUniformHandleuiv64,      "glProgramUniformHandleuiv64","glProgramUniformHandleuiv64ARB", "glProgramUniformHandleuiv64NV", validContext);
980 
981 
982     // Blending
983     isBlendColorSupported = validContext &&
984                             (OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES ||
985                              isGLExtensionSupported(contextID,"GL_EXT_blend_color") ||
986                              (glVersion >= 1.2f));
987 
988     setGLExtensionFuncPtr(glBlendColor, "glBlendColor", "glBlendColorEXT", validContext);
989 
990     bool bultInSupport = OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES;
991     isBlendEquationSupported = validContext &&
992                                (bultInSupport ||
993                                 isGLExtensionSupported(contextID, "GL_EXT_blend_equation") ||
994                                 (glVersion >= 1.2f));
995 
996 
997     isBlendEquationSeparateSupported = validContext &&
998                                        (bultInSupport ||
999                                         isGLExtensionSupported(contextID, "GL_EXT_blend_equation_separate") ||
1000                                         (glVersion >= 2.0f));
1001 
1002 
1003     isSGIXMinMaxSupported = validContext && isGLExtensionSupported(contextID, "GL_SGIX_blend_alpha_minmax");
1004     isLogicOpSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_blend_logic_op");
1005 
1006     setGLExtensionFuncPtr(glBlendEquation, "glBlendEquation", "glBlendEquationEXT", validContext);
1007     setGLExtensionFuncPtr(glBlendEquationSeparate, "glBlendEquationSeparate", "glBlendEquationSeparateEXT", validContext);
1008 
1009     setGLExtensionFuncPtr(glBlendEquationi, "glBlendEquationi", "glBlendEquationiARB", validContext);
1010     setGLExtensionFuncPtr(glBlendEquationSeparatei, "glBlendEquationSeparatei", "glBlendEquationSeparateiARB", validContext);
1011 
1012 
1013     // glEnablei/glDisabli
1014     setGLExtensionFuncPtr(glEnablei, "glEnablei", validContext);
1015     setGLExtensionFuncPtr(glDisablei, "glDisablei", validContext);
1016 
1017 
1018     // Stencil`
1019     isStencilWrapSupported = validContext && isGLExtensionOrVersionSupported(contextID, "GL_EXT_stencil_wrap", 1.4f);
1020     isStencilTwoSidedSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_stencil_two_side");
1021     isOpenGL20Supported = validContext && (glVersion >= 2.0f);
1022     isSeparateStencilSupported = validContext && isGLExtensionSupported(contextID, "GL_ATI_separate_stencil");
1023 
1024     // function pointers
1025     setGLExtensionFuncPtr(glActiveStencilFace, "glActiveStencilFaceEXT", validContext);
1026     setGLExtensionFuncPtr(glStencilOpSeparate, "glStencilOpSeparate", "glStencilOpSeparateATI", validContext);
1027     setGLExtensionFuncPtr(glStencilMaskSeparate, "glStencilMaskSeparate", validContext);
1028     setGLExtensionFuncPtr(glStencilFuncSeparate, "glStencilFuncSeparate", "glStencilFuncSeparateATI", validContext);
1029     setGLExtensionFuncPtr(glStencilFuncSeparateATI, "glStencilFuncSeparateATI", validContext);
1030 
1031 
1032     // Color Mask
1033     setGLExtensionFuncPtr(glColorMaski, "glColorMaski", "glColorMaskiARB", validContext);
1034 
1035 
1036     // ClampColor
1037     isClampColorSupported = validContext &&
1038                             (OSG_GL3_FEATURES ||
1039                              isGLExtensionSupported(contextID,"GL_ARB_color_buffer_float") ||
1040                              (glVersion >= 2.0f));
1041 
1042     setGLExtensionFuncPtr(glClampColor, "glClampColor", "glClampColorARB", validContext);
1043 
1044 
1045     // PrimitiveRestartIndex
1046     setGLExtensionFuncPtr(glPrimitiveRestartIndex, "glPrimitiveRestartIndex", "glPrimitiveRestartIndexNV", validContext);
1047 
1048 
1049     // Point
1050     isPointParametersSupported = validContext &&
1051                                  (OSG_GL3_FEATURES || (glVersion >= 1.4f)  ||
1052                                   isGLExtensionSupported(contextID,"GL_ARB_point_parameters") ||
1053                                   isGLExtensionSupported(contextID,"GL_EXT_point_parameters") ||
1054                                   isGLExtensionSupported(contextID,"GL_SGIS_point_parameters"));
1055 
1056 
1057     isPointSpriteSupported = validContext && (OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_ARB_point_sprite") || isGLExtensionSupported(contextID, "GL_OES_point_sprite") || isGLExtensionSupported(contextID, "GL_NV_point_sprite"));
1058     isPointSpriteModeSupported = isPointSpriteSupported && !OSG_GL3_FEATURES;
1059     isPointSpriteCoordOriginSupported = validContext && (OSG_GL3_FEATURES || (glVersion >= 2.0f));
1060 
1061 
1062     setGLExtensionFuncPtr(glPointParameteri, "glPointParameteri", "glPointParameteriARB", validContext);
1063     if (!glPointParameteri) setGLExtensionFuncPtr(glPointParameteri, "glPointParameteriEXT", "glPointParameteriSGIS", validContext);
1064 
1065     setGLExtensionFuncPtr(glPointParameterf, "glPointParameterf", "glPointParameterfARB", validContext);
1066     if (!glPointParameterf) setGLExtensionFuncPtr(glPointParameterf, "glPointParameterfEXT", "glPointParameterfSGIS", validContext);
1067 
1068     setGLExtensionFuncPtr(glPointParameterfv, "glPointParameterfv", "glPointParameterfvARB", validContext);
1069     if (!glPointParameterfv) setGLExtensionFuncPtr(glPointParameterfv, "glPointParameterfvEXT", "glPointParameterfvSGIS", validContext);
1070 
1071 
1072     // Multisample
1073     isMultisampleSupported = validContext && (OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_multisample"));
1074     isMultisampleFilterHintSupported = validContext && isGLExtensionSupported(contextID, "GL_NV_multisample_filter_hint");
1075 
1076     setGLExtensionFuncPtr(glSampleCoverage, "glSampleCoverage", "glSampleCoverageARB", validContext);
1077 
1078 
1079     // FrameBufferObject
1080     isMultisampledRenderToTextureSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_multisampled_render_to_texture");
1081     isInvalidateFramebufferSupported = validContext && (isGLExtensionSupported(contextID, "GL_ARB_invalidate_subdata") || (OSG_GLES3_FEATURES && glVersion >= 3.0) || glVersion >= 4.3);
1082 
1083     setGLExtensionFuncPtr(glBindRenderbuffer, "glBindRenderbuffer", "glBindRenderbufferEXT", "glBindRenderbufferOES", validContext);
1084     setGLExtensionFuncPtr(glDeleteRenderbuffers, "glDeleteRenderbuffers", "glDeleteRenderbuffersEXT", "glDeleteRenderbuffersOES", validContext);
1085     setGLExtensionFuncPtr(glGenRenderbuffers, "glGenRenderbuffers", "glGenRenderbuffersEXT", "glGenRenderbuffersOES", validContext);
1086     setGLExtensionFuncPtr(glRenderbufferStorage, "glRenderbufferStorage", "glRenderbufferStorageEXT", "glRenderbufferStorageOES", validContext);
1087     setGLExtensionFuncPtr(glRenderbufferStorageMultisample, "glRenderbufferStorageMultisample", "glRenderbufferStorageMultisampleEXT", "glRenderbufferStorageMultisampleOES", validContext);
1088     setGLExtensionFuncPtr(glRenderbufferStorageMultisampleCoverageNV, "glRenderbufferStorageMultisampleCoverageNV", validContext);
1089     setGLExtensionFuncPtr(glBindFramebuffer, "glBindFramebuffer", "glBindFramebufferEXT", "glBindFramebufferOES", validContext);
1090     setGLExtensionFuncPtr(glDeleteFramebuffers, "glDeleteFramebuffers", "glDeleteFramebuffersEXT", "glDeleteFramebuffersOES", validContext);
1091     setGLExtensionFuncPtr(glGenFramebuffers, "glGenFramebuffers", "glGenFramebuffersEXT", "glGenFramebuffersOES", validContext);
1092     setGLExtensionFuncPtr(glCheckFramebufferStatus, "glCheckFramebufferStatus", "glCheckFramebufferStatusEXT", "glCheckFramebufferStatusOES", validContext);
1093 
1094     setGLExtensionFuncPtr(glFramebufferTexture1D, "glFramebufferTexture1D", "glFramebufferTexture1DEXT", "glFramebufferTexture1DOES", validContext);
1095     setGLExtensionFuncPtr(glFramebufferTexture2D, "glFramebufferTexture2D", "glFramebufferTexture2DEXT", "glFramebufferTexture2DOES", validContext);
1096     setGLExtensionFuncPtr(glFramebufferTexture2DMultisample, "glFramebufferTexture2DMultisample", "glFramebufferTexture2DMultisampleEXT", validContext);
1097     setGLExtensionFuncPtr(glFramebufferTexture3D, "glFramebufferTexture3D", "glFramebufferTexture3DEXT", "glFramebufferTexture3DOES", validContext);
1098     setGLExtensionFuncPtr(glFramebufferTexture, "glFramebufferTexture", "glFramebufferTextureEXT", "glFramebufferTextureOES", validContext);
1099     setGLExtensionFuncPtr(glFramebufferTextureLayer, "glFramebufferTextureLayer", "glFramebufferTextureLayerEXT", "glFramebufferTextureLayerOES", validContext);
1100     setGLExtensionFuncPtr(glFramebufferTextureFace,  "glFramebufferTextureFace", "glFramebufferTextureFaceEXT", "glFramebufferTextureFaceOES" , validContext);
1101     setGLExtensionFuncPtr(glFramebufferRenderbuffer, "glFramebufferRenderbuffer", "glFramebufferRenderbufferEXT", "glFramebufferRenderbufferOES", validContext);
1102     //ARB_framebuffer_no_attachments
1103     //OpenGL 4.3
1104     setGLExtensionFuncPtr(glFramebufferParameteri, "glFramebufferParameteri", "glFramebufferParameteriARB", "glFramebufferParameteriOES", validContext);
1105     setGLExtensionFuncPtr(glGetFramebufferParameteriv, "glGetFramebufferParameteriv", "glGetFramebufferParameterivARB", "glGetFramebufferParameterivOES", validContext);
1106     //OpenGL 4.5 (EXT_direct_state_access required)
1107     setGLExtensionFuncPtr(glNamedFramebufferParameteri, "glNamedFramebufferParameteri", "glNamedFramebufferParameteriEXT", "glNamedFramebufferParameteriOES", validContext);
1108     setGLExtensionFuncPtr(glGetNamedFramebufferParameteriv, "glGetNamedFramebufferParameteriv", "glGetNamedFramebufferParameterivEXT", "glGetNamedFramebufferParameterivOES", validContext);
1109 
1110     setGLExtensionFuncPtr(glGenerateMipmap, "glGenerateMipmap", "glGenerateMipmapEXT", "glGenerateMipmapOES", validContext);
1111     setGLExtensionFuncPtr(glBlitFramebuffer, "glBlitFramebuffer", "glBlitFramebufferEXT", "glBlitFramebufferOES", validContext);
1112     setGLExtensionFuncPtr(glInvalidateFramebuffer, "glInvalidateFramebuffer", "glInvalidateFramebufferEXT", validContext);
1113     setGLExtensionFuncPtr(glGetRenderbufferParameteriv, "glGetRenderbufferParameteriv", "glGetRenderbufferParameterivEXT", "glGetRenderbufferParameterivOES", validContext);
1114 
1115 
1116     isFrameBufferObjectSupported =
1117         glBindRenderbuffer != 0 &&
1118         glDeleteRenderbuffers != 0 &&
1119         glGenRenderbuffers != 0 &&
1120         glRenderbufferStorage != 0 &&
1121         glBindFramebuffer != 0 &&
1122         glDeleteFramebuffers != 0 &&
1123         glGenFramebuffers != 0 &&
1124         glCheckFramebufferStatus != 0 &&
1125         glFramebufferTexture2D != 0 &&
1126         glFramebufferRenderbuffer != 0 &&
1127         glGenerateMipmap != 0 &&
1128         glGetRenderbufferParameteriv != 0 &&
1129     ( OSG_GLES2_FEATURES || OSG_GLES1_FEATURES || isGLExtensionOrVersionSupported(contextID, "GL_EXT_framebuffer_object",3.0f) );
1130 
1131 
1132     isPackedDepthStencilSupported = validContext &&
1133                                     (OSG_GL3_FEATURES ||
1134                                      (isGLExtensionSupported(contextID, "GL_EXT_packed_depth_stencil")) ||
1135                                      (isGLExtensionSupported(contextID, "GL_OES_packed_depth_stencil")));
1136 
1137     //subroutine
1138     osg::setGLExtensionFuncPtr(glGetSubroutineUniformLocation, "glGetSubroutineUniformLocation", validContext);
1139     osg::setGLExtensionFuncPtr(glGetActiveSubroutineUniformName, "glGetActiveSubroutineUniformName", validContext);
1140     osg::setGLExtensionFuncPtr(glGetActiveSubroutineUniformiv, "glGetActiveSubroutineUniformiv", validContext);
1141     osg::setGLExtensionFuncPtr(glGetSubroutineIndex, "glGetSubroutineIndex", validContext);
1142     osg::setGLExtensionFuncPtr(glGetActiveSubroutineName, "glGetActiveSubroutineName", validContext);
1143     osg::setGLExtensionFuncPtr(glGetProgramStageiv, "glGetProgramStageiv", validContext);
1144     osg::setGLExtensionFuncPtr(glUniformSubroutinesuiv, "glUniformSubroutinesuiv", validContext);
1145     osg::setGLExtensionFuncPtr(glGetUniformSubroutineuiv, "glGetUniformSubroutineuiv", validContext);
1146 
1147 
1148     // Sync
1149     osg::setGLExtensionFuncPtr(glFenceSync, "glFenceSync", validContext);
1150     osg::setGLExtensionFuncPtr(glIsSync, "glIsSync", validContext);
1151     osg::setGLExtensionFuncPtr(glDeleteSync, "glDeleteSync", validContext);
1152     osg::setGLExtensionFuncPtr(glClientWaitSync, "glClientWaitSync", validContext);
1153     osg::setGLExtensionFuncPtr(glWaitSync, "glWaitSync", validContext);
1154     osg::setGLExtensionFuncPtr(glGetSynciv, "glGetSynciv", validContext);
1155 
1156     // Indirect Rendering
1157     osg::setGLExtensionFuncPtr(glDrawArraysIndirect, "glDrawArraysIndirect", "glDrawArraysIndirectEXT", validContext);
1158     osg::setGLExtensionFuncPtr(glMultiDrawArraysIndirect, "glMultiDrawArraysIndirect", "glMultiDrawArraysIndirectEXT", validContext);
1159     osg::setGLExtensionFuncPtr(glDrawElementsIndirect, "glDrawElementsIndirect", "glDrawElementsIndirectEXT", validContext);
1160     osg::setGLExtensionFuncPtr(glMultiDrawElementsIndirect, "glMultiDrawElementsIndirect", "glMultiDrawElementsIndirectEXT", validContext);
1161 
1162     // ARB_sparse_texture
1163     osg::setGLExtensionFuncPtr(glTexPageCommitment, "glTexPageCommitment","glTexPageCommitmentARB", "glTexPageCommitmentEXT", validContext);
1164 
1165     // Transform Feeedback
1166     osg::setGLExtensionFuncPtr(glBeginTransformFeedback, "glBeginTransformFeedback", "glBeginTransformFeedbackEXT", validContext);
1167     osg::setGLExtensionFuncPtr(glEndTransformFeedback, "glEndTransformFeedback", "glEndTransformFeedbackEXT", validContext);
1168     osg::setGLExtensionFuncPtr(glTransformFeedbackVaryings, "glTransformFeedbackVaryings", "glTransformFeedbackVaryingsEXT", validContext);
1169     osg::setGLExtensionFuncPtr(glGetTransformFeedbackVarying, "glGetTransformFeedbackVarying", "glGetTransformFeedbackVaryingEXT", validContext);
1170     osg::setGLExtensionFuncPtr(glBindTransformFeedback, "glBindTransformFeedback", validContext);
1171     osg::setGLExtensionFuncPtr(glDeleteTransformFeedbacks, "glDeleteTransformFeedbacks", validContext);
1172     osg::setGLExtensionFuncPtr(glGenTransformFeedbacks, "glGenTransformFeedbacks", validContext);
1173     osg::setGLExtensionFuncPtr(glIsTransformFeedback, "glIsTransformFeedback", validContext);
1174     osg::setGLExtensionFuncPtr(glPauseTransformFeedback, "glPauseTransformFeedback", validContext);
1175     osg::setGLExtensionFuncPtr(glResumeTransformFeedback, "glResumeTransformFeedback", validContext);
1176     osg::setGLExtensionFuncPtr(glDrawTransformFeedback, "glDrawTransformFeedback", validContext);
1177     osg::setGLExtensionFuncPtr(glDrawTransformFeedbackStream, "glDrawTransformFeedbackStream", validContext);
1178     osg::setGLExtensionFuncPtr(glDrawTransformFeedbackInstanced, "glDrawTransformFeedbackInstanced", validContext);
1179     osg::setGLExtensionFuncPtr(glDrawTransformFeedbackStreamInstanced, "glDrawTransformFeedbackStreamInstanced", validContext);
1180     osg::setGLExtensionFuncPtr(glCreateTransformFeedbacks, "glCreateTransformFeedbacks", validContext);
1181     osg::setGLExtensionFuncPtr(glTransformFeedbackBufferBase, "glTransformFeedbackBufferBase", validContext);
1182     osg::setGLExtensionFuncPtr(glTransformFeedbackBufferRange, "glTransformFeedbackBufferRange", validContext);
1183     osg::setGLExtensionFuncPtr(glGetTransformFeedbackiv, "glGetTransformFeedbackiv", validContext);
1184     osg::setGLExtensionFuncPtr(glGetTransformFeedbacki_v, "glGetTransformFeedbacki_v", validContext);
1185     osg::setGLExtensionFuncPtr(glGetTransformFeedbacki64_v, "glGetTransformFeedbacki64_v", validContext);
1186 
1187     //Vertex Array Object
1188     osg::setGLExtensionFuncPtr(glGenVertexArrays, "glGenVertexArrays", "glGenVertexArraysOES", validContext);
1189     osg::setGLExtensionFuncPtr(glBindVertexArray, "glBindVertexArray", "glBindVertexArrayOES", validContext);
1190     osg::setGLExtensionFuncPtr(glDeleteVertexArrays, "glDeleteVertexArrays", "glDeleteVertexArraysOES", validContext);
1191     osg::setGLExtensionFuncPtr(glIsVertexArray, "glIsVertexArray", "glIsVertexArrayOES", validContext);
1192 
1193     // OpenGL 4.3 / ARB_vertex_attrib_binding
1194     isVertexAttribBindingSupported = validContext && (isGLExtensionOrVersionSupported(contextID, "GL_ARB_vertex_attrib_binding", 4.3f));
1195 
1196     osg::setGLExtensionFuncPtr(glBindVertexBuffer, "glBindVertexBuffer", "glBindVertexBufferOES", validContext);
1197     osg::setGLExtensionFuncPtr(glVertexArrayVertexBuffer, "glVertexArrayVertexBuffer", "glVertexArrayVertexBufferOES", validContext);
1198     osg::setGLExtensionFuncPtr(glVertexAttribBinding, "glVertexAttribBinding", "glVertexAttribBindingOES", validContext);
1199     osg::setGLExtensionFuncPtr(glVertexArrayAttribBinding, "glVertexArrayAttribBinding", "glVertexArrayAttribBindingOES", validContext);
1200 
1201     osg::setGLExtensionFuncPtr(glVertexAttribFormat, "glVertexAttribBinding", "glVertexAttribBindingOES", validContext);
1202     osg::setGLExtensionFuncPtr(glVertexAttribIFormat, "glVertexAttribBinding", "glVertexAttribBindingOES", validContext);
1203     osg::setGLExtensionFuncPtr(glVertexAttribLFormat, "glVertexAttribLFormat", "glVertexAttribLFormatOES", validContext);
1204     osg::setGLExtensionFuncPtr(glVertexArrayAttribFormat, "glVertexArrayAttribFormat", "glVertexArrayAttribFormatOES", validContext);
1205     osg::setGLExtensionFuncPtr(glVertexArrayAttribIFormat, "glVertexArrayAttribIFormat", "glVertexArrayAttribIFormatOES", validContext);
1206     osg::setGLExtensionFuncPtr(glVertexArrayAttribLFormat, "glVertexArrayAttribLFormat", "glVertexArrayAttribLFormatOES", validContext);
1207 
1208     // MultiDrawArrays
1209     setGLExtensionFuncPtr(glMultiDrawArrays, "glMultiDrawArrays", "glMultiDrawArraysEXT", validContext);
1210     setGLExtensionFuncPtr(glMultiDrawElements, "glMultiDrawElements", "glMultiDrawElementsEXT");
1211     setGLExtensionFuncPtr(glDrawArraysInstancedBaseInstance, "glDrawArraysInstancedBaseInstance", "glDrawArraysInstancedBaseInstanceEXT");
1212     setGLExtensionFuncPtr(glDrawElementsInstancedBaseInstance, "glDrawElementsInstancedBaseInstance", "glDrawElementsInstancedBaseInstanceEXT");
1213     setGLExtensionFuncPtr(glDrawElementsInstancedBaseVertexBaseInstance, "glDrawElementsInstancedBaseVertexBaseInstance", "glDrawElementsInstancedBaseVertexBaseInstanceEXT");
1214 
1215     setGLExtensionFuncPtr(glDrawRangeElements, "glDrawRangeElements");
1216     setGLExtensionFuncPtr(glDrawElementsBaseVertex, "glDrawElementsBaseVertex", "glDrawElementsBaseVertexEXT");
1217     setGLExtensionFuncPtr(glDrawRangeElementsBaseVertex, "glDrawRangeElementsBaseVertex", "glDrawRangeElementsBaseVertexEXT");
1218     setGLExtensionFuncPtr(glDrawElementsInstancedBaseVertex, "glDrawElementsInstancedBaseVertex", "glDrawElementsInstancedBaseVertexEXT");
1219     setGLExtensionFuncPtr(glMultiDrawElementsBaseVertex, "glMultiDrawElementsBaseVertex", "glMultiDrawElementsBaseVertexEXT");
1220     setGLExtensionFuncPtr(glProvokingVertex, "glProvokingVertex", "glProvokingVertexEXT");
1221 
1222     setGLExtensionFuncPtr(glBeginConditionalRender, "glBeginConditionalRender", "glBeginConditionalRenderEXT");
1223     setGLExtensionFuncPtr(glEndConditionalRender, "glEndConditionalRender", "glEndConditionalRenderEXT");
1224 
1225     // ViewportArray
1226     isViewportArraySupported = validContext && (isGLExtensionOrVersionSupported(contextID, "GL_ARB_viewport_array", 4.1f));
1227 
1228     osg::setGLExtensionFuncPtr(glViewportArrayv, "glViewportArrayv", validContext);
1229     osg::setGLExtensionFuncPtr(glViewportIndexedf, "glViewportIndexedf", validContext);
1230     osg::setGLExtensionFuncPtr(glViewportIndexedfv, "glViewportIndexedfv", validContext);
1231     osg::setGLExtensionFuncPtr(glScissorArrayv, "glScissorArrayv", validContext);
1232     osg::setGLExtensionFuncPtr(glScissorIndexed, "glScissorIndexed", validContext);
1233     osg::setGLExtensionFuncPtr(glScissorIndexedv, "glScissorIndexedv", validContext);
1234     osg::setGLExtensionFuncPtr(glDepthRangeArrayv, "glDepthRangeArrayv", validContext);
1235     osg::setGLExtensionFuncPtr(glDepthRangeIndexed, "glDepthRangeIndexed", validContext);
1236     osg::setGLExtensionFuncPtr(glDepthRangeIndexedf, "glDepthRangeIndexedfOES", "glDepthRangeIndexedfNV", validContext);
1237     osg::setGLExtensionFuncPtr(glGetFloati_v, "glGetFloati_v", validContext);
1238     osg::setGLExtensionFuncPtr(glGetDoublei_v, "glGetDoublei_v", validContext);
1239     osg::setGLExtensionFuncPtr(glGetIntegerIndexedvEXT, "glGetIntegerIndexedvEXT", validContext);
1240     osg::setGLExtensionFuncPtr(glEnableIndexedEXT, "glEnableIndexedEXT", validContext);
1241     osg::setGLExtensionFuncPtr(glDisableIndexedEXT, "glDisableIndexedEXT", validContext);
1242     osg::setGLExtensionFuncPtr(glIsEnabledIndexedEXT, "glIsEnabledIndexedEXT", validContext);
1243 
1244     setGLExtensionFuncPtr(glClientActiveTexture,"glClientActiveTexture","glClientActiveTextureARB", validContext);
1245     setGLExtensionFuncPtr(glActiveTexture, "glActiveTexture","glActiveTextureARB", validContext);
1246     setGLExtensionFuncPtr(glFogCoordPointer, "glFogCoordPointer","glFogCoordPointerEXT", validContext);
1247     setGLExtensionFuncPtr(glSecondaryColorPointer, "glSecondaryColorPointer","glSecondaryColorPointerEXT", validContext);
1248 
1249     if (validContext)
1250     {
1251         if (osg::getGLVersionNumber() >= 2.0 || osg::isGLExtensionSupported(contextID, "GL_ARB_vertex_shader") || OSG_GLES2_FEATURES || OSG_GLES3_FEATURES || OSG_GL3_FEATURES)
1252         {
1253             glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,&glMaxTextureUnits);
1254             #ifdef OSG_GL_FIXED_FUNCTION_AVAILABLE
1255                 glGetIntegerv(GL_MAX_TEXTURE_COORDS, &glMaxTextureCoords);
1256             #else
1257                 glMaxTextureCoords = glMaxTextureUnits;
1258             #endif
1259         }
1260         #ifdef GL_MAX_TEXTURE_UNITS
1261         else if ( osg::getGLVersionNumber() >= 1.3 ||
1262                                     osg::isGLExtensionSupported(contextID,"GL_ARB_multitexture") ||
1263                                     osg::isGLExtensionSupported(contextID,"GL_EXT_multitexture") ||
1264                                     OSG_GLES1_FEATURES)
1265         {
1266             GLint maxTextureUnits = 0;
1267             glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxTextureUnits);
1268             glMaxTextureUnits = maxTextureUnits;
1269             glMaxTextureCoords = maxTextureUnits;
1270         }
1271         #endif
1272         else
1273         {
1274             glMaxTextureUnits = 1;
1275             glMaxTextureCoords = 1;
1276         }
1277     }
1278     else
1279     {
1280         glMaxTextureUnits = 0;
1281         glMaxTextureCoords = 0;
1282     }
1283 
1284     osg::setGLExtensionFuncPtr(glObjectLabel, "glObjectLabel", validContext);
1285 
1286 }
1287 
~GLExtensions()1288 GLExtensions::~GLExtensions()
1289 {
1290     // Remove s_gl*List
1291     s_glExtensionSetList[contextID] = ExtensionSet();
1292     s_glRendererList[contextID] = std::string();
1293     s_glInitializedList[contextID] = 0;
1294 }
1295 
1296 ///////////////////////////////////////////////////////////////////////////
1297 // C++-friendly convenience methods
1298 
getCurrentProgram() const1299 GLuint GLExtensions::getCurrentProgram() const
1300 {
1301     if( glVersion >= 2.0f )
1302     {
1303         // GLSL as GL v2.0 core functionality
1304         GLint result = 0;
1305         glGetIntegerv( GL_CURRENT_PROGRAM, &result );
1306         return static_cast<GLuint>(result);
1307     }
1308     else if (glGetHandleARB)
1309     {
1310         // fallback for GLSL as GL v1.5 ARB extension
1311 #ifndef GL_PROGRAM_OBJECT_ARB
1312 #define GL_PROGRAM_OBJECT_ARB 0x8B40
1313 #endif
1314         return glGetHandleARB( GL_PROGRAM_OBJECT_ARB );
1315     }
1316     else
1317     {
1318         OSG_WARN<<"Warning GLExtensions::getCurrentProgram not supported"<<std::endl;;
1319         return 0;
1320     }
1321 }
1322 
1323 
getProgramInfoLog(GLuint program,std::string & result) const1324 bool GLExtensions::getProgramInfoLog( GLuint program, std::string& result ) const
1325 {
1326     GLsizei bufLen = 0;        // length of buffer to allocate
1327     GLsizei strLen = 0;        // strlen GL actually wrote to buffer
1328 
1329     glGetProgramiv( program, GL_INFO_LOG_LENGTH, &bufLen );
1330     if( bufLen > 1 )
1331     {
1332         GLchar* infoLog = new GLchar[bufLen];
1333         glGetProgramInfoLog( program, bufLen, &strLen, infoLog );
1334         if( strLen > 0 ) result = reinterpret_cast<char*>(infoLog);
1335         delete [] infoLog;
1336     }
1337     return (strLen > 0);
1338 }
1339 
1340 
getShaderInfoLog(GLuint shader,std::string & result) const1341 bool GLExtensions::getShaderInfoLog( GLuint shader, std::string& result ) const
1342 {
1343     GLsizei bufLen = 0;        // length of buffer to allocate
1344     GLsizei strLen = 0;        // strlen GL actually wrote to buffer
1345 
1346     glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &bufLen );
1347     if( bufLen > 1 )
1348     {
1349         GLchar* infoLog = new GLchar[bufLen];
1350         glGetShaderInfoLog( shader, bufLen, &strLen, infoLog );
1351         if( strLen > 0 ) result = reinterpret_cast<char*>(infoLog);
1352         delete [] infoLog;
1353     }
1354     return (strLen > 0);
1355 }
1356 
1357 
getAttribLocation(const char * attribName,GLuint & location) const1358 bool GLExtensions::getAttribLocation( const char* attribName, GLuint& location ) const
1359 {
1360     // is there an active GLSL program?
1361     GLuint program = getCurrentProgram();
1362     if( glIsProgram(program) == GL_FALSE ) return false;
1363 
1364     // has that program been successfully linked?
1365     GLint linked = GL_FALSE;
1366     glGetProgramiv( program, GL_LINK_STATUS, &linked );
1367     if( linked == GL_FALSE ) return false;
1368 
1369     // is there such a named attribute?
1370     GLint loc = glGetAttribLocation( program, reinterpret_cast<const GLchar*>(attribName) );
1371     if( loc < 0 ) return false;
1372 
1373     location = loc;
1374     return true;
1375 }
1376 
1377 
getFragDataLocation(const char * fragDataName,GLuint & location) const1378 bool GLExtensions::getFragDataLocation( const char* fragDataName, GLuint& location ) const
1379 {
1380     // is there an active GLSL program?
1381     GLuint program = getCurrentProgram();
1382     if( glIsProgram(program) == GL_FALSE ) return false;
1383 
1384     // has that program been successfully linked?
1385     GLint linked = GL_FALSE;
1386     glGetProgramiv( program, GL_LINK_STATUS, &linked );
1387     if( linked == GL_FALSE ) return false;
1388 
1389     // check if supported
1390     if (glGetFragDataLocation == NULL) return false;
1391 
1392     // is there such a named attribute?
1393     GLint loc = glGetFragDataLocation( program, reinterpret_cast<const GLchar*>(fragDataName) );
1394     if( loc < 0 ) return false;
1395 
1396     location = loc;
1397     return true;
1398 }
1399 
1400