Added framework for GLSL 1.20 support. trunk
authorRyan C. Gordon <icculus@icculus.org>
Sun, 29 Jun 2008 00:16:56 -0400
branchtrunk
changeset 407 620d48c5d13a
parent 406 682e9073a9cf
child 408 796209598bf9
Added framework for GLSL 1.20 support.
mojoshader.c
mojoshader.h
mojoshader_opengl.c
--- a/mojoshader.c	Sun Jun 29 00:15:52 2008 -0400
+++ b/mojoshader.c	Sun Jun 29 00:16:56 2008 -0400
@@ -421,6 +421,7 @@
     int determined_constants_arrays:1;
     int predicated:1;
     int support_nv2:1;
+    int support_glsl120:1;
     int glsl_generated_lit_opcode:1;
 };
 
@@ -2225,6 +2226,23 @@
         return;
     } // if
 
+    ctx->output = &ctx->globals;
+
+    if (strcmp(profilestr, MOJOSHADER_PROFILE_GLSL) == 0)
+        /* no-op. */ ;
+
+    else if (strcmp(profilestr, MOJOSHADER_PROFILE_GLSL120) == 0)
+    {
+        ctx->support_glsl120 = 1;
+        output_line(ctx, "#version 120");
+    } // else if
+
+    else
+    {
+        failf(ctx, "Profile '%s' unsupported or unknown.", profilestr);
+        return;
+    } // else
+
     ctx->output = &ctx->mainline_intro;
     output_line(ctx, "void main()");
     output_line(ctx, "{");
@@ -4928,6 +4946,7 @@
 // This is for profiles that extend other profiles...
 static const struct { const char *from; const char *to; } profileMap[] =
 {
+    { MOJOSHADER_PROFILE_GLSL120, MOJOSHADER_PROFILE_GLSL },
     { MOJOSHADER_PROFILE_NV2, MOJOSHADER_PROFILE_ARB1 },
 };
 
--- a/mojoshader.h	Sun Jun 29 00:15:52 2008 -0400
+++ b/mojoshader.h	Sun Jun 29 00:16:56 2008 -0400
@@ -338,6 +338,11 @@
 #define MOJOSHADER_PROFILE_GLSL "glsl"
 
 /*
+ * Profile string for GLSL 1.20: minor improvements to base GLSL spec.
+ */
+#define MOJOSHADER_PROFILE_GLSL120 "glsl120"
+
+/*
  * Profile string for OpenGL ARB 1.0 shaders: GL_ARB_(vertex|fragment)_program.
  */
 #define MOJOSHADER_PROFILE_ARB1 "arb1"
--- a/mojoshader_opengl.c	Sun Jun 29 00:15:52 2008 -0400
+++ b/mojoshader_opengl.c	Sun Jun 29 00:16:56 2008 -0400
@@ -383,15 +383,35 @@
 } // verify_extension
 
 
-static void parse_opengl_version(const char *verstr)
+static void parse_opengl_version_str(const char *verstr, int *maj, int *min)
 {
     if (verstr == NULL)
-        ctx->opengl_major = ctx->opengl_minor = 0;
+        *maj = *min = 0;
     else
-        sscanf(verstr, "%d.%d", &ctx->opengl_major, &ctx->opengl_minor);
+        sscanf(verstr, "%d.%d", maj, min);
+} // parse_opengl_version_str
+
+
+static inline void parse_opengl_version(const char *verstr)
+{
+    parse_opengl_version_str(verstr, &ctx->opengl_major, &ctx->opengl_minor);
 } // parse_opengl_version
 
 
+static int glsl_version_atleast(int maj, int min)
+{
+    int glslmin = 0;
+    int glslmaj = 0;
+    ctx->glGetError();  // flush any existing error state.
+    const GLenum enumval = GL_SHADING_LANGUAGE_VERSION_ARB;
+    const char *str = (const char *) ctx->glGetString(enumval);
+    if (ctx->glGetError() == GL_INVALID_ENUM)
+        return 0;  // this is a basic, 1.0-compliant implementation.
+    parse_opengl_version_str(str, &glslmaj, &glslmin);
+    return ( (glslmaj > maj) || ((glslmaj == maj) && (glslmin >= min)) );
+} // glsl_version_atleast
+
+
 static void load_extensions(void *(*lookup)(const char *fnname))
 {
     const char *extlist = NULL;
@@ -468,6 +488,17 @@
     #endif
 
     #if SUPPORT_PROFILE_GLSL
+    else if (strcmp(profile, MOJOSHADER_PROFILE_GLSL120) == 0)
+    {
+        MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shader_objects);
+        MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_vertex_shader);
+        MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_fragment_shader);
+        MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shading_language_100);
+        // if you got here, you have all the extensions.
+        if (!glsl_version_atleast(1, 2))
+            return 0;
+    } // else if
+
     else if (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0)
     {
         MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shader_objects);
@@ -502,6 +533,7 @@
     if (ctx->have_base_opengl)
     {
         static const char *priority[] = {
+            MOJOSHADER_PROFILE_GLSL120,
             MOJOSHADER_PROFILE_GLSL,
             MOJOSHADER_PROFILE_NV2,
             MOJOSHADER_PROFILE_ARB1,
@@ -585,7 +617,8 @@
     if (profile == NULL) {}
 
 #if SUPPORT_PROFILE_GLSL
-    else if (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0)
+    else if ( (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0) ||
+              (strcmp(profile, MOJOSHADER_PROFILE_GLSL120) == 0) )
     {
         ctx->profileMaxUniforms = impl_GLSL_MaxUniforms;
         ctx->profileCompileShader = impl_GLSL_CompileShader;