[Bf-blender-cvs] [e47ce1f2d6d] master: Fix T65755 "In Front" (X-Ray) doesn't work with wire objects

Clément Foucault noreply at git.blender.org
Wed Jun 26 12:25:51 CEST 2019


Commit: e47ce1f2d6d7df814bd6498ae7b881989510395f
Author: Clément Foucault
Date:   Mon Jun 24 12:42:04 2019 +0200
Branches: master
https://developer.blender.org/rBe47ce1f2d6d7df814bd6498ae7b881989510395f

Fix T65755 "In Front" (X-Ray) doesn't work with wire objects

We fix by separating the drawing of wire xray objects.

These wire objects gets drawn before normal wires and set the stencil to
0x0 just like the solid counterparts. Also a prepass is done to "dig"
through non-xray solid.

===================================================================

M	source/blender/draw/engines/workbench/workbench_deferred.c
M	source/blender/draw/engines/workbench/workbench_forward.c
M	source/blender/draw/modes/overlay_mode.c

===================================================================

diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index f2f211d1db9..49b84b41744 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -1268,14 +1268,14 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
     DRW_draw_pass(psl->composite_pass);
   }
 
+  /* In order to not draw on top of ghost objects, we clear the stencil
+   * to 0xFF and the ghost object to 0x00 and only draw overlays on top if
+   * stencil is not 0. */
+  GPU_framebuffer_bind(dfbl->depth_only_fb);
+  GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF);
+
   /* TODO(fclem): only enable when needed (when there is overlays). */
   if (GHOST_ENABLED(psl)) {
-    /* In order to not draw on top of ghost objects, we clear the stencil
-     * to 0xFF and the ghost object to 0x00 and only draw overlays on top if
-     * stencil is not 0. */
-    GPU_framebuffer_bind(dfbl->depth_only_fb);
-    GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF);
-
     DRWState state = DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
     DRW_pass_state_set(psl->ghost_prepass_pass, state);
     DRW_pass_state_set(psl->ghost_prepass_hair_pass, state);
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index eccf2b1a0f0..612a3901ca0 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -674,7 +674,7 @@ void workbench_forward_draw_background(WORKBENCH_Data *UNUSED(vedata))
   DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
   DRW_stats_group_start("Clear depth");
   GPU_framebuffer_bind(dfbl->default_fb);
