changeset 29939:319b62d55feb

Pass all OpenGL functions through a function pointer indirection. This still needs more work, but should allow supporting e.g. GLX-OpenGL and Win32-OpenGL with a single binary.
author reimar
date Tue, 08 Dec 2009 23:32:51 +0000
parents eb6c70e2cbea
children 25834f2645d0
files libvo/gl_common.c libvo/gl_common.h libvo/vo_gl.c
diffstat 3 files changed, 251 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/gl_common.c	Tue Dec 08 06:42:46 2009 +0000
+++ b/libvo/gl_common.c	Tue Dec 08 23:32:51 2009 +0000
@@ -35,6 +35,47 @@
 #include "gl_common.h"
 #include "libavutil/common.h"
 
+void (APIENTRY *Begin)(GLenum) = glBegin;
+void (APIENTRY *End)(void) = glEnd;
+void (APIENTRY *Viewport)(GLint, GLint, GLsizei, GLsizei) = glViewport;
+void (APIENTRY *MatrixMode)(GLenum) = glMatrixMode;
+void (APIENTRY *LoadIdentity)(void) = glLoadIdentity;
+void (APIENTRY *Scaled)(double, double, double) = glScaled;
+void (APIENTRY *Ortho)(double, double, double, double, double, double) = glOrtho;
+void (APIENTRY *PushMatrix)(void) = glPushMatrix;
+void (APIENTRY *PopMatrix)(void) = glPopMatrix;
+void (APIENTRY *Clear)(GLbitfield) = glClear;
+GLuint (APIENTRY *GenLists)(GLsizei) = glGenLists;
+void (APIENTRY *DeleteLists)(GLuint, GLsizei) = glDeleteLists;
+void (APIENTRY *NewList)(GLuint, GLenum) = glNewList;
+void (APIENTRY *EndList)(void) = glEndList;
+void (APIENTRY *CallList)(GLuint) = glCallList;
+void (APIENTRY *CallLists)(GLsizei, GLenum, const GLvoid *) = glCallLists;
+void (APIENTRY *GenTextures)(GLsizei, GLuint *) = glGenTextures;
+void (APIENTRY *DeleteTextures)(GLsizei, const GLuint *) = glDeleteTextures;
+void (APIENTRY *TexEnvi)(GLenum, GLenum, GLint) = glTexEnvi;
+void (APIENTRY *Color4ub)(GLubyte, GLubyte, GLubyte, GLubyte) = glColor4ub;
+void (APIENTRY *Color3f)(GLfloat, GLfloat, GLfloat) = glColor3f;
+void (APIENTRY *ClearColor)(GLclampf, GLclampf, GLclampf, GLclampf) = glClearColor;
+void (APIENTRY *Enable)(GLenum) = glEnable;
+void (APIENTRY *Disable)(GLenum) = glDisable;
+const GLubyte *(APIENTRY *GetString)(GLenum) = glGetString;
+void (APIENTRY *DrawBuffer)(GLenum) = glDrawBuffer;
+void (APIENTRY *DepthMask)(GLboolean) = glDepthMask;
+void (APIENTRY *BlendFunc)(GLenum, GLenum) = glBlendFunc;
+void (APIENTRY *Flush)(void) = glFlush;
+void (APIENTRY *Finish)(void) = glFinish;
+void (APIENTRY *PixelStorei)(GLenum, GLint) = glPixelStorei;
+void (APIENTRY *TexImage1D)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const GLvoid *) = glTexImage1D;
+void (APIENTRY *TexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *) = glTexImage2D;
+void (APIENTRY *TexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *) = glTexSubImage2D;
+void (APIENTRY *TexParameteri)(GLenum, GLenum, GLint) = glTexParameteri;
+void (APIENTRY *TexParameterf)(GLenum, GLenum, GLfloat) = glTexParameterf;
+void (APIENTRY *TexParameterfv)(GLenum, GLenum, const GLfloat *) = glTexParameterfv;
+void (APIENTRY *TexCoord2f)(GLfloat, GLfloat) = glTexCoord2f;
+void (APIENTRY *Vertex2f)(GLfloat, GLfloat) = glVertex2f;
+void (APIENTRY *GetIntegerv)(GLenum, GLint *) = glGetIntegerv;
+
 /**
  * \defgroup glextfunctions OpenGL extension functions
  *
@@ -106,7 +147,7 @@
     gl_alignment=2;
   else
     gl_alignment=1;
-  glPixelStorei (GL_UNPACK_ALIGNMENT, gl_alignment);
+  PixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment);
 }
 
 struct gl_name_map_struct {
@@ -290,7 +331,52 @@
   const char *funcnames[7];
 } extfunc_desc_t;
 
+#define DEF_FUNC_DESC(name) {&name, NULL, {"gl"#name, NULL}}
 static const extfunc_desc_t extfuncs[] = {
+  // these aren't extension functions but we query them anyway to allow
+  // different "backends" with one binary
+  DEF_FUNC_DESC(Begin),
+  DEF_FUNC_DESC(End),
+  DEF_FUNC_DESC(Viewport),
+  DEF_FUNC_DESC(MatrixMode),
+  DEF_FUNC_DESC(LoadIdentity),
+  DEF_FUNC_DESC(Scaled),
+  DEF_FUNC_DESC(Ortho),
+  DEF_FUNC_DESC(PushMatrix),
+  DEF_FUNC_DESC(PopMatrix),
+  DEF_FUNC_DESC(Clear),
+  DEF_FUNC_DESC(GenLists),
+  DEF_FUNC_DESC(DeleteLists),
+  DEF_FUNC_DESC(NewList),
+  DEF_FUNC_DESC(EndList),
+  DEF_FUNC_DESC(CallList),
+  DEF_FUNC_DESC(CallLists),
+  DEF_FUNC_DESC(GenTextures),
+  DEF_FUNC_DESC(DeleteTextures),
+  DEF_FUNC_DESC(TexEnvi),
+  DEF_FUNC_DESC(Color4ub),
+  DEF_FUNC_DESC(Color3f),
+  DEF_FUNC_DESC(ClearColor),
+  DEF_FUNC_DESC(Enable),
+  DEF_FUNC_DESC(Disable),
+  DEF_FUNC_DESC(GetString),
+  DEF_FUNC_DESC(DrawBuffer),
+  DEF_FUNC_DESC(DepthMask),
+  DEF_FUNC_DESC(BlendFunc),
+  DEF_FUNC_DESC(Flush),
+  DEF_FUNC_DESC(Finish),
+  DEF_FUNC_DESC(PixelStorei),
+  DEF_FUNC_DESC(TexImage1D),
+  DEF_FUNC_DESC(TexImage2D),
+  DEF_FUNC_DESC(TexSubImage2D),
+  DEF_FUNC_DESC(TexParameteri),
+  DEF_FUNC_DESC(TexParameterf),
+  DEF_FUNC_DESC(TexParameterfv),
+  DEF_FUNC_DESC(TexCoord2f),
+  DEF_FUNC_DESC(Vertex2f),
+  DEF_FUNC_DESC(GetIntegerv),
+
+  // here start the real extensions
   {&GenBuffers, NULL, {"glGenBuffers", "glGenBuffersARB", NULL}},
   {&DeleteBuffers, NULL, {"glDeleteBuffers", "glDeleteBuffersARB", NULL}},
   {&BindBuffer, NULL, {"glBindBuffer", "glBindBufferARB", NULL}},
@@ -331,7 +417,7 @@
 static void getFunctions(void *(*getProcAddress)(const GLubyte *),
                          const char *ext2) {
   const extfunc_desc_t *dsc;
-  const char *extensions = (const char *)glGetString(GL_EXTENSIONS);
+  const char *extensions = (const char *)GetString(GL_EXTENSIONS);
   char *allexts;
   if (!extensions) extensions = "";
   if (!ext2) ext2 = "";
@@ -382,16 +468,16 @@
   init = malloc(stride * h);
   memset(init, val, stride * h);
   glAdjustAlignment(stride);
-  glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
-  glTexImage2D(target, 0, fmt, w, h, 0, format, type, init);
-  glTexParameterf(target, GL_TEXTURE_PRIORITY, 1.0);
-  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
-  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
-  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-  glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+  PixelStorei(GL_UNPACK_ROW_LENGTH, w);
+  TexImage2D(target, 0, fmt, w, h, 0, format, type, init);
+  TexParameterf(target, GL_TEXTURE_PRIORITY, 1.0);
+  TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
+  TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
+  TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   // Border texels should not be used with CLAMP_TO_EDGE
   // We set a sane default anyway.
-  glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border);
+  TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border);
   free(init);
 }
 
@@ -539,13 +625,13 @@
   }
   // this is not always correct, but should work for MPlayer
   glAdjustAlignment(stride);
-  glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / glFmt2bpp(format, type));
+  PixelStorei(GL_UNPACK_ROW_LENGTH, stride / glFmt2bpp(format, type));
   for (; y + slice <= y_max; y += slice) {
-    glTexSubImage2D(target, 0, x, y, w, slice, format, type, data);
+    TexSubImage2D(target, 0, x, y, w, slice, format, type, data);
     data += stride * slice;
   }
   if (y < y_max)
-    glTexSubImage2D(target, 0, x, y, w, y_max - y, format, type, data);
+    TexSubImage2D(target, 0, x, y, w, y_max - y, format, type, data);
 }
 
 static void fillUVcoeff(GLfloat *ucoef, GLfloat *vcoef,
@@ -584,11 +670,11 @@
     mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Combiner functions missing!\n");
     return;
   }
-  glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &i);
+  GetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &i);
   if (i < 2)
     mp_msg(MSGT_VO, MSGL_ERR,
            "[gl] 2 general combiners needed for YUV combiner support (found %i)\n", i);
-  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &i);
+  GetIntegerv(GL_MAX_TEXTURE_UNITS, &i);
   if (i < 3)
     mp_msg(MSGT_VO, MSGL_ERR,
            "[gl] 3 texture units needed for YUV combiner support (found %i)\n", i);
@@ -644,11 +730,11 @@
     mp_msg(MSGT_VO, MSGL_FATAL, "[gl] Combiner (ATI) functions missing!\n");
     return;
   }
-  glGetIntegerv(GL_NUM_FRAGMENT_REGISTERS_ATI, &i);
+  GetIntegerv(GL_NUM_FRAGMENT_REGISTERS_ATI, &i);
   if (i < 3)
     mp_msg(MSGT_VO, MSGL_ERR,
            "[gl] 3 registers needed for YUV combiner (ATI) support (found %i)\n", i);
-  glGetIntegerv (GL_MAX_TEXTURE_UNITS, &i);
+  GetIntegerv (GL_MAX_TEXTURE_UNITS, &i);
   if (i < 3)
     mp_msg(MSGT_VO, MSGL_ERR,
            "[gl] 3 texture units needed for YUV combiner (ATI) support (found %i)\n", i);
@@ -710,11 +796,11 @@
   store_weights(0, tex);
   store_weights(1, &tex[4 * (LOOKUP_BSPLINE_RES - 1)]);
   ActiveTexture(unit);
-  glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16, LOOKUP_BSPLINE_RES, 0, GL_RGBA, GL_FLOAT, tex);
-  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_PRIORITY, 1.0);
-  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  TexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16, LOOKUP_BSPLINE_RES, 0, GL_RGBA, GL_FLOAT, tex);
+  TexParameterf(GL_TEXTURE_1D, GL_TEXTURE_PRIORITY, 1.0);
+  TexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  TexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  TexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   ActiveTexture(GL_TEXTURE0);
   free(tex);
 }
@@ -1023,15 +1109,15 @@
         lookup_data = malloc(3 * sz * sz * sz);
         gen_yuv2rgb_map(params, lookup_data, LOOKUP_3DRES);
         glAdjustAlignment(sz);
-        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+        PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
         TexImage3D(GL_TEXTURE_3D, 0, 3, sz, sz, sz, 1,
                    GL_RGB, GL_UNSIGNED_BYTE, lookup_data);
-        glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_PRIORITY, 1.0);
-        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
+        TexParameterf(GL_TEXTURE_3D, GL_TEXTURE_PRIORITY, 1.0);
+        TexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        TexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        TexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+        TexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+        TexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
         ActiveTexture(GL_TEXTURE0);
         texs[0] += '0';
       }
@@ -1157,13 +1243,13 @@
     return 0;
   }
   ProgramString(target, GL_PROGRAM_FORMAT_ASCII, strlen(prog), prog);
-  glGetIntegerv(GL_PROGRAM_ERROR_POSITION, &err);
+  GetIntegerv(GL_PROGRAM_ERROR_POSITION, &err);
   if (err != -1) {
     mp_msg(MSGT_VO, MSGL_ERR,
       "[gl] Error compiling fragment program, make sure your card supports\n"
       "[gl]   GL_ARB_fragment_program (use glxinfo to check).\n"
       "[gl]   Error message:\n  %s at %.10s\n",
-      glGetString(GL_PROGRAM_ERROR_STRING), &prog[err]);
+      GetString(GL_PROGRAM_ERROR_STRING), &prog[err]);
     return 0;
   }
   if (!GetProgramiv || !mp_msg_test(MSGT_VO, MSGL_DBG2))
@@ -1211,7 +1297,7 @@
     memcpy(chrom_scale_texs, lum_scale_texs, sizeof(chrom_scale_texs));
   else
     create_scaler_textures(YUV_CHROM_SCALER(type), &cur_texu, chrom_scale_texs);
-  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &i);
+  GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &i);
   if (i < cur_texu)
     mp_msg(MSGT_VO, MSGL_ERR,
            "[gl] %i texture units needed for this type of YUV fragment support (found %i)\n",
@@ -1328,25 +1414,25 @@
   switch (YUV_CONVERSION(type)) {
     case YUV_CONVERSION_COMBINERS:
       ActiveTexture(GL_TEXTURE1);
-      glEnable(target);
+      Enable(target);
       ActiveTexture(GL_TEXTURE2);
-      glEnable(target);
+      Enable(target);
       ActiveTexture(GL_TEXTURE0);
-      glEnable(GL_REGISTER_COMBINERS_NV);
+      Enable(GL_REGISTER_COMBINERS_NV);
       break;
     case YUV_CONVERSION_COMBINERS_ATI:
       ActiveTexture(GL_TEXTURE1);
-      glEnable(target);
+      Enable(target);
       ActiveTexture(GL_TEXTURE2);
-      glEnable(target);
+      Enable(target);
       ActiveTexture(GL_TEXTURE0);
-      glEnable(GL_FRAGMENT_SHADER_ATI);
+      Enable(GL_FRAGMENT_SHADER_ATI);
       break;
     case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
     case YUV_CONVERSION_FRAGMENT_LOOKUP:
     case YUV_CONVERSION_FRAGMENT_POW:
     case YUV_CONVERSION_FRAGMENT:
-      glEnable(GL_FRAGMENT_PROGRAM);
+      Enable(GL_FRAGMENT_PROGRAM);
       break;
   }
 }
@@ -1362,25 +1448,25 @@
   switch (YUV_CONVERSION(type)) {
     case YUV_CONVERSION_COMBINERS:
       ActiveTexture(GL_TEXTURE1);
-      glDisable(target);
+      Disable(target);
       ActiveTexture(GL_TEXTURE2);
-      glDisable(target);
+      Disable(target);
       ActiveTexture(GL_TEXTURE0);
-      glDisable(GL_REGISTER_COMBINERS_NV);
+      Disable(GL_REGISTER_COMBINERS_NV);
       break;
     case YUV_CONVERSION_COMBINERS_ATI:
       ActiveTexture(GL_TEXTURE1);
-      glDisable(target);
+      Disable(target);
       ActiveTexture(GL_TEXTURE2);
-      glDisable(target);
+      Disable(target);
       ActiveTexture(GL_TEXTURE0);
-      glDisable(GL_FRAGMENT_SHADER_ATI);
+      Disable(GL_FRAGMENT_SHADER_ATI);
       break;
     case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
     case YUV_CONVERSION_FRAGMENT_LOOKUP:
     case YUV_CONVERSION_FRAGMENT_POW:
     case YUV_CONVERSION_FRAGMENT:
-      glDisable(GL_FRAGMENT_PROGRAM);
+      Disable(GL_FRAGMENT_PROGRAM);
       break;
   }
 }
@@ -1414,32 +1500,32 @@
     y += h;
     h = -h;
   }
-  glBegin(GL_QUADS);
-  glTexCoord2f(tx, ty);
+  Begin(GL_QUADS);
+  TexCoord2f(tx, ty);
   if (is_yv12) {
     MultiTexCoord2f(GL_TEXTURE1, tx2, ty2);
     MultiTexCoord2f(GL_TEXTURE2, tx2, ty2);
   }
-  glVertex2f(x, y);
-  glTexCoord2f(tx, ty + th);
+  Vertex2f(x, y);
+  TexCoord2f(tx, ty + th);
   if (is_yv12) {
     MultiTexCoord2f(GL_TEXTURE1, tx2, ty2 + th2);
     MultiTexCoord2f(GL_TEXTURE2, tx2, ty2 + th2);
   }
-  glVertex2f(x, y + h);
-  glTexCoord2f(tx + tw, ty + th);
+  Vertex2f(x, y + h);
+  TexCoord2f(tx + tw, ty + th);
   if (is_yv12) {
     MultiTexCoord2f(GL_TEXTURE1, tx2 + tw2, ty2 + th2);
     MultiTexCoord2f(GL_TEXTURE2, tx2 + tw2, ty2 + th2);
   }
-  glVertex2f(x + w, y + h);
-  glTexCoord2f(tx + tw, ty);
+  Vertex2f(x + w, y + h);
+  TexCoord2f(tx + tw, ty);
   if (is_yv12) {
     MultiTexCoord2f(GL_TEXTURE1, tx2 + tw2, ty2);
     MultiTexCoord2f(GL_TEXTURE2, tx2 + tw2, ty2);
   }
-  glVertex2f(x + w, y);
-  glEnd();
+  Vertex2f(x + w, y);
+  End();
 }
 
 #ifdef GL_WIN32
@@ -1472,7 +1558,7 @@
   // should only be needed when keeping context, but not doing glFinish
   // can cause flickering even when we do not keep it.
   if (*context)
-  glFinish();
+  Finish();
   new_vinfo = GetPixelFormat(windc);
   if (*context && *vinfo && new_vinfo && *vinfo == new_vinfo) {
       // we can keep the wglContext
@@ -1613,7 +1699,7 @@
   // should only be needed when keeping context, but not doing glFinish
   // can cause flickering even when we do not keep it.
   if (*context)
-  glFinish();
+  Finish();
   new_vinfo = getWindowVisualInfo(win);
   if (*context && *vinfo && new_vinfo &&
       (*vinfo)->visualid == new_vinfo->visualid) {
@@ -1691,7 +1777,7 @@
   *vinfo = NULL;
   if (*context)
   {
-    glFinish();
+    Finish();
     glXMakeCurrent(mDisplay, None, NULL);
     glXDestroyContext(mDisplay, *context);
   }
--- a/libvo/gl_common.h	Tue Dec 08 06:42:46 2009 +0000
+++ b/libvo/gl_common.h	Tue Dec 08 23:32:51 2009 +0000
@@ -387,6 +387,47 @@
 int init_mpglcontext(MPGLContext *ctx, enum MPGLType type);
 void uninit_mpglcontext(MPGLContext *ctx);
 
+extern void (APIENTRY *Begin)(GLenum);
+extern void (APIENTRY *End)(void);
+extern void (APIENTRY *Viewport)(GLint, GLint, GLsizei, GLsizei);
+extern void (APIENTRY *MatrixMode)(GLenum);
+extern void (APIENTRY *LoadIdentity)(void);
+extern void (APIENTRY *Scaled)(double, double, double);
+extern void (APIENTRY *Ortho)(double, double, double, double, double, double);
+extern void (APIENTRY *PushMatrix)(void);
+extern void (APIENTRY *PopMatrix)(void);
+extern void (APIENTRY *Clear)(GLbitfield);
+extern GLuint (APIENTRY *GenLists)(GLsizei);
+extern void (APIENTRY *DeleteLists)(GLuint, GLsizei);
+extern void (APIENTRY *NewList)(GLuint, GLenum);
+extern void (APIENTRY *EndList)(void);
+extern void (APIENTRY *CallList)(GLuint);
+extern void (APIENTRY *CallLists)(GLsizei, GLenum, const GLvoid *);
+extern void (APIENTRY *GenTextures)(GLsizei, GLuint *);
+extern void (APIENTRY *DeleteTextures)(GLsizei, const GLuint *);
+extern void (APIENTRY *TexEnvi)(GLenum, GLenum, GLint);
+extern void (APIENTRY *Color4ub)(GLubyte, GLubyte, GLubyte, GLubyte);
+extern void (APIENTRY *Color3f)(GLfloat, GLfloat, GLfloat);
+extern void (APIENTRY *ClearColor)(GLclampf, GLclampf, GLclampf, GLclampf);
+extern void (APIENTRY *Enable)(GLenum);
+extern void (APIENTRY *Disable)(GLenum);
+extern const GLubyte *(APIENTRY *GetString)(GLenum);
+extern void (APIENTRY *DrawBuffer)(GLenum);
+extern void (APIENTRY *DepthMask)(GLboolean);
+extern void (APIENTRY *BlendFunc)(GLenum, GLenum);
+extern void (APIENTRY *Flush)(void);
+extern void (APIENTRY *Finish)(void);
+extern void (APIENTRY *PixelStorei)(GLenum, GLint);
+extern void (APIENTRY *TexImage1D)(GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+extern void (APIENTRY *TexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+extern void (APIENTRY *TexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+extern void (APIENTRY *TexParameteri)(GLenum, GLenum, GLint);
+extern void (APIENTRY *TexParameterf)(GLenum, GLenum, GLfloat);
+extern void (APIENTRY *TexParameterfv)(GLenum, GLenum, const GLfloat *);
+extern void (APIENTRY *TexCoord2f)(GLfloat, GLfloat);
+extern void (APIENTRY *Vertex2f)(GLfloat, GLfloat);
+extern void (APIENTRY *GetIntegerv)(GLenum, GLint *);
+
 extern void (APIENTRY *GenBuffers)(GLsizei, GLuint *);
 extern void (APIENTRY *DeleteBuffers)(GLsizei, const GLuint *);
 extern void (APIENTRY *BindBuffer)(GLenum, GLuint);
--- a/libvo/vo_gl.c	Tue Dec 08 06:42:46 2009 +0000
+++ b/libvo/vo_gl.c	Tue Dec 08 23:32:51 2009 +0000
@@ -149,12 +149,12 @@
   if (WinID >= 0) {
     int top = 0, left = 0, w = x, h = y;
     geometry(&top, &left, &w, &h, vo_screenwidth, vo_screenheight);
-    glViewport(top, left, w, h);
+    Viewport(top, left, w, h);
   } else
-  glViewport( 0, 0, x, y );
+  Viewport( 0, 0, x, y );
 
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
+  MatrixMode(GL_PROJECTION);
+  LoadIdentity();
   ass_border_x = ass_border_y = 0;
   if (aspect_scaling() && use_aspect) {
     int new_w, new_h;
@@ -165,14 +165,14 @@
     new_h += vo_panscan_y;
     scale_x = (GLdouble)new_w / (GLdouble)x;
     scale_y = (GLdouble)new_h / (GLdouble)y;
-    glScaled(scale_x, scale_y, 1);
+    Scaled(scale_x, scale_y, 1);
     ass_border_x = (vo_dwidth - new_w) / 2;
     ass_border_y = (vo_dheight - new_h) / 2;
   }
-  glOrtho(0, image_width, image_height, 0, -1,1);
+  Ortho(0, image_width, image_height, 0, -1,1);
 
-  glMatrixMode(GL_MODELVIEW);
-  glLoadIdentity();
+  MatrixMode(GL_MODELVIEW);
+  LoadIdentity();
 
   if (!scaled_osd) {
 #ifdef CONFIG_FREETYPE
@@ -181,7 +181,7 @@
 #endif
   vo_osd_changed(OSDTYPE_OSD);
   }
-  glClear(GL_COLOR_BUFFER_BIT);
+  Clear(GL_COLOR_BUFFER_BIT);
   redraw();
 }
 
@@ -259,14 +259,14 @@
   int i;
   if (!osdtexCnt)
     return;
-  glDeleteTextures(osdtexCnt, osdtex);
+  DeleteTextures(osdtexCnt, osdtex);
 #ifndef FAST_OSD
-  glDeleteTextures(osdtexCnt, osdatex);
+  DeleteTextures(osdtexCnt, osdatex);
   for (i = 0; i < osdtexCnt; i++)
-    glDeleteLists(osdaDispList[i], 1);
+    DeleteLists(osdaDispList[i], 1);
 #endif
   for (i = 0; i < osdtexCnt; i++)
-    glDeleteLists(osdDispList[i], 1);
+    DeleteLists(osdDispList[i], 1);
   osdtexCnt = 0;
 }
 
@@ -275,10 +275,10 @@
  */
 static void clearEOSD(void) {
   if (eosdDispList)
-    glDeleteLists(eosdDispList, 1);
+    DeleteLists(eosdDispList, 1);
   eosdDispList = 0;
   if (eosdtexCnt)
-    glDeleteTextures(eosdtexCnt, eosdtex);
+    DeleteTextures(eosdtexCnt, eosdtex);
   eosdtexCnt = 0;
   free(eosdtex);
   eosdtex = NULL;
@@ -373,15 +373,15 @@
     glUploadTex(gl_target, GL_ALPHA, GL_UNSIGNED_BYTE, i->bitmap, i->stride,
                 x, y, i->w, i->h, 0);
   }
