Fix T63669: Particle editing bypassing occlusion.
authormano-wii <germano.costa@ig.com.br>
Fri, 19 Apr 2019 14:49:17 +0000 (11:49 -0300)
committermano-wii <germano.costa@ig.com.br>
Fri, 19 Apr 2019 14:49:17 +0000 (11:49 -0300)
The problem occurs because status changes between BackBuffer and Offscreen.

Reviewers: fclem

Differential Revision: https://developer.blender.org/D4703

source/blender/draw/DRW_engine.h
source/blender/draw/intern/draw_manager.c
source/blender/editors/include/ED_view3d.h
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_draw_legacy.c
source/blender/editors/space_view3d/view3d_intern.h

index 8ff4fbb..d0b7c10 100644 (file)
@@ -132,6 +132,10 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
                                  struct ARegion *ar,
                                  struct View3D *v3d,
                                  struct GPUViewport *viewport);
+void DRW_draw_depth_object(struct ARegion *ar,
+                           struct View3D *v3d,
+                           struct GPUViewport *viewport,
+                           struct Object *object);
 
 void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
 void DRW_framebuffer_select_id_release(struct ARegion *ar);
index b354609..394cb6a 100644 (file)
@@ -2332,42 +2332,6 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
 #endif /* USE_GPU_SELECT */
 }
 
-static void draw_depth_texture_to_screen(GPUTexture *texture)
-{
-  const float w = (float)GPU_texture_width(texture);
-  const float h = (float)GPU_texture_height(texture);
-
-  GPUVertFormat *format = immVertexFormat();
-  uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-  uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
-  immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_DEPTH_COPY);
-
-  GPU_texture_bind(texture, 0);
-
-  immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
-
-  immBegin(GPU_PRIM_TRI_STRIP, 4);
-
-  immAttr2f(texcoord, 0.0f, 0.0f);
-  immVertex2f(pos, 0.0f, 0.0f);
-
-  immAttr2f(texcoord, 1.0f, 0.0f);
-  immVertex2f(pos, w, 0.0f);
-
-  immAttr2f(texcoord, 0.0f, 1.0f);
-  immVertex2f(pos, 0.0f, h);
-
-  immAttr2f(texcoord, 1.0f, 1.0f);
-  immVertex2f(pos, w, h);
-
-  immEnd();
-
-  GPU_texture_unbind(texture);
-
-  immUnbindProgram();
-}
-
 /**
  * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
  */
@@ -2484,21 +2448,6 @@ void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
 
   drw_engines_disable();
 
-  /* XXX Drawing the resulting buffer to the BACK_BUFFER */
-  GPU_matrix_push();
-  GPU_matrix_push_projection();
-  wmOrtho2_region_pixelspace(DST.draw_ctx.ar);
-  GPU_matrix_identity_set();
-
-  glEnable(GL_DEPTH_TEST); /* Cannot write to depth buffer without testing */
-  glDepthFunc(GL_ALWAYS);
-  DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(DST.viewport);
-  draw_depth_texture_to_screen(dtxl->depth);
-  glDepthFunc(GL_LEQUAL);
-
-  GPU_matrix_pop();
-  GPU_matrix_pop_projection();
-
 #ifdef DEBUG
   /* Avoid accidental reuse. */
   drw_state_ensure_not_reused(&DST);
@@ -2544,6 +2493,72 @@ void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
 #endif
 }
 
+/**
+ * Clears the Depth Buffer and draws only the specified object.
+ */
+void DRW_draw_depth_object(ARegion *ar,
+                           View3D *v3d,
+                           GPUViewport *viewport,
+                           Object *object)
+{
+  RegionView3D *rv3d = ar->regiondata;
+
+  DRW_opengl_context_enable();
+
+  /* Setup framebuffer */
+  DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
+
+  GPU_framebuffer_bind(fbl->depth_only_fb);
+  GPU_framebuffer_clear_depth(fbl->depth_only_fb, 1.0f);
+  GPU_depth_test(true);
+  GPU_matrix_mul(object->obmat);
+
+  const float(*world_clip_planes)[4] = NULL;
+  if (rv3d->rflag & RV3D_CLIPPING) {
+    ED_view3d_clipping_set(rv3d);
+    ED_view3d_clipping_local(rv3d, object->obmat);
+    world_clip_planes = rv3d->clip_local;
+  }
+
+  switch (object->type) {
+    case OB_MESH: {
+      GPUBatch *batch;
+
+      Mesh *me = object->data;
+
+      if (object->mode & OB_MODE_EDIT) {
+        batch = DRW_mesh_batch_cache_get_edit_triangles(me);
+      }
+      else {
+        batch = DRW_mesh_batch_cache_get_surface(me);
+      }
+
+      DRW_mesh_batch_cache_create_requested(object, me, NULL, false, true);
+
+      const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
+                                                          GPU_SHADER_CFG_DEFAULT;
+      GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
+      if (world_clip_planes != NULL) {
+        GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
+      }
+
+      GPU_batch_draw(batch);
+    } break;
+    case OB_CURVE:
+    case OB_SURF:
+      break;
+  }
+
+  if (rv3d->rflag & RV3D_CLIPPING) {
+    ED_view3d_clipping_disable();
+  }
+
+  GPU_matrix_set(rv3d->viewmat);
+  GPU_depth_test(false);
+  GPU_framebuffer_restore();
+  DRW_opengl_context_disable();
+}
+
 /* Set an opengl context to be used with shaders that draw on U32 colors. */
 void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear)
 {
index fe7ccb7..caa202c 100644 (file)
@@ -524,8 +524,6 @@ void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc);
 void ED_view3d_viewcontext_init_object(struct ViewContext *vc, struct Object *obact);
 void view3d_operator_needs_opengl(const struct bContext *C);
 void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *ar);
