319 lines
10 KiB
C
319 lines
10 KiB
C
/**
|
|
*
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): Robin Allen
|
|
*
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
*/
|
|
|
|
#include "../TEX_util.h"
|
|
#include "RE_shader_ext.h"
|
|
|
|
/*
|
|
In this file: wrappers to use procedural textures as nodes
|
|
*/
|
|
|
|
|
|
static bNodeSocketType outputs_both[]= {
|
|
{ SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
|
|
{ SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
static bNodeSocketType outputs_color_only[]= {
|
|
{ SOCK_RGBA, 0, "Color", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
|
|
/* Inputs common to all, #defined because nodes will need their own inputs too */
|
|
#define I 2 /* count */
|
|
#define COMMON_INPUTS \
|
|
{ SOCK_RGBA, 1, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, \
|
|
{ SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }
|
|
|
|
/* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */
|
|
static void do_proc(float *result, TexParams *p, float *col1, float *col2, char is_normal, Tex *tex, short thread)
|
|
{
|
|
TexResult texres;
|
|
int textype;
|
|
|
|
if(is_normal) {
|
|
texres.nor = result;
|
|
}
|
|
else
|
|
texres.nor = NULL;
|
|
|
|
textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex,
|
|
&texres, thread, 0, p->shi, p->mtex);
|
|
|
|
if(is_normal)
|
|
return;
|
|
|
|
if(textype & TEX_RGB) {
|
|
QUATCOPY(result, &texres.tr);
|
|
}
|
|
else {
|
|
QUATCOPY(result, col1);
|
|
ramp_blend(MA_RAMP_BLEND, result, result+1, result+2, texres.tin, col2);
|
|
}
|
|
}
|
|
|
|
typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, short thread);
|
|
|
|
static void texfn(
|
|
float *result,
|
|
TexParams *p,
|
|
bNode *node,
|
|
bNodeStack **in,
|
|
char is_normal,
|
|
MapFn map_inputs,
|
|
short thread)
|
|
{
|
|
Tex tex = *((Tex*)(node->storage));
|
|
float col1[4], col2[4];
|
|
tex_input_rgba(col1, in[0], 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);
|
|
}
|
|
|
|
static int count_outputs(bNode *node)
|
|
{
|
|
bNodeSocket *sock;
|
|
int num = 0;
|
|
for(sock= node->outputs.first; sock; sock= sock->next) {
|
|
num++;
|
|
}
|
|
return num;
|
|
}
|
|
|
|
/* Boilerplate generators */
|
|
|
|
#define ProcNoInputs(name) \
|
|
static void name##_map_inputs(Tex *UNUSED(tex), bNodeStack **UNUSED(in), TexParams *UNUSED(p), short UNUSED(thread)) \
|
|
{}
|
|
|
|
#define ProcDef(name) \
|
|
static void name##_colorfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
|
|
{ \
|
|
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, bNode *node, bNodeStack **in, bNodeStack **out) \
|
|
{ \
|
|
int outs = count_outputs(node); \
|
|
if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn, data); \
|
|
if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn, data); \
|
|
}
|
|
|
|
|
|
/* --- VORONOI -- */
|
|
static bNodeSocketType voronoi_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ SOCK_VALUE, 1, "W1", 1.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f },
|
|
{ SOCK_VALUE, 1, "W2", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f },
|
|
{ SOCK_VALUE, 1, "W3", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f },
|
|
{ SOCK_VALUE, 1, "W4", 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f },
|
|
|
|
{ SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.01f, 10.0f },
|
|
{ SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 4.0f },
|
|
|
|
{ -1, 0, "" }
|
|
};
|
|
static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
|
{
|
|
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);
|
|
}
|
|
ProcDef(voronoi)
|
|
|
|
/* --- BLEND -- */
|
|
static bNodeSocketType blend_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ -1, 0, "" }
|
|
};
|
|
ProcNoInputs(blend)
|
|
ProcDef(blend)
|
|
|
|
/* -- MAGIC -- */
|
|
static bNodeSocketType magic_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
|
{
|
|
tex->turbul = tex_input_value(in[I+0], p, thread);
|
|
}
|
|
ProcDef(magic)
|
|
|
|
/* --- MARBLE --- */
|
|
static bNodeSocketType marble_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
|
|
{ SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
|
{
|
|
tex->noisesize = tex_input_value(in[I+0], p, thread);
|
|
tex->turbul = tex_input_value(in[I+1], p, thread);
|
|
}
|
|
ProcDef(marble)
|
|
|
|
/* --- CLOUDS --- */
|
|
static bNodeSocketType clouds_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
|
{
|
|
tex->noisesize = tex_input_value(in[I+0], p, thread);
|
|
}
|
|
ProcDef(clouds)
|
|
|
|
/* --- DISTORTED NOISE --- */
|
|
static bNodeSocketType distnoise_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
|
|
{ SOCK_VALUE, 1, "Distortion", 1.00f, 0.0f, 0.0f, 0.0f, 0.0000f, 10.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
|
{
|
|
tex->noisesize = tex_input_value(in[I+0], p, thread);
|
|
tex->dist_amount = tex_input_value(in[I+1], p, thread);
|
|
}
|
|
ProcDef(distnoise)
|
|
|
|
/* --- WOOD --- */
|
|
static bNodeSocketType wood_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
|
|
{ SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
|
{
|
|
tex->noisesize = tex_input_value(in[I+0], p, thread);
|
|
tex->turbul = tex_input_value(in[I+1], p, thread);
|
|
}
|
|
ProcDef(wood)
|
|
|
|
/* --- MUSGRAVE --- */
|
|
static bNodeSocketType musgrave_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ SOCK_VALUE, 1, "H", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
|
|
{ SOCK_VALUE, 1, "Lacunarity", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 6.0f },
|
|
{ SOCK_VALUE, 1, "Octaves", 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 8.0f },
|
|
|
|
{ SOCK_VALUE, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 10.0f },
|
|
{ SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
|
{
|
|
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);
|
|
}
|
|
ProcDef(musgrave)
|
|
|
|
/* --- NOISE --- */
|
|
static bNodeSocketType noise_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ -1, 0, "" }
|
|
};
|
|
ProcNoInputs(noise)
|
|
ProcDef(noise)
|
|
|
|
/* --- STUCCI --- */
|
|
static bNodeSocketType stucci_inputs[]= {
|
|
COMMON_INPUTS,
|
|
{ SOCK_VALUE, 1, "Size", 0.25f, 0.0f, 0.0f, 0.0f, 0.0001f, 2.0f },
|
|
{ SOCK_VALUE, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 200.0f },
|
|
{ -1, 0, "" }
|
|
};
|
|
static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
|
|
{
|
|
tex->noisesize = tex_input_value(in[I+0], p, thread);
|
|
tex->turbul = tex_input_value(in[I+1], p, thread);
|
|
}
|
|
ProcDef(stucci)
|
|
|
|
/* --- */
|
|
|
|
static void init(bNode *node)
|
|
{
|
|
Tex *tex = MEM_callocN(sizeof(Tex), "Tex");
|
|
node->storage= tex;
|
|
|
|
default_tex(tex);
|
|
tex->type = node->type - TEX_NODE_PROC;
|
|
|
|
if(tex->type == TEX_WOOD)
|
|
tex->stype = TEX_BANDNOISE;
|
|
|
|
}
|
|
|
|
/* Node type definitions */
|
|
#define TexDef(TEXTYPE, outputs, name, Name) \
|
|
void register_node_type_tex_proc_##name(ListBase *lb) \
|
|
{ \
|
|
static bNodeType ntype; \
|
|
\
|
|
node_type_base(&ntype, TEX_NODE_PROC+TEXTYPE, Name, NODE_CLASS_TEXTURE, NODE_PREVIEW|NODE_OPTIONS, name##_inputs, outputs); \
|
|
node_type_size(&ntype, 140, 80, 140); \
|
|
node_type_init(&ntype, init); \
|
|
node_type_storage(&ntype, "Tex", node_free_standard_storage, node_copy_standard_storage); \
|
|
node_type_exec(&ntype, name##_exec); \
|
|
\
|
|
nodeRegisterType(lb, &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" );
|
|
TexDef(TEX_MARBLE, CV, marble, "Marble" );
|
|
TexDef(TEX_CLOUDS, CV, clouds, "Clouds" );
|
|
TexDef(TEX_WOOD, CV, wood, "Wood" );
|
|
TexDef(TEX_MUSGRAVE, CV, musgrave, "Musgrave" );
|
|
TexDef(TEX_NOISE, C, noise, "Noise" );
|
|
TexDef(TEX_STUCCI, CV, stucci, "Stucci" );
|
|
TexDef(TEX_DISTNOISE, CV, distnoise, "Distorted Noise" );
|