
#include <stdlib.h>  /* for exit */
#include <stdio.h>

#include "glprocs.h"

#if !__APPLE__
/* OpenGL 1.3 */
PFNGLACTIVETEXTUREPROC glActiveTexture_;
PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture_;
PFNGLLOADTRANSPOSEMATRIXFPROC glLoadTransposeMatrixf_;

/* OpenGL 1.5 */
PFNGLBINDBUFFERPROC glBindBuffer_;
PFNGLBUFFERDATAPROC glBufferData_;
PFNGLDELETEBUFFERSPROC glDeleteBuffers_;
PFNGLGENBUFFERSPROC glGenBuffers_;
#endif

/* Cross-platform OpenGL extension proc handling. */
#ifdef _WIN32
#  include <windows.h>
#  define GET_PROC_ADDRESS(p)   wglGetProcAddress(p) 
#elif defined(__APPLE__)
/* No need for GetProcAddress */
#else
#  include <string.h>
#  include <GL/glx.h>
#  define GET_PROC_ADDRESS(p)   glXGetProcAddressARB( (const GLubyte *) p) 
#endif

extern const char *myProgramName;

static int
supportsOneDotWhatever(int whatever)
{
  const char *version;
  int major, minor;

  version = (char *) glGetString(GL_VERSION);
  if (sscanf(version, "%d.%d", &major, &minor) == 2) {
    return major > 1 || minor >= whatever;
  }
  return 0;            /* OpenGL version string malformed! */
}

void
init_glprocs(void)
{
  int problems = 0;

  if (!supportsOneDotWhatever(5)) {
    fprintf(stderr, "%s: at least OpenGL 1.5 is required; you have %s\n", myProgramName, glGetString(GL_VERSION));
    exit(1);
  }

#ifdef GET_PROC_ADDRESS

#define LOAD(t,n) \
  n##_ = (t) GET_PROC_ADDRESS(#n); \
  if (0 == n##_) { \
    fprintf(stderr, "%s: could not GetProcAddress for %s from OpenGL\n", myProgramName, #n); \
    problems++; \
  }

  /* Minimal OpenGL 1.3 multitexture API */
  LOAD(PFNGLACTIVETEXTUREPROC,glActiveTexture)
  LOAD(PFNGLCLIENTACTIVETEXTUREPROC,glClientActiveTexture)
  LOAD(PFNGLLOADTRANSPOSEMATRIXFPROC,glLoadTransposeMatrixf);

  /* Minimal OpenGL 1.5 buffer object API */
  LOAD(PFNGLBINDBUFFERPROC,glBindBuffer)
  LOAD(PFNGLBUFFERDATAPROC,glBufferData)
  LOAD(PFNGLDELETEBUFFERSPROC,glDeleteBuffers)
  LOAD(PFNGLGENBUFFERSPROC,glGenBuffers)
#endif

  if (problems) {
    exit(1);
  }
}
