26b00f02e7d1168a5ffaac97e6e9dddcdd1285dc
[blender-staging.git] / source / gameengine / Rasterizer / RAS_OpenGLRasterizer / RAS_GLExtensionManager.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31 /*
32   The extension manager's job is to link at runtime OpenGL extension 
33   functions.
34
35   Since the various platform have different methods of finding a fn
36   pointer, this file attempts to encapsulate all that, so it gets a
37   little messy.  Hopefully we can 
38 */
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 #ifdef WIN32
44 #  include <windows.h>
45
46 #  include <GL/gl.h>
47
48 #elif defined(__APPLE__)
49 #  include <Carbon/Carbon.h>
50 #  define GL_GLEXT_LEGACY 1
51 #  include <OpenGL/gl.h>
52
53 #else /* UNIX */
54 #  include <GL/gl.h>
55 #  include <GL/glx.h>
56
57 #  include <dlfcn.h>
58 #endif
59
60 #include <vector>
61 #include <iostream>
62 #include <algorithm>
63 #include <bitset>
64
65 #include "STR_String.h"
66
67 #include "RAS_GLExtensionManager.h"
68
69 /* -----------------------------------------------------------------------------
70
71    Platform specific functions section.
72    
73    Required Functions:
74    static void bglInitEntryPoints (void)                -- Loads the GL library
75    static void bglDeallocEntryPoints (void)             -- Frees the GL library
76    static void *bglGetProcAddress(const GLubyte* entry) -- Finds the address of
77        the GL function entry
78
79 */
80 #if defined(BGL_NO_EXTENSIONS)
81 static void bglInitEntryPoints (void) {}
82 static void bglDeallocEntryPoints (void) {}
83
84 static void *bglGetProcAddress(const GLubyte* entry)
85 {
86         /* No Extensions! */
87         return NULL;
88 }
89 #elif defined(__APPLE__)
90 /* http://developer.apple.com/qa/qa2001/qa1188.html */
91 CFBundleRef gBundleRefOpenGL = NULL;
92
93 // -------------------------
94
95 static OSStatus bglInitEntryPoints (void)
96 {
97     OSStatus err = noErr;
98     const Str255 frameworkName = "\pOpenGL.framework";
99     FSRefParam fileRefParam;
100     FSRef fileRef;
101     CFURLRef bundleURLOpenGL;
102
103     memset(&fileRefParam, 0, sizeof(fileRefParam));
104     memset(&fileRef, 0, sizeof(fileRef));
105
106     fileRefParam.ioNamePtr  = frameworkName;
107     fileRefParam.newRef = &fileRef;
108
109     // Frameworks directory/folder
110     err = FindFolder (kSystemDomain, kFrameworksFolderType, false,
111                       &fileRefParam.ioVRefNum, (SInt32*)&fileRefParam.ioDirID);
112     if (noErr != err) {
113         DebugStr ((unsigned char *)"\pCould not find frameworks folder");
114         return err;
115     }
116     err = PBMakeFSRefSync (&fileRefParam); // make FSRef for folder
117     if (noErr != err) {
118         DebugStr ((unsigned char *)"\pCould make FSref to frameworks folder");
119         return err;
120     }
121     // create URL to folder
122     bundleURLOpenGL = CFURLCreateFromFSRef (kCFAllocatorDefault,
123                                             &fileRef);
124     if (!bundleURLOpenGL) {
125         DebugStr ((unsigned char *)"\pCould create OpenGL Framework bundle URL");
126         return paramErr;
127     }
128     // create ref to GL's bundle
129     gBundleRefOpenGL = CFBundleCreate (kCFAllocatorDefault,
130                                        bundleURLOpenGL);
131     if (!gBundleRefOpenGL) {
132         DebugStr ((unsigned char *)"\pCould not create OpenGL Framework bundle");
133         return paramErr;
134     }
135     CFRelease (bundleURLOpenGL); // release created bundle
136     // if the code was successfully loaded, look for our function.
137     if (!CFBundleLoadExecutable (gBundleRefOpenGL)) {
138         DebugStr ((unsigned char *)"\pCould not load MachO executable");
139         return paramErr;
140     }
141     return err;
142 }
143
144 // -------------------------
145
146 static void bglDeallocEntryPoints (void)
147 {
148     if (gBundleRefOpenGL != NULL) {
149         // unload the bundle's code.
150         CFBundleUnloadExecutable (gBundleRefOpenGL);
151         CFRelease (gBundleRefOpenGL);
152         gBundleRefOpenGL = NULL;
153     }
154 }
155
156 // -------------------------
157
158 /*unused*/
159 static void * bglGetProcAddress (const GLubyte * pszProc)
160 {
161     if (!gBundleRefOpenGL)
162         return NULL;
163
164     return CFBundleGetFunctionPointerForName (gBundleRefOpenGL,
165                 CFStringCreateWithCStringNoCopy (NULL,
166                      (const char *) pszProc, CFStringGetSystemEncoding (), NULL));
167 }
168 #elif defined(GLX_ARB_get_proc_address)
169 /* Not all glx.h define PFNGLXGETPROCADDRESSARBPROC !
170    We define our own if needed.                         */
171 #ifdef HAVE_PFNGLXGETPROCADDRESSARBPROC
172 #define PFNBGLXGETPROCADDRESSARBPROC PFNGLXGETPROCADDRESSARBPROC
173 #else
174 typedef void (*(*PFNBGLXGETPROCADDRESSARBPROC)(const GLubyte *procname))();
175 #endif
176
177 void *_getProcAddress(const GLubyte *procName) { return NULL; }
178 PFNBGLXGETPROCADDRESSARBPROC bglGetProcAddress;
179
180
181 //weird bug related to combination of pthreads,libGL and dlopen
182 //cannot call dlclose in such environment, causes crashes
183 //so try to keep a global handle to libGL
184 void* libGL = 0;
185
186 static void bglInitEntryPoints (void)
187 {
188         Display *dpy = glXGetCurrentDisplay();
189         std::vector<STR_String> Xextensions = STR_String(glXQueryExtensionsString(dpy, DefaultScreen(dpy))).Explode(' ');
190         if (std::find(Xextensions.begin(), Xextensions.end(), "GLX_ARB_get_proc_address") != Xextensions.end()) 
191         {
192                 if (!libGL)
193                 {
194                         libGL = dlopen("libGL.so", RTLD_LAZY|RTLD_GLOBAL);
195                         if (libGL)
196                                 bglGetProcAddress = (PFNBGLXGETPROCADDRESSARBPROC) (dlsym(libGL, "glXGetProcAddressARB"));
197                         else
198                                 std::cout << "Error: " << dlerror() << std::endl;
199
200                         // dlclose(libGL);
201                         if (!bglGetProcAddress)
202                                 bglGetProcAddress = (PFNBGLXGETPROCADDRESSARBPROC) _getProcAddress;
203                         
204                         // --
205                         if(!bglGetProcAddress)
206                                 std::cout << "Error: unable to find _getProcAddress in libGL" << std::endl;
207                 }
208         }
209 }
210
211 static void bglDeallocEntryPoints (void) {}
212
213 #elif defined(WIN32)
214 static void bglInitEntryPoints (void) {}
215 static void bglDeallocEntryPoints (void) {}
216
217 #define bglGetProcAddress(entry) wglGetProcAddress((LPCSTR) entry)
218
219 #else /* Unknown Platform - disable extensions */
220 static void bglInitEntryPoints (void) {}
221 static void bglDeallocEntryPoints (void) {}
222
223 static void *bglGetProcAddress(const GLubyte* entry)
224 {
225         /* No Extensions! */
226         return NULL;
227 }
228
229 #endif /* End Platform Specific */
230
231 /* -----------------------------------------------------------------------------
232
233    GL Extension Manager.
234 */
235         /* Bit array of available extensions */
236 static std::bitset<bgl::NUM_EXTENSIONS> enabled_extensions;
237 static std::vector<STR_String> extensions;
238 static int m_debug;
239         
240 static void LinkExtensions();
241
242 static void EnableExtension(bgl::ExtensionName name)
243 {
244         unsigned int num = (unsigned int) name;
245         if (num < bgl::NUM_EXTENSIONS)
246                 enabled_extensions.set(num);
247 }
248
249
250 static bool QueryExtension(STR_String extension_name)
251 {
252         return std::find(extensions.begin(), extensions.end(), extension_name) != extensions.end();
253 }
254
255 namespace bgl
256 {
257
258 void InitExtensions(int debug)
259 {
260         m_debug = debug;
261         bglInitEntryPoints (); //init bundle
262         EnableExtension(_BGL_TEST);
263         LinkExtensions();
264         bglDeallocEntryPoints();
265 }
266
267 bool QueryExtension(ExtensionName name)
268 {
269         unsigned int num = (unsigned int) name;
270         if (num < NUM_EXTENSIONS)
271                 return enabled_extensions[num];
272                  
273         return false;
274 }
275
276 bool QueryVersion(int major, int minor)
277 {
278         static int gl_major = 0;
279         static int gl_minor = 0;
280         
281         if (gl_major == 0)
282         {
283                 const char *gl_version_str = (const char *) glGetString(GL_VERSION);
284                 if (!gl_version_str)
285                         return false;
286                 STR_String gl_version = STR_String(gl_version_str);
287                 int i = gl_version.Find('.');
288                 gl_major = gl_version.Left(i).ToInt();
289                 gl_minor = gl_version.Mid(i+1, gl_version.FindOneOf(". ", i+1) - i - 1).ToInt();
290         
291                 static bool doQueryVersion = m_debug;
292                 if (doQueryVersion)
293                 {
294                         doQueryVersion = false;
295                         std::cout << "GL_VERSION: " << gl_major << "." << gl_minor << " (" << gl_version << ")" << std::endl;
296                 }
297         }
298         
299         if (gl_major > major)
300                 return true;
301         
302         if (gl_major == major && gl_minor >= minor)
303                 return true;
304                 
305         return false;
306 }
307
308
309 /*******************************************************************************
310 1. Extension function entry points go here
311
312 Need to #ifdef (compile time test for extension)
313 Add null functions if appropriate
314
315 Some extensions have been incorporated into the core GL, eg Multitexture was 
316 added in GL v1.1.  If Blender calls one of these functions before they are 
317 linked, it will crash.  Even worse, if Blender *indirectly* calls one of these 
318 functions, (ie the GL implementation calls them itself) Blender will crash.
319
320 We fix this by adding them to the bgl namespace - the functions are now 
321 private to the gameengine.  Code can transparently use extensions by adding:
322
323 using namespace bgl;
324
325 to their source.  Cunning like a weasel.
326
327  ******************************************************************************/
328
329 #if defined(PFNGLPNTRIANGLESIATIPROC)
330 PFNGLPNTRIANGLESIATIPROC glPNTrianglesiATI;
331 PFNGLPNTRIANGLESFATIPROC glPNTrianglesfATI;
332 #endif
333
334 BL_EXTInfo RAS_EXT_support;
335
336
337 #ifdef GL_ARB_multitexture
338 int max_texture_units = 2;
339  PFNGLACTIVETEXTUREARBPROC blActiveTextureARB;
340  PFNGLCLIENTACTIVETEXTUREARBPROC blClientActiveTextureARB;
341  PFNGLMULTITEXCOORD1DARBPROC blMultiTexCoord1dARB;
342  PFNGLMULTITEXCOORD1DVARBPROC blMultiTexCoord1dvARB;
343  PFNGLMULTITEXCOORD1FARBPROC blMultiTexCoord1fARB;
344  PFNGLMULTITEXCOORD1FVARBPROC blMultiTexCoord1fvARB;
345  PFNGLMULTITEXCOORD1IARBPROC blMultiTexCoord1iARB;
346  PFNGLMULTITEXCOORD1IVARBPROC blMultiTexCoord1ivARB;
347  PFNGLMULTITEXCOORD1SARBPROC blMultiTexCoord1sARB;
348  PFNGLMULTITEXCOORD1SVARBPROC blMultiTexCoord1svARB;
349  PFNGLMULTITEXCOORD2DARBPROC blMultiTexCoord2dARB;
350  PFNGLMULTITEXCOORD2DVARBPROC blMultiTexCoord2dvARB;
351  PFNGLMULTITEXCOORD2FARBPROC blMultiTexCoord2fARB;
352  PFNGLMULTITEXCOORD2FVARBPROC blMultiTexCoord2fvARB;
353  PFNGLMULTITEXCOORD2IARBPROC blMultiTexCoord2iARB;
354  PFNGLMULTITEXCOORD2IVARBPROC blMultiTexCoord2ivARB;
355  PFNGLMULTITEXCOORD2SARBPROC blMultiTexCoord2sARB;
356  PFNGLMULTITEXCOORD2SVARBPROC blMultiTexCoord2svARB;
357  PFNGLMULTITEXCOORD3DARBPROC blMultiTexCoord3dARB;
358  PFNGLMULTITEXCOORD3DVARBPROC blMultiTexCoord3dvARB;
359  PFNGLMULTITEXCOORD3FARBPROC blMultiTexCoord3fARB;
360  PFNGLMULTITEXCOORD3FVARBPROC blMultiTexCoord3fvARB;
361  PFNGLMULTITEXCOORD3IARBPROC blMultiTexCoord3iARB;
362  PFNGLMULTITEXCOORD3IVARBPROC blMultiTexCoord3ivARB;
363  PFNGLMULTITEXCOORD3SARBPROC blMultiTexCoord3sARB;
364  PFNGLMULTITEXCOORD3SVARBPROC blMultiTexCoord3svARB;
365  PFNGLMULTITEXCOORD4DARBPROC blMultiTexCoord4dARB;
366  PFNGLMULTITEXCOORD4DVARBPROC blMultiTexCoord4dvARB;
367  PFNGLMULTITEXCOORD4FARBPROC blMultiTexCoord4fARB;
368  PFNGLMULTITEXCOORD4FVARBPROC blMultiTexCoord4fvARB;
369  PFNGLMULTITEXCOORD4IARBPROC blMultiTexCoord4iARB;
370  PFNGLMULTITEXCOORD4IVARBPROC blMultiTexCoord4ivARB;
371  PFNGLMULTITEXCOORD4SARBPROC blMultiTexCoord4sARB;
372  PFNGLMULTITEXCOORD4SVARBPROC blMultiTexCoord4svARB;
373 #endif
374
375 #ifdef GL_ARB_shader_objects
376  PFNGLDELETEOBJECTARBPROC blDeleteObjectARB;
377  PFNGLGETHANDLEARBPROC blGetHandleARB;
378  PFNGLDETACHOBJECTARBPROC blDetachObjectARB;
379  PFNGLCREATESHADEROBJECTARBPROC blCreateShaderObjectARB;
380  PFNGLSHADERSOURCEARBPROC blShaderSourceARB;
381  PFNGLCOMPILESHADERARBPROC blCompileShaderARB;
382  PFNGLCREATEPROGRAMOBJECTARBPROC blCreateProgramObjectARB;
383  PFNGLATTACHOBJECTARBPROC blAttachObjectARB;
384  PFNGLLINKPROGRAMARBPROC blLinkProgramARB;
385  PFNGLUSEPROGRAMOBJECTARBPROC blUseProgramObjectARB;
386  PFNGLVALIDATEPROGRAMARBPROC blValidateProgramARB;
387  PFNGLUNIFORM1FARBPROC blUniform1fARB;
388  PFNGLUNIFORM2FARBPROC blUniform2fARB;
389  PFNGLUNIFORM3FARBPROC blUniform3fARB;
390  PFNGLUNIFORM4FARBPROC blUniform4fARB;
391  PFNGLUNIFORM1IARBPROC blUniform1iARB;
392  PFNGLUNIFORM2IARBPROC blUniform2iARB;
393  PFNGLUNIFORM3IARBPROC blUniform3iARB;
394  PFNGLUNIFORM4IARBPROC blUniform4iARB;
395  PFNGLUNIFORM1FVARBPROC blUniform1fvARB;
396  PFNGLUNIFORM2FVARBPROC blUniform2fvARB;
397  PFNGLUNIFORM3FVARBPROC blUniform3fvARB;
398  PFNGLUNIFORM4FVARBPROC blUniform4fvARB;
399  PFNGLUNIFORM1IVARBPROC blUniform1ivARB;
400  PFNGLUNIFORM2IVARBPROC blUniform2ivARB;
401  PFNGLUNIFORM3IVARBPROC blUniform3ivARB;
402  PFNGLUNIFORM4IVARBPROC blUniform4ivARB;
403  PFNGLUNIFORMMATRIX2FVARBPROC blUniformMatrix2fvARB;
404  PFNGLUNIFORMMATRIX3FVARBPROC blUniformMatrix3fvARB;
405  PFNGLUNIFORMMATRIX4FVARBPROC blUniformMatrix4fvARB;
406  PFNGLGETOBJECTPARAMETERFVARBPROC blGetObjectParameterfvARB;
407  PFNGLGETOBJECTPARAMETERIVARBPROC blGetObjectParameterivARB;
408  PFNGLGETINFOLOGARBPROC blGetInfoLogARB;
409  PFNGLGETATTACHEDOBJECTSARBPROC blGetAttachedObjectsARB;
410  PFNGLGETUNIFORMLOCATIONARBPROC blGetUniformLocationARB;
411  PFNGLGETACTIVEUNIFORMARBPROC blGetActiveUniformARB;
412  PFNGLGETUNIFORMFVARBPROC blGetUniformfvARB;
413  PFNGLGETUNIFORMIVARBPROC blGetUniformivARB;
414  PFNGLGETSHADERSOURCEARBPROC blGetShaderSourceARB;
415 #endif
416
417 #ifdef GL_ARB_vertex_shader
418 PFNGLBINDATTRIBLOCATIONARBPROC blBindAttribLocationARB;
419 PFNGLGETACTIVEATTRIBARBPROC blGetActiveAttribARB;
420 PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB;
421 #endif
422
423 #ifdef GL_ARB_vertex_program
424  PFNGLVERTEXATTRIB1FARBPROC blVertexAttrib1fARB;
425  PFNGLVERTEXATTRIB1FVARBPROC blVertexAttrib1fvARB;
426  PFNGLVERTEXATTRIB2FARBPROC blVertexAttrib2fARB;
427  PFNGLVERTEXATTRIB2FVARBPROC blVertexAttrib2fvARB;
428  PFNGLVERTEXATTRIB3FARBPROC blVertexAttrib3fARB;
429  PFNGLVERTEXATTRIB3FVARBPROC blVertexAttrib3fvARB;
430  PFNGLVERTEXATTRIB4FARBPROC blVertexAttrib4fARB;
431  PFNGLVERTEXATTRIB4FVARBPROC blVertexAttrib4fvARB;
432  PFNGLGETPROGRAMSTRINGARBPROC blGetProgramStringARB;
433  PFNGLGETVERTEXATTRIBDVARBPROC blGetVertexAttribdvARB;
434  PFNGLGETVERTEXATTRIBFVARBPROC blGetVertexAttribfvARB;
435  PFNGLGETVERTEXATTRIBIVARBPROC blGetVertexAttribivARB;
436 #endif
437
438  /*
439 #ifdef GL_EXT_compiled_vertex_array
440  PFNGLLOCKARRAYSEXTPROC blLockArraysEXT;
441  PFNGLUNLOCKARRAYSEXTPROC blUnlockArraysEXT;
442 #endif
443 */
444
445 } // namespace bgl
446
447 using namespace bgl;
448 /*******************************************************************************
449 2. Query extension functions here
450
451 Need to #ifdef (compile time test for extension)
452 Use QueryExtension("GL_EXT_name") to test at runtime.
453 Use bglGetProcAddress to find entry point
454 Use EnableExtension(_GL_EXT_...) to allow Blender to use the extension.
455
456  ******************************************************************************/
457 static void LinkExtensions()
458 {
459         static bool doDebugMessages = m_debug;
460         extensions = STR_String((const char *) glGetString(GL_EXTENSIONS)).Explode(' ');
461         RAS_EXT_support = BL_EXTInfo();
462
463 #if defined(PFNGLPNTRIANGLESIATIPROC)
464         if (QueryExtension("GL_ATI_pn_triangles"))
465         {
466                 glPNTrianglesiATI = reinterpret_cast<PFNGLPNTRIANGLESIATIPROC>(bglGetProcAddress((const GLubyte *) "glPNTrianglesiATI"));
467                 glPNTrianglesfATI = reinterpret_cast<PFNGLPNTRIANGLESFATIPROC>(bglGetProcAddress((const GLubyte *) "glPNTrianglesfATI"));
468                 if (glPNTrianglesiATI && glPNTrianglesfATI) {
469                         EnableExtension(_GL_ATI_pn_triangles);
470                         if (doDebugMessages)
471                                 std::cout << "Enabled GL_ATI_pn_triangles" << std::endl;
472                 } else {
473                         std::cout << "ERROR: GL_ATI_pn_triangles implementation is broken!" << std::endl;
474                 }
475         }
476 #endif
477
478 #ifdef GL_ARB_texture_env_combine
479         if (QueryExtension("GL_ARB_texture_env_combine"))
480         {
481                 EnableExtension(_GL_ARB_texture_env_combine);
482                 RAS_EXT_support._ARB_texture_env_combine = 1;
483                 if (doDebugMessages)
484                 {
485                         std::cout << "Detected GL_ARB_texture_env_combine" << std::endl;
486                 }
487         }
488 #endif
489
490 #ifdef GL_ARB_texture_cube_map
491         if (QueryExtension("GL_ARB_texture_cube_map"))
492         {
493                 EnableExtension(_GL_ARB_texture_cube_map);
494                 RAS_EXT_support._ARB_texture_cube_map = 1;
495                 if (doDebugMessages)
496                         std::cout << "Detected GL_ARB_texture_cube_map" << std::endl;
497         }
498 #endif
499
500 #ifdef GL_ARB_multitexture
501         if (QueryExtension("GL_ARB_multitexture"))
502         {
503                 bgl::blActiveTextureARB = reinterpret_cast<PFNGLACTIVETEXTUREARBPROC>(bglGetProcAddress((const GLubyte *) "glActiveTextureARB"));
504                 bgl::blClientActiveTextureARB = reinterpret_cast<PFNGLCLIENTACTIVETEXTUREARBPROC>(bglGetProcAddress((const GLubyte *) "glClientActiveTextureARB"));
505                 bgl::blMultiTexCoord1dARB = reinterpret_cast<PFNGLMULTITEXCOORD1DARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1dARB"));
506                 bgl::blMultiTexCoord1dvARB = reinterpret_cast<PFNGLMULTITEXCOORD1DVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1dvARB"));
507                 bgl::blMultiTexCoord1fARB = reinterpret_cast<PFNGLMULTITEXCOORD1FARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1fARB"));
508                 bgl::blMultiTexCoord1fvARB = reinterpret_cast<PFNGLMULTITEXCOORD1FVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1fvARB"));
509                 bgl::blMultiTexCoord1iARB = reinterpret_cast<PFNGLMULTITEXCOORD1IARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1iARB"));
510                 bgl::blMultiTexCoord1ivARB = reinterpret_cast<PFNGLMULTITEXCOORD1IVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1ivARB"));
511                 bgl::blMultiTexCoord1sARB = reinterpret_cast<PFNGLMULTITEXCOORD1SARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1sARB"));
512                 bgl::blMultiTexCoord1svARB = reinterpret_cast<PFNGLMULTITEXCOORD1SVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1svARB"));
513                 bgl::blMultiTexCoord2dARB = reinterpret_cast<PFNGLMULTITEXCOORD2DARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2dARB"));
514                 bgl::blMultiTexCoord2dvARB = reinterpret_cast<PFNGLMULTITEXCOORD2DVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2dvARB"));
515                 bgl::blMultiTexCoord2fARB = reinterpret_cast<PFNGLMULTITEXCOORD2FARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2fARB"));
516                 bgl::blMultiTexCoord2fvARB = reinterpret_cast<PFNGLMULTITEXCOORD2FVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2fvARB"));
517                 bgl::blMultiTexCoord2iARB = reinterpret_cast<PFNGLMULTITEXCOORD2IARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2iARB"));
518                 bgl::blMultiTexCoord2ivARB = reinterpret_cast<PFNGLMULTITEXCOORD2IVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2ivARB"));
519                 bgl::blMultiTexCoord2sARB = reinterpret_cast<PFNGLMULTITEXCOORD2SARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2sARB"));
520                 bgl::blMultiTexCoord2svARB = reinterpret_cast<PFNGLMULTITEXCOORD2SVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2svARB"));
521                 bgl::blMultiTexCoord3dARB = reinterpret_cast<PFNGLMULTITEXCOORD3DARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3dARB"));
522                 bgl::blMultiTexCoord3dvARB = reinterpret_cast<PFNGLMULTITEXCOORD3DVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3dvARB"));
523                 bgl::blMultiTexCoord3fARB = reinterpret_cast<PFNGLMULTITEXCOORD3FARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3fARB"));
524                 bgl::blMultiTexCoord3fvARB = reinterpret_cast<PFNGLMULTITEXCOORD3FVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3fvARB"));
525                 bgl::blMultiTexCoord3iARB = reinterpret_cast<PFNGLMULTITEXCOORD3IARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3iARB"));
526                 bgl::blMultiTexCoord3ivARB = reinterpret_cast<PFNGLMULTITEXCOORD3IVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3ivARB"));
527                 bgl::blMultiTexCoord3sARB = reinterpret_cast<PFNGLMULTITEXCOORD3SARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3sARB"));
528                 bgl::blMultiTexCoord3svARB = reinterpret_cast<PFNGLMULTITEXCOORD3SVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3svARB"));
529                 bgl::blMultiTexCoord4dARB = reinterpret_cast<PFNGLMULTITEXCOORD4DARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4dARB"));
530                 bgl::blMultiTexCoord4dvARB = reinterpret_cast<PFNGLMULTITEXCOORD4DVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4dvARB"));
531                 bgl::blMultiTexCoord4fARB = reinterpret_cast<PFNGLMULTITEXCOORD4FARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4fARB"));
532                 bgl::blMultiTexCoord4fvARB = reinterpret_cast<PFNGLMULTITEXCOORD4FVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4fvARB"));
533                 bgl::blMultiTexCoord4iARB = reinterpret_cast<PFNGLMULTITEXCOORD4IARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4iARB"));
534                 bgl::blMultiTexCoord4ivARB = reinterpret_cast<PFNGLMULTITEXCOORD4IVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4ivARB"));
535                 bgl::blMultiTexCoord4sARB = reinterpret_cast<PFNGLMULTITEXCOORD4SARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4sARB"));
536                 bgl::blMultiTexCoord4svARB = reinterpret_cast<PFNGLMULTITEXCOORD4SVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4svARB"));
537                 if (bgl::blActiveTextureARB && bgl::blClientActiveTextureARB && bgl::blMultiTexCoord1dARB && bgl::blMultiTexCoord1dvARB && bgl::blMultiTexCoord1fARB && bgl::blMultiTexCoord1fvARB && bgl::blMultiTexCoord1iARB && bgl::blMultiTexCoord1ivARB && bgl::blMultiTexCoord1sARB && bgl::blMultiTexCoord1svARB && bgl::blMultiTexCoord2dARB && bgl::blMultiTexCoord2dvARB && bgl::blMultiTexCoord2fARB && bgl::blMultiTexCoord2fvARB && bgl::blMultiTexCoord2iARB && bgl::blMultiTexCoord2ivARB && bgl::blMultiTexCoord2sARB && bgl::blMultiTexCoord2svARB && bgl::blMultiTexCoord3dARB && bgl::blMultiTexCoord3dvARB && bgl::blMultiTexCoord3fARB && bgl::blMultiTexCoord3fvARB && bgl::blMultiTexCoord3iARB && bgl::blMultiTexCoord3ivARB && bgl::blMultiTexCoord3sARB && bgl::blMultiTexCoord3svARB && bgl::blMultiTexCoord4dARB && bgl::blMultiTexCoord4dvARB && bgl::blMultiTexCoord4fARB && bgl::blMultiTexCoord4fvARB && bgl::blMultiTexCoord4iARB && bgl::blMultiTexCoord4ivARB && bgl::blMultiTexCoord4sARB && bgl::blMultiTexCoord4svARB) {
538                         EnableExtension(_GL_ARB_multitexture);
539                         RAS_EXT_support._ARB_multitexture = 1;
540                         if (doDebugMessages)
541                                 std::cout << "Enabled GL_ARB_multitexture" << std::endl;
542                 } else {
543                         std::cout << "ERROR: GL_ARB_multitexture implementation is broken!" << std::endl;
544                 }
545         }
546 #endif
547
548 #if GL_ARB_shader_objects
549         if (QueryExtension("GL_ARB_shader_objects"))
550         {
551                 bgl::blDeleteObjectARB = reinterpret_cast<PFNGLDELETEOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glDeleteObjectARB"));
552                 bgl::blGetHandleARB = reinterpret_cast<PFNGLGETHANDLEARBPROC>(bglGetProcAddress((const GLubyte *) "glGetHandleARB"));
553                 bgl::blDetachObjectARB = reinterpret_cast<PFNGLDETACHOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glDetachObjectARB"));
554                 bgl::blCreateShaderObjectARB = reinterpret_cast<PFNGLCREATESHADEROBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glCreateShaderObjectARB"));
555                 bgl::blShaderSourceARB = reinterpret_cast<PFNGLSHADERSOURCEARBPROC>(bglGetProcAddress((const GLubyte *) "glShaderSourceARB"));
556                 bgl::blCompileShaderARB = reinterpret_cast<PFNGLCOMPILESHADERARBPROC>(bglGetProcAddress((const GLubyte *) "glCompileShaderARB"));
557                 bgl::blCreateProgramObjectARB = reinterpret_cast<PFNGLCREATEPROGRAMOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glCreateProgramObjectARB"));
558                 bgl::blAttachObjectARB = reinterpret_cast<PFNGLATTACHOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glAttachObjectARB"));
559                 bgl::blLinkProgramARB = reinterpret_cast<PFNGLLINKPROGRAMARBPROC>(bglGetProcAddress((const GLubyte *) "glLinkProgramARB"));
560                 bgl::blUseProgramObjectARB = reinterpret_cast<PFNGLUSEPROGRAMOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glUseProgramObjectARB"));
561                 bgl::blValidateProgramARB = reinterpret_cast<PFNGLVALIDATEPROGRAMARBPROC>(bglGetProcAddress((const GLubyte *) "glValidateProgramARB"));
562                 bgl::blUniform1fARB = reinterpret_cast<PFNGLUNIFORM1FARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform1fARB"));
563                 bgl::blUniform2fARB = reinterpret_cast<PFNGLUNIFORM2FARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform2fARB"));
564                 bgl::blUniform3fARB = reinterpret_cast<PFNGLUNIFORM3FARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform3fARB"));
565                 bgl::blUniform4fARB = reinterpret_cast<PFNGLUNIFORM4FARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform4fARB"));
566                 bgl::blUniform1iARB = reinterpret_cast<PFNGLUNIFORM1IARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform1iARB"));
567                 bgl::blUniform2iARB = reinterpret_cast<PFNGLUNIFORM2IARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform2iARB"));
568                 bgl::blUniform3iARB = reinterpret_cast<PFNGLUNIFORM3IARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform3iARB"));
569                 bgl::blUniform4iARB = reinterpret_cast<PFNGLUNIFORM4IARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform4iARB"));
570                 bgl::blUniform1fvARB = reinterpret_cast<PFNGLUNIFORM1FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform1fvARB"));
571                 bgl::blUniform2fvARB = reinterpret_cast<PFNGLUNIFORM2FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform2fvARB"));
572                 bgl::blUniform3fvARB = reinterpret_cast<PFNGLUNIFORM3FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform3fvARB"));
573                 bgl::blUniform4fvARB = reinterpret_cast<PFNGLUNIFORM4FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform4fvARB"));
574                 bgl::blUniform1ivARB = reinterpret_cast<PFNGLUNIFORM1IVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform1ivARB"));
575                 bgl::blUniform2ivARB = reinterpret_cast<PFNGLUNIFORM2IVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform2ivARB"));
576                 bgl::blUniform3ivARB = reinterpret_cast<PFNGLUNIFORM3IVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform3ivARB"));
577                 bgl::blUniform4ivARB = reinterpret_cast<PFNGLUNIFORM4IVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform4ivARB"));
578                 bgl::blUniformMatrix2fvARB = reinterpret_cast<PFNGLUNIFORMMATRIX2FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniformMatrix2fvARB"));
579                 bgl::blUniformMatrix3fvARB = reinterpret_cast<PFNGLUNIFORMMATRIX3FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniformMatrix3fvARB"));
580                 bgl::blUniformMatrix4fvARB = reinterpret_cast<PFNGLUNIFORMMATRIX4FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniformMatrix4fvARB"));
581                 bgl::blGetObjectParameterfvARB = reinterpret_cast<PFNGLGETOBJECTPARAMETERFVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetObjectParameterfvARB"));
582                 bgl::blGetObjectParameterivARB = reinterpret_cast<PFNGLGETOBJECTPARAMETERIVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetObjectParameterivARB"));
583                 bgl::blGetInfoLogARB = reinterpret_cast<PFNGLGETINFOLOGARBPROC>(bglGetProcAddress((const GLubyte *) "glGetInfoLogARB"));
584                 bgl::blGetAttachedObjectsARB = reinterpret_cast<PFNGLGETATTACHEDOBJECTSARBPROC>(bglGetProcAddress((const GLubyte *) "glGetAttachedObjectsARB"));
585                 bgl::blGetUniformLocationARB = reinterpret_cast<PFNGLGETUNIFORMLOCATIONARBPROC>(bglGetProcAddress((const GLubyte *) "glGetUniformLocationARB"));
586                 bgl::blGetActiveUniformARB = reinterpret_cast<PFNGLGETACTIVEUNIFORMARBPROC>(bglGetProcAddress((const GLubyte *) "glGetActiveUniformARB"));
587                 bgl::blGetUniformfvARB = reinterpret_cast<PFNGLGETUNIFORMFVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetUniformfvARB"));
588                 bgl::blGetUniformivARB = reinterpret_cast<PFNGLGETUNIFORMIVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetUniformivARB"));
589                 bgl::blGetShaderSourceARB = reinterpret_cast<PFNGLGETSHADERSOURCEARBPROC>(bglGetProcAddress((const GLubyte *) "glGetShaderSourceARB"));
590                 if (bgl::blDeleteObjectARB && bgl::blGetHandleARB && bgl::blDetachObjectARB && bgl::blCreateShaderObjectARB && bgl::blShaderSourceARB && bgl::blCompileShaderARB && bgl::blCreateProgramObjectARB && bgl::blAttachObjectARB && bgl::blLinkProgramARB && bgl::blUseProgramObjectARB && bgl::blValidateProgramARB && bgl::blUniform1fARB && bgl::blUniform2fARB && bgl::blUniform3fARB && bgl::blUniform4fARB && bgl::blUniform1iARB && bgl::blUniform2iARB && bgl::blUniform3iARB && bgl::blUniform4iARB && bgl::blUniform1fvARB && bgl::blUniform2fvARB && bgl::blUniform3fvARB && bgl::blUniform4fvARB && bgl::blUniform1ivARB && bgl::blUniform2ivARB && bgl::blUniform3ivARB && bgl::blUniform4ivARB && bgl::blUniformMatrix2fvARB && bgl::blUniformMatrix3fvARB && bgl::blUniformMatrix4fvARB && bgl::blGetObjectParameterfvARB && bgl::blGetObjectParameterivARB && bgl::blGetInfoLogARB && bgl::blGetAttachedObjectsARB && bgl::blGetUniformLocationARB && bgl::blGetActiveUniformARB && bgl::blGetUniformfvARB && bgl::blGetUniformivARB && bgl::blGetShaderSourceARB) {
591                         EnableExtension(_GL_ARB_shader_objects);
592                         RAS_EXT_support._ARB_shader_objects =1;
593                         if (doDebugMessages)
594                                 std::cout << "Enabled GL_ARB_shader_objects" << std::endl;
595                 } else {
596                         std::cout << "ERROR: GL_ARB_shader_objects implementation is broken!" << std::endl;
597                 }
598         }
599 #endif
600
601 #if GL_ARB_vertex_shader
602         if (QueryExtension("GL_ARB_vertex_shader"))
603         {
604                 bgl::blBindAttribLocationARB = reinterpret_cast<PFNGLBINDATTRIBLOCATIONARBPROC>(bglGetProcAddress((const GLubyte *) "glBindAttribLocationARB"));
605                 bgl::blGetActiveAttribARB = reinterpret_cast<PFNGLGETACTIVEATTRIBARBPROC>(bglGetProcAddress((const GLubyte *) "glGetActiveAttribARB"));
606                 bgl::blGetAttribLocationARB = reinterpret_cast<PFNGLGETATTRIBLOCATIONARBPROC>(bglGetProcAddress((const GLubyte *) "glGetAttribLocationARB"));
607                 if (bgl::blBindAttribLocationARB && bgl::blGetActiveAttribARB && bgl::blGetAttribLocationARB) {
608                         EnableExtension(_GL_ARB_vertex_shader);
609                         RAS_EXT_support._ARB_vertex_shader = 1;
610                         if (doDebugMessages)
611                                 std::cout << "Enabled GL_ARB_vertex_shader" << std::endl;
612                 } else {
613                         std::cout << "ERROR: GL_ARB_vertex_shader implementation is broken!" << std::endl;
614                 }
615         }
616 #endif
617
618 #ifdef GL_ARB_fragment_shader
619         if (QueryExtension("GL_ARB_fragment_shader"))
620         {
621                 EnableExtension(_GL_ARB_fragment_shader);
622                 RAS_EXT_support._ARB_fragment_shader = 1;
623                 if (doDebugMessages)
624                         std::cout << "Detected GL_ARB_fragment_shader" << std::endl;
625         }
626 #endif
627
628 #if defined(GL_ARB_vertex_program)
629         if (QueryExtension("GL_ARB_vertex_program"))
630         {
631                 bgl::blVertexAttrib1fARB = reinterpret_cast<PFNGLVERTEXATTRIB1FARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib1fARB"));
632                 bgl::blVertexAttrib1fvARB = reinterpret_cast<PFNGLVERTEXATTRIB1FVARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib1fvARB"));
633                 bgl::blVertexAttrib2fARB = reinterpret_cast<PFNGLVERTEXATTRIB2FARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib2fARB"));
634                 bgl::blVertexAttrib2fvARB = reinterpret_cast<PFNGLVERTEXATTRIB2FVARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib2fvARB"));
635                 bgl::blVertexAttrib3fARB = reinterpret_cast<PFNGLVERTEXATTRIB3FARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib3fARB"));
636                 bgl::blVertexAttrib3fvARB = reinterpret_cast<PFNGLVERTEXATTRIB3FVARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib3fvARB"));
637                 bgl::blVertexAttrib4fARB = reinterpret_cast<PFNGLVERTEXATTRIB4FARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib4fARB"));
638                 bgl::blVertexAttrib4fvARB = reinterpret_cast<PFNGLVERTEXATTRIB4FVARBPROC>(bglGetProcAddress((const GLubyte *) "glVertexAttrib4fvARB"));
639                 bgl::blGetVertexAttribdvARB = reinterpret_cast<PFNGLGETVERTEXATTRIBDVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetVertexAttribdvARB"));
640                 bgl::blGetVertexAttribfvARB = reinterpret_cast<PFNGLGETVERTEXATTRIBFVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetVertexAttribfvARB"));
641                 bgl::blGetVertexAttribivARB = reinterpret_cast<PFNGLGETVERTEXATTRIBIVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetVertexAttribivARB"));
642                 if (bgl::blVertexAttrib1fARB && bgl::blVertexAttrib1fvARB && bgl::blVertexAttrib2fARB && bgl::blVertexAttrib2fvARB && bgl::blVertexAttrib3fARB && bgl::blVertexAttrib3fvARB && bgl::blGetVertexAttribdvARB) {
643                         EnableExtension(_GL_ARB_vertex_program);
644                         RAS_EXT_support._ARB_vertex_program = 1;
645                         if (doDebugMessages)
646                                 std::cout << "Enabled GL_ARB_vertex_program" << std::endl;
647                 } else {
648                         std::cout << "ERROR: GL_ARB_vertex_program implementation is broken!" << std::endl;
649                 }
650         }
651 #endif
652
653
654 #ifdef GL_ARB_depth_texture
655         if (QueryExtension("GL_ARB_depth_texture"))
656         {
657                 EnableExtension(_GL_ARB_depth_texture);
658                 RAS_EXT_support._ARB_depth_texture = 1;
659                 if (doDebugMessages)
660                 {
661                         std::cout << "Detected GL_ARB_depth_texture" << std::endl;
662                 }
663         }
664 #endif
665 /*
666 #ifdef GL_EXT_compiled_vertex_array
667         if (QueryExtension("GL_EXT_compiled_vertex_array"))
668         {
669                 blLockArraysEXT = reinterpret_cast<PFNGLLOCKARRAYSEXTPROC>(bglGetProcAddress((const GLubyte *) "glLockArraysEXT"));
670                 blUnlockArraysEXT = reinterpret_cast<PFNGLUNLOCKARRAYSEXTPROC>(bglGetProcAddress((const GLubyte *) "glUnlockArraysEXT"));
671                 if (blLockArraysEXT && blUnlockArraysEXT) {
672                         EnableExtension(_GL_EXT_compiled_vertex_array);
673                         RAS_EXT_support._EXT_compiled_vertex_array = 1;
674                         if (doDebugMessages)
675                                 std::cout << "Enabled GL_EXT_compiled_vertex_array" << std::endl;
676                 } else {
677                         std::cout << "ERROR: GL_EXT_compiled_vertex_array implementation is broken!" << std::endl;
678                 }
679         }
680 #endif
681 */
682         if (QueryExtension("GL_EXT_separate_specular_color"))
683         {
684                         EnableExtension(_GL_EXT_separate_specular_color);
685                         if (doDebugMessages)
686                                         std::cout << "Detected GL_EXT_separate_specular_color" << std::endl;
687         }
688
689         doDebugMessages = false;
690 }
691