-  eosdDispList = glGenLists(1);
+  eosdDispList = GenLists(1);
 skip_upload:
-  glNewList(eosdDispList, GL_COMPILE);
+  NewList(eosdDispList, GL_COMPILE);
   tinytexcur = smalltexcur = 0;
   for (i = img, curtex = eosdtex; i; i = i->next) {
     int x = 0, y = 0;
     if (i->w <= 0 || i->h <= 0 || i->stride < i->w)
       continue;
-    glColor4ub(i->color >> 24, (i->color >> 16) & 0xff, (i->color >> 8) & 0xff, 255 - (i->color & 0xff));
+    Color4ub(i->color >> 24, (i->color >> 16) & 0xff, (i->color >> 8) & 0xff, 255 - (i->color & 0xff));
     if (is_tinytex(i, tinytexcur)) {
       tinytex_pos(tinytexcur, &x, &y);
       sx = sy = LARGE_EOSD_TEX_SIZE;
@@ -398,7 +398,7 @@
     }
     glDrawTex(i->dst_x, i->dst_y, i->w, i->h, x, y, i->w, i->h, sx, sy, use_rectangle == 1, 0, 0);
   }
-  glEndList();
+  EndList();
   BindTexture(gl_target, 0);
 }
 
@@ -413,12 +413,12 @@
   while (default_texs[i] != 0)
     i++;
   if (i)
