bool GLRenderCallCache::Init()
{
    //Return if we cannot make OpenGL calls
    if(!gliCallBacks->GetGLInternalCallState())
    {
        return false;
    }

    //Test extension support
    float glVersion = gliCallBacks->GetGLVersion();
    if(glVersion < 1.4f)
    {
        LOGERR(("GLRenderCallCache::Init - Need OpenGL 1.4 implementation to use render call cache"));
        return false;
    }


    void **loadFunc;

    //Helper define for function lookups

#define GL_FUNC_LOOKUP(string)                           \
  loadFunc  = (void**)(&i##string);                      \
  *loadFunc = gliCallBacks->GetGLFunction(#string);      \
  if(*loadFunc == NULL)                                  \
  {                                                      \
    LOGERR(("Function %s unable to be mapped",#string)); \
    return false;                                        \
  }

    //Init function pointers
    GL_FUNC_LOOKUP(glDrawRangeElements);
    GL_FUNC_LOOKUP(glMultiDrawArrays);
    GL_FUNC_LOOKUP(glMultiDrawElements);

#undef GL_FUNC_LOOKUP


#define FUNC_REGISTER(function, token)        \
  gliCallBacks->RegisterGLFunction(function); \
  gliCallBacks->SetFunctionID(function, token);

    FUNC_REGISTER("glDrawArrays",  CBI_glDrawArrays);
    FUNC_REGISTER("glDrawElements",CBI_glDrawElements);

    FUNC_REGISTER("glDrawRangeElements",   CBI_glDrawRangeElements);
    FUNC_REGISTER("glDrawRangeElementsEXT",CBI_glDrawRangeElements);

    FUNC_REGISTER("glMultiDrawArrays",   CBI_glMultiDrawArrays);
    FUNC_REGISTER("glMultiDrawArraysEXT",CBI_glMultiDrawArrays);

    FUNC_REGISTER("glMultiDrawElements",   CBI_glMultiDrawElements);
    FUNC_REGISTER("glMultiDrawElementsEXT",CBI_glMultiDrawElements);

#undef FUNC_REGISTER

    return true;
}
bool SubstituteShaderGLSL::Init(GLuint oldProgram, string &initLog)
{
  //Check the program ID's
  if(oldProgram == 0 || programID == 0)
  {
    return false;
  }

  //Assign the old program ID
  oldProgramID = oldProgram;

  //Check if GL calls can be made
  if(!gliCallBacks->GetGLInternalCallState())
  {
    return false;
  }

  //Only allow usage of the 2.0 interfaces
  if(gliCallBacks->GetGLVersion() < 2.0)
  {
    return false;
  }

  //Init the shader utils object
  if(!shaderUtils.Init())
  {
    return false;
  }

  void **loadFunc;

  //Helper define for function lookups
#define GL_FUNC_LOOKUP(string)                           \
  loadFunc  = (void**)(&i##string);                      \
  *loadFunc = gliCallBacks->GetGLFunction(#string); \
  if(*loadFunc == NULL)                                  \
  {                                                      \
    LOGERR(("Function %s unable to be mapped",#string)); \
    return false;                                        \
  }                                                    

  GL_FUNC_LOOKUP(glUseProgram);
  GL_FUNC_LOOKUP(glDeleteProgram);

#undef GL_FUNC_LOOKUP

  //Generate the lookup table of values to copy
  string uniformLog;
  GenerateUniformRemapArray(uniformLog);
  if(uniformLog.size() > 0)
  {
    initLog += "New program uniform mismatchs:\n\n";
    initLog += uniformLog;
    initLog += "\n";
  }

  return true;
}
bool ShaderUtilsGLSL::Init()
{
  //Check if GL calls can be made
  if(!gliCallBacks->GetGLInternalCallState())
  {
    return false;
  }

  //Only allow usage of the 2.0 interfaces
  if(gliCallBacks->GetGLVersion() < 2.0)
  {
    return false;
  }

  void **loadFunc;

  //Helper define for function lookups
#define GL_FUNC_LOOKUP(string)                           \
  loadFunc  = (void**)(&i##string);                      \
  *loadFunc = gliCallBacks->GetGLFunction(#string); \
  if(*loadFunc == NULL)                                  \
  {                                                      \
    LOGERR(("Function %s unable to be mapped",#string)); \
    return false;                                        \
  }                                                    

  GL_FUNC_LOOKUP(glGetProgramiv);
  GL_FUNC_LOOKUP(glGetActiveUniform);
  GL_FUNC_LOOKUP(glGetUniformLocation);
  GL_FUNC_LOOKUP(glGetUniformfv);
  GL_FUNC_LOOKUP(glGetUniformiv);

  GL_FUNC_LOOKUP(glUniform1fv);
  GL_FUNC_LOOKUP(glUniform2fv);
  GL_FUNC_LOOKUP(glUniform3fv);
  GL_FUNC_LOOKUP(glUniform4fv);
  GL_FUNC_LOOKUP(glUniformMatrix2fv);
  GL_FUNC_LOOKUP(glUniformMatrix3fv);
  GL_FUNC_LOOKUP(glUniformMatrix4fv);
  GL_FUNC_LOOKUP(glUniform1iv);
  GL_FUNC_LOOKUP(glUniform2iv);
  GL_FUNC_LOOKUP(glUniform3iv);
  GL_FUNC_LOOKUP(glUniform4iv);

  if(gliCallBacks->GetGLVersion() >= 2.1)
  {
    GL_FUNC_LOOKUP(glUniformMatrix2x3fv);
    GL_FUNC_LOOKUP(glUniformMatrix2x4fv);
    GL_FUNC_LOOKUP(glUniformMatrix3x2fv);
    GL_FUNC_LOOKUP(glUniformMatrix3x4fv);
    GL_FUNC_LOOKUP(glUniformMatrix4x2fv);
    GL_FUNC_LOOKUP(glUniformMatrix4x3fv);
  }

  if(gliCallBacks->GetGLVersion() >= 3.0)
  {
    GL_FUNC_LOOKUP(glGetUniformuiv);
    GL_FUNC_LOOKUP(glUniform1uiv);
    GL_FUNC_LOOKUP(glUniform2uiv);
    GL_FUNC_LOOKUP(glUniform3uiv);
    GL_FUNC_LOOKUP(glUniform4uiv);
  }

#undef GL_FUNC_LOOKUP

  return true;
}
bool ShaderEditASM::Init()
{
  //Return if we cannot make OpenGL calls
  if(!gliCallBacks->GetGLInternalCallState())
  {
    return false;
  }

  //Check extension support
  extensionARBVertexProgram   = gliCallBacks->IsGLExtensionSupported("GL_ARB_vertex_program");
  extensionNVVertexProgram    = gliCallBacks->IsGLExtensionSupported("GL_NV_vertex_program"); 
  extensionARBFragmentProgram = gliCallBacks->IsGLExtensionSupported("GL_ARB_fragment_program"); 
  extensionNVFragmentProgram  = gliCallBacks->IsGLExtensionSupported("GL_NV_fragment_program"); 

  //Check that at least some ASM shaders are supported
  if(!extensionARBVertexProgram   && !extensionNVVertexProgram &&
     !extensionARBFragmentProgram && !extensionNVFragmentProgram)
  {
    LOGERR(("ShaderEditASM::Init - No asm OpenGL extension support."));
    return false;
  }

  //Init function pointers
  // (this can be done as these functions will only be called on valid programs)
  iglGetProgramiv = (void (GLAPIENTRY *)(GLenum target, GLenum pname, GLint *params))gliCallBacks->GetGLFunction("glGetProgramivARB");  
  if((extensionARBVertexProgram || extensionARBFragmentProgram) && 
    iglGetProgramiv == NULL)
  {
    LOGERR(("ShaderEditASM::Init - Unable to get ARB shader function entry point."));
    return false;
  }

  void **loadFunc;

  //Helper define for function lookups
#define GL_FUNC_LOOKUP(string)                           \
  loadFunc  = (void**)(&i##string);                      \
  *loadFunc = gliCallBacks->GetGLFunction(#string);      \
  if(*loadFunc == NULL)                                  \
  {                                                      \
    LOGERR(("Function %s unable to be mapped",#string)); \
    return false;                                        \
  }

  //Load the ARB extension entry points
  if(extensionARBVertexProgram || extensionARBFragmentProgram)
  {
    GL_FUNC_LOOKUP(glGenProgramsARB);
    GL_FUNC_LOOKUP(glBindProgramARB);
    GL_FUNC_LOOKUP(glProgramStringARB);
    GL_FUNC_LOOKUP(glDeleteProgramsARB);
  }

  //Load the NV extension entry points
  if(extensionNVVertexProgram || extensionNVFragmentProgram)
  {
    GL_FUNC_LOOKUP(glGenProgramsNV);
    GL_FUNC_LOOKUP(glBindProgramNV);
    GL_FUNC_LOOKUP(glLoadProgramNV);
    GL_FUNC_LOOKUP(glDeleteProgramsNV);
  }

#undef GL_FUNC_LOOKUP

  //Register the shader based functions
  gliCallBacks->RegisterGLFunction("glGenProgramsARB");
  gliCallBacks->RegisterGLFunction("glGenProgramsNV");
  gliCallBacks->SetFunctionID("glGenProgramsARB",CBI_glGenPrograms);
  gliCallBacks->SetFunctionID("glGenProgramsNV", CBI_glGenPrograms);

  gliCallBacks->RegisterGLFunction("glDeleteProgramsARB");
  gliCallBacks->RegisterGLFunction("glDeleteProgramsNV");
  gliCallBacks->SetFunctionID("glDeleteProgramsARB",CBI_glDeletePrograms);
  gliCallBacks->SetFunctionID("glDeleteProgramsNV", CBI_glDeletePrograms);

  gliCallBacks->RegisterGLFunction("glBindProgramARB");
  gliCallBacks->RegisterGLFunction("glBindProgramNV");
  gliCallBacks->SetFunctionID("glBindProgramARB",CBI_glBindProgram);
  gliCallBacks->SetFunctionID("glBindProgramNV", CBI_glBindProgram);

  gliCallBacks->RegisterGLFunction("glProgramStringARB");
  gliCallBacks->SetFunctionID("glProgramStringARB",CBI_glProgramString);

  gliCallBacks->RegisterGLFunction("glLoadProgramNV");
  gliCallBacks->SetFunctionID("glLoadProgramNV", CBI_glLoadProgram);

  return true;
}