DwM: Option to use final material over mode shading
authorCampbell Barton <ideasman42@gmail.com>
Wed, 12 Jul 2017 14:27:06 +0000 (00:27 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 12 Jul 2017 15:59:44 +0000 (01:59 +1000)
Support using full material shading in sculpt & paint modes mode.

Access 'Full Shading' from the display panel when in paint modes.

16 files changed:
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/paint.c
source/blender/draw/engines/clay/clay_engine.c
source/blender/draw/engines/eevee/eevee_engine.c
source/blender/draw/engines/eevee/eevee_materials.c
source/blender/draw/intern/DRW_render.h
source/blender/draw/intern/draw_cache.c
source/blender/draw/intern/draw_cache.h
source/blender/draw/intern/draw_cache_impl.h
source/blender/draw/intern/draw_cache_impl_mesh.c
source/blender/draw/intern/draw_manager.c
source/blender/draw/modes/paint_texture_mode.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesrna/intern/rna_space.c

index b3792686fc49f6cf121d4af485aba27495710565..cac7066f76275ab9ad490cd335f816cfaa8534ae 100644 (file)
@@ -3266,6 +3266,9 @@ class VIEW3D_PT_view3d_display(Panel):
         col.prop(view, "show_only_render")
         col.prop(view, "show_world")
 
+        if context.mode in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE', 'SCULPT'}:
+            col.prop(view, "show_mode_shade_override")
+
         col = layout.column()
         display_all = not view.show_only_render
         col.active = display_all
index e6893dca928bfc065ed3221b56a41bf0079bf441..9a94b9513f4b821b335c094357df1d450a9cc6cf 100644 (file)
@@ -407,6 +407,7 @@ enum {
        BKE_MESH_BATCH_DIRTY_SELECT,
        BKE_MESH_BATCH_DIRTY_NOCHECK,
        BKE_MESH_BATCH_DIRTY_SHADING,
+       BKE_MESH_BATCH_DIRTY_SCULPT_COORDS,
 };
 void BKE_mesh_batch_cache_dirty(struct Mesh *me, int mode);
 void BKE_mesh_batch_cache_free(struct Mesh *me);
index 00efa4aa7326a1ae0a72f1be1c285209bb1b79e8..c798a1587ee85d187ffacfd529768c35f3b6d023 100644 (file)
@@ -929,6 +929,9 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
                        }
                }
        }
+
+       /* 2.8x - avoid full mesh update! */
+       BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS);
 }
 
 int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
index 00cc93a9db23039e2bbafa01fbd31c1e9b853923..61edc7fa318181d3eb24f937a2cacbda40590085 100644 (file)
@@ -771,7 +771,7 @@ static void CLAY_cache_populate(void *vedata, Object *ob)
        const DRWContextState *draw_ctx = DRW_context_state_get();
        const bool is_active = (ob == draw_ctx->obact);
        if (is_active) {
-               if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
+               if (DRW_object_is_mode_shade(ob) == true) {
                        return;
                }
        }
index dd45d87b6e10166677ec353f0d0b85763cdf2c91..1f178fb1302a556c20d6b747605582eda81fbadb 100644 (file)
@@ -86,7 +86,7 @@ static void EEVEE_cache_populate(void *vedata, Object *ob)
        const DRWContextState *draw_ctx = DRW_context_state_get();
        const bool is_active = (ob == draw_ctx->obact);
        if (is_active) {
-               if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
+               if (DRW_object_is_mode_shade(ob) == true) {
                        return;
                }
        }
index 57015e8a58243d61194400c60f1e8773b403cbc5..8b94ffb34c36544a38dfa6a70bba94033f15f56c 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "DNA_world_types.h"
 #include "DNA_modifier_types.h"
+#include "DNA_view3d_types.h"
 
 #include "BLI_dynstr.h"
 #include "BLI_ghash.h"
@@ -719,7 +720,7 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
 }
 
 #define ADD_SHGROUP_CALL(shgrp, ob, geom) do { \
