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:
authorLukas Tönne <lukas.toenne@gmail.com>2014-02-24 14:24:43 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2014-02-24 14:35:32 +0400
commitd59f53f7b7dac5eff66fcf182f2cdc7dfabd6f87 (patch)
tree41939ef555fe97606d1b59b83ddacc77179bc7e9 /intern/cycles/app
parent7078fb936ab756c4741a56ba6036e33513bf02d3 (diff)
Support for generic OSL shader parameters in the Cycles standalone XML
reader. To make a generic OSL shader connectable to other nodes, the parameters must be declared via "input" and "output" child elements: <osl_shader name="tex" src="./osl/stripes.osl"> <input name="Stripes" type="int" /> <output name="ColorOut" type="color" /> </osl_shader> `name` must be the same as the OSL shader parameter name. `type` must be one of float, int, color, vector, point, normal, closure, string (matching cycles socket types) Beyond this the OSL script nodes then work just like all other nodes. OSL parameter sockets can be connected to other cycles nodes: <connect from="checker color" to="tex Stripes" /> <connect from="tex ColorOut" to="floor_closure color" /> They can set default values for the input sockets by attributes of the main node element: <osl_shader name="tex" src="./osl/stripes.osl" Stripes="3" > <input name="Stripes" type="int" /> <output name="ColorOut" type="color" /> </osl_shader> This system of specifying custom attributes should probably be changed, since it can easily create name conflicts and arbitrarily long elements. But that is a different issue to be solved for all nodes in general.
Diffstat (limited to 'intern/cycles/app')
-rw-r--r--intern/cycles/app/cycles_xml.cpp76
1 files changed, 60 insertions, 16 deletions
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index eef7d02e849..4557a6a688b 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -219,6 +219,35 @@ static bool xml_read_enum(ustring *str, ShaderEnum& enm, pugi::xml_node node, co
return false;
}
+static ShaderSocketType xml_read_socket_type(pugi::xml_node node, const char *name)
+{
+ pugi::xml_attribute attr = node.attribute(name);
+
+ if(attr) {
+ string value = attr.value();
+ if (string_iequals(value, "float"))
+ return SHADER_SOCKET_FLOAT;
+ else if (string_iequals(value, "int"))
+ return SHADER_SOCKET_INT;
+ else if (string_iequals(value, "color"))
+ return SHADER_SOCKET_COLOR;
+ else if (string_iequals(value, "vector"))
+ return SHADER_SOCKET_VECTOR;
+ else if (string_iequals(value, "point"))
+ return SHADER_SOCKET_POINT;
+ else if (string_iequals(value, "normal"))
+ return SHADER_SOCKET_NORMAL;
+ else if (string_iequals(value, "closure"))
+ return SHADER_SOCKET_CLOSURE;
+ else if (string_iequals(value, "string"))
+ return SHADER_SOCKET_STRING;
+ else
+ fprintf(stderr, "Unknown shader socket type \"%s\" for attribute \"%s\".\n", value.c_str(), name);
+ }
+
+ return SHADER_SOCKET_UNDEFINED;
+}
+
/* Film */
static void xml_read_film(const XMLReadState& state, pugi::xml_node node)
@@ -379,22 +408,37 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
xml_read_string(&osl->filepath, node, "src");
osl->filepath = path_join(state.base, osl->filepath);
- /* Outputs */
- string output = "", output_type = "";
- ShaderSocketType type = SHADER_SOCKET_FLOAT;
-
- xml_read_string(&output, node, "output");
- xml_read_string(&output_type, node, "output_type");
-
- if(output_type == "float")
- type = SHADER_SOCKET_FLOAT;
- else if(output_type == "closure color")
- type = SHADER_SOCKET_CLOSURE;
- else if(output_type == "color")
- type = SHADER_SOCKET_COLOR;
-
- osl->output_names.push_back(ustring(output));
- osl->add_output(osl->output_names.back().c_str(), type);
+ /* Generate inputs/outputs from node sockets
+ *
+ * Note: ShaderInput/ShaderOutput store shallow string copies only!
+ * Socket names must be stored in the extra lists instead. */
+ /* read input values */
+ for(pugi::xml_node param = node.first_child(); param; param = param.next_sibling()) {
+ if (string_iequals(param.name(), "input")) {
+ string name;
+ if (!xml_read_string(&name, param, "name"))
+ continue;
+
+ ShaderSocketType type = xml_read_socket_type(param, "type");
+ if (type == SHADER_SOCKET_UNDEFINED)
+ continue;
+
+ osl->input_names.push_back(ustring(name));
+ osl->add_input(osl->input_names.back().c_str(), type);
+ }
+ else if (string_iequals(param.name(), "output")) {
+ string name;
+ if (!xml_read_string(&name, param, "name"))
+ continue;
+
+ ShaderSocketType type = xml_read_socket_type(param, "type");
+ if (type == SHADER_SOCKET_UNDEFINED)
+ continue;
+
+ osl->output_names.push_back(ustring(name));
+ osl->add_output(osl->output_names.back().c_str(), type);
+ }
+ }
snode = osl;
}