Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/external')
-rw-r--r--source/blender/draw/engines/external/external_engine.c115
1 files changed, 103 insertions, 12 deletions
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index d0f8826c914..ed8c609c01f 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -54,12 +54,12 @@ typedef struct EXTERNAL_StorageList {
} EXTERNAL_StorageList;
typedef struct EXTERNAL_FramebufferList {
- struct GPUFrameBuffer *default_fb;
+ struct GPUFrameBuffer *depth_buffer_fb;
} EXTERNAL_FramebufferList;
typedef struct EXTERNAL_TextureList {
/* default */
- struct GPUTexture *depth;
+ struct GPUTexture *depth_buffer_tx;
} EXTERNAL_TextureList;
typedef struct EXTERNAL_PassList {
@@ -80,30 +80,77 @@ typedef struct EXTERNAL_Data {
static struct {
/* Depth Pre Pass */
struct GPUShader *depth_sh;
+ bool draw_depth;
} e_data = {NULL}; /* Engine data */
typedef struct EXTERNAL_PrivateData {
DRWShadingGroup *depth_shgrp;
+
+ /* Do we need to update the depth or can we reuse the last calculated texture. */
+ bool update_depth;
+ bool view_updated;
+
+ float last_mat[4][4];
+ float curr_mat[4][4];
} EXTERNAL_PrivateData; /* Transient data */
/* Functions */
-static void external_engine_init(void *UNUSED(vedata))
+static void external_engine_init(void *vedata)
{
+ EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ RegionView3D *rv3d = draw_ctx->rv3d;
+
/* Depth prepass */
if (!e_data.depth_sh) {
e_data.depth_sh = DRW_shader_create_3d_depth_only(GPU_SHADER_CFG_DEFAULT);
}
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ stl->g_data->update_depth = true;
+ stl->g_data->view_updated = false;
+ }
+
+ if (stl->g_data->update_depth == false) {
+ if (rv3d && rv3d->rflag & RV3D_NAVIGATING) {
+ stl->g_data->update_depth = true;
+ }
+ }
+
+ if (stl->g_data->view_updated) {
+ stl->g_data->update_depth = true;
+ stl->g_data->view_updated = false;
+ }
+
+ {
+ float view[4][4];
+ float win[4][4];
+ DRW_viewport_matrix_get(view, DRW_MAT_VIEW);
+ DRW_viewport_matrix_get(win, DRW_MAT_WIN);
+ mul_m4_m4m4(stl->g_data->curr_mat, view, win);
+ if (!equals_m4m4(stl->g_data->curr_mat, stl->g_data->last_mat)) {
+ stl->g_data->update_depth = true;
+ }
+ }
}
static void external_cache_init(void *vedata)
{
EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
+ EXTERNAL_TextureList *txl = ((EXTERNAL_Data *)vedata)->txl;
+ EXTERNAL_FramebufferList *fbl = ((EXTERNAL_Data *)vedata)->fbl;
- if (!stl->g_data) {
- /* Alloc transient pointers */
- stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ {
+ DRW_texture_ensure_fullscreen_2d(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->depth_buffer_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(txl->depth_buffer_tx),
+ });
}
/* Depth Pass */
@@ -112,6 +159,16 @@ static void external_cache_init(void *vedata)
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL);
stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
}
+
+ /* Do not draw depth pass when overlays are turned off. */
+ e_data.draw_depth = false;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const View3D *v3d = draw_ctx->v3d;
+ if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
+ /* mark `update_depth` for when overlays are turned on again. */
+ stl->g_data->update_depth = true;
+ return;
+ }
}
static void external_cache_populate(void *vedata, Object *ob)
@@ -122,10 +179,20 @@ static void external_cache_populate(void *vedata, Object *ob)
return;
}
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
- if (geom) {
- /* Depth Prepass */
- DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat);
+ /* Do not draw depth pass when overlays are turned off. */
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const View3D *v3d = draw_ctx->v3d;
+ if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
+ return;
+ }
+
+ if (stl->g_data->update_depth) {
+ e_data.draw_depth = true;
+ struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ /* Depth Prepass */
+ DRW_shgroup_call_add(stl->g_data->depth_shgrp, geom, ob->obmat);
+ }
}
}
@@ -181,7 +248,10 @@ static void external_draw_scene_do(void *vedata)
static void external_draw_scene(void *vedata)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
+ EXTERNAL_StorageList *stl = ((EXTERNAL_Data *)vedata)->stl;
EXTERNAL_PassList *psl = ((EXTERNAL_Data *)vedata)->psl;
+ EXTERNAL_FramebufferList *fbl = ((EXTERNAL_Data *)vedata)->fbl;
+ const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
/* Will be NULL during OpenGL render.
* OpenGL render is used for quick preview (thumbnails or sequencer preview)
@@ -189,7 +259,28 @@ static void external_draw_scene(void *vedata)
if (draw_ctx->evil_C) {
external_draw_scene_do(vedata);
}
- DRW_draw_pass(psl->depth_pass);
+
+ if (e_data.draw_depth) {
+ DRW_draw_pass(psl->depth_pass);
+ // copy result to tmp buffer
+ GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->depth_buffer_fb, 0, GPU_DEPTH_BIT);
+ stl->g_data->update_depth = false;
+ }
+ else {
+ // copy tmp buffer to default
+ GPU_framebuffer_blit(fbl->depth_buffer_fb, 0, dfbl->depth_only_fb, 0, GPU_DEPTH_BIT);
+ }
+
+ copy_m4_m4(stl->g_data->last_mat, stl->g_data->curr_mat);
+}
+
+static void external_view_update(void *vedata)
+{
+ EXTERNAL_Data *data = vedata;
+ EXTERNAL_StorageList *stl = data->stl;
+ if (stl && stl->g_data) {
+ stl->g_data->view_updated = true;
+ }
}
static void external_engine_free(void)
@@ -211,7 +302,7 @@ static DrawEngineType draw_engine_external_type = {
&external_cache_finish,
NULL,
&external_draw_scene,
- NULL,
+ &external_view_update,
NULL,
NULL,
};