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