From 89cfeefab5149eb5e815740e222949c99b5525b3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 28 Nov 2013 01:38:23 +0100 Subject: [PATCH] Cycles: experimental OSL ptex reading code. This code can't actually be enabled for building and is incomplete, but it's here because we know we want to support this at some point and there's not much reason to have it in a separate branch if a simple #ifdef can disable it. --- intern/cycles/CMakeLists.txt | 4 ++ intern/cycles/kernel/osl/osl_services.cpp | 51 +++++++++++++++++++++++ intern/cycles/kernel/osl/osl_services.h | 7 ++++ intern/cycles/render/nodes.cpp | 28 +++++++++++++ intern/cycles/render/nodes.h | 2 + intern/cycles/util/util_string.cpp | 10 +++++ intern/cycles/util/util_string.h | 1 + 7 files changed, 103 insertions(+) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 9b84f882046..44b0ba808cf 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -62,6 +62,10 @@ if(WITH_CYCLES_NETWORK) add_definitions(-DWITH_NETWORK) endif() +if(WITH_CYCLES_PTEX) + add_definitions(-DWITH_PTEX) +endif() + if(WITH_CYCLES_OSL) add_definitions(-DWITH_OSL) add_definitions(-DOSL_STATIC_LIBRARY) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 309f5ded96d..d7d3301c0b0 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -44,6 +44,10 @@ #include "kernel_camera.h" #include "kernel_shader.h" +#ifdef WITH_PTEX +#include +#endif + CCL_NAMESPACE_BEGIN /* RenderServices implementation */ @@ -98,10 +102,18 @@ OSLRenderServices::OSLRenderServices() { kernel_globals = NULL; osl_ts = NULL; + +#ifdef WITH_PTEX + size_t maxmem = 16384 * 1024; + ptex_cache = PtexCache::create(0, maxmem); +#endif } OSLRenderServices::~OSLRenderServices() { +#ifdef WITH_PTEX + ptex_cache->release(); +#endif } void OSLRenderServices::thread_init(KernelGlobals *kernel_globals_, OSL::TextureSystem *osl_ts_) @@ -776,6 +788,45 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options, 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 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 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; diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index f62895047b3..21609621b1d 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -28,6 +28,10 @@ #include #include +#ifdef WITH_PTEX +class PtexCache; +#endif + CCL_NAMESPACE_BEGIN class Object; @@ -148,6 +152,9 @@ public: private: KernelGlobals *kernel_globals; OSL::TextureSystem *osl_ts; +#ifdef WITH_PTEX + PtexCache *ptex_cache; +#endif }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index daf75c81396..fcc92b641fd 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -217,6 +217,21 @@ ShaderNode *ImageTextureNode::clone() const return node; } +void ImageTextureNode::attributes(AttributeRequestSet *attributes) +{ +#ifdef WITH_PTEX + /* todo: avoid loading other texture coordinates when using ptex, + * and hide texture coordinate socket in the UI */ + if (string_endswith(filename, ".ptx")) { + /* ptex */ + attributes->add(ATTR_STD_PTEX_FACE_ID); + attributes->add(ATTR_STD_PTEX_UV); + } +#endif + + ShaderNode::attributes(attributes); +} + void ImageTextureNode::compile(SVMCompiler& compiler) { ShaderInput *vector_in = input("Vector"); @@ -352,6 +367,19 @@ ShaderNode *EnvironmentTextureNode::clone() const return node; } +void EnvironmentTextureNode::attributes(AttributeRequestSet *attributes) +{ +#ifdef WITH_PTEX + if (string_endswith(filename, ".ptx")) { + /* ptex */ + attributes->add(ATTR_STD_PTEX_FACE_ID); + attributes->add(ATTR_STD_PTEX_UV); + } +#endif + + ShaderNode::attributes(attributes); +} + void EnvironmentTextureNode::compile(SVMCompiler& compiler) { ShaderInput *vector_in = input("Vector"); diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 430c37158f4..d7a110af83b 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -66,6 +66,7 @@ public: SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode) ~ImageTextureNode(); ShaderNode *clone() const; + void attributes(AttributeRequestSet *attributes); ImageManager *image_manager; int slot; @@ -87,6 +88,7 @@ public: SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode) ~EnvironmentTextureNode(); ShaderNode *clone() const; + void attributes(AttributeRequestSet *attributes); ImageManager *image_manager; int slot; diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp index 53603c54da0..c4a81fc7190 100644 --- a/intern/cycles/util/util_string.cpp +++ b/intern/cycles/util/util_string.cpp @@ -86,5 +86,15 @@ void string_split(vector& tokens, const string& str, const string& separ tokens.push_back(token); } +bool string_endswith(const string& s, const char *end) +{ + size_t len = strlen(end); + + if(len > s.size()) + return 0; + else + return strncmp(s.c_str() + s.size() - len, end, len) == 0; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h index ee924340716..2d63a075e71 100644 --- a/intern/cycles/util/util_string.h +++ b/intern/cycles/util/util_string.h @@ -40,6 +40,7 @@ string string_printf(const char *format, ...) PRINTF_ATTRIBUTE; bool string_iequals(const string& a, const string& b); void string_split(vector& tokens, const string& str, const string& separators = "\t "); +bool string_endswith(const string& s, const char *end); CCL_NAMESPACE_END