-void view3d_opengl_read_pixels(
-    struct ARegion *ar, int x, int y, int w, int h, int format, int type, void *data);
 
 /* XXX should move to BLI_math */
 bool edge_inside_circle(const float cent[2],
index c304642..638c77f 100644 (file)
@@ -348,51 +348,6 @@ void draw_object_select_id(Depsgraph *depsgraph,
   GPU_matrix_set(rv3d->viewmat);
 }
 
-void draw_object_depth(RegionView3D *rv3d, Object *ob)
-{
-  GPU_matrix_mul(ob->obmat);
-  GPU_depth_test(true);
-
-  const float(*world_clip_planes)[4] = NULL;
-  if (rv3d->rflag & RV3D_CLIPPING) {
-    ED_view3d_clipping_local(rv3d, ob->obmat);
-    world_clip_planes = rv3d->clip_local;
-  }
-
-  switch (ob->type) {
-    case OB_MESH: {
-      GPUBatch *batch;
-
-      Mesh *me = ob->data;
-
-      if (ob->mode & OB_MODE_EDIT) {
-        batch = DRW_mesh_batch_cache_get_edit_triangles(me);
-      }
-      else {
-        batch = DRW_mesh_batch_cache_get_surface(me);
-      }
-
-      DRW_mesh_batch_cache_create_requested(ob, me, NULL, false, true);
-
-      DRW_opengl_context_enable();
-      const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
-                                                          GPU_SHADER_CFG_DEFAULT;
-      GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
-      if (world_clip_planes != NULL) {
-        bbs_world_clip_planes_from_rv3d(batch, world_clip_planes);
-      }
-
-      GPU_batch_draw(batch);
-      DRW_opengl_context_disable();
-    } break;
-    case OB_CURVE:
-    case OB_SURF:
-      break;
-  }
-
-  GPU_matrix_set(rv3d->viewmat);
-}
-
 void ED_draw_object_facemap(Depsgraph *depsgraph,
                             Object *ob,
                             const float col[4],
index 85bc0fb..e78eb79 100644 (file)
@@ -219,12 +219,6 @@ static void validate_object_select_id(struct Depsgraph *depsgraph,
   G.f &= ~G_FLAG_BACKBUFSEL;
 }
 
-void view3d_opengl_read_pixels(
-    ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
-{
-  glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
-}
-
 /* TODO: Creating, attaching texture, and destroying a framebuffer is quite slow.
  *       Calling this function should be avoided during interactive drawing. */
 static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data)
@@ -234,7 +228,6 @@ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void
   GPUFrameBuffer *tmp_fb = GPU_framebuffer_create();
   GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0);
   GPU_framebuffer_bind(tmp_fb);
-  glDisable(GL_SCISSOR_TEST);
 
   glReadPixels(rect->xmin,
                rect->ymin,
@@ -244,9 +237,7 @@ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void
                GL_FLOAT,
                data);
 
-  glEnable(GL_SCISSOR_TEST);
   GPU_framebuffer_restore();
-
   GPU_framebuffer_free(tmp_fb);
 }
 
@@ -273,25 +264,8 @@ void ED_view3d_backbuf_depth_validate(ViewContext *vc)
     Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
 
     if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
-      GPU_scissor(ar->winrct.xmin,
-                  ar->winrct.ymin,
-                  BLI_rcti_size_x(&ar->winrct),
-                  BLI_rcti_size_y(&ar->winrct));
-
-      GPU_depth_test(true);
-      GPU_clear(GPU_DEPTH_BIT);
-
-      if (rv3d->rflag & RV3D_CLIPPING) {
-        ED_view3d_clipping_set(rv3d);
-      }
-
-      draw_object_depth(rv3d, obact_eval);
-
-      if (rv3d->rflag & RV3D_CLIPPING) {
-        ED_view3d_clipping_disable();
-      }
-
-      GPU_depth_test(false);
+      GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
+      DRW_draw_depth_object(vc->ar, vc->v3d, viewport, obact_eval);
     }
 
     vc->v3d->flag &= ~V3D_INVALID_BACKBUF;
@@ -855,9 +829,15 @@ void ED_view3d_depth_update(ARegion *ar)
     }
 
     if (d->damaged) {
-      view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
+      GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
+      rcti r = {
+          .xmin = 0,
+          .xmax = d->w,
+          .ymin = 0,
+          .ymax = d->h,
+      };
+      view3d_opengl_read_Z_pixels(viewport, &r, d->depths);
       glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
-
       d->damaged = false;
     }
   }
index d3d0254..9075909 100644 (file)
@@ -134,8 +134,6 @@ void draw_object_select_id(struct Depsgraph *depsgraph,
                            struct Object *ob,
                            short select_mode);
 
-void draw_object_depth(RegionView3D *rv3d, struct Object *ob);
-
 int view3d_effective_drawtype(const struct View3D *v3d);
 
 /* view3d_draw.c */