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:
parent
b6a9e88aff
commit
8f4ba1c046
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue