diff options
Diffstat (limited to 'intern/cycles/render/mesh.cpp')
-rw-r--r-- | intern/cycles/render/mesh.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 74ea3c94593..b6f3cb3502b 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -20,9 +20,11 @@ #include "camera.h" #include "curves.h" #include "device.h" +#include "graph.h" #include "shader.h" #include "light.h" #include "mesh.h" +#include "nodes.h" #include "object.h" #include "scene.h" @@ -1148,6 +1150,55 @@ void MeshManager::device_update_flags(Device * /*device*/, need_flags_update = false; } +void MeshManager::device_update_displacement_images(Device *device, + DeviceScene *dscene, + Scene *scene, + Progress& progress) +{ + progress.set_status("Updating Displacement Images"); + TaskPool pool; + ImageManager *image_manager = scene->image_manager; + set<int> bump_images; + foreach(Mesh *mesh, scene->meshes) { + if(mesh->need_update) { + foreach(uint shader_index, mesh->used_shaders) { + Shader *shader = scene->shaders[shader_index]; + if(shader->graph_bump == NULL) { + continue; + } + foreach(ShaderNode* node, shader->graph_bump->nodes) { + if(node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) { + continue; + } + if(device->info.pack_images) { + /* If device requires packed images we need to update all + * images now, even if they're not used for displacement. + */ + image_manager->device_update(device, + dscene, + progress); + return; + } + ImageSlotNode *image_node = static_cast<ImageSlotNode*>(node); + int slot = image_node->slot; + if(slot != -1) { + bump_images.insert(slot); + } + } + } + } + } + foreach(int slot, bump_images) { + pool.push(function_bind(&ImageManager::device_update_slot, + image_manager, + device, + dscene, + slot, + &progress)); + } + pool.wait_work(); +} + void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) { VLOG(1) << "Total " << scene->meshes.size() << " meshes."; @@ -1170,6 +1221,21 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen } } + /* Update images needed for true displacement. */ + bool need_displacement_images = false; + foreach(Mesh *mesh, scene->meshes) { + if(mesh->need_update && + mesh->displacement_method != Mesh::DISPLACE_BUMP) + { + need_displacement_images = true; + break; + } + } + if(need_displacement_images) { + VLOG(1) << "Updating images used for true displacement."; + device_update_displacement_images(device, dscene, scene, progress); + } + /* device update */ device_free(device, dscene); |