Revision: 49594
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49594
Author:   kupoman
Date:     2012-08-06 02:06:13 +0000 (Mon, 06 Aug 2012)
Log Message:
-----------
Allowing multiple fragment shaders to be added to a material by mixing them 
together before the shader is compiled. This works so far with simple shaders, 
but more complicated shaders, or shaders that declare a version, may break the 
system.

Modified Paths:
--------------
    branches/ge_harmony/source/blender/gpu/intern/gpu_material.c

Modified: branches/ge_harmony/source/blender/gpu/intern/gpu_material.c
===================================================================
--- branches/ge_harmony/source/blender/gpu/intern/gpu_material.c        
2012-08-06 00:53:26 UTC (rev 49593)
+++ branches/ge_harmony/source/blender/gpu/intern/gpu_material.c        
2012-08-06 02:06:13 UTC (rev 49594)
@@ -47,6 +47,7 @@
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
 
 #include "BKE_anim.h"
 #include "BKE_colortools.h"
@@ -213,32 +214,72 @@
        if (material->outlink) {
                GPUNodeLink *outlink;
                GPUShader *shader;
+               CustomShader *cs;
+               DynStr *frag_vars = BLI_dynstr_new(), *frag_funcs = 
BLI_dynstr_new(), *frag_main = BLI_dynstr_new();
+               char *frag_funcs_c, *frag_main_c;
+               char *fname = "void functionx";
+               int fcount = 0;
                char *frag=NULL, *vert=NULL, *geom=NULL;
                int geom_in = SHADER_GEOM_IN_TRIS;
                int geom_out = SHADER_GEOM_OUT_TRIANGLE_STRIP;
                int source_len;
 
-               CustomShader *cs = 
(CustomShader*)material->ma->custom_shaders.first;
-
+               cs = (CustomShader*)material->ma->custom_shaders.first;
+               BLI_dynstr_append(frag_main, "\n\nvoid main()\n{\n");
                while (cs) {
                        if (!cs->shader || !cs->shader->source) {
                                cs = cs->next;
                                continue;
                        }
 
-                       if (cs->shader->type & SHADER_TYPE_VERTEX)
-                               vert = BLI_strdup(cs->shader->source);
-                       else if (cs->shader->type & SHADER_TYPE_FRAGMENT)
-                               frag = BLI_strdup(cs->shader->source);
+                       if (cs->shader->type & SHADER_TYPE_VERTEX) {
+                               if (vert) {
+                                       MEM_freeN(vert);
+                               }
+                               else {
+                                       vert = BLI_strdup(cs->shader->source);
+                               }
+                       }
+
+                       else if (cs->shader->type & SHADER_TYPE_FRAGMENT) {
+                               char *source = cs->shader->source;
+                               char *split = strstr(source, "void main") - 1;
+                               fname[13] = '0' + fcount++;
+                               BLI_dynstr_nappend(frag_vars, source, 
split-source);
+                               BLI_dynstr_append(frag_funcs, fname);
+                               BLI_dynstr_append(frag_funcs, split+10);
+                               BLI_dynstr_appendf(frag_main, "\t%s();\n", 
fname+5);
+                       }
+
                        else if (cs->shader->type & SHADER_TYPE_GEOMETRY) {
-                               geom = BLI_strdup(cs->shader->source);
-                               geom_in = cs->shader->geom_in;
-                               geom_out = cs->shader->geom_out;
+                               if (geom) {
+                                       MEM_freeN(geom);
+                               }
+                               else {
+                                       geom = BLI_strdup(cs->shader->source);
+                                       geom_in = cs->shader->geom_in;
+                                       geom_out = cs->shader->geom_out;
+                               }
                        }
 
                        cs = cs->next;
                }
 
+               if (fcount > 0) {
+                       BLI_dynstr_append(frag_main, "}\n");
+                       frag_funcs_c = BLI_dynstr_get_cstring(frag_funcs);
+                       frag_main_c = BLI_dynstr_get_cstring(frag_main);
+                       BLI_dynstr_append(frag_vars, frag_funcs_c);
+                       BLI_dynstr_append(frag_vars, frag_main_c);
+                       MEM_freeN(frag_funcs_c);
+                       MEM_freeN(frag_main_c);
+                       frag = BLI_dynstr_get_cstring(frag_vars);
+               }
+               
+               BLI_dynstr_free(frag_vars);
+               BLI_dynstr_free(frag_funcs);
+               BLI_dynstr_free(frag_main);
+
                outlink = material->outlink;
                material->pass = GPU_generate_pass(&material->nodes, outlink,
                        &material->attribs, &material->builtins, 
material->ma->id.name,

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to