diff options
Diffstat (limited to 'source')
41 files changed, 2605 insertions, 44 deletions
diff --git a/source/Makefile b/source/Makefile index 18c2da6b4c3..b0182ff131d 100644 --- a/source/Makefile +++ b/source/Makefile @@ -96,6 +96,7 @@ COMLIB += $(OCGDIR)/blender/blenloader/$(DEBUG_DIR)libblenloader.a COMLIB += $(OCGDIR)/blender/blenpluginapi/$(DEBUG_DIR)libblenpluginapi.a COMLIB += $(OCGDIR)/blender/nodes_shd/$(DEBUG_DIR)libnodes_shd.a COMLIB += $(OCGDIR)/blender/nodes_cmp/$(DEBUG_DIR)libnodes_cmp.a +COMLIB += $(OCGDIR)/blender/nodes_tex/$(DEBUG_DIR)libnodes_tex.a COMLIB += $(OCGDIR)/blender/nodes/$(DEBUG_DIR)libnodes.a COMLIB += $(OCGDIR)/blender/imbuf/$(DEBUG_DIR)libimbuf.a COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a 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); |