-       if (is_sculpt_mode) { \
+       if (is_sculpt_mode_draw) { \
                DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat); \
        } \
        else { \
@@ -927,11 +928,12 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
        const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
        const bool is_active = (ob == draw_ctx->obact);
        const bool is_sculpt_mode = is_active && (ob->mode & OB_MODE_SCULPT) != 0;
+       const bool is_sculpt_mode_draw = is_sculpt_mode && (draw_ctx->v3d->flag2 & V3D_SHOW_MODE_SHADE_OVERRIDE) == 0;
        const bool is_default_mode_shader = is_sculpt_mode;
 
        /* First get materials for this mesh. */
        if (ELEM(ob->type, OB_MESH)) {
-               const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
+               const int materials_len = MAX2(1, (is_sculpt_mode_draw ? 1 : ob->totcol));
 
                struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len);
                struct DRWShadingGroup **shgrp_depth_array = BLI_array_alloca(shgrp_depth_array, materials_len);
@@ -943,13 +945,20 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
                bool use_flat_nor = false;
 
                if (is_default_mode_shader) {
-                       if (is_sculpt_mode) {
+                       if (is_sculpt_mode_draw) {
                                use_flat_nor = DRW_object_is_flat_normal(ob);
                        }
                }
 
                for (int i = 0; i < materials_len; ++i) {
-                       Material *ma = give_current_material(ob, i + 1);
+                       Material *ma;
+
+                       if (is_sculpt_mode_draw) {
+                               ma = NULL;
+                       }
+                       else {
+                               ma = give_current_material(ob, i + 1);
+                       }
 
                        gpumat_array[i] = NULL;
                        gpumat_depth_array[i] = NULL;
@@ -980,6 +989,10 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
                        }
                }
 
+               if (is_sculpt_mode && is_sculpt_mode_draw == false) {
+                       DRW_cache_mesh_sculpt_coords_ensure(ob);
+               }
+
                /* Get per-material split surface */
                struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
                if (mat_geom) {
index 51145b15237c4fa44be252d6117e6f561a0714f1..ee1e14f88985880bfc1334d566e962e201f9399e 100644 (file)
@@ -356,7 +356,8 @@ void DRW_lamp_engine_data_free(struct LampEngineData *led);
 
 /* Settings */
 bool DRW_object_is_renderable(struct Object *ob);
-bool DRW_object_is_flat_normal(struct Object *ob);
+bool DRW_object_is_flat_normal(const struct Object *ob);
+int  DRW_object_is_mode_shade(const struct Object *ob);
 
 /* Draw commands */
 void DRW_draw_pass(DRWPass *pass);
index b62559fdb0ec7666b405a4211a0cd7a4cec7a740..c0338de3d54d27040a1b3e2013da5348065ca530 100644 (file)
@@ -2287,6 +2287,14 @@ Gwn_Batch *DRW_cache_mesh_verts_weight_overlay_get(Object *ob)
        return DRW_mesh_batch_cache_get_weight_overlay_verts(me);
 }
 
+void DRW_cache_mesh_sculpt_coords_ensure(Object *ob)
+{
+       BLI_assert(ob->type == OB_MESH);
+
+       Mesh *me = ob->data;
+       DRW_mesh_cache_sculpt_coords_ensure(me);
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
index 21fa652778be0892baf97393f947c2fc6f7f5041..ac7062b3cc8a72a2df86575193be999c97527fd3 100644 (file)
@@ -125,6 +125,8 @@ struct Gwn_Batch **DRW_cache_mesh_surface_shaded_get(
 struct Gwn_Batch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
 
+void DRW_cache_mesh_sculpt_coords_ensure(struct Object *ob);
+
 /* Curve */
 struct Gwn_Batch *DRW_cache_curve_surface_get(struct Object *ob);
 struct Gwn_Batch *DRW_cache_curve_surface_verts_get(struct Object *ob);
index 9328f6f63145ff2998760f61bb01b655bad378d5..f8feeb37b82987db9b0bba41b45be8e2b923b143 100644 (file)
@@ -96,6 +96,8 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(struct Mesh *
 struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me);
 struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_facedots(struct Mesh *me);
 
+void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
+
 /* Particles */
 struct Gwn_Batch *DRW_particles_batch_cache_get_hair(struct ParticleSystem *psys, struct ModifierData *md);
 struct Gwn_Batch *DRW_particles_batch_cache_get_dots(struct ParticleSystem *psys);
index ae0e62809bb9b58fa903f6fe4f4b2898ea0f619a..f48d739f11ba0cd67bc11face8d27f9fbae4c910 100644 (file)
@@ -1494,6 +1494,9 @@ typedef struct MeshBatchCache {
        int vert_len;
        int mat_len;
        bool is_editmode;
+
+       /* XXX, only keep for as long as sculpt mode uses shaded drawing. */
+       bool is_sculpt_points_tag;
 } MeshBatchCache;
 
 /* Gwn_Batch cache management. */
@@ -1603,6 +1606,9 @@ void DRW_mesh_batch_cache_dirty(Mesh *me, int mode)
                         * and not free the entire cache. */
                        cache->is_really_dirty = true;
                        break;
+               case BKE_MESH_BATCH_DIRTY_SCULPT_COORDS:
+                       cache->is_sculpt_points_tag = true;
+                       break;
                default:
                        BLI_assert(0);
        }
@@ -3433,6 +3439,34 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(Mesh *me)
        return cache->overlay_weight_verts;
 }
 
+/**
+ * Needed for when we draw with shaded data.
+ */
+void DRW_mesh_cache_sculpt_coords_ensure(Mesh *me)
+{
+       if (me->batch_cache) {
+               MeshBatchCache *cache = mesh_batch_cache_get(me);
+               if (cache && cache->pos_with_normals && cache->is_sculpt_points_tag) {
+
+                       const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
+                       MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+                       Gwn_VertBuf *pos_with_normals = cache->pos_with_normals;
+                       cache->pos_with_normals = NULL;
+                       GWN_vertbuf_clear(pos_with_normals);
+                       Gwn_VertBuf *vbo = mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+                       *pos_with_normals = *vbo;
+                       GWN_vertformat_copy(&pos_with_normals->format, &vbo->format);
+
+                       free(vbo);
+                       cache->pos_with_normals = pos_with_normals;
+
+                       mesh_render_data_free(rdata);
+               }
+               cache->is_sculpt_points_tag = false;
+       }
+}
+
 /** \} */
 
 #undef MESH_RENDER_FUNCTION
index 812280319e998b366abc2c00550d1450a63bce91..b93b7e21df2d8cd374a9153ca42ad753513f3587 100644 (file)
@@ -2045,11 +2045,10 @@ bool DRW_object_is_renderable(Object *ob)
        return true;
 }
 
