--- a/src/tools/genglsl.c Fri Sep 17 20:08:50 2010 +1000 +++ b/src/tools/genglsl.c Wed Dec 08 18:33:23 2010 +1000 @@ -37,10 +37,16 @@ FRAGMENT_SHADER = 1 } shader_type_t; +typedef struct uniform { + const char *name; + const char *var_name; +} *uniform_t; + typedef struct shader { shader_type_t type; const char *name; char *body; + GList *uniforms; } *shader_t; typedef struct program { @@ -86,6 +92,7 @@ shader->name = strdup(g_strstrip(buf+8)); shader->body = malloc(DEF_ALLOC_SIZE); shader->body[0] = '\0'; + shader->uniforms = 0; current_size = DEF_ALLOC_SIZE; current_posn = 0; result->shaders = g_list_append(result->shaders, shader); @@ -96,12 +103,14 @@ shader->name = strdup(g_strstrip(buf+10)); shader->body = malloc(DEF_ALLOC_SIZE); shader->body[0] = '\0'; + shader->uniforms = 0; current_size = DEF_ALLOC_SIZE; current_posn = 0; result->shaders = g_list_append(result->shaders, shader); } else if( strncmp( buf, "#program ", 9 ) == 0 ) { shader = NULL; program_t program = malloc(sizeof(struct program)); + assert( program != NULL ); char *rest = buf+9; char *equals = strchr(rest, '='); if( equals == NULL ) { @@ -115,6 +124,23 @@ for(i=0;program->shader_names[i] != NULL; i++ ); if( i > result->max_shaders ) result->max_shaders = i; + } else if( strncmp( buf, "#uniform ", 9 ) == 0 ) { + uniform_t uniform = malloc(sizeof(struct uniform)); + assert( uniform != NULL ); + if( shader == NULL ) { + fprintf( stderr, "Error: #uniform specified outside of shader: %s\n", buf ); + exit(2); + } + char *rest = buf+9; + char *equals = strchr(rest, '='); + if( equals == NULL ) { + fprintf( stderr, "Error: invalid program line %s\n", buf ); + exit(2); + } + *equals = '\0'; + uniform->name = g_strdup(g_strstrip(rest)); + uniform->var_name = g_strdup(g_strstrip(equals+1)); + shader->uniforms = g_list_append(shader->uniforms, uniform); } else if( shader != NULL ) { size_t len = strlen(buf); if( current_posn + len > current_size ) { @@ -149,6 +175,17 @@ } } +static uniform_t find_uniform_name( GList *list, const char *name ) +{ + GList *ptr; + for( ptr = list; ptr != NULL; ptr = ptr->next ) { + uniform_t data = (uniform_t)list->data; + if( strcmp( data->name, name ) == 0 ) + return data; + } + return NULL; +} + static void writeHeader( FILE *out, glsldata_t data ) { fprintf( out, "/*\n * This file automatically generated by genglsl from %s\n */\n", data->filename ); @@ -168,12 +205,22 @@ fprintf( f, "typedef enum {\n" ); const char *last_name = NULL; int count = 0; + GList *unique_uniforms; + int uniform_count = 0; GList *shader_ptr; for( shader_ptr = data->shaders; shader_ptr != NULL; shader_ptr = shader_ptr->next ) { count++; shader_t shader = (shader_t)shader_ptr->data; fprintf( f, " %s,\n", shader->name ); last_name = shader->name; + GList *uniform_ptr; + for( uniform_ptr = shader->uniforms; uniform_ptr != NULL; uniform_ptr = uniform_ptr->next ) { + uniform_t uniform = (uniform_t)uniform_ptr->data; + if( find_uniform_name(unique_uniforms, uniform->name) == NULL ) { + unique_uniforms = g_list_append( unique_uniforms, uniform ); + uniform_count++; + } + } } fprintf( f, "} shader_id;\n\n" ); @@ -184,6 +231,7 @@ fprintf( f, "#define GLSL_NO_SHADER -1\n\n" ); fprintf( f, "#define GLSL_VERTEX_SHADER 1\n" ); fprintf( f, "#define GLSL_FRAGMENT_SHADER 2\n" ); + fprintf( f, "#define GLSL_NUM_UNIFORMS %d\n", uniform_count ); fprintf( f, "typedef enum {\n" ); last_name = NULL;