[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49594] branches/ge_harmony/source/blender /gpu/intern/gpu_material.c: Allowing multiple fragment shaders to be added to a material by mixing them together before the shader is compiled .

Daniel Stokes kupomail at gmail.com
Mon Aug 6 04:06:15 CEST 2012


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,




More information about the Bf-blender-cvs mailing list