| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2013-08-18 14:16:15 +00:00
										 |  |  |  * Copyright 2011-2013 Blender Foundation | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-08-18 14:16:15 +00:00
										 |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-08-18 14:16:15 +00:00
										 |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-08-18 14:16:15 +00:00
										 |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "device.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "graph.h"
 | 
					
						
							|  |  |  | #include "light.h"
 | 
					
						
							|  |  |  | #include "osl.h"
 | 
					
						
							|  |  |  | #include "scene.h"
 | 
					
						
							|  |  |  | #include "shader.h"
 | 
					
						
							| 
									
										
										
										
											2013-12-31 17:30:34 +01:00
										 |  |  | #include "nodes.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef WITH_OSL
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "osl_globals.h"
 | 
					
						
							|  |  |  | #include "osl_services.h"
 | 
					
						
							|  |  |  | #include "osl_shader.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "util_foreach.h"
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | #include "util_md5.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | #include "util_path.h"
 | 
					
						
							|  |  |  | #include "util_progress.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CCL_NAMESPACE_BEGIN | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef WITH_OSL
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | /* Shared Texture and Shading System */ | 
					
						
							| 
									
										
										
										
											2013-04-04 23:48:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | OSL::TextureSystem *OSLShaderManager::ts_shared = NULL; | 
					
						
							|  |  |  | int OSLShaderManager::ts_shared_users = 0; | 
					
						
							|  |  |  | thread_mutex OSLShaderManager::ts_shared_mutex; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | OSL::ShadingSystem *OSLShaderManager::ss_shared = NULL; | 
					
						
							|  |  |  | OSLRenderServices *OSLShaderManager::services_shared = NULL; | 
					
						
							|  |  |  | int OSLShaderManager::ss_shared_users = 0; | 
					
						
							|  |  |  | thread_mutex OSLShaderManager::ss_shared_mutex; | 
					
						
							|  |  |  | thread_mutex OSLShaderManager::ss_mutex; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | /* Shader Manager */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OSLShaderManager::OSLShaderManager() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 	texture_system_init(); | 
					
						
							| 
									
										
										
										
											2013-02-14 16:11:47 +00:00
										 |  |  | 	shading_system_init(); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OSLShaderManager::~OSLShaderManager() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | 	shading_system_free(); | 
					
						
							|  |  |  | 	texture_system_free(); | 
					
						
							| 
									
										
										
										
											2013-02-14 16:11:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLShaderManager::reset(Scene *scene) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | 	shading_system_free(); | 
					
						
							| 
									
										
										
										
											2013-02-14 16:11:47 +00:00
										 |  |  | 	shading_system_init(); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(!need_update) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-01 20:26:52 +00:00
										 |  |  | 	device_free(device, dscene, scene); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-30 11:51:17 +00:00
										 |  |  | 	/* determine which shaders are in use */ | 
					
						
							|  |  |  | 	device_update_shaders_used(scene); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	/* create shaders */ | 
					
						
							|  |  |  | 	OSLGlobals *og = (OSLGlobals*)device->osl_memory(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	foreach(Shader *shader, scene->shaders) { | 
					
						
							|  |  |  | 		assert(shader->graph); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(progress.get_cancel()) return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | 		/* we can only compile one shader at the time as the OSL ShadingSytem
 | 
					
						
							|  |  |  | 		 * has a single state, but we put the lock here so different renders can | 
					
						
							|  |  |  | 		 * compile shaders alternating */ | 
					
						
							|  |  |  | 		thread_scoped_lock lock(ss_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-20 17:40:10 +00:00
										 |  |  | 		OSLCompiler compiler((void*)this, (void*)ss, scene->image_manager); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 		compiler.background = (shader == scene->shaders[scene->default_background]); | 
					
						
							|  |  |  | 		compiler.compile(og, shader); | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-18 09:36:00 +00:00
										 |  |  | 		if(shader->use_mis && shader->has_surface_emission) | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 			scene->light_manager->need_update = true; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* setup shader engine */ | 
					
						
							|  |  |  | 	og->ss = ss; | 
					
						
							| 
									
										
										
										
											2012-11-20 17:40:21 +00:00
										 |  |  | 	og->ts = ts; | 
					
						
							| 
									
										
										
										
											2012-09-03 18:51:02 +00:00
										 |  |  | 	og->services = services; | 
					
						
							| 
									
										
										
										
											2013-02-14 16:11:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	int background_id = scene->shader_manager->get_shader_id(scene->default_background); | 
					
						
							| 
									
										
										
										
											2012-09-03 18:50:59 +00:00
										 |  |  | 	og->background_state = og->surface_state[background_id & SHADER_MASK]; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	og->use = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	foreach(Shader *shader, scene->shaders) | 
					
						
							|  |  |  | 		shader->need_update = false; | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	need_update = false; | 
					
						
							| 
									
										
										
										
											2011-05-31 16:21:30 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* set texture system */ | 
					
						
							|  |  |  | 	scene->image_manager->set_osl_texture_system((void*)ts); | 
					
						
							| 
									
										
										
										
											2011-09-27 20:37:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	device_update_common(device, dscene, scene, progress); | 
					
						
							| 
									
										
										
										
											2013-06-28 13:05:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* greedyjit test
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		thread_scoped_lock lock(ss_shared_mutex); | 
					
						
							|  |  |  | 		ss->optimize_all_groups(); | 
					
						
							|  |  |  | 	}*/ | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-01 20:26:52 +00:00
										 |  |  | void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene) | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	OSLGlobals *og = (OSLGlobals*)device->osl_memory(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-01 20:26:52 +00:00
										 |  |  | 	device_free_common(device, dscene, scene); | 
					
						
							| 
									
										
										
										
											2011-09-27 20:37:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	/* clear shader engine */ | 
					
						
							|  |  |  | 	og->use = false; | 
					
						
							|  |  |  | 	og->ss = NULL; | 
					
						
							| 
									
										
										
										
											2012-11-20 17:40:21 +00:00
										 |  |  | 	og->ts = NULL; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 23:03:12 +00:00
										 |  |  | 	og->surface_state.clear(); | 
					
						
							|  |  |  | 	og->volume_state.clear(); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	og->displacement_state.clear(); | 
					
						
							|  |  |  | 	og->background_state.reset(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | void OSLShaderManager::texture_system_init() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-04-04 23:48:07 +00:00
										 |  |  | 	/* create texture system, shared between different renders to reduce memory usage */ | 
					
						
							|  |  |  | 	thread_scoped_lock lock(ts_shared_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(ts_shared_users == 0) { | 
					
						
							|  |  |  | 		ts_shared = TextureSystem::create(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ts_shared->attribute("automip",  1); | 
					
						
							|  |  |  | 		ts_shared->attribute("autotile", 64); | 
					
						
							|  |  |  | 		ts_shared->attribute("gray_to_rgb", 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* effectively unlimited for now, until we support proper mipmap lookups */ | 
					
						
							|  |  |  | 		ts_shared->attribute("max_memory_MB", 16384); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ts = ts_shared; | 
					
						
							|  |  |  | 	ts_shared_users++; | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | void OSLShaderManager::texture_system_free() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* shared texture system decrease users and destroy if no longer used */ | 
					
						
							|  |  |  | 	thread_scoped_lock lock(ts_shared_mutex); | 
					
						
							|  |  |  | 	ts_shared_users--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(ts_shared_users == 0) { | 
					
						
							|  |  |  | 		OSL::TextureSystem::destroy(ts_shared); | 
					
						
							|  |  |  | 		ts_shared = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ts = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | void OSLShaderManager::shading_system_init() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | 	/* create shading system, shared between different renders to reduce memory usage */ | 
					
						
							|  |  |  | 	thread_scoped_lock lock(ss_shared_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(ss_shared_users == 0) { | 
					
						
							|  |  |  | 		services_shared = new OSLRenderServices(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ss_shared = OSL::ShadingSystem::create(services_shared, ts_shared, &errhandler); | 
					
						
							|  |  |  | 		ss_shared->attribute("lockgeom", 1); | 
					
						
							|  |  |  | 		ss_shared->attribute("commonspace", "world"); | 
					
						
							|  |  |  | 		ss_shared->attribute("searchpath:shader", path_get("shader")); | 
					
						
							| 
									
										
										
										
											2013-06-28 13:05:21 +00:00
										 |  |  | 		//ss_shared->attribute("greedyjit", 1);
 | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* our own ray types */ | 
					
						
							|  |  |  | 		static const char *raytypes[] = { | 
					
						
							| 
									
										
										
										
											2013-12-28 01:54:44 +01:00
										 |  |  | 			"camera",			/* PATH_RAY_CAMERA */ | 
					
						
							|  |  |  | 			"reflection",		/* PATH_RAY_REFLECT */ | 
					
						
							|  |  |  | 			"refraction",		/* PATH_RAY_TRANSMIT */ | 
					
						
							|  |  |  | 			"diffuse",			/* PATH_RAY_DIFFUSE */ | 
					
						
							|  |  |  | 			"glossy",			/* PATH_RAY_GLOSSY */ | 
					
						
							|  |  |  | 			"singular",			/* PATH_RAY_SINGULAR */ | 
					
						
							|  |  |  | 			"transparent",		/* PATH_RAY_TRANSPARENT */ | 
					
						
							|  |  |  | 			"shadow",			/* PATH_RAY_SHADOW_OPAQUE */ | 
					
						
							|  |  |  | 			"shadow",			/* PATH_RAY_SHADOW_TRANSPARENT */ | 
					
						
							| 
									
										
										
										
											2013-08-18 14:15:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			"__unused__", | 
					
						
							|  |  |  | 			"__unused__", | 
					
						
							|  |  |  | 			"diffuse_ancestor", /* PATH_RAY_DIFFUSE_ANCESTOR */ | 
					
						
							|  |  |  | 			"glossy_ancestor",  /* PATH_RAY_GLOSSY_ANCESTOR */ | 
					
						
							| 
									
										
										
										
											2013-08-24 15:02:08 +00:00
										 |  |  | 			"bssrdf_ancestor",  /* PATH_RAY_BSSRDF_ANCESTOR */ | 
					
						
							| 
									
										
										
										
											2014-02-27 21:09:27 +01:00
										 |  |  | 			"__unused__",		/* PATH_RAY_SINGLE_PASS_DONE */ | 
					
						
							|  |  |  | 			"volume_scatter",	/* PATH_RAY_VOLUME_SCATTER */ | 
					
						
							| 
									
										
										
										
											2013-04-22 14:27:12 +00:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		const int nraytypes = sizeof(raytypes)/sizeof(raytypes[0]); | 
					
						
							|  |  |  | 		ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		OSLShader::register_closures((OSLShadingSystem*)ss_shared); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		loaded_shaders.clear(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ss = ss_shared; | 
					
						
							|  |  |  | 	services = services_shared; | 
					
						
							|  |  |  | 	ss_shared_users++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLShaderManager::shading_system_free() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* shared shading system decrease users and destroy if no longer used */ | 
					
						
							|  |  |  | 	thread_scoped_lock lock(ss_shared_mutex); | 
					
						
							|  |  |  | 	ss_shared_users--; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(ss_shared_users == 0) { | 
					
						
							|  |  |  | 		OSL::ShadingSystem::destroy(ss_shared); | 
					
						
							|  |  |  | 		ss_shared = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		delete services_shared; | 
					
						
							|  |  |  | 		services_shared = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ss = NULL; | 
					
						
							|  |  |  | 	services = NULL; | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool OSLShaderManager::osl_compile(const string& inputfile, const string& outputfile) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	vector<string> options; | 
					
						
							|  |  |  | 	string stdosl_path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* specify output file name */ | 
					
						
							|  |  |  | 	options.push_back("-o"); | 
					
						
							|  |  |  | 	options.push_back(outputfile); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* specify standard include path */ | 
					
						
							|  |  |  | 	options.push_back("-I" + path_get("shader")); | 
					
						
							|  |  |  | 	stdosl_path = path_get("shader/stdosl.h"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* compile */ | 
					
						
							|  |  |  | 	OSL::OSLCompiler *compiler = OSL::OSLCompiler::create(); | 
					
						
							|  |  |  | 	bool ok = compiler->compile(inputfile, options, stdosl_path); | 
					
						
							|  |  |  | 	delete compiler; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ok; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool OSLShaderManager::osl_query(OSL::OSLQuery& query, const string& filepath) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	string searchpath = path_user_get("shaders"); | 
					
						
							|  |  |  | 	return query.open(filepath, searchpath); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static string shader_filepath_hash(const string& filepath, uint64_t modified_time) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* compute a hash from filepath and modified time to detect changes */ | 
					
						
							|  |  |  | 	MD5Hash md5; | 
					
						
							|  |  |  | 	md5.append((const uint8_t*)filepath.c_str(), filepath.size()); | 
					
						
							|  |  |  | 	md5.append((const uint8_t*)&modified_time, sizeof(modified_time)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return md5.get_hex(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *OSLShaderManager::shader_test_loaded(const string& hash) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 	map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash); | 
					
						
							|  |  |  | 	return (it == loaded_shaders.end())? NULL: it->first.c_str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string& hash) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash); | 
					
						
							|  |  |  | 	return (it == loaded_shaders.end())? NULL: &it->second; | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *OSLShaderManager::shader_load_filepath(string filepath) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	size_t len = filepath.size(); | 
					
						
							|  |  |  | 	string extension = filepath.substr(len - 4); | 
					
						
							|  |  |  | 	uint64_t modified_time = path_modified_time(filepath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(extension == ".osl") { | 
					
						
							|  |  |  | 		/* .OSL File */ | 
					
						
							|  |  |  | 		string osopath = filepath.substr(0, len - 4) + ".oso"; | 
					
						
							|  |  |  | 		uint64_t oso_modified_time = path_modified_time(osopath); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* test if we have loaded the corresponding .OSO already */ | 
					
						
							|  |  |  | 		if(oso_modified_time != 0) { | 
					
						
							|  |  |  | 			const char *hash = shader_test_loaded(shader_filepath_hash(osopath, oso_modified_time)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(hash) | 
					
						
							|  |  |  | 				return hash; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* autocompile .OSL to .OSO if needed */ | 
					
						
							|  |  |  | 		if(oso_modified_time == 0 || (oso_modified_time < modified_time)) { | 
					
						
							|  |  |  | 			OSLShaderManager::osl_compile(filepath, osopath); | 
					
						
							|  |  |  | 			modified_time = path_modified_time(osopath); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			modified_time = oso_modified_time; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		filepath = osopath; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		if(extension == ".oso") { | 
					
						
							|  |  |  | 			/* .OSO File, nothing to do */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if(path_dirname(filepath) == "") { | 
					
						
							|  |  |  | 			/* .OSO File in search path */ | 
					
						
							|  |  |  | 			filepath = path_join(path_user_get("shaders"), filepath + ".oso"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			/* unknown file */ | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* test if we have loaded this .OSO already */ | 
					
						
							|  |  |  | 		const char *hash = shader_test_loaded(shader_filepath_hash(filepath, modified_time)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(hash) | 
					
						
							|  |  |  | 			return hash; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* read oso bytecode from file */ | 
					
						
							|  |  |  | 	string bytecode_hash = shader_filepath_hash(filepath, modified_time); | 
					
						
							|  |  |  | 	string bytecode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(!path_read_text(filepath, bytecode)) { | 
					
						
							|  |  |  | 		fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str()); | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 		OSLShaderInfo info; | 
					
						
							|  |  |  | 		loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */ | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return shader_load_bytecode(bytecode_hash, bytecode); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *OSLShaderManager::shader_load_bytecode(const string& hash, const string& bytecode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-05-09 14:13:43 +00:00
										 |  |  | 	ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str()); | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 	/* this is a bit weak, but works */ | 
					
						
							|  |  |  | 	OSLShaderInfo info; | 
					
						
							|  |  |  | 	info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos); | 
					
						
							|  |  |  | 	info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos); | 
					
						
							| 
									
										
										
										
											2013-04-01 20:26:52 +00:00
										 |  |  | 	info.has_surface_bssrdf = (bytecode.find("\"bssrdf\"") != string::npos); | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 	loaded_shaders[hash] = info; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return loaded_shaders.find(hash)->first.c_str(); | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | /* Graph Compiler */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-20 17:40:10 +00:00
										 |  |  | OSLCompiler::OSLCompiler(void *manager_, void *shadingsys_, ImageManager *image_manager_) | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 	manager = manager_; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	shadingsys = shadingsys_; | 
					
						
							| 
									
										
										
										
											2012-11-20 17:40:10 +00:00
										 |  |  | 	image_manager = image_manager_; | 
					
						
							| 
									
										
										
										
											2011-10-12 23:03:12 +00:00
										 |  |  | 	current_type = SHADER_TYPE_SURFACE; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	current_shader = NULL; | 
					
						
							|  |  |  | 	background = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | string OSLCompiler::id(ShaderNode *node) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* assign layer unique name based on pointer address + bump mode */ | 
					
						
							|  |  |  | 	stringstream stream; | 
					
						
							|  |  |  | 	stream << "node_" << node->name << "_" << node; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return stream.str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input) | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 	string sname(input->name); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	size_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 	/* strip whitespace */ | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	while((i = sname.find(" ")) != string::npos) | 
					
						
							|  |  |  | 		sname.replace(i, 1, ""); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 	/* if output exists with the same name, add "In" suffix */ | 
					
						
							|  |  |  | 	foreach(ShaderOutput *output, node->outputs) { | 
					
						
							|  |  |  | 		if (strcmp(input->name, output->name)==0) { | 
					
						
							|  |  |  | 			sname += "In"; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return sname; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	string sname(output->name); | 
					
						
							|  |  |  | 	size_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* strip whitespace */ | 
					
						
							|  |  |  | 	while((i = sname.find(" ")) != string::npos) | 
					
						
							|  |  |  | 		sname.replace(i, 1, ""); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-11-20 17:40:21 +00:00
										 |  |  | 	/* if input exists with the same name, add "Out" suffix */ | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 	foreach(ShaderInput *input, node->inputs) { | 
					
						
							|  |  |  | 		if (strcmp(input->name, output->name)==0) { | 
					
						
							|  |  |  | 			sname += "Out"; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	return sname; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* exception for output node, only one input is actually used
 | 
					
						
							| 
									
										
										
										
											2012-06-09 17:22:52 +00:00
										 |  |  | 	 * depending on the current shader type */ | 
					
						
							| 
									
										
										
										
											2012-11-27 16:02:12 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if(!(input->usage & ShaderInput::USE_OSL)) | 
					
						
							|  |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(node->name == ustring("output")) { | 
					
						
							| 
									
										
										
										
											2011-10-12 23:03:12 +00:00
										 |  |  | 		if(strcmp(input->name, "Surface") == 0 && current_type != SHADER_TYPE_SURFACE) | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		if(strcmp(input->name, "Volume") == 0 && current_type != SHADER_TYPE_VOLUME) | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 			return true; | 
					
						
							|  |  |  | 		if(strcmp(input->name, "Displacement") == 0 && current_type != SHADER_TYPE_DISPLACEMENT) | 
					
						
							|  |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2012-10-20 12:18:00 +00:00
										 |  |  | 		if(strcmp(input->name, "Normal") == 0) | 
					
						
							|  |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-10-20 15:09:36 +00:00
										 |  |  | 	else if(node->name == ustring("bump")) { | 
					
						
							|  |  |  | 		if(strcmp(input->name, "Height") == 0) | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	else if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->name == ustring("bump")) | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 	/* load filepath */ | 
					
						
							|  |  |  | 	if(isfilepath) { | 
					
						
							|  |  |  | 		name = ((OSLShaderManager*)manager)->shader_load_filepath(name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(name == NULL) | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	/* pass in fixed parameter values */ | 
					
						
							|  |  |  | 	foreach(ShaderInput *input, node->inputs) { | 
					
						
							|  |  |  | 		if(!input->link) { | 
					
						
							|  |  |  | 			/* checks to untangle graphs */ | 
					
						
							|  |  |  | 			if(node_skip_input(node, input)) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			/* already has default value assigned */ | 
					
						
							|  |  |  | 			else if(input->default_value != ShaderInput::NONE) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 			string param_name = compatible_name(node, input); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 			switch(input->type) { | 
					
						
							|  |  |  | 				case SHADER_SOCKET_COLOR: | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 					parameter_color(param_name.c_str(), input->value); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				case SHADER_SOCKET_POINT: | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 					parameter_point(param_name.c_str(), input->value); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				case SHADER_SOCKET_VECTOR: | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 					parameter_vector(param_name.c_str(), input->value); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				case SHADER_SOCKET_NORMAL: | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 					parameter_normal(param_name.c_str(), input->value); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				case SHADER_SOCKET_FLOAT: | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 					parameter(param_name.c_str(), input->value.x); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2012-10-20 13:11:45 +00:00
										 |  |  | 				case SHADER_SOCKET_INT: | 
					
						
							|  |  |  | 					parameter(param_name.c_str(), (int)input->value.x); | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2012-11-06 21:36:44 +00:00
										 |  |  | 				case SHADER_SOCKET_STRING: | 
					
						
							|  |  |  | 					parameter(param_name.c_str(), input->value_string); | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 				case SHADER_SOCKET_CLOSURE: | 
					
						
							| 
									
										
										
										
											2013-03-18 19:27:31 +00:00
										 |  |  | 				case SHADER_SOCKET_UNDEFINED: | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 21:02:41 +01:00
										 |  |  | 	/* create shader of the appropriate type. OSL only distinguishes between "surface"
 | 
					
						
							|  |  |  | 	 * and "displacement" atm */ | 
					
						
							| 
									
										
										
										
											2011-10-12 23:03:12 +00:00
										 |  |  | 	if(current_type == SHADER_TYPE_SURFACE) | 
					
						
							|  |  |  | 		ss->Shader("surface", name, id(node).c_str()); | 
					
						
							|  |  |  | 	else if(current_type == SHADER_TYPE_VOLUME) | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 		ss->Shader("surface", name, id(node).c_str()); | 
					
						
							|  |  |  | 	else if(current_type == SHADER_TYPE_DISPLACEMENT) | 
					
						
							| 
									
										
										
										
											2014-03-06 21:02:41 +01:00
										 |  |  | 		ss->Shader("displacement", name, id(node).c_str()); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		assert(0); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* link inputs to other nodes */ | 
					
						
							|  |  |  | 	foreach(ShaderInput *input, node->inputs) { | 
					
						
							|  |  |  | 		if(input->link) { | 
					
						
							|  |  |  | 			if(node_skip_input(node, input)) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* connect shaders */ | 
					
						
							|  |  |  | 			string id_from = id(input->link->parent); | 
					
						
							|  |  |  | 			string id_to = id(node); | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:07 +00:00
										 |  |  | 			string param_from = compatible_name(input->link->parent, input->link); | 
					
						
							|  |  |  | 			string param_to = compatible_name(node, input); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* test if we shader contains specific closures */ | 
					
						
							|  |  |  | 	OSLShaderInfo *info = ((OSLShaderManager*)manager)->shader_loaded_info(name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-29 13:03:48 +01:00
										 |  |  | 	if(info && current_type == SHADER_TYPE_SURFACE) { | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 		if(info->has_surface_emission) | 
					
						
							|  |  |  | 			current_shader->has_surface_emission = true; | 
					
						
							|  |  |  | 		if(info->has_surface_transparent) | 
					
						
							|  |  |  | 			current_shader->has_surface_transparent = true; | 
					
						
							| 
									
										
										
										
											2013-08-18 14:15:57 +00:00
										 |  |  | 		if(info->has_surface_bssrdf) { | 
					
						
							| 
									
										
										
										
											2013-04-01 20:26:52 +00:00
										 |  |  | 			current_shader->has_surface_bssrdf = true; | 
					
						
							| 
									
										
										
										
											2013-08-18 14:15:57 +00:00
										 |  |  | 			current_shader->has_bssrdf_bump = true; /* can't detect yet */ | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-12 06:51:06 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-04-04 13:20:46 +02:00
										 |  |  | 	else if(current_type == SHADER_TYPE_VOLUME) { | 
					
						
							|  |  |  | 		if(node->has_spatial_varying()) | 
					
						
							|  |  |  | 			current_shader->has_heterogeneous_volume = true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, float f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypeFloat, &f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_color(const char *name, float3 f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypeColor, &f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_point(const char *name, float3 f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypePoint, &f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_normal(const char *name, float3 f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypeNormal, &f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_vector(const char *name, float3 f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypeVector, &f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, int f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypeInt, &f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, const char *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypeString, &s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, ustring s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	const char *str = s.c_str(); | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypeString, &str); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, const Transform& tfm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	ss->Parameter(name, TypeDesc::TypeMatrix, (float*)&tfm); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-15 15:41:37 +00:00
										 |  |  | void OSLCompiler::parameter_array(const char *name, const float f[], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	TypeDesc type = TypeDesc::TypeFloat; | 
					
						
							|  |  |  | 	type.arraylen = arraylen; | 
					
						
							|  |  |  | 	ss->Parameter(name, type, f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_color_array(const char *name, const float f[][3], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	TypeDesc type = TypeDesc::TypeColor; | 
					
						
							|  |  |  | 	type.arraylen = arraylen; | 
					
						
							|  |  |  | 	ss->Parameter(name, type, f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_vector_array(const char *name, const float f[][3], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	TypeDesc type = TypeDesc::TypeVector; | 
					
						
							|  |  |  | 	type.arraylen = arraylen; | 
					
						
							|  |  |  | 	ss->Parameter(name, type, f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_normal_array(const char *name, const float f[][3], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	TypeDesc type = TypeDesc::TypeNormal; | 
					
						
							|  |  |  | 	type.arraylen = arraylen; | 
					
						
							|  |  |  | 	ss->Parameter(name, type, f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_point_array(const char *name, const float f[][3], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	TypeDesc type = TypeDesc::TypePoint; | 
					
						
							|  |  |  | 	type.arraylen = arraylen; | 
					
						
							|  |  |  | 	ss->Parameter(name, type, f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_array(const char *name, const int f[], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	TypeDesc type = TypeDesc::TypeInt; | 
					
						
							|  |  |  | 	type.arraylen = arraylen; | 
					
						
							|  |  |  | 	ss->Parameter(name, type, f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_array(const char *name, const char * const s[], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	TypeDesc type = TypeDesc::TypeString; | 
					
						
							|  |  |  | 	type.arraylen = arraylen; | 
					
						
							|  |  |  | 	ss->Parameter(name, type, s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_array(const char *name, const Transform tfm[], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 	TypeDesc type = TypeDesc::TypeMatrix; | 
					
						
							|  |  |  | 	type.arraylen = arraylen; | 
					
						
							|  |  |  | 	ss->Parameter(name, type, (const float *)tfm); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | void OSLCompiler::find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ShaderNode *node = (input->link)? input->link->parent: NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(node) { | 
					
						
							|  |  |  | 		foreach(ShaderInput *in, node->inputs) | 
					
						
							|  |  |  | 			if(!node_skip_input(node, in)) | 
					
						
							|  |  |  | 				find_dependencies(dependencies, in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dependencies.insert(node); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::generate_nodes(const set<ShaderNode*>& nodes) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	set<ShaderNode*> done; | 
					
						
							|  |  |  | 	bool nodes_done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		nodes_done = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		foreach(ShaderNode *node, nodes) { | 
					
						
							|  |  |  | 			if(done.find(node) == done.end()) { | 
					
						
							|  |  |  | 				bool inputs_done = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				foreach(ShaderInput *input, node->inputs) | 
					
						
							|  |  |  | 					if(!node_skip_input(node, input)) | 
					
						
							|  |  |  | 						if(input->link && done.find(input->link->parent) == done.end()) | 
					
						
							|  |  |  | 							inputs_done = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(inputs_done) { | 
					
						
							|  |  |  | 					node->compile(*this); | 
					
						
							|  |  |  | 					done.insert(node); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-29 13:03:48 +01:00
										 |  |  | 					if(current_type == SHADER_TYPE_SURFACE) { | 
					
						
							|  |  |  | 						if(node->has_surface_emission()) | 
					
						
							|  |  |  | 							current_shader->has_surface_emission = true; | 
					
						
							|  |  |  | 						if(node->has_surface_transparent()) | 
					
						
							|  |  |  | 							current_shader->has_surface_transparent = true; | 
					
						
							|  |  |  | 						if(node->has_surface_bssrdf()) { | 
					
						
							|  |  |  | 							current_shader->has_surface_bssrdf = true; | 
					
						
							|  |  |  | 							if(node->has_bssrdf_bump()) | 
					
						
							|  |  |  | 								current_shader->has_bssrdf_bump = true; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2013-08-18 14:15:57 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-04-04 13:20:46 +02:00
										 |  |  | 					else if(current_type == SHADER_TYPE_VOLUME) { | 
					
						
							|  |  |  | 						if(node->has_spatial_varying()) | 
					
						
							|  |  |  | 							current_shader->has_heterogeneous_volume = true; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					nodes_done = false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} while(!nodes_done); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-08 15:15:27 +01:00
										 |  |  | OSL::ShadingAttribStateRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type) | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	current_type = type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-08 15:15:27 +01:00
										 |  |  | #if OSL_LIBRARY_VERSION_CODE >= 10501
 | 
					
						
							|  |  |  | 	OSL::ShadingAttribStateRef group = ss->ShaderGroupBegin(shader->name.c_str()); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2013-06-28 13:05:21 +00:00
										 |  |  | 	ss->ShaderGroupBegin(shader->name.c_str()); | 
					
						
							| 
									
										
										
										
											2013-12-08 15:15:27 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ShaderNode *output = graph->output(); | 
					
						
							|  |  |  | 	set<ShaderNode*> dependencies; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-12 23:03:12 +00:00
										 |  |  | 	if(type == SHADER_TYPE_SURFACE) { | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 		/* generate surface shader */ | 
					
						
							| 
									
										
										
										
											2011-10-12 23:03:12 +00:00
										 |  |  | 		find_dependencies(dependencies, output->input("Surface")); | 
					
						
							|  |  |  | 		generate_nodes(dependencies); | 
					
						
							|  |  |  | 		output->compile(*this); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if(type == SHADER_TYPE_VOLUME) { | 
					
						
							|  |  |  | 		/* generate volume shader */ | 
					
						
							|  |  |  | 		find_dependencies(dependencies, output->input("Volume")); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 		generate_nodes(dependencies); | 
					
						
							|  |  |  | 		output->compile(*this); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if(type == SHADER_TYPE_DISPLACEMENT) { | 
					
						
							|  |  |  | 		/* generate displacement shader */ | 
					
						
							|  |  |  | 		find_dependencies(dependencies, output->input("Displacement")); | 
					
						
							|  |  |  | 		generate_nodes(dependencies); | 
					
						
							|  |  |  | 		output->compile(*this); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		assert(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ss->ShaderGroupEnd(); | 
					
						
							| 
									
										
										
										
											2013-12-08 15:15:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if OSL_LIBRARY_VERSION_CODE >= 10501
 | 
					
						
							|  |  |  | 	return group; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	OSL::ShadingAttribStateRef group = ss->state(); | 
					
						
							|  |  |  | 	ss->clear_state(); | 
					
						
							|  |  |  | 	return group; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::compile(OSLGlobals *og, Shader *shader) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 	if(shader->need_update) { | 
					
						
							|  |  |  | 		ShaderGraph *graph = shader->graph; | 
					
						
							|  |  |  | 		ShaderNode *output = (graph)? graph->output(): NULL; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		/* copy graph for shader with bump mapping */ | 
					
						
							|  |  |  | 		if(output->input("Surface")->link && output->input("Displacement")->link) | 
					
						
							|  |  |  | 			if(!shader->graph_bump) | 
					
						
							|  |  |  | 				shader->graph_bump = shader->graph->copy(); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		/* finalize */ | 
					
						
							|  |  |  | 		shader->graph->finalize(false, true); | 
					
						
							|  |  |  | 		if(shader->graph_bump) | 
					
						
							|  |  |  | 			shader->graph_bump->finalize(true, true); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		current_shader = shader; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		shader->has_surface = false; | 
					
						
							|  |  |  | 		shader->has_surface_emission = false; | 
					
						
							|  |  |  | 		shader->has_surface_transparent = false; | 
					
						
							| 
									
										
										
										
											2013-04-01 20:26:52 +00:00
										 |  |  | 		shader->has_surface_bssrdf = false; | 
					
						
							| 
									
										
										
										
											2013-08-18 14:15:57 +00:00
										 |  |  | 		shader->has_bssrdf_bump = false; | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		shader->has_volume = false; | 
					
						
							|  |  |  | 		shader->has_displacement = false; | 
					
						
							| 
									
										
										
										
											2014-04-04 13:20:46 +02:00
										 |  |  | 		shader->has_heterogeneous_volume = false; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		/* generate surface shader */ | 
					
						
							|  |  |  | 		if(shader->used && graph && output->input("Surface")->link) { | 
					
						
							| 
									
										
										
										
											2013-12-08 15:15:27 +01:00
										 |  |  | 			shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-08 15:15:27 +01:00
										 |  |  | 			if(shader->graph_bump) | 
					
						
							|  |  |  | 				shader->osl_surface_bump_ref = compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE); | 
					
						
							| 
									
										
										
										
											2013-06-28 13:05:21 +00:00
										 |  |  | 			else | 
					
						
							|  |  |  | 				shader->osl_surface_bump_ref = shader->osl_surface_ref; | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 			shader->has_surface = true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			shader->osl_surface_ref = OSL::ShadingAttribStateRef(); | 
					
						
							|  |  |  | 			shader->osl_surface_bump_ref = OSL::ShadingAttribStateRef(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-10-12 23:03:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		/* generate volume shader */ | 
					
						
							|  |  |  | 		if(shader->used && graph && output->input("Volume")->link) { | 
					
						
							| 
									
										
										
										
											2013-12-08 15:15:27 +01:00
										 |  |  | 			shader->osl_volume_ref = compile_type(shader, shader->graph, SHADER_TYPE_VOLUME); | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 			shader->has_volume = true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			shader->osl_volume_ref = OSL::ShadingAttribStateRef(); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 		/* generate displacement shader */ | 
					
						
							|  |  |  | 		if(shader->used && graph && output->input("Displacement")->link) { | 
					
						
							| 
									
										
										
										
											2013-12-08 15:15:27 +01:00
										 |  |  | 			shader->osl_displacement_ref = compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT); | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 			shader->has_displacement = true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			shader->osl_displacement_ref = OSL::ShadingAttribStateRef(); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 	/* push state to array for lookup */ | 
					
						
							|  |  |  | 	og->surface_state.push_back(shader->osl_surface_ref); | 
					
						
							|  |  |  | 	og->surface_state.push_back(shader->osl_surface_bump_ref); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | 	og->volume_state.push_back(shader->osl_volume_ref); | 
					
						
							|  |  |  | 	og->volume_state.push_back(shader->osl_volume_ref); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	og->displacement_state.push_back(shader->osl_displacement_ref); | 
					
						
							|  |  |  | 	og->displacement_state.push_back(shader->osl_displacement_ref); | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-03 14:32:35 +00:00
										 |  |  | void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, float f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_color(const char *name, float3 f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_vector(const char *name, float3 f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-15 18:08:51 +00:00
										 |  |  | void OSLCompiler::parameter_point(const char *name, float3 f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_normal(const char *name, float3 f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | void OSLCompiler::parameter(const char *name, int f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, const char *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, ustring s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter(const char *name, const Transform& tfm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-15 16:31:11 +00:00
										 |  |  | void OSLCompiler::parameter_array(const char *name, const float f[], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_color_array(const char *name, const float f[][3], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_vector_array(const char *name, const float f[][3], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_normal_array(const char *name, const float f[][3], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_point_array(const char *name, const float f[][3], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_array(const char *name, const int f[], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_array(const char *name, const char * const s[], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void OSLCompiler::parameter_array(const char *name, const Transform tfm[], int arraylen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-27 11:58:34 +00:00
										 |  |  | #endif /* WITH_OSL */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CCL_NAMESPACE_END | 
					
						
							|  |  |  | 
 |