TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring filename) { OSLTextureHandleMap::iterator it = textures.find(filename); /* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */ if (it != textures.end()) { if (it->second->type != OSLTextureHandle::OIIO) { return (TextureSystem::TextureHandle *)it->second.get(); } } /* Get handle from OpenImageIO. */ OSL::TextureSystem *ts = texture_system; TextureSystem::TextureHandle *handle = ts->get_texture_handle(filename); if (handle == NULL) { return NULL; } /* Insert new OSLTextureHandle if needed. */ if (it == textures.end()) { textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO)); it = textures.find(filename); } /* Assign OIIO texture handle and return. */ it->second->oiio_handle = handle; return (TextureSystem::TextureHandle *)it->second.get(); }
bool OSLRenderServices::get_texture_info(ustring filename, int subimage, ustring dataname, TypeDesc datatype, void *data) { OSL::TextureSystem *ts = kernel_globals->osl->ts; return ts->get_texture_info(filename, subimage, dataname, datatype, data); }
bool OSLRenderServices::environment(ustring filename, TextureOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &R, const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result) { OSL::TextureSystem *ts = osl_ts; ShaderData *sd = (ShaderData *)(sg->renderstate); KernelGlobals *kg = sd->osl_globals; OSLThreadData *tdata = kg->osl_tdata; OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info; OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info); bool status = ts->environment(th, thread_info, options, R, dRdx, dRdy, result); if(!status) { if(options.nchannels == 3 || options.nchannels == 4) { result[0] = 1.0f; result[1] = 0.0f; result[2] = 1.0f; if(options.nchannels == 4) result[3] = 1.0f; } } return status; }
bool OSLRenderServices::environment(ustring filename, TextureHandle *texture_handle, TexturePerthread *thread_info, TextureOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &R, const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, int nchannels, float *result, float *dresultds, float *dresultdt, ustring *errormessage) { OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle; OSL::TextureSystem *ts = texture_system; bool status = false; if (handle && handle->oiio_handle) { if (thread_info == NULL) { ShaderData *sd = (ShaderData *)(sg->renderstate); KernelGlobals *kernel_globals = sd->osl_globals; OSLThreadData *tdata = kernel_globals->osl_tdata; thread_info = tdata->oiio_thread_info; } status = ts->environment(handle->oiio_handle, thread_info, options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt); } else { status = ts->environment( filename, options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt); } if (!status) { if (nchannels == 3 || nchannels == 4) { result[0] = 1.0f; result[1] = 0.0f; result[2] = 1.0f; if (nchannels == 4) result[3] = 1.0f; } } else if (handle && handle->processor) { ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels); } return status; }
bool OSLRenderServices::good(TextureSystem::TextureHandle *texture_handle) { OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle; if (handle->oiio_handle) { OSL::TextureSystem *ts = texture_system; return ts->good(handle->oiio_handle); } else { return true; } }
bool OSLRenderServices::get_texture_info(OSL::ShaderGlobals *sg, ustring filename, TextureHandle *texture_handle, int subimage, ustring dataname, TypeDesc datatype, void *data) { OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle; /* No texture info for other texture types. */ if (handle && handle->type != OSLTextureHandle::OIIO) { return false; } /* Get texture info from OpenImageIO. */ OSL::TextureSystem *ts = texture_system; return ts->get_texture_info(filename, subimage, dataname, datatype, data); }
bool OSLRenderServices::environment(ustring filename, TextureOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &R, const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result) { OSL::TextureSystem *ts = kernel_globals->osl->ts; bool status = ts->environment(filename, options, R, dRdx, dRdy, result); if(!status) { if(options.nchannels == 3 || options.nchannels == 4) { result[0] = 1.0f; result[1] = 0.0f; result[2] = 1.0f; if(options.nchannels == 4) result[3] = 1.0f; } } return status; }
bool OSLRenderServices::texture(ustring filename, TextureOpt &options, OSL::ShaderGlobals *sg, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) { OSL::TextureSystem *ts = kernel_globals->osl->ts; bool status = ts->texture(filename, options, s, t, dsdx, dtdx, dsdy, dtdy, result); if(!status) { if(options.nchannels == 3 || options.nchannels == 4) { result[0] = 1.0f; result[1] = 0.0f; result[2] = 1.0f; if(options.nchannels == 4) result[3] = 1.0f; } } return status; }
bool OSLRenderServices::texture(ustring filename, TextureHandle *texture_handle, TexturePerthread *texture_thread_info, TextureOpt &options, OSL::ShaderGlobals *sg, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, int nchannels, float *result, float *dresultds, float *dresultdt, ustring *errormessage) { OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle; OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO; ShaderData *sd = (ShaderData *)(sg->renderstate); KernelGlobals *kernel_globals = sd->osl_globals; bool status = false; switch (texture_type) { case OSLTextureHandle::BEVEL: { /* Bevel shader hack. */ if (nchannels >= 3) { PathState *state = sd->osl_path_state; int num_samples = (int)s; float radius = t; float3 N = svm_bevel(kernel_globals, sd, state, radius, num_samples); result[0] = N.x; result[1] = N.y; result[2] = N.z; status = true; } break; } case OSLTextureHandle::AO: { /* AO shader hack. */ PathState *state = sd->osl_path_state; int num_samples = (int)s; float radius = t; float3 N = make_float3(dsdx, dtdx, dsdy); int flags = 0; if ((int)dtdy) { flags |= NODE_AO_INSIDE; } if ((int)options.sblur) { flags |= NODE_AO_ONLY_LOCAL; } if ((int)options.tblur) { flags |= NODE_AO_GLOBAL_RADIUS; } result[0] = svm_ao(kernel_globals, sd, N, state, radius, num_samples, flags); status = true; break; } case OSLTextureHandle::SVM: { /* Packed texture. */ float4 rgba = kernel_tex_image_interp(kernel_globals, handle->svm_slot, s, 1.0f - t); result[0] = rgba[0]; if (nchannels > 1) result[1] = rgba[1]; if (nchannels > 2) result[2] = rgba[2]; if (nchannels > 3) result[3] = rgba[3]; status = true; break; } case OSLTextureHandle::IES: { /* IES light. */ result[0] = kernel_ies_interp(kernel_globals, handle->svm_slot, s, t); status = true; break; } case OSLTextureHandle::OIIO: { /* OpenImageIO texture cache. */ OSL::TextureSystem *ts = texture_system; if (handle && handle->oiio_handle) { if (texture_thread_info == NULL) { OSLThreadData *tdata = kernel_globals->osl_tdata; texture_thread_info = tdata->oiio_thread_info; } status = ts->texture(handle->oiio_handle, texture_thread_info, options, s, t, dsdx, dtdx, dsdy, dtdy, nchannels, result, dresultds, dresultdt); } else { status = ts->texture(filename, options, s, t, dsdx, dtdx, dsdy, dtdy, nchannels, result, dresultds, dresultdt); } if (!status) { /* This might be slow, but prevents error messages leak and * other nasty stuff happening. */ ts->geterror(); } else if (handle && handle->processor) { ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels); } break; } } if (!status) { if (nchannels == 3 || nchannels == 4) { result[0] = 1.0f; result[1] = 0.0f; result[2] = 1.0f; if (nchannels == 4) result[3] = 1.0f; } } return status; }
bool OSLRenderServices::texture3d(ustring filename, TextureHandle *texture_handle, TexturePerthread *texture_thread_info, TextureOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &P, const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy, const OSL::Vec3 &dPdz, int nchannels, float *result, float *dresultds, float *dresultdt, float *dresultdr, ustring *errormessage) { OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle; OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO; bool status = false; switch (texture_type) { case OSLTextureHandle::SVM: { /* Packed texture. */ ShaderData *sd = (ShaderData *)(sg->renderstate); KernelGlobals *kernel_globals = sd->osl_globals; int slot = handle->svm_slot; float4 rgba = kernel_tex_image_interp_3d( kernel_globals, slot, P.x, P.y, P.z, INTERPOLATION_NONE); result[0] = rgba[0]; if (nchannels > 1) result[1] = rgba[1]; if (nchannels > 2) result[2] = rgba[2]; if (nchannels > 3) result[3] = rgba[3]; status = true; break; } case OSLTextureHandle::OIIO: { /* OpenImageIO texture cache. */ OSL::TextureSystem *ts = texture_system; if (handle && handle->oiio_handle) { if (texture_thread_info == NULL) { ShaderData *sd = (ShaderData *)(sg->renderstate); KernelGlobals *kernel_globals = sd->osl_globals; OSLThreadData *tdata = kernel_globals->osl_tdata; texture_thread_info = tdata->oiio_thread_info; } status = ts->texture3d(handle->oiio_handle, texture_thread_info, options, P, dPdx, dPdy, dPdz, nchannels, result, dresultds, dresultdt, dresultdr); } else { status = ts->texture3d(filename, options, P, dPdx, dPdy, dPdz, nchannels, result, dresultds, dresultdt, dresultdr); } if (!status) { /* This might be slow, but prevents error messages leak and * other nasty stuff happening. */ ts->geterror(); } else if (handle && handle->processor) { ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels); } break; } case OSLTextureHandle::IES: case OSLTextureHandle::AO: case OSLTextureHandle::BEVEL: { status = false; break; } } if (!status) { if (nchannels == 3 || nchannels == 4) { result[0] = 1.0f; result[1] = 0.0f; result[2] = 1.0f; if (nchannels == 4) result[3] = 1.0f; } } return status; }
bool OSLRenderServices::texture(ustring filename, TextureOpt &options, OSL::ShaderGlobals *sg, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, float *result) { OSL::TextureSystem *ts = osl_ts; ShaderData *sd = (ShaderData *)(sg->renderstate); KernelGlobals *kg = sd->osl_globals; #ifdef WITH_PTEX /* todo: this is just a quick hack, only works with particular files and options */ if(string_endswith(filename.string(), ".ptx")) { float2 uv; int faceid; if(!primitive_ptex(kg, sd, &uv, &faceid)) return false; float u = uv.x; float v = uv.y; float dudx = 0.0f; float dvdx = 0.0f; float dudy = 0.0f; float dvdy = 0.0f; Ptex::String error; PtexPtr<PtexTexture> r(ptex_cache->get(filename.c_str(), error)); if(!r) { //std::cerr << error.c_str() << std::endl; return false; } bool mipmaplerp = false; float sharpness = 1.0f; PtexFilter::Options opts(PtexFilter::f_bicubic, mipmaplerp, sharpness); PtexPtr<PtexFilter> f(PtexFilter::getFilter(r, opts)); f->eval(result, options.firstchannel, options.nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy); for(int c = r->numChannels(); c < options.nchannels; c++) result[c] = result[0]; return true; } #endif OSLThreadData *tdata = kg->osl_tdata; OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info; OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info); bool status = ts->texture(th, thread_info, options, s, t, dsdx, dtdx, dsdy, dtdy, result); if(!status) { if(options.nchannels == 3 || options.nchannels == 4) { result[0] = 1.0f; result[1] = 0.0f; result[2] = 1.0f; if(options.nchannels == 4) result[3] = 1.0f; } } return status; }