| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * ***** 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): none yet. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/nodes/shader/node_shader_util.c
 | 
					
						
							|  |  |  |  *  \ingroup nodes | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_node_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "node_shader_util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "node_exec.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ****** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void nodestack_get_vec(float *in, short type_in, bNodeStack *ns) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float *from= ns->vec; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (type_in==SOCK_FLOAT) { | 
					
						
							|  |  |  | 		if (ns->sockettype==SOCK_FLOAT) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			*in= *from; | 
					
						
							|  |  |  | 		else  | 
					
						
							|  |  |  | 			*in= 0.333333f*(from[0]+from[1]+from[2]); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	else if (type_in==SOCK_VECTOR) { | 
					
						
							|  |  |  | 		if (ns->sockettype==SOCK_FLOAT) { | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			in[0] = from[0]; | 
					
						
							|  |  |  | 			in[1] = from[0]; | 
					
						
							|  |  |  | 			in[2] = from[0]; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 			copy_v3_v3(in, from); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { /* type_in==SOCK_RGBA */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (ns->sockettype==SOCK_RGBA) { | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 			copy_v4_v4(in, from); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		else if (ns->sockettype==SOCK_FLOAT) { | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			in[0] = from[0]; | 
					
						
							|  |  |  | 			in[1] = from[0]; | 
					
						
							|  |  |  | 			in[2] = from[0]; | 
					
						
							|  |  |  | 			in[3] = 1.0f; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 			copy_v3_v3(in, from); | 
					
						
							| 
									
										
										
										
											2012-10-22 08:15:51 +00:00
										 |  |  | 			in[3] = 1.0f; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* go over all used Geometry and Texture nodes, and return a texco flag */ | 
					
						
							|  |  |  | /* no group inside needed, this function is called for groups too */ | 
					
						
							|  |  |  | void ntreeShaderGetTexcoMode(bNodeTree *ntree, int r_mode, short *texco, int *mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNode *node; | 
					
						
							|  |  |  | 	bNodeSocket *sock; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	for (node= ntree->nodes.first; node; node= node->next) { | 
					
						
							|  |  |  | 		if (node->type==SH_NODE_TEXTURE) { | 
					
						
							|  |  |  | 			if ((r_mode & R_OSA) && node->id) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 				Tex *tex= (Tex *)node->id; | 
					
						
							| 
									
										
										
										
											2012-05-29 10:21:07 +00:00
										 |  |  | 				if (ELEM(tex->type, TEX_IMAGE, TEX_ENVMAP)) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 					*texco |= TEXCO_OSA|NEED_UV; | 
					
						
							| 
									
										
										
										
											2012-03-25 22:35:18 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			/* usability exception... without input we still give the node orcos */ | 
					
						
							|  |  |  | 			sock= node->inputs.first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (sock==NULL || sock->link==NULL) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 				*texco |= TEXCO_ORCO|NEED_UV; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		else if (node->type==SH_NODE_GEOMETRY) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 			/* note; sockets always exist for the given type! */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { | 
					
						
							|  |  |  | 				if (sock->flag & SOCK_IN_USE) { | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 					switch (a) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case GEOM_OUT_GLOB:  | 
					
						
							|  |  |  | 							*texco |= TEXCO_GLOB|NEED_UV; break; | 
					
						
							|  |  |  | 						case GEOM_OUT_VIEW:  | 
					
						
							|  |  |  | 							*texco |= TEXCO_VIEW|NEED_UV; break; | 
					
						
							|  |  |  | 						case GEOM_OUT_ORCO:  | 
					
						
							|  |  |  | 							*texco |= TEXCO_ORCO|NEED_UV; break; | 
					
						
							|  |  |  | 						case GEOM_OUT_UV:  | 
					
						
							|  |  |  | 							*texco |= TEXCO_UV|NEED_UV; break; | 
					
						
							|  |  |  | 						case GEOM_OUT_NORMAL:  | 
					
						
							|  |  |  | 							*texco |= TEXCO_NORM|NEED_UV; break; | 
					
						
							|  |  |  | 						case GEOM_OUT_VCOL: | 
					
						
							|  |  |  | 							*texco |= NEED_UV; *mode |= MA_VERTEXCOL; break; | 
					
						
							| 
									
										
										
										
											2011-09-20 17:51:04 +00:00
										 |  |  | 						case GEOM_OUT_VCOL_ALPHA: | 
					
						
							|  |  |  | 							*texco |= NEED_UV; *mode |= MA_VERTEXCOL; break; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* nodes that use ID data get synced with local data */ | 
					
						
							|  |  |  | void nodeShaderSynchronizeID(bNode *node, int copyto) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (node->id==NULL) return; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		bNodeSocket *sock; | 
					
						
							|  |  |  | 		Material *ma= (Material *)node->id; | 
					
						
							|  |  |  | 		int a; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 		/* hrmf, case in loop isn't super fast, but we don't edit 100s of material at same time either! */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		for (a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { | 
					
						
							|  |  |  | 			if (!nodeSocketIsHidden(sock)) { | 
					
						
							|  |  |  | 				if (copyto) { | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 					switch (a) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case MAT_IN_COLOR: | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 							copy_v3_v3(&ma->r, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case MAT_IN_SPEC: | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 							copy_v3_v3(&ma->specr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case MAT_IN_REFL: | 
					
						
							|  |  |  | 							ma->ref= ((bNodeSocketValueFloat*)sock->default_value)->value; break; | 
					
						
							|  |  |  | 						case MAT_IN_MIR: | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 							copy_v3_v3(&ma->mirr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case MAT_IN_AMB: | 
					
						
							|  |  |  | 							ma->amb= ((bNodeSocketValueFloat*)sock->default_value)->value; break; | 
					
						
							|  |  |  | 						case MAT_IN_EMIT: | 
					
						
							|  |  |  | 							ma->emit= ((bNodeSocketValueFloat*)sock->default_value)->value; break; | 
					
						
							|  |  |  | 						case MAT_IN_SPECTRA: | 
					
						
							|  |  |  | 							ma->spectra= ((bNodeSocketValueFloat*)sock->default_value)->value; break; | 
					
						
							|  |  |  | 						case MAT_IN_RAY_MIRROR: | 
					
						
							|  |  |  | 							ma->ray_mirror= ((bNodeSocketValueFloat*)sock->default_value)->value; break; | 
					
						
							|  |  |  | 						case MAT_IN_ALPHA: | 
					
						
							|  |  |  | 							ma->alpha= ((bNodeSocketValueFloat*)sock->default_value)->value; break; | 
					
						
							|  |  |  | 						case MAT_IN_TRANSLUCENCY: | 
					
						
							|  |  |  | 							ma->translucency= ((bNodeSocketValueFloat*)sock->default_value)->value; break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 					switch (a) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case MAT_IN_COLOR: | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 							copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->r); break; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case MAT_IN_SPEC: | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 							copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->specr); break; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case MAT_IN_REFL: | 
					
						
							|  |  |  | 							((bNodeSocketValueFloat*)sock->default_value)->value= ma->ref; break; | 
					
						
							|  |  |  | 						case MAT_IN_MIR: | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 							copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->mirr); break; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 						case MAT_IN_AMB: | 
					
						
							|  |  |  | 							((bNodeSocketValueFloat*)sock->default_value)->value= ma->amb; break; | 
					
						
							|  |  |  | 						case MAT_IN_EMIT: | 
					
						
							|  |  |  | 							((bNodeSocketValueFloat*)sock->default_value)->value= ma->emit; break; | 
					
						
							|  |  |  | 						case MAT_IN_SPECTRA: | 
					
						
							|  |  |  | 							((bNodeSocketValueFloat*)sock->default_value)->value= ma->spectra; break; | 
					
						
							|  |  |  | 						case MAT_IN_RAY_MIRROR: | 
					
						
							|  |  |  | 							((bNodeSocketValueFloat*)sock->default_value)->value= ma->ray_mirror; break; | 
					
						
							|  |  |  | 						case MAT_IN_ALPHA: | 
					
						
							|  |  |  | 							((bNodeSocketValueFloat*)sock->default_value)->value= ma->alpha; break; | 
					
						
							|  |  |  | 						case MAT_IN_TRANSLUCENCY: | 
					
						
							|  |  |  | 							((bNodeSocketValueFloat*)sock->default_value)->value= ma->translucency; break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	memset(gs, 0, sizeof(*gs)); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-11-06 16:23:28 +00:00
										 |  |  | 	copy_v4_v4(gs->vec, ns->vec); | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	gs->link= ns->data; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (type == SOCK_FLOAT) | 
					
						
							|  |  |  | 		gs->type= GPU_FLOAT; | 
					
						
							|  |  |  | 	else if (type == SOCK_VECTOR) | 
					
						
							|  |  |  | 		gs->type= GPU_VEC3; | 
					
						
							|  |  |  | 	else if (type == SOCK_RGBA) | 
					
						
							|  |  |  | 		gs->type= GPU_VEC4; | 
					
						
							| 
									
										
										
										
											2011-11-02 18:55:32 +00:00
										 |  |  | 	else if (type == SOCK_SHADER) | 
					
						
							|  |  |  | 		gs->type= GPU_VEC4; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		gs->type= GPU_NONE; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	gs->name = ""; | 
					
						
							|  |  |  | 	gs->hasinput= ns->hasinput && ns->data; | 
					
						
							| 
									
										
										
										
											2012-07-16 23:23:33 +00:00
										 |  |  | 	/* XXX Commented out the ns->data check here, as it seems it's not always set,
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:38:23 +00:00
										 |  |  | 	 *     even though there *is* a valid connection/output... But that might need | 
					
						
							|  |  |  | 	 *     further investigation. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	gs->hasoutput= ns->hasoutput /*&& ns->data*/; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 	gs->sockettype= ns->sockettype; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void node_data_from_gpu_stack(bNodeStack *ns, GPUNodeStack *gs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ns->data= gs->link; | 
					
						
							|  |  |  | 	ns->sockettype= gs->sockettype; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void gpu_stack_from_data_list(GPUNodeStack *gs, ListBase *sockets, bNodeStack **ns) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNodeSocket *sock; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (sock=sockets->first, i=0; sock; sock=sock->next, i++) | 
					
						
							|  |  |  | 		node_gpu_stack_from_data(&gs[i], sock->type, ns[i]); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	gs[i].type= GPU_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void data_from_gpu_stack_list(ListBase *sockets, bNodeStack **ns, GPUNodeStack *gs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNodeSocket *sock; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (sock=sockets->first, i=0; sock; sock=sock->next, i++) | 
					
						
							|  |  |  | 		node_data_from_gpu_stack(ns[i], &gs[i]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-08 13:07:16 +00:00
										 |  |  | bNode *nodeGetActiveTexture(bNodeTree *ntree) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* this is the node we texture paint and draw in textured draw */ | 
					
						
							|  |  |  | 	bNode *node; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (!ntree) | 
					
						
							| 
									
										
										
										
											2011-11-08 13:07:16 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* check for group edit */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	for (node= ntree->nodes.first; node; node= node->next) | 
					
						
							|  |  |  | 		if (node->flag & NODE_GROUP_EDIT) | 
					
						
							| 
									
										
										
										
											2011-11-08 13:07:16 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (node) | 
					
						
							| 
									
										
										
										
											2011-11-08 13:07:16 +00:00
										 |  |  | 		ntree= (bNodeTree*)node->id; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	for (node= ntree->nodes.first; node; node= node->next) | 
					
						
							|  |  |  | 		if (node->flag & NODE_ACTIVE_TEXTURE) | 
					
						
							| 
									
										
										
										
											2011-11-08 13:07:16 +00:00
										 |  |  | 			return node; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bNodeExec *nodeexec; | 
					
						
							|  |  |  | 	bNode *node; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | 	bNodeStack *stack; | 
					
						
							|  |  |  | 	bNodeStack *nsin[MAX_SOCKET];	/* arbitrary... watch this */ | 
					
						
							|  |  |  | 	bNodeStack *nsout[MAX_SOCKET];	/* arbitrary... watch this */ | 
					
						
							|  |  |  | 	GPUNodeStack gpuin[MAX_SOCKET+1], gpuout[MAX_SOCKET+1]; | 
					
						
							| 
									
										
										
										
											2012-05-19 13:28:19 +00:00
										 |  |  | 	int do_it; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	stack= exec->stack; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	for (n=0, nodeexec= exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		node = nodeexec->node; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2012-05-19 13:28:19 +00:00
										 |  |  | 		do_it = FALSE; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		/* for groups, only execute outputs for edited group */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (node->typeinfo->nclass==NODE_CLASS_OUTPUT) { | 
					
						
							|  |  |  | 			if (do_outputs && (node->flag & NODE_DO_OUTPUT)) | 
					
						
							| 
									
										
										
										
											2012-05-19 13:28:19 +00:00
										 |  |  | 				do_it = TRUE; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2012-05-19 13:28:19 +00:00
										 |  |  | 			do_it = TRUE; | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-19 13:28:19 +00:00
										 |  |  | 		if (do_it) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (node->typeinfo->gpufunc) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 				node_get_stack(node, stack, nsin, nsout); | 
					
						
							|  |  |  | 				gpu_stack_from_data_list(gpuin, &node->inputs, nsin); | 
					
						
							|  |  |  | 				gpu_stack_from_data_list(gpuout, &node->outputs, nsout); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (node->typeinfo->gpufunc(mat, node, gpuin, gpuout)) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 					data_from_gpu_stack_list(&node->outputs, nsout, gpuout); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			else if (node->typeinfo->gpuextfunc) { | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 				node_get_stack(node, stack, nsin, nsout); | 
					
						
							|  |  |  | 				gpu_stack_from_data_list(gpuin, &node->inputs, nsin); | 
					
						
							|  |  |  | 				gpu_stack_from_data_list(gpuout, &node->outputs, nsout); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (node->typeinfo->gpuextfunc(mat, node, nodeexec->data, gpuin, gpuout)) | 
					
						
							| 
									
										
										
										
											2011-09-05 21:01:50 +00:00
										 |  |  | 					data_from_gpu_stack_list(&node->outputs, nsout, gpuout); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-11-08 11:38:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *UNUSED(out)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	NodeTexBase *base= node->storage; | 
					
						
							|  |  |  | 	TexMapping *texmap= &base->tex_mapping; | 
					
						
							|  |  |  | 	float domin= (texmap->flag & TEXMAP_CLIP_MIN) != 0; | 
					
						
							|  |  |  | 	float domax= (texmap->flag & TEXMAP_CLIP_MAX) != 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (domin || domax || !(texmap->flag & TEXMAP_UNIT_MATRIX)) { | 
					
						
							| 
									
										
										
										
											2011-11-08 11:38:16 +00:00
										 |  |  | 		GPUNodeLink *tmat = GPU_uniform((float*)texmap->mat); | 
					
						
							|  |  |  | 		GPUNodeLink *tmin = GPU_uniform(texmap->min); | 
					
						
							|  |  |  | 		GPUNodeLink *tmax = GPU_uniform(texmap->max); | 
					
						
							|  |  |  | 		GPUNodeLink *tdomin = GPU_uniform(&domin); | 
					
						
							|  |  |  | 		GPUNodeLink *tdomax = GPU_uniform(&domax); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		GPU_link(mat, "mapping", in[0].link, tmat, tmin, tmax, tdomin, tdomax, &in[0].link); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |