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
This commit is contained in:
Germano Cavalcante 2019-04-19 11:49:17 -03:00
parent b6a9e88aff
commit 8f4ba1c046
Notes: blender-bot 2023-02-14 02:59:29 +01:00
Referenced by issue #63669, Particle edit effects not visible hair every time.
6 changed files with 80 additions and 130 deletions

View 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);

View 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)
{

View 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],

View 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],

View 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;
}
}

View 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 */