-    glDeleteTextures(i, default_texs);
+    DeleteTextures(i, default_texs);
   default_texs[0] = 0;
   clearOSD();
   clearEOSD();
   if (largeeosdtex[0])
-    glDeleteTextures(2, largeeosdtex);
+    DeleteTextures(2, largeeosdtex);
   largeeosdtex[0] = 0;
   if (DeleteBuffers && gl_buffer)
     DeleteBuffers(1, &gl_buffer);
@@ -437,9 +437,9 @@
 }
 
 static void autodetectGlExtensions(void) {
-  const char *extensions = glGetString(GL_EXTENSIONS);
-  const char *vendor     = glGetString(GL_VENDOR);
-  const char *version    = glGetString(GL_VERSION);
+  const char *extensions = GetString(GL_EXTENSIONS);
+  const char *vendor     = GetString(GL_VENDOR);
+  const char *version    = GetString(GL_VERSION);
   int is_ati = strstr(vendor, "ATI") != NULL;
   int ati_broken_pbo = 0;
   if (is_ati && strncmp(version, "2.1.", 4) == 0) {
@@ -465,20 +465,20 @@
   autodetectGlExtensions();
   texSize(image_width, image_height, &texture_width, &texture_height);
 
-  glDisable(GL_BLEND);
-  glDisable(GL_DEPTH_TEST);
-  glDepthMask(GL_FALSE);
-  glDisable(GL_CULL_FACE);
-  glEnable(gl_target);
-  glDrawBuffer(vo_doublebuffering?GL_BACK:GL_FRONT);
-  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+  Disable(GL_BLEND);
+  Disable(GL_DEPTH_TEST);
+  DepthMask(GL_FALSE);
+  Disable(GL_CULL_FACE);
+  Enable(gl_target);
+  DrawBuffer(vo_doublebuffering?GL_BACK:GL_FRONT);
+  TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
   mp_msg(MSGT_VO, MSGL_V, "[gl] Creating %dx%d texture...\n",
           texture_width, texture_height);
 
   if (image_format == IMGFMT_YV12) {
     int i;
-    glGenTextures(21, default_texs);
+    GenTextures(21, default_texs);
     default_texs[21] = 0;
     for (i = 0; i < 7; i++) {
       ActiveTexture(GL_TEXTURE1 + i);
@@ -513,8 +513,8 @@
 
   resize(d_width, d_height);
 
-  glClearColor( 0.0f,0.0f,0.0f,0.0f );
-  glClear( GL_COLOR_BUFFER_BIT );
+  ClearColor( 0.0f,0.0f,0.0f,0.0f );
+  Clear( GL_COLOR_BUFFER_BIT );
   if (SwapInterval && swap_interval >= 0)
     SwapInterval(swap_interval);
   return 1;
@@ -607,14 +607,14 @@
   }
 
   // create Textures for OSD part
-  glGenTextures(1, &osdtex[osdtexCnt]);
+  GenTextures(1, &osdtex[osdtexCnt]);
   BindTexture(gl_target, osdtex[osdtexCnt]);
   glCreateClearTex(gl_target, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, scale_type, sx, sy, 0);
   glUploadTex(gl_target, GL_LUMINANCE, GL_UNSIGNED_BYTE, src, stride,
               0, 0, w, h, 0);
 
 #ifndef FAST_OSD
-  glGenTextures(1, &osdatex[osdtexCnt]);
+  GenTextures(1, &osdatex[osdtexCnt]);
   BindTexture(gl_target, osdatex[osdtexCnt]);
   glCreateClearTex(gl_target, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, scale_type, sx, sy, 0);
   {
@@ -634,19 +634,19 @@
 
   // Create a list for rendering this OSD part
 #ifndef FAST_OSD
-  osdaDispList[osdtexCnt] = glGenLists(1);
-  glNewList(osdaDispList[osdtexCnt], GL_COMPILE);
+  osdaDispList[osdtexCnt] = GenLists(1);
+  NewList(osdaDispList[osdtexCnt], GL_COMPILE);
   // render alpha
   BindTexture(gl_target, osdatex[osdtexCnt]);
   glDrawTex(x0, y0, w, h, 0, 0, w, h, sx, sy, use_rectangle == 1, 0, 0);
-  glEndList();
+  EndList();
 #endif
-  osdDispList[osdtexCnt] = glGenLists(1);
-  glNewList(osdDispList[osdtexCnt], GL_COMPILE);
+  osdDispList[osdtexCnt] = GenLists(1);
+  NewList(osdDispList[osdtexCnt], GL_COMPILE);
   // render OSD
   BindTexture(gl_target, osdtex[osdtexCnt]);
   glDrawTex(x0, y0, w, h, 0, 0, w, h, sx, sy, use_rectangle == 1, 0, 0);
-  glEndList();
+  EndList();
 
   osdtexCnt++;
 }
@@ -666,10 +666,10 @@
 }
 
 static void do_render(void) {
-//  glEnable(GL_TEXTURE_2D);
-//  glBindTexture(GL_TEXTURE_2D, texture_id);
+//  Enable(GL_TEXTURE_2D);
+//  BindTexture(GL_TEXTURE_2D, texture_id);
 
-  glColor3f(1,1,1);
+  Color3f(1,1,1);
   if (image_format == IMGFMT_YV12)
     glEnableYUVConversion(gl_target, yuvconvtype);
   glDrawTex(0, 0, image_width, image_height,
@@ -688,45 +688,45 @@
   if (((type & 1) && osdtexCnt > 0) || ((type & 2) && eosdDispList)) {
     // set special rendering parameters
     if (!scaled_osd) {
-      glMatrixMode(GL_PROJECTION);
-      glPushMatrix();
-      glLoadIdentity();
-      glOrtho(0, vo_dwidth, vo_dheight, 0, -1, 1);
+      MatrixMode(GL_PROJECTION);
+      PushMatrix();
+      LoadIdentity();
+      Ortho(0, vo_dwidth, vo_dheight, 0, -1, 1);
     }
-    glEnable(GL_BLEND);
+    Enable(GL_BLEND);
     if ((type & 2) && eosdDispList) {
-      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-      glCallList(eosdDispList);
+      BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      CallList(eosdDispList);
     }
     if ((type & 1) && osdtexCnt > 0) {
-      glColor4ub((osd_color >> 16) & 0xff, (osd_color >> 8) & 0xff, osd_color & 0xff, 0xff - (osd_color >> 24));
+      Color4ub((osd_color >> 16) & 0xff, (osd_color >> 8) & 0xff, osd_color & 0xff, 0xff - (osd_color >> 24));
       // draw OSD
 #ifndef FAST_OSD
-      glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
-      glCallLists(osdtexCnt, GL_UNSIGNED_INT, osdaDispList);
+      BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
+      CallLists(osdtexCnt, GL_UNSIGNED_INT, osdaDispList);
 #endif
-      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-      glCallLists(osdtexCnt, GL_UNSIGNED_INT, osdDispList);
+      BlendFunc(GL_SRC_ALPHA, GL_ONE);
+      CallLists(osdtexCnt, GL_UNSIGNED_INT, osdDispList);
     }
     // set rendering parameters back to defaults
-    glDisable(GL_BLEND);
+    Disable(GL_BLEND);
     if (!scaled_osd)
-      glPopMatrix();
+      PopMatrix();
     BindTexture(gl_target, 0);
   }
 }
 
 static void flip_page(void) {
   if (vo_doublebuffering) {
-    if (use_glFinish) glFinish();
+    if (use_glFinish) Finish();
     glctx.swapGlBuffers(&glctx);
     if (aspect_scaling() && use_aspect)
-      glClear(GL_COLOR_BUFFER_BIT);
+      Clear(GL_COLOR_BUFFER_BIT);
   } else {
     do_render();
     do_render_osd(3);
-    if (use_glFinish) glFinish();
-    else glFlush();
+    if (use_glFinish) Finish();
+    else Flush();
   }
 }
 
@@ -882,7 +882,7 @@
   mpi_flipped = stride[0] < 0;
   if (mpi->flags & MP_IMGFLAG_DIRECT) {
     if (mesa_buffer) {
-      glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);
+      PixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);
       w = texture_width;
     } else {
       intptr_t base = (intptr_t)planes[0];
@@ -922,7 +922,7 @@
     ActiveTexture(GL_TEXTURE0);
   }
   if (mpi->flags & MP_IMGFLAG_DIRECT) {
-    if (mesa_buffer) glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 0);
+    if (mesa_buffer) PixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 0);
     else BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
   }
 skip_upload: