af3a9bca03e86e271236bac03ecd020ed75da43b
[blender.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, &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 static void bglInitEntryPoints (void)
181 {
182         Display *dpy = glXGetCurrentDisplay();
183         std::vector<STR_String> Xextensions = STR_String(glXQueryExtensionsString(dpy, DefaultScreen(dpy))).Explode(' ');
184         if (std::find(Xextensions.begin(), Xextensions.end(), "GLX_ARB_get_proc_address") != Xextensions.end()) 
185         {
186                 void *libGL = dlopen("libGL.so", RTLD_LAZY);
187                 if (libGL)
188                 {
189                         bglGetProcAddress = (PFNBGLXGETPROCADDRESSARBPROC) (dlsym(libGL, "glXGetProcAddressARB"));
190                         dlclose(libGL);
191                         if (!bglGetProcAddress)
192                                 bglGetProcAddress = (PFNBGLXGETPROCADDRESSARBPROC) _getProcAddress;
193                 }
194         }
195 }
196
197 static void bglDeallocEntryPoints (void) {}
198
199 #elif defined(WIN32)
200 static void bglInitEntryPoints (void) {}
201 static void bglDeallocEntryPoints (void) {}
202
203 #define bglGetProcAddress(entry) wglGetProcAddress((LPCSTR) entry)
204
205 #else /* Unknown Platform - disable extensions */
206 static void bglInitEntryPoints (void) {}
207 static void bglDeallocEntryPoints (void) {}
208
209 static void *bglGetProcAddress(const GLubyte* entry)
210 {
211         /* No Extensions! */
212         return NULL;
213 }
214
215 #endif /* End Platform Specific */
216
217 /* -----------------------------------------------------------------------------
218
219    GL Extension Manager.
220 */
221         /* Bit array of available extensions */
222 static std::bitset<bgl::NUM_EXTENSIONS> enabled_extensions;
223 static std::vector<STR_String> extensions;
224 static int m_debug;
225         
226 static void LinkExtensions();
227
228 static void EnableExtension(bgl::ExtensionName name)
229 {
230         unsigned int num = (unsigned int) name;
231         if (num < bgl::NUM_EXTENSIONS)
232                 enabled_extensions.set(num);
233 }
234
235
236 static bool QueryExtension(STR_String extension_name)
237 {
238         return std::find(extensions.begin(), extensions.end(), extension_name) != extensions.end();
239 }
240
241 namespace bgl
242 {
243
244 void InitExtensions(int debug)
245 {
246         m_debug = debug;
247         bglInitEntryPoints (); //init bundle
248         EnableExtension(_BGL_TEST);
249         LinkExtensions();
250         bglDeallocEntryPoints();
251 }
252
253 bool QueryExtension(ExtensionName name)
254 {
255         unsigned int num = (unsigned int) name;
256         if (num < NUM_EXTENSIONS)
257                 return enabled_extensions[num];
258                  
259         return false;
260 }
261
262 bool QueryVersion(int major, int minor)
263 {
264         static int gl_major = 0;
265         static int gl_minor = 0;
266         
267         if (gl_major == 0)
268         {
269                 const char *gl_version_str = (const char *) glGetString(GL_VERSION);
270                 if (!gl_version_str)
271                         return false;
272                 STR_String gl_version = STR_String(gl_version_str);
273                 int i = gl_version.Find('.');
274                 gl_major = gl_version.Left(i).ToInt();
275                 gl_minor = gl_version.Mid(i+1, gl_version.FindOneOf(". ", i+1) - i - 1).ToInt();
276         
277                 static bool doQueryVersion = m_debug;
278                 if (doQueryVersion)
279                 {
280                         doQueryVersion = false;
281                         std::cout << "GL_VERSION: " << gl_major << "." << gl_minor << " (" << gl_version << ")" << std::endl;
282                 }
283         }
284         
285         if (gl_major > major)
286                 return true;
287         
288         if (gl_major == major && gl_minor >= minor)
289                 return true;
290                 
291         return false;
292 }
293
294
295 /*******************************************************************************
296 1. Extension function entry points go here
297
298 Need to #ifdef (compile time test for extension)
299 Add null functions if appropriate
300
301 Some extensions have been incorporated into the core GL, eg Multitexture was 
302 added in GL v1.1.  If Blender calls one of these functions before they are 
303 linked, it will crash.  Even worse, if Blender *indirectly* calls one of these 
304 functions, (ie the GL implementation calls them itself) Blender will crash.
305
306 We fix this by adding them to the bgl namespace - the functions are now 
307 private to the gameengine.  Code can transparently use extensions by adding:
308
309 using namespace bgl;
310
311 to their source.  Cunning like a weasel.
312
313  ******************************************************************************/
314
315 #if defined(PFNGLPNTRIANGLESIATIPROC)
316 PFNGLPNTRIANGLESIATIPROC glPNTrianglesiATI;
317 PFNGLPNTRIANGLESFATIPROC glPNTrianglesfATI;
318 #endif
319
320 BL_EXTInfo RAS_EXT_support;
321
322
323 #ifdef GL_ARB_multitexture
324 int max_texture_units = 2;
325  PFNGLACTIVETEXTUREARBPROC blActiveTextureARB;
326  PFNGLCLIENTACTIVETEXTUREARBPROC blClientActiveTextureARB;
327  PFNGLMULTITEXCOORD1DARBPROC blMultiTexCoord1dARB;
328  PFNGLMULTITEXCOORD1DVARBPROC blMultiTexCoord1dvARB;
329  PFNGLMULTITEXCOORD1FARBPROC blMultiTexCoord1fARB;
330  PFNGLMULTITEXCOORD1FVARBPROC blMultiTexCoord1fvARB;
331  PFNGLMULTITEXCOORD1IARBPROC blMultiTexCoord1iARB;
332  PFNGLMULTITEXCOORD1IVARBPROC blMultiTexCoord1ivARB;
333  PFNGLMULTITEXCOORD1SARBPROC blMultiTexCoord1sARB;
334  PFNGLMULTITEXCOORD1SVARBPROC blMultiTexCoord1svARB;
335  PFNGLMULTITEXCOORD2DARBPROC blMultiTexCoord2dARB;
336  PFNGLMULTITEXCOORD2DVARBPROC blMultiTexCoord2dvARB;
337  PFNGLMULTITEXCOORD2FARBPROC blMultiTexCoord2fARB;
338  PFNGLMULTITEXCOORD2FVARBPROC blMultiTexCoord2fvARB;
339  PFNGLMULTITEXCOORD2IARBPROC blMultiTexCoord2iARB;
340  PFNGLMULTITEXCOORD2IVARBPROC blMultiTexCoord2ivARB;
341  PFNGLMULTITEXCOORD2SARBPROC blMultiTexCoord2sARB;
342  PFNGLMULTITEXCOORD2SVARBPROC blMultiTexCoord2svARB;
343  PFNGLMULTITEXCOORD3DARBPROC blMultiTexCoord3dARB;
344  PFNGLMULTITEXCOORD3DVARBPROC blMultiTexCoord3dvARB;
345  PFNGLMULTITEXCOORD3FARBPROC blMultiTexCoord3fARB;
346  PFNGLMULTITEXCOORD3FVARBPROC blMultiTexCoord3fvARB;
347  PFNGLMULTITEXCOORD3IARBPROC blMultiTexCoord3iARB;
348  PFNGLMULTITEXCOORD3IVARBPROC blMultiTexCoord3ivARB;
349  PFNGLMULTITEXCOORD3SARBPROC blMultiTexCoord3sARB;
350  PFNGLMULTITEXCOORD3SVARBPROC blMultiTexCoord3svARB;
351  PFNGLMULTITEXCOORD4DARBPROC blMultiTexCoord4dARB;
352  PFNGLMULTITEXCOORD4DVARBPROC blMultiTexCoord4dvARB;
353  PFNGLMULTITEXCOORD4FARBPROC blMultiTexCoord4fARB;
354  PFNGLMULTITEXCOORD4FVARBPROC blMultiTexCoord4fvARB;
355  PFNGLMULTITEXCOORD4IARBPROC blMultiTexCoord4iARB;
356  PFNGLMULTITEXCOORD4IVARBPROC blMultiTexCoord4ivARB;
357  PFNGLMULTITEXCOORD4SARBPROC blMultiTexCoord4sARB;
358  PFNGLMULTITEXCOORD4SVARBPROC blMultiTexCoord4svARB;
359 #endif
360
361 #ifdef GL_ARB_shader_objects
362  PFNGLDELETEOBJECTARBPROC blDeleteObjectARB;
363  PFNGLGETHANDLEARBPROC blGetHandleARB;
364  PFNGLDETACHOBJECTARBPROC blDetachObjectARB;
365  PFNGLCREATESHADEROBJECTARBPROC blCreateShaderObjectARB;
366  PFNGLSHADERSOURCEARBPROC blShaderSourceARB;
367  PFNGLCOMPILESHADERARBPROC blCompileShaderARB;
368  PFNGLCREATEPROGRAMOBJECTARBPROC blCreateProgramObjectARB;
369  PFNGLATTACHOBJECTARBPROC blAttachObjectARB;
370  PFNGLLINKPROGRAMARBPROC blLinkProgramARB;
371  PFNGLUSEPROGRAMOBJECTARBPROC blUseProgramObjectARB;
372  PFNGLVALIDATEPROGRAMARBPROC blValidateProgramARB;
373  PFNGLUNIFORM1FARBPROC blUniform1fARB;
374  PFNGLUNIFORM2FARBPROC blUniform2fARB;
375  PFNGLUNIFORM3FARBPROC blUniform3fARB;
376  PFNGLUNIFORM4FARBPROC blUniform4fARB;
377  PFNGLUNIFORM1IARBPROC blUniform1iARB;
378  PFNGLUNIFORM2IARBPROC blUniform2iARB;
379  PFNGLUNIFORM3IARBPROC blUniform3iARB;
380  PFNGLUNIFORM4IARBPROC blUniform4iARB;
381  PFNGLUNIFORM1FVARBPROC blUniform1fvARB;
382  PFNGLUNIFORM2FVARBPROC blUniform2fvARB;
383  PFNGLUNIFORM3FVARBPROC blUniform3fvARB;
384  PFNGLUNIFORM4FVARBPROC blUniform4fvARB;
385  PFNGLUNIFORM1IVARBPROC blUniform1ivARB;
386  PFNGLUNIFORM2IVARBPROC blUniform2ivARB;
387  PFNGLUNIFORM3IVARBPROC blUniform3ivARB;
388  PFNGLUNIFORM4IVARBPROC blUniform4ivARB;
389  PFNGLUNIFORMMATRIX2FVARBPROC blUniformMatrix2fvARB;
390  PFNGLUNIFORMMATRIX3FVARBPROC blUniformMatrix3fvARB;
391  PFNGLUNIFORMMATRIX4FVARBPROC blUniformMatrix4fvARB;
392  PFNGLGETOBJECTPARAMETERFVARBPROC blGetObjectParameterfvARB;
393  PFNGLGETOBJECTPARAMETERIVARBPROC blGetObjectParameterivARB;
394  PFNGLGETINFOLOGARBPROC blGetInfoLogARB;
395  PFNGLGETATTACHEDOBJECTSARBPROC blGetAttachedObjectsARB;
396  PFNGLGETUNIFORMLOCATIONARBPROC blGetUniformLocationARB;
397  PFNGLGETACTIVEUNIFORMARBPROC blGetActiveUniformARB;
398  PFNGLGETUNIFORMFVARBPROC blGetUniformfvARB;
399  PFNGLGETUNIFORMIVARBPROC blGetUniformivARB;
400  PFNGLGETSHADERSOURCEARBPROC blGetShaderSourceARB;
401 #endif
402
403 #ifdef GL_ARB_vertex_shader
404 PFNGLBINDATTRIBLOCATIONARBPROC blBindAttribLocationARB;
405 PFNGLGETACTIVEATTRIBARBPROC blGetActiveAttribARB;
406 PFNGLGETATTRIBLOCATIONARBPROC blGetAttribLocationARB;
407 #endif
408
409 } // namespace bgl
410
411 using namespace bgl;
412 /*******************************************************************************
413 2. Query extension functions here
414
415 Need to #ifdef (compile time test for extension)
416 Use QueryExtension("GL_EXT_name") to test at runtime.
417 Use bglGetProcAddress to find entry point
418 Use EnableExtension(_GL_EXT_...) to allow Blender to use the extension.
419
420  ******************************************************************************/
421 static void LinkExtensions()
422 {
423         static bool doDebugMessages = m_debug;
424         extensions = STR_String((const char *) glGetString(GL_EXTENSIONS)).Explode(' ');
425         RAS_EXT_support = BL_EXTInfo();
426
427 #if defined(PFNGLPNTRIANGLESIATIPROC)
428         if (QueryExtension("GL_ATI_pn_triangles"))
429         {
430                 glPNTrianglesiATI = reinterpret_cast<PFNGLPNTRIANGLESIATIPROC>(bglGetProcAddress((const GLubyte *) "glPNTrianglesiATI"));
431                 glPNTrianglesfATI = reinterpret_cast<PFNGLPNTRIANGLESFATIPROC>(bglGetProcAddress((const GLubyte *) "glPNTrianglesfATI"));
432                 if (glPNTrianglesiATI && glPNTrianglesfATI) {
433                         EnableExtension(_GL_ATI_pn_triangles);
434                         if (doDebugMessages)
435                                 std::cout << "Enabled GL_ATI_pn_triangles" << std::endl;
436                 } else {
437                         std::cout << "ERROR: GL_ATI_pn_triangles implementation is broken!" << std::endl;
438                 }
439         }
440 #endif
441
442 #ifdef GL_ARB_texture_env_combine
443         if (QueryExtension("GL_ARB_texture_env_combine"))
444         {
445                 EnableExtension(_GL_ARB_texture_env_combine);
446                 RAS_EXT_support._ARB_texture_env_combine = 1;
447                 if (doDebugMessages)
448                 {
449                         std::cout << "Detected GL_ARB_texture_env_combine" << std::endl;
450                 }
451         }
452 #endif
453
454 #ifdef GL_ARB_texture_cube_map
455         if (QueryExtension("GL_ARB_texture_cube_map"))
456         {
457                 EnableExtension(_GL_ARB_texture_cube_map);
458                 RAS_EXT_support._ARB_texture_cube_map = 1;
459                 if (doDebugMessages)
460                         std::cout << "Detected GL_ARB_texture_cube_map" << std::endl;
461         }
462 #endif
463
464 #ifdef GL_ARB_multitexture
465         if (QueryExtension("GL_ARB_multitexture"))
466         {
467                 bgl::blActiveTextureARB = reinterpret_cast<PFNGLACTIVETEXTUREARBPROC>(bglGetProcAddress((const GLubyte *) "glActiveTextureARB"));
468                 bgl::blClientActiveTextureARB = reinterpret_cast<PFNGLCLIENTACTIVETEXTUREARBPROC>(bglGetProcAddress((const GLubyte *) "glClientActiveTextureARB"));
469                 bgl::blMultiTexCoord1dARB = reinterpret_cast<PFNGLMULTITEXCOORD1DARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1dARB"));
470                 bgl::blMultiTexCoord1dvARB = reinterpret_cast<PFNGLMULTITEXCOORD1DVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1dvARB"));
471                 bgl::blMultiTexCoord1fARB = reinterpret_cast<PFNGLMULTITEXCOORD1FARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1fARB"));
472                 bgl::blMultiTexCoord1fvARB = reinterpret_cast<PFNGLMULTITEXCOORD1FVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1fvARB"));
473                 bgl::blMultiTexCoord1iARB = reinterpret_cast<PFNGLMULTITEXCOORD1IARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1iARB"));
474                 bgl::blMultiTexCoord1ivARB = reinterpret_cast<PFNGLMULTITEXCOORD1IVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1ivARB"));
475                 bgl::blMultiTexCoord1sARB = reinterpret_cast<PFNGLMULTITEXCOORD1SARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1sARB"));
476                 bgl::blMultiTexCoord1svARB = reinterpret_cast<PFNGLMULTITEXCOORD1SVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord1svARB"));
477                 bgl::blMultiTexCoord2dARB = reinterpret_cast<PFNGLMULTITEXCOORD2DARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2dARB"));
478                 bgl::blMultiTexCoord2dvARB = reinterpret_cast<PFNGLMULTITEXCOORD2DVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2dvARB"));
479                 bgl::blMultiTexCoord2fARB = reinterpret_cast<PFNGLMULTITEXCOORD2FARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2fARB"));
480                 bgl::blMultiTexCoord2fvARB = reinterpret_cast<PFNGLMULTITEXCOORD2FVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2fvARB"));
481                 bgl::blMultiTexCoord2iARB = reinterpret_cast<PFNGLMULTITEXCOORD2IARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2iARB"));
482                 bgl::blMultiTexCoord2ivARB = reinterpret_cast<PFNGLMULTITEXCOORD2IVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2ivARB"));
483                 bgl::blMultiTexCoord2sARB = reinterpret_cast<PFNGLMULTITEXCOORD2SARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2sARB"));
484                 bgl::blMultiTexCoord2svARB = reinterpret_cast<PFNGLMULTITEXCOORD2SVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord2svARB"));
485                 bgl::blMultiTexCoord3dARB = reinterpret_cast<PFNGLMULTITEXCOORD3DARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3dARB"));
486                 bgl::blMultiTexCoord3dvARB = reinterpret_cast<PFNGLMULTITEXCOORD3DVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3dvARB"));
487                 bgl::blMultiTexCoord3fARB = reinterpret_cast<PFNGLMULTITEXCOORD3FARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3fARB"));
488                 bgl::blMultiTexCoord3fvARB = reinterpret_cast<PFNGLMULTITEXCOORD3FVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3fvARB"));
489                 bgl::blMultiTexCoord3iARB = reinterpret_cast<PFNGLMULTITEXCOORD3IARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3iARB"));
490                 bgl::blMultiTexCoord3ivARB = reinterpret_cast<PFNGLMULTITEXCOORD3IVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3ivARB"));
491                 bgl::blMultiTexCoord3sARB = reinterpret_cast<PFNGLMULTITEXCOORD3SARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3sARB"));
492                 bgl::blMultiTexCoord3svARB = reinterpret_cast<PFNGLMULTITEXCOORD3SVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord3svARB"));
493                 bgl::blMultiTexCoord4dARB = reinterpret_cast<PFNGLMULTITEXCOORD4DARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4dARB"));
494                 bgl::blMultiTexCoord4dvARB = reinterpret_cast<PFNGLMULTITEXCOORD4DVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4dvARB"));
495                 bgl::blMultiTexCoord4fARB = reinterpret_cast<PFNGLMULTITEXCOORD4FARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4fARB"));
496                 bgl::blMultiTexCoord4fvARB = reinterpret_cast<PFNGLMULTITEXCOORD4FVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4fvARB"));
497                 bgl::blMultiTexCoord4iARB = reinterpret_cast<PFNGLMULTITEXCOORD4IARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4iARB"));
498                 bgl::blMultiTexCoord4ivARB = reinterpret_cast<PFNGLMULTITEXCOORD4IVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4ivARB"));
499                 bgl::blMultiTexCoord4sARB = reinterpret_cast<PFNGLMULTITEXCOORD4SARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4sARB"));
500                 bgl::blMultiTexCoord4svARB = reinterpret_cast<PFNGLMULTITEXCOORD4SVARBPROC>(bglGetProcAddress((const GLubyte *) "glMultiTexCoord4svARB"));
501                 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) {
502                         EnableExtension(_GL_ARB_multitexture);
503                         RAS_EXT_support._ARB_multitexture = 1;
504                         if (doDebugMessages)
505                                 std::cout << "Enabled GL_ARB_multitexture" << std::endl;
506                 } else {
507                         std::cout << "ERROR: GL_ARB_multitexture implementation is broken!" << std::endl;
508                 }
509         }
510 #endif
511
512 #if GL_ARB_shader_objects
513         if (QueryExtension("GL_ARB_shader_objects"))
514         {
515                 bgl::blDeleteObjectARB = reinterpret_cast<PFNGLDELETEOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glDeleteObjectARB"));
516                 bgl::blGetHandleARB = reinterpret_cast<PFNGLGETHANDLEARBPROC>(bglGetProcAddress((const GLubyte *) "glGetHandleARB"));
517                 bgl::blDetachObjectARB = reinterpret_cast<PFNGLDETACHOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glDetachObjectARB"));
518                 bgl::blCreateShaderObjectARB = reinterpret_cast<PFNGLCREATESHADEROBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glCreateShaderObjectARB"));
519                 bgl::blShaderSourceARB = reinterpret_cast<PFNGLSHADERSOURCEARBPROC>(bglGetProcAddress((const GLubyte *) "glShaderSourceARB"));
520                 bgl::blCompileShaderARB = reinterpret_cast<PFNGLCOMPILESHADERARBPROC>(bglGetProcAddress((const GLubyte *) "glCompileShaderARB"));
521                 bgl::blCreateProgramObjectARB = reinterpret_cast<PFNGLCREATEPROGRAMOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glCreateProgramObjectARB"));
522                 bgl::blAttachObjectARB = reinterpret_cast<PFNGLATTACHOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glAttachObjectARB"));
523                 bgl::blLinkProgramARB = reinterpret_cast<PFNGLLINKPROGRAMARBPROC>(bglGetProcAddress((const GLubyte *) "glLinkProgramARB"));
524                 bgl::blUseProgramObjectARB = reinterpret_cast<PFNGLUSEPROGRAMOBJECTARBPROC>(bglGetProcAddress((const GLubyte *) "glUseProgramObjectARB"));
525                 bgl::blValidateProgramARB = reinterpret_cast<PFNGLVALIDATEPROGRAMARBPROC>(bglGetProcAddress((const GLubyte *) "glValidateProgramARB"));
526                 bgl::blUniform1fARB = reinterpret_cast<PFNGLUNIFORM1FARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform1fARB"));
527                 bgl::blUniform2fARB = reinterpret_cast<PFNGLUNIFORM2FARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform2fARB"));
528                 bgl::blUniform3fARB = reinterpret_cast<PFNGLUNIFORM3FARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform3fARB"));
529                 bgl::blUniform4fARB = reinterpret_cast<PFNGLUNIFORM4FARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform4fARB"));
530                 bgl::blUniform1iARB = reinterpret_cast<PFNGLUNIFORM1IARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform1iARB"));
531                 bgl::blUniform2iARB = reinterpret_cast<PFNGLUNIFORM2IARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform2iARB"));
532                 bgl::blUniform3iARB = reinterpret_cast<PFNGLUNIFORM3IARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform3iARB"));
533                 bgl::blUniform4iARB = reinterpret_cast<PFNGLUNIFORM4IARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform4iARB"));
534                 bgl::blUniform1fvARB = reinterpret_cast<PFNGLUNIFORM1FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform1fvARB"));
535                 bgl::blUniform2fvARB = reinterpret_cast<PFNGLUNIFORM2FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform2fvARB"));
536                 bgl::blUniform3fvARB = reinterpret_cast<PFNGLUNIFORM3FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform3fvARB"));
537                 bgl::blUniform4fvARB = reinterpret_cast<PFNGLUNIFORM4FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform4fvARB"));
538                 bgl::blUniform1ivARB = reinterpret_cast<PFNGLUNIFORM1IVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform1ivARB"));
539                 bgl::blUniform2ivARB = reinterpret_cast<PFNGLUNIFORM2IVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform2ivARB"));
540                 bgl::blUniform3ivARB = reinterpret_cast<PFNGLUNIFORM3IVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform3ivARB"));
541                 bgl::blUniform4ivARB = reinterpret_cast<PFNGLUNIFORM4IVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniform4ivARB"));
542                 bgl::blUniformMatrix2fvARB = reinterpret_cast<PFNGLUNIFORMMATRIX2FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniformMatrix2fvARB"));
543                 bgl::blUniformMatrix3fvARB = reinterpret_cast<PFNGLUNIFORMMATRIX3FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniformMatrix3fvARB"));
544                 bgl::blUniformMatrix4fvARB = reinterpret_cast<PFNGLUNIFORMMATRIX4FVARBPROC>(bglGetProcAddress((const GLubyte *) "glUniformMatrix4fvARB"));
545                 bgl::blGetObjectParameterfvARB = reinterpret_cast<PFNGLGETOBJECTPARAMETERFVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetObjectParameterfvARB"));
546                 bgl::blGetObjectParameterivARB = reinterpret_cast<PFNGLGETOBJECTPARAMETERIVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetObjectParameterivARB"));
547                 bgl::blGetInfoLogARB = reinterpret_cast<PFNGLGETINFOLOGARBPROC>(bglGetProcAddress((const GLubyte *) "glGetInfoLogARB"));
548                 bgl::blGetAttachedObjectsARB = reinterpret_cast<PFNGLGETATTACHEDOBJECTSARBPROC>(bglGetProcAddress((const GLubyte *) "glGetAttachedObjectsARB"));
549                 bgl::blGetUniformLocationARB = reinterpret_cast<PFNGLGETUNIFORMLOCATIONARBPROC>(bglGetProcAddress((const GLubyte *) "glGetUniformLocationARB"));
550                 bgl::blGetActiveUniformARB = reinterpret_cast<PFNGLGETACTIVEUNIFORMARBPROC>(bglGetProcAddress((const GLubyte *) "glGetActiveUniformARB"));
551                 bgl::blGetUniformfvARB = reinterpret_cast<PFNGLGETUNIFORMFVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetUniformfvARB"));
552                 bgl::blGetUniformivARB = reinterpret_cast<PFNGLGETUNIFORMIVARBPROC>(bglGetProcAddress((const GLubyte *) "glGetUniformivARB"));
553                 bgl::blGetShaderSourceARB = reinterpret_cast<PFNGLGETSHADERSOURCEARBPROC>(bglGetProcAddress((const GLubyte *) "glGetShaderSourceARB"));
554                 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) {
555                         EnableExtension(_GL_ARB_shader_objects);
556                         RAS_EXT_support._ARB_shader_objects =1;
557                         if (doDebugMessages)
558                                 std::cout << "Enabled GL_ARB_shader_objects" << std::endl;
559                 } else {
560                         std::cout << "ERROR: GL_ARB_shader_objects implementation is broken!" << std::endl;
561                 }
562         }
563 #endif
564
565 #if GL_ARB_vertex_shader
566         if (QueryExtension("GL_ARB_vertex_shader"))
567         {
568                 bgl::blBindAttribLocationARB = reinterpret_cast<PFNGLBINDATTRIBLOCATIONARBPROC>(bglGetProcAddress((const GLubyte *) "glBindAttribLocationARB"));
569                 bgl::blGetActiveAttribARB = reinterpret_cast<PFNGLGETACTIVEATTRIBARBPROC>(bglGetProcAddress((const GLubyte *) "glGetActiveAttribARB"));
570                 bgl::blGetAttribLocationARB = reinterpret_cast<PFNGLGETATTRIBLOCATIONARBPROC>(bglGetProcAddress((const GLubyte *) "glGetAttribLocationARB"));
571                 if (bgl::blBindAttribLocationARB && bgl::blGetActiveAttribARB && bgl::blGetAttribLocationARB) {
572                         EnableExtension(_GL_ARB_vertex_shader);
573                         RAS_EXT_support._ARB_vertex_shader = 1;
574                         if (doDebugMessages)
575                                 std::cout << "Enabled GL_ARB_vertex_shader" << std::endl;
576                 } else {
577                         std::cout << "ERROR: GL_ARB_vertex_shader implementation is broken!" << std::endl;
578                 }
579         }
580 #endif
581
582 #ifdef GL_ARB_fragment_shader
583         if (QueryExtension("GL_ARB_fragment_shader"))
584         {
585                 EnableExtension(_GL_ARB_fragment_shader);
586                 RAS_EXT_support._ARB_fragment_shader = 1;
587                 if (doDebugMessages)
588                         std::cout << "Detected GL_ARB_fragment_shader" << std::endl;
589         }
590 #endif
591
592         if (QueryExtension("GL_EXT_separate_specular_color"))
593         {
594                         EnableExtension(_GL_EXT_separate_specular_color);
595                         if (doDebugMessages)
596                                         std::cout << "Detected GL_EXT_separate_specular_color" << std::endl;
597         }
598
599         doDebugMessages = false;
600 }
601