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>2008-11-13 01:03:11 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-11-13 01:03:11 +0300
commitb3c238e8bc4c38a8f2ba483be2d19c76d03d674c (patch)
treea86991622fa5582498612cf348d0de58af048a08 /source/blender
parentbdfe7d89e2f1292644577972c716931b4ce3c6c3 (diff)
parent7e4db234cee71ead34ee81a12e27da4bd548eb4b (diff)
2.5: merge with trunk, previous merge was only up to yesterday.
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r17416:HEAD
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_node.h42
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/node.c173
-rw-r--r--source/blender/blenkernel/intern/texture.c14
-rw-r--r--source/blender/blenloader/intern/readfile.c39
-rw-r--r--source/blender/blenloader/intern/writefile.c8
-rw-r--r--source/blender/makesdna/DNA_node_types.h9
-rw-r--r--source/blender/makesdna/DNA_texture_types.h8
-rw-r--r--source/blender/nodes/Makefile2
-rw-r--r--source/blender/nodes/SConscript1
-rw-r--r--source/blender/nodes/TEX_node.h70
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_texture.c13
-rw-r--r--source/blender/nodes/intern/SHD_util.c1
-rw-r--r--source/blender/nodes/intern/TEX_nodes/Makefile48
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_bricks.c123
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_checker.c85
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_curves.c127
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c104
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_image.c106
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_invert.c79
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_math.c172
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c81
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_output.c90
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_proc.c310
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_rotate.c114
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_texture.c103
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_translate.c78
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c122
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_viewer.c61
-rw-r--r--source/blender/nodes/intern/TEX_util.c270
-rw-r--r--source/blender/nodes/intern/TEX_util.h104
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h1
-rw-r--r--source/blender/render/intern/include/pixelshading.h4
-rw-r--r--source/blender/render/intern/include/texture.h3
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/pixelshading.c8
-rw-r--r--source/blender/render/intern/source/rayshade.c6
-rw-r--r--source/blender/render/intern/source/rendercore.c2
-rw-r--r--source/blender/render/intern/source/texture.c61
40 files changed, 2604 insertions, 44 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 01c54663c6d..fa3a654c1c2 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -47,6 +47,7 @@ struct rctf;
struct ListBase;
struct RenderData;
struct Scene;
+struct Tex;
struct GPUMaterial;
struct GPUNode;
struct GPUNodeStack;
@@ -118,6 +119,8 @@ typedef struct bNodeType {
#define NODE_CLASS_MATTE 9
#define NODE_CLASS_DISTORT 10
#define NODE_CLASS_OP_DYNAMIC 11
+#define NODE_CLASS_PATTERN 12
+#define NODE_CLASS_TEXTURE 13
/* ************** GENERIC API, TREES *************** */
@@ -377,6 +380,45 @@ void ntreeCompositForceHidden(struct bNodeTree *ntree);
void free_compbuf(struct CompBuf *cbuf); /* internal...*/
+
+/* ************** TEXTURE NODES *************** */
+
+struct TexResult;
+
+#define TEX_NODE_OUTPUT 101
+#define TEX_NODE_CHECKER 102
+#define TEX_NODE_TEXTURE 103
+#define TEX_NODE_BRICKS 104
+#define TEX_NODE_MATH 105
+#define TEX_NODE_MIX_RGB 106
+#define TEX_NODE_RGBTOBW 107
+#define TEX_NODE_VALTORGB 108
+#define TEX_NODE_IMAGE 109
+#define TEX_NODE_CURVE_RGB 110
+#define TEX_NODE_INVERT 111
+#define TEX_NODE_HUE_SAT 112
+#define TEX_NODE_CURVE_TIME 113
+#define TEX_NODE_ROTATE 114
+#define TEX_NODE_VIEWER 115
+#define TEX_NODE_TRANSLATE 116
+
+/* 201-299 reserved. Use like this: TEX_NODE_PROC + TEX_CLOUDS, etc */
+#define TEX_NODE_PROC 200
+#define TEX_NODE_PROC_MAX 300
+
+extern struct ListBase node_all_textures;
+
+/* API */
+int ntreeTexTagAnimated(struct bNodeTree *ntree);
+void ntreeTexUpdatePreviews( struct bNodeTree* nodetree );
+void ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, char do_preview, short thread, struct Tex *tex, short which_output);
+void ntreeTexCheckCyclics(struct bNodeTree *ntree);
+void ntreeTexAssignIndex(struct bNodeTree *ntree, struct bNode *node);
+char* ntreeTexOutputMenu(struct bNodeTree *ntree);
+
+
+/**/
+
void init_nodesystem(void);
void free_nodesystem(void);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 3acc10e8022..8e36ea0204b 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -613,6 +613,8 @@ static void get_flags_for_id(ID *id, char *buf)
if(GS(id->name)==ID_MA)
isnode= ((Material *)id)->use_nodes;
+ if(GS(id->name)==ID_TE)
+ isnode= ((Tex *)id)->use_nodes;
if (id->us<0)
sprintf(buf, "-1W ");
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 95534deae66..d697ef2de4e 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -649,7 +649,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
if(ma->septex & (1<<a)) continue;
mtex= ma->mtex[a];
- if(mtex && mtex->tex && mtex->tex->type) {
+ if(mtex && mtex->tex && (mtex->tex->type | (mtex->tex->use_nodes && mtex->tex->nodetree) )) {
ma->texco |= mtex->texco;
ma->mapto |= mtex->mapto;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 8d60b1b4359..e189891d884 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -38,6 +38,7 @@
#include "DNA_image_types.h"
#include "DNA_node_types.h"
#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
#include "DNA_text_types.h"
#include "DNA_scene_types.h"
@@ -70,6 +71,8 @@
#include "intern/CMP_util.h" /* stupid include path... */
#include "SHD_node.h"
+#include "TEX_node.h"
+#include "intern/TEX_util.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@@ -77,6 +80,7 @@
static ListBase empty_list = {NULL, NULL};
ListBase node_all_composit = {NULL, NULL};
ListBase node_all_shaders = {NULL, NULL};
+ListBase node_all_textures = {NULL, NULL};
/* ************** Type stuff ********** */
@@ -106,6 +110,8 @@ void ntreeInitTypes(bNodeTree *ntree)
ntree->alltypes= node_all_shaders;
else if(ntree->type==NTREE_COMPOSIT)
ntree->alltypes= node_all_composit;
+ else if(ntree->type==NTREE_TEXTURE)
+ ntree->alltypes= node_all_textures;
else {
ntree->alltypes= empty_list;
printf("Error: no type definitions for nodes\n");
@@ -661,6 +667,28 @@ void nodeVerifyGroup(bNodeTree *ngroup)
}
}
}
+ else if(ngroup->type==NTREE_TEXTURE) {
+ Tex *tx;
+ for(tx= G.main->tex.first; tx; tx= tx->id.next) {
+ if(tx->nodetree) {
+ bNode *node;
+
+ /* find if group is in tree */
+ for(node= tx->nodetree->nodes.first; node; node= node->next)
+ if(node->id == (ID *)ngroup)
+ break;
+
+ if(node) {
+ /* set all type pointers OK */
+ ntreeInitTypes(tx->nodetree);
+
+ for(node= tx->nodetree->nodes.first; node; node= node->next)
+ if(node->id == (ID *)ngroup)
+ nodeVerifyType(tx->nodetree, node);
+ }
+ }
+ }
+ }
}
/* also to check all users of groups. Now only used in editor for hide/unhide */
@@ -717,6 +745,26 @@ void nodeGroupSocketUseFlags(bNodeTree *ngroup)
}
}
}
+ else if(ngroup->type==NTREE_TEXTURE) {
+ Tex *tx;
+ for(tx= G.main->tex.first; tx; tx= tx->id.next) {
+ if(tx->nodetree) {
+ for(node= tx->nodetree->nodes.first; node; node= node->next) {
+ if(node->id==(ID *)ngroup) {
+ for(sock= node->inputs.first; sock; sock= sock->next)
+ if(sock->link)
+ if(sock->tosock)
+ sock->tosock->flag |= SOCK_IN_USE;
+ for(sock= node->outputs.first; sock; sock= sock->next)
+ if(nodeCountSocketLinks(tx->nodetree, sock))
+ if(sock->tosock)
+ sock->tosock->flag |= SOCK_IN_USE;
+ }
+ }
+ }
+ }
+ }
+
}
/* finds a node based on given socket */
@@ -901,9 +949,12 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
/* got it-bob*/
if(ntype->initfunc!=NULL)
ntype->initfunc(node);
+
+ if(type==TEX_NODE_OUTPUT)
+ ntreeTexAssignIndex(ntree, node);
nodeAddSockets(node, ntype);
-
+
return node;
}
@@ -970,6 +1021,9 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int internal)
node->new_node= nnode;
nnode->new_node= NULL;
nnode->preview= NULL;
+
+ if(node->type==TEX_NODE_OUTPUT)
+ ntreeTexAssignIndex(ntree, node);
return nnode;
}
@@ -1260,6 +1314,22 @@ void ntreeMakeLocal(bNodeTree *ntree)
}
}
}
+ else if(ntree->type==NTREE_TEXTURE) {
+ Tex *tx;
+ for(tx= G.main->tex.first; tx; tx= tx->id.next) {
+ if(tx->nodetree) {
+ bNode *node;
+
+ /* find if group is in tree */
+ for(node= tx->nodetree->nodes.first; node; node= node->next) {
+ if(node->id == (ID *)ntree) {
+ if(tx->id.lib) lib= 1;
+ else local= 1;
+ }
+ }
+ }
+ }
+ }
/* if all users are local, we simply make tree local */
if(local && lib==0) {
@@ -1311,6 +1381,25 @@ void ntreeMakeLocal(bNodeTree *ntree)
}
}
}
+ else if(ntree->type==NTREE_TEXTURE) {
+ Tex *tx;
+ for(tx= G.main->tex.first; tx; tx= tx->id.next) {
+ if(tx->nodetree) {
+ bNode *node;
+
+ /* find if group is in tree */
+ for(node= tx->nodetree->nodes.first; node; node= node->next) {
+ if(node->id == (ID *)ntree) {
+ if(tx->id.lib==NULL) {
+ node->id= &newtree->id;
+ newtree->id.us++;
+ ntree->id.us--;
+ }
+ }
+ }
+ }
+ }
+ }
}
}
@@ -1575,6 +1664,8 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
}
node->need_exec= 1;
}
+ else if(ntree->type == NTREE_TEXTURE)
+ ntreeTexUpdatePreviews(ntree);
}
void NodeTagIDChanged(bNodeTree *ntree, ID *id)
@@ -1813,7 +1904,7 @@ static void composit_begin_exec(bNodeTree *ntree, int is_group)
sock->ns.data= NULL;
}
}
- }
+ }
/* cannot initialize them while using in threads */
if(ELEM3(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB)) {
curvemapping_initialize(node->storage);
@@ -1929,12 +2020,28 @@ static void ntreeReleaseThreadStack(bNodeThreadStack *nts)
nts->used= 0;
}
+/* free texture delegates */
+static void tex_end_exec(bNodeTree *ntree)
+{
+ bNodeThreadStack *nts;
+ bNodeStack *ns;
+ int th, a;
+
+ if(ntree->threadstack)
+ for(th=0; th<BLENDER_MAX_THREADS; th++)
+ for(nts=ntree->threadstack[th].first; nts; nts=nts->next)
+ for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++)
+ if(ns->data)
+ MEM_freeN(ns->data);
+
+}
+
void ntreeBeginExecTree(bNodeTree *ntree)
{
/* let's make it sure */
if(ntree->init & NTREE_EXEC_INIT)
return;
-
+
/* allocate the thread stack listbase array */
if(ntree->type!=NTREE_COMPOSIT)
ntree->threadstack= MEM_callocN(BLENDER_MAX_THREADS*sizeof(ListBase), "thread stack array");
@@ -1986,6 +2093,8 @@ void ntreeEndExecTree(bNodeTree *ntree)
/* another callback candidate! */
if(ntree->type==NTREE_COMPOSIT)
composit_end_exec(ntree, 0);
+ else if(ntree->type==NTREE_TEXTURE)
+ tex_end_exec(ntree);
if(ntree->stack) {
MEM_freeN(ntree->stack);
@@ -2622,6 +2731,27 @@ void ntreeCompositTagGenerators(bNodeTree *ntree)
}
}
+int ntreeTexTagAnimated(bNodeTree *ntree)
+{
+ bNode *node;
+
+ if(ntree==NULL) return 0;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->type==TEX_NODE_CURVE_TIME) {
+ NodeTagChanged(ntree, node);
+ return 1;
+ }
+ else if(node->type==NODE_GROUP) {
+ if( ntreeTexTagAnimated((bNodeTree *)node->id) ) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
/* ************* node definition init ********** */
static bNodeType *is_nodetype_registered(ListBase *typelist, int type, ID *id)
@@ -2745,6 +2875,41 @@ static void registerShaderNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &sh_node_hue_sat);
}
+static void registerTextureNodes(ListBase *ntypelist)
+{
+ nodeRegisterType(ntypelist, &node_group_typeinfo);
+ nodeRegisterType(ntypelist, &tex_node_math);
+ nodeRegisterType(ntypelist, &tex_node_mix_rgb);
+ nodeRegisterType(ntypelist, &tex_node_valtorgb);
+ nodeRegisterType(ntypelist, &tex_node_rgbtobw);
+ nodeRegisterType(ntypelist, &tex_node_curve_rgb);
+ nodeRegisterType(ntypelist, &tex_node_curve_time);
+ nodeRegisterType(ntypelist, &tex_node_invert);
+ nodeRegisterType(ntypelist, &tex_node_hue_sat);
+
+ nodeRegisterType(ntypelist, &tex_node_output);
+ nodeRegisterType(ntypelist, &tex_node_viewer);
+
+ nodeRegisterType(ntypelist, &tex_node_checker);
+ nodeRegisterType(ntypelist, &tex_node_texture);
+ nodeRegisterType(ntypelist, &tex_node_bricks);
+ nodeRegisterType(ntypelist, &tex_node_image);
+
+ nodeRegisterType(ntypelist, &tex_node_rotate);
+ nodeRegisterType(ntypelist, &tex_node_translate);
+
+ nodeRegisterType(ntypelist, &tex_node_proc_voronoi);
+ nodeRegisterType(ntypelist, &tex_node_proc_blend);
+ nodeRegisterType(ntypelist, &tex_node_proc_magic);
+ nodeRegisterType(ntypelist, &tex_node_proc_marble);
+ nodeRegisterType(ntypelist, &tex_node_proc_clouds);
+ nodeRegisterType(ntypelist, &tex_node_proc_wood);
+ nodeRegisterType(ntypelist, &tex_node_proc_musgrave);
+ nodeRegisterType(ntypelist, &tex_node_proc_noise);
+ nodeRegisterType(ntypelist, &tex_node_proc_stucci);
+ nodeRegisterType(ntypelist, &tex_node_proc_distnoise);
+}
+
static void remove_dynamic_typeinfos(ListBase *list)
{
bNodeType *ntype= list->first;
@@ -2782,6 +2947,7 @@ void init_nodesystem(void)
{
registerCompositNodes(&node_all_composit);
registerShaderNodes(&node_all_shaders);
+ registerTextureNodes(&node_all_textures);
}
void free_nodesystem(void)
@@ -2790,4 +2956,5 @@ void free_nodesystem(void)
BLI_freelistN(&node_all_composit);
remove_dynamic_typeinfos(&node_all_shaders);
BLI_freelistN(&node_all_shaders);
+ BLI_freelistN(&node_all_textures);
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 372c51b0da5..9300b39a767 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -420,6 +420,11 @@ void free_texture(Tex *tex)
BKE_previewimg_free(&tex->preview);
BKE_icon_delete((struct ID*)tex);
tex->id.icon_id = 0;
+
+ if(tex->nodetree) {
+ ntreeFreeTree(tex->nodetree);
+ MEM_freeN(tex->nodetree);
+ }
}
/* ------------------------------------------------------------------------- */
@@ -577,6 +582,11 @@ Tex *copy_texture(Tex *tex)
if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
+ if(tex->nodetree) {
+ ntreeEndExecTree(tex->nodetree);
+ texn->nodetree= ntreeCopyTree(tex->nodetree, 0); /* 0 == full new tree */
+ }
+
return texn;
}
@@ -727,6 +737,10 @@ void autotexname(Tex *tex)
char di[FILE_MAXDIR], fi[FILE_MAXFILE];
if(tex) {
+ if(tex->use_nodes) {
+ new_id(&G.main->tex, (ID *)tex, "Noddy");
+ }
+ else
if(tex->type==TEX_IMAGE) {
ima= tex->ima;
if(ima) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1ecd402bd56..ed53c31dd67 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1510,6 +1510,7 @@ static void lib_verify_nodetree(Main *main, int open)
{
Scene *sce;
Material *ma;
+ Tex *tx;
bNodeTree *ntree;
/* this crashes blender on undo/redo
@@ -1534,6 +1535,11 @@ static void lib_verify_nodetree(Main *main, int open)
if(sce->nodetree)
ntreeVerifyTypes(sce->nodetree);
}
+ /* and texture trees */
+ for(tx= main->tex.first; tx; tx= tx->id.next) {
+ if(tx->nodetree)
+ ntreeVerifyTypes(tx->nodetree);
+ }
}
@@ -1570,6 +1576,9 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
else if(ELEM3(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
((ImageUser *)node->storage)->ok= 1;
}
+ else if( ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) {
+ direct_link_curvemapping(fd, node->storage);
+ }
}
link_list(fd, &node->inputs);
link_list(fd, &node->outputs);
@@ -2476,6 +2485,9 @@ static void lib_link_texture(FileData *fd, Main *main)
tex->ipo= newlibadr_us(fd, tex->id.lib, tex->ipo);
if(tex->env) tex->env->object= newlibadr(fd, tex->id.lib, tex->env->object);
+ if(tex->nodetree)
+ lib_link_ntree(fd, &tex->id, tex->nodetree);
+
tex->id.flag -= LIB_NEEDLINK;
}
tex= tex->id.next;
@@ -2501,6 +2513,11 @@ static void direct_link_texture(FileData *fd, Tex *tex)
memset(tex->env->cube, 0, 6*sizeof(void *));
tex->env->ok= 0;
}
+
+ tex->nodetree= newdataadr(fd, tex->nodetree);
+ if(tex->nodetree)
+ direct_link_nodetree(fd, tex->nodetree);
+
tex->preview = direct_link_preview_image(fd, tex->preview);
tex->iuser.ok= 1;
@@ -8395,11 +8412,23 @@ static void expand_key(FileData *fd, Main *mainvar, Key *key)
expand_doit(fd, mainvar, key->ipo);
}
+static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
+{
+ bNode *node;
+
+ for(node= ntree->nodes.first; node; node= node->next)
+ if(node->id && node->type!=CMP_NODE_R_LAYERS)
+ expand_doit(fd, mainvar, node->id);
+
+}
static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
{
expand_doit(fd, mainvar, tex->ima);
expand_doit(fd, mainvar, tex->ipo);
+
+ if(tex->nodetree)
+ expand_nodetree(fd, mainvar, tex->nodetree);
}
static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
@@ -8412,16 +8441,6 @@ static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
expand_doit(fd, mainvar, brush->clone.image);
}
-static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
-{
- bNode *node;
-
- for(node= ntree->nodes.first; node; node= node->next)
- if(node->id && node->type!=CMP_NODE_R_LAYERS)
- expand_doit(fd, mainvar, node->id);
-
-}
-
static void expand_material(FileData *fd, Main *mainvar, Material *ma)
{
int a;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index a4883087cfa..d84211411fa 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -457,6 +457,8 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree)
write_curvemapping(wd, node->storage);
else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_TIME || node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB))
write_curvemapping(wd, node->storage);
+ else if(ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) )
+ write_curvemapping(wd, node->storage);
else
writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage);
}
@@ -1321,6 +1323,12 @@ static void write_textures(WriteData *wd, ListBase *idbase)
if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba);
if(tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env);
+ /* nodetree is integral part of texture, no libdata */
+ if(tex->nodetree) {
+ writestruct(wd, DATA, "bNodeTree", 1, tex->nodetree);
+ write_nodetree(wd, tex->nodetree);
+ }
+
write_previews(wd, tex->preview);
}
tex= tex->id.next;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index eda37d952c1..d5eb4024dcc 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -121,6 +121,7 @@ typedef struct bNode {
float locx, locy; /* root offset for drawing */
float width, miniwidth;
short custom1, custom2; /* to be abused for buttons */
+ float custom3, custom4;
short need_exec, exec; /* need_exec is set as UI execution event, exec is flag during exec */
@@ -156,7 +157,7 @@ typedef struct bNodeLink {
} bNodeLink;
/* the basis for a Node tree, all links and nodes reside internal here */
-/* only re-usable node trees are in the library though, materials allocate own tree struct */
+/* only re-usable node trees are in the library though, materials and textures allocate own tree struct */
typedef struct bNodeTree {
ID id;
@@ -185,6 +186,7 @@ typedef struct bNodeTree {
/* ntree->type, index */
#define NTREE_SHADER 0
#define NTREE_COMPOSIT 1
+#define NTREE_TEXTURE 2
/* ntree->init, flag */
#define NTREE_TYPE_INIT 1
@@ -285,4 +287,9 @@ typedef struct NodeLensDist {
short jit, proj, fit, pad;
} NodeLensDist;
+/* TEX_output */
+typedef struct TexNodeOutput {
+ char name[32];
+} TexNodeOutput;
+
#endif
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index 111dc08ee02..6e07336a4b1 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -55,13 +55,13 @@ typedef struct MTex {
float ofs[3], size[3];
short texflag, colormodel, pmapto, pmaptoneg;
- short normapspace, pad[3];
+ short normapspace, which_output, pad[2];
float r, g, b, k;
float def_var, rt;
float colfac, norfac, varfac;
float dispfac;
- float warpfac;
+ float warpfac;
} MTex;
@@ -166,6 +166,7 @@ typedef struct Tex {
struct ImageUser iuser;
+ struct bNodeTree *nodetree;
struct Ipo *ipo;
struct Image *ima;
struct PluginTex *plugin;
@@ -173,6 +174,9 @@ typedef struct Tex {
struct EnvMap *env;
struct PreviewImage * preview;
+ char use_nodes;
+ char pad[7];
+
} Tex;
/* used for mapping node. note: rot is in degrees */
diff --git a/source/blender/nodes/Makefile b/source/blender/nodes/Makefile
index 57f57ebebfe..400064f24b8 100644
--- a/source/blender/nodes/Makefile
+++ b/source/blender/nodes/Makefile
@@ -29,6 +29,6 @@
# Bounces make to subdirectories.
SOURCEDIR = source/blender/nodes
-DIRS = intern
+DIRS = intern intern/CMP_nodes intern/SHD_nodes intern/TEX_nodes
include nan_subdirs.mk
diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript
index 5f7f29dab83..5104bcd0046 100644
--- a/source/blender/nodes/SConscript
+++ b/source/blender/nodes/SConscript
@@ -4,6 +4,7 @@ Import ('env')
sources = env.Glob('intern/*.c')
sources += env.Glob('intern/CMP_nodes/*.c')
sources += env.Glob('intern/SHD_nodes/*.c')
+sources += env.Glob('intern/TEX_nodes/*.c')
incs = '. ./intern '
incs += '#/intern/guardedalloc ../editors/include ../blenlib ../makesdna'
diff --git a/source/blender/nodes/TEX_node.h b/source/blender/nodes/TEX_node.h
new file mode 100644
index 00000000000..6be2123b96d
--- /dev/null
+++ b/source/blender/nodes/TEX_node.h
@@ -0,0 +1,70 @@
+/**
+ * $Id: CMP_node.h 12429 2007-10-29 14:37:19Z bebraw $
+ *
+ * ***** 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef TEX_NODE_H
+#define TEX_NODE_H
+
+#include "BKE_node.h"
+
+
+/* ****************** types array for all texture nodes ****************** */
+
+extern bNodeType tex_node_math;
+extern bNodeType tex_node_mix_rgb;
+extern bNodeType tex_node_valtorgb;
+extern bNodeType tex_node_rgbtobw;
+extern bNodeType tex_node_output;
+extern bNodeType tex_node_viewer;
+extern bNodeType tex_node_checker;
+extern bNodeType tex_node_texture;
+extern bNodeType tex_node_bricks;
+extern bNodeType tex_node_image;
+extern bNodeType tex_node_curve_rgb;
+extern bNodeType tex_node_curve_time;
+extern bNodeType tex_node_invert;
+extern bNodeType tex_node_hue_sat;
+
+extern bNodeType tex_node_rotate;
+extern bNodeType tex_node_translate;
+
+extern bNodeType tex_node_proc_voronoi;
+extern bNodeType tex_node_proc_blend;
+extern bNodeType tex_node_proc_magic;
+extern bNodeType tex_node_proc_marble;
+extern bNodeType tex_node_proc_clouds;
+extern bNodeType tex_node_proc_wood;
+extern bNodeType tex_node_proc_musgrave;
+extern bNodeType tex_node_proc_noise;
+extern bNodeType tex_node_proc_stucci;
+extern bNodeType tex_node_proc_distnoise;
+
+#endif
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_texture.c b/source/blender/nodes/intern/SHD_nodes/SHD_texture.c
index 31dbde940fd..908cbf5abfd 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_texture.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_texture.c
@@ -50,6 +50,9 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b
TexResult texres;
float vec[3], nor[3]={0.0f, 0.0f, 0.0f};
int retval;
+ short which_output = node->custom1;
+
+ short thread = shi->thread;
/* out: value, color, normal */
@@ -61,7 +64,7 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b
if(in[0]->datatype==NS_OSA_VECTORS) {
float *fp= in[0]->data;
- retval= multitex_ext((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres);
+ retval= multitex_thread((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres, thread, which_output);
}
else if(in[0]->datatype==NS_OSA_VALUES) {
float *fp= in[0]->data;
@@ -69,14 +72,14 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b
dxt[0]= fp[0]; dxt[1]= dxt[2]= 0.0f;
dyt[0]= fp[1]; dyt[1]= dyt[2]= 0.0f;
- retval= multitex_ext((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres);
+ retval= multitex_thread((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres, thread, which_output);
}
else
- retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres);
+ retval= multitex_thread((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output);
}
- else { /* only for previewrender, so we see stuff */
+ else {
VECCOPY(vec, shi->lo);
- retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres);
+ retval= multitex_thread((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output);
}
/* stupid exception */
diff --git a/source/blender/nodes/intern/SHD_util.c b/source/blender/nodes/intern/SHD_util.c
index f673834d2b7..b5e82db8a93 100644
--- a/source/blender/nodes/intern/SHD_util.c
+++ b/source/blender/nodes/intern/SHD_util.c
@@ -82,6 +82,7 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
/* convert caller data to struct */
scd.shi= shi;
scd.shr= shr;
+
/* each material node has own local shaderesult, with optional copying */
memset(shr, 0, sizeof(ShadeResult));
diff --git a/source/blender/nodes/intern/TEX_nodes/Makefile b/source/blender/nodes/intern/TEX_nodes/Makefile
new file mode 100644
index 00000000000..7fad19a772c
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/Makefile
@@ -0,0 +1,48 @@
+#
+# $Id: Makefile 12796 2007-12-05 16:58:52Z sirdude $
+#
+# ***** BEGIN GPL/BL DUAL 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. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = nodes_tex
+DIR = $(OCGDIR)/blender/$(LIBNAME)
+
+include nan_compile.mk
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+
+CPPFLAGS += -I../../../blenkernel
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../../../makesdna
+CPPFLAGS += -I../../../blenlib
+CPPFLAGS += -I../../../include
+CPPFLAGS += -I../../../imbuf
+CPPFLAGS += -I../../../render/extern/include
+CPPFLAGS += -I$(OPENGL_HEADERS)
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c b/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c
new file mode 100644
index 00000000000..c9fa3528b02
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_bricks.c
@@ -0,0 +1,123 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+#include <math.h>
+
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Bricks 1", 0.596f, 0.282f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { SOCK_RGBA, 1, "Bricks 2", 0.632f, 0.504f, 0.05f, 1.0f, 0.0f, 1.0f },
+ { SOCK_RGBA, 1, "Mortar", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 1, "Thickness", 0.02f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 1, "Bias", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f },
+ { SOCK_VALUE, 1, "Brick Width", 0.5f, 0.0f, 0.0f, 0.0f, 0.001f, 99.0f },
+ { SOCK_VALUE, 1, "Row Height", 0.25f, 0.0f, 0.0f, 0.0f, 0.001f, 99.0f },
+ { -1, 0, "" }
+};
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void init(bNode *node) {
+ node->custom3 = 0.5; /* offset */
+ node->custom4 = 1.0; /* squash */
+}
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float x = coord[0];
+ float y = coord[1];
+
+ float bricknum, rownum, offset = 0;
+ float ins_x, ins_y;
+ float tint;
+
+ float bricks1[4];
+ float bricks2[4];
+ float mortar[4];
+
+ float mortar_thickness = tex_input_value(in[3], coord, thread);
+ float bias = tex_input_value(in[4], coord, thread);
+ float brick_width = tex_input_value(in[5], coord, thread);
+ float row_height = tex_input_value(in[6], coord, thread);
+
+ tex_input_rgba(bricks1, in[0], coord, thread);
+ tex_input_rgba(bricks2, in[1], coord, thread);
+ tex_input_rgba(mortar, in[2], coord, thread);
+
+ rownum = floor(y / row_height);
+
+ if( node->custom1 && node->custom2 ) {
+ brick_width *= ((int)(rownum) % node->custom2 ) ? 1.0f : node->custom4; /* squash */
+ offset = ((int)(rownum) % node->custom1 ) ? 0 : (brick_width*node->custom3); /* offset */
+ }
+
+ bricknum = floor((x+offset) / brick_width);
+
+ ins_x = (x+offset) - brick_width*bricknum;
+ ins_y = y - row_height*rownum;
+
+ srand( (123456*rownum) + bricknum );
+ tint = rand() / (float)RAND_MAX + bias;
+ CLAMP(tint,0.0f,1.0f);
+
+ if( ins_x < mortar_thickness || ins_y < mortar_thickness ||
+ ins_x > (brick_width - mortar_thickness) ||
+ ins_y > (row_height - mortar_thickness) ) {
+ QUATCOPY( out, mortar );
+ } else {
+ QUATCOPY( out, bricks1 );
+ ramp_blend( MA_RAMP_BLEND, out, out+1, out+2, tint, bricks2 );
+ }
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_bricks= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_BRICKS,
+ /* name */ "Bricks",
+ /* width+range */ 150, 60, 150,
+ /* class+opts */ NODE_CLASS_PATTERN, NODE_OPTIONS | NODE_PREVIEW,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ init,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_checker.c b/source/blender/nodes/intern/TEX_nodes/TEX_checker.c
new file mode 100644
index 00000000000..60357782e25
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_checker.c
@@ -0,0 +1,85 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+#include <math.h>
+
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color1", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { SOCK_RGBA, 1, "Color2", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 1, "Size", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 100.0f },
+ { -1, 0, "" }
+};
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float x = coord[0];
+ float y = coord[1];
+ float z = coord[2];
+ float sz = tex_input_value(in[2], coord, thread);
+
+ /* 0.00001 because of unit sized stuff */
+ int xi = (int)fabs(floor(0.00001 + x / sz));
+ int yi = (int)fabs(floor(0.00001 + y / sz));
+ int zi = (int)fabs(floor(0.00001 + z / sz));
+
+ if( (xi % 2 == yi % 2) == (zi % 2) ) {
+ tex_input_rgba(out, in[0], coord, thread);
+ } else {
+ tex_input_rgba(out, in[1], coord, thread);
+ }
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_checker= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_CHECKER,
+ /* name */ "Checker",
+ /* width+range */ 100, 60, 150,
+ /* class+opts */ NODE_CLASS_PATTERN, NODE_OPTIONS | NODE_PREVIEW,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_curves.c b/source/blender/nodes/intern/TEX_nodes/TEX_curves.c
new file mode 100644
index 00000000000..8c86656b4f3
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_curves.c
@@ -0,0 +1,127 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+/* **************** CURVE Time ******************** */
+
+/* custom1 = sfra, custom2 = efra */
+static bNodeSocketType time_outputs[]= {
+ { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void time_colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ /* stack order output: fac */
+ float fac= 0.0f;
+
+ if(node->custom1 < node->custom2)
+ fac = (G.scene->r.cfra - node->custom1)/(float)(node->custom2-node->custom1);
+
+ fac = curvemapping_evaluateF(node->storage, 0, fac);
+ out[0] = CLAMPIS(fac, 0.0f, 1.0f);
+}
+
+static void time_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &time_colorfn);
+}
+
+
+static void time_init(bNode* node)
+{
+ node->custom1= G.scene->r.sfra;
+ node->custom2= G.scene->r.efra;
+ node->storage= curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+}
+
+bNodeType tex_node_curve_time= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_CURVE_TIME,
+ /* name */ "Time",
+ /* width+range */ 140, 100, 320,
+ /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS,
+ /* input sock */ NULL,
+ /* output sock */ time_outputs,
+ /* storage */ "CurveMapping",
+ /* execfunc */ time_exec,
+ /* butfunc */ NULL,
+ /* initfunc */ time_init,
+ /* freestoragefunc */ node_free_curves,
+ /* copystoragefunc */ node_copy_curves,
+ /* id */ NULL
+};
+
+/* **************** CURVE RGB ******************** */
+static bNodeSocketType rgb_inputs[]= {
+ { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketType rgb_outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void rgb_colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float cin[4];
+ tex_input_rgba(cin, in[0], coord, thread);
+
+ curvemapping_evaluateRGBF(node->storage, out, cin);
+ out[3] = cin[3];
+}
+
+static void rgb_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &rgb_colorfn);
+}
+
+static void rgb_init(bNode *node)
+{
+ node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
+}
+
+bNodeType tex_node_curve_rgb= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_CURVE_RGB,
+ /* name */ "RGB Curves",
+ /* width+range */ 200, 140, 320,
+ /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS,
+ /* input sock */ rgb_inputs,
+ /* output sock */ rgb_outputs,
+ /* storage */ "CurveMapping",
+ /* execfunc */ rgb_exec,
+ /* butfunc */ NULL,
+ /* initfunc */ rgb_init,
+ /* freestoragefunc */ node_free_curves,
+ /* copystoragefunc */ node_copy_curves,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c b/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c
new file mode 100644
index 00000000000..d1a33896fc3
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c
@@ -0,0 +1,104 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Juho Vepsäläinen
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+
+static bNodeSocketType inputs[]= {
+ { SOCK_VALUE, 1, "Hue", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 1, "Saturation", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f},
+ { SOCK_VALUE, 1, "Value", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f},
+ { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void do_hue_sat_fac(bNode *node, float *out, float hue, float sat, float val, float *in, float fac)
+{
+ if(fac != 0 && (hue != 0.5f || sat != 1 || val != 1)) {
+ float col[3], hsv[3], mfac= 1.0f - fac;
+
+ rgb_to_hsv(in[0], in[1], in[2], hsv, hsv+1, hsv+2);
+ hsv[0]+= (hue - 0.5f);
+ if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
+ hsv[1]*= sat;
+ if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
+ hsv[2]*= val;
+ if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
+
+ out[0]= mfac*in[0] + fac*col[0];
+ out[1]= mfac*in[1] + fac*col[1];
+ out[2]= mfac*in[2] + fac*col[2];
+ }
+ else {
+ QUATCOPY(out, in);
+ }
+}
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float in0 = tex_input_value(in[0], coord, thread);
+ float in1 = tex_input_value(in[1], coord, thread);
+ float in2 = tex_input_value(in[2], coord, thread);
+ float in3 = tex_input_value(in[3], coord, thread);
+
+ float in4[4];
+ tex_input_rgba(in4, in[4], coord, thread);
+
+ do_hue_sat_fac(node, out, in0, in1, in2, in4, in3);
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+}
+
+bNodeType tex_node_hue_sat= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_HUE_SAT,
+ /* name */ "Hue Saturation Value",
+ /* width+range */ 150, 80, 250,
+ /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
+
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_image.c b/source/blender/nodes/intern/TEX_nodes/TEX_image.c
new file mode 100644
index 00000000000..f9477fef12b
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_image.c
@@ -0,0 +1,106 @@
+/**
+ * $Id: TEX_image.c 10456 2007-04-04 13:58:12Z jesterking $
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float x = coord[0];
+ float y = coord[1];
+ Image *ima= (Image *)node->id;
+ ImageUser *iuser= (ImageUser *)node->storage;
+
+ if( ima ) {
+ ImBuf *ibuf = BKE_image_get_ibuf(ima, iuser);
+ if( ibuf ) {
+ float xsize, ysize;
+ float xoff, yoff;
+ int px, py;
+
+ float *result;
+
+ xsize = ibuf->x / 2;
+ ysize = ibuf->y / 2;
+ xoff = yoff = -1;
+
+ px = (int)( (x-xoff) * xsize );
+ py = (int)( (y-yoff) * ysize );
+
+ if( (!xsize) || (!ysize) ) return;
+ if( !ibuf->rect_float ) IMB_float_from_rect(ibuf);
+
+ while( px < 0 ) px += ibuf->x;
+ while( py < 0 ) py += ibuf->y;
+ while( px >= ibuf->x ) px -= ibuf->x;
+ while( py >= ibuf->y ) py -= ibuf->y;
+
+ result = ibuf->rect_float + py*ibuf->x*4 + px*4;
+ QUATCOPY( out, result );
+ }
+ }
+};
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+static void init(bNode* node)
+{
+ ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
+ node->storage= iuser;
+ iuser->sfra= 1;
+ iuser->fie_ima= 2;
+ iuser->ok= 1;
+}
+
+bNodeType tex_node_image= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_IMAGE,
+ /* name */ "Image",
+ /* width+range */ 120, 80, 300,
+ /* class+opts */ NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS,
+ /* input sock */ NULL,
+ /* output sock */ outputs,
+ /* storage */ "ImageUser",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ init,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_invert.c b/source/blender/nodes/intern/TEX_nodes/TEX_invert.c
new file mode 100644
index 00000000000..09716951009
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_invert.c
@@ -0,0 +1,79 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+/* **************** INVERT ******************** */
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float col[4];
+
+ tex_input_rgba(col, in[0], coord, thread);
+
+ col[0] = 1.0f - col[0];
+ col[1] = 1.0f - col[1];
+ col[2] = 1.0f - col[2];
+
+ VECCOPY(out, col);
+ out[3] = col[3];
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_invert= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_INVERT,
+ /* name */ "Invert",
+ /* width+range */ 90, 80, 100,
+ /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_math.c b/source/blender/nodes/intern/TEX_nodes/TEX_math.c
new file mode 100644
index 00000000000..a2c66078692
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_math.c
@@ -0,0 +1,172 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+
+
+/* **************** SCALAR MATH ******************** */
+static bNodeSocketType inputs[]= {
+ { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f},
+ { SOCK_VALUE, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f},
+ { -1, 0, "" }
+};
+
+static bNodeSocketType outputs[]= {
+ { SOCK_VALUE, 0, "Value", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void valuefn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float in0 = tex_input_value(in[0], coord, thread);
+ float in1 = tex_input_value(in[1], coord, thread);
+
+ switch(node->custom1){
+
+ case 0: /* Add */
+ *out= in0 + in1;
+ break;
+ case 1: /* Subtract */
+ *out= in0 - in1;
+ break;
+ case 2: /* Multiply */
+ *out= in0 * in1;
+ break;
+ case 3: /* Divide */
+ {
+ if(in1==0) /* We don't want to divide by zero. */
+ *out= 0.0;
+ else
+ *out= in0 / in1;
+ }
+ break;
+ case 4: /* Sine */
+ {
+ *out= sin(in0);
+ }
+ break;
+ case 5: /* Cosine */
+ {
+ *out= cos(in0);
+ }
+ break;
+ case 6: /* Tangent */
+ {
+ *out= tan(in0);
+ }
+ break;
+ case 7: /* Arc-Sine */
+ {
+ /* Can't do the impossible... */
+ if( in0 <= 1 && in0 >= -1 )
+ *out= asin(in0);
+ else
+ *out= 0.0;
+ }
+ break;
+ case 8: /* Arc-Cosine */
+ {
+ /* Can't do the impossible... */
+ if( in0 <= 1 && in0 >= -1 )
+ *out= acos(in0);
+ else
+ *out= 0.0;
+ }
+ break;
+ case 9: /* Arc-Tangent */
+ {
+ *out= atan(in0);
+ }
+ break;
+ case 10: /* Power */
+ {
+ /* Don't want any imaginary numbers... */
+ if( in0 >= 0 )
+ *out= pow(in0, in1);
+ else
+ *out= 0.0;
+ }
+ break;
+ case 11: /* Logarithm */
+ {
+ /* Don't want any imaginary numbers... */
+ if( in0 > 0 && in1 > 0 )
+ *out= log(in0) / log(in1);
+ else
+ *out= 0.0;
+ }
+ break;
+ case 12: /* Minimum */
+ {
+ if( in0 < in1 )
+ *out= in0;
+ else
+ *out= in1;
+ }
+ break;
+ case 13: /* Maximum */
+ {
+ if( in0 > in1 )
+ *out= in0;
+ else
+ *out= in1;
+ }
+ break;
+ case 14: /* Round */
+ {
+ *out= (int)(in0 + 0.5f);
+ }
+ break;
+ }
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &valuefn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_math= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_MATH,
+ /* name */ "Math",
+ /* width+range */ 120, 110, 160,
+ /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "node_math",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c b/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c
new file mode 100644
index 00000000000..b1ccb7a3d07
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_mixRgb.c
@@ -0,0 +1,81 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+
+/* **************** MIX RGB ******************** */
+static bNodeSocketType inputs[]= {
+ { SOCK_VALUE, 1, "Factor", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_RGBA, 1, "Color1", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f },
+ { SOCK_RGBA , 1, "Color2", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float fac = tex_input_value(in[0], coord, thread);
+ float col1[4], col2[4];
+
+ tex_input_rgba(col1, in[1], coord, thread);
+ tex_input_rgba(col2, in[2], coord, thread);
+
+ CLAMP(fac, 0.0f, 1.0f);
+
+ QUATCOPY(out, col1);
+ ramp_blend(node->custom1, out, out+1, out+2, fac, col2);
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_mix_rgb= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_MIX_RGB,
+ /* name */ "Mix",
+ /* width+range */ 100, 60, 150,
+ /* class+opts */ NODE_CLASS_OP_COLOR, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_output.c b/source/blender/nodes/intern/TEX_nodes/TEX_output.c
new file mode 100644
index 00000000000..060ea8d7e67
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_output.c
@@ -0,0 +1,90 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+/* **************** COMPOSITE ******************** */
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+/* applies to render pipeline */
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ TexCallData *cdata = (TexCallData *)data;
+ TexResult *target = cdata->target;
+
+ if(in[1]->hasinput && !in[0]->hasinput)
+ tex_do_preview(node, in[1], data);
+ else
+ tex_do_preview(node, in[0], data);
+
+ if(!cdata->do_preview) {
+ if(cdata->which_output == node->custom1)
+ {
+ tex_input_rgba(&target->tr, in[0], cdata->coord, cdata->thread);
+
+ target->tin = (target->tr + target->tg + target->tb) / 3.0f;
+ target->talpha = 1.0f;
+
+ if(target->nor) {
+ if(in[1]->hasinput)
+ tex_input_vec(target->nor, in[1], cdata->coord, cdata->thread);
+ else
+ target->nor = 0;
+ }
+ }
+ }
+}
+
+static void init(bNode* node)
+{
+ TexNodeOutput *tno = MEM_callocN(sizeof(TexNodeOutput), "TEX_output");
+ strcpy(tno->name, "Default");
+ node->storage= tno;
+}
+
+
+bNodeType tex_node_output= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_OUTPUT,
+ /* name */ "Output",
+ /* width+range */ 150, 60, 200,
+ /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW | NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ NULL,
+ /* storage */ "TexNodeOutput",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ init,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+};
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_proc.c b/source/blender/nodes/intern/TEX_nodes/TEX_proc.c
new file mode 100644
index 00000000000..9078dd1be21
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_proc.c
@@ -0,0 +1,310 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+#include "RE_shader_ext.h"
+
+/*
+ In this file: wrappers to use procedural textures as nodes
+*/
+
+
+static bNodeSocketType outputs_both[]= {
+ { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+static bNodeSocketType outputs_color_only[]= {
+ { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+/* Inputs common to all, #defined because nodes will need their own inputs too */
+#define I 2 /* count */
+#define COMMON_INPUTS \
+ { SOCK_RGBA, 1, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, \
+ { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }
+
+/* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */
+static void do_proc(float *result, float *coord, float *col1, float *col2, char is_normal, Tex *tex, short thread)
+{
+ TexResult texres;
+ int textype;
+
+ if(is_normal) {
+ texres.nor = result;
+ }
+ else
+ texres.nor = NULL;
+
+ textype = multitex_thread(tex, coord, 0, 0, 0, &texres, thread, 0);
+
+ if(is_normal)
+ return;
+
+ if(textype & TEX_RGB) {
+ QUATCOPY(result, &texres.tr);
+ }
+ else {
+ QUATCOPY(result, col1);
+ ramp_blend(MA_RAMP_BLEND, result, result+1, result+2, texres.tin, col2);
+ }
+}
+
+typedef void (*MapFn) (Tex *tex, bNodeStack **in, float *coord, short thread);
+
+static void texfn(
+ float *result,
+ float *coord,
+ bNode *node,
+ bNodeStack **in,
+ char is_normal,
+ MapFn map_inputs,
+ short thread)
+{
+ Tex tex = *((Tex*)(node->storage));
+ float col1[4], col2[4];
+ tex_input_rgba(col1, in[0], coord, thread);
+ tex_input_rgba(col2, in[1], coord, thread);
+
+ map_inputs(&tex, in, coord, thread);
+
+ do_proc(result, coord, col1, col2, is_normal, &tex, thread);
+}
+
+static int count_outputs(bNode *node)
+{
+ bNodeSocket *sock;
+ int num = 0;
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ num++;
+ }
+ return num;
+}
+
+/* Boilerplate generators */
+
+#define ProcNoInputs(name) \
+ static void name##_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) \
+ {}
+
+#define ProcDef(name) \
+ static void name##_colorfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \
+ { \
+ texfn(result, coord, node, in, 0, &name##_map_inputs, thread); \
+ } \
+ static void name##_normalfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \
+ { \
+ texfn(result, coord, node, in, 1, &name##_map_inputs, thread); \
+ } \
+ static void name##_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) \
+ { \
+ int outs = count_outputs(node); \
+ if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn); \
+ if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn); \
+ if(outs >= 1) tex_do_preview(node, out[0], data); \
+ }
+
+
+/* --- VORONOI -- */
+static bNodeSocketType voronoi_inputs[]= {
+ COMMON_INPUTS,
+ { SOCK_VALUE, 1, "W1", 1.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f },
+ { SOCK_VALUE, 1, "W2", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f },
+ { SOCK_VALUE, 1, "W3", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f },
+ { SOCK_VALUE, 1, "W4", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f },
+
+ { SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f },
+ { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f },
+
+ { -1, 0, "" }
+};
+static void voronoi_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
+{
+ tex->vn_w1 = tex_input_value(in[I+0], coord, thread);
+ tex->vn_w2 = tex_input_value(in[I+1], coord, thread);
+ tex->vn_w3 = tex_input_value(in[I+2], coord, thread);
+ tex->vn_w4 = tex_input_value(in[I+3], coord, thread);
+
+ tex->ns_outscale = tex_input_value(in[I+4], coord, thread);
+ tex->noisesize = tex_input_value(in[I+5], coord, thread);
+}
+ProcDef(voronoi)
+
+/* --- BLEND -- */
+static bNodeSocketType blend_inputs[]= {
+ COMMON_INPUTS,
+ { -1, 0, "" }
+};
+ProcNoInputs(blend)
+ProcDef(blend)
+
+/* -- MAGIC -- */
+static bNodeSocketType magic_inputs[]= {
+ COMMON_INPUTS,
+ { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f },
+ { -1, 0, "" }
+};
+static void magic_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
+{
+ tex->turbul = tex_input_value(in[I+0], coord, thread);
+}
+ProcDef(magic)
+
+/* --- MARBLE --- */
+static bNodeSocketType marble_inputs[]= {
+ COMMON_INPUTS,
+ { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
+ { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f },
+ { -1, 0, "" }
+};
+static void marble_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
+{
+ tex->noisesize = tex_input_value(in[I+0], coord, thread);
+ tex->turbul = tex_input_value(in[I+1], coord, thread);
+}
+ProcDef(marble)
+
+/* --- CLOUDS --- */
+static bNodeSocketType clouds_inputs[]= {
+ COMMON_INPUTS,
+ { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
+ { -1, 0, "" }
+};
+static void clouds_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
+{
+ tex->noisesize = tex_input_value(in[I+0], coord, thread);
+}
+ProcDef(clouds)
+
+/* --- DISTORTED NOISE --- */
+static bNodeSocketType distnoise_inputs[]= {
+ COMMON_INPUTS,
+ { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
+ { SOCK_VALUE, 1, "Distortion", 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f },
+ { -1, 0, "" }
+};
+static void distnoise_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
+{
+ tex->noisesize = tex_input_value(in[I+0], coord, thread);
+ tex->dist_amount = tex_input_value(in[I+1], coord, thread);
+}
+ProcDef(distnoise)
+
+/* --- WOOD --- */
+static bNodeSocketType wood_inputs[]= {
+ COMMON_INPUTS,
+ { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
+ { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f },
+ { -1, 0, "" }
+};
+static void wood_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
+{
+ tex->noisesize = tex_input_value(in[I+0], coord, thread);
+ tex->turbul = tex_input_value(in[I+1], coord, thread);
+}
+ProcDef(wood)
+
+/* --- MUSGRAVE --- */
+static bNodeSocketType musgrave_inputs[]= {
+ COMMON_INPUTS,
+ { SOCK_VALUE, 1, "H", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
+ { SOCK_VALUE, 1, "Lacunarity", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f },
+ { SOCK_VALUE, 1, "Octaves", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f },
+
+ { SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f },
+ { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
+ { -1, 0, "" }
+};
+static void musgrave_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
+{
+ tex->mg_H = tex_input_value(in[I+0], coord, thread);
+ tex->mg_lacunarity = tex_input_value(in[I+1], coord, thread);
+ tex->mg_octaves = tex_input_value(in[I+2], coord, thread);
+ tex->ns_outscale = tex_input_value(in[I+3], coord, thread);
+ tex->noisesize = tex_input_value(in[I+4], coord, thread);
+}
+ProcDef(musgrave)
+
+/* --- NOISE --- */
+static bNodeSocketType noise_inputs[]= {
+ COMMON_INPUTS,
+ { -1, 0, "" }
+};
+ProcNoInputs(noise)
+ProcDef(noise)
+
+/* --- STUCCI --- */
+static bNodeSocketType stucci_inputs[]= {
+ COMMON_INPUTS,
+ { SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
+ { SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f },
+ { -1, 0, "" }
+};
+static void stucci_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread)
+{
+ tex->noisesize = tex_input_value(in[I+0], coord, thread);
+ tex->turbul = tex_input_value(in[I+1], coord, thread);
+}
+ProcDef(stucci)
+
+/* --- */
+
+static void init(bNode *node)
+{
+ Tex *tex = MEM_callocN(sizeof(Tex), "Tex");
+ node->storage= tex;
+
+ default_tex(tex);
+ tex->type = node->type - TEX_NODE_PROC;
+
+ if(tex->type == TEX_WOOD)
+ tex->stype = TEX_BANDNOISE;
+
+}
+
+/* Node type definitions */
+#define TexDef(TEXTYPE, outputs, name, Name) \
+ { NULL, NULL, TEX_NODE_PROC+TEXTYPE, Name, 140,80,140, NODE_CLASS_TEXTURE, \
+ NODE_OPTIONS | NODE_PREVIEW, name##_inputs, outputs, "Tex", name##_exec, NULL, init, \
+ node_free_standard_storage, node_copy_standard_storage, NULL }
+
+#define C outputs_color_only
+#define CV outputs_both
+
+bNodeType tex_node_proc_voronoi = TexDef(TEX_VORONOI, CV, voronoi, "Voronoi" );
+bNodeType tex_node_proc_blend = TexDef(TEX_BLEND, C, blend, "Blend" );
+bNodeType tex_node_proc_magic = TexDef(TEX_MAGIC, C, magic, "Magic" );
+bNodeType tex_node_proc_marble = TexDef(TEX_MARBLE, CV, marble, "Marble" );
+bNodeType tex_node_proc_clouds = TexDef(TEX_CLOUDS, CV, clouds, "Clouds" );
+bNodeType tex_node_proc_wood = TexDef(TEX_WOOD, CV, wood, "Wood" );
+bNodeType tex_node_proc_musgrave = TexDef(TEX_MUSGRAVE, CV, musgrave, "Musgrave" );
+bNodeType tex_node_proc_noise = TexDef(TEX_NOISE, C, noise, "Noise" );
+bNodeType tex_node_proc_stucci = TexDef(TEX_STUCCI, CV, stucci, "Stucci" );
+bNodeType tex_node_proc_distnoise = TexDef(TEX_DISTNOISE, CV, distnoise, "Distorted Noise" );
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c
new file mode 100644
index 00000000000..93bf17d4862
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c
@@ -0,0 +1,114 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include "MTC_vectorops.h"
+#include "../TEX_util.h"
+
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VALUE, 1, "Turns", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f },
+ { SOCK_VECTOR, 1, "Axis", 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float new_coord[3];
+
+ float ax[4];
+ float para[3];
+ float perp[3];
+ float cp[3];
+
+ float magsq, ndx;
+
+ float a = tex_input_value(in[1], coord, thread);
+ float cos_a = cos(a * 2 * M_PI);
+ float sin_a = sin(a * 2 * M_PI);
+
+ // x' = xcosa + n(n.x)(1-cosa)+(x*n)sina
+
+ tex_input_vec(ax, in[2], coord, thread);
+ magsq = ax[0]*ax[0] + ax[1]*ax[1] + ax[2]*ax[2];
+
+ if(magsq == 0) magsq = 1;
+
+ ndx = MTC_dot3Float(coord, ax);
+
+ para[0] = ax[0] * ndx * (1 - cos_a);
+ para[1] = ax[1] * ndx * (1 - cos_a);
+ para[2] = ax[2] * ndx * (1 - cos_a);
+
+ MTC_diff3Float(perp, coord, para);
+
+ perp[0] = coord[0] * cos_a;
+ perp[1] = coord[1] * cos_a;
+ perp[2] = coord[2] * cos_a;
+
+ MTC_cross3Float(cp, ax, coord);
+
+ cp[0] = cp[0] * sin_a;
+ cp[1] = cp[1] * sin_a;
+ cp[2] = cp[2] * sin_a;
+
+ new_coord[0] = para[0] + perp[0] + cp[0];
+ new_coord[1] = para[1] + perp[1] + cp[1];
+ new_coord[2] = para[2] + perp[2] + cp[2];
+
+ tex_input_rgba(out, in[0], new_coord, thread);
+}
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_rotate= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_ROTATE,
+ /* name */ "Rotate",
+ /* width+range */ 90, 80, 100,
+ /* class+opts */ NODE_CLASS_DISTORT, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_texture.c b/source/blender/nodes/intern/TEX_nodes/TEX_texture.c
new file mode 100644
index 00000000000..884d2cd0eb6
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_texture.c
@@ -0,0 +1,103 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+#include "RE_shader_ext.h"
+
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color1", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f },
+ { SOCK_RGBA, 1, "Color2", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ static float red[] = {1,0,0,1};
+ static float white[] = {1,1,1,1};
+
+ Tex *nodetex = (Tex *)node->id;
+
+ if(node->custom2) {
+ /* this node refers to its own texture tree! */
+ QUATCOPY(
+ out,
+ (fabs(coord[0] - coord[1]) < .01) ? white : red
+ );
+ }
+ else if(nodetex) {
+ TexResult texres;
+ int textype;
+ float nor[] = {0,0,0};
+ float col1[4], col2[4];
+
+ tex_input_rgba(col1, in[0], coord, thread);
+ tex_input_rgba(col2, in[1], coord, thread);
+
+ texres.nor = nor;
+ textype = multitex_ext(nodetex, coord, 0, 0, 0, &texres);
+
+ if(textype & TEX_RGB) {
+ QUATCOPY(out, &texres.tr);
+ }
+ else {
+ QUATCOPY(out, col1);
+ ramp_blend(MA_RAMP_BLEND, out, out+1, out+2, texres.tin, col2);
+ }
+ }
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_texture= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_TEXTURE,
+ /* name */ "Texture",
+ /* width+range */ 120, 80, 240,
+ /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c b/source/blender/nodes/intern/TEX_nodes/TEX_translate.c
new file mode 100644
index 00000000000..bd7e61d0ff4
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_translate.c
@@ -0,0 +1,78 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include "../TEX_util.h"
+
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 1, "Offset", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float offset[3], new_coord[3];
+
+ tex_input_vec(offset, in[1], coord, thread);
+
+ new_coord[0] = coord[0] + offset[0];
+ new_coord[1] = coord[1] + offset[1];
+ new_coord[2] = coord[2] + offset[2];
+
+ tex_input_rgba(out, in[0], new_coord, thread);
+}
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_translate = {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_TRANSLATE,
+ /* name */ "Translate",
+ /* width+range */ 90, 80, 100,
+ /* class+opts */ NODE_CLASS_DISTORT, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c b/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c
new file mode 100644
index 00000000000..ec59769fdfd
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_valToRgb.c
@@ -0,0 +1,122 @@
+/**
+ * $Id: SHD_valToRgb.c 10456 2007-04-04 13:58:12Z jesterking $
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+/* **************** VALTORGB ******************** */
+static bNodeSocketType valtorgb_in[]= {
+ { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType valtorgb_out[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void valtorgb_colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ if(node->storage) {
+ float fac = tex_input_value(in[0], coord, thread);
+
+ do_colorband(node->storage, fac, out);
+ }
+}
+
+static void valtorgb_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &valtorgb_colorfn);
+}
+
+static void valtorgb_init(bNode *node)
+{
+ node->storage = add_colorband(1);
+}
+
+bNodeType tex_node_valtorgb= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_VALTORGB,
+ /* name */ "ColorRamp",
+ /* width+range */ 240, 200, 300,
+ /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS,
+ /* input sock */ valtorgb_in,
+ /* output sock */ valtorgb_out,
+ /* storage */ "ColorBand",
+ /* execfunc */ valtorgb_exec,
+ /* butfunc */ NULL,
+ /* initfunc */ valtorgb_init,
+ /* freestoragefunc */ node_free_standard_storage,
+ /* copystoragefunc */ node_copy_standard_storage,
+ /* id */ NULL
+
+};
+
+/* **************** RGBTOBW ******************** */
+static bNodeSocketType rgbtobw_in[]= {
+ { SOCK_RGBA, 1, "Color", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+static bNodeSocketType rgbtobw_out[]= {
+ { SOCK_VALUE, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+
+static void rgbtobw_valuefn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float cin[4];
+ tex_input_rgba(cin, in[0], coord, thread);
+
+ *out = cin[0] * 0.35f + cin[1] * 0.45f + cin[2] * 0.2f;
+}
+
+static void rgbtobw_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &rgbtobw_valuefn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_rgbtobw= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_RGBTOBW,
+ /* name */ "RGB to BW",
+ /* width+range */ 80, 40, 120,
+ /* class+opts */ NODE_CLASS_CONVERTOR, 0,
+ /* input sock */ rgbtobw_in,
+ /* output sock */ rgbtobw_out,
+ /* storage */ "",
+ /* execfunc */ rgbtobw_exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c b/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c
new file mode 100644
index 00000000000..acdaacf873c
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_viewer.c
@@ -0,0 +1,61 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+#include <math.h>
+
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+static bNodeSocketType outputs[]= {
+ { -1, 0, "" }
+};
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_do_preview(node, in[0], data);
+}
+
+bNodeType tex_node_viewer = {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_VIEWER,
+ /* name */ "Viewer",
+ /* width+range */ 100, 60, 150,
+ /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c
new file mode 100644
index 00000000000..10fe3bab26c
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_util.c
@@ -0,0 +1,270 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/*
+ HOW TEXTURE NODES WORK
+
+ In contrast to Shader nodes, which place a colour into the output
+ stack when executed, Texture nodes place a TexDelegate* there. To
+ obtain a colour value from this, a node further up the chain reads
+ the TexDelegate* from its input stack, and uses tex_call_delegate to
+ retrieve the colour from the delegate.
+*/
+
+#include <assert.h>
+#include "TEX_util.h"
+
+#define PREV_RES 128 /* default preview resolution */
+
+void tex_call_delegate(TexDelegate *dg, float *out, float *coord, short thread)
+{
+ dg->fn(out, coord, dg->node, dg->in, thread);
+}
+
+void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread)
+{
+ TexDelegate *dg = in->data;
+ if(dg) {
+ tex_call_delegate(dg, out, coord, thread);
+
+ if(in->hasoutput && in->sockettype == SOCK_VALUE) {
+ out[1] = out[2] = out[0];
+ out[3] = 1;
+ }
+ }
+ else {
+ QUATCOPY(out, in->vec);
+ }
+}
+
+void tex_input_rgba(float *out, bNodeStack *in, float *coord, short thread)
+{
+ tex_input_vec(out, in, coord, thread);
+
+ if(in->hasoutput && in->sockettype == SOCK_VECTOR) {
+ out[0] = out[0] * .5f + .5f;
+ out[1] = out[1] * .5f + .5f;
+ out[2] = out[2] * .5f + .5f;
+ out[3] = 1;
+ }
+}
+
+float tex_input_value(bNodeStack *in, float *coord, short thread)
+{
+ float out[4];
+ tex_input_vec(out, in, coord, thread);
+ return out[0];
+}
+
+static void init_preview(bNode *node)
+{
+ int xsize = node->prvr.xmax - node->prvr.xmin;
+ int ysize = node->prvr.ymax - node->prvr.ymin;
+
+ if(xsize == 0) {
+ xsize = PREV_RES;
+ ysize = PREV_RES;
+ }
+
+ if(node->preview==NULL)
+ node->preview= MEM_callocN(sizeof(bNodePreview), "node preview");
+
+ if(node->preview->rect)
+ if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) {
+ MEM_freeN(node->preview->rect);
+ node->preview->rect= NULL;
+ }
+
+ if(node->preview->rect==NULL) {
+ node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect");
+ node->preview->xsize= xsize;
+ node->preview->ysize= ysize;
+ }
+}
+
+void tex_do_preview(bNode *node, bNodeStack *ns, TexCallData *cdata)
+{
+ int x, y;
+ float *result;
+ bNodePreview *preview;
+
+ if(!cdata->do_preview)
+ return;
+
+ if(!(node->typeinfo->flag & NODE_PREVIEW))
+ return;
+
+ init_preview(node);
+
+ preview = node->preview;
+
+ for(x=0; x<preview->xsize; x++)
+ for(y=0; y<preview->ysize; y++)
+ {
+ cdata->coord[0] = ((float) x / preview->xsize) * 2 - 1;
+ cdata->coord[1] = ((float) y / preview->ysize) * 2 - 1;
+
+ result = preview->rect + 4 * (preview->xsize*y + x);
+
+ tex_input_rgba(result, ns, cdata->coord, cdata->thread);
+ }
+}
+
+void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn)
+{
+ TexDelegate *dg;
+ if(!out->data)
+ /* Freed in tex_end_exec (node.c) */
+ dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
+ else
+ dg = out->data;
+
+
+ dg->fn = texfn;
+ dg->node = node;
+ memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack*));
+ dg->type = out->sockettype;
+}
+
+void ntreeTexCheckCyclics(struct bNodeTree *ntree)
+{
+ bNode *node;
+ for(node= ntree->nodes.first; node; node= node->next) {
+
+ if(node->type == TEX_NODE_TEXTURE && node->id)
+ {
+ /* custom2 stops the node from rendering */
+ if(node->custom1) {
+ node->custom2 = 1;
+ node->custom1 = 0;
+ } else {
+ Tex *tex = (Tex *)node->id;
+
+ node->custom2 = 0;
+
+ node->custom1 = 1;
+ if(tex->use_nodes && tex->nodetree) {
+ ntreeTexCheckCyclics(tex->nodetree);
+ }
+ node->custom1 = 0;
+ }
+ }
+
+ }
+}
+
+void ntreeTexExecTree(bNodeTree *nodes, TexResult *texres, float *coord, char do_preview, short thread, Tex *tex, short which_output)
+{
+ TexResult dummy_texres;
+ TexCallData data;
+
+ if(!texres) texres = &dummy_texres;
+ data.coord = coord;
+ data.target = texres;
+ data.do_preview = do_preview;
+ data.thread = thread;
+ data.which_output = which_output;
+
+ ntreeExecTree(nodes, &data, thread);
+}
+
+void ntreeTexUpdatePreviews(bNodeTree* nodetree)
+{
+ Tex *tex;
+ float coord[] = {0,0,0};
+ TexResult dummy_texres;
+
+ for(tex= G.main->tex.first; tex; tex= tex->id.next)
+ if(tex->nodetree == nodetree) break;
+ if(!tex) return;
+
+ dummy_texres.nor = 0;
+
+ ntreeBeginExecTree(nodetree);
+ ntreeTexExecTree(nodetree, &dummy_texres, coord, 1, 0, tex, 0);
+ ntreeEndExecTree(nodetree);
+
+}
+
+char* ntreeTexOutputMenu(bNodeTree *ntree)
+{
+ bNode *node;
+ int len = 1;
+ char *str;
+ char ctrl[4];
+ int index = 0;
+
+ for(node= ntree->nodes.first; node; node= node->next)
+ if(node->type == TEX_NODE_OUTPUT) {
+ len += strlen(
+ ((TexNodeOutput*)node->storage)->name
+ ) + strlen(" %xNNN|");
+ index ++;
+
+ if(node->custom1 > 999) {
+ printf("Error: too many outputs");
+ break;
+ }
+ }
+
+ str = malloc(len * sizeof(char));
+ *str = 0;
+
+ for(node= ntree->nodes.first; node; node= node->next)
+ if(node->type == TEX_NODE_OUTPUT) {
+ strcat(str, ((TexNodeOutput*)node->storage)->name);
+ strcat(str, " %x");
+
+ sprintf(ctrl, "%d", node->custom1);
+ strcat(str, ctrl);
+
+ if(--index)
+ strcat(str, "|");
+ else
+ break;
+ }
+
+ return str;
+}
+
+void ntreeTexAssignIndex(struct bNodeTree *ntree, struct bNode *node)
+{
+ bNode *tnode;
+ int index = 0;
+
+ check_index:
+ for(tnode= ntree->nodes.first; tnode; tnode= tnode->next)
+ if(tnode->type == TEX_NODE_OUTPUT && tnode != node)
+ if(tnode->custom1 == index) {
+ index ++;
+ goto check_index;
+ }
+
+ node->custom1 = index;
+}
+
diff --git a/source/blender/nodes/intern/TEX_util.h b/source/blender/nodes/intern/TEX_util.h
new file mode 100644
index 00000000000..69cf20794c9
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_util.h
@@ -0,0 +1,104 @@
+/**
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef TEX_NODE_UTIL_H_
+#define TEX_NODE_UTIL_H_
+
+#include <math.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_action_types.h"
+#include "DNA_color_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_ID.h"
+#include "DNA_image_types.h"
+#include "DNA_material_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BKE_blender.h"
+#include "BKE_colortools.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+#include "BKE_library.h"
+
+#include "../SHD_node.h"
+#include "node_util.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_rand.h"
+#include "BLI_threads.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "RE_pipeline.h"
+#include "RE_shader_ext.h"
+
+typedef struct TexCallData {
+ TexResult *target;
+ float *coord;
+ char do_preview;
+ short thread;
+ short which_output;
+} TexCallData;
+
+typedef void(*TexFn) (float *out, float *coord, bNode *node, bNodeStack **in, short thread);
+
+typedef struct TexDelegate {
+ TexFn fn;
+ bNode *node;
+ bNodeStack *in[MAX_SOCKET];
+ int type;
+} TexDelegate;
+
+void tex_call_delegate(TexDelegate*, float *out, float *coord, short thread);
+
+void tex_input_rgba(float *out, bNodeStack *in, float *coord, short thread);
+void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread);
+float tex_input_value(bNodeStack *in, float *coord, short thread);
+
+void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn);
+void tex_do_preview(bNode *node, bNodeStack *ns, TexCallData *cdata);
+
+void ntreeTexUpdatePreviews( bNodeTree* nodetree );
+void ntreeTexExecTree(bNodeTree *nodes, TexResult *texres, float *coord, char do_preview, short thread, struct Tex *tex, short which_output);
+
+#endif
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 888474ffa18..2cee2673a26 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -183,6 +183,7 @@ typedef struct ShadeInput
/* node shaders... */
struct Tex;
int multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres);
+int multitex_thread(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres, short thread, short which_output);
/* shaded view and bake */
struct Render;
diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h
index c6b11b4af9a..799f5521017 100644
--- a/source/blender/render/intern/include/pixelshading.h
+++ b/source/blender/render/intern/include/pixelshading.h
@@ -53,8 +53,8 @@ int shadeHaloFloat(HaloRen *har,
/**
* Render the sky at pixel (x, y).
*/
-void shadeSkyPixel(float *collector, float fx, float fy);
-void shadeSkyView(float *colf, float *rco, float *view, float *dxyview);
+void shadeSkyPixel(float *collector, float fx, float fy, short thread);
+void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short thread);
void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance);
void shadeSunView(float *colf, float *view);
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index be5471e07c4..c254b768292 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -53,11 +53,12 @@ struct ImBuf;
/* texture.h */
void do_halo_tex(struct HaloRen *har, float xn, float yn, float *colf);
-void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag);
+void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread);
void do_material_tex(struct ShadeInput *shi);
void do_lamp_tex(LampRen *la, float *lavec, struct ShadeInput *shi, float *colf, int effect);
void init_render_textures(Render *re);
+void end_render_textures(void);
void render_realtime_texture(struct ShadeInput *shi, struct Image *ima);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index a9bc2131d77..e2692113d16 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -2271,6 +2271,7 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float
shi.vlr= vlr; /* current render face */
shi.mat= vlr->mat; /* current input material */
+ shi.thread= 0;
/* Displace the verts, flag is set when done */
if (!vlr->v1->flag)
@@ -4406,6 +4407,7 @@ void RE_Database_Free(Render *re)
end_radio_render();
end_render_materials();
+ end_render_textures();
if(re->wrld.aosphere) {
MEM_freeN(re->wrld.aosphere);
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 60723963af9..af6093ab36c 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -511,7 +511,7 @@ static void fillBackgroundImage(float *collector, float fx, float fy)
}
/* Only view vector is important here. Result goes to colf[3] */
-void shadeSkyView(float *colf, float *rco, float *view, float *dxyview)
+void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short thread)
{
float lo[3], zen[3], hor[3], blend, blendm;
int skyflag;
@@ -550,7 +550,7 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview)
SWAP(float, lo[1], lo[2]);
}
- do_sky_tex(rco, lo, dxyview, hor, zen, &blend, skyflag);
+ do_sky_tex(rco, lo, dxyview, hor, zen, &blend, skyflag, thread);
}
if(blend>1.0) blend= 1.0;
@@ -607,7 +607,7 @@ void shadeSunView(float *colf, float *view)
/*
Stuff the sky color into the collector.
*/
-void shadeSkyPixel(float *collector, float fx, float fy)
+void shadeSkyPixel(float *collector, float fx, float fy, short thread)
{
float view[3], dxyview[2];
@@ -653,7 +653,7 @@ void shadeSkyPixel(float *collector, float fx, float fy)
}
/* get sky color in the collector */
- shadeSkyView(collector, NULL, view, dxyview);
+ shadeSkyView(collector, NULL, view, dxyview, thread);
collector[3] = 0.0f;
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index f822d41bb85..46a7a1c556c 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -396,7 +396,7 @@ static void ray_fadeout_endcolor(float *col, ShadeInput *origshi, ShadeInput *sh
VECCOPY(shi->view, vec);
Normalize(shi->view);
- shadeSkyView(col, isec->start, shi->view, NULL);
+ shadeSkyView(col, isec->start, shi->view, NULL, shi->thread);
shadeSunView(col, shi->view);
}
}
@@ -1627,7 +1627,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
shadfac[2]+= (1.0f-skyfac)*R.wrld.horb + skyfac*R.wrld.zenb;
}
else { /* WO_AOSKYTEX */
- shadeSkyView(skycol, isec.start, view, dxyview);
+ shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
shadeSunView(skycol, shi->view);
shadfac[0]+= skycol[0];
shadfac[1]+= skycol[1];
@@ -1752,7 +1752,7 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
shadfac[2]+= (1.0f-fac)*R.wrld.horb + fac*R.wrld.zenb;
}
else { /* WO_AOSKYTEX */
- shadeSkyView(skycol, isec.start, view, dxyview);
+ shadeSkyView(skycol, isec.start, view, dxyview, shi->thread);
shadeSunView(skycol, shi->view);
shadfac[0]+= skycol[0];
shadfac[1]+= skycol[1];
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 1eb42bca569..c3b281f2a23 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -647,7 +647,7 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
if(pass[3]<1.0f) {
if(done==0) {
- shadeSkyPixel(col, x, y);
+ shadeSkyPixel(col, x, y, pa->thread);
done= 1;
}
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 7ce66ff6d12..61e9d9cf412 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -43,11 +43,13 @@
#include "DNA_meshdata_types.h"
#include "DNA_material_types.h"
#include "DNA_image_types.h"
+#include "DNA_node_types.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "BKE_image.h"
+#include "BKE_node.h"
#include "BKE_plugin_types.h"
#include "BKE_utildefines.h"
@@ -114,6 +116,10 @@ void init_render_texture(Render *re, Tex *tex)
}
}
}
+
+ if(tex->nodetree && tex->use_nodes) {
+ ntreeBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
+ }
}
/* ------------------------------------------------------------------------- */
@@ -129,6 +135,20 @@ void init_render_textures(Render *re)
}
}
+void end_render_texture(Tex *tex)
+{
+ if(tex && tex->use_nodes && tex->nodetree)
+ ntreeEndExecTree(tex->nodetree);
+}
+
+void end_render_textures(void)
+{
+ Tex *tex;
+ for(tex= G.main->tex.first; tex; tex= tex->id.next)
+ if(tex->id.us)
+ end_render_texture(tex);
+}
+
/* ------------------------------------------------------------------------- */
@@ -691,6 +711,19 @@ static float voronoiTex(Tex *tex, float *texvec, TexResult *texres)
}
+/* ------------------------------------------------------------------------- */
+
+static int evalnodes(Tex *tex, float *texvec, TexResult *texres, short thread, short which_output)
+{
+ short rv = TEX_INT;
+ bNodeTree *nodes = tex->nodetree;
+
+ ntreeTexExecTree(nodes, texres, texvec, 0, thread, tex, which_output);
+
+ if(texres->nor) rv |= TEX_NOR;
+ rv |= TEX_RGB;
+ return rv;
+}
/* ------------------------------------------------------------------------- */
@@ -1130,13 +1163,17 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *d
/* ************************************** */
-static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
+static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output)
{
float tmpvec[3];
int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */
texres->talpha= 0; /* is set when image texture returns alpha (considered premul) */
+ if(tex->use_nodes && tex->nodetree) {
+ retval = evalnodes(tex, texvec, texres, thread, which_output);
+ }
+ else
switch(tex->type) {
case 0:
@@ -1236,7 +1273,11 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex,
* the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */
int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
{
-
+ return multitex_thread(tex, texvec, dxt, dyt, osatex, texres, 0, 0);
+}
+
+int multitex_thread(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output)
+{
if(tex==NULL) {
memset(texres, 0, sizeof(TexResult));
return 0;
@@ -1264,10 +1305,10 @@ int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, Te
do_2d_mapping(&mtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
- return multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres);
+ return multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output);
}
else
- return multitex(tex, texvec, dxt, dyt, osatex, texres);
+ return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
}
/* ------------------------------------------------------------------------- */
@@ -1671,7 +1712,7 @@ void do_material_tex(ShadeInput *shi)
}
}
- rgbnor= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres);
+ rgbnor= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
/* texture output */
@@ -2055,7 +2096,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
- rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres);
+ rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output);
/* texture output */
if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -2126,7 +2167,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf)
/* ------------------------------------------------------------------------- */
/* hor and zen are RGB vectors, blend is 1 float, should all be initialized */
-void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag)
+void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread)
{
MTex *mtex;
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
@@ -2226,7 +2267,7 @@ void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, f
/* texture */
if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
- rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres);
+ rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output);
/* texture output */
if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -2407,7 +2448,7 @@ void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int ef
do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
}
- rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres);
+ rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
/* texture output */
if(rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -2492,7 +2533,7 @@ int externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *t
do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
}
- rgb= multitex(tex, texvec, dxt, dyt, 0, &texr);
+ rgb= multitex(tex, texvec, dxt, dyt, 0, &texr, 0, mtex->which_output);
if(rgb) {
texr.tin= (0.35*texr.tr+0.45*texr.tg+0.2*texr.tb);