Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-11-03 18:32:26 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-11-03 18:32:26 +0400
commite02b23b81ab05579c0ee11ee3a1acb283643e528 (patch)
tree59b14c01bcb4c274d57c89a42e5a5d80c41ff06d /source/blender/makesrna
parent615fe0295fe13c229d7376b02a50ac110b636c47 (diff)
Render API: shader script node for custom shaders.
* Shader script node added, which stores either a link to a text datablock or file on disk, and has functions to add and remove sockets. * Callback RenderEngine.update_script_node(self, node) added for render engines to compile the shader and update the node with new sockets. Thanks to Thomas, Lukas and Dalai for the implementation.
Diffstat (limited to 'source/blender/makesrna')
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c205
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_render.c28
4 files changed, 233 insertions, 4 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index a9dbbe4273f..5f667db4425 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -457,6 +457,7 @@ extern StructRNA RNA_ShaderNodeMath;
extern StructRNA RNA_ShaderNodeMixRGB;
extern StructRNA RNA_ShaderNodeNormal;
extern StructRNA RNA_ShaderNodeOutput;
+extern StructRNA RNA_ShaderNodeScript;
extern StructRNA RNA_ShaderNodeRGB;
extern StructRNA RNA_ShaderNodeRGBCurve;
extern StructRNA RNA_ShaderNodeRGBToBW;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index be9a2d8c613..85df288b38b 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -35,12 +35,16 @@
#include "rna_internal_types.h"
#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_text_types.h"
#include "DNA_texture_types.h"
#include "BKE_animsys.h"
@@ -48,9 +52,9 @@
#include "BKE_node.h"
#include "BKE_image.h"
#include "BKE_texture.h"
+#include "BKE_idprop.h"
-#include "BLI_math.h"
-#include "BLI_utildefines.h"
+#include "IMB_imbuf.h"
#include "WM_types.h"
@@ -206,6 +210,8 @@ EnumPropertyItem prop_wave_items[] = {
#include "BLI_linklist.h"
+#include "BKE_global.h"
+
#include "ED_node.h"
#include "RE_pipeline.h"
@@ -995,6 +1001,125 @@ static void rna_NodeOutputFileSlotLayer_name_set(PointerRNA *ptr, const char *va
}
}
+static bNodeSocket *rna_ShaderNodeScript_find_socket(bNode *node, const char *name, int is_output)
+{
+ bNodeSocket *sock;
+
+ if (is_output) {
+ for (sock = node->outputs.first; sock; sock = sock->next)
+ if (strcmp(sock->name, name)==0)
+ return sock;
+ }
+ else {
+ for (sock = node->inputs.first; sock; sock = sock->next)
+ if (strcmp(sock->name, name)==0)
+ return sock;
+ }
+
+ return NULL;
+}
+
+static void rna_ShaderNodeScript_remove_socket(ID *id, bNode *node, bNodeSocket *sock)
+{
+ bNodeTree *ntree = (bNodeTree *)id;
+
+ nodeRemoveSocket(ntree, node, sock);
+
+ ED_node_generic_update(G.main, ntree, node);
+}
+
+static bNodeSocket *rna_ShaderNodeScript_add_socket(ID *id, bNode *node, const char *name, int type, int is_output)
+{
+ bNodeTree *ntree = (bNodeTree *)id;
+ bNodeSocket *sock;
+
+ /* replace existing socket with the same name, to keep it unique */
+ sock = rna_ShaderNodeScript_find_socket(node, name, is_output);
+ if (sock)
+ nodeRemoveSocket(ntree, node, sock);
+ sock = nodeAddSocket(ntree, node, (is_output ? SOCK_OUT : SOCK_IN), name, type);
+
+ ED_node_generic_update(G.main, ntree, node);
+
+ return sock;
+}
+
+static void rna_ShaderNodeScript_mode_set(PointerRNA *ptr, int value)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeShaderScript *nss = node->storage;
+
+ if (nss->mode != value) {
+ nss->mode = value;
+ nss->filepath[0] = '\0';
+ nss->flag &= ~NODE_SCRIPT_AUTO_UPDATE;
+
+ /* replace text datablock by filepath */
+ if (node->id) {
+ Text *text = (Text*)node->id;
+
+ if(value == NODE_SCRIPT_EXTERNAL && text->name) {
+ BLI_strncpy(nss->filepath, text->name, sizeof(nss->filepath));
+ BLI_path_rel(nss->filepath, G.main->name);
+ }
+
+ id_us_min(node->id);
+ node->id = NULL;
+ }
+
+ /* remove any bytecode */
+ if(nss->bytecode) {
+ MEM_freeN(nss->bytecode);
+ nss->bytecode = NULL;
+ }
+
+ nss->bytecode_hash[0] = '\0';
+ }
+}
+
+static void rna_ShaderNodeScript_bytecode_get(PointerRNA *ptr, char *value)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeShaderScript *nss = node->storage;
+
+ strcpy(value, (nss->bytecode)? nss->bytecode: "");
+}
+
+static int rna_ShaderNodeScript_bytecode_length(PointerRNA *ptr)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeShaderScript *nss = node->storage;
+
+ return (nss->bytecode) ? strlen(nss->bytecode) : 0;
+}
+
+static void rna_ShaderNodeScript_bytecode_set(PointerRNA *ptr, const char *value)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeShaderScript *nss = node->storage;
+
+ if (nss->bytecode)
+ MEM_freeN(nss->bytecode);
+
+ if (value && value[0])
+ nss->bytecode = BLI_strdup(value);
+ else
+ nss->bytecode = NULL;
+}
+
+static IDProperty *rna_ShaderNodeScript_idprops(PointerRNA *ptr, int create)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeShaderScript *nss = node->storage;
+
+ if (create && !nss->prop) {
+ IDPropertyTemplate val = {0};
+ nss->prop = IDP_New(IDP_GROUP, &val, "RNA_ShaderNodeScript ID properties");
+ }
+
+ return nss->prop;
+}
+
#else
static EnumPropertyItem prop_image_layer_items[] = {
@@ -1035,6 +1160,12 @@ static EnumPropertyItem node_glossy_items[] = {
{0, NULL, 0, NULL, NULL}
};
+static EnumPropertyItem node_script_mode_items[] = {
+ {NODE_SCRIPT_INTERNAL, "INTERNAL", 0, "Internal", "Use internal text datablock"},
+ {NODE_SCRIPT_EXTERNAL, "EXTERNAL", 0, "External", "Use external .osl or oso file"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#define MaxNodes 50000
enum
@@ -1707,6 +1838,76 @@ static void def_glossy(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_sh_script(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *prop, *parm;
+
+ prop = RNA_def_property(srna, "script", 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 | PROP_ID_REFCOUNT);
+ RNA_def_property_ui_text(prop, "Script", "Internal shader script to define the shader");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "NodeShaderScript", "storage");
+ RNA_def_struct_idprops_func(srna, "rna_ShaderNodeScript_idprops");
+
+ prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
+ RNA_def_property_ui_text(prop, "File Path", "Shader script path");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_ShaderNodeScript_mode_set", NULL);
+ RNA_def_property_enum_items(prop, node_script_mode_items);
+ RNA_def_property_ui_text(prop, "Script Source", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "use_auto_update", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_SCRIPT_AUTO_UPDATE);
+ RNA_def_property_ui_text(prop, "Auto Update", "Automatically updates the shader when the .osl file changes - external scripts only");
+
+ prop = RNA_def_property(srna, "bytecode", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_ShaderNodeScript_bytecode_get",
+ "rna_ShaderNodeScript_bytecode_length", "rna_ShaderNodeScript_bytecode_set");
+ RNA_def_property_ui_text(prop, "Bytecode", "Compile bytecode for shader script node");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "bytecode_hash", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Bytecode Hash", "Hash of compile bytecode, for quick equality checking");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ /* needs to be reset to avoid bad pointer type in API functions below */
+ RNA_def_struct_sdna_from(srna, "bNode", NULL);
+
+ /* API functions */
+
+ func = RNA_def_function(srna, "find_socket", "rna_ShaderNodeScript_find_socket");
+ RNA_def_function_ui_description(func, "Find a socket by name");
+ parm = RNA_def_string(func, "name", "", 0, "Socket name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ /*parm =*/ RNA_def_boolean(func, "is_output", FALSE, "Output", "Whether the socket is an output");
+ parm = RNA_def_pointer(func, "result", "NodeSocket", "", "");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "add_socket", "rna_ShaderNodeScript_add_socket");
+ RNA_def_function_ui_description(func, "Add a socket socket");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ parm = RNA_def_string(func, "name", "", 0, "Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_enum(func, "type", node_socket_type_items, SOCK_FLOAT, "Type", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ /*parm =*/ RNA_def_boolean(func, "is_output", FALSE, "Output", "Whether the socket is an output");
+ parm = RNA_def_pointer(func, "result", "NodeSocket", "", "");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove_socket", "rna_ShaderNodeScript_remove_socket");
+ RNA_def_function_ui_description(func, "Remove a socket socket");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ parm = RNA_def_pointer(func, "sock", "NodeSocket", "Socket", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+}
+
/* -- Compositor Nodes ------------------------------------------------------ */
static void def_cmp_alpha_over(StructRNA *srna)
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
index 6d97e959112..c45c9b71442 100644
--- a/source/blender/makesrna/intern/rna_nodetree_types.h
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -82,7 +82,8 @@ DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LI
DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" )
DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" )
DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" )
-DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", BumpNode, "Bump", "" )
+DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", BumpNode, "Bump", "" )
+DefNode( ShaderNode, SH_NODE_SCRIPT, def_sh_script, "SCRIPT", Script, "Script", "" )
DefNode( ShaderNode, SH_NODE_TEX_IMAGE, def_sh_tex_image, "TEX_IMAGE", TexImage, "Image Texture", "" )
DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TEX_ENVIRONMENT", TexEnvironment, "Environment Texture","" )
DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" )
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 7a638e9e40b..56497e96c67 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -129,6 +129,24 @@ static void engine_view_draw(RenderEngine *engine, const struct bContext *contex
RNA_parameter_list_free(&list);
}
+static void engine_update_script_node(RenderEngine *engine, struct bNodeTree *ntree, struct bNode *node)
+{
+ extern FunctionRNA rna_RenderEngine_update_script_node_func;
+ PointerRNA ptr, nodeptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+ RNA_pointer_create((ID*)ntree, &RNA_Node, node, &nodeptr);
+ func = &rna_RenderEngine_update_script_node_func;
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "node", &nodeptr);
+ engine->type->ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
/* RenderEngine registration */
static void rna_RenderEngine_unregister(Main *UNUSED(bmain), StructRNA *type)
@@ -149,7 +167,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
RenderEngineType *et, dummyet = {NULL};
RenderEngine dummyengine = {NULL};
PointerRNA dummyptr;
- int have_function[4];
+ int have_function[5];
/* setup dummy engine & engine type to store static properties in */
dummyengine.type = &dummyet;
@@ -188,6 +206,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
et->render = (have_function[1]) ? engine_render : NULL;
et->view_update = (have_function[2]) ? engine_view_update : NULL;
et->view_draw = (have_function[3]) ? engine_view_draw : NULL;
+ et->update_script_node = (have_function[4]) ? engine_update_script_node : NULL;
BLI_addtail(&R_engines, et);
@@ -300,6 +319,13 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
RNA_def_pointer(func, "context", "Context", "", "");
+ /* shader script callbacks */
+ func = RNA_def_function(srna, "update_script_node", NULL);
+ RNA_def_function_ui_description(func, "Compile shader script node");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ prop = RNA_def_pointer(func, "node", "Node", "", "");
+ RNA_def_property_flag(prop, PROP_RNAPTR);
+
/* tag for redraw */
RNA_def_function(srna, "tag_redraw", "engine_tag_redraw");
RNA_def_function_ui_description(func, "Request redraw for viewport rendering");