diff options
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 20 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_view.c | 38 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_view.h | 1 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 104 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/object_camera_image_frag.glsl | 2 |
5 files changed, 109 insertions, 56 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 6387cecc01f..66cf921d47d 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1171,7 +1171,7 @@ static void drw_engines_cache_finish(void) MEM_freeN(DST.vedata_array); } -static void drw_engines_draw_background(void) +static bool drw_engines_draw_background(void) { for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *engine = link->data; @@ -1185,10 +1185,20 @@ static void drw_engines_draw_background(void) DRW_stats_group_end(); PROFILE_END_UPDATE(data->background_time, stime); - return; + return true; } } + /* No draw engines draw the background. We clear the background. + * We draw the background after drawing of the scene so the camera background + * images can be drawn using ALPHA Under. Otherwise the background always + * interferred with the alpha blending */ + DRW_clear_background(); + return false; +} + +static void drw_draw_background_alpha_under(void) +{ /* No draw_background found, doing default background */ const bool do_alpha_checker = !DRW_state_draw_background(); DRW_draw_background(do_alpha_checker); @@ -1685,7 +1695,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, DRW_hair_update(); - drw_engines_draw_background(); + const bool background_drawn = drw_engines_draw_background(); GPU_framebuffer_bind(DST.default_framebuffer); @@ -1696,6 +1706,10 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, drw_engines_draw_scene(); + if (!background_drawn) { + drw_draw_background_alpha_under(); + } + /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */ GPU_flush(); diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 7aa2e007f79..58643eb12a8 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -41,11 +41,9 @@ #include "BKE_object.h" #include "BKE_paint.h" -#include "DRW_render.h" - #include "view3d_intern.h" -#include "draw_view.h" +#include "draw_manager.h" /* ******************** region info ***************** */ @@ -60,18 +58,17 @@ void DRW_draw_region_info(void) } /* ************************* Background ************************** */ +void DRW_clear_background() +{ + GPU_clear_color(0.0, 0.0, 0.0, 0.0); + GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT); +} void DRW_draw_background(bool do_alpha_checker) { - /* Just to make sure */ - glDepthMask(GL_TRUE); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glStencilMask(0xFF); - + drw_state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL); if (do_alpha_checker) { /* Transparent render, do alpha checker. */ - GPU_depth_test(false); - GPU_matrix_push(); GPU_matrix_identity_set(); GPU_matrix_identity_projection_set(); @@ -79,18 +76,11 @@ void DRW_draw_background(bool do_alpha_checker) imm_draw_box_checker_2d(-1.0f, -1.0f, 1.0f, 1.0f); GPU_matrix_pop(); - - GPU_clear(GPU_DEPTH_BIT | GPU_STENCIL_BIT); - - GPU_depth_test(true); } - else if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { + else { float m[4][4]; unit_m4(m); - /* Gradient background Color */ - GPU_depth_test(false); - GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint color = GPU_vertformat_attr_add( @@ -103,8 +93,8 @@ void DRW_draw_background(bool do_alpha_checker) immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR_DITHER); - UI_GetThemeColor3ubv(TH_BACK_GRAD, col_lo); UI_GetThemeColor3ubv(TH_BACK, col_hi); + UI_GetThemeColor3ubv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_BACK_GRAD : TH_BACK, col_lo); immBegin(GPU_PRIM_TRI_FAN, 4); immAttr3ubv(color, col_lo); @@ -119,16 +109,6 @@ void DRW_draw_background(bool do_alpha_checker) immUnbindProgram(); GPU_matrix_pop(); - - GPU_clear(GPU_DEPTH_BIT | GPU_STENCIL_BIT); - - GPU_depth_test(true); - } - else { - /* Solid background Color */ - UI_ThemeClearColorAlpha(TH_BACK, 1.0f); - - GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT); } } diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h index 715c3c0d40c..7be186f1c72 100644 --- a/source/blender/draw/intern/draw_view.h +++ b/source/blender/draw/intern/draw_view.h @@ -24,6 +24,7 @@ #define __DRAW_VIEW_H__ void DRW_draw_region_info(void); +void DRW_clear_background(void); void DRW_draw_background(bool do_alpha_checker); void DRW_draw_cursor(void); void DRW_draw_gizmo_3d(void); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 05a915185df..ec19c731e96 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -122,8 +122,9 @@ typedef struct OBJECT_PassList { struct DRWPass *bone_axes[2]; struct DRWPass *particle; struct DRWPass *lightprobes; - struct DRWPass *camera_images_back; - struct DRWPass *camera_images_front; + struct DRWPass *camera_images_back_alpha_under; + struct DRWPass *camera_images_back_alpha_over; + struct DRWPass *camera_images_front_alpha_over; } OBJECT_PassList; typedef struct OBJECT_FramebufferList { @@ -991,13 +992,19 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data, } } -/* Draw Camera Background Images */ +/* -------------------------------------------------------------------- */ +/** \name Camera Background Images + * \{ */ typedef struct CameraEngineData { DrawData dd; ListBase bg_data; } CameraEngineData; + typedef struct CameraEngineBGData { + CameraBGImage *camera_image; + GPUTexture *texture; float transform_mat[4][4]; + bool premultiplied; } CameraEngineBGData; static void camera_engine_data_free(DrawData *dd) @@ -1032,6 +1039,26 @@ static void camera_background_images_stereo_setup(Scene *scene, iuser->flag &= ~IMA_SHOW_STEREO; } } +static void camera_background_images_add_shgroup(DRWPass *pass, + CameraEngineBGData *bg_data, + GPUShader *shader, + GPUBatch *batch) +{ + CameraBGImage *camera_image = bg_data->camera_image; + DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + + DRW_shgroup_uniform_float_copy( + grp, "depth", camera_image->flag & CAM_BGIMG_FLAG_FOREGROUND ? 0.000001f : 0.999999f); + DRW_shgroup_uniform_float_copy(grp, "alpha", camera_image->alpha); + DRW_shgroup_uniform_texture(grp, "image", bg_data->texture); + DRW_shgroup_uniform_bool_copy(grp, "imagePremultiplied", bg_data->premultiplied); + DRW_shgroup_uniform_float_copy( + grp, "flipX", (camera_image->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0); + DRW_shgroup_uniform_float_copy( + grp, "flipY", (camera_image->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0); + DRW_shgroup_uniform_mat4(grp, "TransformMat", bg_data->transform_mat); + DRW_shgroup_call(grp, batch, NULL); +} static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data, OBJECT_PassList *psl, @@ -1255,25 +1282,46 @@ static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data, scale_m4, uv2img_space); - DRWPass *pass = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? psl->camera_images_front : - psl->camera_images_back; - GPUShader *shader = DRW_state_do_color_management() ? sh_data->object_camera_image_cm : - sh_data->object_camera_image; - DRWShadingGroup *grp = DRW_shgroup_create(shader, pass); + /* Keep the references so we can reverse the loop */ + bg_data->camera_image = bgpic; + bg_data->texture = tex; + bg_data->premultiplied = premultiplied; + } - DRW_shgroup_uniform_float_copy( - grp, "depth", (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? 0.000001 : 0.999999); - DRW_shgroup_uniform_float_copy(grp, "alpha", bgpic->alpha); - DRW_shgroup_uniform_texture(grp, "image", tex); - DRW_shgroup_uniform_bool_copy(grp, "imagePremultiplied", premultiplied); + /* Mark the rest bg_data's to be reused in the next drawing call */ + LinkData *last_node = list_node ? list_node->prev : camera_engine_data->bg_data.last; + while (list_node != NULL) { + CameraEngineBGData *bg_data = (CameraEngineBGData *)list_node->data; + bg_data->texture = NULL; + bg_data->camera_image = NULL; + list_node = list_node->next; + } - DRW_shgroup_uniform_float_copy( - grp, "flipX", (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0); - DRW_shgroup_uniform_float_copy( - grp, "flipY", (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0); - DRW_shgroup_uniform_mat4(grp, "TransformMat", bg_data->transform_mat); + GPUShader *shader = DRW_state_do_color_management() ? sh_data->object_camera_image_cm : + sh_data->object_camera_image; + /* loop 1: camera images alpha under */ + for (list_node = last_node; list_node; list_node = list_node->prev) { + CameraEngineBGData *bg_data = (CameraEngineBGData *)list_node->data; + CameraBGImage *camera_image = bg_data->camera_image; + if ((camera_image->flag & CAM_BGIMG_FLAG_FOREGROUND) == 0) { + camera_background_images_add_shgroup( + psl->camera_images_back_alpha_under, bg_data, shader, batch); + } + } - DRW_shgroup_call(grp, batch, NULL); + /* loop 2: camera images alpha over */ + for (list_node = camera_engine_data->bg_data.first; list_node; list_node = list_node->next) { + CameraEngineBGData *bg_data = (CameraEngineBGData *)list_node->data; + CameraBGImage *camera_image = bg_data->camera_image; + if (camera_image == NULL) { + break; + } + camera_background_images_add_shgroup((camera_image->flag & CAM_BGIMG_FLAG_FOREGROUND) ? + psl->camera_images_front_alpha_over : + psl->camera_images_back_alpha_over, + bg_data, + shader, + batch); } } } @@ -1286,6 +1334,7 @@ static void camera_background_images_free_textures(void) } BLI_freelistN(&e_data.movie_clips); } +/* \} */ static void OBJECT_cache_init(void *vedata) { @@ -1427,9 +1476,15 @@ static void OBJECT_cache_init(void *vedata) /* Camera background images */ { - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA; - psl->camera_images_back = DRW_pass_create("Camera Images Back", state); - psl->camera_images_front = DRW_pass_create("Camera Images Front", state); + psl->camera_images_back_alpha_over = DRW_pass_create( + "Camera Images Back Over", + DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA_PREMUL); + psl->camera_images_back_alpha_under = DRW_pass_create( + "Camera Images Back Under", + DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL); + psl->camera_images_front_alpha_over = DRW_pass_create( + "Camera Images Front Over", + DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA_PREMUL); } for (int i = 0; i < 2; i++) { @@ -3666,7 +3721,8 @@ static void OBJECT_draw_scene(void *vedata) float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - DRW_draw_pass(psl->camera_images_back); + DRW_draw_pass(psl->camera_images_back_alpha_under); + DRW_draw_pass(psl->camera_images_back_alpha_over); /* Don't draw Transparent passes in MSAA buffer. */ // DRW_draw_pass(psl->bone_envelope); /* Never drawn in Object mode currently. */ @@ -3774,7 +3830,7 @@ static void OBJECT_draw_scene(void *vedata) batch_camera_path_free(&stl->g_data->sgl_ghost.camera_path); - DRW_draw_pass(psl->camera_images_front); + DRW_draw_pass(psl->camera_images_front_alpha_over); camera_background_images_free_textures(); DRW_draw_pass(psl->ob_center); diff --git a/source/blender/draw/modes/shaders/object_camera_image_frag.glsl b/source/blender/draw/modes/shaders/object_camera_image_frag.glsl index 5d8ad3c79ea..7804ebdb8c9 100644 --- a/source/blender/draw/modes/shaders/object_camera_image_frag.glsl +++ b/source/blender/draw/modes/shaders/object_camera_image_frag.glsl @@ -19,5 +19,7 @@ void main() #endif color.a *= alpha; + color.rgb *= color.a; + fragColor = color; } |