Added data argument to GL entry point lookup callback.
Sorry to break the public API!
--- a/mojoshader.h Mon Mar 29 14:46:59 2010 -0400
+++ b/mojoshader.h Tue Mar 30 20:12:29 2010 -0400
@@ -885,6 +885,27 @@
/* OpenGL interface... */
/*
+ * Signature for function lookup callbacks. MojoShader will call a function
+ * you provide to get OpenGL entry points (both standard functions and
+ * extensions). Through this, MojoShader never links directly to OpenGL,
+ * but relies on you to provide the implementation. This means you can
+ * swap in different drivers, or hook functions (log every GL call MojoShader
+ * makes, etc).
+ *
+ * (fnname) is the function name we want the address for ("glBegin" or
+ * whatever. (data) is a void pointer you provide, if this callback needs
+ * extra information. If you don't need it, you may specify NULL.
+ *
+ * Return the entry point on success, NULL if it couldn't be found.
+ * Note that this could ask for standard entry points like glEnable(), or
+ * extensions like glProgramLocalParameterI4ivNV(), so you might need
+ * to check two places to find the desired entry point, depending on your
+ * platform (Windows might need to look in OpenGL32.dll and use WGL, etc).
+ */
+typedef void *(*MOJOSHADER_glGetProcAddress)(const char *fnname, void *data);
+
+
+/*
* "Contexts" map to OpenGL contexts...you need one per window, or whatever,
* and need to inform MojoShader when you make a new one current.
*
@@ -913,9 +934,9 @@
*
* You can only call this AFTER you have successfully built your GL context
* and made it current. This function will lookup the GL functions it needs
- * through the callback you supply. The lookup function is neither stored nor
- * used by MojoShader after this function returns, nor are the functions it
- * might look up.
+ * through the callback you supply, via (lookup) and (d). The lookup function
+ * is neither stored nor used by MojoShader after this function returns, nor
+ * are the functions it might look up.
*
* You should not free any strings returned from this function; they are
* pointers to internal, probably static, memory.
@@ -924,7 +945,7 @@
* safe, you should probably only call this from the same thread that created
* the GL context.
*/
-int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
+int MOJOSHADER_glAvailableProfiles(MOJOSHADER_glGetProcAddress lookup, void *d,
const char **profs, const int size);
@@ -933,9 +954,9 @@
*
* You can only call this AFTER you have successfully built your GL context
* and made it current. This function will lookup the GL functions it needs
- * through the callback you supply. The lookup function is neither stored nor
- * used by MojoShader after this function returns, nor are the functions it
- * might look up.
+ * through the callback you supply via (lookup) and (d). The lookup function
+ * is neither stored nor used by MojoShader after this function returns, nor
+ * are the functions it might look up.
*
* Returns the name of the "best" profile on success, NULL if none of the
* available profiles will work on this system. "Best" is a relative term,
@@ -950,7 +971,7 @@
* safe, you should probably only call this from the same thread that created
* the GL context.
*/
-const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname));
+const char *MOJOSHADER_glBestProfile(MOJOSHADER_glGetProcAddress lookup, void *d);
/*
@@ -960,23 +981,26 @@
*
* You must call this once AFTER you have successfully built your GL context
* and made it current. This function will lookup the GL functions it needs
- * through the callback you supply, after which it may call them at any time
- * up until you call MOJOSHADER_glDestroyContext(). The lookup function is
- * neither stored nor used by MojoShader after this function returns.
+ * through the callback you supply via (lookup) and (lookup_d), after which
+ * it may call them at any time up until you call
+ * MOJOSHADER_glDestroyContext(). The lookup function is neither stored nor
+ * used by MojoShader after this function returns.
*
* (profile) is an OpenGL-specific MojoShader profile, which decides how
* Direct3D bytecode shaders get turned into OpenGL programs, and how they
* are fed to the GL.
*
* (lookup) is a callback that is used to load GL entry points. This callback
- * has to look up base GL functions and extension entry points.
+ * has to look up base GL functions and extension entry points. The pointer
+ * you supply in (lookup_d) is passed as-is to the callback.
*
* As MojoShader requires some memory to be allocated, you may provide a
* custom allocator to this function, which will be used to allocate/free
* memory. They function just like malloc() and free(). We do not use
* realloc(). If you don't care, pass NULL in for the allocator functions.
* If your allocator needs instance-specific data, you may supply it with the
- * (d) parameter. This pointer is passed as-is to your (m) and (f) functions.
+ * (malloc_d) parameter. This pointer is passed as-is to your (m) and (f)
+ * functions.
*
* Returns a new context on success, NULL on error. If you get a new context,
* you need to make it current before using it with
@@ -988,9 +1012,10 @@
* thread that created the GL context.
*/
MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
- void *(*lookup)(const char *fnname),
+ MOJOSHADER_glGetProcAddress lookup,
+ void *lookup_d,
MOJOSHADER_malloc m, MOJOSHADER_free f,
- void *d);
+ void *malloc_d);
/*
* You must call this before using the context that you got from
--- a/mojoshader_opengl.c Mon Mar 29 14:46:59 2010 -0400
+++ b/mojoshader_opengl.c Tue Mar 30 20:12:29 2010 -0400
@@ -748,17 +748,18 @@
} // MOJOSHADER_glGetError
-static void *loadsym(void *(*lookup)(const char *fn), const char *fn, int *ext)
+static void *loadsym(MOJOSHADER_glGetProcAddress lookup, void *d,
+ const char *fn, int *ext)
{
void *retval = NULL;
if (lookup != NULL)
{
- retval = lookup(fn);
+ retval = lookup(fn, d);
if (retval == NULL)
{
char arbfn[64];
snprintf(arbfn, sizeof (arbfn), "%sARB", fn);
- retval = lookup(arbfn);
+ retval = lookup(arbfn, d);
} // if
} // if
@@ -768,11 +769,11 @@
return retval;
} // loadsym
-static void lookup_entry_points(void *(*lookup)(const char *fnname))
+static void lookup_entry_points(MOJOSHADER_glGetProcAddress lookup, void *d)
{
#define DO_LOOKUP(ext, typ, fn) { \
int exist = ctx->have_##ext; \
- ctx->fn = (typ) loadsym(lookup, #fn, &exist); \
+ ctx->fn = (typ) loadsym(lookup, d, #fn, &exist); \
ctx->have_##ext = exist; \
}
@@ -875,7 +876,7 @@
#endif
-static void load_extensions(void *(*lookup)(const char *fnname))
+static void load_extensions(MOJOSHADER_glGetProcAddress lookup, void *d)
{
const char *extlist = NULL;
@@ -894,7 +895,7 @@
ctx->have_GL_ARB_half_float_vertex = 1;
ctx->have_GL_OES_vertex_half_float = 1;
- lookup_entry_points(lookup);
+ lookup_entry_points(lookup, d);
if (!ctx->have_base_opengl)
set_error("missing basic OpenGL entry points");
@@ -1034,7 +1035,7 @@
#endif
};
-int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
+int MOJOSHADER_glAvailableProfiles(MOJOSHADER_glGetProcAddress lookup, void *d,
const char **profs, const int size)
{
int retval = 0;
@@ -1043,7 +1044,7 @@
ctx = &_ctx;
memset(ctx, '\0', sizeof (MOJOSHADER_glContext));
- load_extensions(lookup);
+ load_extensions(lookup, d);
if (ctx->have_base_opengl)
{
@@ -1065,10 +1066,10 @@
} // MOJOSHADER_glAvailableProfiles
-const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname))
+const char *MOJOSHADER_glBestProfile(MOJOSHADER_glGetProcAddress gpa, void *d)
{
const char *prof[STATICARRAYLEN(profile_priorities)];
- if (MOJOSHADER_glAvailableProfiles(lookup, prof, STATICARRAYLEN(prof)) <= 0)
+ if (MOJOSHADER_glAvailableProfiles(gpa, d, prof, STATICARRAYLEN(prof)) <= 0)
{
set_error("no profiles available");
return NULL;
@@ -1079,9 +1080,10 @@
MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
- void *(*lookup)(const char *fnname),
+ MOJOSHADER_glGetProcAddress lookup,
+ void *lookup_d,
MOJOSHADER_malloc m, MOJOSHADER_free f,
- void *d)
+ void *malloc_d)
{
MOJOSHADER_glContext *retval = NULL;
MOJOSHADER_glContext *current_ctx = ctx;
@@ -1091,7 +1093,7 @@
if (m == NULL) m = MOJOSHADER_internal_malloc;
if (f == NULL) f = MOJOSHADER_internal_free;
- ctx = (MOJOSHADER_glContext *) m(sizeof (MOJOSHADER_glContext), d);
+ ctx = (MOJOSHADER_glContext *) m(sizeof (MOJOSHADER_glContext), malloc_d);
if (ctx == NULL)
{
set_error("out of memory");
@@ -1101,10 +1103,10 @@
memset(ctx, '\0', sizeof (MOJOSHADER_glContext));
ctx->malloc_fn = m;
ctx->free_fn = f;
- ctx->malloc_data = d;
+ ctx->malloc_data = malloc_d;
snprintf(ctx->profile, sizeof (ctx->profile), "%s", profile);
- load_extensions(lookup);
+ load_extensions(lookup, lookup_d);
if (!valid_profile(profile))
goto init_fail;
@@ -1184,7 +1186,7 @@
init_fail:
if (ctx != NULL)
- f(ctx, d);
+ f(ctx, malloc_d);
ctx = current_ctx;
return NULL;
} // MOJOSHADER_glCreateContext
@@ -1909,7 +1911,7 @@
ctx = _ctx;
MOJOSHADER_glBindProgram(NULL);
update_enabled_arrays(); // disables all vertex arrays.
- lookup_entry_points(NULL);
+ lookup_entry_points(NULL, NULL);
Free(ctx);
ctx = ((current_ctx == _ctx) ? NULL : current_ctx);
} // MOJOSHADER_glDestroyContext
--- a/utils/availableprofiles.c Mon Mar 29 14:46:59 2010 -0400
+++ b/utils/availableprofiles.c Tue Mar 30 20:12:29 2010 -0400
@@ -11,14 +11,20 @@
#include "mojoshader.h"
#include "SDL.h"
+static void *lookup(const char *fnname, void *unused)
+{
+ (void) unused;
+ return SDL_GL_GetProcAddress(fnname);
+} // lookup
+
static int check_available(void)
{
const char **avail = NULL;
- int total = MOJOSHADER_glAvailableProfiles(SDL_GL_GetProcAddress, NULL, 0);
+ int total = MOJOSHADER_glAvailableProfiles(lookup, NULL, NULL, 0);
if (total > 0)
{
avail = (const char **) alloca(sizeof (const char *) * total);
- total = MOJOSHADER_glAvailableProfiles(SDL_GL_GetProcAddress, avail, total);
+ total = MOJOSHADER_glAvailableProfiles(lookup, NULL, avail, total);
} // if
if (total <= 0)
--- a/utils/bestprofile.c Mon Mar 29 14:46:59 2010 -0400
+++ b/utils/bestprofile.c Tue Mar 30 20:12:29 2010 -0400
@@ -11,6 +11,12 @@
#include "mojoshader.h"
#include "SDL.h"
+static void *lookup(const char *fnname, void *unused)
+{
+ (void) unused;
+ return SDL_GL_GetProcAddress(fnname);
+} // lookup
+
int main(int argc, char **argv)
{
int retval = 1;
@@ -31,9 +37,9 @@
fprintf(stderr, "SDL_SetVideoMode() error: %s\n", SDL_GetError());
else
{
- const char *best = MOJOSHADER_glBestProfile(SDL_GL_GetProcAddress);
+ const char *best = MOJOSHADER_glBestProfile(lookup, NULL);
MOJOSHADER_glContext *ctx;
- ctx = MOJOSHADER_glCreateContext(best, SDL_GL_GetProcAddress, 0, 0, 0);
+ ctx = MOJOSHADER_glCreateContext(best, lookup, 0, 0, 0, 0);
if (ctx == NULL)
printf("MOJOSHADER_glCreateContext() fail: %s\n", MOJOSHADER_glGetError());
else
--- a/utils/finderrors.c Mon Mar 29 14:46:59 2010 -0400
+++ b/utils/finderrors.c Tue Mar 30 20:12:29 2010 -0400
@@ -18,6 +18,11 @@
#if FINDERRORS_COMPILE_SHADERS
#include "SDL.h"
+static void *lookup(const char *fnname, void *unused)
+{
+ (void) unused;
+ return SDL_GL_GetProcAddress(fnname);
+} // lookup
#endif
#ifdef _MSC_VER
@@ -192,9 +197,9 @@
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_LoadLibrary(NULL);
SDL_SetVideoMode(640, 480, 0, SDL_OPENGL);
- printf("Best profile is '%s'\n", MOJOSHADER_glBestProfile(SDL_GL_GetProcAddress));
+ printf("Best profile is '%s'\n", MOJOSHADER_glBestProfile(lookup, 0));
MOJOSHADER_glContext *ctx;
- ctx = MOJOSHADER_glCreateContext(profile, SDL_GL_GetProcAddress, 0, 0, 0);
+ ctx = MOJOSHADER_glCreateContext(profile, lookup, 0, 0, 0, 0);
if (ctx == NULL)
{
printf("MOJOSHADER_glCreateContext() fail: %s\n", MOJOSHADER_glGetError());