Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Bishop <nicholasbishop@gmail.com>2015-01-19 22:04:27 +0300
committerNicholas Bishop <nicholasbishop@gmail.com>2015-02-06 19:19:49 +0300
commit964285c25e299589b013893be0cf9b7fe36606db (patch)
tree4b4fd52e593580fb1122b7b54d2dc1b4c96b96f0 /intern/cycles
parentc50694060db83a1a77685dbe2cb01350a7bed98d (diff)
Add Ptex support to Cycles image node, also add Ptex node
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/CMakeLists.txt5
-rw-r--r--intern/cycles/blender/blender_session.cpp21
-rw-r--r--intern/cycles/blender/blender_session.h5
-rw-r--r--intern/cycles/blender/blender_shader.cpp12
-rw-r--r--intern/cycles/kernel/kernel_textures.h3
-rw-r--r--intern/cycles/kernel/kernel_types.h1
-rw-r--r--intern/cycles/kernel/svm/svm_image.h52
-rw-r--r--intern/cycles/render/attribute.cpp5
-rw-r--r--intern/cycles/render/image.cpp133
-rw-r--r--intern/cycles/render/image.h7
-rw-r--r--intern/cycles/render/nodes.cpp244
-rw-r--r--intern/cycles/render/nodes.h26
-rw-r--r--intern/cycles/render/scene.h3
-rw-r--r--intern/cycles/util/util_types.h6
14 files changed, 499 insertions, 24 deletions
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 2ba6af48d0d..34a51957bdf 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -129,9 +129,10 @@ if(WITH_CYCLES_STANDALONE_GUI)
add_definitions(-DWITH_CYCLES_STANDALONE_GUI)
endif()
-if(WITH_CYCLES_PTEX)
+#if(WITH_CYCLES_PTEX)
add_definitions(-DWITH_PTEX)
-endif()
+ include_directories("../../extern/ptex")
+#endif()
if(WITH_CYCLES_OPENSUBDIV)
add_definitions(-DWITH_OPENSUBDIV)
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index eb3f54ae90c..db70bad4e1f 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -101,8 +101,8 @@ void BlenderSession::create_session()
scene = new Scene(scene_params, session_params.device);
/* setup callbacks for builtin image support */
- scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7);
- scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3);
+ scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7, _8);
+ scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5);
scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3);
/* create session */
@@ -927,7 +927,7 @@ int BlenderSession::builtin_image_frame(const string &builtin_name)
return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
}
-void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels)
+void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels, int &num_ptex_regions)
{
/* empty image */
is_float = false;
@@ -953,6 +953,10 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti
height = b_image.size()[1];
depth = 1;
channels = b_image.channels();
+
+ // TODO: ptex
+ is_float = false;
+ num_ptex_regions = b_image.ptex_regions().length;
}
else if(b_id.is_a(&RNA_Object)) {
/* smoke volume data */
@@ -981,7 +985,8 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti
}
}
-bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels)
+bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels,
+ PtexRegions ptex_regions, const int num_ptex_regions)
{
if(!builtin_data)
return false;
@@ -1019,6 +1024,14 @@ bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *buil
}
}
+ {
+ // TODO
+ BL::DynamicArray<int> regions = b_image.ptex_regions();
+ assert(num_ptex_regions == regions.length);
+ memcpy(ptex_regions, regions.data,
+ sizeof(**ptex_regions) * num_ptex_regions);
+ }
+
/* premultiply, byte images are always straight for blender */
unsigned char *cp = pixels;
for(int i = 0; i < width * height; i++, cp += channels) {
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 33da3076b55..0eeabdaade8 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -104,8 +104,9 @@ protected:
void do_write_update_render_tile(RenderTile& rtile, bool do_update_only);
int builtin_image_frame(const string &builtin_name);
- void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels);
- bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels);
+ void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels, int &num_ptex_regions);
+ bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels,
+ PtexRegions ptex_regions, int num_ptex_regions);
bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels);
};
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index baf79a78987..c141b9eeabd 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -577,6 +577,9 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
image->animated = b_image_node.image_user().use_auto_refresh();
image->use_alpha = b_image.use_alpha();
+ // TODO(nicholasbishop)
+ image->ptex = string_endswith(image->filename, ".ptx");
+
/* TODO(sergey): Does not work properly when we change builtin type. */
if (b_image.is_updated()) {
scene->image_manager->tag_reload_image(image->filename,
@@ -591,6 +594,15 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
node = image;
}
+ else if (b_node.is_a(&RNA_ShaderNodeTexPtex)) {
+ // TODO
+ BL::ShaderNodeTexPtex b_image_node(b_node);
+ PtexTextureNode *image = new PtexTextureNode();
+
+ image->ptex = true;
+ image->ptex_layer = b_image_node.layer_name();
+ node = image;
+ }
else if (b_node.is_a(&RNA_ShaderNodeTexEnvironment)) {
BL::ShaderNodeTexEnvironment b_env_node(b_node);
BL::Image b_image(b_env_node.image());
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 374dc6d1dd9..ca2da1fca06 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -71,6 +71,9 @@ KERNEL_TEX(float, texture_float, __lookup_table)
/* sobol */
KERNEL_TEX(uint, texture_uint, __sobol_directions)
+/* ptex */
+KERNEL_TEX(uint, texture_uint, __ptex_table)
+
/* full-float image */
KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_000)
KERNEL_IMAGE_TEX(float4, texture_image_float4, __tex_image_float_001)
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 77d3ea874d0..19452b97c30 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -534,6 +534,7 @@ typedef enum AttributeStandard {
ATTR_STD_VOLUME_FLAME,
ATTR_STD_VOLUME_HEAT,
ATTR_STD_VOLUME_VELOCITY,
+ ATTR_STD_PTEX_LAYER,
ATTR_STD_NUM,
ATTR_STD_NOT_FOUND = ~0
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index e667fc2033d..139c637bb19 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -377,7 +377,57 @@ ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *sta
co = texco_remap_square(co);
map_to_tube(&co.x, &co.y, co.x, co.y, co.z);
}
- float4 f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha);
+
+ float4 f;
+
+ // TODO
+ bool err = false;
+ if (srgb & 4) {
+ AttributeElement ae;
+ int image_attr_offset = find_attribute(kg, sd, id, &ae);
+ if(image_attr_offset == ATTR_STD_NOT_FOUND) {
+ /* Error */
+ err = true;
+ }
+ else {
+ float fid = kernel_tex_fetch(__attributes_float,
+ image_attr_offset);
+ id = (int)(fid + 0.5f);
+ }
+ }
+
+ if (err) {
+ f = make_float4(1.0f, 0.0f, 1.0f, 1.0f);
+ }
+ else if (srgb & 2) {
+ assert(co.x >= 0 && co.x <= 1);
+ assert(co.y >= 0 && co.y <= 1);
+
+ // TODO: test hacks for Ptex
+ uint face_id = (uint)(co[2] + 0.5f);
+ uint offset = kernel_tex_fetch(__ptex_table, id - /* TODO */ 1024);
+ float2 tex_size =
+ make_float2((float)kernel_tex_fetch(__ptex_table, offset + 0),
+ (float)kernel_tex_fetch(__ptex_table, offset + 1));
+ offset += 2;
+ offset += 4 * face_id;
+
+ float2 ptex_origin =
+ make_float2((float)kernel_tex_fetch(__ptex_table, offset + 0),
+ (float)kernel_tex_fetch(__ptex_table, offset + 1));
+ float2 ptex_res =
+ make_float2((float)kernel_tex_fetch(__ptex_table, offset + 2),
+ (float)kernel_tex_fetch(__ptex_table, offset + 3));
+
+ float2 ptex_uv = ptex_origin + make_float2(co.x, co.y) * ptex_res;
+ ptex_uv /= tex_size;
+
+ f = svm_image_texture(kg, id, ptex_uv.x, ptex_uv.y, srgb,
+ use_alpha);
+ }
+ else {
+ f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha);
+ }
if(stack_valid(out_offset))
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 15d7134cc55..fbd751fd778 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -230,6 +230,8 @@ const char *Attribute::standard_name(AttributeStandard std)
return "heat";
case ATTR_STD_VOLUME_VELOCITY:
return "velocity";
+ case ATTR_STD_PTEX_LAYER:
+ return "ptex_layer";
case ATTR_STD_NOT_FOUND:
case ATTR_STD_NONE:
case ATTR_STD_NUM:
@@ -375,6 +377,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_VOLUME_VELOCITY:
attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_VOXEL);
break;
+ case ATTR_STD_PTEX_LAYER:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_MESH);
+ break;
default:
assert(0);
break;
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 61a0a81d51d..3eb6bd53a19 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -27,6 +27,10 @@
#include <OSL/oslexec.h>
#endif
+#ifdef WITH_PTEX
+#include "BPX_pack.h"
+#endif
+
CCL_NAMESPACE_BEGIN
ImageManager::ImageManager()
@@ -96,7 +100,8 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data, bo
if(builtin_data) {
if(builtin_image_info_cb) {
int width, height, depth, channels;
- builtin_image_info_cb(filename, builtin_data, is_float, width, height, depth, channels);
+ int num_ptex_regions;
+ builtin_image_info_cb(filename, builtin_data, is_float, width, height, depth, channels, num_ptex_regions);
}
if(is_float)
@@ -348,7 +353,77 @@ void ImageManager::tag_reload_image(const string& filename, void *builtin_data,
}
}
-bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
+// TODO
+static PtexRegions ptex_table_reserve(DeviceScene *dscene,
+ const int texture_slot,
+ const int texture_width,
+ const int texture_height,
+ const int num_ptex_regions)
+{
+ // Simple encoding (not necessarily a good one):
+ //
+ // Two-step lookup: index is image slot, value there is an another
+ // index into same array. At that index, two ints store
+ // width/height of the whole texture. Then come 4-tuples of Ptex
+ // regions (x, y, w, h ints).
+ if (dscene->ptex_table.size() == 0) {
+ dscene->ptex_table.resize(TEX_EXTENDED_NUM_IMAGES_CPU);
+ }
+
+ uint offset = dscene->ptex_table.size();
+ uint *table_data = dscene->ptex_table.resize(offset +
+ 2 +
+ num_ptex_regions);
+ table_data[texture_slot] = offset;
+ table_data[offset] = texture_width;
+ offset++;
+ table_data[offset] = texture_height;
+ offset++;
+
+ return (PtexRegions)(&table_data[offset]);
+}
+
+struct PtexPackUcharContext {
+ uchar **pixels;
+ device_vector<uchar4> &tex_img;
+ DeviceScene *dscene;
+ int slot;
+};
+
+static BPXImageBuf *ptex_pack_uchar_cb(const struct PtexPackedLayout *layout,
+ void *c)
+{
+ PtexPackUcharContext &context = *static_cast<PtexPackUcharContext*>(c);
+ const int width = ptex_packed_layout_width(layout);
+ const int height = ptex_packed_layout_height(layout);
+ const int depth = 1;
+ (*context.pixels) = (uchar*)context.tex_img.resize(width, height, depth);
+
+ const int num_regions = BPX_packed_layout_num_regions(layout);
+ PtexRegions regions = ptex_table_reserve(context.dscene, context.slot,
+ // TODO: 4
+ width, height, num_regions*4);
+
+ for (int i = 0; i < num_regions; i++) {
+ int x, y, w, h;
+ if (ptex_packed_layout_item(layout, i, &x, &y, &w, &h)) {
+ regions[i][0] = x;
+ regions[i][1] = y;
+ regions[i][2] = w;
+ regions[i][3] = h;
+ }
+ else {
+ // TODO
+ assert(!"TODO");
+ }
+ }
+
+ return BPX_image_buf_wrap(width, height, 4, BPX_TYPE_DESC_UINT8,
+ *context.pixels);
+}
+
+bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img,
+ DeviceScene *dscene, int slot)
{
if(img->filename == "")
return false;
@@ -356,6 +431,8 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
ImageInput *in = NULL;
int width, height, depth, components;
+ bool use_ptex_file = false;
+ int num_ptex_regions = 0;
if(!img->builtin_data) {
/* load image from file through OIIO */
in = ImageInput::create(img->filename);
@@ -374,8 +451,14 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
return false;
}
- width = spec.width;
- height = spec.height;
+ if (in->format_name() == std::string("ptex")) {
+ use_ptex_file = true;
+ }
+ else {
+ width = spec.width;
+ height = spec.height;
+ }
+
depth = spec.depth;
components = spec.nchannels;
}
@@ -385,7 +468,7 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
return false;
bool is_float;
- builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components);
+ builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components, num_ptex_regions);
}
/* we only handle certain number of components */
@@ -399,9 +482,28 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
}
/* read RGBA pixels */
- uchar *pixels = (uchar*)tex_img.resize(width, height, depth);
+ uchar *pixels = NULL;
bool cmyk = false;
+ if (use_ptex_file) {
+ BPXImageBuf *packed_buf;
+ BPXImageInput *bpx_in = reinterpret_cast<BPXImageInput*>(in);
+ // TODO, subtraction
+ PtexPackUcharContext context = {&pixels, tex_img, dscene, slot - 1024};
+ packed_buf = BPX_image_buf_ptex_pack(bpx_in, ptex_pack_uchar_cb,
+ &context);
+ delete in;
+
+ if (!packed_buf) {
+ return false;
+ }
+
+ BPX_image_buf_free(packed_buf);
+ in = NULL;
+ } else {
+ pixels = (uchar*)tex_img.resize(width, height, depth);
+ }
+
if(in) {
if(depth <= 1) {
int scanlinesize = width*components*sizeof(uchar);
@@ -421,8 +523,15 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img)
in->close();
delete in;
}
- else {
- builtin_image_pixels_cb(img->filename, img->builtin_data, pixels);
+ else if (!use_ptex_file) {
+ PtexRegions ptex_regions;
+ thread_scoped_lock device_lock(device_mutex);
+ ptex_regions = ptex_table_reserve(dscene, slot - 1024, width,
+ height, num_ptex_regions);
+
+
+ builtin_image_pixels_cb(img->filename, img->builtin_data, pixels,
+ ptex_regions, num_ptex_regions);
}
if(cmyk) {
@@ -509,7 +618,8 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_
return false;
bool is_float;
- builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components);
+ int num_ptex_regions;
+ builtin_image_info_cb(img->filename, img->builtin_data, is_float, width, height, depth, components, num_ptex_regions);
}
if(components < 1 || width == 0 || height == 0) {
@@ -675,7 +785,7 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl
device->tex_free(tex_img);
}
- if(!file_load_image(img, tex_img)) {
+ if(!file_load_image(img, tex_img, dscene, slot)) {
/* on failure to load, we set a 1x1 pixels pink image */
uchar *pixels = (uchar*)tex_img.resize(1, 1);
@@ -788,6 +898,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
if(pack_images)
device_pack_images(device, dscene, progress);
+ device->tex_alloc("__ptex_table", dscene->ptex_table);
need_update = false;
}
@@ -864,9 +975,11 @@ void ImageManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->tex_image_packed);
device->tex_free(dscene->tex_image_packed_info);
+ device->tex_free(dscene->ptex_table);
dscene->tex_image_packed.clear();
dscene->tex_image_packed_info.clear();
+ dscene->ptex_table.clear();
images.clear();
float_images.clear();
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 2f5dcb6efd5..2abfd3995bf 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -73,8 +73,8 @@ public:
bool need_update;
- boost::function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &depth, int &channels)> builtin_image_info_cb;
- boost::function<bool(const string &filename, void *data, unsigned char *pixels)> builtin_image_pixels_cb;
+ boost::function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &depth, int &channels, int &num_ptex_regions)> builtin_image_info_cb;
+ boost::function<bool(const string &filename, void *data, unsigned char *pixels, PtexRegions ptex_regions, int num_ptex_regions)> builtin_image_pixels_cb;
boost::function<bool(const string &filename, void *data, float *pixels)> builtin_image_float_pixels_cb;
struct Image {
@@ -102,7 +102,8 @@ private:
void *osl_texture_system;
bool pack_images;
- bool file_load_image(Image *img, device_vector<uchar4>& tex_img);
+ bool file_load_image(Image *img, device_vector<uchar4>& tex_img,
+ DeviceScene *dscene, int slot);
bool file_load_float_image(Image *img, device_vector<float4>& tex_img);
void device_load_image(Device *device, DeviceScene *dscene, int slot, Progress *progess);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 3448209f101..4e9678e20ae 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -200,6 +200,7 @@ ImageTextureNode::ImageTextureNode()
interpolation = INTERPOLATION_LINEAR;
projection_blend = 0.0f;
animated = false;
+ ptex = false;
add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_UV);
add_output("Color", SHADER_SOCKET_COLOR);
@@ -234,6 +235,10 @@ void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attribute
}
#endif
+ if (ptex) {
+ attributes->add(ATTR_STD_PTEX_UV);
+ }
+
ShaderNode::attributes(shader, attributes);
}
@@ -243,6 +248,21 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
ShaderOutput *color_out = output("Color");
ShaderOutput *alpha_out = output("Alpha");
+ if (ptex) {
+ int attr = compiler.attribute(ATTR_STD_PTEX_UV);
+ compiler.stack_assign(vector_in);
+ compiler.add_node(NODE_ATTR, attr, vector_in->stack_offset,
+ NODE_ATTR_FLOAT3);
+ }
+
+ if (ptex) {
+ // TODO
+ // int attr = compiler.attribute(ATTR_STD_PTEX_LAYER);
+ // compiler.stack_assign(out);
+ // compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
+ // slot =
+ }
+
image_manager = compiler.image_manager;
if(is_float == -1) {
bool is_float_bool;
@@ -261,6 +281,11 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
compiler.stack_assign(vector_in);
int srgb = (is_linear || color_space != "Color")? 0: 1;
+ // TODO(nicholasbishop): clean this up of course
+ int flags = srgb;
+ if (ptex || string_endswith(filename, ".ptx")) {
+ flags |= 2;
+ }
int vector_offset = vector_in->stack_offset;
if(!tex_mapping.skip()) {
@@ -275,7 +300,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
vector_offset,
color_out->stack_offset,
alpha_out->stack_offset,
- srgb),
+ flags),
projection_enum[projection]);
}
else {
@@ -285,7 +310,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
vector_offset,
color_out->stack_offset,
alpha_out->stack_offset,
- srgb),
+ flags & 1),
__float_as_int(projection_blend));
}
@@ -364,6 +389,221 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_image_texture");
}
+PtexTextureNode::PtexTextureNode()
+: ShaderNode("ptex_texture")
+{
+ image_manager = NULL;
+ slot = -1;
+ is_float = -1;
+ is_linear = false;
+ use_alpha = true;
+ filename = "";
+ builtin_data = NULL;
+ color_space = ustring("Color");
+ projection = ustring("Flat");
+ interpolation = INTERPOLATION_LINEAR;
+ projection_blend = 0.0f;
+ animated = false;
+
+ add_input("Layer", SHADER_SOCKET_FLOAT);
+ add_input("Vector", SHADER_SOCKET_POINT);
+ add_output("Color", SHADER_SOCKET_COLOR);
+ add_output("Alpha", SHADER_SOCKET_FLOAT);
+}
+
+PtexTextureNode::~PtexTextureNode()
+{
+ // if(image_manager)
+ // image_manager->remove_image(filename, builtin_data, interpolation);
+}
+
+ShaderNode *PtexTextureNode::clone() const
+{
+ PtexTextureNode *node = new PtexTextureNode(*this);
+ node->image_manager = NULL;
+ node->slot = -1;
+ node->is_float = -1;
+ node->is_linear = false;
+ return node;
+}
+
+void PtexTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
+{
+#ifdef WITH_PTEX
+ /* todo: avoid loading other texture coordinates when using ptex,
+ * and hide texture coordinate socket in the UI */
+ if (shader->has_surface && string_endswith(filename, ".ptx")) {
+ /* ptex */
+ attributes->add(ATTR_STD_PTEX_FACE_ID);
+ attributes->add(ATTR_STD_PTEX_UV);
+ }
+#endif
+
+ attributes->add(ptex_layer);
+ attributes->add(ATTR_STD_PTEX_UV);
+
+ ShaderNode::attributes(shader, attributes);
+}
+
+void PtexTextureNode::compile(SVMCompiler& compiler)
+{
+ ShaderInput *layer_in = input("Layer");
+ ShaderInput *vector_in = input("Vector");
+ ShaderOutput *color_out = output("Color");
+ ShaderOutput *alpha_out = output("Alpha");
+ int layer_attr_id = -1;
+
+
+ {
+ // TODO
+ layer_attr_id = compiler.attribute(ptex_layer);
+ //compiler.stack_assign(layer_in);
+ // compiler.add_node(NODE_ATTR, attr, layer_in->stack_offset,
+ // NODE_ATTR_FLOAT);
+ }
+
+ {
+ int attr = compiler.attribute(ATTR_STD_PTEX_UV);
+ compiler.stack_assign(vector_in);
+ compiler.add_node(NODE_ATTR, attr, vector_in->stack_offset,
+ NODE_ATTR_FLOAT3);
+ }
+
+ image_manager = compiler.image_manager;
+
+
+
+ // if(slot != -1 && is_float == -1) {
+ // bool is_float_bool;
+ // slot = image_manager->add_image(filename, builtin_data,
+ // animated, 0, is_float_bool, is_linear,
+ // interpolation, use_alpha);
+ // is_float = (int)is_float_bool;
+ // }
+
+ if(!color_out->links.empty())
+ compiler.stack_assign(color_out);
+ if(!alpha_out->links.empty())
+ compiler.stack_assign(alpha_out);
+
+ if (true)
+ {
+ //if(slot != -1) {
+ compiler.stack_assign(layer_in);
+ compiler.stack_assign(vector_in);
+
+ int srgb = (is_linear || color_space != "Color")? 0: 1;
+ // TODO(nicholasbishop): clean this up of course
+ int flags = srgb;
+ if (ptex || string_endswith(filename, ".ptx")) {
+ flags |= 2;
+ }
+ flags |= 4;
+ int vector_offset = vector_in->stack_offset;
+
+ // if(!tex_mapping.skip()) {
+ // vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
+ // tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
+ // }
+
+ if(projection != "Box") {
+ compiler.add_node(NODE_TEX_IMAGE,
+ layer_attr_id,
+ compiler.encode_uchar4(
+ vector_offset,
+ color_out->stack_offset,
+ alpha_out->stack_offset,
+ flags),
+ ImageTextureNode::projection_enum[projection]);
+ }
+ else {
+ compiler.add_node(NODE_TEX_IMAGE_BOX,
+ slot,
+ compiler.encode_uchar4(
+ vector_offset,
+ color_out->stack_offset,
+ alpha_out->stack_offset,
+ flags & 1),
+ __float_as_int(projection_blend));
+ }
+
+ if(vector_offset != vector_in->stack_offset)
+ compiler.stack_clear_offset(vector_in->type, vector_offset);
+ }
+ else {
+ /* image not found */
+ if(!color_out->links.empty()) {
+ compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
+ compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
+ TEX_IMAGE_MISSING_G,
+ TEX_IMAGE_MISSING_B));
+ }
+ if(!alpha_out->links.empty())
+ compiler.add_node(NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), alpha_out->stack_offset);
+ }
+}
+
+void PtexTextureNode::compile(OSLCompiler& compiler)
+{
+ #if 0
+ ShaderOutput *alpha_out = output("Alpha");
+
+ tex_mapping.compile(compiler);
+
+ image_manager = compiler.image_manager;
+ if(is_float == -1) {
+ if(builtin_data == NULL) {
+ is_float = (int)image_manager->is_float_image(filename, NULL, is_linear);
+ }
+ else {
+ bool is_float_bool;
+ slot = image_manager->add_image(filename, builtin_data,
+ animated, 0, is_float_bool, is_linear,
+ interpolation, use_alpha);
+ is_float = (int)is_float_bool;
+ }
+ }
+
+ if(slot == -1) {
+ compiler.parameter("filename", filename.c_str());
+ }
+ else {
+ /* TODO(sergey): It's not so simple to pass custom attribute
+ * to the texture() function in order to make builtin images
+ * support more clear. So we use special file name which is
+ * "@<slot_number>" and check whether file name matches this
+ * mask in the OSLRenderServices::texture().
+ */
+ compiler.parameter("filename", string_printf("@%d", slot).c_str());
+ }
+ if(is_linear || color_space != "Color")
+ compiler.parameter("color_space", "Linear");
+ else
+ compiler.parameter("color_space", "sRGB");
+ compiler.parameter("projection", projection);
+ compiler.parameter("projection_blend", projection_blend);
+ compiler.parameter("is_float", is_float);
+ compiler.parameter("use_alpha", !alpha_out->links.empty());
+
+ switch (interpolation) {
+ case INTERPOLATION_CLOSEST:
+ compiler.parameter("interpolation", "closest");
+ break;
+ case INTERPOLATION_CUBIC:
+ compiler.parameter("interpolation", "cubic");
+ break;
+ case INTERPOLATION_SMART:
+ compiler.parameter("interpolation", "smart");
+ break;
+ case INTERPOLATION_LINEAR:
+ default:
+ compiler.parameter("interpolation", "linear");
+ break;
+ }
+ compiler.add(this, "node_image_texture");
+#endif
+}
+
/* Environment Texture */
static ShaderEnum env_projection_init()
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 0ec0fce512f..513fb334ff7 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -80,11 +80,37 @@ public:
InterpolationType interpolation;
float projection_blend;
bool animated;
+ bool ptex;
+ ustring ptex_layer;
static ShaderEnum color_space_enum;
static ShaderEnum projection_enum;
};
+// TODO
+class PtexTextureNode : public ShaderNode {
+public:
+ SHADER_NODE_NO_CLONE_CLASS(PtexTextureNode)
+ ~PtexTextureNode();
+ ShaderNode *clone() const;
+ void attributes(Shader *shader, AttributeRequestSet *attributes);
+
+ ImageManager *image_manager;
+ int slot;
+ int is_float;
+ bool is_linear;
+ bool use_alpha;
+ string filename;
+ void *builtin_data;
+ ustring color_space;
+ ustring projection;
+ InterpolationType interpolation;
+ float projection_blend;
+ bool animated;
+ bool ptex;
+ ustring ptex_layer;
+};
+
class EnvironmentTextureNode : public TextureNode {
public:
SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 53c3a95903c..781d0b4cb7c 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -108,6 +108,9 @@ public:
/* integrator */
device_vector<uint> sobol_directions;
+ /* ptex */
+ device_vector<uint> ptex_table;
+
/* cpu images */
device_vector<uchar4> tex_image[TEX_EXTENDED_NUM_IMAGES_CPU];
device_vector<float4> tex_float_image[TEX_EXTENDED_NUM_FLOAT_IMAGES];
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index df61b6ead21..0951684ab85 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -460,6 +460,12 @@ ccl_device_inline int4 make_int4(const float3& f)
#endif
+// TODO
+typedef uint (*PtexRegions)[4];
+struct PtexRegion {
+ int x, y, width, height;
+};
+
/* Interpolation types for textures
* cuda also use texture space to store other objects */
enum InterpolationType {