-
-bool DRW_object_is_flat_normal(Object *ob)
+bool DRW_object_is_flat_normal(const Object *ob)
 {
        if (ob->type == OB_MESH) {
-               Mesh *me = ob->data;
+               const Mesh *me = ob->data;
                if (me->mpoly && me->mpoly[0].flag & ME_SMOOTH) {
                        return false;
                }
@@ -2057,6 +2056,26 @@ bool DRW_object_is_flat_normal(Object *ob)
        return true;
 }
 
+
+/**
+ * Return true if the object has its own draw mode.
+ * Caller must check this is active */
+int DRW_object_is_mode_shade(const Object *ob)
+{
+       BLI_assert(ob == DST.draw_ctx.obact);
+       if ((ob->mode & OB_MODE_EDIT) == 0) {
+               if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
+                       if ((DST.draw_ctx.v3d->flag2 & V3D_SHOW_MODE_SHADE_OVERRIDE) == 0) {
+                               return true;
+                       }
+                       else {
+                               return false;
+                       }
+               }
+       }
+       return -1;
+}
+
 /** \} */
 
 
@@ -2811,12 +2830,15 @@ static void DRW_engines_enable_external(void)
 
 static void DRW_engines_enable(const Scene *scene, SceneLayer *sl)
 {
-       const int mode = CTX_data_mode_enum_ex(scene->obedit, OBACT_NEW);
+       Object *obact = OBACT_NEW;
+       const int mode = CTX_data_mode_enum_ex(scene->obedit, obact);
        DRW_engines_enable_from_engine(scene);
 
        if (DRW_state_draw_support()) {
                DRW_engines_enable_from_object_mode();
-               DRW_engines_enable_from_mode(mode);
+               if ((obact == NULL) || (DRW_object_is_mode_shade(obact) != false)) {
+                       DRW_engines_enable_from_mode(mode);
+               }
        }
 }
 
