Blender  V2.59
TEX_proc.c
Go to the documentation of this file.
00001 /*
00002  *
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version. 
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2005 Blender Foundation.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): Robin Allen
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include "../TEX_util.h"
00035 #include "TEX_node.h"
00036 
00037 #include "RE_shader_ext.h"
00038 
00039 /* 
00040         In this file: wrappers to use procedural textures as nodes
00041 */
00042 
00043 
00044 static bNodeSocketType outputs_both[]= {
00045         { SOCK_RGBA, 0, "Color",  1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
00046         { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
00047         { -1, 0, "" }
00048 };
00049 static bNodeSocketType outputs_color_only[]= {
00050         { SOCK_RGBA, 0, "Color",  1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
00051         { -1, 0, "" }
00052 };
00053 
00054 /* Inputs common to all, #defined because nodes will need their own inputs too */
00055 #define I 2 /* count */
00056 #define COMMON_INPUTS \
00057         { SOCK_RGBA, 1, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, \
00058         { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }
00059 
00060 /* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */
00061 static void do_proc(float *result, TexParams *p, float *col1, float *col2, char is_normal, Tex *tex, short thread)
00062 {
00063         TexResult texres;
00064         int textype;
00065         
00066         if(is_normal) {
00067                 texres.nor = result;
00068         }
00069         else
00070                 texres.nor = NULL;
00071         
00072         textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex,
00073                 &texres, thread, 0, p->shi, p->mtex);
00074         
00075         if(is_normal)
00076                 return;
00077         
00078         if(textype & TEX_RGB) {
00079                 QUATCOPY(result, &texres.tr);
00080         }
00081         else {
00082                 QUATCOPY(result, col1);
00083                 ramp_blend(MA_RAMP_BLEND, result, result+1, result+2, texres.tin, col2);
00084         }
00085 }
00086 
00087 typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, short thread);
00088 
00089 static void texfn(
00090         float *result, 
00091         TexParams *p,
00092         bNode *node, 
00093         bNodeStack **in,
00094         char is_normal, 
00095         MapFn map_inputs,
00096         short thread)
00097 {
00098         Tex tex = *((Tex*)(node->storage));
00099         float col1[4], col2[4];
00100         tex_input_rgba(col1, in[0], p, thread);
00101         tex_input_rgba(col2, in[1], p, thread);
00102         
00103         map_inputs(&tex, in, p, thread);
00104         
00105         do_proc(result, p, col1, col2, is_normal, &tex, thread);
00106 }
00107 
00108 static int count_outputs(bNode *node)
00109 {
00110         bNodeSocket *sock;
00111         int num = 0;
00112         for(sock= node->outputs.first; sock; sock= sock->next) {
00113                 num++;
00114         }
00115         return num;
00116 }
00117 
00118 /* Boilerplate generators */
00119 
00120 #define ProcNoInputs(name) \
00121                 static void name##_map_inputs(Tex *UNUSED(tex), bNodeStack **UNUSED(in), TexParams *UNUSED(p), short UNUSED(thread)) \
00122                 {}
00123 
00124 #define ProcDef(name) \
00125                 static void name##_colorfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread)  \
00126                 {                                                                                                    \
00127                                 texfn(result, p, node, in, 0, &name##_map_inputs, thread);                               \
00128                 }                                                                                                    \
00129                 static void name##_normalfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
00130                 {                                                                                                    \
00131                                 texfn(result, p, node, in, 1, &name##_map_inputs, thread);                               \
00132                 }                                                                                                    \
00133                 static void name##_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)                  \
00134                 {                                                                                                    \
00135                                 int outs = count_outputs(node);                                                              \
00136                                 if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn, data);                                 \
00137                                 if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn, data);                                \
00138                 }
00139 
00140 
00141 /* --- VORONOI -- */
00142 static bNodeSocketType voronoi_inputs[]= {
00143         COMMON_INPUTS,
00144         { SOCK_VALUE, 1, "W1", 1.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f },
00145         { SOCK_VALUE, 1, "W2", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f },
00146         { SOCK_VALUE, 1, "W3", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f },
00147         { SOCK_VALUE, 1, "W4", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f },
00148         
00149         { SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f,    0.01f,  10.0f },
00150         { SOCK_VALUE, 1, "Size",   0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 4.0f },
00151         
00152         { -1, 0, "" }
00153 };
00154 static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
00155 {
00156         tex->vn_w1 = tex_input_value(in[I+0], p, thread);
00157         tex->vn_w2 = tex_input_value(in[I+1], p, thread);
00158         tex->vn_w3 = tex_input_value(in[I+2], p, thread);
00159         tex->vn_w4 = tex_input_value(in[I+3], p, thread);
00160         
00161         tex->ns_outscale = tex_input_value(in[I+4], p, thread);
00162         tex->noisesize   = tex_input_value(in[I+5], p, thread);
00163 }
00164 ProcDef(voronoi)
00165 
00166 /* --- BLEND -- */
00167 static bNodeSocketType blend_inputs[]= {
00168         COMMON_INPUTS,
00169         { -1, 0, "" }
00170 };
00171 ProcNoInputs(blend)
00172 ProcDef(blend)
00173 
00174 /* -- MAGIC -- */
00175 static bNodeSocketType magic_inputs[]= {
00176         COMMON_INPUTS,
00177         { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f,   0.0f, 200.0f },
00178         { -1, 0, "" }
00179 };
00180 static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
00181 {
00182         tex->turbul = tex_input_value(in[I+0], p, thread);
00183 }
00184 ProcDef(magic)
00185 
00186 /* --- MARBLE --- */
00187 static bNodeSocketType marble_inputs[]= {
00188         COMMON_INPUTS,
00189         { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
00190         { SOCK_VALUE, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f },
00191         { -1, 0, "" }
00192 };
00193 static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
00194 {
00195         tex->noisesize = tex_input_value(in[I+0], p, thread);
00196         tex->turbul    = tex_input_value(in[I+1], p, thread);
00197 }
00198 ProcDef(marble)
00199 
00200 /* --- CLOUDS --- */
00201 static bNodeSocketType clouds_inputs[]= {
00202         COMMON_INPUTS,
00203         { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
00204         { -1, 0, "" }
00205 };
00206 static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
00207 {
00208         tex->noisesize = tex_input_value(in[I+0], p, thread);
00209 }
00210 ProcDef(clouds)
00211 
00212 /* --- DISTORTED NOISE --- */
00213 static bNodeSocketType distnoise_inputs[]= {
00214         COMMON_INPUTS,
00215         { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f,  2.0f },
00216         { SOCK_VALUE, 1, "Distortion", 1.00f, 0.0f, 0.0f, 0.0f,   0.0000f, 10.0f },
00217         { -1, 0, "" }
00218 };
00219 static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
00220 {
00221         tex->noisesize   = tex_input_value(in[I+0], p, thread);
00222         tex->dist_amount = tex_input_value(in[I+1], p, thread);
00223 }
00224 ProcDef(distnoise)
00225 
00226 /* --- WOOD --- */
00227 static bNodeSocketType wood_inputs[]= {
00228         COMMON_INPUTS,
00229         { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
00230         { SOCK_VALUE, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f },
00231         { -1, 0, "" }
00232 };
00233 static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
00234 {
00235         tex->noisesize = tex_input_value(in[I+0], p, thread);
00236         tex->turbul    = tex_input_value(in[I+1], p, thread);
00237 }
00238 ProcDef(wood)
00239 
00240 /* --- MUSGRAVE --- */
00241 static bNodeSocketType musgrave_inputs[]= {
00242         COMMON_INPUTS,
00243         { SOCK_VALUE, 1, "H",          1.0f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
00244         { SOCK_VALUE, 1, "Lacunarity", 2.0f, 0.0f, 0.0f, 0.0f,   0.0f,    6.0f },
00245         { SOCK_VALUE, 1, "Octaves",    2.0f, 0.0f, 0.0f, 0.0f,   0.0f,    8.0f },
00246         
00247         { SOCK_VALUE, 1, "iScale",     1.0f,  0.0f, 0.0f, 0.0f,  0.0f,   10.0f },
00248         { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,  0.0001f, 2.0f },
00249         { -1, 0, "" }
00250 };
00251 static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
00252 {
00253         tex->mg_H          = tex_input_value(in[I+0], p, thread);
00254         tex->mg_lacunarity = tex_input_value(in[I+1], p, thread);
00255         tex->mg_octaves    = tex_input_value(in[I+2], p, thread);
00256         tex->ns_outscale   = tex_input_value(in[I+3], p, thread);
00257         tex->noisesize     = tex_input_value(in[I+4], p, thread);
00258 }
00259 ProcDef(musgrave)
00260 
00261 /* --- NOISE --- */
00262 static bNodeSocketType noise_inputs[]= {
00263         COMMON_INPUTS,
00264         { -1, 0, "" }
00265 };
00266 ProcNoInputs(noise)
00267 ProcDef(noise)
00268 
00269 /* --- STUCCI --- */
00270 static bNodeSocketType stucci_inputs[]= {
00271         COMMON_INPUTS,
00272         { SOCK_VALUE, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f },
00273         { SOCK_VALUE, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f },
00274         { -1, 0, "" }
00275 };
00276 static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
00277 {
00278         tex->noisesize = tex_input_value(in[I+0], p, thread);
00279         tex->turbul    = tex_input_value(in[I+1], p, thread);
00280 }
00281 ProcDef(stucci)
00282 
00283 /* --- */
00284 
00285 static void init(bNode *node)
00286 {
00287         Tex *tex = MEM_callocN(sizeof(Tex), "Tex");
00288         node->storage= tex;
00289         
00290         default_tex(tex);
00291         tex->type = node->type - TEX_NODE_PROC;
00292         
00293         if(tex->type == TEX_WOOD)
00294                 tex->stype = TEX_BANDNOISE;
00295         
00296 }
00297 
00298 /* Node type definitions */
00299 #define TexDef(TEXTYPE, outputs, name, Name) \
00300 void register_node_type_tex_proc_##name(ListBase *lb) \
00301 { \
00302         static bNodeType ntype; \
00303         \
00304         node_type_base(&ntype, TEX_NODE_PROC+TEXTYPE, Name, NODE_CLASS_TEXTURE, NODE_PREVIEW|NODE_OPTIONS, name##_inputs, outputs); \
00305         node_type_size(&ntype, 140, 80, 140); \
00306         node_type_init(&ntype, init); \
00307         node_type_storage(&ntype, "Tex", node_free_standard_storage, node_copy_standard_storage); \
00308         node_type_exec(&ntype, name##_exec); \
00309         \
00310         nodeRegisterType(lb, &ntype); \
00311 }
00312         
00313 #define C outputs_color_only
00314 #define CV outputs_both
00315         
00316 TexDef(TEX_VORONOI,   CV, voronoi,   "Voronoi"  )
00317 TexDef(TEX_BLEND,     C,  blend,     "Blend"    )
00318 TexDef(TEX_MAGIC,     C,  magic,     "Magic"    )
00319 TexDef(TEX_MARBLE,    CV, marble,    "Marble"   )
00320 TexDef(TEX_CLOUDS,    CV, clouds,    "Clouds"   )
00321 TexDef(TEX_WOOD,      CV, wood,      "Wood"     )
00322 TexDef(TEX_MUSGRAVE,  CV, musgrave,  "Musgrave" )
00323 TexDef(TEX_NOISE,     C,  noise,     "Noise"    )
00324 TexDef(TEX_STUCCI,    CV, stucci,    "Stucci"   )
00325 TexDef(TEX_DISTNOISE, CV, distnoise, "Distorted Noise" )