Added MOJOSHADER_glAvailableProfiles(). trunk
authorRyan C. Gordon <icculus@icculus.org>
Thu, 03 Jul 2008 15:25:12 -0400
branchtrunk
changeset 422 1d5eaf3a4c98
parent 421 bfd3d95273ec
child 423 ee393c1cf3b4
Added MOJOSHADER_glAvailableProfiles().
mojoshader.h
mojoshader_opengl.c
--- a/mojoshader.h	Thu Jul 03 12:09:26 2008 -0400
+++ b/mojoshader.h	Thu Jul 03 15:25:12 2008 -0400
@@ -434,9 +434,36 @@
 
 
 /*
- * Determine the best profile to use for the current system.
+ * Get a list of available profiles. This will fill in the array (profs)
+ *  with up to (size) pointers of profiles that the current system can handle;
+ *  that is, the profiles are built into MojoShader and the OpenGL extensions
+ *  required for them exist at runtime. This function returns the number of
+ *  available profiles, which may be more, less, or equal to (size).
+ *
+ * If there are more than (size) profiles, the (profs) buffer will not
+ *  overflow. You can check the return value for the total number of
+ *  available profiles, allocate more space, and try again if necessary.
+ *  Calling this function with (size) == 0 is legal.
  *
- * You do not need to call this if all you want is MOJOSHADER_parse().
+ * 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.
+ *
+ * You should not free any strings returned from this function; they are
+ *  pointers to internal, probably static, memory.
+ *
+ * This call is NOT thread safe! As most OpenGL implementations are not thread
+ *  safe, you should probably only call this from the same thread that created
+ *  the GL context.
+ */
+int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
+                                   const char **profs, const int size);
+
+
+/*
+ * Determine the best profile to use for the current system.
  *
  * 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
--- a/mojoshader_opengl.c	Thu Jul 03 12:09:26 2008 -0400
+++ b/mojoshader_opengl.c	Thu Jul 03 15:25:12 2008 -0400
@@ -804,9 +804,22 @@
 } // valid_profile
 
 
-const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname))
+static const char *profile_priorities[] = {
+#if SUPPORT_PROFILE_GLSL
+    MOJOSHADER_PROFILE_GLSL120,
+    MOJOSHADER_PROFILE_GLSL,
+#endif
+#if SUPPORT_PROFILE_ARB1
+    MOJOSHADER_PROFILE_NV3,
+    MOJOSHADER_PROFILE_NV2,
+    MOJOSHADER_PROFILE_ARB1,
+#endif
+};
+
+int MOJOSHADER_glAvailableProfiles(void *(*lookup)(const char *fnname),
+                                   const char **profs, const int size)
 {
-    const char *retval = NULL;
+    int retval = 0;
     MOJOSHADER_glContext _ctx;
     MOJOSHADER_glContext *current_ctx = ctx;
 
@@ -816,32 +829,36 @@
 
     if (ctx->have_base_opengl)
     {
-        static const char *priority[] = {
-            MOJOSHADER_PROFILE_GLSL120,
-            MOJOSHADER_PROFILE_GLSL,
-            MOJOSHADER_PROFILE_NV3,
-            MOJOSHADER_PROFILE_NV2,
-            MOJOSHADER_PROFILE_ARB1,
-        };
-
         int i;
-        for (i = 0; i < STATICARRAYLEN(priority); i++)
+        for (i = 0; i < STATICARRAYLEN(profile_priorities); i++)
         {
             // !!! FIXME: if Mac OS X <= 10.4, don't ever pick GLSL, even if
             // !!! FIXME:  the system claims it is available.
-            if (valid_profile(priority[i]))
+            const char *profile = profile_priorities[i];
+            if (valid_profile(profile))
             {
-                retval = priority[i];
-                break;
+                if (retval < size)
+                    profs[retval] = profile;
+                retval++;
             } // if
         } // for
-
-        if (retval == NULL)
-            set_error("no profiles available");
     } // if
 
     ctx = current_ctx;
     return retval;
+} // MOJOSHADER_glAvailableProfiles
+
+
+const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname))
+{
+    const char *prof[STATICARRAYLEN(profile_priorities)];
+    if (MOJOSHADER_glAvailableProfiles(lookup, prof, STATICARRAYLEN(prof)) <= 0)
+    {
+        set_error("no profiles available");
+        return NULL;
+    } // if
+
+    return prof[0];  // profiles are sorted "best" to "worst."
 } // MOJOSHADER_glBestProfile