OpenGL glue now handles Uniform arrays. trunk
authorRyan C. Gordon <icculus@icculus.org>
Mon, 05 May 2008 21:20:06 -0400
branchtrunk
changeset 281 cb0ee573a33d
parent 280 61b2abd9c927
child 282 21d1615a627e
OpenGL glue now handles Uniform arrays. Completed untested and sort of crappy.
mojoshader_opengl.c
--- a/mojoshader_opengl.c	Mon May 05 02:50:19 2008 -0400
+++ b/mojoshader_opengl.c	Mon May 05 21:20:06 2008 -0400
@@ -70,6 +70,8 @@
     MOJOSHADER_glShader *vertex;
     MOJOSHADER_glShader *fragment;
     GLhandleARB handle;
+    uint32 constant_count;  // !!! FIXME: misnamed.
+    GLfloat *constants;  // !!! FIXME: misnamed.
     uint32 uniform_count;
     UniformMap *uniforms;
     uint32 attribute_count;
@@ -524,6 +526,7 @@
             shader_unref(program->fragment);
             Free(program->attributes);
             Free(program->uniforms);
+            Free(program->constants);
             Free(program);
         } // else
     } // if
@@ -614,8 +617,12 @@
     retval->fragment = pshader;
     retval->refcount = 1;
 
+    uint32 const_count = 0;
+
     if (vshader != NULL)
     {
+        if (const_count < vshader->parseData->constant_count)
+            const_count = vshader->parseData->constant_count;
         retval->attributes = (AttributeMap *) Malloc(sizeof (AttributeMap) *
                                         vshader->parseData->attribute_count);
         if (retval->attributes == NULL)
@@ -628,10 +635,21 @@
 
     if (pshader != NULL)
     {
+        if (const_count < pshader->parseData->constant_count)
+            const_count = pshader->parseData->constant_count;
+
         lookup_uniforms(retval, pshader);
         pshader->refcount++;
     } // if
 
+    if (const_count > 0)    
+    {
+        retval->constants = (GLfloat *) Malloc(sizeof (GLfloat) * const_count);
+        if (retval->constants == NULL)
+            goto link_program_fail;
+        retval->constant_count = const_count;
+    } // if
+
     return retval;
 
 link_program_fail:
@@ -639,6 +657,7 @@
     {
         Free(retval->uniforms);
         Free(retval->attributes);
+        Free(retval->constants);
         Free(retval);
     } // if
 
@@ -853,9 +872,95 @@
         const MOJOSHADER_uniformType type = u->type;
         const MOJOSHADER_shaderType shader_type = map->shader_type;
         const int index = u->index;
+        const int size = u->array_count;
         const GLint location = map->location;
 
-        if (shader_type == MOJOSHADER_TYPE_VERTEX)
+        // only use arrays for 'c' registers.
+        assert((size == 0) || (type == MOJOSHADER_UNIFORM_FLOAT));
+
+        if (size != 0)  // !!! FIXME: this code sucks.
+        {
+            // !!! FIXME: calculate this all at link time.
+            if (shader_type == MOJOSHADER_TYPE_VERTEX)
+            {
+                const MOJOSHADER_constant *c = ctx->bound_program->vertex->parseData->constants;
+                int hi = ctx->bound_program->vertex->parseData->constant_count;
+
+                int j;
+                GLfloat *ptr = ctx->bound_program->constants;
+
+                for (j = 0; j < hi; j++)
+                {
+                    if (c[j].type != MOJOSHADER_UNIFORM_FLOAT)
+                        continue;
+
+                    const int idx = c[j].index;
+                    if ( (idx >= index) && (idx < (index + size)) )
+                    {
+                        memcpy(ptr, &ctx->vs_reg_file_f[idx * 4], 16);  // !!! FIXME: 16
+                        memcpy(&ctx->vs_reg_file_f[idx * 4], &c->value.f, 16);  // !!! FIXME: 16
+                        ptr += 4;
+                    } // if
+                } // for
+
+                ctx->glUniform4fv(location, size, &ctx->vs_reg_file_f[index * 4]);
+
+                ptr = ctx->bound_program->constants;
+                for (j = 0; j < hi; j++)
+                {
+                    if (c[j].type != MOJOSHADER_UNIFORM_FLOAT)
+                        continue;
+
+                    const int idx = c[j].index;
+                    if ( (idx >= index) && (idx < (index + size)) )
+                    {
+                        memcpy(&ctx->vs_reg_file_f[idx * 4], ptr, 16);  // !!! FIXME: 16
+                        ptr += 4;
+                    } // if
+                } // for
+            } // if
+
+            else if (shader_type == MOJOSHADER_TYPE_PIXEL)
+            {
+                const MOJOSHADER_constant *c = ctx->bound_program->fragment->parseData->constants;
+                int hi = ctx->bound_program->fragment->parseData->constant_count;
+
+                int j;
+                GLfloat *ptr = ctx->bound_program->constants;
+
+                for (j = 0; j < hi; j++)
+                {
+                    if (c[j].type != MOJOSHADER_UNIFORM_FLOAT)
+                        continue;
+
+                    const int idx = c[j].index;
+                    if ( (idx >= index) && (idx < (index + size)) )
+                    {
+                        memcpy(ptr, &ctx->ps_reg_file_f[idx * 4], 16);  // !!! FIXME: 16
+                        memcpy(&ctx->ps_reg_file_f[idx * 4], &c->value.f, 16);  // !!! FIXME: 16
+                        ptr += 4;
+                    } // if
+                } // for
+
+                ctx->glUniform4fv(location, size, &ctx->ps_reg_file_f[index * 4]);
+
+                ptr = ctx->bound_program->constants;
+                for (j = 0; j < hi; j++)
+                {
+                    if (c[j].type != MOJOSHADER_UNIFORM_FLOAT)
+                        continue;
+
+                    const int idx = c[j].index;
+                    if ( (idx >= index) && (idx < (index + size)) )
+                    {
+                        memcpy(&ctx->ps_reg_file_f[idx * 4], ptr, 16);  // !!! FIXME: 16
+                        ptr += 4;
+                    } // if
+                } // for
+            } // else if
+        } // if
+
+        else if (shader_type == MOJOSHADER_TYPE_VERTEX)
         {
             if (type == MOJOSHADER_UNIFORM_FLOAT)
                 ctx->glUniform4fv(location, 1, &ctx->vs_reg_file_f[index * 4]);