From 8f4ba1c0467d9e6169451e03be5efffbd1f7a896 Mon Sep 17 00:00:00 2001 From: mano-wii Date: Fri, 19 Apr 2019 11:49:17 -0300 Subject: [PATCH] Fix T63669: Particle editing bypassing occlusion. 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 | 4 + source/blender/draw/intern/draw_manager.c | 117 ++++++++++-------- source/blender/editors/include/ED_view3d.h | 2 - .../blender/editors/space_view3d/drawobject.c | 45 ------- .../editors/space_view3d/view3d_draw_legacy.c | 40 ++---- .../editors/space_view3d/view3d_intern.h | 2 - 6 files changed, 80 insertions(+), 130 deletions(-) diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 8ff4fbbe5a5..d0b7c10a3cb 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -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); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index b3546092667..394cb6a144f 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -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) { diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index fe7ccb7170c..caa202c46a8 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -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], diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index c304642c4c3..638c77fc3cb 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -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], diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 85bc0fba36b..e78eb790072 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -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; } } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index d3d0254578b..9075909a6fe 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -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 */