diff options
author | Luca Rood <dev@lucarood.com> | 2017-07-10 15:43:57 +0300 |
---|---|---|
committer | Luca Rood <dev@lucarood.com> | 2017-07-10 15:43:57 +0300 |
commit | 45897f12f8c35a455d5a33dbb9a8c0589d04e8b9 (patch) | |
tree | 13161449b27a4df1c0f9a71b3739123921fa8a37 | |
parent | d33cacf7e46deb12713e058fff4c1096f8113469 (diff) |
Fix T51931: VBO not updating when UVs are added to shader node tree
UVs need specific data in the VBO, which is not computed unless the
shaders assigned to the mesh actually use UVs. When adding UVs to the
shader, the VBOs were not being recomputed to include the required data.
This adds a DEG relation between the shader and the mesh, and recomputes
the required data if the shader changed.
Thanks Sergey, for all the DEG stuff...
9 files changed, 56 insertions, 4 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index cba0927d0f8..e6893dca928 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -406,6 +406,7 @@ enum { BKE_MESH_BATCH_DIRTY_ALL = 0, BKE_MESH_BATCH_DIRTY_SELECT, BKE_MESH_BATCH_DIRTY_NOCHECK, + BKE_MESH_BATCH_DIRTY_SHADING, }; void BKE_mesh_batch_cache_dirty(struct Mesh *me, int mode); void BKE_mesh_batch_cache_free(struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 2aa7829c9df..c3de20d7089 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -200,6 +200,8 @@ void BKE_object_eval_cloth(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *object); +void BKE_object_eval_update_shading(struct EvaluationContext *eval_ctx, + struct Object *object); void BKE_object_handle_data_update(struct EvaluationContext *eval_ctx, struct Scene *scene, diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 70e1f434388..50502115edc 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -401,3 +401,11 @@ void BKE_object_eval_cloth(EvaluationContext *UNUSED(eval_ctx), Scene *scene, Ob DEBUG_PRINT("%s on %s\n", __func__, object->id.name); BKE_ptcache_object_reset(scene, object, PTCACHE_RESET_DEPSGRAPH); } + +void BKE_object_eval_update_shading(EvaluationContext *UNUSED(eval_ctx), Object *object) +{ + DEBUG_PRINT("%s on %s\n", __func__, object->id.name); + if (object->type == OB_MESH) { + BKE_mesh_batch_cache_dirty(object->data, BKE_MESH_BATCH_DIRTY_SHADING); + } +} diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 1fc107f0437..1f8b3ebaa74 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -781,10 +781,19 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) } /* materials */ - for (int a = 1; a <= ob->totcol; a++) { - Material *ma = give_current_material(ob, a); - if (ma != NULL) { - build_material(ma); + if (ob->totcol != 0) { + if (ob->type == OB_MESH) { + add_operation_node(&ob->id, + DEG_NODE_TYPE_SHADING, + function_bind(BKE_object_eval_update_shading, _1, ob), + DEG_OPCODE_SHADING); + } + + for (int a = 1; a <= ob->totcol; a++) { + Material *ma = give_current_material(ob, a); + if (ma != NULL) { + build_material(ma); + } } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 384dbc628ba..2665f28ee94 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1448,6 +1448,15 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje Material *ma = give_current_material(ob, a); if (ma != NULL) { build_material(ma); + + if (ob->type == OB_MESH) { + OperationKey material_key(&ma->id, + DEG_NODE_TYPE_SHADING, + DEG_OPCODE_PLACEHOLDER, + "Material Update"); + OperationKey shading_key(&ob->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_SHADING); + add_relation(material_key, shading_key, "Material Update"); + } } } } diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index bb75a85eea4..eab1913727d 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -129,6 +129,8 @@ static const char *stringify_opcode(eDepsOperation_Code opcode) STRINGIFY_OPCODE(COPY_ON_WRITE); + STRINGIFY_OPCODE(SHADING); + case DEG_NUM_OPCODES: return "SpecialCase"; #undef STRINGIFY_OPCODE } diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index 737452549ec..15b6f9bd00e 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -217,6 +217,9 @@ typedef enum eDepsOperation_Code { /* Copy on Write ------------------------- */ DEG_OPCODE_COPY_ON_WRITE, + /* Shading operations ------------------------- */ + DEG_OPCODE_SHADING, + DEG_NUM_OPCODES, } eDepsOperation_Code; diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index 548911dcfa9..07aae7e15c4 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -239,6 +239,14 @@ void IDDepsNode::tag_update(Depsgraph *graph) do_component_tag = true; } } + else if (comp_node->type == DEG_NODE_TYPE_SHADING) { + /* TODO(sergey): For until we properly handle granular flags for DEG_id_tag_update() + * we skip flushing here to keep Luca happy. + */ + if (GS(id_orig->name) != ID_MA) { + do_component_tag = false; + } + } if (do_component_tag) { comp_node->tag_update(graph); } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 495e72fc9ac..66a946ef4a1 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -1598,6 +1598,16 @@ void DRW_mesh_batch_cache_dirty(Mesh *me, int mode) case BKE_MESH_BATCH_DIRTY_NOCHECK: cache->is_really_dirty = true; break; + case BKE_MESH_BATCH_DIRTY_SHADING: + GWN_VERTBUF_DISCARD_SAFE(cache->shaded_triangles_data); + if (cache->shaded_triangles) { + for (int i = 0; i < cache->mat_len; ++i) { + GWN_BATCH_DISCARD_SAFE(cache->shaded_triangles[i]); + } + } + + MEM_SAFE_FREE(cache->shaded_triangles); + break; default: BLI_assert(0); } |