text: //  ---------------------------------------------------------------------------
  //
  //  @file       LoadOGL.cpp
  //  @author     Philippe Decaudin
  //  @license    This file is part of the AntTweakBar library.
  //              For conditions of distribution and use, see License.txt
  //
  //  ---------------------------------------------------------------------------
  
  
  #include "TwPrecomp.h"
  #include "LoadOGL.h"
  
  
  //  ---------------------------------------------------------------------------
  
  #define ANT_NB_OGL_FUNC_MAX 1024
  
  struct COGLFuncRec
  {
      const char *    m_Name;
      GL::PFNOpenGL * m_FuncPtr;
      COGLFuncRec() : m_Name(NULL), m_FuncPtr(NULL) {}
  };
  COGLFuncRec g_OGLFuncRec[ANT_NB_OGL_FUNC_MAX];
  int g_NbOGLFunc = 0;
  #if defined(ANT_WINDOWS)
  HMODULE g_OGLModule = NULL;
  #endif
  
  //  ---------------------------------------------------------------------------
  
  ANT_GL_IMPL(glAccum)
  ANT_GL_IMPL(glAlphaFunc)
  ANT_GL_IMPL(glAreTexturesResident)
  ANT_GL_IMPL(glArrayElement)
  ANT_GL_IMPL(glBegin)
  ANT_GL_IMPL(glBindTexture)
  ANT_GL_IMPL(glBitmap)
  ANT_GL_IMPL(glBlendFunc)
  ANT_GL_IMPL(glCallList)
  ANT_GL_IMPL(glCallLists)
  ANT_GL_IMPL(glClear)
  ANT_GL_IMPL(glClearAccum)
  ANT_GL_IMPL(glClearColor)
  ANT_GL_IMPL(glClearDepth)
  ANT_GL_IMPL(glClearIndex)
  ANT_GL_IMPL(glClearStencil)
  ANT_GL_IMPL(glClipPlane)
  ANT_GL_IMPL(glColor3b)
  ANT_GL_IMPL(glColor3bv)
  ANT_GL_IMPL(glColor3d)
  ANT_GL_IMPL(glColor3dv)
  ANT_GL_IMPL(glColor3f)
  ANT_GL_IMPL(glColor3fv)
  ANT_GL_IMPL(glColor3i)
  ANT_GL_IMPL(glColor3iv)
  ANT_GL_IMPL(glColor3s)
  ANT_GL_IMPL(glColor3sv)
  ANT_GL_IMPL(glColor3ub)
  ANT_GL_IMPL(glColor3ubv)
  ANT_GL_IMPL(glColor3ui)
  ANT_GL_IMPL(glColor3uiv)
  ANT_GL_IMPL(glColor3us)
  ANT_GL_IMPL(glColor3usv)
  ANT_GL_IMPL(glColor4b)
  ANT_GL_IMPL(glColor4bv)
  ANT_GL_IMPL(glColor4d)
  ANT_GL_IMPL(glColor4dv)
  ANT_GL_IMPL(glColor4f)
  ANT_GL_IMPL(glColor4fv)
  ANT_GL_IMPL(glColor4i)
  ANT_GL_IMPL(glColor4iv)
  ANT_GL_IMPL(glColor4s)
  ANT_GL_IMPL(glColor4sv)
  ANT_GL_IMPL(glColor4ub)
  ANT_GL_IMPL(glColor4ubv)
  ANT_GL_IMPL(glColor4ui)
  ANT_GL_IMPL(glColor4uiv)
  ANT_GL_IMPL(glColor4us)
  ANT_GL_IMPL(glColor4usv)
  ANT_GL_IMPL(glColorMask)
  ANT_GL_IMPL(glColorMaterial)
  ANT_GL_IMPL(glColorPointer)
  ANT_GL_IMPL(glCopyPixels)
  ANT_GL_IMPL(glCopyTexImage1D)
  ANT_GL_IMPL(glCopyTexImage2D)
  ANT_GL_IMPL(glCopyTexSubImage1D)
  ANT_GL_IMPL(glCopyTexSubImage2D)
  ANT_GL_IMPL(glCullFace)
  ANT_GL_IMPL(glDeleteLists)
  ANT_GL_IMPL(glDeleteTextures)
  ANT_GL_IMPL(glDepthFunc)
  ANT_GL_IMPL(glDepthMask)
  ANT_GL_IMPL(glDepthRange)
  ANT_GL_IMPL(glDisable)
  ANT_GL_IMPL(glDisableClientState)
  ANT_GL_IMPL(glDrawArrays)
  ANT_GL_IMPL(glDrawBuffer)
  ANT_GL_IMPL(glDrawElements)
  ANT_GL_IMPL(glDrawPixels)
  ANT_GL_IMPL(glEdgeFlag)
  ANT_GL_IMPL(glEdgeFlagPointer)
  ANT_GL_IMPL(glEdgeFlagv)
  ANT_GL_IMPL(glEnable)
  ANT_GL_IMPL(glEnableClientState)
  ANT_GL_IMPL(glEnd)
  ANT_GL_IMPL(glEndList)
  ANT_GL_IMPL(glEvalCoord1d)
  ANT_GL_IMPL(glEvalCoord1dv)
  ANT_GL_IMPL(glEvalCoord1f)
  ANT_GL_IMPL(glEvalCoord1fv)
  ANT_GL_IMPL(glEvalCoord2d)
  ANT_GL_IMPL(glEvalCoord2dv)
  ANT_GL_IMPL(glEvalCoord2f)
  ANT_GL_IMPL(glEvalCoord2fv)
  ANT_GL_IMPL(glEvalMesh1)
  ANT_GL_IMPL(glEvalMesh2)
  ANT_GL_IMPL(glEvalPoint1)
  ANT_GL_IMPL(glEvalPoint2)
  ANT_GL_IMPL(glFeedbackBuffer)
  ANT_GL_IMPL(glFinish)
  ANT_GL_IMPL(glFlush)
  ANT_GL_IMPL(glFogf)
  ANT_GL_IMPL(glFogfv)
  ANT_GL_IMPL(glFogi)
  ANT_GL_IMPL(glFogiv)
  ANT_GL_IMPL(glFrontFace)
  ANT_GL_IMPL(glFrustum)
  ANT_GL_IMPL(glGenLists)
  ANT_GL_IMPL(glGenTextures)
  ANT_GL_IMPL(glGetBooleanv)
  ANT_GL_IMPL(glGetClipPlane)
  ANT_GL_IMPL(glGetDoublev)
  ANT_GL_IMPL(glGetError)
  ANT_GL_IMPL(glGetFloatv)
  ANT_GL_IMPL(glGetIntegerv)
  ANT_GL_IMPL(glGetLightfv)
  ANT_GL_IMPL(glGetLightiv)
  ANT_GL_IMPL(glGetMapdv)
  ANT_GL_IMPL(glGetMapfv)
  ANT_GL_IMPL(glGetMapiv)
  ANT_GL_IMPL(glGetMaterialfv)
  ANT_GL_IMPL(glGetMaterialiv)
  ANT_GL_IMPL(glGetPixelMapfv)
  ANT_GL_IMPL(glGetPixelMapuiv)
  ANT_GL_IMPL(glGetPixelMapusv)
  ANT_GL_IMPL(glGetPointerv)
  ANT_GL_IMPL(glGetPolygonStipple)
  ANT_GL_IMPL(glGetString)
  ANT_GL_IMPL(glGetTexEnvfv)
  ANT_GL_IMPL(glGetTexEnviv)
  ANT_GL_IMPL(glGetTexGendv)
  ANT_GL_IMPL(glGetTexGenfv)
  ANT_GL_IMPL(glGetTexGeniv)
  ANT_GL_IMPL(glGetTexImage)
  ANT_GL_IMPL(glGetTexLevelParameterfv)
  ANT_GL_IMPL(glGetTexLevelParameteriv)
  ANT_GL_IMPL(glGetTexParameterfv)
  ANT_GL_IMPL(glGetTexParameteriv)
  ANT_GL_IMPL(glHint)
  ANT_GL_IMPL(glIndexMask)
  ANT_GL_IMPL(glIndexPointer)
  ANT_GL_IMPL(glIndexd)
  ANT_GL_IMPL(glIndexdv)
  ANT_GL_IMPL(glIndexf)
  ANT_GL_IMPL(glIndexfv)
  ANT_GL_IMPL(glIndexi)
  ANT_GL_IMPL(glIndexiv)
  ANT_GL_IMPL(glIndexs)
  ANT_GL_IMPL(glIndexsv)
  ANT_GL_IMPL(glIndexub)
  ANT_GL_IMPL(glIndexubv)
  ANT_GL_IMPL(glInitNames)
  ANT_GL_IMPL(glInterleavedArrays)
  ANT_GL_IMPL(glIsEnabled)
  ANT_GL_IMPL(glIsList)
  ANT_GL_IMPL(glIsTexture)
  ANT_GL_IMPL(glLightModelf)
  ANT_GL_IMPL(glLightModelfv)
  ANT_GL_IMPL(glLightModeli)
  ANT_GL_IMPL(glLightModeliv)
  ANT_GL_IMPL(glLightf)
  ANT_GL_IMPL(glLightfv)
  ANT_GL_IMPL(glLighti)
  ANT_GL_IMPL(glLightiv)
  ANT_GL_IMPL(glLineStipple)
  ANT_GL_IMPL(glLineWidth)
  ANT_GL_IMPL(glListBase)
  ANT_GL_IMPL(glLoadIdentity)
  ANT_GL_IMPL(glLoadMatrixd)
  ANT_GL_IMPL(glLoadMatrixf)
  ANT_GL_IMPL(glLoadName)
  ANT_GL_IMPL(glLogicOp)
  ANT_GL_IMPL(glMap1d)
  ANT_GL_IMPL(glMap1f)
  ANT_GL_IMPL(glMap2d)
  ANT_GL_IMPL(glMap2f)
  ANT_GL_IMPL(glMapGrid1d)
  ANT_GL_IMPL(glMapGrid1f)
  ANT_GL_IMPL(glMapGrid2d)
  ANT_GL_IMPL(glMapGrid2f)
  ANT_GL_IMPL(glMaterialf)
  ANT_GL_IMPL(glMaterialfv)
  ANT_GL_IMPL(glMateriali)
  ANT_GL_IMPL(glMaterialiv)
  ANT_GL_IMPL(glMatrixMode)
  ANT_GL_IMPL(glMultMatrixd)
  ANT_GL_IMPL(glMultMatrixf)
  ANT_GL_IMPL(glNewList)
  ANT_GL_IMPL(glNormal3b)
  ANT_GL_IMPL(glNormal3bv)
  ANT_GL_IMPL(glNormal3d)
  ANT_GL_IMPL(glNormal3dv)
  ANT_GL_IMPL(glNormal3f)
  ANT_GL_IMPL(glNormal3fv)
  ANT_GL_IMPL(glNormal3i)
  ANT_GL_IMPL(glNormal3iv)
  ANT_GL_IMPL(glNormal3s)
  ANT_GL_IMPL(glNormal3sv)
  ANT_GL_IMPL(glNormalPointer)
  ANT_GL_IMPL(glOrtho)
  ANT_GL_IMPL(glPassThrough)
  ANT_GL_IMPL(glPixelMapfv)
  ANT_GL_IMPL(glPixelMapuiv)
  ANT_GL_IMPL(glPixelMapusv)
  ANT_GL_IMPL(glPixelStoref)
  ANT_GL_IMPL(glPixelStorei)
  ANT_GL_IMPL(glPixelTransferf)
  ANT_GL_IMPL(glPixelTransferi)
  ANT_GL_IMPL(glPixelZoom)
  ANT_GL_IMPL(glPointSize)
  ANT_GL_IMPL(glPolygonMode)
  ANT_GL_IMPL(glPolygonOffset)
  ANT_GL_IMPL(glPolygonStipple)
  ANT_GL_IMPL(glPopAttrib)
  ANT_GL_IMPL(glPopClientAttrib)
  ANT_GL_IMPL(glPopMatrix)
  ANT_GL_IMPL(glPopName)
  ANT_GL_IMPL(glPrioritizeTextures)
  ANT_GL_IMPL(glPushAttrib)
  ANT_GL_IMPL(glPushClientAttrib)
  ANT_GL_IMPL(glPushMatrix)
  ANT_GL_IMPL(glPushName)
  ANT_GL_IMPL(glRasterPos2d)
  ANT_GL_IMPL(glRasterPos2dv)
  ANT_GL_IMPL(glRasterPos2f)
  ANT_GL_IMPL(glRasterPos2fv)
  ANT_GL_IMPL(glRasterPos2i)
  ANT_GL_IMPL(glRasterPos2iv)
  ANT_GL_IMPL(glRasterPos2s)
  ANT_GL_IMPL(glRasterPos2sv)
  ANT_GL_IMPL(glRasterPos3d)
  ANT_GL_IMPL(glRasterPos3dv)
  ANT_GL_IMPL(glRasterPos3f)
  ANT_GL_IMPL(glRasterPos3fv)
  ANT_GL_IMPL(glRasterPos3i)
  ANT_GL_IMPL(glRasterPos3iv)
  ANT_GL_IMPL(glRasterPos3s)
  ANT_GL_IMPL(glRasterPos3sv)
  ANT_GL_IMPL(glRasterPos4d)
  ANT_GL_IMPL(glRasterPos4dv)
  ANT_GL_IMPL(glRasterPos4f)
  ANT_GL_IMPL(glRasterPos4fv)
  ANT_GL_IMPL(glRasterPos4i)
  ANT_GL_IMPL(glRasterPos4iv)
  ANT_GL_IMPL(glRasterPos4s)
  ANT_GL_IMPL(glRasterPos4sv)
  ANT_GL_IMPL(glReadBuffer)
  ANT_GL_IMPL(glReadPixels)
  ANT_GL_IMPL(glRectd)
  ANT_GL_IMPL(glRectdv)
  ANT_GL_IMPL(glRectf)
  ANT_GL_IMPL(glRectfv)
  ANT_GL_IMPL(glRecti)
  ANT_GL_IMPL(glRectiv)
  ANT_GL_IMPL(glRects)
  ANT_GL_IMPL(glRectsv)
  ANT_GL_IMPL(glRenderMode)
  ANT_GL_IMPL(glRotated)
  ANT_GL_IMPL(glRotatef)
  ANT_GL_IMPL(glScaled)
  ANT_GL_IMPL(glScalef)
  ANT_GL_IMPL(glScissor)
  ANT_GL_IMPL(glSelectBuffer)
  ANT_GL_IMPL(glShadeModel)
  ANT_GL_IMPL(glStencilFunc)
  ANT_GL_IMPL(glStencilMask)
  ANT_GL_IMPL(glStencilOp)
  ANT_GL_IMPL(glTexCoord1d)
  ANT_GL_IMPL(glTexCoord1dv)
  ANT_GL_IMPL(glTexCoord1f)
  ANT_GL_IMPL(glTexCoord1fv)
  ANT_GL_IMPL(glTexCoord1i)
  ANT_GL_IMPL(glTexCoord1iv)
  ANT_GL_IMPL(glTexCoord1s)
  ANT_GL_IMPL(glTexCoord1sv)
  ANT_GL_IMPL(glTexCoord2d)
  ANT_GL_IMPL(glTexCoord2dv)
  ANT_GL_IMPL(glTexCoord2f)
  ANT_GL_IMPL(glTexCoord2fv)
  ANT_GL_IMPL(glTexCoord2i)
  ANT_GL_IMPL(glTexCoord2iv)
  ANT_GL_IMPL(glTexCoord2s)
  ANT_GL_IMPL(glTexCoord2sv)
  ANT_GL_IMPL(glTexCoord3d)
  ANT_GL_IMPL(glTexCoord3dv)
  ANT_GL_IMPL(glTexCoord3f)
  ANT_GL_IMPL(glTexCoord3fv)
  ANT_GL_IMPL(glTexCoord3i)
  ANT_GL_IMPL(glTexCoord3iv)
  ANT_GL_IMPL(glTexCoord3s)
  ANT_GL_IMPL(glTexCoord3sv)
  ANT_GL_IMPL(glTexCoord4d)
  ANT_GL_IMPL(glTexCoord4dv)
  ANT_GL_IMPL(glTexCoord4f)
  ANT_GL_IMPL(glTexCoord4fv)
  ANT_GL_IMPL(glTexCoord4i)
  ANT_GL_IMPL(glTexCoord4iv)
  ANT_GL_IMPL(glTexCoord4s)
  ANT_GL_IMPL(glTexCoord4sv)
  ANT_GL_IMPL(glTexCoordPointer)
  ANT_GL_IMPL(glTexEnvf)
  ANT_GL_IMPL(glTexEnvfv)
  ANT_GL_IMPL(glTexEnvi)
  ANT_GL_IMPL(glTexEnviv)
  ANT_GL_IMPL(glTexGend)
  ANT_GL_IMPL(glTexGendv)
  ANT_GL_IMPL(glTexGenf)
  ANT_GL_IMPL(glTexGenfv)
  ANT_GL_IMPL(glTexGeni)
  ANT_GL_IMPL(glTexGeniv)
  ANT_GL_IMPL(glTexImage1D)
  ANT_GL_IMPL(glTexImage2D)
  ANT_GL_IMPL(glTexParameterf)
  ANT_GL_IMPL(glTexParameterfv)
  ANT_GL_IMPL(glTexParameteri)
  ANT_GL_IMPL(glTexParameteriv)
  ANT_GL_IMPL(glTexSubImage1D)
  ANT_GL_IMPL(glTexSubImage2D)
  ANT_GL_IMPL(glTranslated)
  ANT_GL_IMPL(glTranslatef)
  ANT_GL_IMPL(glVertex2d)
  ANT_GL_IMPL(glVertex2dv)
  ANT_GL_IMPL(glVertex2f)
  ANT_GL_IMPL(glVertex2fv)
  ANT_GL_IMPL(glVertex2i)
  ANT_GL_IMPL(glVertex2iv)
  ANT_GL_IMPL(glVertex2s)
  ANT_GL_IMPL(glVertex2sv)
  ANT_GL_IMPL(glVertex3d)
  ANT_GL_IMPL(glVertex3dv)
  ANT_GL_IMPL(glVertex3f)
  ANT_GL_IMPL(glVertex3fv)
  ANT_GL_IMPL(glVertex3i)
  ANT_GL_IMPL(glVertex3iv)
  ANT_GL_IMPL(glVertex3s)
  ANT_GL_IMPL(glVertex3sv)
  ANT_GL_IMPL(glVertex4d)
  ANT_GL_IMPL(glVertex4dv)
  ANT_GL_IMPL(glVertex4f)
  ANT_GL_IMPL(glVertex4fv)
  ANT_GL_IMPL(glVertex4i)
  ANT_GL_IMPL(glVertex4iv)
  ANT_GL_IMPL(glVertex4s)
  ANT_GL_IMPL(glVertex4sv)
  ANT_GL_IMPL(glVertexPointer)
  ANT_GL_IMPL(glViewport)
  #if defined(ANT_WINDOWS)
  ANT_GL_IMPL(wglGetProcAddress)
  #endif
  
  namespace GL { PFNGLGetProcAddress _glGetProcAddress = NULL; }
  
  //  ---------------------------------------------------------------------------
  
  #if defined(ANT_WINDOWS)
  
      //  ---------------------------------------------------------------------------
      
      int LoadOpenGL()
      {
          if( g_OGLModule!=NULL )
          {
              return 1; // "OpenGL library already loaded"
          }
      
          g_OGLModule = LoadLibrary("OPENGL32.DLL");
          if( g_OGLModule )
          {
              // Info(VERB_LOW, "Load %d OpenGL functions", g_NbOGLFunc);
      
              int Res = 1;
              for(int i=0; i<g_NbOGLFunc; ++i)
              {
                  assert(g_OGLFuncRec[i].m_FuncPtr!=NULL);
                  assert(*(g_OGLFuncRec[i].m_FuncPtr)==NULL);
                  assert(g_OGLFuncRec[i].m_Name!=NULL);
                  assert(strlen(g_OGLFuncRec[i].m_Name)>0);
                  *(g_OGLFuncRec[i].m_FuncPtr) = reinterpret_cast<GL::PFNOpenGL>(GetProcAddress(g_OGLModule, g_OGLFuncRec[i].m_Name));
                  if( *(g_OGLFuncRec[i].m_FuncPtr)==NULL )
                      Res = 0; // Error("cannot find OpenGL function");
      
              }
  
              _glGetProcAddress = reinterpret_cast<GL::PFNGLGetProcAddress>(_wglGetProcAddress);
              if( _glGetProcAddress==NULL )
                  Res = 0;
  
              return Res;
          }
          else
          {
              // InternDisplayLastErrorWIN("Cannot load opengl32 DLL", false);
              return 0;   // cannot load DLL
          }
      }
      
      //  ---------------------------------------------------------------------------
      
      int UnloadOpenGL()
      {
          if( g_OGLModule==NULL )
          {
              return 1; // "OpenGL library not loaded"
          }
      
          // Info(VERB_LOW, "Unload %d OpenGL functions", g_NbOGLFunc);
          for(int i=0; i<g_NbOGLFunc; ++i)
          {
              assert(g_OGLFuncRec[i].m_FuncPtr!=NULL);
              assert(*(g_OGLFuncRec[i].m_FuncPtr)!=NULL);
              assert(g_OGLFuncRec[i].m_Name!=NULL);
              assert(strlen(g_OGLFuncRec[i].m_Name)>0);
              *(g_OGLFuncRec[i].m_FuncPtr) = NULL;
          }
          if( FreeLibrary(g_OGLModule) )
          {
              // Info(VERB_LOW, "OpenGL library unloaded");
              g_OGLModule = NULL;
              return 1;
          }
          else
          {
              // InternDisplayLastErrorWIN("Cannot unload opengl32 DLL", false);
              return 0; // cannot unload opengl32.dll
          }
      }
      
      //  ---------------------------------------------------------------------------
      
      namespace GL
      {
      
          PFNOpenGL Record(const char *_FuncName, PFNOpenGL *_FuncPtr)
          {
              if( g_NbOGLFunc>=ANT_NB_OGL_FUNC_MAX )
              {
                  fprintf(stderr, "Too many OpenGL functions declared. Change ANT_NB_OGL_FUNC_MAX.");
                  exit(-1);
              }
      
              g_OGLFuncRec[g_NbOGLFunc].m_Name = _FuncName;
              g_OGLFuncRec[g_NbOGLFunc].m_FuncPtr = _FuncPtr;
              ++g_NbOGLFunc;
      
              return NULL;
          }
      
      } // namespace GL
      
      //  ---------------------------------------------------------------------------
  
  #endif // defined(ANT_WINDOWS)
  
  //  ---------------------------------------------------------------------------
  
  #if defined(ANT_UNIX)
      
      int LoadOpenGL()
      {
          _glGetProcAddress = reinterpret_cast<GL::PFNGLGetProcAddress>(glXGetProcAddressARB);
  
          return 1; // "OpenGL library is statically linked"
      }
      
      int UnloadOpenGL()
      {
          return 1; // "OpenGL library is statically linked"
      }
      
  #elif defined(ANT_OSX)
  
      #include <dlfcn.h>
  
      static void *gl_dyld = NULL;
      static const char *gl_prefix = "_";
      void *NSGLGetProcAddressNew(const GLubyte *name) 
      {
          void *proc=NULL;
          if (gl_dyld == NULL) 
          {
              gl_dyld = dlopen("OpenGL",RTLD_LAZY);
          }
          if (gl_dyld) 
          {
              NSString *sym = [[NSString alloc] initWithFormat: @"%s%s",gl_prefix,name];
              proc = dlsym(gl_dyld,[sym UTF8String]);
              [sym release];
          }
          return proc;
      }
  
      int LoadOpenGL() 
      {
          _glGetProcAddress = reinterpret_cast<GL::PFNGLGetProcAddress>(NSGLGetProcAddressNew);
  		
  		// try to load a symbol
  		if (_glGetProcAddress("glBindBufferARB") == NULL)
  		{
  			// remove the symbols underscore prefix (OSX 10.7 and later)
  			gl_prefix = "";
  			if (_glGetProcAddress("glBindBufferARB") == NULL)
  			{
  				// fail: fall back to underscore 
  		        gl_prefix = "_";
  			}
  		}		
  		
  		return 1;
      }
  
      int UnloadOpenGL() 
      {
         if (gl_dyld) 
         {
             dlclose(gl_dyld);
             gl_dyld = NULL;
         }
         return 1;
     }    
     
  #endif // defined(ANT_UNIX)
  
  //  ---------------------------------------------------------------------------
  