added stb, more binaryout changes"
[henge/apc.git] / stb / tests / caveview / stb_glprog.h
diff --git a/stb/tests/caveview/stb_glprog.h b/stb/tests/caveview/stb_glprog.h
new file mode 100644 (file)
index 0000000..8883a3e
--- /dev/null
@@ -0,0 +1,504 @@
+// stb_glprog v0.02 public domain         functions to reduce GLSL boilerplate
+// http://nothings.org/stb/stb_glprog.h   especially with GL1 + ARB extensions
+//
+// Following defines *before* including have following effects:
+//
+//     STB_GLPROG_IMPLEMENTATION
+//           creates the implementation
+//
+//     STB_GLPROG_STATIC
+//           forces the implementation to be static (private to file that creates it)
+//
+//     STB_GLPROG_ARB
+//           uses ARB extension names for GLSL functions and enumerants instead of core names
+//
+//     STB_GLPROG_ARB_DEFINE_EXTENSIONS
+//           instantiates function pointers needed, static to implementing file
+//           to avoid collisions (but will collide if implementing file also
+//           defines any; best to isolate this to its own file in this case).
+//           This will try to automatically #include glext.h, but if it's not
+//           in the default include directories you'll need to include it
+//           yourself and define the next macro.
+//
+//     STB_GLPROG_SUPPRESS_GLEXT_INCLUDE
+//           disables the automatic #include of glext.h which is normally
+//           forced by STB_GLPROG_ARB_DEFINE_EXTENSIONS
+//
+// So, e.g., sample usage on an old Windows compiler:
+//
+//     #define STB_GLPROG_IMPLEMENTATION
+//     #define STB_GLPROG_ARB_DEFINE_EXTENSIONS
+//     #include <windows.h>
+//     #include "gl/gl.h"
+//     #include "stb_glprog.h"
+//
+// Note though that the header-file version of this (when you don't define
+// STB_GLPROG_IMPLEMENTATION) still uses GLint and such, so you basically
+// can only include it in places where you're already including GL, especially
+// on Windows where including "gl.h" requires (some of) "windows.h".
+//
+// See following comment blocks for function documentation.
+//
+// Version history:
+//    2013-12-08   v0.02   slightly simplified API and reduced GL resource usage (@rygorous)
+//    2013-12-08   v0.01   initial release
+
+
+// header file section starts here
+#if !defined(INCLUDE_STB_GLPROG_H)
+#define INCLUDE_STB_GLPROG_H
+
+#ifndef STB_GLPROG_STATIC
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+
+/////////////    SHADER CREATION
+
+
+/// EASY API
+
+extern GLuint stbgl_create_program(char const **vertex_source, char const **frag_source, char const **binds, char *error, int error_buflen);
+// This function returns a compiled program or 0 if there's an error.
+// To free the created program, call stbgl_delete_program.
+//
+//     stbgl_create_program(
+//             char **vertex_source,   // NULL or one or more strings with the vertex shader source, with a final NULL
+//             char **frag_source,     // NULL or one or more strings with the fragment shader source, with a final NULL
+//             char **binds,           // NULL or zero or more strings with attribute bind names, with a final NULL
+//             char *error,            // output location where compile error message is placed
+//             int error_buflen)       // length of error output buffer
+//
+// Returns a GLuint with the GL program object handle.
+//
+// If an individual bind string is "", no name is bound to that slot (this
+// allows you to create binds that aren't continuous integers starting at 0).
+//
+// If the vertex shader is NULL, then fixed-function vertex pipeline
+// is used, if that's legal in your version of GL.
+//
+// If the fragment shader is NULL, then fixed-function fragment pipeline
+// is used, if that's legal in your version of GL.
+
+extern void stgbl_delete_program(GLuint program);
+// deletes a program created by stbgl_create_program or stbgl_link_program
+
+
+/// FLEXIBLE API
+
+extern GLuint stbgl_compile_shader(GLenum type, char const **sources, int num_sources, char *error, int error_buflen);
+// compiles a shader. returns the shader on success or 0 on failure.
+//
+//    type          either:  GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
+//                     or    GL_VERTEX_SHADER_ARB or GL_FRAGMENT_SHADER_ARB
+//                     or    STBGL_VERTEX_SHADER or STBGL_FRAGMENT_SHADER
+//    sources       array of strings containing the shader source
+//    num_sources   number of string in sources, or -1 meaning sources is NULL-terminated
+//    error         string to output compiler error to
+//    error_buflen  length of error buffer in chars
+
+extern GLuint stbgl_link_program(GLuint vertex_shader, GLuint fragment_shader, char const **binds, int num_binds, char *error, int error_buflen);
+// links a shader. returns the linked program on success or 0 on failure.
+//
+//    vertex_shader    a compiled vertex shader from stbgl_compile_shader, or 0 for fixed-function (if legal)
+//    fragment_shader  a compiled fragment shader from stbgl_compile_shader, or 0 for fixed-function (if legal)
+//
+
+extern void stbgl_delete_shader(GLuint shader);
+// deletes a shader created by stbgl_compile_shader
+
+
+/////////////    RENDERING WITH SHADERS
+
+extern GLint stbgl_find_uniform(GLuint prog, char *uniform);
+
+extern void stbgl_find_uniforms(GLuint prog, GLint *locations, char const **uniforms, int num_uniforms);
+// Given the locations array that is num_uniforms long, fills out
+// the locations of each of those uniforms for the specified program.
+// If num_uniforms is -1, then uniforms[] must be NULL-terminated
+
+// the following functions just wrap the difference in naming between GL2+ and ARB,
+// so you don't need them unless you're using both ARB and GL2+ in the same codebase,
+// or you're relying on this lib to provide the extensions
+extern void stbglUseProgram(GLuint program);
+extern void stbglVertexAttribPointer(GLuint index,  GLint size,  GLenum type,  GLboolean normalized,  GLsizei stride,  const GLvoid * pointer);
+extern void stbglEnableVertexAttribArray(GLuint index);
+extern void stbglDisableVertexAttribArray(GLuint index);
+extern void stbglUniform1fv(GLint loc, GLsizei count, const GLfloat *v);
+extern void stbglUniform2fv(GLint loc, GLsizei count, const GLfloat *v);
+extern void stbglUniform3fv(GLint loc, GLsizei count, const GLfloat *v);
+extern void stbglUniform4fv(GLint loc, GLsizei count, const GLfloat *v);
+extern void stbglUniform1iv(GLint loc, GLsizei count, const GLint *v);
+extern void stbglUniform2iv(GLint loc, GLsizei count, const GLint *v);
+extern void stbglUniform3iv(GLint loc, GLsizei count, const GLint *v);
+extern void stbglUniform4iv(GLint loc, GLsizei count, const GLint *v);
+extern void stbglUniform1f(GLint loc, float v0);
+extern void stbglUniform2f(GLint loc, float v0, float v1);
+extern void stbglUniform3f(GLint loc, float v0, float v1, float v2);
+extern void stbglUniform4f(GLint loc, float v0, float v1, float v2, float v3);
+extern void stbglUniform1i(GLint loc, GLint v0);
+extern void stbglUniform2i(GLint loc, GLint v0, GLint v1);
+extern void stbglUniform3i(GLint loc, GLint v0, GLint v1, GLint v2);
+extern void stbglUniform4i(GLint loc, GLint v0, GLint v1, GLint v2, GLint v3);
+
+
+//////////////     END OF FUNCTIONS
+
+//////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
+#endif // STB_GLPROG_STATIC
+
+#ifdef STB_GLPROG_ARB
+#define STBGL_VERTEX_SHADER    GL_VERTEX_SHADER_ARB
+#define STBGL_FRAGMENT_SHADER  GL_FRAGMENT_SHADER_ARB
+#else
+#define STBGL_VERTEX_SHADER    GL_VERTEX_SHADER
+#define STBGL_FRAGMENT_SHADER  GL_FRAGMENT_SHADER
+#endif
+
+#endif // INCLUDE_STB_GLPROG_H
+
+
+/////////    header file section ends here
+
+
+#ifdef STB_GLPROG_IMPLEMENTATION
+#include <string.h> // strncpy
+
+#ifdef STB_GLPROG_STATIC
+#define STB_GLPROG_DECLARE static
+#else
+#define STB_GLPROG_DECLARE extern
+#endif
+
+// check if user wants this file to define the GL extensions itself
+#ifdef STB_GLPROG_ARB_DEFINE_EXTENSIONS
+#define STB_GLPROG_ARB  // make sure later code uses the extensions
+
+#ifndef STB_GLPROG_SUPPRESS_GLEXT_INCLUDE
+#include "glext.h"
+#endif
+
+#define STB_GLPROG_EXTENSIONS                                 \
+   STB_GLPROG_FUNC(ATTACHOBJECT        , AttachObject        ) \
+   STB_GLPROG_FUNC(BINDATTRIBLOCATION  , BindAttribLocation  ) \
+   STB_GLPROG_FUNC(COMPILESHADER       , CompileShader       ) \
+   STB_GLPROG_FUNC(CREATEPROGRAMOBJECT , CreateProgramObject ) \
+   STB_GLPROG_FUNC(CREATESHADEROBJECT  , CreateShaderObject  ) \
+   STB_GLPROG_FUNC(DELETEOBJECT        , DeleteObject        ) \
+   STB_GLPROG_FUNC(DETACHOBJECT        , DetachObject        ) \
+   STB_GLPROG_FUNC(DISABLEVERTEXATTRIBARRAY, DisableVertexAttribArray) \
+   STB_GLPROG_FUNC(ENABLEVERTEXATTRIBARRAY,  EnableVertexAttribArray ) \
+   STB_GLPROG_FUNC(GETATTACHEDOBJECTS  , GetAttachedObjects  ) \
+   STB_GLPROG_FUNC(GETOBJECTPARAMETERIV, GetObjectParameteriv) \
+   STB_GLPROG_FUNC(GETINFOLOG          , GetInfoLog          ) \
+   STB_GLPROG_FUNC(GETUNIFORMLOCATION  , GetUniformLocation  ) \
+   STB_GLPROG_FUNC(LINKPROGRAM         , LinkProgram         ) \
+   STB_GLPROG_FUNC(SHADERSOURCE        , ShaderSource        ) \
+   STB_GLPROG_FUNC(UNIFORM1F           , Uniform1f           ) \
+   STB_GLPROG_FUNC(UNIFORM2F           , Uniform2f           ) \
+   STB_GLPROG_FUNC(UNIFORM3F           , Uniform3f           ) \
+   STB_GLPROG_FUNC(UNIFORM4F           , Uniform4f           ) \
+   STB_GLPROG_FUNC(UNIFORM1I           , Uniform1i           ) \
+   STB_GLPROG_FUNC(UNIFORM2I           , Uniform2i           ) \
+   STB_GLPROG_FUNC(UNIFORM3I           , Uniform3i           ) \
+   STB_GLPROG_FUNC(UNIFORM4I           , Uniform4i           ) \
+   STB_GLPROG_FUNC(UNIFORM1FV          , Uniform1fv          ) \
+   STB_GLPROG_FUNC(UNIFORM2FV          , Uniform2fv          ) \
+   STB_GLPROG_FUNC(UNIFORM3FV          , Uniform3fv          ) \
+   STB_GLPROG_FUNC(UNIFORM4FV          , Uniform4fv          ) \
+   STB_GLPROG_FUNC(UNIFORM1IV          , Uniform1iv          ) \
+   STB_GLPROG_FUNC(UNIFORM2IV          , Uniform2iv          ) \
+   STB_GLPROG_FUNC(UNIFORM3IV          , Uniform3iv          ) \
+   STB_GLPROG_FUNC(UNIFORM4IV          , Uniform4iv          ) \
+   STB_GLPROG_FUNC(USEPROGRAMOBJECT    , UseProgramObject    ) \
+   STB_GLPROG_FUNC(VERTEXATTRIBPOINTER , VertexAttribPointer )
+
+// define the static function pointers
+
+#define STB_GLPROG_FUNC(x,y)  static PFNGL##x##ARBPROC gl##y##ARB;
+STB_GLPROG_EXTENSIONS
+#undef STB_GLPROG_FUNC
+
+// define the GetProcAddress
+
+#ifdef _WIN32
+#ifndef WINGDIAPI
+#ifndef STB__HAS_WGLPROC
+typedef int (__stdcall *stbgl__voidfunc)(void);
+static __declspec(dllimport) stbgl__voidfunc wglGetProcAddress(char *);
+#endif
+#endif
+#define STBGL__GET_FUNC(x)   wglGetProcAddress(x)
+#else
+#error "need to define how this platform gets extensions"
+#endif
+
+// create a function that fills out the function pointers
+
+static void stb_glprog_init(void)
+{
+   static int initialized = 0; // not thread safe!
+   if (initialized) return;
+   #define STB_GLPROG_FUNC(x,y) gl##y##ARB = (PFNGL##x##ARBPROC) STBGL__GET_FUNC("gl" #y "ARB");
+   STB_GLPROG_EXTENSIONS
+   #undef STB_GLPROG_FUNC
+}
+#undef STB_GLPROG_EXTENSIONS
+
+#else
+static void stb_glprog_init(void)
+{
+}
+#endif
+
+
+// define generic names for many of the gl functions or extensions for later use;
+// note that in some cases there are two functions in core and one function in ARB
+#ifdef STB_GLPROG_ARB
+#define stbglCreateShader          glCreateShaderObjectARB
+#define stbglDeleteShader          glDeleteObjectARB
+#define stbglAttachShader          glAttachObjectARB
+#define stbglDetachShader          glDetachObjectARB
+#define stbglShaderSource          glShaderSourceARB
+#define stbglCompileShader         glCompileShaderARB
+#define stbglGetShaderStatus(a,b)  glGetObjectParameterivARB(a, GL_OBJECT_COMPILE_STATUS_ARB, b)
+#define stbglGetShaderInfoLog      glGetInfoLogARB
+#define stbglCreateProgram         glCreateProgramObjectARB
+#define stbglDeleteProgram         glDeleteObjectARB
+#define stbglLinkProgram           glLinkProgramARB
+#define stbglGetProgramStatus(a,b) glGetObjectParameterivARB(a, GL_OBJECT_LINK_STATUS_ARB, b)
+#define stbglGetProgramInfoLog     glGetInfoLogARB
+#define stbglGetAttachedShaders    glGetAttachedObjectsARB
+#define stbglBindAttribLocation    glBindAttribLocationARB
+#define stbglGetUniformLocation    glGetUniformLocationARB
+#define stbgl_UseProgram           glUseProgramObjectARB
+#else
+#define stbglCreateShader          glCreateShader
+#define stbglDeleteShader          glDeleteShader
+#define stbglAttachShader          glAttachShader
+#define stbglDetachShader          glDetachShader
+#define stbglShaderSource          glShaderSource
+#define stbglCompileShader         glCompileShader
+#define stbglGetShaderStatus(a,b)  glGetShaderiv(a, GL_COMPILE_STATUS, b)
+#define stbglGetShaderInfoLog      glGetShaderInfoLog
+#define stbglCreateProgram         glCreateProgram
+#define stbglDeleteProgram         glDeleteProgram
+#define stbglLinkProgram           glLinkProgram
+#define stbglGetProgramStatus(a,b) glGetProgramiv(a, GL_LINK_STATUS, b)
+#define stbglGetProgramInfoLog     glGetProgramInfoLog
+#define stbglGetAttachedShaders    glGetAttachedShaders
+#define stbglBindAttribLocation    glBindAttribLocation
+#define stbglGetUniformLocation    glGetUniformLocation
+#define stbgl_UseProgram           glUseProgram
+#endif
+
+
+// perform a safe strcat of 3 strings, given that we can't rely on portable snprintf
+// if you need to break on error, this is the best place to place a breakpoint
+static void stb_glprog_error(char *error, int error_buflen, char *str1, char *str2, char *str3)
+{
+   int n = strlen(str1);
+   strncpy(error, str1, error_buflen);
+   if (n < error_buflen && str2) {
+      strncpy(error+n, str2, error_buflen - n);
+      n += strlen(str2);
+      if (n < error_buflen && str3) {
+         strncpy(error+n, str3, error_buflen - n);
+      }
+   }
+   error[error_buflen-1] = 0;
+}
+
+STB_GLPROG_DECLARE GLuint stbgl_compile_shader(GLenum type, char const **sources, int num_sources, char *error, int error_buflen)
+{
+   char *typename = (type == STBGL_VERTEX_SHADER ? "vertex" : "fragment");
+   int len;
+   GLint result;
+   GLuint shader;
+
+   // initialize the extensions if we haven't already
+   stb_glprog_init();
+
+   // allocate
+
+   shader = stbglCreateShader(type);
+   if (!shader) {
+      stb_glprog_error(error, error_buflen, "Couldn't allocate shader object in stbgl_compile_shader for ", typename, NULL);
+      return 0;
+   }
+
+   // compile
+
+   // if num_sources is negative, assume source is NULL-terminated and count the non-NULL ones
+   if (num_sources < 0)
+      for (num_sources = 0; sources[num_sources] != NULL; ++num_sources)
+         ;
+   stbglShaderSource(shader, num_sources, sources, NULL);
+   stbglCompileShader(shader);
+   stbglGetShaderStatus(shader, &result);
+   if (result)
+      return shader;
+
+   // errors
+
+   stb_glprog_error(error, error_buflen, "Compile error for ", typename, " shader: ");
+   len = strlen(error);
+   if (len < error_buflen)
+      stbglGetShaderInfoLog(shader, error_buflen-len, NULL, error+len);
+
+   stbglDeleteShader(shader);
+   return 0;
+}
+
+STB_GLPROG_DECLARE GLuint stbgl_link_program(GLuint vertex_shader, GLuint fragment_shader, char const **binds, int num_binds, char *error, int error_buflen)
+{
+   int len;
+   GLint result;
+
+   // allocate
+
+   GLuint prog = stbglCreateProgram();
+   if (!prog) {
+      stb_glprog_error(error, error_buflen, "Couldn't allocate program object in stbgl_link_program", NULL, NULL);
+      return 0;
+   }
+
+   // attach
+
+   if (vertex_shader)
+      stbglAttachShader(prog, vertex_shader);
+   if (fragment_shader)
+      stbglAttachShader(prog, fragment_shader);
+
+   // attribute binds
+
+   if (binds) {
+      int i;
+      // if num_binds is negative, then it is NULL terminated
+      if (num_binds < 0)
+         for (num_binds=0; binds[num_binds]; ++num_binds)
+            ;
+      for (i=0; i < num_binds; ++i)
+         if (binds[i] && binds[i][0]) // empty binds can be NULL or ""
+            stbglBindAttribLocation(prog, i, binds[i]);
+   }
+
+   // link
+
+   stbglLinkProgram(prog);
+
+   // detach
+
+   if (vertex_shader)
+      stbglDetachShader(prog, vertex_shader);
+   if (fragment_shader)
+      stbglDetachShader(prog, fragment_shader);
+
+   // errors
+
+   stbglGetProgramStatus(prog, &result);
+   if (result)
+      return prog;
+
+   stb_glprog_error(error, error_buflen, "Link error: ", NULL, NULL);
+   len = strlen(error);
+   if (len < error_buflen)
+      stbglGetProgramInfoLog(prog, error_buflen-len, NULL, error+len);
+
+   stbglDeleteProgram(prog);
+   return 0;   
+}
+
+STB_GLPROG_DECLARE GLuint stbgl_create_program(char const **vertex_source, char const **frag_source, char const **binds, char *error, int error_buflen)
+{
+   GLuint vertex, fragment, prog=0;
+   vertex = stbgl_compile_shader(STBGL_VERTEX_SHADER, vertex_source, -1, error, error_buflen);
+   if (vertex) {
+      fragment = stbgl_compile_shader(STBGL_FRAGMENT_SHADER, frag_source, -1, error, error_buflen);
+      if (fragment)
+         prog = stbgl_link_program(vertex, fragment, binds, -1, error, error_buflen);
+      if (fragment)
+         stbglDeleteShader(fragment);
+      stbglDeleteShader(vertex);
+   }
+   return prog;
+}
+
+STB_GLPROG_DECLARE void stbgl_delete_shader(GLuint shader)
+{
+   stbglDeleteShader(shader);
+}
+
+STB_GLPROG_DECLARE void stgbl_delete_program(GLuint program)
+{
+   stbglDeleteProgram(program);
+}
+
+GLint stbgl_find_uniform(GLuint prog, char *uniform)
+{
+   return stbglGetUniformLocation(prog, uniform);
+}
+
+STB_GLPROG_DECLARE void stbgl_find_uniforms(GLuint prog, GLint *locations, char const **uniforms, int num_uniforms)
+{
+   int i;
+   if (num_uniforms < 0)
+      num_uniforms = 999999;
+   for (i=0; i < num_uniforms && uniforms[i]; ++i)
+      locations[i] = stbglGetUniformLocation(prog, uniforms[i]);
+}
+
+STB_GLPROG_DECLARE void stbglUseProgram(GLuint program)
+{
+   stbgl_UseProgram(program);
+}
+
+#ifdef STB_GLPROG_ARB
+#define STBGL_ARBIFY(name)   name##ARB
+#else
+#define STBGL_ARBIFY(name)   name
+#endif
+
+STB_GLPROG_DECLARE void stbglVertexAttribPointer(GLuint index,  GLint size,  GLenum type,  GLboolean normalized,  GLsizei stride,  const GLvoid * pointer)
+{
+   STBGL_ARBIFY(glVertexAttribPointer)(index, size, type, normalized, stride, pointer);
+}
+
+STB_GLPROG_DECLARE void stbglEnableVertexAttribArray (GLuint index) { STBGL_ARBIFY(glEnableVertexAttribArray )(index); }
+STB_GLPROG_DECLARE void stbglDisableVertexAttribArray(GLuint index) { STBGL_ARBIFY(glDisableVertexAttribArray)(index); }
+
+STB_GLPROG_DECLARE void stbglUniform1fv(GLint loc, GLsizei count, const GLfloat *v) { STBGL_ARBIFY(glUniform1fv)(loc,count,v); }
+STB_GLPROG_DECLARE void stbglUniform2fv(GLint loc, GLsizei count, const GLfloat *v) { STBGL_ARBIFY(glUniform2fv)(loc,count,v); }
+STB_GLPROG_DECLARE void stbglUniform3fv(GLint loc, GLsizei count, const GLfloat *v) { STBGL_ARBIFY(glUniform3fv)(loc,count,v); }
+STB_GLPROG_DECLARE void stbglUniform4fv(GLint loc, GLsizei count, const GLfloat *v) { STBGL_ARBIFY(glUniform4fv)(loc,count,v); }
+
+STB_GLPROG_DECLARE void stbglUniform1iv(GLint loc, GLsizei count, const GLint   *v) { STBGL_ARBIFY(glUniform1iv)(loc,count,v); }
+STB_GLPROG_DECLARE void stbglUniform2iv(GLint loc, GLsizei count, const GLint   *v) { STBGL_ARBIFY(glUniform2iv)(loc,count,v); }
+STB_GLPROG_DECLARE void stbglUniform3iv(GLint loc, GLsizei count, const GLint   *v) { STBGL_ARBIFY(glUniform3iv)(loc,count,v); }
+STB_GLPROG_DECLARE void stbglUniform4iv(GLint loc, GLsizei count, const GLint   *v) { STBGL_ARBIFY(glUniform4iv)(loc,count,v); }
+
+STB_GLPROG_DECLARE void stbglUniform1f(GLint loc, float v0)
+    { STBGL_ARBIFY(glUniform1f)(loc,v0); }
+STB_GLPROG_DECLARE void stbglUniform2f(GLint loc, float v0, float v1)
+    { STBGL_ARBIFY(glUniform2f)(loc,v0,v1); }
+STB_GLPROG_DECLARE void stbglUniform3f(GLint loc, float v0, float v1, float v2)
+    { STBGL_ARBIFY(glUniform3f)(loc,v0,v1,v2); }
+STB_GLPROG_DECLARE void stbglUniform4f(GLint loc, float v0, float v1, float v2, float v3)
+    { STBGL_ARBIFY(glUniform4f)(loc,v0,v1,v2,v3); }
+
+STB_GLPROG_DECLARE void stbglUniform1i(GLint loc, GLint v0)
+    { STBGL_ARBIFY(glUniform1i)(loc,v0); }
+STB_GLPROG_DECLARE void stbglUniform2i(GLint loc, GLint v0, GLint v1)
+    { STBGL_ARBIFY(glUniform2i)(loc,v0,v1); }
+STB_GLPROG_DECLARE void stbglUniform3i(GLint loc, GLint v0, GLint v1, GLint v2)
+    { STBGL_ARBIFY(glUniform3i)(loc,v0,v1,v2); }
+STB_GLPROG_DECLARE void stbglUniform4i(GLint loc, GLint v0, GLint v1, GLint v2, GLint v3)
+    { STBGL_ARBIFY(glUniform4i)(loc,v0,v1,v2,v3); }
+
+#endif