-  GPU_framebuffer_clear_depth(dfbl->default_fb, clear_depth);
+  GPU_framebuffer_clear_depth_stencil(dfbl->default_fb, clear_depth, 0xFF);
   DRW_stats_group_end();
 }
 
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index aaaeefa81c9..ae5c0064cde 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -59,6 +59,8 @@ typedef struct OVERLAY_StorageList {
 typedef struct OVERLAY_PassList {
   struct DRWPass *face_orientation_pass;
   struct DRWPass *face_wireframe_pass;
+  struct DRWPass *face_wireframe_only_pass;
+  struct DRWPass *face_wireframe_xray_pass;
 } OVERLAY_PassList;
 
 typedef struct OVERLAY_Data {
@@ -72,11 +74,12 @@ typedef struct OVERLAY_Data {
 typedef struct OVERLAY_PrivateData {
   DRWShadingGroup *face_orientation_shgrp;
   DRWShadingGroup *face_wires_shgrp;
+  DRWShadingGroup *face_wires_xray_shgrp;
   DRWView *view_wires;
   BLI_mempool *wire_color_mempool;
   View3DOverlay overlay;
   float wire_step_param;
-  bool ghost_stencil_test;
+  bool clear_stencil;
   bool show_overlays;
 } OVERLAY_PrivateData; /* Transient data */
 
@@ -117,7 +120,8 @@ static void overlay_engine_init(void *vedata)
     /* Alloc transient pointers */
     stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
   }
-  stl->g_data->ghost_stencil_test = false;
+
+  stl->g_data->clear_stencil = (draw_ctx->v3d->shading.type > OB_SOLID);
 
   const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
 
@@ -169,6 +173,13 @@ static void overlay_engine_init(void *vedata)
   stl->g_data->view_wires = DRW_view_create_with_zoffset(draw_ctx->rv3d, 0.5f);
 }
 
+static void geometry_shader_uniforms(DRWShadingGroup *shgrp)
+{
+  DRW_shgroup_uniform_float_copy(shgrp, "wireSize", U.pixelsize * 0.5f);
+  DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+  DRW_shgroup_uniform_vec2(shgrp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
+}
+
 static void overlay_cache_init(void *vedata)
 {
   OVERLAY_Data *data = vedata;
@@ -215,27 +226,28 @@ static void overlay_cache_init(void *vedata)
 
   {
     /* Wireframe */
-    DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS |
-                     DRW_STATE_FIRST_VERTEX_CONVENTION;
-    float wire_size = U.pixelsize * 0.5f;
-
     const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
     GPUShader *face_wires_sh = use_select ? sh_data->select_wireframe : sh_data->face_wireframe;
 
-    psl->face_wireframe_pass = DRW_pass_create("Face Wires", state);
-
+    DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
+                     DRW_STATE_STENCIL_EQUAL | DRW_STATE_FIRST_VERTEX_CONVENTION;
+    psl->face_wireframe_pass = DRW_pass_create("Wires", state);
     g_data->face_wires_shgrp = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
-    DRW_shgroup_uniform_float(
-        g_data->face_wires_shgrp, "wireStepParam", &g_data->wire_step_param, 1);
+
+    DRWState state_xray = DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_STENCIL |
+                          DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_STENCIL_NEQUAL |
+                          DRW_STATE_FIRST_VERTEX_CONVENTION;
+    psl->face_wireframe_xray_pass = DRW_pass_create("Wires Only Xray", state_xray);
+    g_data->face_wires_xray_shgrp = DRW_shgroup_create(face_wires_sh,
+                                                       psl->face_wireframe_xray_pass);
+
     if (use_select || USE_GEOM_SHADER_WORKAROUND) {
-      DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "wireSize", wire_size);
-      DRW_shgroup_uniform_vec2(
-          g_data->face_wires_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
-      DRW_shgroup_uniform_vec2(
-          g_data->face_wires_shgrp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
+      geometry_shader_uniforms(g_data->face_wires_shgrp);
+      geometry_shader_uniforms(g_data->face_wires_xray_shgrp);
     }
     if (rv3d->rflag & RV3D_CLIPPING) {
       DRW_shgroup_state_enable(g_data->face_wires_shgrp, DRW_STATE_CLIP_PLANES);
+      DRW_shgroup_state_enable(g_data->face_wires_xray_shgrp, DRW_STATE_CLIP_PLANES);
     }
 
     g_data->wire_step_param = stl->g_data->overlay.wireframe_threshold - 254.0f / 255.0f;
@@ -383,19 +395,21 @@ static void overlay_cache_populate(void *vedata, Object *ob)
       const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
       const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES);
       const bool is_wire = (ob->dt < OB_SOLID);
+      const bool is_xray = (ob->dtx & OB_DRAWXRAY);
       const bool use_coloring = (pd->show_overlays && !is_edit_mode && !use_sculpt_pbvh &&
                                  !has_edit_mesh_cage);
-      const int stencil_mask = (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF;
-      float *rim_col, *wire_col;
       DRWShadingGroup *shgrp = NULL;
 
-      overlay_wire_color_get(v3d, pd, ob, use_coloring, &rim_col, &wire_col);
-
       struct GPUBatch *geom;
       geom = DRW_cache_object_face_wireframe_get(ob);
 
       if (geom || use_sculpt_pbvh) {
-        shgrp = DRW_shgroup_create_sub(pd->face_wires_shgrp);
+        if (is_wire && is_xray) {
+          shgrp = DRW_shgroup_create_sub(pd->face_wires_xray_shgrp);
+        }
+        else {
+          shgrp = DRW_shgroup_create_sub(pd->face_wires_shgrp);
+        }
 
         float wire_step_param = 10.0f;
         if (!use_sculpt_pbvh) {
@@ -404,9 +418,12 @@ static void overlay_cache_populate(void *vedata, Object *ob)
         DRW_shgroup_uniform_float_copy(shgrp, "wireStepParam", wire_step_param);
 
         if (!(DRW_state_is_select() || DRW_state_is_depth())) {
-          DRW_shgroup_stencil_mask(shgrp, stencil_mask);
+          float *rim_col, *wire_col;
+          overlay_wire_color_get(v3d, pd, ob, use_coloring, &rim_col, &wire_col);
           DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
           DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
+          DRW_shgroup_stencil_mask(shgrp,
+                                   (is_xray && (is_wire || !pd->clear_stencil)) ? 0x00 : 0xFF);
         }
 
         if (use_sculpt_pbvh) {
@@ -421,35 +438,6 @@ static void overlay_cache_populate(void *vedata, Object *ob)
         (*dupli_data)->shgrp = shgrp;
         (*dupli_data)->geom = geom;
       }
-
-      if (is_wire && shgrp != NULL) {
-        /* If object is wireframe, don't try to use stencil test. */
-        DRW_shgroup_state_disable(shgrp, DRW_STATE_STENCIL_EQUAL);
-
-        if (ob->dtx & OB_DRAWXRAY) {
-          DRW_shgroup_state_disable(shgrp, DRW_STATE_DEPTH_LESS_EQUAL);
-        }
-      }
-      else if ((ob->dtx & OB_DRAWXRAY) && shgrp != NULL) {
-        pd->ghost_stencil_test = true;
-      }
-    }
-  }
-}
-
-static void overlay_cache_finish(void *vedata)
-{
-  OVERLAY_Data *data = vedata;
-  OVERLAY_PassList *psl = data->psl;
-  OVERLAY_StorageList *stl = data->stl;
-
-  const DRWContextState *ctx = DRW_context_state_get();
-  View3D *v3d = ctx->v3d;
-
-  /* only in solid mode */
-  if (v3d->shading.type == OB_SOLID && !XRAY_FLAG_ENABLED(v3d)) {
-    if (stl->g_data->ghost_stencil_test) {
-      DRW_pass_state_add(psl->face_wireframe_pass, DRW_STATE_STENCIL_EQUAL);
     }
   }
 }
@@ -464,9 +452,18 @@ static void overlay_draw_scene(void *vedata)
 
   if (DRW_state_is_fbo()) {
     GPU_framebuffer_bind(dfbl->default_fb);
+
+    /* In material/rendered mode, Stencil has not be rendered correctly.
+     * Clear it to avoid problems.*/
+    if (stl->g_data->clear_stencil) {
+      GPU_framebuffer_clear_stencil(dfbl->default_fb, 0xFF);
+    }
   }
   DRW_draw_pass(psl->face_orientation_pass);
 
+  /* Do a depth prepass to lower the depth where the xray wire objects can pass through */
+  DRW_draw_pass(psl->face_wireframe_xray_pass);
+
   /* This is replaced by the next code block  */
   // MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
 
@@ -479,9 +476,20 @@ static void overlay_draw_scene(void *vedata)
     GPU_framebuffer_blit(
         dfbl->default_fb, 0, dfbl->multisample_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
     DRW_stats_query_end();
+
+    /* Redo the prepass so we ge nice AA lines. */
+    DRW_draw_pass(psl->face_wireframe_xray_pass);
   }
 
   DRW_view_set

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list