Index: source/blender/blenkernel/BKE_node.h
===================================================================
--- source/blender/blenkernel/BKE_node.h (revision 27607)
+++ source/blender/blenkernel/BKE_node.h (working copy)
@@ -228,6 +228,7 @@
#define SH_NODE_VALTORGB 104
#define SH_NODE_RGBTOBW 105
#define SH_NODE_TEXTURE 106
+#define SH_NODE_GLSL 124
#define SH_NODE_NORMAL 107
#define SH_NODE_GEOMETRY 108
#define SH_NODE_MAPPING 109
Index: source/blender/blenkernel/intern/node.c
===================================================================
--- source/blender/blenkernel/intern/node.c (revision 27607)
+++ source/blender/blenkernel/intern/node.c (working copy)
@@ -3120,6 +3120,7 @@
nodeRegisterType(ntypelist, &sh_node_value);
nodeRegisterType(ntypelist, &sh_node_rgb);
nodeRegisterType(ntypelist, &sh_node_texture);
+ nodeRegisterType(ntypelist, &sh_node_glsl);
nodeRegisterType(ntypelist, &node_dynamic_typeinfo);
nodeRegisterType(ntypelist, &sh_node_invert);
nodeRegisterType(ntypelist, &sh_node_seprgb);
Index: source/blender/gpu/intern/gpu_codegen.c
===================================================================
--- source/blender/gpu/intern/gpu_codegen.c (revision 27607)
+++ source/blender/gpu/intern/gpu_codegen.c (working copy)
@@ -92,6 +92,11 @@
ListBase outputs;
};
+struct GPUCode {
+ struct GPUCode *next, *prev;
+ char* body;
+};
+
struct GPUNodeLink {
GPUNodeStack *socket;
@@ -299,6 +304,79 @@
}
}
+char* GPU_parse_function( char *code )
+{
+ GHash *hash;
+ GPUFunction *function;
+ int i, type, qual;
+
+ if(!FUNCTION_HASH) {
+ FUNCTION_HASH = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+ gpu_parse_functions_string(FUNCTION_HASH, datatoc_gpu_shader_material_glsl);
+ /*FUNCTION_PROTOTYPES = gpu_generate_function_prototyps(FUNCTION_HASH);
+ FUNCTION_LIB = GPU_shader_create_lib(datatoc_gpu_shader_material_glsl);*/
+ }
+ hash = FUNCTION_HASH;
+
+ while((code = strstr(code, "void "))) {
+ function = MEM_callocN(sizeof(GPUFunction), "GPUFunction");
+
+ code = gpu_str_skip_token(code, NULL, 0);
+ code = gpu_str_skip_token(code, function->name, MAX_FUNCTION_NAME);
+
+ /* get parameters */
+ while(*code && *code != ')') {
+ /* test if it's an input or output */
+ qual = FUNCTION_QUAL_IN;
+ if(gpu_str_prefix(code, "out "))
+ qual = FUNCTION_QUAL_OUT;
+ if(gpu_str_prefix(code, "inout "))
+ qual = FUNCTION_QUAL_INOUT;
+ if((qual != FUNCTION_QUAL_IN) || gpu_str_prefix(code, "in "))
+ code = gpu_str_skip_token(code, NULL, 0);
+
+ /* test for type */
+ type= 0;
+ for(i=1; i<=16; i++) {
+ if(GPU_DATATYPE_STR[i] && gpu_str_prefix(code, GPU_DATATYPE_STR[i])) {
+ type= i;
+ break;
+ }
+ }
+
+ if(!type && gpu_str_prefix(code, "sampler2DShadow"))
+ type= GPU_SHADOW2D;
+ if(!type && gpu_str_prefix(code, "sampler1D"))
+ type= GPU_TEX1D;
+ if(!type && gpu_str_prefix(code, "sampler2D"))
+ type= GPU_TEX2D;
+
+ if(type) {
+ /* add paramater */
+ code = gpu_str_skip_token(code, NULL, 0);
+ code = gpu_str_skip_token(code, NULL, 0);
+ function->paramqual[function->totparam]= qual;
+ function->paramtype[function->totparam]= type;
+ function->totparam++;
+ }
+ else {
+ fprintf(stderr, "GPU invalid function parameter in %s.\n", function->name);
+ break;
+ }
+ }
+
+ if(strlen(function->name) == 0 || function->totparam == 0) {
+ fprintf(stderr, "GPU functions parse error.\n");
+ MEM_freeN(function);
+ break;
+ }
+
+ BLI_ghash_insert(hash, function->name, function);
+ return function->name;
+ }
+ return 0;
+}
+
#if 0
static char *gpu_generate_function_prototyps(GHash *hash)
{
@@ -638,6 +716,14 @@
BLI_dynstr_append(ds, "\n");
}
+static void codegen_define_functions(DynStr *ds, ListBase* functions )
+{
+ GPUCode* code;
+ for (code=functions->first; code; code=code->next) {
+ BLI_dynstr_printf(ds, code->body );
+ }
+}
+
static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *finaloutput)
{
GPUNode *node;
@@ -689,13 +775,15 @@
BLI_dynstr_append(ds, ";\n");
}
-static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const char *name)
+static char *code_generate_fragment(ListBase *codes, ListBase *nodes, GPUOutput *output, const char *name)
{
DynStr *ds = BLI_dynstr_new();
char *code;
/*BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);*/
+ codegen_define_functions(ds, codes );
+
codegen_set_unique_ids(nodes);
codegen_print_uniforms_functions(ds, nodes);
@@ -908,6 +996,15 @@
}
}
+/* Code Functions */
+
+GPUCode *GPU_code_begin(char * body)
+{
+ GPUCode *code = MEM_callocN(sizeof(GPUCode), "GPUCode");
+ code->body = body;
+ return code;
+}
+
/* Node Functions */
GPUNode *GPU_node_begin(char *name)
@@ -1392,7 +1489,7 @@
}
}
-GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, const char *name)
+GPUPass *GPU_generate_pass(ListBase *codes, ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, const char *name)
{
GPUShader *shader;
GPUPass *pass;
@@ -1410,7 +1507,7 @@
gpu_nodes_get_builtin_flag(nodes, builtins);
/* generate code and compile with opengl */
- fragmentcode = code_generate_fragment(nodes, outlink->output, name);
+ fragmentcode = code_generate_fragment(codes, nodes, outlink->output, name);
vertexcode = code_generate_vertex(nodes);
shader = GPU_shader_create(vertexcode, fragmentcode, datatoc_gpu_shader_material_glsl); /*FUNCTION_LIB);*/
MEM_freeN(fragmentcode);
Index: source/blender/gpu/intern/gpu_codegen.h
===================================================================
--- source/blender/gpu/intern/gpu_codegen.h (revision 27607)
+++ source/blender/gpu/intern/gpu_codegen.h (working copy)
@@ -66,7 +66,7 @@
struct GPUPass;
typedef struct GPUPass GPUPass;
-GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
+GPUPass *GPU_generate_pass(ListBase* functions, ListBase *nodes, struct GPUNodeLink *outlink,
struct GPUVertexAttribs *attribs, int *builtin, const char *name);
struct GPUShader *GPU_pass_shader(GPUPass *pass);
Index: source/blender/gpu/intern/gpu_material.c
===================================================================
--- source/blender/gpu/intern/gpu_material.c (revision 27607)
+++ source/blender/gpu/intern/gpu_material.c (working copy)
@@ -78,6 +78,7 @@
Material *ma;
/* for creating the material */
+ ListBase codes;
ListBase nodes;
GPUNodeLink *outlink;
@@ -190,7 +191,7 @@
GPUShader *shader;
outlink = material->outlink;
- material->pass = GPU_generate_pass(&material->nodes, outlink,
+ material->pass = GPU_generate_pass(&material->codes, &material->nodes, outlink,
&material->attribs, &material->builtins, material->ma->id.name);
if(!material->pass)
@@ -367,6 +368,12 @@
BLI_addtail(&material->nodes, node);
}
+
+void GPU_material_add_code(GPUMaterial* material, GPUCode* code)
+{
+ BLI_addtail(&material->codes, code);
+}
+
/* Code generation */
static GPUNodeLink *lamp_get_visibility(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **lv, GPUNodeLink **dist)
Index: source/blender/gpu/GPU_material.h
===================================================================
--- source/blender/gpu/GPU_material.h (revision 27607)
+++ source/blender/gpu/GPU_material.h (working copy)
@@ -38,6 +38,7 @@
#endif
struct Image;
+struct Text;
struct ImageUser;
struct Material;
struct Object;
@@ -54,6 +55,7 @@
struct GPULamp;
typedef struct GPUNode GPUNode;
+typedef struct GPUCode GPUCode;
typedef struct GPUNodeLink GPUNodeLink;
typedef struct GPUMaterial GPUMaterial;
typedef struct GPULamp GPULamp;
@@ -110,6 +112,10 @@
GPUNodeLink *GPU_socket(GPUNodeStack *sock);
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
+char* GPU_parse_function(char *code);
+GPUCode* GPU_code_begin(char * body);
+void GPU_add_function(GPUMaterial* mat, GPUCode *code);
+
int GPU_link(GPUMaterial *mat, char *name, ...);
int GPU_stack_link(GPUMaterial *mat, char *name, GPUNodeStack *in, GPUNodeStack *out, ...);
Index: source/blender/makesrna/intern/rna_nodetree_types.h
===================================================================
--- source/blender/makesrna/intern/rna_nodetree_types.h (revision 27607)
+++ source/blender/makesrna/intern/rna_nodetree_types.h (working copy)
@@ -31,6 +31,7 @@
DefNode( ShaderNode, SH_NODE_VALTORGB, def_colorramp, "VALTORGB", ValToRGB, "Value to RGB", "" )
DefNode( ShaderNode, SH_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
DefNode( ShaderNode, SH_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" )
+DefNode( ShaderNode, SH_NODE_GLSL, def_glsl , "GLSL", GLSL, "GLSL", "" )
DefNode( ShaderNode, SH_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" )
DefNode( ShaderNode, SH_NODE_GEOMETRY, def_sh_geometry, "GEOMETRY", Geometry, "Geometry", "" )
DefNode( ShaderNode, SH_NODE_MAPPING, def_sh_mapping, "MAPPING", Mapping, "Mapping", "" )
Index: source/blender/makesrna/intern/rna_nodetree.c
===================================================================
--- source/blender/makesrna/intern/rna_nodetree.c (revision 27607)
+++ source/blender/makesrna/intern/rna_nodetree.c (working copy)
@@ -695,7 +695,18 @@
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
}
+static void def_glsl(StructRNA *srna)
+{
+ PropertyRNA *prop;
+ prop = RNA_def_property(srna, "shader", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "Text");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "GLSL Shader Text", "");
+ RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
+}
+
/* -- Shader Nodes ---------------------------------------------------------- */
static void def_sh_material(StructRNA *srna)
Index: source/blender/nodes/intern/SHD_nodes/SHD_glsl.c
===================================================================
--- source/blender/nodes/intern/SHD_nodes/SHD_glsl.c (revision 0)
+++ source/blender/nodes/intern/SHD_nodes/SHD_glsl.c (revision 0)
@@ -0,0 +1,90 @@
+/**
+ * $Id: SHD_glsl.c 26958 2010-03-19 15:45:19Z blendix $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Matthias Fauconneau
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BKE_text.h"
+#include "../SHD_util.h"
+#include "GPU_material.h"
+
+typedef struct Text Text;
+
+/* **************** GLSL ******************** */
+static bNodeSocketType sh_node_glsl_in[]= {
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, /* no limit */
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, /* no limit */
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, /* no limit */
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, /* no limit */
+ { -1, 0, "" }
+};
+static bNodeSocketType sh_node_glsl_out[]= {
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void node_shader_exec_glsl(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+}
+
+static int gpu_shader_glsl(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out)
+{
+ Text* shader = (Text*)node->id;
+ if(shader) {
+ char* name = GPU_parse_function( txt_to_buf(shader) );
+ if( name && GPU_stack_link(mat, name, in, out ) ) {
+ GPU_material_add_code(mat, GPU_code_begin( txt_to_buf(shader) ) );
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else
+ return 0;
+}
+
+bNodeType sh_node_glsl= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ SH_NODE_GLSL,
+ /* name */ "GLSL",
+ /* width+range */ 120, 80, 240,
+ /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW,
+ /* input sock */ sh_node_glsl_in,
+ /* output sock */ sh_node_glsl_out,
+ /* storage */ "",
+ /* execfunc */ node_shader_exec_glsl,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL, NULL, NULL,
+ /* gpufunc */ gpu_shader_glsl
+
+};
+
Index: source/blender/nodes/SHD_node.h
===================================================================
--- source/blender/nodes/SHD_node.h (revision 27607)
+++ source/blender/nodes/SHD_node.h (working copy)
@@ -48,6 +48,7 @@
extern bNodeType sh_node_valtorgb;
extern bNodeType sh_node_rgbtobw;
extern bNodeType sh_node_texture;
+extern bNodeType sh_node_glsl;
extern bNodeType sh_node_normal;
extern bNodeType sh_node_geom;
extern bNodeType sh_node_mapping;
Index: source/blender/editors/space_node/drawnode.c
===================================================================
--- source/blender/editors/space_node/drawnode.c (revision 27607)
+++ source/blender/editors/space_node/drawnode.c (working copy)
@@ -286,6 +286,11 @@
}
}
+static void node_buts_glsl(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiItemR(layout, "", 0, ptr, "shader", 0);
+}
+
static void node_buts_math(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
uiItemR(layout, "", 0, ptr, "operation", 0);
@@ -425,6 +430,9 @@
case SH_NODE_TEXTURE:
ntype->uifunc= node_buts_texture;
break;
+ case SH_NODE_GLSL:
+ ntype->uifunc= node_buts_glsl;
+ break;
case SH_NODE_NORMAL:
ntype->uifunc= node_buts_normal;
break;