Compare commits
12 Commits
temp-enum-
...
texture_no
Author | SHA1 | Date | |
---|---|---|---|
9282d305bd | |||
de724a258e | |||
a4ba73311b | |||
b35aafab6a | |||
94dd73b995 | |||
e9e555fb85 | |||
5c50820e6a | |||
f5c526f29c | |||
4bd79aca12 | |||
b2d6cd2e33 | |||
98bd0b4027 | |||
c4235ce820 |
@@ -36,6 +36,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct bNodeTreeExecPool;
|
||||
struct Main;
|
||||
struct Material;
|
||||
struct ID;
|
||||
@@ -96,10 +97,16 @@ struct Material *BKE_material_pop_id(struct ID *id, int index, bool update_data)
|
||||
void BKE_material_clear_id(struct ID *id, bool update_data);
|
||||
/* rendering */
|
||||
|
||||
void init_render_material(struct Material *, int, float *);
|
||||
void init_render_materials(struct Main *, int, float *);
|
||||
void end_render_material(struct Material *);
|
||||
void end_render_materials(struct Main *);
|
||||
void init_render_material(struct Material *mat,
|
||||
struct bNodeTreeExecPool *exec_tree_pool,
|
||||
int render_mode, float *amb);
|
||||
void init_render_materials(struct Main *bmain,
|
||||
struct bNodeTreeExecPool *exec_tree_pool,
|
||||
int render_mode, float *amb);
|
||||
void end_render_material(struct bNodeTreeExecPool *exec_tree_pool,
|
||||
struct Material *mat);
|
||||
void end_render_materials(struct Main *bmain,
|
||||
struct bNodeTreeExecPool *exec_tree_pool);
|
||||
|
||||
bool material_in_material(struct Material *parmat, struct Material *mat);
|
||||
|
||||
|
@@ -84,6 +84,7 @@ struct ColorManagedViewSettings;
|
||||
struct ColorManagedDisplaySettings;
|
||||
struct bNodeInstanceHash;
|
||||
|
||||
typedef struct bNodeTreeExecPool bNodeTreeExecPool;
|
||||
|
||||
/* ************** NODE TYPE DEFINITIONS ***** */
|
||||
|
||||
@@ -773,7 +774,7 @@ struct ShadeResult;
|
||||
|
||||
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree);
|
||||
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec);
|
||||
bool ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
|
||||
bool ntreeShaderExecTree(bNodeTreeExecPool *exec_tree_pool, struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
|
||||
void ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode);
|
||||
|
||||
/* switch material render loop */
|
||||
@@ -999,13 +1000,24 @@ struct TexResult;
|
||||
int ntreeTexTagAnimated(struct bNodeTree *ntree);
|
||||
void ntreeTexCheckCyclics(struct bNodeTree *ntree);
|
||||
|
||||
struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree);
|
||||
struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree) ATTR_WARN_UNUSED_RESULT;
|
||||
void ntreeTexEndExecTree(struct bNodeTreeExec *exec);
|
||||
int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target,
|
||||
int ntreeTexExecTree(bNodeTreeExecPool *pool,
|
||||
struct bNodeTree *ntree, struct TexResult *target,
|
||||
float coord[3], float dxt[3], float dyt[3], int osatex, const short thread,
|
||||
struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex);
|
||||
|
||||
|
||||
bNodeTreeExecPool *BKE_node_tree_exec_pool_new(void);
|
||||
void BKE_node_tree_exec_pool_free(bNodeTreeExecPool *pool);
|
||||
void BKE_node_tree_exec_pool_put(bNodeTreeExecPool *pool,
|
||||
struct ID *id,
|
||||
void *data);
|
||||
void *BKE_node_tree_exec_pool_get(bNodeTreeExecPool *pool,
|
||||
struct ID *id);
|
||||
void *BKE_node_tree_exec_pool_pop(bNodeTreeExecPool *pool,
|
||||
struct ID *id);
|
||||
|
||||
/*************************************************/
|
||||
|
||||
void init_nodesystem(void);
|
||||
|
@@ -1058,12 +1058,15 @@ static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode
|
||||
}
|
||||
}
|
||||
|
||||
void init_render_material(Material *mat, int r_mode, float *amb)
|
||||
void init_render_material(Material *mat,
|
||||
bNodeTreeExecPool *exec_tree_pool,
|
||||
int r_mode, float *amb)
|
||||
{
|
||||
|
||||
do_init_render_material(mat, r_mode, amb);
|
||||
|
||||
|
||||
if (mat->nodetree && mat->use_nodes) {
|
||||
struct bNodeTreeExec *exec_data;
|
||||
/* mode_l will take the pipeline options from the main material, and the or-ed
|
||||
* result of non-pipeline options from the nodes. shadeless is an exception,
|
||||
* mode_l will have it set when all node materials are shadeless. */
|
||||
@@ -1074,9 +1077,15 @@ void init_render_material(Material *mat, int r_mode, float *amb)
|
||||
ntreeShaderGetTexcoMode(mat->nodetree, r_mode, &mat->texco, &mat->mode_l);
|
||||
|
||||
init_render_nodetree(mat->nodetree, mat, r_mode, amb);
|
||||
|
||||
if (!mat->nodetree->execdata)
|
||||
mat->nodetree->execdata = ntreeShaderBeginExecTree(mat->nodetree);
|
||||
|
||||
exec_data = BKE_node_tree_exec_pool_get(exec_tree_pool,
|
||||
&mat->nodetree->id);
|
||||
if (exec_data == NULL) {
|
||||
exec_data = ntreeShaderBeginExecTree(mat->nodetree);
|
||||
BKE_node_tree_exec_pool_put(exec_tree_pool,
|
||||
&mat->nodetree->id,
|
||||
exec_data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mat->mode_l = mat->mode;
|
||||
@@ -1087,7 +1096,9 @@ void init_render_material(Material *mat, int r_mode, float *amb)
|
||||
}
|
||||
}
|
||||
|
||||
void init_render_materials(Main *bmain, int r_mode, float *amb)
|
||||
void init_render_materials(Main *bmain,
|
||||
bNodeTreeExecPool *exec_tree_pool,
|
||||
int r_mode, float *amb)
|
||||
{
|
||||
Material *ma;
|
||||
|
||||
@@ -1106,27 +1117,32 @@ void init_render_materials(Main *bmain, int r_mode, float *amb)
|
||||
/* is_used flag comes back in convertblender.c */
|
||||
ma->flag &= ~MA_IS_USED;
|
||||
if (ma->id.us)
|
||||
init_render_material(ma, r_mode, amb);
|
||||
init_render_material(ma, exec_tree_pool, r_mode, amb);
|
||||
}
|
||||
|
||||
init_render_material(&defmaterial, r_mode, amb);
|
||||
init_render_material(&defmaterial, exec_tree_pool, r_mode, amb);
|
||||
}
|
||||
|
||||
/* only needed for nodes now */
|
||||
void end_render_material(Material *mat)
|
||||
void end_render_material(bNodeTreeExecPool *exec_tree_pool,
|
||||
Material *mat)
|
||||
{
|
||||
if (mat && mat->nodetree && mat->use_nodes) {
|
||||
if (mat->nodetree->execdata)
|
||||
ntreeShaderEndExecTree(mat->nodetree->execdata);
|
||||
struct bNodeTreeExec *exec_data;
|
||||
exec_data = BKE_node_tree_exec_pool_pop(exec_tree_pool,
|
||||
&mat->nodetree->id);
|
||||
if (exec_data != NULL) {
|
||||
ntreeShaderEndExecTree(exec_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void end_render_materials(Main *bmain)
|
||||
void end_render_materials(Main *bmain, bNodeTreeExecPool *exec_tree_pool)
|
||||
{
|
||||
Material *ma;
|
||||
for (ma = bmain->mat.first; ma; ma = ma->id.next)
|
||||
if (ma->id.us)
|
||||
end_render_material(ma);
|
||||
end_render_material(exec_tree_pool, ma);
|
||||
}
|
||||
|
||||
static bool material_in_nodetree(bNodeTree *ntree, Material *mat)
|
||||
|
@@ -46,11 +46,12 @@
|
||||
#include "DNA_world_types.h"
|
||||
#include "DNA_linestyle_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLF_translation.h"
|
||||
|
||||
@@ -1129,9 +1130,6 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_
|
||||
|
||||
id_us_plus((ID *)newtree->gpd);
|
||||
|
||||
/* in case a running nodetree is copied */
|
||||
newtree->execdata = NULL;
|
||||
|
||||
BLI_listbase_clear(&newtree->nodes);
|
||||
BLI_listbase_clear(&newtree->links);
|
||||
|
||||
@@ -1625,13 +1623,7 @@ static void node_free_node_ex(bNodeTree *ntree, bNode *node, bool remove_animdat
|
||||
|
||||
if (ntree->typeinfo->free_node_cache)
|
||||
ntree->typeinfo->free_node_cache(ntree, node);
|
||||
|
||||
/* texture node has bad habit of keeping exec data around */
|
||||
if (ntree->type == NTREE_TEXTURE && ntree->execdata) {
|
||||
ntreeTexEndExecTree(ntree->execdata);
|
||||
ntree->execdata = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (node->typeinfo->freefunc)
|
||||
node->typeinfo->freefunc(node);
|
||||
}
|
||||
@@ -1705,24 +1697,7 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const bool do_id_user)
|
||||
bNodeSocket *sock, *nextsock;
|
||||
|
||||
if (ntree == NULL) return;
|
||||
|
||||
/* XXX hack! node trees should not store execution graphs at all.
|
||||
* This should be removed when old tree types no longer require it.
|
||||
* Currently the execution data for texture nodes remains in the tree
|
||||
* after execution, until the node tree is updated or freed.
|
||||
*/
|
||||
if (ntree->execdata) {
|
||||
switch (ntree->type) {
|
||||
case NTREE_SHADER:
|
||||
ntreeShaderEndExecTree(ntree->execdata);
|
||||
break;
|
||||
case NTREE_TEXTURE:
|
||||
ntreeTexEndExecTree(ntree->execdata);
|
||||
ntree->execdata = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* XXX not nice, but needed to free localized node groups properly */
|
||||
free_localized_node_groups(ntree);
|
||||
|
||||
@@ -3716,3 +3691,47 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Node execution. */
|
||||
|
||||
typedef struct bNodeTreeExecPool {
|
||||
GHash *hash;
|
||||
} bNodeTreeExecPool;
|
||||
|
||||
struct bNodeTreeExecPool *BKE_node_tree_exec_pool_new(void)
|
||||
{
|
||||
bNodeTreeExecPool *pool;
|
||||
pool = MEM_callocN(sizeof(bNodeTreeExecPool), __func__);
|
||||
pool->hash = BLI_ghash_ptr_new(__func__);
|
||||
return pool;
|
||||
}
|
||||
|
||||
void BKE_node_tree_exec_pool_free(bNodeTreeExecPool *pool)
|
||||
{
|
||||
/* Only destroys pool, all exec data is expected to be freed already. */
|
||||
BLI_assert(pool != NULL);
|
||||
BLI_ghash_free(pool->hash, NULL, NULL);
|
||||
MEM_freeN(pool);
|
||||
}
|
||||
|
||||
void BKE_node_tree_exec_pool_put(bNodeTreeExecPool *pool,
|
||||
struct ID *id,
|
||||
void *data)
|
||||
{
|
||||
BLI_assert(pool != NULL);
|
||||
BLI_ghash_insert(pool->hash, id, data);
|
||||
}
|
||||
|
||||
void *BKE_node_tree_exec_pool_get(bNodeTreeExecPool *pool,
|
||||
struct ID *id)
|
||||
{
|
||||
BLI_assert(pool != NULL);
|
||||
return BLI_ghash_lookup(pool->hash, id);
|
||||
}
|
||||
|
||||
void *BKE_node_tree_exec_pool_pop(bNodeTreeExecPool *pool,
|
||||
struct ID *id)
|
||||
{
|
||||
BLI_assert(pool != NULL);
|
||||
return BLI_ghash_popkey(pool->hash, id, NULL);
|
||||
}
|
||||
|
@@ -835,10 +835,7 @@ Tex *BKE_texture_copy(Tex *tex)
|
||||
if (texn->ot) texn->ot = BKE_copy_oceantex(texn->ot);
|
||||
if (tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
|
||||
|
||||
if (tex->nodetree) {
|
||||
if (tex->nodetree->execdata) {
|
||||
ntreeTexEndExecTree(tex->nodetree->execdata);
|
||||
}
|
||||
if (tex->nodetree != NULL) {
|
||||
texn->nodetree = ntreeCopyTree(tex->nodetree);
|
||||
}
|
||||
|
||||
|
@@ -2704,7 +2704,6 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
|
||||
ntree->interface_type = NULL;
|
||||
|
||||
ntree->progress = NULL;
|
||||
ntree->execdata = NULL;
|
||||
|
||||
ntree->adt = newdataadr(fd, ntree->adt);
|
||||
direct_link_animdata(fd, ntree->adt);
|
||||
|
@@ -261,7 +261,11 @@ static Scene *preview_get_scene(Main *pr_main)
|
||||
|
||||
/* call this with a pointer to initialize preview scene */
|
||||
/* call this with NULL to restore assigned ID pointers in preview scene */
|
||||
static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPreview *sp)
|
||||
static Scene *preview_prepare_scene(Render *re,
|
||||
Scene *scene,
|
||||
ID *id,
|
||||
int id_type,
|
||||
ShaderPreview *sp)
|
||||
{
|
||||
Scene *sce;
|
||||
Base *base;
|
||||
@@ -323,8 +327,11 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
|
||||
BLI_addtail(&pr_main->mat, mat);
|
||||
|
||||
if (!BKE_scene_use_new_shading_nodes(scene)) {
|
||||
init_render_material(mat, 0, NULL); /* call that retrieves mode_l */
|
||||
end_render_material(mat);
|
||||
bNodeTreeExecPool *tree_exec_pool;
|
||||
tree_exec_pool = RE_tree_exec_pool_get(re);
|
||||
init_render_material(mat, tree_exec_pool, 0, NULL); /* call that retrieves mode_l */
|
||||
/* TODO(sergey): Wait, that's kind of stupid. */
|
||||
end_render_material(tree_exec_pool, mat);
|
||||
|
||||
/* un-useful option */
|
||||
if (sp->pr_method == PR_ICON_RENDER)
|
||||
@@ -700,19 +707,19 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
|
||||
sce->r.ysch = sp->sizey;
|
||||
sce->r.size = 100;
|
||||
}
|
||||
|
||||
/* get the stuff from the builtin preview dbase */
|
||||
sce = preview_prepare_scene(sp->scene, id, idtype, sp);
|
||||
if (sce == NULL) return;
|
||||
|
||||
|
||||
if (!split || first) sprintf(name, "Preview %p", sp->owner);
|
||||
else sprintf(name, "SecondPreview %p", sp->owner);
|
||||
re = RE_GetRender(name);
|
||||
|
||||
|
||||
/* full refreshed render from first tile */
|
||||
if (re == NULL)
|
||||
re = RE_NewRender(name);
|
||||
|
||||
|
||||
/* get the stuff from the builtin preview dbase */
|
||||
sce = preview_prepare_scene(re, sp->scene, id, idtype, sp);
|
||||
if (sce == NULL) return;
|
||||
|
||||
/* sce->r gets copied in RE_InitState! */
|
||||
sce->r.scemode &= ~(R_MATNODE_PREVIEW | R_TEXNODE_PREVIEW);
|
||||
sce->r.scemode &= ~R_NO_IMAGE_LOAD;
|
||||
@@ -757,7 +764,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
|
||||
}
|
||||
|
||||
/* unassign the pointers, reset vars */
|
||||
preview_prepare_scene(sp->scene, NULL, GS(id->name), sp);
|
||||
preview_prepare_scene(re, sp->scene, NULL, GS(id->name), sp);
|
||||
|
||||
/* XXX bad exception, end-exec is not being called in render, because it uses local main */
|
||||
// if (idtype == ID_TE) {
|
||||
|
@@ -209,8 +209,10 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
|
||||
|
||||
pool = BKE_image_pool_new();
|
||||
|
||||
if (mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
if (mtex->tex && mtex->tex->nodetree) {
|
||||
BLI_assert(!"Port over to the new system");
|
||||
//ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
}
|
||||
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (j = 0; j < size; j++) {
|
||||
@@ -305,8 +307,10 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
|
||||
}
|
||||
}
|
||||
|
||||
if (mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
|
||||
if (mtex->tex && mtex->tex->nodetree) {
|
||||
/* ntreeTexEndExecTree(mtex->tex->nodetree->execdata); */
|
||||
BLI_assert(!"Need to port this over");
|
||||
}
|
||||
|
||||
if (pool)
|
||||
BKE_image_pool_free(pool);
|
||||
|
@@ -690,12 +690,16 @@ void paint_brush_init_tex(Brush *brush)
|
||||
{
|
||||
/* init mtex nodes */
|
||||
if (brush) {
|
||||
#if 0
|
||||
MTex *mtex = &brush->mtex;
|
||||
if (mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
mtex = &brush->mask_mtex;
|
||||
if (mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexBeginExecTree(mtex->tex->nodetree);
|
||||
#else
|
||||
BLI_assert(!"Port over to the new system");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -703,11 +707,15 @@ void paint_brush_exit_tex(Brush *brush)
|
||||
{
|
||||
if (brush) {
|
||||
MTex *mtex = &brush->mtex;
|
||||
if (mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
|
||||
if (mtex->tex && mtex->tex->nodetree) {
|
||||
/* ntreeTexEndExecTree(mtex->tex->nodetree->execdata); */
|
||||
BLI_assert(!"Need to port thing over");
|
||||
}
|
||||
mtex = &brush->mask_mtex;
|
||||
if (mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
|
||||
if (mtex->tex && mtex->tex->nodetree) {
|
||||
/* ntreeTexEndExecTree(mtex->tex->nodetree->execdata); */
|
||||
BLI_assert(!"Need to port thing over");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -4125,8 +4125,10 @@ static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession
|
||||
MTex *mtex = &brush->mtex;
|
||||
|
||||
/* init mtex nodes */
|
||||
if (mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
if (mtex->tex && mtex->tex->nodetree) {
|
||||
//ntreeTexBeginExecTree(mtex->tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
BLI_assert(!"Port over to the new system");
|
||||
}
|
||||
|
||||
/* TODO: Shouldn't really have to do this at the start of every
|
||||
* stroke, but sculpt would need some sort of notification when
|
||||
@@ -4328,8 +4330,10 @@ static void sculpt_brush_exit_tex(Sculpt *sd)
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
MTex *mtex = &brush->mtex;
|
||||
|
||||
if (mtex->tex && mtex->tex->nodetree)
|
||||
ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
|
||||
if (mtex->tex && mtex->tex->nodetree) {
|
||||
/* ntreeTexEndExecTree(mtex->tex->nodetree->execdata); */
|
||||
BLI_assert(!"Need to port the damn thing");
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(stroke))
|
||||
|
@@ -372,15 +372,6 @@ typedef struct bNodeTree {
|
||||
bNodeInstanceKey active_viewer_key;
|
||||
int pad;
|
||||
|
||||
/* execution data */
|
||||
/* XXX It would be preferable to completely move this data out of the underlying node tree,
|
||||
* so node tree execution could finally run independent of the tree itself. This would allow node trees
|
||||
* to be merely linked by other data (materials, textures, etc.), as ID data is supposed to.
|
||||
* Execution data is generated from the tree once at execution start and can then be used
|
||||
* as long as necessary, even while the tree is being modified.
|
||||
*/
|
||||
struct bNodeTreeExec *execdata;
|
||||
|
||||
/* callbacks */
|
||||
void (*progress)(void *, float progress);
|
||||
void (*stats_draw)(void *, char *str);
|
||||
|
@@ -77,20 +77,20 @@ typedef struct bNodeThreadStack {
|
||||
|
||||
int node_exec_socket_use_stack(struct bNodeSocket *sock);
|
||||
|
||||
struct bNodeStack *node_get_socket_stack(struct bNodeStack *stack, struct bNodeSocket *sock);
|
||||
struct bNodeStack *node_get_socket_stack(struct bNodeStack *stack, struct bNodeSocket *sock) ATTR_WARN_UNUSED_RESULT;
|
||||
void node_get_stack(struct bNode *node, struct bNodeStack *stack, struct bNodeStack **in, struct bNodeStack **out);
|
||||
|
||||
struct bNodeTreeExec *ntree_exec_begin(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key);
|
||||
struct bNodeTreeExec *ntree_exec_begin(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key) ATTR_WARN_UNUSED_RESULT;
|
||||
void ntree_exec_end(struct bNodeTreeExec *exec);
|
||||
|
||||
struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread);
|
||||
struct bNodeThreadStack *ntreeGetThreadStack(struct bNodeTreeExec *exec, int thread) ATTR_WARN_UNUSED_RESULT;
|
||||
void ntreeReleaseThreadStack(struct bNodeThreadStack *nts);
|
||||
bool ntreeExecThreadNodes(struct bNodeTreeExec *exec, struct bNodeThreadStack *nts, void *callerdata, int thread);
|
||||
|
||||
struct bNodeTreeExec *ntreeShaderBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key);
|
||||
struct bNodeTreeExec *ntreeShaderBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key) ATTR_WARN_UNUSED_RESULT;
|
||||
void ntreeShaderEndExecTree_internal(struct bNodeTreeExec *exec);
|
||||
|
||||
struct bNodeTreeExec *ntreeTexBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key);
|
||||
struct bNodeTreeExec *ntreeTexBeginExecTree_internal(struct bNodeExecContext *context, struct bNodeTree *ntree, bNodeInstanceKey parent_key) ATTR_WARN_UNUSED_RESULT;
|
||||
void ntreeTexEndExecTree_internal(struct bNodeTreeExec *exec);
|
||||
|
||||
#endif
|
||||
|
@@ -245,24 +245,8 @@ bNodeTreeExec *ntreeShaderBeginExecTree_internal(bNodeExecContext *context, bNod
|
||||
bNodeTreeExec *ntreeShaderBeginExecTree(bNodeTree *ntree)
|
||||
{
|
||||
bNodeExecContext context;
|
||||
bNodeTreeExec *exec;
|
||||
|
||||
/* XXX hack: prevent exec data from being generated twice.
|
||||
* this should be handled by the renderer!
|
||||
*/
|
||||
if (ntree->execdata)
|
||||
return ntree->execdata;
|
||||
|
||||
context.previews = ntree->previews;
|
||||
|
||||
exec = ntreeShaderBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
|
||||
|
||||
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
|
||||
* which only store the ntree pointer. Should be fixed at some point!
|
||||
*/
|
||||
ntree->execdata = exec;
|
||||
|
||||
return exec;
|
||||
return ntreeShaderBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
|
||||
}
|
||||
|
||||
void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
|
||||
@@ -286,18 +270,16 @@ void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
|
||||
|
||||
void ntreeShaderEndExecTree(bNodeTreeExec *exec)
|
||||
{
|
||||
if (exec) {
|
||||
/* exec may get freed, so assign ntree */
|
||||
bNodeTree *ntree = exec->nodetree;
|
||||
if (exec != NULL) {
|
||||
ntreeShaderEndExecTree_internal(exec);
|
||||
|
||||
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
|
||||
ntree->execdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* only for Blender internal */
|
||||
bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
|
||||
bool ntreeShaderExecTree(bNodeTreeExecPool *exec_tree_pool,
|
||||
bNodeTree *ntree,
|
||||
ShadeInput *shi,
|
||||
ShadeResult *shr)
|
||||
{
|
||||
ShaderCallData scd;
|
||||
/**
|
||||
@@ -306,9 +288,13 @@ bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
|
||||
*/
|
||||
Material *mat = shi->mat;
|
||||
bNodeThreadStack *nts = NULL;
|
||||
bNodeTreeExec *exec = ntree->execdata;
|
||||
bNodeTreeExec *exec = NULL;
|
||||
int compat;
|
||||
|
||||
|
||||
exec = BKE_node_tree_exec_pool_get(exec_tree_pool,
|
||||
&ntree->id);
|
||||
BLI_assert(exec != NULL);
|
||||
|
||||
/* convert caller data to struct */
|
||||
scd.shi = shi;
|
||||
scd.shr = shr;
|
||||
@@ -316,16 +302,6 @@ bool ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr)
|
||||
/* each material node has own local shaderesult, with optional copying */
|
||||
memset(shr, 0, sizeof(ShadeResult));
|
||||
|
||||
/* ensure execdata is only initialized once */
|
||||
if (!exec) {
|
||||
BLI_lock_thread(LOCK_NODES);
|
||||
if (!ntree->execdata)
|
||||
ntree->execdata = ntreeShaderBeginExecTree(ntree);
|
||||
BLI_unlock_thread(LOCK_NODES);
|
||||
|
||||
exec = ntree->execdata;
|
||||
}
|
||||
|
||||
nts = ntreeGetThreadStack(exec, shi->thread);
|
||||
compat = ntreeExecThreadNodes(exec, nts, &scd, shi->thread);
|
||||
ntreeReleaseThreadStack(nts);
|
||||
|
@@ -134,10 +134,6 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
|
||||
func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
|
||||
}
|
||||
|
||||
/* XXX muting disabled in previews because of threading issues with the main execution
|
||||
* it works here, but disabled for consistency
|
||||
*/
|
||||
#if 1
|
||||
static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
|
||||
{
|
||||
bNode *node, *node_next;
|
||||
@@ -152,11 +148,6 @@ static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void localize(bNodeTree *UNUSED(localtree), bNodeTree *UNUSED(ntree))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void local_sync(bNodeTree *localtree, bNodeTree *ntree)
|
||||
{
|
||||
@@ -178,6 +169,7 @@ static void update(bNodeTree *ntree)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bNodeTreeType *ntreeType_Texture;
|
||||
|
||||
void register_node_tree_type_tex(void)
|
||||
@@ -243,38 +235,8 @@ bNodeTreeExec *ntreeTexBeginExecTree_internal(bNodeExecContext *context, bNodeTr
|
||||
bNodeTreeExec *ntreeTexBeginExecTree(bNodeTree *ntree)
|
||||
{
|
||||
bNodeExecContext context;
|
||||
bNodeTreeExec *exec;
|
||||
|
||||
/* XXX hack: prevent exec data from being generated twice.
|
||||
* this should be handled by the renderer!
|
||||
*/
|
||||
if (ntree->execdata)
|
||||
return ntree->execdata;
|
||||
|
||||
context.previews = ntree->previews;
|
||||
|
||||
exec = ntreeTexBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
|
||||
|
||||
/* XXX this should not be necessary, but is still used for cmp/sha/tex nodes,
|
||||
* which only store the ntree pointer. Should be fixed at some point!
|
||||
*/
|
||||
ntree->execdata = exec;
|
||||
|
||||
return exec;
|
||||
}
|
||||
|
||||
/* free texture delegates */
|
||||
static void tex_free_delegates(bNodeTreeExec *exec)
|
||||
{
|
||||
bNodeThreadStack *nts;
|
||||
bNodeStack *ns;
|
||||
int th, a;
|
||||
|
||||
for (th = 0; th < BLENDER_MAX_THREADS; th++)
|
||||
for (nts = exec->threadstack[th].first; nts; nts = nts->next)
|
||||
for (ns = nts->stack, a = 0; a < exec->stacksize; a++, ns++)
|
||||
if (ns->data && !ns->is_copy)
|
||||
MEM_freeN(ns->data);
|
||||
return ntreeTexBeginExecTree_internal(&context, ntree, NODE_INSTANCE_KEY_BASE);
|
||||
}
|
||||
|
||||
void ntreeTexEndExecTree_internal(bNodeTreeExec *exec)
|
||||
@@ -283,8 +245,6 @@ void ntreeTexEndExecTree_internal(bNodeTreeExec *exec)
|
||||
int a;
|
||||
|
||||
if (exec->threadstack) {
|
||||
tex_free_delegates(exec);
|
||||
|
||||
for (a = 0; a < BLENDER_MAX_THREADS; a++) {
|
||||
for (nts = exec->threadstack[a].first; nts; nts = nts->next)
|
||||
if (nts->stack) MEM_freeN(nts->stack);
|
||||
@@ -300,18 +260,14 @@ void ntreeTexEndExecTree_internal(bNodeTreeExec *exec)
|
||||
|
||||
void ntreeTexEndExecTree(bNodeTreeExec *exec)
|
||||
{
|
||||
if (exec) {
|
||||
/* exec may get freed, so assign ntree */
|
||||
bNodeTree *ntree = exec->nodetree;
|
||||
if (exec != NULL) {
|
||||
ntreeTexEndExecTree_internal(exec);
|
||||
|
||||
/* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */
|
||||
ntree->execdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int ntreeTexExecTree(
|
||||
bNodeTree *nodes,
|
||||
bNodeTreeExecPool *exec_tree_pool,
|
||||
bNodeTree *ntree,
|
||||
TexResult *texres,
|
||||
float co[3],
|
||||
float dxt[3], float dyt[3],
|
||||
@@ -328,7 +284,11 @@ int ntreeTexExecTree(
|
||||
float *nor = texres->nor;
|
||||
int retval = TEX_INT;
|
||||
bNodeThreadStack *nts = NULL;
|
||||
bNodeTreeExec *exec = nodes->execdata;
|
||||
bNodeTreeExec *exec;
|
||||
|
||||
exec = BKE_node_tree_exec_pool_get(exec_tree_pool,
|
||||
&ntree->id);
|
||||
BLI_assert(exec != NULL);
|
||||
|
||||
data.co = co;
|
||||
data.dxt = dxt;
|
||||
@@ -342,17 +302,7 @@ int ntreeTexExecTree(
|
||||
data.cfra = cfra;
|
||||
data.mtex = mtex;
|
||||
data.shi = shi;
|
||||
|
||||
/* ensure execdata is only initialized once */
|
||||
if (!exec) {
|
||||
BLI_lock_thread(LOCK_NODES);
|
||||
if (!nodes->execdata)
|
||||
ntreeTexBeginExecTree(nodes);
|
||||
BLI_unlock_thread(LOCK_NODES);
|
||||
|
||||
exec = nodes->execdata;
|
||||
}
|
||||
|
||||
nts = ntreeGetThreadStack(exec, thread);
|
||||
ntreeExecThreadNodes(exec, nts, &data, thread);
|
||||
ntreeReleaseThreadStack(nts);
|
||||
|
@@ -63,37 +63,52 @@ void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, sho
|
||||
ntype->update_internal_links = node_update_internal_links_default;
|
||||
}
|
||||
|
||||
|
||||
static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread)
|
||||
/* TODO(sergey): De-duplicate with the shader nodes. */
|
||||
static void tex_input(float *in, int type_in, bNodeStack *ns)
|
||||
{
|
||||
if (dg->node->need_exec) {
|
||||
dg->fn(out, params, dg->node, dg->in, thread);
|
||||
const float *from = ns->vec;
|
||||
|
||||
if (dg->cdata->do_preview)
|
||||
tex_do_preview(dg->preview, params->previewco, out, dg->cdata->do_manage);
|
||||
if (type_in == SOCK_FLOAT) {
|
||||
if (ns->sockettype == SOCK_FLOAT)
|
||||
*in = *from;
|
||||
else
|
||||
*in = (from[0] + from[1] + from[2]) / 3.0f;
|
||||
}
|
||||
else if (type_in == SOCK_VECTOR) {
|
||||
if (ns->sockettype == SOCK_FLOAT) {
|
||||
in[0] = from[0];
|
||||
in[1] = from[0];
|
||||
in[2] = from[0];
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(in, from);
|
||||
}
|
||||
}
|
||||
else { /* type_in==SOCK_RGBA */
|
||||
if (ns->sockettype == SOCK_RGBA) {
|
||||
copy_v4_v4(in, from);
|
||||
}
|
||||
else if (ns->sockettype == SOCK_FLOAT) {
|
||||
in[0] = from[0];
|
||||
in[1] = from[0];
|
||||
in[2] = from[0];
|
||||
in[3] = 1.0f;
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(in, from);
|
||||
in[3] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, short thread)
|
||||
void tex_input_vec(float *out, bNodeStack *in)
|
||||
{
|
||||
TexDelegate *dg = in->data;
|
||||
if (dg) {
|
||||
tex_call_delegate(dg, in->vec, params, thread);
|
||||
|
||||
if (in->hasoutput && in->sockettype == SOCK_FLOAT)
|
||||
in->vec[1] = in->vec[2] = in->vec[0];
|
||||
}
|
||||
memcpy(out, in->vec, sz * sizeof(float));
|
||||
tex_input(out, SOCK_FLOAT, in);
|
||||
}
|
||||
|
||||
void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread)
|
||||
void tex_input_rgba(float *out, bNodeStack *in)
|
||||
{
|
||||
tex_input(out, 3, in, params, thread);
|
||||
}
|
||||
|
||||
void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
|
||||
{
|
||||
tex_input(out, 4, in, params, thread);
|
||||
tex_input(out, SOCK_RGBA, in);
|
||||
|
||||
if (in->hasoutput && in->sockettype == SOCK_FLOAT) {
|
||||
out[1] = out[2] = out[0];
|
||||
@@ -108,10 +123,10 @@ void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
|
||||
}
|
||||
}
|
||||
|
||||
float tex_input_value(bNodeStack *in, TexParams *params, short thread)
|
||||
float tex_input_value(bNodeStack *in)
|
||||
{
|
||||
float out[4];
|
||||
tex_input_vec(out, in, params, thread);
|
||||
tex_input_vec(out, in);
|
||||
return out[0];
|
||||
}
|
||||
|
||||
@@ -139,27 +154,12 @@ void tex_do_preview(bNodePreview *preview, const float coord[2], const float col
|
||||
|
||||
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata)
|
||||
{
|
||||
TexDelegate *dg;
|
||||
|
||||
if (node->flag & NODE_MUTED) {
|
||||
/* do not add a delegate if the node is muted */
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (!out->data)
|
||||
/* Freed in tex_end_exec (node.c) */
|
||||
dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
|
||||
else
|
||||
dg = out->data;
|
||||
}
|
||||
|
||||
|
||||
dg->cdata = cdata;
|
||||
dg->fn = texfn;
|
||||
dg->node = node;
|
||||
dg->preview = execdata->preview;
|
||||
memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *));
|
||||
dg->type = out->sockettype;
|
||||
(void) node;
|
||||
(void) execdata;
|
||||
(void) in;
|
||||
(void) out;
|
||||
(void) texfn;
|
||||
(void) cdata;
|
||||
}
|
||||
|
||||
void ntreeTexCheckCyclics(struct bNodeTree *ntree)
|
||||
|
@@ -109,22 +109,12 @@ typedef struct TexParams {
|
||||
|
||||
typedef void(*TexFn) (float *out, TexParams *params, bNode *node, bNodeStack **in, short thread);
|
||||
|
||||
typedef struct TexDelegate {
|
||||
TexCallData *cdata;
|
||||
TexFn fn;
|
||||
bNode *node;
|
||||
bNodePreview *preview;
|
||||
bNodeStack *in[MAX_SOCKET];
|
||||
int type;
|
||||
} TexDelegate;
|
||||
|
||||
|
||||
int tex_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
|
||||
void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
|
||||
|
||||
void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread);
|
||||
void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread);
|
||||
float tex_input_value(bNodeStack *in, TexParams *params, short thread);
|
||||
void tex_input_rgba(float *out, bNodeStack *in);
|
||||
void tex_input_vec(float *out, bNodeStack *in);
|
||||
float tex_input_value(bNodeStack *in);
|
||||
|
||||
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *data);
|
||||
void tex_do_preview(bNodePreview *preview, const float coord[2], const float col[4], bool do_manage);
|
||||
|
@@ -49,8 +49,12 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
|
||||
float new_co[3];
|
||||
np.co = new_co;
|
||||
|
||||
tex_input_vec(new_co, in[1], p, thread);
|
||||
tex_input_rgba(out, in[0], &np, thread);
|
||||
(void) out;
|
||||
(void) in;
|
||||
(void) thread;
|
||||
tex_input_vec(new_co, in[1]);
|
||||
//tex_input_rgba(out, in[0], &np, thread);
|
||||
BLI_assert(!"Needs proper solution");
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -64,72 +64,75 @@ static float noise(int n) /* fast integer noise */
|
||||
return 0.5f * ((float)nn / 1073741824.0f);
|
||||
}
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
|
||||
static void exec(void *data,
|
||||
int UNUSED(thread),
|
||||
bNode *node,
|
||||
bNodeExecData *execdata,
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
const float *co = p->co;
|
||||
|
||||
TexCallData *cdata = (TexCallData *)data;
|
||||
const float *co = cdata->co;
|
||||
|
||||
float x = co[0];
|
||||
float y = co[1];
|
||||
|
||||
|
||||
int bricknum, rownum;
|
||||
float 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], p, thread);
|
||||
float bias = tex_input_value(in[4], p, thread);
|
||||
float brick_width = tex_input_value(in[5], p, thread);
|
||||
float row_height = tex_input_value(in[6], p, thread);
|
||||
|
||||
tex_input_rgba(bricks1, in[0], p, thread);
|
||||
tex_input_rgba(bricks2, in[1], p, thread);
|
||||
tex_input_rgba(mortar, in[2], p, thread);
|
||||
|
||||
rownum = (int)floor(y / row_height);
|
||||
|
||||
|
||||
float mortar_thickness = tex_input_value(in[3]);
|
||||
float bias = tex_input_value(in[4]);
|
||||
float brick_width = tex_input_value(in[5]);
|
||||
float row_height = tex_input_value(in[6]);
|
||||
|
||||
tex_input_rgba(bricks1, in[0]);
|
||||
tex_input_rgba(bricks2, in[1]);
|
||||
tex_input_rgba(mortar, in[2]);
|
||||
|
||||
rownum = (int)floorf(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 = (int)floor((x + offset) / brick_width);
|
||||
|
||||
|
||||
bricknum = (int)floorf((x + offset) / brick_width);
|
||||
|
||||
ins_x = (x + offset) - brick_width * bricknum;
|
||||
ins_y = y - row_height * rownum;
|
||||
|
||||
|
||||
tint = noise((rownum << 16) + (bricknum & 0xFFFF)) + 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))
|
||||
{
|
||||
copy_v4_v4(out, mortar);
|
||||
copy_v4_v4(out[0]->vec, mortar);
|
||||
}
|
||||
else {
|
||||
copy_v4_v4(out, bricks1);
|
||||
ramp_blend(MA_RAMP_BLEND, out, tint, bricks2);
|
||||
copy_v4_v4(out[0]->vec, bricks1);
|
||||
ramp_blend(MA_RAMP_BLEND, out[0]->vec, tint, bricks2);
|
||||
}
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &colorfn, data);
|
||||
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage);
|
||||
}
|
||||
|
||||
void register_node_type_tex_bricks(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_BRICKS, "Bricks", NODE_CLASS_PATTERN, NODE_PREVIEW);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
|
||||
node_type_init(&ntype, init);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -45,38 +45,44 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void exec(void *data,
|
||||
int UNUSED(thread),
|
||||
bNode *UNUSED(node),
|
||||
bNodeExecData *execdata,
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
float x = p->co[0];
|
||||
float y = p->co[1];
|
||||
float z = p->co[2];
|
||||
float sz = tex_input_value(in[2], p, thread);
|
||||
|
||||
TexCallData *cdata = (TexCallData *)data;
|
||||
float x, y, z, sz;
|
||||
int xi, yi, zi;
|
||||
|
||||
x = cdata->co[0];
|
||||
y = cdata->co[1];
|
||||
z = cdata->co[2];
|
||||
sz = tex_input_value(in[2]);
|
||||
|
||||
/* 0.00001 because of unit sized stuff */
|
||||
int xi = (int)fabs(floor(0.00001f + x / sz));
|
||||
int yi = (int)fabs(floor(0.00001f + y / sz));
|
||||
int zi = (int)fabs(floor(0.00001f + z / sz));
|
||||
|
||||
xi = (int)fabsf(floorf(0.00001f + x / sz));
|
||||
yi = (int)fabsf(floorf(0.00001f + y / sz));
|
||||
zi = (int)fabsf(floorf(0.00001f + z / sz));
|
||||
|
||||
if ( (xi % 2 == yi % 2) == (zi % 2) ) {
|
||||
tex_input_rgba(out, in[0], p, thread);
|
||||
tex_input_rgba(out[0]->vec, in[0]);
|
||||
}
|
||||
else {
|
||||
tex_input_rgba(out, in[1], p, thread);
|
||||
tex_input_rgba(out[0]->vec, in[1]);
|
||||
}
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &colorfn, data);
|
||||
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage);
|
||||
}
|
||||
|
||||
void register_node_type_tex_checker(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_CHECKER, "Checker", NODE_CLASS_PATTERN, NODE_PREVIEW);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "node_texture_util.h"
|
||||
#include "node_texture_util.h"
|
||||
#include "NOD_texture.h"
|
||||
|
||||
static bNodeSocketTemplate inputs[] = {
|
||||
@@ -45,25 +45,26 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *UNUSED(node),
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
out[i] = tex_input_value(in[i], p, thread);
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &colorfn, data);
|
||||
for (i = 0; i < 4; i++) {
|
||||
out[0]->vec[i] = tex_input_value(in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void register_node_type_tex_compose(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_COMPOSE, "Combine RGBA", NODE_CLASS_OP_COLOR, 0);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -38,24 +38,25 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void vectorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **UNUSED(in), short UNUSED(thread))
|
||||
static void exec(void *data,
|
||||
int UNUSED(thread),
|
||||
bNode *UNUSED(node),
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **UNUSED(in),
|
||||
bNodeStack **out)
|
||||
{
|
||||
copy_v3_v3(out, p->co);
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &vectorfn, data);
|
||||
TexCallData *cdata = (TexCallData *)data;
|
||||
copy_v3_v3(out[0]->vec, cdata->co);
|
||||
}
|
||||
|
||||
void register_node_type_tex_coord(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_COORD, "Coordinates", NODE_CLASS_INPUT, 0);
|
||||
node_type_socket_templates(&ntype, NULL, outputs);
|
||||
node_type_storage(&ntype, "", NULL, NULL);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -41,22 +41,23 @@ static bNodeSocketTemplate time_outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void time_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread))
|
||||
static void time_exec(void *data,
|
||||
int UNUSED(thread),
|
||||
bNode *node,
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **UNUSED(in),
|
||||
bNodeStack **out)
|
||||
{
|
||||
TexCallData *cdata = (TexCallData *)data;
|
||||
/* stack order output: fac */
|
||||
float fac = 0.0f;
|
||||
|
||||
|
||||
if (node->custom1 < node->custom2)
|
||||
fac = (p->cfra - node->custom1) / (float)(node->custom2 - node->custom1);
|
||||
|
||||
fac = (cdata->cfra - node->custom1) / (float)(node->custom2 - node->custom1);
|
||||
|
||||
curvemapping_initialize(node->storage);
|
||||
fac = curvemapping_evaluateF(node->storage, 0, fac);
|
||||
out[0] = CLAMPIS(fac, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
static void time_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &time_colorfn, data);
|
||||
out[0]->vec[0] = CLAMPIS(fac, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,14 +71,14 @@ static void time_init(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
void register_node_type_tex_curve_time(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_CURVE_TIME, "Time", NODE_CLASS_INPUT, 0);
|
||||
node_type_socket_templates(&ntype, NULL, time_outputs);
|
||||
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
|
||||
node_type_init(&ntype, time_init);
|
||||
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
|
||||
node_type_exec(&ntype, node_initexec_curves, NULL, time_exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
||||
@@ -92,18 +93,17 @@ static bNodeSocketTemplate rgb_outputs[] = {
|
||||
{ -1, 0, ""}
|
||||
};
|
||||
|
||||
static void rgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
|
||||
static void rgb_exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *node,
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
float cin[4];
|
||||
tex_input_rgba(cin, in[0], p, thread);
|
||||
|
||||
curvemapping_evaluateRGBF(node->storage, out, cin);
|
||||
out[3] = cin[3];
|
||||
}
|
||||
|
||||
static void rgb_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &rgb_colorfn, data);
|
||||
tex_input_rgba(cin, in[0]);
|
||||
curvemapping_evaluateRGBF(node->storage, out[0]->vec, cin);
|
||||
out[0]->vec[3] = cin[3];
|
||||
}
|
||||
|
||||
static void rgb_init(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
@@ -114,13 +114,13 @@ static void rgb_init(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
void register_node_type_tex_curve_rgb(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, 0);
|
||||
node_type_socket_templates(&ntype, rgb_inputs, rgb_outputs);
|
||||
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
|
||||
node_type_init(&ntype, rgb_init);
|
||||
node_type_storage(&ntype, "CurveMapping", node_free_curves, node_copy_curves);
|
||||
node_type_exec(&ntype, node_initexec_curves, NULL, rgb_exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "node_texture_util.h"
|
||||
#include "node_texture_util.h"
|
||||
#include "NOD_texture.h"
|
||||
#include <math.h>
|
||||
|
||||
@@ -46,45 +46,28 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void valuefn_r(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *UNUSED(node),
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
tex_input_rgba(out, in[0], p, thread);
|
||||
*out = out[0];
|
||||
}
|
||||
|
||||
static void valuefn_g(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
{
|
||||
tex_input_rgba(out, in[0], p, thread);
|
||||
*out = out[1];
|
||||
}
|
||||
|
||||
static void valuefn_b(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
{
|
||||
tex_input_rgba(out, in[0], p, thread);
|
||||
*out = out[2];
|
||||
}
|
||||
|
||||
static void valuefn_a(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
{
|
||||
tex_input_rgba(out, in[0], p, thread);
|
||||
*out = out[3];
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &valuefn_r, data);
|
||||
tex_output(node, execdata, in, out[1], &valuefn_g, data);
|
||||
tex_output(node, execdata, in, out[2], &valuefn_b, data);
|
||||
tex_output(node, execdata, in, out[3], &valuefn_a, data);
|
||||
float color[4];
|
||||
tex_input_rgba(color, in[0]);
|
||||
out[0]->vec[0] = color[0];
|
||||
out[1]->vec[0] = color[1];
|
||||
out[2]->vec[0] = color[2];
|
||||
out[3]->vec[0] = color[3];
|
||||
}
|
||||
|
||||
void register_node_type_tex_decompose(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_DECOMPOSE, "Separate RGBA", NODE_CLASS_OP_COLOR, 0);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -46,29 +46,31 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void valuefn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *UNUSED(node),
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
float co1[3], co2[3];
|
||||
|
||||
tex_input_vec(co1, in[0], p, thread);
|
||||
tex_input_vec(co2, in[1], p, thread);
|
||||
|
||||
*out = len_v3v3(co2, co1);
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &valuefn, data);
|
||||
tex_input_vec(co1, in[0]);
|
||||
tex_input_vec(co2, in[1]);
|
||||
zero_v4(out[0]->vec);
|
||||
/* TODO(sergey): This appears to be darker than 2.72 somehow.
|
||||
* Could be because testing with OCIO disabled tho.
|
||||
*/
|
||||
out[0]->vec[0] = len_v3v3(co2, co1);
|
||||
}
|
||||
|
||||
void register_node_type_tex_distance(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_DISTANCE, "Distance", NODE_CLASS_CONVERTOR, 0);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_storage(&ntype, "", NULL, NULL);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -70,36 +70,35 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat
|
||||
}
|
||||
}
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
|
||||
{
|
||||
float hue = tex_input_value(in[0], p, thread);
|
||||
float sat = tex_input_value(in[1], p, thread);
|
||||
float val = tex_input_value(in[2], p, thread);
|
||||
float fac = tex_input_value(in[3], p, thread);
|
||||
|
||||
float col[4];
|
||||
tex_input_rgba(col, in[4], p, thread);
|
||||
|
||||
hue += 0.5f; /* [-0.5, 0.5] -> [0, 1] */
|
||||
|
||||
do_hue_sat_fac(node, out, hue, sat, val, col, fac);
|
||||
|
||||
out[3] = col[3];
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
static void exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *node,
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &colorfn, data);
|
||||
float hue = tex_input_value(in[0]);
|
||||
float sat = tex_input_value(in[1]);
|
||||
float val = tex_input_value(in[2]);
|
||||
float fac = tex_input_value(in[3]);
|
||||
|
||||
float col[4];
|
||||
tex_input_rgba(col, in[4]);
|
||||
|
||||
hue += 0.5f; /* [-0.5, 0.5] -> [0, 1] */
|
||||
|
||||
do_hue_sat_fac(node, out[0]->vec, hue, sat, val, col, fac);
|
||||
out[0]->vec[3] = col[3];
|
||||
}
|
||||
|
||||
void register_node_type_tex_hue_sat(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, 0);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -38,54 +38,59 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread))
|
||||
static void exec(void *data,
|
||||
int UNUSED(thread),
|
||||
bNode *node,
|
||||
bNodeExecData *execdata,
|
||||
bNodeStack **UNUSED(in),
|
||||
bNodeStack **out)
|
||||
{
|
||||
float x = p->co[0];
|
||||
float y = p->co[1];
|
||||
TexCallData *cdata = (TexCallData *)data;
|
||||
float x, y;
|
||||
Image *ima = (Image *)node->id;
|
||||
ImageUser *iuser = (ImageUser *)node->storage;
|
||||
|
||||
|
||||
x = cdata->co[0];
|
||||
y = cdata->co[1];
|
||||
|
||||
if (ima) {
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
|
||||
if (ibuf) {
|
||||
float xsize, ysize;
|
||||
float xoff, yoff;
|
||||
int px, py;
|
||||
|
||||
|
||||
const 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) {
|
||||
BLI_lock_thread(LOCK_IMAGE);
|
||||
if (!ibuf->rect_float)
|
||||
IMB_float_from_rect(ibuf);
|
||||
BLI_unlock_thread(LOCK_IMAGE);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
copy_v4_v4(out, result);
|
||||
copy_v4_v4(out[0]->vec, result);
|
||||
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &colorfn, data);
|
||||
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage);
|
||||
}
|
||||
|
||||
static void init(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
@@ -100,12 +105,12 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
void register_node_type_tex_image(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_IMAGE, "Image", NODE_CLASS_INPUT, NODE_PREVIEW);
|
||||
node_type_socket_templates(&ntype, NULL, outputs);
|
||||
node_type_init(&ntype, init);
|
||||
node_type_storage(&ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -44,23 +44,22 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *UNUSED(node),
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
float col[4];
|
||||
|
||||
tex_input_rgba(col, in[0], p, thread);
|
||||
|
||||
tex_input_rgba(col, in[0]);
|
||||
|
||||
col[0] = 1.0f - col[0];
|
||||
col[1] = 1.0f - col[1];
|
||||
col[2] = 1.0f - col[2];
|
||||
|
||||
copy_v3_v3(out, col);
|
||||
out[3] = col[3];
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &colorfn, data);
|
||||
copy_v4_v4(out[0]->vec, col);
|
||||
}
|
||||
|
||||
void register_node_type_tex_invert(void)
|
||||
|
@@ -46,81 +46,86 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
|
||||
static void exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *node,
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
float in0 = tex_input_value(in[0], p, thread);
|
||||
float in1 = tex_input_value(in[1], p, thread);
|
||||
float in0 = tex_input_value(in[0]);
|
||||
float in1 = tex_input_value(in[1]);
|
||||
|
||||
switch (node->custom1) {
|
||||
|
||||
case NODE_MATH_ADD:
|
||||
*out = in0 + in1;
|
||||
out[0]->vec[0] = in0 + in1;
|
||||
break;
|
||||
case NODE_MATH_SUB:
|
||||
*out = in0 - in1;
|
||||
out[0]->vec[0] = in0 - in1;
|
||||
break;
|
||||
case NODE_MATH_MUL:
|
||||
*out = in0 * in1;
|
||||
out[0]->vec[0] = in0 * in1;
|
||||
break;
|
||||
case NODE_MATH_DIVIDE:
|
||||
{
|
||||
if (in1 == 0) /* We don't want to divide by zero. */
|
||||
*out = 0.0;
|
||||
out[0]->vec[0] = 0.0f;
|
||||
else
|
||||
*out = in0 / in1;
|
||||
out[0]->vec[0] = in0 / in1;
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_SIN:
|
||||
{
|
||||
*out = sinf(in0);
|
||||
out[0]->vec[0] = sinf(in0);
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_COS:
|
||||
{
|
||||
*out = cosf(in0);
|
||||
out[0]->vec[0] = cosf(in0);
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_TAN:
|
||||
{
|
||||
*out = tanf(in0);
|
||||
out[0]->vec[0] = tanf(in0);
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_ASIN:
|
||||
{
|
||||
/* Can't do the impossible... */
|
||||
if (in0 <= 1 && in0 >= -1)
|
||||
*out = asinf(in0);
|
||||
if (in0 <= 1.0f && in0 >= -1.0f)
|
||||
out[0]->vec[0] = asinf(in0);
|
||||
else
|
||||
*out = 0.0;
|
||||
out[0]->vec[0] = 0.0f;
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_ACOS:
|
||||
{
|
||||
/* Can't do the impossible... */
|
||||
if (in0 <= 1 && in0 >= -1)
|
||||
*out = acosf(in0);
|
||||
if (in0 <= 1.0f && in0 >= -1.0f)
|
||||
out[0]->vec[0]= acosf(in0);
|
||||
else
|
||||
*out = 0.0;
|
||||
out[0]->vec[0] = 0.0;
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_ATAN:
|
||||
{
|
||||
*out = atan(in0);
|
||||
out[0]->vec[0] = atan(in0);
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_POW:
|
||||
{
|
||||
/* Only raise negative numbers by full integers */
|
||||
if (in0 >= 0) {
|
||||
out[0] = pow(in0, in1);
|
||||
if (in0 >= 0.0f) {
|
||||
out[0]->vec[0] = pow(in0, in1);
|
||||
}
|
||||
else {
|
||||
float y_mod_1 = fmod(in1, 1);
|
||||
float y_mod_1 = fmod(in1, 1.0f);
|
||||
if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
|
||||
*out = pow(in0, floor(in1 + 0.5f));
|
||||
out[0]->vec[0] = powf(in0, floor(in1 + 0.5f));
|
||||
}
|
||||
else {
|
||||
*out = 0.0;
|
||||
out[0]->vec[0] = 0.0f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -128,64 +133,64 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
|
||||
case NODE_MATH_LOG:
|
||||
{
|
||||
/* Don't want any imaginary numbers... */
|
||||
if (in0 > 0 && in1 > 0)
|
||||
*out = log(in0) / log(in1);
|
||||
if (in0 > 0.0f && in1 > 0.0f)
|
||||
out[0]->vec[0] = log(in0) / log(in1);
|
||||
else
|
||||
*out = 0.0;
|
||||
out[0]->vec[0] = 0.0;
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_MIN:
|
||||
{
|
||||
if (in0 < in1)
|
||||
*out = in0;
|
||||
out[0]->vec[0] = in0;
|
||||
else
|
||||
*out = in1;
|
||||
out[0]->vec[0] = in1;
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_MAX:
|
||||
{
|
||||
if (in0 > in1)
|
||||
*out = in0;
|
||||
out[0]->vec[0] = in0;
|
||||
else
|
||||
*out = in1;
|
||||
out[0]->vec[0] = in1;
|
||||
break;
|
||||
}
|
||||
case NODE_MATH_ROUND:
|
||||
{
|
||||
*out = (in0 < 0) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f);
|
||||
out[0]->vec[0] = (in0 < 0.0f) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f);
|
||||
break;
|
||||
}
|
||||
|
||||
case NODE_MATH_LESS:
|
||||
{
|
||||
if (in0 < in1)
|
||||
*out = 1.0f;
|
||||
out[0]->vec[0] = 1.0f;
|
||||
else
|
||||
*out = 0.0f;
|
||||
out[0]->vec[0] = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
case NODE_MATH_GREATER:
|
||||
{
|
||||
if (in0 > in1)
|
||||
*out = 1.0f;
|
||||
out[0]->vec[0] = 1.0f;
|
||||
else
|
||||
*out = 0.0f;
|
||||
out[0]->vec[0] = 0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
case NODE_MATH_MOD:
|
||||
{
|
||||
if (in1 == 0.0f)
|
||||
*out = 0.0f;
|
||||
out[0]->vec[0] = 0.0f;
|
||||
else
|
||||
*out = fmod(in0, in1);
|
||||
out[0]->vec[0] = fmod(in0, in1);
|
||||
break;
|
||||
}
|
||||
|
||||
case NODE_MATH_ABS:
|
||||
{
|
||||
*out = fabsf(in0);
|
||||
out[0]->vec[0] = fabsf(in0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -197,11 +202,6 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
|
||||
}
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &valuefn, data);
|
||||
}
|
||||
|
||||
void register_node_type_tex_math(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -45,37 +45,37 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
|
||||
static void exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *node,
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
float fac = tex_input_value(in[0], p, thread);
|
||||
float fac = tex_input_value(in[0]);
|
||||
float col1[4], col2[4];
|
||||
|
||||
tex_input_rgba(col1, in[1], p, thread);
|
||||
tex_input_rgba(col2, in[2], p, thread);
|
||||
|
||||
tex_input_rgba(col1, in[1]);
|
||||
tex_input_rgba(col2, in[2]);
|
||||
|
||||
/* use alpha */
|
||||
if (node->custom2 & 1)
|
||||
fac *= col2[3];
|
||||
|
||||
CLAMP(fac, 0.0f, 1.0f);
|
||||
|
||||
copy_v4_v4(out, col1);
|
||||
ramp_blend(node->custom1, out, fac, col2);
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &colorfn, data);
|
||||
CLAMP(fac, 0.0f, 1.0f);
|
||||
|
||||
copy_v4_v4(out[0]->vec, col1);
|
||||
ramp_blend(node->custom1, out[0]->vec, fac, col2);
|
||||
}
|
||||
|
||||
void register_node_type_tex_mix_rgb(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, 0);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_label(&ntype, node_blend_label);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -41,35 +41,34 @@ static bNodeSocketTemplate inputs[] = {
|
||||
};
|
||||
|
||||
/* applies to render pipeline */
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **UNUSED(out))
|
||||
static void exec(void *data,
|
||||
int UNUSED(thread),
|
||||
bNode *node,
|
||||
bNodeExecData *execdata,
|
||||
bNodeStack **in,
|
||||
bNodeStack **UNUSED(out))
|
||||
{
|
||||
TexCallData *cdata = (TexCallData *)data;
|
||||
TexResult *target = cdata->target;
|
||||
|
||||
if (cdata->do_preview) {
|
||||
TexParams params;
|
||||
params_from_cdata(¶ms, cdata);
|
||||
|
||||
if (cdata->do_preview) {
|
||||
if (in[1] && in[1]->hasinput && !in[0]->hasinput)
|
||||
tex_input_rgba(&target->tr, in[1], ¶ms, cdata->thread);
|
||||
tex_input_rgba(&target->tr, in[1]);
|
||||
else
|
||||
tex_input_rgba(&target->tr, in[0], ¶ms, cdata->thread);
|
||||
tex_do_preview(execdata->preview, params.co, &target->tr, cdata->do_manage);
|
||||
tex_input_rgba(&target->tr, in[0]);
|
||||
tex_do_preview(execdata->preview, cdata->co, &target->tr, cdata->do_manage);
|
||||
}
|
||||
else {
|
||||
/* 0 means don't care, so just use first */
|
||||
if (cdata->which_output == node->custom1 || (cdata->which_output == 0 && node->custom1 == 1)) {
|
||||
TexParams params;
|
||||
params_from_cdata(¶ms, cdata);
|
||||
|
||||
tex_input_rgba(&target->tr, in[0], ¶ms, cdata->thread);
|
||||
|
||||
tex_input_rgba(&target->tr, in[0]);
|
||||
|
||||
target->tin = (target->tr + target->tg + target->tb) / 3.0f;
|
||||
target->talpha = true;
|
||||
|
||||
|
||||
if (target->nor) {
|
||||
if (in[1] && in[1]->hasinput)
|
||||
tex_input_vec(target->nor, in[1], ¶ms, cdata->thread);
|
||||
tex_input_vec(target->nor, in[1]);
|
||||
else
|
||||
target->nor = NULL;
|
||||
}
|
||||
@@ -85,7 +84,7 @@ static void unique_name(bNode *node)
|
||||
int suffix;
|
||||
bNode *i;
|
||||
const char *name = tno->name;
|
||||
|
||||
|
||||
new_name[0] = '\0';
|
||||
i = node;
|
||||
while (i->prev) i = i->prev;
|
||||
@@ -114,7 +113,7 @@ static void unique_name(bNode *node)
|
||||
}
|
||||
sprintf(new_name + new_len - 4, ".%03d", ++suffix);
|
||||
}
|
||||
|
||||
|
||||
if (new_name[0] != '\0') {
|
||||
BLI_strncpy(tno->name, new_name, sizeof(tno->name));
|
||||
}
|
||||
@@ -124,19 +123,21 @@ static void assign_index(struct bNode *node)
|
||||
{
|
||||
bNode *tnode;
|
||||
int index = 1;
|
||||
|
||||
|
||||
tnode = node;
|
||||
while (tnode->prev)
|
||||
tnode = tnode->prev;
|
||||
|
||||
|
||||
check_index:
|
||||
for (; tnode; tnode = tnode->next)
|
||||
if (tnode->type == TEX_NODE_OUTPUT && tnode != node)
|
||||
for (; tnode; tnode = tnode->next) {
|
||||
if (tnode->type == TEX_NODE_OUTPUT && tnode != node) {
|
||||
if (tnode->custom1 == index) {
|
||||
index++;
|
||||
goto check_index;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
node->custom1 = index;
|
||||
}
|
||||
|
||||
@@ -144,7 +145,7 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
{
|
||||
TexNodeOutput *tno = MEM_callocN(sizeof(TexNodeOutput), "TEX_output");
|
||||
node->storage = tno;
|
||||
|
||||
|
||||
strcpy(tno->name, "Default");
|
||||
unique_name(node);
|
||||
assign_index(node);
|
||||
@@ -160,16 +161,16 @@ static void copy(bNodeTree *dest_ntree, bNode *dest_node, bNode *src_node)
|
||||
void register_node_type_tex_output(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW);
|
||||
node_type_socket_templates(&ntype, inputs, NULL);
|
||||
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
|
||||
node_type_init(&ntype, init);
|
||||
node_type_storage(&ntype, "TexNodeOutput", node_free_standard_storage, copy);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
/* Do not allow muting output. */
|
||||
node_type_internal_links(&ntype, NULL);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
#include "RE_shader_ext.h"
|
||||
|
||||
/*
|
||||
/*
|
||||
* In this file: wrappers to use procedural textures as nodes
|
||||
*/
|
||||
|
||||
@@ -57,23 +57,29 @@ static bNodeSocketTemplate outputs_color_only[] = {
|
||||
{ SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.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, TexParams *p, const float col1[4], const float col2[4], char is_normal, Tex *tex, const short thread)
|
||||
static void do_proc(float *result,
|
||||
TexCallData *cdata,
|
||||
const float col1[4],
|
||||
const float col2[4],
|
||||
bool is_normal,
|
||||
Tex *tex,
|
||||
const short thread)
|
||||
{
|
||||
TexResult texres;
|
||||
int textype;
|
||||
|
||||
|
||||
if (is_normal) {
|
||||
texres.nor = result;
|
||||
}
|
||||
else
|
||||
texres.nor = NULL;
|
||||
|
||||
textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex,
|
||||
&texres, thread, 0, p->shi, p->mtex, NULL);
|
||||
|
||||
|
||||
textype = multitex_nodes(tex, cdata->co, cdata->dxt, cdata->dyt, cdata->osatex,
|
||||
&texres, thread, 0, cdata->shi, cdata->mtex, NULL);
|
||||
|
||||
if (is_normal)
|
||||
return;
|
||||
|
||||
|
||||
if (textype & TEX_RGB) {
|
||||
copy_v4_v4(result, &texres.tr);
|
||||
}
|
||||
@@ -83,57 +89,42 @@ static void do_proc(float *result, TexParams *p, const float col1[4], const floa
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, const short thread);
|
||||
typedef void (*MapFn) (Tex *tex, bNodeStack **in);
|
||||
|
||||
static void texfn(
|
||||
float *result,
|
||||
TexParams *p,
|
||||
bNode *node,
|
||||
bNodeStack **in,
|
||||
char is_normal,
|
||||
MapFn map_inputs,
|
||||
short thread)
|
||||
static void texfn(float *result,
|
||||
TexCallData *cdata,
|
||||
bNode *node,
|
||||
bNodeStack **in,
|
||||
bool is_normal,
|
||||
MapFn map_inputs,
|
||||
short thread)
|
||||
{
|
||||
Tex tex = *((Tex *)(node->storage));
|
||||
float col1[4], col2[4];
|
||||
tex_input_rgba(col1, in[0], p, thread);
|
||||
tex_input_rgba(col2, in[1], p, thread);
|
||||
|
||||
map_inputs(&tex, in, p, thread);
|
||||
|
||||
do_proc(result, p, col1, col2, is_normal, &tex, thread);
|
||||
}
|
||||
tex_input_rgba(col1, in[0]);
|
||||
tex_input_rgba(col2, in[1]);
|
||||
|
||||
static int count_outputs(bNode *node)
|
||||
{
|
||||
bNodeSocket *sock;
|
||||
int num = 0;
|
||||
for (sock = node->outputs.first; sock; sock = sock->next) {
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
map_inputs(&tex, in);
|
||||
|
||||
do_proc(result, cdata, col1, col2, is_normal, &tex, thread);
|
||||
}
|
||||
|
||||
/* Boilerplate generators */
|
||||
|
||||
#define ProcNoInputs(name) \
|
||||
static void name##_map_inputs(Tex *UNUSED(tex), bNodeStack **UNUSED(in), TexParams *UNUSED(p), short UNUSED(thread)) \
|
||||
static void name##_map_inputs(Tex *UNUSED(tex), bNodeStack **UNUSED(in)) \
|
||||
{}
|
||||
|
||||
#define ProcDef(name) \
|
||||
static void name##_colorfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
|
||||
static void name##_exec(void *data, int thread, bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out) \
|
||||
{ \
|
||||
texfn(result, p, node, in, 0, &name##_map_inputs, thread); \
|
||||
} \
|
||||
static void name##_normalfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
|
||||
{ \
|
||||
texfn(result, p, node, in, 1, &name##_map_inputs, thread); \
|
||||
} \
|
||||
static void name##_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out) \
|
||||
{ \
|
||||
int outs = count_outputs(node); \
|
||||
if (outs >= 1) tex_output(node, execdata, in, out[0], &name##_colorfn, data); \
|
||||
if (outs >= 2) tex_output(node, execdata, in, out[1], &name##_normalfn, data); \
|
||||
int outs = BLI_countlist(&node->outputs); \
|
||||
TexCallData *cdata = (TexCallData *)data; \
|
||||
if (outs >= 1) { \
|
||||
texfn(out[0]->vec, cdata, node, in, false, &name##_map_inputs, thread); \
|
||||
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage); \
|
||||
} \
|
||||
if (outs >= 2) texfn(out[1]->vec, cdata, node, in, true, &name##_map_inputs, thread); \
|
||||
}
|
||||
|
||||
|
||||
@@ -144,21 +135,21 @@ static bNodeSocketTemplate voronoi_inputs[] = {
|
||||
{ SOCK_FLOAT, 1, N_("W2"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
|
||||
{ SOCK_FLOAT, 1, N_("W3"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
|
||||
{ SOCK_FLOAT, 1, N_("W4"), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_NONE },
|
||||
|
||||
|
||||
{ SOCK_FLOAT, 1, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f, PROP_UNSIGNED },
|
||||
{ SOCK_FLOAT, 1, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f, PROP_UNSIGNED },
|
||||
|
||||
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
||||
static void voronoi_map_inputs(Tex *tex, bNodeStack **in)
|
||||
{
|
||||
tex->vn_w1 = tex_input_value(in[I + 0], p, thread);
|
||||
tex->vn_w2 = tex_input_value(in[I + 1], p, thread);
|
||||
tex->vn_w3 = tex_input_value(in[I + 2], p, thread);
|
||||
tex->vn_w4 = tex_input_value(in[I + 3], p, thread);
|
||||
|
||||
tex->ns_outscale = tex_input_value(in[I + 4], p, thread);
|
||||
tex->noisesize = tex_input_value(in[I + 5], p, thread);
|
||||
tex->vn_w1 = tex_input_value(in[I + 0]);
|
||||
tex->vn_w2 = tex_input_value(in[I + 1]);
|
||||
tex->vn_w3 = tex_input_value(in[I + 2]);
|
||||
tex->vn_w4 = tex_input_value(in[I + 3]);
|
||||
|
||||
tex->ns_outscale = tex_input_value(in[I + 4]);
|
||||
tex->noisesize = tex_input_value(in[I + 5]);
|
||||
}
|
||||
ProcDef(voronoi)
|
||||
|
||||
@@ -176,9 +167,9 @@ static bNodeSocketTemplate magic_inputs[] = {
|
||||
{ SOCK_FLOAT, 1, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED },
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
||||
static void magic_map_inputs(Tex *tex, bNodeStack **in)
|
||||
{
|
||||
tex->turbul = tex_input_value(in[I + 0], p, thread);
|
||||
tex->turbul = tex_input_value(in[I + 0]);
|
||||
}
|
||||
ProcDef(magic)
|
||||
|
||||
@@ -189,10 +180,10 @@ static bNodeSocketTemplate marble_inputs[] = {
|
||||
{ SOCK_FLOAT, 1, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED },
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
||||
static void marble_map_inputs(Tex *tex, bNodeStack **in)
|
||||
{
|
||||
tex->noisesize = tex_input_value(in[I + 0], p, thread);
|
||||
tex->turbul = tex_input_value(in[I + 1], p, thread);
|
||||
tex->noisesize = tex_input_value(in[I + 0]);
|
||||
tex->turbul = tex_input_value(in[I + 1]);
|
||||
}
|
||||
ProcDef(marble)
|
||||
|
||||
@@ -202,9 +193,9 @@ static bNodeSocketTemplate clouds_inputs[] = {
|
||||
{ SOCK_FLOAT, 1, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED },
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
||||
static void clouds_map_inputs(Tex *tex, bNodeStack **in)
|
||||
{
|
||||
tex->noisesize = tex_input_value(in[I + 0], p, thread);
|
||||
tex->noisesize = tex_input_value(in[I + 0]);
|
||||
}
|
||||
ProcDef(clouds)
|
||||
|
||||
@@ -215,10 +206,10 @@ static bNodeSocketTemplate distnoise_inputs[] = {
|
||||
{ SOCK_FLOAT, 1, N_("Distortion"), 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f, PROP_UNSIGNED },
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
||||
static void distnoise_map_inputs(Tex *tex, bNodeStack **in)
|
||||
{
|
||||
tex->noisesize = tex_input_value(in[I + 0], p, thread);
|
||||
tex->dist_amount = tex_input_value(in[I + 1], p, thread);
|
||||
tex->noisesize = tex_input_value(in[I + 0]);
|
||||
tex->dist_amount = tex_input_value(in[I + 1]);
|
||||
}
|
||||
ProcDef(distnoise)
|
||||
|
||||
@@ -229,10 +220,10 @@ static bNodeSocketTemplate wood_inputs[] = {
|
||||
{ SOCK_FLOAT, 1, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED },
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
||||
static void wood_map_inputs(Tex *tex, bNodeStack **in)
|
||||
{
|
||||
tex->noisesize = tex_input_value(in[I + 0], p, thread);
|
||||
tex->turbul = tex_input_value(in[I + 1], p, thread);
|
||||
tex->noisesize = tex_input_value(in[I + 0]);
|
||||
tex->turbul = tex_input_value(in[I + 1]);
|
||||
}
|
||||
ProcDef(wood)
|
||||
|
||||
@@ -242,18 +233,18 @@ static bNodeSocketTemplate musgrave_inputs[] = {
|
||||
{ SOCK_FLOAT, 1, N_("H"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED },
|
||||
{ SOCK_FLOAT, 1, N_("Lacunarity"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f, PROP_UNSIGNED },
|
||||
{ SOCK_FLOAT, 1, N_("Octaves"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f, PROP_UNSIGNED },
|
||||
|
||||
|
||||
{ SOCK_FLOAT, 1, N_("iScale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f, PROP_UNSIGNED },
|
||||
{ SOCK_FLOAT, 1, N_("Size"), 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f, PROP_UNSIGNED },
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
||||
static void musgrave_map_inputs(Tex *tex, bNodeStack **in)
|
||||
{
|
||||
tex->mg_H = tex_input_value(in[I + 0], p, thread);
|
||||
tex->mg_lacunarity = tex_input_value(in[I + 1], p, thread);
|
||||
tex->mg_octaves = tex_input_value(in[I + 2], p, thread);
|
||||
tex->ns_outscale = tex_input_value(in[I + 3], p, thread);
|
||||
tex->noisesize = tex_input_value(in[I + 4], p, thread);
|
||||
tex->mg_H = tex_input_value(in[I + 0]);
|
||||
tex->mg_lacunarity = tex_input_value(in[I + 1]);
|
||||
tex->mg_octaves = tex_input_value(in[I + 2]);
|
||||
tex->ns_outscale = tex_input_value(in[I + 3]);
|
||||
tex->noisesize = tex_input_value(in[I + 4]);
|
||||
}
|
||||
ProcDef(musgrave)
|
||||
|
||||
@@ -272,10 +263,10 @@ static bNodeSocketTemplate stucci_inputs[] = {
|
||||
{ SOCK_FLOAT, 1, N_("Turbulence"), 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f, PROP_UNSIGNED },
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
||||
static void stucci_map_inputs(Tex *tex, bNodeStack **in)
|
||||
{
|
||||
tex->noisesize = tex_input_value(in[I + 0], p, thread);
|
||||
tex->turbul = tex_input_value(in[I + 1], p, thread);
|
||||
tex->noisesize = tex_input_value(in[I + 0]);
|
||||
tex->turbul = tex_input_value(in[I + 1]);
|
||||
}
|
||||
ProcDef(stucci)
|
||||
|
||||
@@ -285,13 +276,12 @@ static void init(bNodeTree *UNUSED(ntree), 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 */
|
||||
@@ -309,10 +299,10 @@ void register_node_type_tex_proc_##name(void) \
|
||||
\
|
||||
nodeRegisterType(&ntype); \
|
||||
}
|
||||
|
||||
|
||||
#define C outputs_color_only
|
||||
#define CV outputs_both
|
||||
|
||||
|
||||
TexDef(TEX_VORONOI, CV, voronoi, "Voronoi" )
|
||||
TexDef(TEX_BLEND, C, blend, "Blend" )
|
||||
TexDef(TEX_MAGIC, C, magic, "Magic" )
|
||||
|
@@ -69,12 +69,12 @@ static void rotate(float new_co[3], float a, float ax[3], const float co[3])
|
||||
new_co[2] = para[2] + perp[2] + cp[2];
|
||||
}
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void colorfn(float *UNUSED(out), TexParams *p, bNode *UNUSED(node), bNodeStack **in, short UNUSED(thread))
|
||||
{
|
||||
float new_co[3], new_dxt[3], new_dyt[3], a, ax[3];
|
||||
|
||||
a = tex_input_value(in[1], p, thread);
|
||||
tex_input_vec(ax, in[2], p, thread);
|
||||
a = tex_input_value(in[1]);
|
||||
tex_input_vec(ax, in[2]);
|
||||
|
||||
rotate(new_co, a, ax, p->co);
|
||||
if (p->osatex) {
|
||||
@@ -87,7 +87,8 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
|
||||
np.co = new_co;
|
||||
np.dxt = new_dxt;
|
||||
np.dyt = new_dyt;
|
||||
tex_input_rgba(out, in[0], &np, thread);
|
||||
//tex_input_rgba(out, in[0], &np, thread);
|
||||
BLI_assert(!"Needs proper solution");
|
||||
}
|
||||
}
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
|
@@ -44,7 +44,7 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void colorfn(float *UNUSED(out), TexParams *p, bNode *UNUSED(node), bNodeStack **in, short UNUSED(thread))
|
||||
{
|
||||
float scale[3], new_co[3], new_dxt[3], new_dyt[3];
|
||||
TexParams np = *p;
|
||||
@@ -53,7 +53,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
|
||||
np.dxt = new_dxt;
|
||||
np.dyt = new_dyt;
|
||||
|
||||
tex_input_vec(scale, in[1], p, thread);
|
||||
tex_input_vec(scale, in[1]);
|
||||
|
||||
mul_v3_v3v3(new_co, p->co, scale);
|
||||
if (p->osatex) {
|
||||
@@ -61,7 +61,8 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **
|
||||
mul_v3_v3v3(new_dyt, p->dyt, scale);
|
||||
}
|
||||
|
||||
tex_input_rgba(out, in[0], &np, thread);
|
||||
//tex_input_rgba(out, in[0], &np, thread);
|
||||
BLI_assert(!"Need proper solution");
|
||||
}
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
|
@@ -46,62 +46,64 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
|
||||
static void exec(void *data,
|
||||
int thread,
|
||||
bNode *node,
|
||||
bNodeExecData *execdata,
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
Tex *nodetex = (Tex *)node->id;
|
||||
static float red[] = {1, 0, 0, 1};
|
||||
static float white[] = {1, 1, 1, 1};
|
||||
TexCallData *cdata = (TexCallData *)data;
|
||||
static float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
|
||||
static float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
float co[3], dxt[3], dyt[3];
|
||||
|
||||
copy_v3_v3(co, p->co);
|
||||
if (p->osatex) {
|
||||
copy_v3_v3(dxt, p->dxt);
|
||||
copy_v3_v3(dyt, p->dyt);
|
||||
|
||||
copy_v3_v3(co, cdata->co);
|
||||
if (cdata->osatex) {
|
||||
copy_v3_v3(dxt, cdata->dxt);
|
||||
copy_v3_v3(dyt, cdata->dyt);
|
||||
}
|
||||
else {
|
||||
zero_v3(dxt);
|
||||
zero_v3(dyt);
|
||||
}
|
||||
|
||||
|
||||
if (node->custom2 || node->need_exec == 0) {
|
||||
/* this node refers to its own texture tree! */
|
||||
copy_v4_v4(out, (fabsf(co[0] - co[1]) < 0.01f) ? white : red);
|
||||
copy_v4_v4(out[0]->vec, (fabsf(co[0] - co[1]) < 0.01f) ? 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], p, thread);
|
||||
tex_input_rgba(col2, in[1], p, thread);
|
||||
|
||||
|
||||
tex_input_rgba(col1, in[0]);
|
||||
tex_input_rgba(col2, in[1]);
|
||||
|
||||
texres.nor = nor;
|
||||
textype = multitex_nodes(nodetex, co, dxt, dyt, p->osatex,
|
||||
&texres, thread, 0, p->shi, p->mtex, NULL);
|
||||
|
||||
textype = multitex_nodes(nodetex, co, dxt, dyt, cdata->osatex,
|
||||
&texres, thread, 0, cdata->shi, cdata->mtex, NULL);
|
||||
|
||||
if (textype & TEX_RGB) {
|
||||
copy_v4_v4(out, &texres.tr);
|
||||
copy_v4_v4(out[0]->vec, &texres.tr);
|
||||
}
|
||||
else {
|
||||
copy_v4_v4(out, col1);
|
||||
ramp_blend(MA_RAMP_BLEND, out, texres.tin, col2);
|
||||
copy_v4_v4(out[0]->vec, col1);
|
||||
ramp_blend(MA_RAMP_BLEND, out[0]->vec, texres.tin, col2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &colorfn, data);
|
||||
tex_do_preview(execdata->preview, cdata->co, out[0]->vec, cdata->do_manage);
|
||||
}
|
||||
|
||||
void register_node_type_tex_texture(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_PREVIEW);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -45,19 +45,20 @@ static bNodeSocketTemplate outputs[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void colorfn(float *UNUSED(out), TexParams *p, bNode *UNUSED(node), bNodeStack **in, short UNUSED(thread))
|
||||
{
|
||||
float offset[3], new_co[3];
|
||||
TexParams np = *p;
|
||||
np.co = new_co;
|
||||
|
||||
tex_input_vec(offset, in[1], p, thread);
|
||||
tex_input_vec(offset, in[1]);
|
||||
|
||||
new_co[0] = p->co[0] + offset[0];
|
||||
new_co[1] = p->co[1] + offset[1];
|
||||
new_co[2] = p->co[2] + offset[2];
|
||||
|
||||
tex_input_rgba(out, in[0], &np, thread);
|
||||
//tex_input_rgba(out, in[0], &np, thread);
|
||||
BLI_assert(!"Need a proper port");
|
||||
}
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
|
@@ -46,6 +46,7 @@ static bNodeSocketTemplate outputs[] = {
|
||||
|
||||
static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
{
|
||||
#if 0
|
||||
float new_co[3];
|
||||
const float *co = p->co;
|
||||
|
||||
@@ -74,6 +75,13 @@ static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack *
|
||||
out[0] = val - nor[0];
|
||||
out[1] = val - nor[1];
|
||||
out[2] = val - nor[2];
|
||||
#else
|
||||
(void) out;
|
||||
(void) p;
|
||||
(void) in;
|
||||
(void) thread;
|
||||
BLI_assert(!"Need a proper port");
|
||||
#endif
|
||||
}
|
||||
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -43,10 +43,10 @@ static bNodeSocketTemplate valtorgb_out[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
static void valtorgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
|
||||
static void valtorgb_colorfn(float *out, TexParams *UNUSED(p), bNode *node, bNodeStack **in, short UNUSED(thread))
|
||||
{
|
||||
if (node->storage) {
|
||||
float fac = tex_input_value(in[0], p, thread);
|
||||
float fac = tex_input_value(in[0]);
|
||||
|
||||
do_colorband(node->storage, fac, out);
|
||||
}
|
||||
@@ -86,26 +86,25 @@ static bNodeSocketTemplate rgbtobw_out[] = {
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
|
||||
static void rgbtobw_valuefn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
|
||||
static void rgbtobw_exec(void *UNUSED(data),
|
||||
int UNUSED(thread),
|
||||
bNode *UNUSED(node),
|
||||
bNodeExecData *UNUSED(execdata),
|
||||
bNodeStack **in,
|
||||
bNodeStack **out)
|
||||
{
|
||||
float cin[4];
|
||||
tex_input_rgba(cin, in[0], p, thread);
|
||||
*out = rgb_to_bw(cin);
|
||||
}
|
||||
|
||||
static void rgbtobw_exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
|
||||
{
|
||||
tex_output(node, execdata, in, out[0], &rgbtobw_valuefn, data);
|
||||
tex_input_rgba(cin, in[0]);
|
||||
out[0]->vec[0] = rgb_to_bw(cin);
|
||||
}
|
||||
|
||||
void register_node_type_tex_rgbtobw(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0);
|
||||
node_type_socket_templates(&ntype, rgbtobw_in, rgbtobw_out);
|
||||
node_type_exec(&ntype, NULL, NULL, rgbtobw_exec);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* 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
|
||||
@@ -45,27 +45,23 @@ static bNodeSocketTemplate outputs[] = {
|
||||
static void exec(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *execdata, bNodeStack **in, bNodeStack **UNUSED(out))
|
||||
{
|
||||
TexCallData *cdata = (TexCallData *)data;
|
||||
|
||||
if (cdata->do_preview) {
|
||||
TexParams params;
|
||||
float col[4];
|
||||
params_from_cdata(¶ms, cdata);
|
||||
|
||||
tex_input_rgba(col, in[0], ¶ms, cdata->thread);
|
||||
tex_do_preview(execdata->preview, params.previewco, col, cdata->do_manage);
|
||||
tex_input_rgba(col, in[0]);
|
||||
tex_do_preview(execdata->preview, cdata->co, col, cdata->do_manage);
|
||||
}
|
||||
}
|
||||
|
||||
void register_node_type_tex_viewer(void)
|
||||
{
|
||||
static bNodeType ntype;
|
||||
|
||||
|
||||
tex_node_type_base(&ntype, TEX_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, NODE_PREVIEW);
|
||||
node_type_socket_templates(&ntype, inputs, outputs);
|
||||
node_type_exec(&ntype, NULL, NULL, exec);
|
||||
|
||||
|
||||
/* Do not allow muting viewer node. */
|
||||
node_type_internal_links(&ntype, NULL);
|
||||
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
@@ -304,5 +304,8 @@ bool RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override
|
||||
|
||||
bool RE_allow_render_generic_object(struct Object *ob);
|
||||
|
||||
struct bNodeTreeExecPool;
|
||||
struct bNodeTreeExecPool *RE_tree_exec_pool_get(struct Render *re);
|
||||
|
||||
#endif /* __RE_PIPELINE_H__ */
|
||||
|
||||
|
@@ -66,6 +66,7 @@ struct RenderEngine;
|
||||
struct ReportList;
|
||||
struct Main;
|
||||
struct ImagePool;
|
||||
struct bNodeTreeExecPool;
|
||||
|
||||
#define TABLEINITSIZE 1024
|
||||
|
||||
@@ -275,6 +276,7 @@ struct Render
|
||||
|
||||
struct ImagePool *pool;
|
||||
struct EvaluationContext *eval_ctx;
|
||||
struct bNodeTreeExecPool *tree_exec_pool;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@@ -176,7 +176,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
|
||||
shade_samples_do_AO(ssamp);
|
||||
|
||||
if (shi->mat->nodetree && shi->mat->use_nodes) {
|
||||
ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
|
||||
ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, &shr);
|
||||
shi->mat = vlr->mat; /* shi->mat is being set in nodetree */
|
||||
}
|
||||
else
|
||||
|
@@ -4741,7 +4741,7 @@ void RE_Database_Free(Render *re)
|
||||
free_mesh_orco_hash(re);
|
||||
|
||||
if (re->main) {
|
||||
end_render_materials(re->main);
|
||||
end_render_materials(re->main, re->tree_exec_pool);
|
||||
end_render_textures(re);
|
||||
free_pointdensities(re);
|
||||
}
|
||||
@@ -5110,6 +5110,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
|
||||
{
|
||||
Scene *sce;
|
||||
Object *camera;
|
||||
bNodeTreeExecPool *tree_exec_pool;
|
||||
float mat[4][4];
|
||||
float amb[3];
|
||||
|
||||
@@ -5176,9 +5177,10 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
|
||||
}
|
||||
|
||||
/* still bad... doing all */
|
||||
tree_exec_pool = RE_tree_exec_pool_get(re);
|
||||
init_render_textures(re);
|
||||
copy_v3_v3(amb, &re->wrld.ambr);
|
||||
init_render_materials(re->main, re->r.mode, amb);
|
||||
init_render_materials(re->main, tree_exec_pool, re->r.mode, amb);
|
||||
set_node_shader_lamp_loop(shade_material_loop);
|
||||
|
||||
/* MAKE RENDER DATA */
|
||||
@@ -5829,6 +5831,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
|
||||
void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay, const int type, Object *actob)
|
||||
{
|
||||
Object *camera;
|
||||
bNodeTreeExecPool *tree_exec_pool;
|
||||
float mat[4][4];
|
||||
float amb[3];
|
||||
const short onlyselected= !ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL, RE_BAKE_SHADOW, RE_BAKE_AO, RE_BAKE_VERTEX_COLORS);
|
||||
@@ -5910,7 +5913,8 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
|
||||
init_render_textures(re);
|
||||
|
||||
copy_v3_v3(amb, &re->wrld.ambr);
|
||||
init_render_materials(re->main, re->r.mode, amb);
|
||||
tree_exec_pool = RE_tree_exec_pool_get(re);
|
||||
init_render_materials(re->main, tree_exec_pool, re->r.mode, amb);
|
||||
|
||||
set_node_shader_lamp_loop(shade_material_loop);
|
||||
|
||||
|
@@ -199,7 +199,7 @@ static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr,
|
||||
shade_input_set_shade_texco(shi);
|
||||
|
||||
if (shi->mat->nodetree && shi->mat->use_nodes) {
|
||||
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
|
||||
ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, shr);
|
||||
shi->mat = vlr->mat; /* shi->mat is being set in nodetree */
|
||||
}
|
||||
else {
|
||||
|
@@ -387,6 +387,7 @@ Render *RE_NewRender(const char *name)
|
||||
BLI_rw_mutex_init(&re->resultmutex);
|
||||
re->eval_ctx = MEM_callocN(sizeof(EvaluationContext), "re->eval_ctx");
|
||||
re->eval_ctx->mode = DAG_EVAL_RENDER;
|
||||
re->tree_exec_pool = BKE_node_tree_exec_pool_new();
|
||||
}
|
||||
|
||||
RE_InitRenderCB(re);
|
||||
@@ -435,7 +436,9 @@ void RE_FreeRender(Render *re)
|
||||
|
||||
render_result_free(re->result);
|
||||
render_result_free(re->pushedresult);
|
||||
|
||||
|
||||
BKE_node_tree_exec_pool_free(re->tree_exec_pool);
|
||||
|
||||
BLI_remlink(&RenderGlobal.renderlist, re);
|
||||
MEM_freeN(re->eval_ctx);
|
||||
MEM_freeN(re);
|
||||
@@ -3330,3 +3333,8 @@ bool RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env,
|
||||
}
|
||||
}
|
||||
|
||||
struct bNodeTreeExecPool *RE_tree_exec_pool_get(Render *re)
|
||||
{
|
||||
return re->tree_exec_pool;
|
||||
}
|
||||
|
||||
|
@@ -534,7 +534,7 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
|
||||
else if (is->mode==RE_RAY_SHADOW_TRA) {
|
||||
/* temp hack to prevent recursion */
|
||||
if (shi->nodes==0 && shi->mat->nodetree && shi->mat->use_nodes) {
|
||||
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
|
||||
ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, shr);
|
||||
shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
|
||||
}
|
||||
else
|
||||
@@ -542,7 +542,7 @@ void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
|
||||
}
|
||||
else {
|
||||
if (shi->mat->nodetree && shi->mat->use_nodes) {
|
||||
ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
|
||||
ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, shr);
|
||||
shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
|
||||
}
|
||||
else {
|
||||
|
@@ -122,7 +122,16 @@ static void init_render_texture(Render *re, Tex *tex)
|
||||
}
|
||||
|
||||
if (tex->nodetree && tex->use_nodes) {
|
||||
ntreeTexBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
struct bNodeTreeExec *exec_data;
|
||||
BLI_assert(re != NULL);
|
||||
exec_data = BKE_node_tree_exec_pool_get(re->tree_exec_pool,
|
||||
&tex->nodetree->id);
|
||||
if (exec_data == NULL) {
|
||||
exec_data = ntreeTexBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
|
||||
BKE_node_tree_exec_pool_put(re->tree_exec_pool,
|
||||
&tex->nodetree->id,
|
||||
exec_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,10 +148,16 @@ void init_render_textures(Render *re)
|
||||
}
|
||||
}
|
||||
|
||||
static void end_render_texture(Tex *tex)
|
||||
static void end_render_texture(Render *re, Tex *tex)
|
||||
{
|
||||
if (tex && tex->use_nodes && tex->nodetree && tex->nodetree->execdata)
|
||||
ntreeTexEndExecTree(tex->nodetree->execdata);
|
||||
if (tex && tex->use_nodes && tex->nodetree) {
|
||||
struct bNodeTreeExec *exec_data =
|
||||
BKE_node_tree_exec_pool_pop(re->tree_exec_pool,
|
||||
&tex->nodetree->id);
|
||||
if (exec_data != NULL) {
|
||||
ntreeTexEndExecTree(exec_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void end_render_textures(Render *re)
|
||||
@@ -150,7 +165,7 @@ void end_render_textures(Render *re)
|
||||
Tex *tex;
|
||||
for (tex= re->main->tex.first; tex; tex= tex->id.next)
|
||||
if (tex->id.us)
|
||||
end_render_texture(tex);
|
||||
end_render_texture(re, tex);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -1111,7 +1126,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
|
||||
texres->talpha = false; /* is set when image texture returns alpha (considered premul) */
|
||||
|
||||
if (tex->use_nodes && tex->nodetree) {
|
||||
retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
|
||||
retval = ntreeTexExecTree(R.tree_exec_pool, tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
|
||||
tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
@@ -1307,7 +1322,7 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt
|
||||
if (tex->use_nodes && tex->nodetree) {
|
||||
/* stupid exception here .. but we have to pass shi and mtex to
|
||||
* textures nodes for 2d mapping and color management for images */
|
||||
return ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread,
|
||||
return ntreeTexExecTree(R.tree_exec_pool, tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread,
|
||||
tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex);
|
||||
}
|
||||
else {
|
||||
|
@@ -156,7 +156,7 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
|
||||
#endif
|
||||
|
||||
if (shi->mat->nodetree && shi->mat->use_nodes)
|
||||
compat = ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
|
||||
compat = ntreeShaderExecTree(R.tree_exec_pool, shi->mat->nodetree, shi, shr);
|
||||
|
||||
/* also run this when node shaders fail, due to incompatible shader nodes */
|
||||
if (compat == false) {
|
||||
|
Reference in New Issue
Block a user