index 795b0bae02bef5a4c19c1360e1b9e5dba563a703..ae6ee12ee7d898e7d73bf9b95405702c85e79645 100644 (file)
@@ -178,8 +178,7 @@ static void PAINT_TEXTURE_engine_init(void *vedata)
                e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
        }
 }
-#include "BKE_global.h"
-#include "BKE_main.h"
+
 /* Here init all passes and shading groups
  * Assume that all Passes are NULL */
 static void PAINT_TEXTURE_cache_init(void *vedata)
@@ -199,12 +198,6 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
                                 DRW_STATE_BLEND | DRW_STATE_WIRE;
                psl->image_faces = DRW_pass_create("Image Color Pass", state);
 
-               /* Create a shadingGroup using a function in draw_common.c or custom one */
-               /*
-                * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
-                * -- or --
-                * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
-                */
                stl->g_data->shgroup_fallback = DRW_shgroup_create(e_data.fallback_sh, psl->image_faces);
 
                /* Uniforms need a pointer to it's value so be sure it's accessible at
index b8e2724f78678fb350e907f5d86fe8cfb6a3c421..9be196d1561c4004b61b1aae87b37474e3552e68 100644 (file)
@@ -4642,6 +4642,9 @@ static void sculpt_flush_update(bContext *C)
                        ED_region_tag_redraw_partial(ar, &r);
                }
        }
+
+       /* 2.8x - avoid full mesh update! */
+       BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS);
 }
 
 /* Returns whether the mouse/stylus is over the mesh (1)
index 22bb3cd5add8af945e25787b1a9ba4b37102ee46..6a9b979596b418a87bf37557c575d962538782d7 100644 (file)
@@ -324,7 +324,7 @@ typedef struct View3D {
 #define V3D_SOLID_MATCAP               (1 << 12)       /* user flag */
 #define V3D_SHOW_SOLID_MATCAP  (1 << 13)       /* runtime flag */
 #define V3D_OCCLUDE_WIRE               (1 << 14)
-#define V3D_SHADELESS_TEX              (1 << 15)
+#define V3D_SHOW_MODE_SHADE_OVERRIDE   (1 << 15)
 
 
 /* View3d->flag3 (short) */
index 2af131038053f36b8bbfd1dc80bab3cee889419e..a16380e70e98a142a7bf2b682563c4880d3c6268 100644 (file)
@@ -2621,9 +2621,9 @@ static void rna_def_space_view3d(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Backface Culling", "Use back face culling to hide the back side of faces");
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
 
-       prop = RNA_def_property(srna, "show_textured_shadeless", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHADELESS_TEX);
-       RNA_def_property_ui_text(prop, "Shadeless", "Show shadeless texture without lighting in textured draw mode");
+       prop = RNA_def_property(srna, "show_mode_shade_override", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_MODE_SHADE_OVERRIDE);
+       RNA_def_property_ui_text(prop, "Full Shading", "Use full shading for mode drawing (to view final result)");
        RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
 
        prop = RNA_def_property(srna, "show_occlude_wire", PROP_BOOLEAN, PROP_NONE);