Merging trunk up to revision 41245.
[blender.git] / source / blender / nodes / composite / nodes / node_composite_texture.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2006 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/nodes/composite/nodes/node_composite_texture.c
29  *  \ingroup cmpnodes
30  */
31
32
33 #include "node_composite_util.h"
34
35 /* **************** TEXTURE ******************** */
36 static bNodeSocketTemplate cmp_node_texture_in[]= {
37         {       SOCK_VECTOR, 1, "Offset",               0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 2.0f, PROP_TRANSLATION},
38         {       SOCK_VECTOR, 1, "Scale",                1.0f, 1.0f, 1.0f, 1.0f, -10.0f, 10.0f, PROP_XYZ},
39         {       -1, 0, ""       }
40 };
41 static bNodeSocketTemplate cmp_node_texture_out[]= {
42         {       SOCK_FLOAT, 0, "Value"},
43         {       SOCK_RGBA , 0, "Color"},
44         {       -1, 0, ""       }
45 };
46
47 /* called without rect allocated */
48 static void texture_procedural(CompBuf *cbuf, float *out, float xco, float yco)
49 {
50         bNode *node= cbuf->node;
51         TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
52         float vec[3], *size, nor[3]={0.0f, 0.0f, 0.0f}, col[4];
53         int retval, type= cbuf->procedural_type;
54         
55         size= cbuf->procedural_size;
56         
57         vec[0]= size[0]*(xco + cbuf->procedural_offset[0]);
58         vec[1]= size[1]*(yco + cbuf->procedural_offset[1]);
59         vec[2]= size[2]*cbuf->procedural_offset[2];
60         
61         retval= multitex_ext((Tex *)node->id, vec, NULL, NULL, 0, &texres);
62         
63         if(type==CB_VAL) {
64                 if(texres.talpha)
65                         col[0]= texres.ta;
66                 else
67                         col[0]= texres.tin;
68         }
69         else if(type==CB_RGBA) {
70                 if(texres.talpha)
71                         col[3]= texres.ta;
72                 else
73                         col[3]= texres.tin;
74                 
75                 if((retval & TEX_RGB)) {
76                         col[0]= texres.tr;
77                         col[1]= texres.tg;
78                         col[2]= texres.tb;
79                 }
80                 else col[0]= col[1]= col[2]= col[3];
81         }
82         else { 
83                 VECCOPY(col, nor);
84         }
85         
86         typecheck_compbuf_color(out, col, cbuf->type, cbuf->procedural_type);
87 }
88
89 /* texture node outputs get a small rect, to make sure all other nodes accept it */
90 /* only the pixel-processor nodes do something with it though */
91 static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
92 {
93         /* outputs: value, color, normal */
94         
95         if(node->id) {
96                 RenderData *rd= data;
97                 short sizex, sizey;
98                 
99                 /* first make the preview image */
100                 CompBuf *prevbuf= alloc_compbuf(140, 140, CB_RGBA, 1); /* alloc */
101
102                 prevbuf->rect_procedural= texture_procedural;
103                 prevbuf->node= node;
104                 VECCOPY(prevbuf->procedural_offset, in[0]->vec);
105                 VECCOPY(prevbuf->procedural_size, in[1]->vec);
106                 prevbuf->procedural_type= CB_RGBA;
107                 composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA);
108                 
109                 generate_preview(data, node, prevbuf);
110                 free_compbuf(prevbuf);
111                 
112                 /* texture procedural buffer type doesnt work well, we now render a buffer in scene size */
113                 sizex = (rd->size*rd->xsch)/100;
114                 sizey = (rd->size*rd->ysch)/100;
115                 
116                 if(out[0]->hasoutput) {
117                         CompBuf *stackbuf= alloc_compbuf(sizex, sizey, CB_VAL, 1); /* alloc */
118                         
119                         stackbuf->rect_procedural= texture_procedural;
120                         stackbuf->node= node;
121                         VECCOPY(stackbuf->procedural_offset, in[0]->vec);
122                         VECCOPY(stackbuf->procedural_size, in[1]->vec);
123                         stackbuf->procedural_type= CB_VAL;
124                         composit1_pixel_processor(node, stackbuf, stackbuf, out[0]->vec, do_copy_value, CB_VAL);
125                         stackbuf->rect_procedural= NULL;
126                         
127                         out[0]->data= stackbuf; 
128                 }
129                 if(out[1]->hasoutput) {
130                         CompBuf *stackbuf= alloc_compbuf(sizex, sizey, CB_RGBA, 1); /* alloc */
131                         
132                         stackbuf->rect_procedural= texture_procedural;
133                         stackbuf->node= node;
134                         VECCOPY(stackbuf->procedural_offset, in[0]->vec);
135                         VECCOPY(stackbuf->procedural_size, in[1]->vec);
136                         stackbuf->procedural_type= CB_RGBA;
137                         composit1_pixel_processor(node, stackbuf, stackbuf, out[0]->vec, do_copy_rgba, CB_RGBA);
138                         stackbuf->rect_procedural= NULL;
139                         
140                         out[1]->data= stackbuf;
141                 }
142         }
143 }
144
145 void register_node_type_cmp_texture(ListBase *lb)
146 {
147         static bNodeType ntype;
148
149         node_type_base(&ntype, CMP_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW);
150         node_type_socket_templates(&ntype, cmp_node_texture_in, cmp_node_texture_out);
151         node_type_size(&ntype, 120, 80, 240);
152         node_type_exec(&ntype, node_composit_exec_texture);
153
154         nodeRegisterType(lb, &ntype);
155 }
156
157
158