From 804e90b42d728ecb1073af8d0bae15a91b13a469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 11 Feb 2020 15:18:55 +0100 Subject: DRW: Color Management improvement Reviewed By: brecht sergey jbakker Differential Revision: http://developer.blender.org/D6729 --- source/blender/draw/CMakeLists.txt | 6 +- source/blender/draw/DRW_engine.h | 6 +- source/blender/draw/engines/basic/basic_engine.c | 1 - source/blender/draw/engines/eevee/eevee_effects.c | 45 -- source/blender/draw/engines/eevee/eevee_engine.c | 80 +--- source/blender/draw/engines/eevee/eevee_private.h | 3 +- .../draw/engines/eevee/eevee_renderpasses.c | 58 ++- .../draw/engines/eevee/eevee_temporal_sampling.c | 4 +- .../draw/engines/external/external_engine.c | 7 +- .../blender/draw/engines/gpencil/gpencil_engine.c | 1 - .../blender/draw/engines/gpencil/gpencil_engine.h | 1 - .../draw/engines/overlay/overlay_antialiasing.c | 6 +- .../draw/engines/overlay/overlay_armature.c | 257 +++-------- .../draw/engines/overlay/overlay_background.c | 112 +++++ .../draw/engines/overlay/overlay_edit_text.c | 4 +- .../blender/draw/engines/overlay/overlay_engine.c | 16 +- .../blender/draw/engines/overlay/overlay_extra.c | 53 +-- .../blender/draw/engines/overlay/overlay_image.c | 60 +-- .../draw/engines/overlay/overlay_metaball.c | 8 +- .../draw/engines/overlay/overlay_motion_path.c | 1 + .../blender/draw/engines/overlay/overlay_private.h | 11 +- .../blender/draw/engines/overlay/overlay_shader.c | 29 ++ .../shaders/armature_envelope_solid_frag.glsl | 2 +- .../overlay/shaders/armature_shape_solid_vert.glsl | 2 +- .../shaders/armature_sphere_solid_frag.glsl | 2 +- .../engines/overlay/shaders/background_frag.glsl | 73 ++++ .../engines/overlay/shaders/clipbound_vert.glsl | 13 + .../draw/engines/overlay/shaders/image_frag.glsl | 9 +- source/blender/draw/engines/select/select_engine.c | 1 - .../shaders/workbench_background_lib.glsl | 5 - .../workbench/shaders/workbench_data_lib.glsl | 5 - .../workbench_deferred_background_frag.glsl | 14 +- .../shaders/workbench_forward_composite_frag.glsl | 16 +- source/blender/draw/engines/workbench/solid_mode.c | 6 +- .../draw/engines/workbench/transparent_mode.c | 6 +- .../draw/engines/workbench/workbench_data.c | 60 +-- .../draw/engines/workbench/workbench_deferred.c | 68 ++- .../draw/engines/workbench/workbench_effect_aa.c | 13 +- .../draw/engines/workbench/workbench_forward.c | 39 +- .../draw/engines/workbench/workbench_private.h | 22 +- .../draw/engines/workbench/workbench_render.c | 2 - source/blender/draw/intern/DRW_render.h | 14 +- source/blender/draw/intern/draw_cache.c | 28 +- source/blender/draw/intern/draw_color_management.c | 63 +++ source/blender/draw/intern/draw_color_management.h | 28 ++ source/blender/draw/intern/draw_common.c | 34 +- source/blender/draw/intern/draw_common.h | 28 ++ source/blender/draw/intern/draw_manager.c | 469 ++++++--------------- source/blender/draw/intern/draw_manager_exec.c | 40 +- source/blender/draw/intern/draw_view.c | 89 ---- source/blender/draw/intern/draw_view.h | 2 - .../draw/intern/shaders/common_globals_lib.glsl | 28 ++ source/blender/editors/screen/glutil.c | 4 +- source/blender/editors/space_image/space_image.c | 7 +- source/blender/gpu/CMakeLists.txt | 2 +- source/blender/gpu/GPU_batch.h | 1 + source/blender/gpu/GPU_shader.h | 2 +- source/blender/gpu/GPU_texture.h | 2 +- source/blender/gpu/GPU_viewport.h | 11 +- source/blender/gpu/intern/gpu_batch.c | 11 + source/blender/gpu/intern/gpu_framebuffer.c | 2 + source/blender/gpu/intern/gpu_immediate.c | 7 + source/blender/gpu/intern/gpu_shader.c | 6 +- source/blender/gpu/intern/gpu_shader_private.h | 3 + source/blender/gpu/intern/gpu_texture.c | 8 +- source/blender/gpu/intern/gpu_viewport.c | 335 +++++++++------ .../gpu/shaders/gpu_shader_image_linear_frag.glsl | 33 -- .../gpu_shader_image_overlays_merge_frag.glsl | 42 ++ source/blender/imbuf/IMB_colormanagement.h | 3 +- source/blender/imbuf/intern/colormanagement.c | 101 +++-- source/blender/makesrna/intern/rna_render.c | 15 +- 71 files changed, 1255 insertions(+), 1290 deletions(-) create mode 100644 source/blender/draw/engines/overlay/overlay_background.c create mode 100644 source/blender/draw/engines/overlay/shaders/background_frag.glsl create mode 100644 source/blender/draw/engines/overlay/shaders/clipbound_vert.glsl delete mode 100644 source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl create mode 100644 source/blender/draw/intern/draw_color_management.c create mode 100644 source/blender/draw/intern/draw_color_management.h delete mode 100644 source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl create mode 100644 source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl (limited to 'source/blender') diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index a74a255045a..37fe04e9d8a 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -56,6 +56,7 @@ set(SRC intern/draw_cache_impl_mesh.c intern/draw_cache_impl_metaball.c intern/draw_cache_impl_particles.c + intern/draw_color_management.c intern/draw_common.c intern/draw_debug.c intern/draw_hair.c @@ -121,6 +122,7 @@ set(SRC engines/select/select_engine.c engines/overlay/overlay_antialiasing.c engines/overlay/overlay_armature.c + engines/overlay/overlay_background.c engines/overlay/overlay_edit_curve.c engines/overlay/overlay_edit_mesh.c engines/overlay/overlay_edit_text.c @@ -146,6 +148,7 @@ set(SRC intern/draw_cache_extract.h intern/draw_cache_impl.h intern/draw_cache_inline.h + intern/draw_color_management.h intern/draw_common.h intern/draw_debug.h intern/draw_hair_private.h @@ -237,7 +240,6 @@ data_to_c_simple(engines/eevee/shaders/volumetric_resolve_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/volumetric_scatter_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/volumetric_integration_frag.glsl SRC) -data_to_c_simple(engines/workbench/shaders/workbench_background_lib.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_cavity_lib.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_cavity_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl SRC) @@ -329,6 +331,8 @@ data_to_c_simple(engines/overlay/shaders/armature_stick_frag.glsl SRC) data_to_c_simple(engines/overlay/shaders/armature_stick_vert.glsl SRC) data_to_c_simple(engines/overlay/shaders/armature_wire_frag.glsl SRC) data_to_c_simple(engines/overlay/shaders/armature_wire_vert.glsl SRC) +data_to_c_simple(engines/overlay/shaders/background_frag.glsl SRC) +data_to_c_simple(engines/overlay/shaders/clipbound_vert.glsl SRC) data_to_c_simple(engines/overlay/shaders/depth_only_vert.glsl SRC) data_to_c_simple(engines/overlay/shaders/edit_curve_handle_geom.glsl SRC) data_to_c_simple(engines/overlay/shaders/edit_curve_handle_vert.glsl SRC) diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index b9e7908b3ef..647d8a0841f 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -52,18 +52,18 @@ struct rcti; /* Buffer and textures used by the viewport by default */ typedef struct DefaultFramebufferList { struct GPUFrameBuffer *default_fb; + struct GPUFrameBuffer *overlay_fb; struct GPUFrameBuffer *in_front_fb; struct GPUFrameBuffer *color_only_fb; struct GPUFrameBuffer *depth_only_fb; - struct GPUFrameBuffer *multisample_fb; + struct GPUFrameBuffer *overlay_only_fb; } DefaultFramebufferList; typedef struct DefaultTextureList { struct GPUTexture *color; + struct GPUTexture *color_overlay; struct GPUTexture *depth; struct GPUTexture *depth_in_front; - struct GPUTexture *multisample_color; - struct GPUTexture *multisample_depth; } DefaultTextureList; void DRW_engines_register(void); diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index 79da067095a..799359098fe 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -245,7 +245,6 @@ DrawEngineType draw_engine_basic_type = { &basic_cache_init, &basic_cache_populate, &basic_cache_finish, - NULL, &basic_draw_scene, NULL, NULL, diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 824ea69ea73..a20921b639f 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -174,11 +174,6 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, effects->enabled_effects |= EFFECT_NORMAL_BUFFER; } - /* Alpha checker if background is not drawn in viewport. */ - if (!DRW_state_is_image_render() && !DRW_state_draw_background()) { - effects->enabled_effects |= EFFECT_ALPHA_CHECKER; - } - /** * MinMax Pyramid */ @@ -342,31 +337,6 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat); DRW_shgroup_call(grp, quad, NULL); } - - if ((effects->enabled_effects & EFFECT_ALPHA_CHECKER) != 0) { - GPUShader *checker_sh = GPU_shader_get_builtin_shader(GPU_SHADER_2D_CHECKER); - - copy_v4_fl4(effects->color_checker_dark, 0.15f, 0.15f, 0.15f, 1.0f); - copy_v4_fl4(effects->color_checker_light, 0.2f, 0.2f, 0.2f, 1.0f); - - DRW_PASS_CREATE(psl->alpha_checker, - DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL); - grp = DRW_shgroup_create(checker_sh, psl->alpha_checker); - DRW_shgroup_uniform_vec4(grp, "color1", effects->color_checker_dark, 1); - DRW_shgroup_uniform_vec4(grp, "color2", effects->color_checker_light, 1); - DRW_shgroup_uniform_int_copy(grp, "size", 8); - DRW_shgroup_call(grp, quad, NULL); - - float viewmat[4][4], winmat[4][4]; - unit_m4(viewmat); - unit_m4(winmat); - /* Winmat must be negative. */ - swap_v3_v3(winmat[0], winmat[1]); - - /* Using default view bypasses the culling. */ - const DRWView *default_view = DRW_view_default_get(); - effects->checker_view = DRW_view_create_sub(default_view, viewmat, winmat); - } } void EEVEE_effects_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) @@ -524,21 +494,6 @@ void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, GPUTexture *texture_src, i DRW_stats_group_end(); } -void EEVEE_draw_alpha_checker(EEVEE_Data *vedata) -{ - EEVEE_PassList *psl = vedata->psl; - EEVEE_StorageList *stl = vedata->stl; - EEVEE_EffectsInfo *effects = stl->effects; - - if ((effects->enabled_effects & EFFECT_ALPHA_CHECKER) != 0) { - DRW_view_set_active(effects->checker_view); - - DRW_draw_pass(psl->alpha_checker); - - DRW_view_set_active(NULL); - } -} - static void EEVEE_velocity_resolve(EEVEE_Data *vedata) { EEVEE_PassList *psl = vedata->psl; diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 420249ab930..e3b50bb2142 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -22,10 +22,11 @@ #include "DRW_render.h" +#include "draw_color_management.h" /* TODO remove dependency */ + #include "BLI_rand.h" #include "BKE_object.h" -#include "BKE_global.h" /* for G.debug_value */ #include "DEG_depsgraph_query.h" @@ -183,13 +184,11 @@ static void eevee_cache_finish(void *vedata) * the background and the scene pass are visible. * Note: we could break it up in two passes using some depth test * to reduce the fillrate */ -static void eevee_draw_background(void *vedata) +static void eevee_draw_scene(void *vedata) { EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; - EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl; EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; EEVEE_FramebufferList *fbl = ((EEVEE_Data *)vedata)->fbl; - EEVEE_EffectsInfo *effects = stl->effects; EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); /* Default framebuffer and texture */ @@ -338,79 +337,15 @@ static void eevee_draw_background(void *vedata) } if ((stl->g_data->render_passes & SCE_PASS_COMBINED) > 0) { - /* Tonemapping and transfer result to default framebuffer. */ - bool use_render_settings = stl->g_data->use_color_render_settings; - + /* Transfer result to default framebuffer. */ GPU_framebuffer_bind(dfbl->default_fb); - DRW_transform_to_display(stl->effects->final_tx, true, use_render_settings); - - /* Draw checkerboard with alpha under. */ - EEVEE_draw_alpha_checker(vedata); + DRW_transform_none(stl->effects->final_tx); } else { EEVEE_renderpasses_draw(sldata, vedata); } - /* Debug : Output buffer to view. */ - switch (G.debug_value) { - case 1: - if (txl->maxzbuffer) { - DRW_transform_to_display(txl->maxzbuffer, false, false); - } - break; - case 2: - if (effects->ssr_pdf_output) { - DRW_transform_to_display(effects->ssr_pdf_output, false, false); - } - break; - case 3: - if (effects->ssr_normal_input) { - DRW_transform_to_display(effects->ssr_normal_input, false, false); - } - break; - case 4: - if (effects->ssr_specrough_input) { - DRW_transform_to_display(effects->ssr_specrough_input, false, false); - } - break; - case 5: - if (txl->color_double_buffer) { - DRW_transform_to_display(txl->color_double_buffer, false, false); - } - break; - case 6: - if (effects->gtao_horizons_debug) { - DRW_transform_to_display(effects->gtao_horizons_debug, false, false); - } - break; - case 7: - if (effects->gtao_horizons) { - DRW_transform_to_display(effects->gtao_horizons, false, false); - } - break; - case 8: - if (effects->sss_irradiance) { - DRW_transform_to_display(effects->sss_irradiance, false, false); - } - break; - case 9: - if (effects->sss_radius) { - DRW_transform_to_display(effects->sss_radius, false, false); - } - break; - case 10: - if (effects->sss_albedo) { - DRW_transform_to_display(effects->sss_albedo, false, false); - } - break; - case 11: - if (effects->velocity_tx) { - DRW_transform_to_display(effects->velocity_tx, false, false); - } - break; - default: - break; - } + EEVEE_renderpasses_draw_debug(vedata); EEVEE_volumes_free_smoke_textures(); @@ -525,8 +460,7 @@ DrawEngineType draw_engine_eevee_type = { &eevee_cache_init, &EEVEE_cache_populate, &eevee_cache_finish, - &eevee_draw_background, - NULL, /* Everything is drawn in the background pass (see comment on function) */ + &eevee_draw_scene, &eevee_view_update, &eevee_id_update, &eevee_render_to_image, diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 97bde2e5f2e..8ba68589cbd 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -523,7 +523,6 @@ typedef enum EEVEE_EffectsFlag { EFFECT_VELOCITY_BUFFER = (1 << 12), /* Not really an effect but a feature */ EFFECT_TAA_REPROJECT = (1 << 13), /* should be mutually exclusive with EFFECT_TAA */ EFFECT_DEPTH_DOUBLE_BUFFER = (1 << 14), /* Not really an effect but a feature */ - EFFECT_ALPHA_CHECKER = (1 << 15), /* Not really an effect but a feature */ } EEVEE_EffectsFlag; typedef struct EEVEE_EffectsInfo { @@ -588,7 +587,6 @@ typedef struct EEVEE_EffectsInfo { /* Alpha Checker */ float color_checker_dark[4]; float color_checker_light[4]; - struct DRWView *checker_view; /* Other */ float prev_persmat[4][4]; /* Lookdev */ @@ -1057,6 +1055,7 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, eScenePassType renderpass_type); void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata); void EEVEE_renderpasses_free(void); bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata); diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c index 927ff70a52b..e3cdf98925c 100644 --- a/source/blender/draw/engines/eevee/eevee_renderpasses.c +++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c @@ -23,6 +23,10 @@ #include "DRW_engine.h" #include "DRW_render.h" +#include "draw_color_management.h" /* TODO remove dependency. */ + +#include "BKE_global.h" /* for G.debug_value */ + #include "BLI_string_utils.h" #include "DEG_depsgraph_query.h" @@ -239,6 +243,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) > 0; bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 && DRW_state_is_opengl_render(); + UNUSED_VARS(needs_color_transfer); /* When SSS isn't available, but the pass is requested, we mark it as invalid */ if ((render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0 && @@ -261,7 +266,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) if (is_valid) { EEVEE_renderpasses_postprocess(sldata, vedata, render_pass); GPU_framebuffer_bind(dfbl->default_fb); - DRW_transform_to_display(txl->renderpass, needs_color_transfer, false); + DRW_transform_none(txl->renderpass); } else { /* Draw state is not valid for this pass, clear the buffer */ @@ -276,3 +281,54 @@ void EEVEE_renderpasses_free(void) { DRW_SHADER_FREE_SAFE(e_data.postprocess_sh); } + +void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata) +{ + EEVEE_TextureList *txl = vedata->txl; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_EffectsInfo *effects = stl->effects; + + GPUTexture *tx = NULL; + /* Debug : Output buffer to view. */ + switch (G.debug_value) { + case 1: + tx = txl->maxzbuffer; + break; + case 2: + tx = effects->ssr_pdf_output; + break; + case 3: + tx = effects->ssr_normal_input; + break; + case 4: + tx = effects->ssr_specrough_input; + break; + case 5: + tx = txl->color_double_buffer; + break; + case 6: + tx = effects->gtao_horizons; + break; + case 7: + tx = effects->gtao_horizons; + break; + case 8: + tx = effects->sss_irradiance; + break; + case 9: + tx = effects->sss_radius; + break; + case 10: + tx = effects->sss_albedo; + break; + case 11: + tx = effects->velocity_tx; + break; + default: + break; + } + + if (tx) { + DRW_transform_none(tx); + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 0f0b4a3e0a9..093a4780a97 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -198,7 +198,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data /** * Reset for each "redraw". When rendering using ogl render, - * we accumulate the redraw inside the drawing loop in eevee_draw_background(). + * we accumulate the redraw inside the drawing loop in eevee_draw_scene(). **/ effects->taa_render_sample = 1; effects->taa_view = NULL; @@ -251,7 +251,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data (effects->taa_current_sample < effects->taa_total_sample)) || DRW_state_is_image_render()) { if (view_is_valid) { - /* Viewport rendering updates the matrices in `eevee_draw_background` */ + /* Viewport rendering updates the matrices in `eevee_draw_scene` */ if (!DRW_state_is_image_render()) { effects->taa_current_sample += 1; repro_flag = 0; diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index 23fa30b5c13..ac3e5550030 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -236,6 +236,12 @@ static void external_draw_scene(void *vedata) * OpenGL render is used for quick preview (thumbnails or sequencer preview) * where using the rendering engine to preview doesn't make so much sense. */ if (draw_ctx->evil_C) { + float clear_col[4] = {0, 0, 0, 0}; + /* This is to keep compatibility with external engine. */ + /* TODO(fclem) remove it eventually. */ + GPU_framebuffer_bind(dfbl->default_fb); + GPU_framebuffer_clear_color(dfbl->default_fb, clear_col); + external_draw_scene_do(vedata); } @@ -266,7 +272,6 @@ static DrawEngineType draw_engine_external_type = { &external_cache_init, &external_cache_populate, &external_cache_finish, - NULL, &external_draw_scene, NULL, NULL, diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index ba02f03f6de..0106aae686d 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -1180,7 +1180,6 @@ DrawEngineType draw_engine_gpencil_type = { &GPENCIL_cache_init, &GPENCIL_cache_populate, &GPENCIL_cache_finish, - NULL, &GPENCIL_draw_scene, NULL, NULL, diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index b5e7349fb88..9d5b9d5f7c1 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -524,7 +524,6 @@ void DRW_gpencil_free_runtime_data(void *ved); if ((lvl > 0) && (fbl->multisample_fb != NULL) && (DRW_state_is_fbo())) { \ DRW_stats_query_start("GP Multisample Resolve"); \ GPU_framebuffer_bind(fb); \ - DRW_multisamples_resolve(txl->multisample_depth, txl->multisample_color, true); \ DRW_stats_query_end(); \ } \ } \ diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.c index 751c6dc7016..84a1fd346b4 100644 --- a/source/blender/draw/engines/overlay/overlay_antialiasing.c +++ b/source/blender/draw/engines/overlay/overlay_antialiasing.c @@ -83,7 +83,7 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata) GPUTexture *line_tex = NULL; if (pd->antialiasing.enabled) { - DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_tx, GPU_RGBA8, DRW_TEX_FILTER); + DRW_texture_ensure_fullscreen_2d(&txl->overlay_color_tx, GPU_SRGB8_A8, DRW_TEX_FILTER); DRW_texture_ensure_fullscreen_2d(&txl->overlay_line_tx, GPU_RGBA8, 0); color_tex = txl->overlay_color_tx; @@ -194,9 +194,7 @@ void OVERLAY_antialiasing_end(OVERLAY_Data *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (pd->antialiasing.enabled) { - GPU_framebuffer_bind(dfbl->color_only_fb); + GPU_framebuffer_bind(dfbl->overlay_only_fb); DRW_draw_pass(psl->antialiasing_ps); - - GPU_framebuffer_bind(dfbl->default_fb); } } diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c index 4571446763c..c80cda26fa2 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.c +++ b/source/blender/draw/engines/overlay/overlay_armature.c @@ -88,26 +88,6 @@ typedef struct ArmatureDrawContext { OVERLAY_ExtraCallBuffers *extras; - /** - * Follow `TH_*` naming except for mixed colors. - */ - struct { - float select[4]; - float edge_select[4]; - float bone_select[4]; /* tint */ - float wire[4]; - float wire_edit[4]; - float bone_solid[4]; - float bone_active_unselect[4]; /* mix */ - float bone_pose[4]; - float bone_pose_active[4]; - float bone_pose_active_unselect[4]; /* mix */ - float text_hi[4]; - float text[4]; - float vertex_select[4]; - float vertex[4]; - } color; - /* not a theme, this is an override */ const float *const_color; float const_wire; @@ -684,31 +664,28 @@ static void drw_shgroup_bone_relationship_lines(ArmatureDrawContext *ctx, const float start[3], const float end[3]) { - drw_shgroup_bone_relationship_lines_ex(ctx, start, end, ctx->color.wire); + drw_shgroup_bone_relationship_lines_ex(ctx, start, end, G_draw.block.colorWire); } static void drw_shgroup_bone_ik_lines(ArmatureDrawContext *ctx, const float start[3], const float end[3]) { - float fcolor[4] = {0.8f, 0.5f, 0.0f, 1.0f}; /* add theme! */ - drw_shgroup_bone_relationship_lines_ex(ctx, start, end, fcolor); + drw_shgroup_bone_relationship_lines_ex(ctx, start, end, G_draw.block.colorBoneIKLine); } static void drw_shgroup_bone_ik_no_target_lines(ArmatureDrawContext *ctx, const float start[3], const float end[3]) { - float fcolor[4] = {0.8f, 0.8f, 0.2f, 1.0f}; /* add theme! */ - drw_shgroup_bone_relationship_lines_ex(ctx, start, end, fcolor); + drw_shgroup_bone_relationship_lines_ex(ctx, start, end, G_draw.block.colorBoneIKLineNoTarget); } static void drw_shgroup_bone_ik_spline_lines(ArmatureDrawContext *ctx, const float start[3], const float end[3]) { - float fcolor[4] = {0.8f, 0.8f, 0.2f, 1.0f}; /* add theme! */ - drw_shgroup_bone_relationship_lines_ex(ctx, start, end, fcolor); + drw_shgroup_bone_relationship_lines_ex(ctx, start, end, G_draw.block.colorBoneIKLineSpline); } /** \} */ @@ -725,10 +702,6 @@ enum { PCHAN_COLOR_NORMAL = 0, /* normal drawing */ PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */ PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */ - - PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */ - PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */ - PCHAN_COLOR_LINEBONE, /* for the middle of line-bones */ }; /* This function sets the color-set for coloring a certain bone */ @@ -791,14 +764,6 @@ static void cp_shade_color3ub(uchar cp[3], const int offset) cp[2] = b; } -static void cp_shade_color3f(float cp[3], const float offset) -{ - add_v3_fl(cp, offset); - CLAMP(cp[0], 0, 255); - CLAMP(cp[1], 0, 255); - CLAMP(cp[2], 0, 255); -} - /* This function sets the gl-color for coloring a certain bone (based on bcolor) */ static bool set_pchan_color(const ArmatureDrawContext *ctx, short colCode, @@ -813,7 +778,6 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx, case PCHAN_COLOR_NORMAL: { if (bcolor) { uchar cp[4] = {255}; - if (boneflag & BONE_DRAW_ACTIVE) { copy_v3_v3_uchar(cp, bcolor->active); if (!(boneflag & BONE_SELECTED)) { @@ -828,159 +792,58 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx, copy_v3_v3_uchar(cp, bcolor->solid); cp_shade_color3ub(cp, -50); } - rgb_uchar_to_float(fcolor, cp); + /* Meh, hardcoded srgb transform here. */ + srgb_to_linearrgb_v4(fcolor, fcolor); } else { if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) { - UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, fcolor); + copy_v4_v4(fcolor, G_draw.block.colorBonePoseActive); } else if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, fcolor); + copy_v4_v4(fcolor, G_draw.block.colorBonePoseActiveUnsel); } else if (boneflag & BONE_SELECTED) { - UI_GetThemeColor4fv(TH_BONE_POSE, fcolor); + copy_v4_v4(fcolor, G_draw.block.colorBonePose); } else { - UI_GetThemeColor4fv(TH_WIRE, fcolor); + copy_v4_v4(fcolor, G_draw.block.colorWire); } } - return true; } case PCHAN_COLOR_SOLID: { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - if (bcolor) { - float solid_bcolor[3]; - rgb_uchar_to_float(solid_bcolor, (uchar *)bcolor->solid); - interp_v3_v3v3(fcolor, fcolor, solid_bcolor, 1.0f); + rgb_uchar_to_float(fcolor, (uchar *)bcolor->solid); + /* Meh, hardcoded srgb transform here. */ + srgb_to_linearrgb_v4(fcolor, fcolor); + } + else { + copy_v4_v4(fcolor, G_draw.block.colorBoneSolid); } - return true; } case PCHAN_COLOR_CONSTS: { if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) { - uchar cp[4]; if (constflag & PCHAN_HAS_TARGET) { - rgba_uchar_args_set(cp, 255, 150, 0, 80); + copy_v4_v4(fcolor, G_draw.block.colorBonePoseTarget); } else if (constflag & PCHAN_HAS_IK) { - rgba_uchar_args_set(cp, 255, 255, 0, 80); + copy_v4_v4(fcolor, G_draw.block.colorBonePoseIK); } else if (constflag & PCHAN_HAS_SPLINEIK) { - rgba_uchar_args_set(cp, 200, 255, 0, 80); + copy_v4_v4(fcolor, G_draw.block.colorBonePoseSplineIK); } else if (constflag & PCHAN_HAS_CONST) { - rgba_uchar_args_set(cp, 0, 255, 120, 80); + copy_v4_v4(fcolor, G_draw.block.colorBonePoseConstraint); } else { return false; } - - rgba_uchar_to_float(fcolor, cp); - return true; } return false; } - case PCHAN_COLOR_SPHEREBONE_BASE: { - if (bcolor) { - uchar cp[4] = {255}; - - if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3_uchar(cp, bcolor->active); - } - else if (boneflag & BONE_SELECTED) { - copy_v3_v3_uchar(cp, bcolor->select); - } - else { - copy_v3_v3_uchar(cp, bcolor->solid); - } - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, 40, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColor4fv(TH_BONE_POSE, fcolor); - } - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - return true; - } - case PCHAN_COLOR_SPHEREBONE_END: { - if (bcolor) { - uchar cp[4] = {255}; - - if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3_uchar(cp, bcolor->active); - cp_shade_color3ub(cp, 10); - } - else if (boneflag & BONE_SELECTED) { - copy_v3_v3_uchar(cp, bcolor->select); - cp_shade_color3ub(cp, -30); - } - else { - copy_v3_v3_uchar(cp, bcolor->solid); - cp_shade_color3ub(cp, -30); - } - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, 10, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, -30, fcolor); - } - else { - UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - } - } - break; - } - case PCHAN_COLOR_LINEBONE: { - /* inner part in background color or constraint */ - if ((constflag) && ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS))) { - uchar cp[4]; - if (constflag & PCHAN_HAS_TARGET) { - rgba_uchar_args_set(cp, 255, 150, 0, 255); - } - else if (constflag & PCHAN_HAS_IK) { - rgba_uchar_args_set(cp, 255, 255, 0, 255); - } - else if (constflag & PCHAN_HAS_SPLINEIK) { - rgba_uchar_args_set(cp, 200, 255, 0, 255); - } - else if (constflag & PCHAN_HAS_CONST) { - rgba_uchar_args_set(cp, 0, 255, 120, 255); - } - else if (constflag) { - UI_GetThemeColor4ubv(TH_BONE_POSE, cp); - } /* PCHAN_HAS_ACTION */ - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (bcolor) { - const uchar *cp = bcolor->solid; - rgb_uchar_to_float(fcolor, (uchar *)cp); - fcolor[3] = 204.f / 255.f; - } - else { - UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor); - } - } - - return true; - } } return false; @@ -994,9 +857,7 @@ static bool set_pchan_color(const ArmatureDrawContext *ctx, static void bone_locked_color_shade(float color[4]) { - float locked_color[4]; - - UI_GetThemeColor4fv(TH_BONE_LOCKED_WEIGHT, locked_color); + float *locked_color = G_draw.block.colorBoneLocked; interp_v3_v3v3(color, color, locked_color, locked_color[3]); } @@ -1009,7 +870,7 @@ static const float *get_bone_solid_color(const ArmatureDrawContext *ctx, const short constflag) { if (ctx->const_color) { - return ctx->color.bone_solid; + return G_draw.block.colorBoneSolid; } if (arm->flag & ARM_POSEMODE) { @@ -1024,7 +885,7 @@ static const float *get_bone_solid_color(const ArmatureDrawContext *ctx, return disp_color; } - return ctx->color.bone_solid; + return G_draw.block.colorBoneSolid; } static const float *get_bone_solid_with_consts_color(const ArmatureDrawContext *ctx, @@ -1035,7 +896,7 @@ static const float *get_bone_solid_with_consts_color(const ArmatureDrawContext * const short constflag) { if (ctx->const_color) { - return ctx->color.bone_solid; + return G_draw.block.colorBoneSolid; } const float *col = get_bone_solid_color(ctx, eBone, pchan, arm, boneflag, constflag); @@ -1079,18 +940,18 @@ static const float *get_bone_wire_color(const ArmatureDrawContext *ctx, else if (eBone) { if (boneflag & BONE_SELECTED) { if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3(disp_color, ctx->color.edge_select); + copy_v3_v3(disp_color, G_draw.block.colorBoneActive); } else { - copy_v3_v3(disp_color, ctx->color.bone_select); + copy_v3_v3(disp_color, G_draw.block.colorBoneSelect); } } else { if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3(disp_color, ctx->color.bone_active_unselect); + copy_v3_v3(disp_color, G_draw.block.colorBoneActiveUnsel); } else { - copy_v3_v3(disp_color, ctx->color.wire_edit); + copy_v3_v3(disp_color, G_draw.block.colorWireEdit); } } } @@ -1103,7 +964,7 @@ static const float *get_bone_wire_color(const ArmatureDrawContext *ctx, } } else { - copy_v3_v3(disp_color, ctx->color.vertex); + copy_v3_v3(disp_color, G_draw.block.colorVertex); } disp_color[3] = get_bone_wire_thickness(ctx, boneflag); @@ -1111,13 +972,12 @@ static const float *get_bone_wire_color(const ArmatureDrawContext *ctx, return disp_color; } -#define HINT_MUL 0.5f -#define HINT_SHADE 0.2f - static void bone_hint_color_shade(float hint_color[4], const float color[4]) { - mul_v3_v3fl(hint_color, color, HINT_MUL); - cp_shade_color3f(hint_color, -HINT_SHADE); + /* Increase contrast. */ + mul_v3_v3v3(hint_color, color, color); + /* Decrease value to add mode shading to the shape. */ + mul_v3_fl(hint_color, 0.1f); hint_color[3] = 1.0f; } @@ -1131,7 +991,7 @@ static const float *get_bone_hint_color(const ArmatureDrawContext *ctx, static float hint_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; if (ctx->const_color) { - bone_hint_color_shade(hint_color, ctx->color.bone_solid); + bone_hint_color_shade(hint_color, G_draw.block.colorBoneSolid); } else { const float *wire_color = get_bone_wire_color(ctx, eBone, pchan, arm, boneflag, constflag); @@ -1412,11 +1272,11 @@ static void draw_axes(ArmatureDrawContext *ctx, EditBone *eBone, bPoseChannel *p float final_col[4]; const float *col = (ctx->const_color) ? ctx->const_color : - (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? ctx->color.text_hi : - ctx->color.text; + (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? G_draw.block.colorTextHi : + G_draw.block.colorText; copy_v4_v4(final_col, col); /* Mix with axes color. */ - final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.3 : 0.8; + final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.1 : 0.65; drw_shgroup_bone_axes(ctx, BONE_VAR(eBone, pchan, disp_mat), final_col); } @@ -1431,10 +1291,10 @@ static void draw_points(ArmatureDrawContext *ctx, float col_solid_root[4], col_solid_tail[4], col_wire_root[4], col_wire_tail[4]; float col_hint_root[4], col_hint_tail[4]; - copy_v4_v4(col_solid_root, ctx->color.bone_solid); - copy_v4_v4(col_solid_tail, ctx->color.bone_solid); - copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : ctx->color.vertex); - copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : ctx->color.vertex); + copy_v4_v4(col_solid_root, G_draw.block.colorBoneSolid); + copy_v4_v4(col_solid_tail, G_draw.block.colorBoneSolid); + copy_v4_v4(col_wire_root, (ctx->const_color) ? ctx->const_color : G_draw.block.colorVertex); + copy_v4_v4(col_wire_tail, (ctx->const_color) ? ctx->const_color : G_draw.block.colorVertex); const bool is_envelope_draw = (arm->drawtype == ARM_ENVELOPE); const float envelope_ignore = -1.0f; @@ -1444,10 +1304,10 @@ static void draw_points(ArmatureDrawContext *ctx, /* Edit bone points can be selected */ if (eBone) { if (eBone->flag & BONE_ROOTSEL) { - copy_v3_v3(col_wire_root, ctx->color.vertex_select); + copy_v3_v3(col_wire_root, G_draw.block.colorVertexSelect); } if (eBone->flag & BONE_TIPSEL) { - copy_v3_v3(col_wire_tail, ctx->color.vertex_select); + copy_v3_v3(col_wire_tail, G_draw.block.colorVertexSelect); } } else if (arm->flag & ARM_POSEMODE) { @@ -1635,12 +1495,12 @@ static void draw_bone_line(ArmatureDrawContext *ctx, else { if (eBone) { if (eBone->flag & BONE_TIPSEL) { - col_tail = ctx->color.vertex_select; + col_tail = G_draw.block.colorVertexSelect; } if (boneflag & BONE_SELECTED) { - col_bone = ctx->color.edge_select; + col_bone = G_draw.block.colorBoneActive; } - col_wire = ctx->color.wire; + col_wire = G_draw.block.colorWire; } /* Draw root point if we are not connected to our parent. */ @@ -1648,7 +1508,7 @@ static void draw_bone_line(ArmatureDrawContext *ctx, (pchan->bone->parent && (pchan->bone->flag & BONE_CONNECTED)))) { if (eBone) { - col_head = (eBone->flag & BONE_ROOTSEL) ? ctx->color.vertex_select : col_bone; + col_head = (eBone->flag & BONE_ROOTSEL) ? G_draw.block.colorVertexSelect : col_bone; } else { col_head = col_bone; @@ -1989,6 +1849,7 @@ static void draw_bone_name(ArmatureDrawContext *ctx, bool highlight = (pchan && (arm->flag & ARM_POSEMODE) && (boneflag & BONE_SELECTED)) || (eBone && (eBone->flag & BONE_SELECTED)); + /* Color Management: Exception here as texts are drawn in sRGB space directly. */ UI_GetThemeColor4ubv(highlight ? TH_TEXT_HI : TH_TEXT, color); float *head = pchan ? pchan->pose_head : eBone->head; @@ -2289,28 +2150,6 @@ static void armature_context_setup(ArmatureDrawContext *ctx, ctx->const_wire = (((ob->base_flag & BASE_SELECTED) || (arm->drawtype == ARM_WIRE)) ? 1.5f : ((!is_filled || is_transparent) ? 1.0f : 0.0f)); - - /** See: 'set_pchan_color'*/ -#define NO_ALPHA(c) (((c)[3] = 1.0f), (c)) - - UI_GetThemeColor3fv(TH_SELECT, NO_ALPHA(ctx->color.select)); - UI_GetThemeColorShade3fv(TH_EDGE_SELECT, 60, NO_ALPHA(ctx->color.edge_select)); - UI_GetThemeColorShade3fv(TH_EDGE_SELECT, -20, NO_ALPHA(ctx->color.bone_select)); - UI_GetThemeColor3fv(TH_WIRE, NO_ALPHA(ctx->color.wire)); - UI_GetThemeColor3fv(TH_WIRE_EDIT, NO_ALPHA(ctx->color.wire_edit)); - UI_GetThemeColor3fv(TH_BONE_SOLID, NO_ALPHA(ctx->color.bone_solid)); - UI_GetThemeColorBlendShade3fv( - TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, NO_ALPHA(ctx->color.bone_active_unselect)); - UI_GetThemeColor3fv(TH_BONE_POSE, NO_ALPHA(ctx->color.bone_pose)); - UI_GetThemeColor3fv(TH_BONE_POSE_ACTIVE, NO_ALPHA(ctx->color.bone_pose_active)); - UI_GetThemeColorBlendShade3fv( - TH_WIRE, TH_BONE_POSE, 0.15f, 0, NO_ALPHA(ctx->color.bone_pose_active_unselect)); - UI_GetThemeColor3fv(TH_TEXT_HI, NO_ALPHA(ctx->color.text_hi)); - UI_GetThemeColor3fv(TH_TEXT, NO_ALPHA(ctx->color.text)); - UI_GetThemeColor3fv(TH_VERTEX_SELECT, NO_ALPHA(ctx->color.vertex_select)); - UI_GetThemeColor3fv(TH_VERTEX, NO_ALPHA(ctx->color.vertex)); - -#undef NO_ALPHA } void OVERLAY_edit_armature_cache_populate(OVERLAY_Data *vedata, Object *ob) diff --git a/source/blender/draw/engines/overlay/overlay_background.c b/source/blender/draw/engines/overlay/overlay_background.c new file mode 100644 index 00000000000..23aad3506ad --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_background.c @@ -0,0 +1,112 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + */ + +#include "DRW_render.h" + +#include "UI_resources.h" + +#include "overlay_private.h" +#include "draw_manager_text.h" + +#define BG_SOLID 0 +#define BG_GRADIENT 1 +#define BG_CHECKER 2 + +void OVERLAY_background_cache_init(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + OVERLAY_PrivateData *pd = vedata->stl->pd; + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + const DRWContextState *draw_ctx = DRW_context_state_get(); + const Scene *scene = draw_ctx->scene; + const RegionView3D *rv3d = draw_ctx->rv3d; + const BoundBox *bb = rv3d->clipbb; + const View3D *v3d = draw_ctx->v3d; + bool draw_clipping_bounds = (pd->clipping_state != 0); + + { + float color_override[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + int background_type; + if (!DRW_state_draw_background()) { + background_type = BG_CHECKER; + } + else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD && scene->world) { + background_type = BG_SOLID; + /* TODO(fclem) this is a scene refered linear color. we should convert + * it to display linear here. */ + copy_v3_v3(color_override, &scene->world->horr); + color_override[3] = 1.0f; + } + else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT) { + background_type = BG_SOLID; + copy_v3_v3(color_override, v3d->shading.background_color); + color_override[3] = 1.0f; + } + else if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { + background_type = BG_GRADIENT; + } + else { + background_type = BG_SOLID; + } + + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_BACKGROUND; + DRW_PASS_CREATE(psl->background_ps, state); + + GPUShader *sh = OVERLAY_shader_background(); + DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->background_ps); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &dtxl->color); + DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_vec4_copy(grp, "colorOverride", color_override); + DRW_shgroup_uniform_int_copy(grp, "bgType", background_type); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); + } + + if (draw_clipping_bounds) { + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA | DRW_STATE_CULL_BACK; + DRW_PASS_CREATE(psl->clipping_frustum_ps, state); + + GPUShader *sh = OVERLAY_shader_clipbound(); + DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->clipping_frustum_ps); + DRW_shgroup_uniform_vec4_copy(grp, "color", G_draw.block.colorClippingBorder); + DRW_shgroup_uniform_vec3(grp, "boundbox", &bb->vec[0][0], 8); + + struct GPUBatch *cube = DRW_cache_cube_get(); + DRW_shgroup_call(grp, cube, NULL); + } + else { + psl->clipping_frustum_ps = NULL; + } +} + +void OVERLAY_background_draw(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + + if (DRW_state_is_fbo()) { + if (psl->clipping_frustum_ps) { + DRW_draw_pass(psl->clipping_frustum_ps); + } + + DRW_draw_pass(psl->background_ps); + } +} diff --git a/source/blender/draw/engines/overlay/overlay_edit_text.c b/source/blender/draw/engines/overlay/overlay_edit_text.c index 72b5ae74255..3de0155d6e0 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_text.c +++ b/source/blender/draw/engines/overlay/overlay_edit_text.c @@ -56,7 +56,9 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata) DRW_PASS_CREATE(psl->edit_text_overlay_ps, state | pd->clipping_state); sh = OVERLAY_shader_uniform_color(); - pd->edit_text_overlay_grp = DRW_shgroup_create(sh, psl->edit_text_overlay_ps); + pd->edit_text_overlay_grp = grp = DRW_shgroup_create(sh, psl->edit_text_overlay_ps); + + DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, 1.0f}); } } diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c index c83b3487db0..c41fc274f17 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.c +++ b/source/blender/draw/engines/overlay/overlay_engine.c @@ -144,6 +144,7 @@ static void OVERLAY_cache_init(void *vedata) } OVERLAY_antialiasing_cache_init(vedata); OVERLAY_armature_cache_init(vedata); + OVERLAY_background_cache_init(vedata); OVERLAY_extra_cache_init(vedata); OVERLAY_facing_cache_init(vedata); OVERLAY_grid_cache_init(vedata); @@ -389,11 +390,25 @@ static void OVERLAY_draw_scene(void *vedata) OVERLAY_Data *data = vedata; OVERLAY_PrivateData *pd = data->stl->pd; OVERLAY_FramebufferList *fbl = data->fbl; + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + + if (DRW_state_is_fbo()) { + float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_framebuffer_bind(dfbl->overlay_only_fb); + GPU_framebuffer_clear_color(dfbl->overlay_only_fb, clear_col); + } + + OVERLAY_image_background_draw(vedata); + OVERLAY_background_draw(vedata); OVERLAY_antialiasing_start(vedata); DRW_view_set_active(NULL); + if (DRW_state_is_fbo()) { + GPU_framebuffer_bind(fbl->overlay_color_only_fb); + } + OVERLAY_outline_draw(vedata); if (DRW_state_is_fbo()) { @@ -503,7 +518,6 @@ DrawEngineType draw_engine_overlay_type = { &OVERLAY_cache_init, &OVERLAY_cache_populate, &OVERLAY_cache_finish, - NULL, &OVERLAY_draw_scene, NULL, NULL, diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c index 7db55ee9b34..3764994613f 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.c +++ b/source/blender/draw/engines/overlay/overlay_extra.c @@ -344,10 +344,13 @@ void OVERLAY_empty_cache_populate(OVERLAY_Data *vedata, Object *ob) } } -static void OVERLAY_bounds( - OVERLAY_ExtraCallBuffers *cb, Object *ob, int theme_id, char boundtype, bool around_origin) +static void OVERLAY_bounds(OVERLAY_ExtraCallBuffers *cb, + Object *ob, + const float *color, + char boundtype, + bool around_origin) { - float color[4], center[3], size[3], tmp[4][4], final_mat[4][4]; + float center[3], size[3], tmp[4][4], final_mat[4][4]; BoundBox bb_local; if (ob->type == OB_MBALL && !BKE_mball_is_basis(ob)) { @@ -362,7 +365,6 @@ static void OVERLAY_bounds( BKE_boundbox_init_from_minmax(bb, min, max); } - UI_GetThemeColor4fv(theme_id, color); BKE_boundbox_calc_size_aabb(bb, size); if (around_origin) { @@ -425,28 +427,28 @@ static void OVERLAY_bounds( } } -static void OVERLAY_collision(OVERLAY_ExtraCallBuffers *cb, Object *ob, int theme_id) +static void OVERLAY_collision(OVERLAY_ExtraCallBuffers *cb, Object *ob, const float *color) { switch (ob->rigidbody_object->shape) { case RB_SHAPE_BOX: - OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_BOX, true); + OVERLAY_bounds(cb, ob, color, OB_BOUND_BOX, true); break; case RB_SHAPE_SPHERE: - OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_SPHERE, true); + OVERLAY_bounds(cb, ob, color, OB_BOUND_SPHERE, true); break; case RB_SHAPE_CONE: - OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_CONE, true); + OVERLAY_bounds(cb, ob, color, OB_BOUND_CONE, true); break; case RB_SHAPE_CYLINDER: - OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_CYLINDER, true); + OVERLAY_bounds(cb, ob, color, OB_BOUND_CYLINDER, true); break; case RB_SHAPE_CAPSULE: - OVERLAY_bounds(cb, ob, theme_id, OB_BOUND_CAPSULE, true); + OVERLAY_bounds(cb, ob, color, OB_BOUND_CAPSULE, true); break; } } -static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, int theme_id) +static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, const float *color) { if (ob->data == NULL) { return; @@ -477,14 +479,12 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, int BLI_assert(0); } - float mat[4][4], color[4]; + float mat[4][4]; size_to_mat4(mat, texcosize); copy_v3_v3(mat[3], texcoloc); mul_m4_m4m4(mat, ob->obmat, mat); - UI_GetThemeColor4fv(theme_id, color); - DRW_buffer_add_entry(cb->empty_cube, color, mat); } @@ -600,7 +600,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) float *color_p; DRW_object_wire_theme_get(ob, view_layer, &color_p); /* Remove the alpha. */ - float color[4] = {color_p[0], color_p[1], color_p[2], 1.0f}; + float color[4] = {UNPACK3(color_p), 1.0f}; /* Pack render data into object matrix. */ union { float mat[4][4]; @@ -867,13 +867,13 @@ static void camera_view3d_reconstruction(OVERLAY_ExtraCallBuffers *cb, /* Index must start in 1, to mimic BKE_tracking_track_get_indexed. */ int track_index = 1; + float bundle_color_custom[3]; + float *bundle_color_solid = G_draw.block.colorBundleSolid; + float *bundle_color_unselected = G_draw.block.colorWire; uchar text_color_selected[4], text_color_unselected[4]; - float bundle_color_unselected[4], bundle_color_solid[4]; - + /* Color Management: Exception here as texts are drawn in sRGB space directly. */ UI_GetThemeColor4ubv(TH_SELECT, text_color_selected); UI_GetThemeColor4ubv(TH_TEXT, text_color_unselected); - UI_GetThemeColor4fv(TH_WIRE, bundle_color_unselected); - UI_GetThemeColor4fv(TH_BUNDLE_SOLID, bundle_color_solid); float camera_mat[4][4], normal_mat[4][4]; BKE_tracking_get_camera_object_matrix(ob, camera_mat); @@ -910,7 +910,10 @@ static void camera_view3d_reconstruction(OVERLAY_ExtraCallBuffers *cb, const float *bundle_color; if (track->flag & TRACK_CUSTOMCOLOR) { - bundle_color = track->color; + /* Meh, hardcoded srgb transform here. */ + /* TODO change the actual DNA color to be linear. */ + srgb_to_linearrgb_v3_v3(bundle_color_custom, track->color); + bundle_color = bundle_color_custom; } else if (is_solid_bundle) { bundle_color = bundle_color_solid; @@ -1346,6 +1349,7 @@ static void OVERLAY_gpencil_color_names(Object *ob) ViewLayer *view_layer = draw_ctx->view_layer; int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); uchar color[4]; + /* Color Management: Exception here as texts are drawn in sRGB space directly. */ UI_GetThemeColor4ubv(theme_id, color); struct DRWTextStore *dt = DRW_text_cache_ensure(); @@ -1525,6 +1529,7 @@ static void OVERLAY_object_name(Object *ob, int theme_id) { struct DRWTextStore *dt = DRW_text_cache_ensure(); uchar color[4]; + /* Color Management: Exception here as texts are drawn in sRGB space directly. */ UI_GetThemeColor4ubv(theme_id, color); DRW_text_cache_add(dt, @@ -1576,11 +1581,11 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob) } if (draw_bounds) { - OVERLAY_bounds(cb, ob, theme_id, ob->boundtype, false); + OVERLAY_bounds(cb, ob, color, ob->boundtype, false); } /* Helpers for when we're transforming origins. */ if (draw_xform) { - float color_xform[4] = {0.75f, 0.75f, 0.75f, 0.5f}; + float color_xform[4] = {0.15f, 0.15f, 0.15f, 0.7f}; DRW_buffer_add_entry(cb->origin_xform, color_xform, ob->obmat); } /* don't show object extras in set's */ @@ -1595,10 +1600,10 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob) OVERLAY_object_name(ob, theme_id); } if (draw_texspace) { - OVERLAY_texture_space(cb, ob, theme_id); + OVERLAY_texture_space(cb, ob, color); } if (ob->rigidbody_object != NULL) { - OVERLAY_collision(cb, ob, theme_id); + OVERLAY_collision(cb, ob, color); } if (ob->dtx & OB_AXIS) { DRW_buffer_add_entry(cb->empty_axes, color, ob->obmat); diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.c index cf90c12b357..8536c642cb6 100644 --- a/source/blender/draw/engines/overlay/overlay_image.c +++ b/source/blender/draw/engines/overlay/overlay_image.c @@ -53,11 +53,8 @@ void OVERLAY_image_cache_init(OVERLAY_Data *vedata) OVERLAY_PrivateData *pd = vedata->stl->pd; DRWState state; - state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL; - DRW_PASS_CREATE(psl->image_background_under_ps, state); - - state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA; - DRW_PASS_CREATE(psl->image_background_over_ps, state); + state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER | DRW_STATE_BLEND_ALPHA_PREMUL; + DRW_PASS_CREATE(psl->image_background_ps, state); state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS; DRW_PASS_CREATE(psl->image_empties_ps, state | pd->clipping_state); @@ -330,29 +327,18 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob) mul_m4_m4m4(mat, norm_obmat, mat); const bool is_foreground = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != 0; - float color_alpha[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha}; float color_premult_alpha[4] = {bgpic->alpha, bgpic->alpha, bgpic->alpha, bgpic->alpha}; - /* When drawing background we do 2 passes. - * - One alpha over, which works where background is visible. - * - One alpha under, works under partially visible objects. (only in cycles) - * This approach is not ideal and should be revisited. - **/ - for (int i = 0; i < (is_foreground ? 1 : 2); i++) { - DRWPass *pass = is_foreground ? psl->image_foreground_ps : - ((i == 0) ? psl->image_background_under_ps : - psl->image_background_over_ps); - GPUShader *sh = OVERLAY_shader_image(); - DRWShadingGroup *grp = DRW_shgroup_create(sh, pass); - float *color = (is_foreground || i == 1) ? color_alpha : color_premult_alpha; - DRW_shgroup_uniform_texture(grp, "imgTexture", tex); - DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult); - DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true); - DRW_shgroup_uniform_bool_copy(grp, "imgLinear", !DRW_state_do_color_management()); - DRW_shgroup_uniform_bool_copy(grp, "depthSet", true); - DRW_shgroup_uniform_vec4_copy(grp, "color", color); - DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat); - } + DRWPass *pass = is_foreground ? psl->image_foreground_ps : psl->image_background_ps; + + GPUShader *sh = OVERLAY_shader_image(); + DRWShadingGroup *grp = DRW_shgroup_create(sh, pass); + DRW_shgroup_uniform_texture(grp, "imgTexture", tex); + DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult); + DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true); + DRW_shgroup_uniform_bool_copy(grp, "depthSet", true); + DRW_shgroup_uniform_vec4_copy(grp, "color", color_premult_alpha); + DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat); } } } @@ -427,7 +413,6 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob) DRW_shgroup_uniform_texture(grp, "imgTexture", tex); DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", use_alpha_premult); DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", use_alpha_blend); - DRW_shgroup_uniform_bool_copy(grp, "imgLinear", false); DRW_shgroup_uniform_bool_copy(grp, "depthSet", depth_mode != OB_EMPTY_IMAGE_DEPTH_DEFAULT); DRW_shgroup_uniform_vec4_copy(grp, "color", ob->color); DRW_shgroup_call_obmat(grp, DRW_cache_quad_get(), mat); @@ -438,30 +423,25 @@ void OVERLAY_image_cache_finish(OVERLAY_Data *vedata) { OVERLAY_PassList *psl = vedata->psl; - DRW_pass_sort_shgroup_reverse(psl->image_background_under_ps); DRW_pass_sort_shgroup_z(psl->image_empties_blend_ps); DRW_pass_sort_shgroup_z(psl->image_empties_front_ps); DRW_pass_sort_shgroup_z(psl->image_empties_back_ps); } +void OVERLAY_image_background_draw(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + + DRW_draw_pass(psl->image_background_ps); + DRW_draw_pass(psl->image_empties_back_ps); +} + void OVERLAY_image_draw(OVERLAY_Data *vedata) { OVERLAY_PassList *psl = vedata->psl; OVERLAY_PrivateData *pd = vedata->stl->pd; - OVERLAY_FramebufferList *fbl = vedata->fbl; - - const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DRW_view_set_active(pd->view_reference_images); - DRW_draw_pass(psl->image_background_over_ps); - - if (DRW_state_is_fbo() && !DRW_pass_is_empty(psl->image_background_under_ps)) { - GPU_framebuffer_bind(dfbl->default_fb); - DRW_draw_pass(psl->image_background_under_ps); - GPU_framebuffer_bind(fbl->overlay_default_fb); - } - - DRW_draw_pass(psl->image_empties_back_ps); DRW_draw_pass(psl->image_empties_ps); DRW_draw_pass(psl->image_empties_blend_ps); diff --git a/source/blender/draw/engines/overlay/overlay_metaball.c b/source/blender/draw/engines/overlay/overlay_metaball.c index a634aed812c..76ffbe4cc6b 100644 --- a/source/blender/draw/engines/overlay/overlay_metaball.c +++ b/source/blender/draw/engines/overlay/overlay_metaball.c @@ -75,10 +75,10 @@ void OVERLAY_edit_metaball_cache_populate(OVERLAY_Data *vedata, Object *ob) MetaBall *mb = ob->data; const float *color; - const float col_radius[4] = {0.63f, 0.19f, 0.19f, 1.0f}; /* 0x3030A0 */ - const float col_radius_select[4] = {0.94f, 0.63f, 0.63f, 1.0f}; /* 0xA0A0F0 */ - const float col_stiffness[4] = {0.19f, 0.63f, 0.19f, 1.0f}; /* 0x30A030 */ - const float col_stiffness_select[4] = {0.63f, 0.94f, 0.63f, 1.0f}; /* 0xA0F0A0 */ + const float *col_radius = G_draw.block.colorMballRadius; + const float *col_radius_select = G_draw.block.colorMballRadiusSelect; + const float *col_stiffness = G_draw.block.colorMballStiffness; + const float *col_stiffness_select = G_draw.block.colorMballStiffnessSelect; int select_id = 0; if (is_select) { diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.c b/source/blender/draw/engines/overlay/overlay_motion_path.c index a532618d472..555e0084c49 100644 --- a/source/blender/draw/engines/overlay/overlay_motion_path.c +++ b/source/blender/draw/engines/overlay/overlay_motion_path.c @@ -174,6 +174,7 @@ static void motion_path_cache(OVERLAY_Data *vedata, if (show_frame_no || (show_keyframes_no && show_keyframes)) { int i; uchar col[4], col_kf[4]; + /* Color Management: Exception here as texts are drawn in sRGB space directly. */ UI_GetThemeColor3ubv(TH_TEXT_HI, col); UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col_kf); col[3] = col_kf[3] = 255; diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h index f8eeeed42ef..6ab6da9a18d 100644 --- a/source/blender/draw/engines/overlay/overlay_private.h +++ b/source/blender/draw/engines/overlay/overlay_private.h @@ -55,6 +55,8 @@ typedef struct OVERLAY_PassList { DRWPass *armature_ps[2]; DRWPass *armature_bone_select_ps; DRWPass *armature_transp_ps; + DRWPass *background_ps; + DRWPass *clipping_frustum_ps; DRWPass *edit_curve_wire_ps[2]; DRWPass *edit_curve_handle_ps; DRWPass *edit_lattice_ps; @@ -75,8 +77,7 @@ typedef struct OVERLAY_PassList { DRWPass *extra_grid_ps; DRWPass *facing_ps; DRWPass *grid_ps; - DRWPass *image_background_under_ps; - DRWPass *image_background_over_ps; + DRWPass *image_background_ps; DRWPass *image_empties_ps; DRWPass *image_empties_back_ps; DRWPass *image_empties_blend_ps; @@ -402,6 +403,9 @@ void OVERLAY_armature_in_front_draw(OVERLAY_Data *vedata); void OVERLAY_pose_cache_populate(OVERLAY_Data *vedata, Object *ob); void OVERLAY_pose_draw(OVERLAY_Data *vedata); +void OVERLAY_background_cache_init(OVERLAY_Data *vedata); +void OVERLAY_background_draw(OVERLAY_Data *vedata); + void OVERLAY_bone_instance_data_set_color_hint(BoneInstanceData *data, const float hint_color[4]); void OVERLAY_bone_instance_data_set_color(BoneInstanceData *data, const float bone_color[4]); @@ -481,6 +485,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob); void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob); void OVERLAY_image_cache_finish(OVERLAY_Data *vedata); void OVERLAY_image_draw(OVERLAY_Data *vedata); +void OVERLAY_image_background_draw(OVERLAY_Data *vedata); void OVERLAY_image_in_front_draw(OVERLAY_Data *vedata); void OVERLAY_metaball_cache_init(OVERLAY_Data *vedata); @@ -532,6 +537,8 @@ GPUShader *OVERLAY_shader_armature_shape_wire(void); GPUShader *OVERLAY_shader_armature_sphere(bool use_outline); GPUShader *OVERLAY_shader_armature_stick(void); GPUShader *OVERLAY_shader_armature_wire(void); +GPUShader *OVERLAY_shader_background(void); +GPUShader *OVERLAY_shader_clipbound(void); GPUShader *OVERLAY_shader_depth_only(void); GPUShader *OVERLAY_shader_edit_curve_handle(void); GPUShader *OVERLAY_shader_edit_curve_point(void); diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c index 7bd3cf4a067..6b8c5b23e58 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.c +++ b/source/blender/draw/engines/overlay/overlay_shader.c @@ -47,6 +47,8 @@ extern char datatoc_armature_stick_frag_glsl[]; extern char datatoc_armature_stick_vert_glsl[]; extern char datatoc_armature_wire_frag_glsl[]; extern char datatoc_armature_wire_vert_glsl[]; +extern char datatoc_background_frag_glsl[]; +extern char datatoc_clipbound_vert_glsl[]; extern char datatoc_depth_only_vert_glsl[]; extern char datatoc_edit_curve_handle_geom_glsl[]; extern char datatoc_edit_curve_handle_vert_glsl[]; @@ -129,6 +131,8 @@ typedef struct OVERLAY_Shaders { GPUShader *armature_sphere_solid; GPUShader *armature_stick; GPUShader *armature_wire; + GPUShader *background; + GPUShader *clipbound; GPUShader *depth_only; GPUShader *edit_curve_handle; GPUShader *edit_curve_point; @@ -198,6 +202,31 @@ GPUShader *OVERLAY_shader_antialiasing(void) return sh_data->antialiasing; } +GPUShader *OVERLAY_shader_background(void) +{ + OVERLAY_Shaders *sh_data = &e_data.sh_data[0]; + if (!sh_data->background) { + sh_data->background = GPU_shader_create_from_arrays({ + .vert = (const char *[]){datatoc_common_fullscreen_vert_glsl, NULL}, + .frag = + (const char *[]){datatoc_common_globals_lib_glsl, datatoc_background_frag_glsl, NULL}, + }); + } + return sh_data->background; +} + +GPUShader *OVERLAY_shader_clipbound(void) +{ + OVERLAY_Shaders *sh_data = &e_data.sh_data[0]; + if (!sh_data->clipbound) { + sh_data->clipbound = GPU_shader_create_from_arrays({ + .vert = (const char *[]){datatoc_common_view_lib_glsl, datatoc_clipbound_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL}, + }); + } + return sh_data->clipbound; +} + GPUShader *OVERLAY_shader_depth_only(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); diff --git a/source/blender/draw/engines/overlay/shaders/armature_envelope_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/armature_envelope_solid_frag.glsl index 1be9a46e8c7..e4a4f0875f8 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_envelope_solid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/armature_envelope_solid_frag.glsl @@ -20,7 +20,7 @@ void main() /* Smooth lighting factor. */ const float s = 0.2; /* [0.0-0.5] range */ float fac = clamp((n * (1.0 - s)) + s, 0.0, 1.0); - fragColor.rgb = mix(finalStateColor, finalBoneColor, fac); + fragColor.rgb = mix(finalStateColor, finalBoneColor, fac * fac); fragColor.a = alpha; } lineOutput = vec4(0.0); diff --git a/source/blender/draw/engines/overlay/shaders/armature_shape_solid_vert.glsl b/source/blender/draw/engines/overlay/shaders/armature_shape_solid_vert.glsl index a6af7214de1..5979a877681 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_shape_solid_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/armature_shape_solid_vert.glsl @@ -28,7 +28,7 @@ void main() /* Smooth lighting factor. */ const float s = 0.2; /* [0.0-0.5] range */ float fac = clamp((n * (1.0 - s)) + s, 0.0, 1.0); - finalColor.rgb = mix(state_color.rgb, bone_color.rgb, fac); + finalColor.rgb = mix(state_color.rgb, bone_color.rgb, fac * fac); finalColor.a = 1.0; vec4 worldPosition = model_mat * vec4(pos, 1.0); diff --git a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl index 0ff0fdf0870..380708795e9 100644 --- a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl @@ -64,7 +64,7 @@ void main() /* Smooth lighting factor. */ const float s = 0.2; /* [0.0-0.5] range */ float fac = clamp((dot(n, l) * (1.0 - s)) + s, 0.0, 1.0); - fragColor.rgb = mix(finalStateColor, finalBoneColor, fac); + fragColor.rgb = mix(finalStateColor, finalBoneColor, fac * fac); /* 2x2 dither pattern to smooth the lighting. */ float dither = (0.5 + dot(vec2(ivec2(gl_FragCoord.xy) & ivec2(1)), vec2(1.0, 2.0))) * 0.25; diff --git a/source/blender/draw/engines/overlay/shaders/background_frag.glsl b/source/blender/draw/engines/overlay/shaders/background_frag.glsl new file mode 100644 index 00000000000..737c3acb438 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/background_frag.glsl @@ -0,0 +1,73 @@ + +uniform sampler2D colorBuffer; +uniform sampler2D depthBuffer; + +uniform int bgType; +uniform vec4 colorOverride; + +in vec4 uvcoordsvar; + +out vec4 fragColor; + +#define BG_SOLID 0 +#define BG_GRADIENT 1 +#define BG_CHECKER 2 + +/* 4x4 bayer matrix prepared for 8bit UNORM precision error. */ +#define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0)) +const vec4 dither_mat4x4[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)), + vec4(P(12.0), P(4.0), P(14.0), P(6.0)), + vec4(P(3.0), P(11.0), P(1.0), P(9.0)), + vec4(P(15.0), P(7.0), P(13.0), P(5.0))); + +float dither(void) +{ + ivec2 co = ivec2(gl_FragCoord.xy) % 4; + return dither_mat4x4[co.x][co.y]; +} + +void main() +{ + /* The blend equation is: + * resutl.rgb = SRC.rgb * (1 - DST.a) + DST.rgb * (SRC.a) + * result.a = SRC.a * 0 + DST.a * SRC.a + * This removes the alpha channel and put the background behind reference images + * while masking the reference images by the render alpha. + */ + float alpha = texture(colorBuffer, uvcoordsvar.st).a; + float depth = texture(depthBuffer, uvcoordsvar.st).r; + + vec3 bg_col; + + switch (bgType) { + case BG_SOLID: + bg_col = colorBackground.rgb; + break; + case BG_GRADIENT: + /* XXX do interpolation in a non-linear space to have a better visual result. */ + vec3 col_high = pow(colorBackground.rgb, vec3(1.0 / 2.2)); + vec3 col_low = pow(colorBackgroundGradient.rgb, vec3(1.0 / 2.2)); + bg_col = mix(col_low, col_high, uvcoordsvar.t); + /* Convert back to linear. */ + bg_col = pow(bg_col, vec3(2.2)); + /* Dither to hide low precision buffer. (Could be improved) */ + bg_col += dither(); + break; + case BG_CHECKER: + float size = 8.0 * sizePixel; + ivec2 p = ivec2(floor(gl_FragCoord.xy / size)); + bool check = mod(p.x, 2) == mod(p.y, 2); + bg_col = (check) ? colorCheckerLow.rgb : colorCheckerHigh.rgb; + break; + } + + bg_col = mix(bg_col, colorOverride.rgb, colorOverride.a); + + /* Mimic alpha under behavior. Result is premultiplied. */ + fragColor = vec4(bg_col, 1.0) * (1.0 - alpha); + + /* Special case: If the render is not transparent, do not clear alpha values. */ + if (depth == 1.0 && alpha == 1.0) { + fragColor.a = 1.0; + } +} diff --git a/source/blender/draw/engines/overlay/shaders/clipbound_vert.glsl b/source/blender/draw/engines/overlay/shaders/clipbound_vert.glsl new file mode 100644 index 00000000000..1bfa5dadc32 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/clipbound_vert.glsl @@ -0,0 +1,13 @@ + +uniform vec3 boundbox[8]; + +void main() +{ + vec3 world_pos = boundbox[gl_VertexID]; + gl_Position = point_world_to_ndc(world_pos); + + /* Result in a position at 1.0 (far plane). Small epsilon to avoid precision issue. + * This mimics the effect of infinite projection matrix + * (see http://www.terathon.com/gdc07_lengyel.pdf). */ + gl_Position.z = gl_Position.w - 2.4e-7; +} diff --git a/source/blender/draw/engines/overlay/shaders/image_frag.glsl b/source/blender/draw/engines/overlay/shaders/image_frag.glsl index 0da7067851d..298ba1e27ed 100644 --- a/source/blender/draw/engines/overlay/shaders/image_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/image_frag.glsl @@ -2,7 +2,6 @@ uniform sampler2D imgTexture; uniform bool imgPremultiplied; uniform bool imgAlphaBlend; -uniform bool imgLinear; uniform vec4 color; in vec2 uvs; @@ -13,12 +12,8 @@ void main() { vec2 uvs_clamped = clamp(uvs, 0.0, 1.0); vec4 tex_color; - if (imgLinear) { - tex_color = texture_read_as_linearrgb(imgTexture, imgPremultiplied, uvs_clamped); - } - else { - tex_color = texture_read_as_srgb(imgTexture, imgPremultiplied, uvs_clamped); - } + tex_color = texture_read_as_linearrgb(imgTexture, imgPremultiplied, uvs_clamped); + fragColor = tex_color * color; if (!imgAlphaBlend) { diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c index 4701e544a04..f56482235b3 100644 --- a/source/blender/draw/engines/select/select_engine.c +++ b/source/blender/draw/engines/select/select_engine.c @@ -368,7 +368,6 @@ DrawEngineType draw_engine_select_type = { &select_cache_init, &select_cache_populate, NULL, - NULL, &select_draw_scene, NULL, NULL, diff --git a/source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl deleted file mode 100644 index 3ac220aee59..00000000000 --- a/source/blender/draw/engines/workbench/shaders/workbench_background_lib.glsl +++ /dev/null @@ -1,5 +0,0 @@ -vec3 background_color(WorldData world_data, float y) -{ - return mix(world_data.background_color_low, world_data.background_color_high, y).xyz + - (world_data.background_dither_factor * bayer_dither_noise()); -} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl index f60eca24821..0c984b094d3 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_data_lib.glsl @@ -5,17 +5,12 @@ struct LightData { }; struct WorldData { - vec4 background_color_low; - vec4 background_color_high; vec4 object_outline_color; vec4 shadow_direction_vs; LightData lights[4]; vec4 ambient_color; int num_lights; int matcap_orientation; - float background_alpha; float curvature_ridge; float curvature_valley; - float background_dither_factor; - int pad[2]; }; diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl index 45ebf09d623..22fa2babbbf 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_background_frag.glsl @@ -13,11 +13,10 @@ layout(std140) uniform world_block void main() { vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; - vec3 background = background_color(world_data, uv_viewport.y); #ifndef V3D_SHADING_OBJECT_OUTLINE - fragColor = vec4(background, world_data.background_alpha); + fragColor = vec4(0.0); #else /* !V3D_SHADING_OBJECT_OUTLINE */ @@ -25,16 +24,7 @@ void main() uint object_id = texelFetch(objectId, texel, 0).r; float object_outline = calculate_object_outline(objectId, texel, object_id); - if (object_outline == 0.0) { - fragColor = vec4(background, world_data.background_alpha); - } - else { - /* Do correct alpha blending. */ - vec4 background_color = vec4(background, 1.0) * world_data.background_alpha; - vec4 outline_color = vec4(world_data.object_outline_color.rgb, 1.0); - fragColor = mix(outline_color, background_color, object_outline); - fragColor = vec4(fragColor.rgb / max(1e-8, fragColor.a), fragColor.a); - } + fragColor = vec4(world_data.object_outline_color.rgb, 1.0) * (1.0 - object_outline); #endif /* !V3D_SHADING_OBJECT_OUTLINE */ } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl index 6915055e356..91e1ebabae4 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl @@ -25,21 +25,11 @@ void main() vec3 trans_color = trans_accum.rgb / clamp(trans_accum.a, 1e-4, 5e4); -#ifndef ALPHA_COMPOSITE - vec3 bg_color = background_color(world_data, uv_viewport.y); - - bg_color = (world_data.background_alpha == 0.0) ? trans_color : bg_color; - vec4 color = mix( - vec4(trans_color, 1.0), vec4(bg_color, world_data.background_alpha), trans_revealage); + fragColor = vec4(trans_color, 1.0 - trans_revealage); -# ifdef V3D_SHADING_OBJECT_OUTLINE +#ifdef V3D_SHADING_OBJECT_OUTLINE uint object_id = texelFetch(objectId, texel, 0).r; float outline = calculate_object_outline(objectId, texel, object_id); - color = mix(vec4(world_data.object_outline_color.rgb, 1.0), color, outline); -# endif - - fragColor = color; -#else - fragColor = vec4(trans_color, 1.0 - trans_revealage); + fragColor = mix(vec4(world_data.object_outline_color.rgb, 1.0), fragColor, outline); #endif } diff --git a/source/blender/draw/engines/workbench/solid_mode.c b/source/blender/draw/engines/workbench/solid_mode.c index e1050751830..fed7e230a86 100644 --- a/source/blender/draw/engines/workbench/solid_mode.c +++ b/source/blender/draw/engines/workbench/solid_mode.c @@ -58,13 +58,12 @@ static void workbench_solid_cache_finish(void *vedata) workbench_deferred_cache_finish(data); } -static void workbench_solid_draw_background(void *vedata) +static void workbench_solid_draw_scene(void *vedata) { WORKBENCH_Data *data = vedata; const int num_samples = workbench_num_viewport_rendering_iterations(data); for (int sample = 0; sample < num_samples; sample++) { - workbench_deferred_draw_background(data); workbench_deferred_draw_scene(data); } workbench_deferred_draw_finish(data); @@ -113,8 +112,7 @@ DrawEngineType draw_engine_workbench_solid = { &workbench_solid_cache_init, &workbench_solid_cache_populate, &workbench_solid_cache_finish, - &workbench_solid_draw_background, - NULL, + &workbench_solid_draw_scene, &workbench_solid_view_update, &workbench_solid_id_update, &workbench_render_to_image, diff --git a/source/blender/draw/engines/workbench/transparent_mode.c b/source/blender/draw/engines/workbench/transparent_mode.c index bd2fb24dd85..fef1ffded8d 100644 --- a/source/blender/draw/engines/workbench/transparent_mode.c +++ b/source/blender/draw/engines/workbench/transparent_mode.c @@ -56,13 +56,12 @@ static void workbench_transparent_cache_finish(void *vedata) workbench_forward_cache_finish(data); } -static void workbench_transparent_draw_background(void *vedata) +static void workbench_transparent_draw_scene(void *vedata) { WORKBENCH_Data *data = vedata; const int num_samples = workbench_num_viewport_rendering_iterations(data); for (int sample = 0; sample < num_samples; sample++) { - workbench_forward_draw_background(data); workbench_forward_draw_scene(data); } workbench_forward_draw_finish(data); @@ -91,8 +90,7 @@ DrawEngineType draw_engine_workbench_transparent = { &workbench_transparent_cache_init, &workbench_transparent_cache_populate, &workbench_transparent_cache_finish, - &workbench_transparent_draw_background, - NULL, + &workbench_transparent_draw_scene, &workbench_transparent_view_update, NULL, NULL, diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index f07b21ebcc2..056e6a6c364 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -99,8 +99,27 @@ static void workbench_world_data_update_shadow_direction_vs(WORKBENCH_PrivateDat /* Shadow direction. */ mul_v3_mat3_m4v3(wd->shadow_direction_vs, view_matrix, light_direction); } + /* \} */ +void workbench_clear_color_get(float color[4]) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + const Scene *scene = draw_ctx->scene; + + if (!DRW_state_is_scene_render() || !DRW_state_draw_background()) { + zero_v4(color); + } + else if (scene->world) { + copy_v3_v3(color, &scene->world->horr); + color[3] = 1.0f; + } + else { + zero_v3(color); + color[3] = 1.0f; + } +} + void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info) { effect_info->jitter_index = 0; @@ -152,39 +171,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) WORKBENCH_UBO_World *wd = &wpd->world_data; wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0; - wd->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f; - - if ((scene->world != NULL) && - (!v3d || (v3d && ((v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) || - (v3d->shading.type == OB_RENDER))))) { - copy_v3_v3(wd->background_color_low, &scene->world->horr); - copy_v3_v3(wd->background_color_high, &scene->world->horr); - } - else if (v3d && (v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT)) { - copy_v3_v3(wd->background_color_low, v3d->shading.background_color); - copy_v3_v3(wd->background_color_high, v3d->shading.background_color); - } - else if (v3d) { - UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_BACK_GRAD : TH_BACK, - wd->background_color_low); - UI_GetThemeColor3fv(TH_BACK, wd->background_color_high); - - /* XXX: Really quick conversion to avoid washed out background. - * Needs to be addressed properly (color managed using ocio). */ - if (wpd->use_color_management) { - srgb_to_linearrgb_v3_v3(wd->background_color_high, wd->background_color_high); - srgb_to_linearrgb_v3_v3(wd->background_color_low, wd->background_color_low); - } - else { - copy_v3_v3(wd->background_color_high, wd->background_color_high); - copy_v3_v3(wd->background_color_low, wd->background_color_low); - } - } - else { - zero_v3(wd->background_color_low); - zero_v3(wd->background_color_high); - } - wd->background_dither_factor = workbench_background_dither_factor(wpd); studiolight_update_world(wpd, wpd->studio_light, wd); @@ -197,13 +183,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) /* Will be NULL when rendering. */ if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) { wpd->world_clip_planes = rv3d->clip; - UI_GetThemeColor4fv(TH_V3D_CLIPPING_BORDER, wpd->world_clip_planes_color); - if (wpd->use_color_management) { - srgb_to_linearrgb_v3_v3(wpd->world_clip_planes_color, wpd->world_clip_planes_color); - } - else { - copy_v3_v3(wpd->world_clip_planes_color, wpd->world_clip_planes_color); - } } else { wpd->world_clip_planes = NULL; @@ -298,5 +277,4 @@ void workbench_private_data_free(WORKBENCH_PrivateData *wpd) } DRW_UBO_FREE_SAFE(wpd->dof_ubo); - GPU_BATCH_DISCARD_SAFE(wpd->world_clip_planes_batch); } diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index 3a62e150a9f..dfeb50248df 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -105,7 +105,6 @@ extern char datatoc_workbench_shadow_geom_glsl[]; extern char datatoc_workbench_shadow_caps_geom_glsl[]; extern char datatoc_workbench_shadow_debug_frag_glsl[]; -extern char datatoc_workbench_background_lib_glsl[]; extern char datatoc_workbench_cavity_lib_glsl[]; extern char datatoc_workbench_common_lib_glsl[]; extern char datatoc_workbench_data_lib_glsl[]; @@ -122,7 +121,6 @@ static char *workbench_build_composite_frag(WORKBENCH_PrivateData *wpd) BLI_dynstr_append(ds, datatoc_common_view_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl); - BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl); if (!FLAT_ENABLED(wpd)) { BLI_dynstr_append(ds, datatoc_workbench_world_light_lib_glsl); @@ -260,7 +258,6 @@ static GPUShader *ensure_background_shader(WORKBENCH_PrivateData *wpd) const char *defines = (index) ? "#define V3D_SHADING_OBJECT_OUTLINE\n" : NULL; char *frag = BLI_string_joinN(datatoc_workbench_data_lib_glsl, datatoc_workbench_common_lib_glsl, - datatoc_workbench_background_lib_glsl, datatoc_workbench_object_outline_lib_glsl, datatoc_workbench_deferred_background_frag_glsl); e_data.background_sh[index] = DRW_shader_create_fullscreen(frag, defines); @@ -481,8 +478,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) const float *viewport_size = DRW_viewport_size_get(); const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; const eGPUTextureFormat nor_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16 : GPU_RGBA32F; - const eGPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : - GPU_R11F_G11F_B10F; + const eGPUTextureFormat comp_tex_format = GPU_RGBA16F; const eGPUTextureFormat col_tex_format = workbench_color_texture_format(wpd); const eGPUTextureFormat id_tex_format = OBJECT_ID_PASS_ENABLED(wpd) ? GPU_R32UI : GPU_R8; @@ -718,8 +714,12 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata) /* Background Pass */ { - psl->background_pass = DRW_pass_create("Background", - DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; + if (DRW_state_is_scene_render()) { + /* Composite the scene over cleared background. */ + state |= DRW_STATE_BLEND_ALPHA_PREMUL; + } + psl->background_pass = DRW_pass_create("Background", state); grp = DRW_shgroup_create(wpd->background_sh, psl->background_pass); DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); @@ -727,14 +727,6 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata) DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx); } DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); - - if (RV3D_CLIPPING_ENABLED(draw_ctx->v3d, draw_ctx->rv3d)) { - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND); - grp = DRW_shgroup_create(shader, psl->background_pass); - wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d); - DRW_shgroup_call(grp, wpd->world_clip_planes_batch, NULL); - DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1); - } } /* Deferred Mix Pass */ @@ -1269,30 +1261,6 @@ void workbench_deferred_cache_finish(WORKBENCH_Data *vedata) } } -void workbench_deferred_draw_background(WORKBENCH_Data *vedata) -{ - WORKBENCH_StorageList *stl = vedata->stl; - WORKBENCH_FramebufferList *fbl = vedata->fbl; - WORKBENCH_PrivateData *wpd = stl->g_data; - const float clear_depth = 1.0f; - const float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - uint clear_stencil = 0x00; - - DRW_stats_group_start("Clear Background"); - - if (OBJECT_ID_PASS_ENABLED(wpd)) { - /* From all the color buffers, only object id needs to be cleared. */ - GPU_framebuffer_bind(fbl->id_clear_fb); - GPU_framebuffer_clear_color(fbl->id_clear_fb, clear_color); - } - - GPU_framebuffer_bind(fbl->prepass_fb); - int clear_bits = GPU_DEPTH_BIT; - SET_FLAG_FROM_TEST(clear_bits, SHADOW_ENABLED(wpd), GPU_STENCIL_BIT); - GPU_framebuffer_clear(fbl->prepass_fb, clear_bits, clear_color, clear_depth, clear_stencil); - DRW_stats_group_end(); -} - void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) { WORKBENCH_PassList *psl = vedata->psl; @@ -1306,8 +1274,21 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) workbench_taa_draw_scene_start(vedata); } - /* clear in background */ + const float clear_depth = 1.0f; + const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + uint clear_stencil = 0x00; + int clear_bits = GPU_DEPTH_BIT; + SET_FLAG_FROM_TEST(clear_bits, SHADOW_ENABLED(wpd), GPU_STENCIL_BIT); + + if (OBJECT_ID_PASS_ENABLED(wpd)) { + /* From all the color buffers, only object id needs to be cleared. */ + GPU_framebuffer_bind(fbl->id_clear_fb); + GPU_framebuffer_clear_color(fbl->id_clear_fb, clear_col); + } + GPU_framebuffer_bind(fbl->prepass_fb); + GPU_framebuffer_clear(fbl->prepass_fb, clear_bits, clear_col, clear_depth, clear_stencil); + DRW_draw_pass(psl->prepass_pass); DRW_draw_pass(psl->prepass_hair_pass); @@ -1334,6 +1315,13 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->cavity_pass); } + if (DRW_state_is_scene_render()) { + float clear_color[4]; + workbench_clear_color_get(clear_color); + GPU_framebuffer_bind(fbl->composite_fb); + GPU_framebuffer_clear_color(fbl->composite_fb, clear_color); + } + if (SHADOW_ENABLED(wpd)) { #ifdef DEBUG_SHADOW_VOLUME GPU_framebuffer_bind(fbl->composite_fb); diff --git a/source/blender/draw/engines/workbench/workbench_effect_aa.c b/source/blender/draw/engines/workbench/workbench_effect_aa.c index ed311db0626..c03fe5cd5c8 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_aa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_aa.c @@ -22,6 +22,8 @@ #include "ED_screen.h" +#include "draw_color_management.h" + #include "workbench_private.h" void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx) @@ -53,16 +55,9 @@ void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx) } } -static void workspace_aa_draw_transform(GPUTexture *tx, WORKBENCH_PrivateData *wpd) +static void workspace_aa_draw_transform(GPUTexture *tx, WORKBENCH_PrivateData *UNUSED(wpd)) { - if (DRW_state_do_color_management()) { - /* Display space result for viewport. */ - DRW_transform_to_display(tx, wpd->use_color_render_settings, wpd->use_color_render_settings); - } - else { - /* Linear result for render. */ - DRW_transform_none(tx); - } + DRW_transform_none(tx); } void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 05494b79af0..8d78373a057 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -72,7 +72,6 @@ extern char datatoc_workbench_forward_composite_frag_glsl[]; extern char datatoc_workbench_forward_depth_frag_glsl[]; extern char datatoc_workbench_forward_transparent_accum_frag_glsl[]; extern char datatoc_workbench_data_lib_glsl[]; -extern char datatoc_workbench_background_lib_glsl[]; extern char datatoc_workbench_checkerboard_depth_frag_glsl[]; extern char datatoc_workbench_object_outline_lib_glsl[]; extern char datatoc_workbench_curvature_lib_glsl[]; @@ -128,7 +127,6 @@ static char *workbench_build_forward_composite_frag(void) BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl); - BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl); BLI_dynstr_append(ds, datatoc_workbench_forward_composite_frag_glsl); @@ -367,8 +365,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) const float *viewport_size = DRW_viewport_size_get(); const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; - const eGPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : - GPU_R11F_G11F_B10F; + const eGPUTextureFormat comp_tex_format = GPU_RGBA16F; e_data.object_id_tx = DRW_texture_pool_query_2d( size[0], size[1], GPU_R32UI, &draw_engine_workbench_transparent); @@ -420,6 +417,10 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) /* Composite */ { int state = DRW_STATE_WRITE_COLOR; + if (DRW_state_is_scene_render()) { + /* Composite the scene over cleared background. */ + state |= DRW_STATE_BLEND_ALPHA_PREMUL; + } psl->composite_pass = DRW_pass_create("Composite", state); grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass); @@ -433,19 +434,6 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); } - /* TODO(campbell): displays but masks geometry, - * only use with wire or solid-without-xray for now. */ - if ((wpd->shading.type != OB_WIRE && !XRAY_FLAG_ENABLED(wpd)) && - RV3D_CLIPPING_ENABLED(draw_ctx->v3d, draw_ctx->rv3d)) { - psl->background_pass = DRW_pass_create("Background", - DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR_BACKGROUND); - grp = DRW_shgroup_create(shader, psl->background_pass); - wpd->world_clip_planes_batch = DRW_draw_background_clipping_batch_from_rv3d(draw_ctx->rv3d); - DRW_shgroup_call(grp, wpd->world_clip_planes_batch, NULL); - DRW_shgroup_uniform_vec4(grp, "color", &wpd->world_clip_planes_color[0], 1); - } - { workbench_aa_create_pass(vedata, &e_data.transparent_accum_tx); } @@ -783,16 +771,6 @@ void workbench_forward_cache_finish(WORKBENCH_Data *UNUSED(vedata)) { } -void workbench_forward_draw_background(WORKBENCH_Data *UNUSED(vedata)) -{ - const float clear_depth = 1.0f; - DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); - DRW_stats_group_start("Clear depth"); - GPU_framebuffer_bind(dfbl->default_fb); - GPU_framebuffer_clear_depth_stencil(dfbl->default_fb, clear_depth, 0xFF); - DRW_stats_group_end(); -} - void workbench_forward_draw_scene(WORKBENCH_Data *vedata) { WORKBENCH_PassList *psl = vedata->psl; @@ -827,6 +805,13 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata) /* Composite */ GPU_framebuffer_bind(fbl->composite_fb); + + if (DRW_state_is_scene_render()) { + float clear_color[4]; + workbench_clear_color_get(clear_color); + GPU_framebuffer_clear_color(fbl->composite_fb, clear_color); + } + DRW_draw_pass(psl->composite_pass); DRW_draw_pass(psl->volume_pass); diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index e100f6e875c..6b459c3693e 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -183,19 +183,14 @@ typedef struct WORKBENCH_UBO_Light { } WORKBENCH_UBO_Light; typedef struct WORKBENCH_UBO_World { - float background_color_low[4]; - float background_color_high[4]; float object_outline_color[4]; float shadow_direction_vs[4]; WORKBENCH_UBO_Light lights[4]; float ambient_color[4]; int num_lights; int matcap_orientation; - float background_alpha; float curvature_ridge; float curvature_valley; - float background_dither_factor; - int pad[2]; } WORKBENCH_UBO_World; BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16) @@ -249,8 +244,6 @@ typedef struct WORKBENCH_PrivateData { bool is_playback; float (*world_clip_planes)[4]; - struct GPUBatch *world_clip_planes_batch; - float world_clip_planes_color[4]; /* Volumes */ bool volumes_do; @@ -434,26 +427,15 @@ BLI_INLINE eGPUTextureFormat workbench_color_texture_format(const WORKBENCH_Priv TEXTURE_DRAWING_ENABLED(wpd)) { result = GPU_RGBA16F; } - else if (workbench_is_in_vertex_paint_mode() || VERTEX_COLORS_ENABLED(wpd)) { - result = GPU_RGBA16; - } else { - result = GPU_RGBA8; + result = GPU_RGBA16; } return result; } -BLI_INLINE bool workbench_background_dither_factor(const WORKBENCH_PrivateData *wpd) -{ - /* Only apply dithering when rendering on a RGBA8 texture. - * The dithering will remove banding when using a gradient as background */ - return workbench_color_texture_format(wpd) == GPU_RGBA8; -} - /* workbench_deferred.c */ void workbench_deferred_engine_init(WORKBENCH_Data *vedata); void workbench_deferred_engine_free(void); -void workbench_deferred_draw_background(WORKBENCH_Data *vedata); void workbench_deferred_draw_scene(WORKBENCH_Data *vedata); void workbench_deferred_draw_finish(WORKBENCH_Data *vedata); void workbench_deferred_cache_init(WORKBENCH_Data *vedata); @@ -463,7 +445,6 @@ void workbench_deferred_cache_finish(WORKBENCH_Data *vedata); /* workbench_forward.c */ void workbench_forward_engine_init(WORKBENCH_Data *vedata); void workbench_forward_engine_free(void); -void workbench_forward_draw_background(WORKBENCH_Data *vedata); void workbench_forward_draw_scene(WORKBENCH_Data *vedata); void workbench_forward_draw_finish(WORKBENCH_Data *vedata); void workbench_forward_cache_init(WORKBENCH_Data *vedata); @@ -567,6 +548,7 @@ void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info); void workbench_private_data_init(WORKBENCH_PrivateData *wpd); void workbench_private_data_free(WORKBENCH_PrivateData *wpd); void workbench_private_data_get_light_direction(float r_light_direction[3]); +void workbench_clear_color_get(float color[4]); /* workbench_volume.c */ void workbench_volume_engine_init(void); diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c index 899fbdc9b71..c8f74120113 100644 --- a/source/blender/draw/engines/workbench/workbench_render.c +++ b/source/blender/draw/engines/workbench/workbench_render.c @@ -159,7 +159,6 @@ void workbench_render(WORKBENCH_Data *data, if (RE_engine_test_break(engine)) { break; } - workbench_deferred_draw_background(data); workbench_deferred_draw_scene(data); } @@ -186,7 +185,6 @@ void workbench_render(WORKBENCH_Data *data, break; } - workbench_forward_draw_background(data); workbench_forward_draw_scene(data); } diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index ddaf851324d..60c6e66bfe9 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -122,7 +122,6 @@ typedef struct DrawEngineType { void (*cache_populate)(void *vedata, struct Object *ob); void (*cache_finish)(void *vedata); - void (*draw_background)(void *vedata); void (*draw_scene)(void *vedata); void (*view_update)(void *vedata); @@ -138,13 +137,16 @@ typedef struct DrawEngineType { /* Buffer and textures used by the viewport by default */ typedef struct DefaultFramebufferList { struct GPUFrameBuffer *default_fb; + struct GPUFrameBuffer *overlay_fb; struct GPUFrameBuffer *in_front_fb; struct GPUFrameBuffer *color_only_fb; struct GPUFrameBuffer *depth_only_fb; + struct GPUFrameBuffer *overlay_only_fb; } DefaultFramebufferList; typedef struct DefaultTextureList { struct GPUTexture *color; + struct GPUTexture *color_overlay; struct GPUTexture *depth; struct GPUTexture *depth_in_front; } DefaultTextureList; @@ -209,14 +211,6 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo); } \ } while (0) -void DRW_transform_to_display(struct GPUTexture *tex, - bool use_view_transform, - bool use_render_settings); -void DRW_transform_none(struct GPUTexture *tex); -void DRW_multisamples_resolve(struct GPUTexture *src_depth, - struct GPUTexture *src_color, - bool use_depth); - /* Shaders */ struct GPUShader *DRW_shader_create(const char *vert, const char *geom, @@ -302,7 +296,7 @@ typedef enum { DRW_STATE_BLEND_ALPHA = (1 << 18), /** Use that if color is already premult by alpha. */ DRW_STATE_BLEND_ALPHA_PREMUL = (1 << 19), - DRW_STATE_BLEND_ALPHA_UNDER_PREMUL = (1 << 20), + DRW_STATE_BLEND_BACKGROUND = (1 << 20), DRW_STATE_BLEND_OIT = (1 << 21), DRW_STATE_BLEND_MUL = (1 << 22), /** Use dual source blending. WARNING: Only one color buffer allowed. */ diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 22fd22e4818..8057d167e2f 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -679,20 +679,30 @@ GPUBatch *DRW_cache_cube_get(void) if (!SHC.drw_cube) { GPUVertFormat format = extra_vert_format(); + const int tri_len = ARRAY_SIZE(bone_box_solid_tris); + const int vert_len = ARRAY_SIZE(bone_box_verts); + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, ARRAY_SIZE(bone_box_solid_tris) * 3); + GPU_vertbuf_data_alloc(vbo, vert_len); + + GPUIndexBufBuilder elb; + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len); int v = 0; - for (int i = 0; i < ARRAY_SIZE(bone_box_solid_tris); i++) { - for (int a = 0; a < 3; a++) { - float x = bone_box_verts[bone_box_solid_tris[i][a]][0]; - float y = bone_box_verts[bone_box_solid_tris[i][a]][1] * 2.0f - 1.0f; - float z = bone_box_verts[bone_box_solid_tris[i][a]][2]; - GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, z}, VCLASS_EMPTY_SCALED}); - } + for (int i = 0; i < vert_len; i++) { + float x = bone_box_verts[i][0]; + float y = bone_box_verts[i][1] * 2.0f - 1.0f; + float z = bone_box_verts[i][2]; + GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, z}, VCLASS_EMPTY_SCALED}); + } + + for (int i = 0; i < tri_len; i++) { + const uint *tri_indices = bone_box_solid_tris[i]; + GPU_indexbuf_add_tri_verts(&elb, tri_indices[0], tri_indices[1], tri_indices[2]); } - SHC.drw_cube = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); + SHC.drw_cube = GPU_batch_create_ex( + GPU_PRIM_TRIS, vbo, GPU_indexbuf_build(&elb), GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); } return SHC.drw_cube; } diff --git a/source/blender/draw/intern/draw_color_management.c b/source/blender/draw/intern/draw_color_management.c new file mode 100644 index 00000000000..33000d1ecd0 --- /dev/null +++ b/source/blender/draw/intern/draw_color_management.c @@ -0,0 +1,63 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +/** \file + * \ingroup draw + */ + +#include + +#include "draw_manager.h" + +#include "DRW_render.h" + +#include "GPU_batch.h" +#include "GPU_framebuffer.h" +#include "GPU_matrix.h" +#include "GPU_texture.h" + +#include "BKE_colortools.h" + +#include "IMB_colormanagement.h" + +#include "draw_color_management.h" + +/* -------------------------------------------------------------------- */ +/** \name Color Management + * \{ */ + +/* Draw texture to framebuffer without any color transforms */ +void DRW_transform_none(GPUTexture *tex) +{ + drw_state_set(DRW_STATE_WRITE_COLOR); + + GPU_matrix_identity_set(); + GPU_matrix_identity_projection_set(); + + /* Draw as texture for final render (without immediate mode). */ + GPUBatch *geom = DRW_cache_fullscreen_quad_get(); + GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR); + GPU_batch_uniform_4f(geom, "color", 1.0f, 1.0f, 1.0f, 1.0f); + GPU_batch_uniform_1i(geom, "image", 0); + + GPU_texture_bind(tex, 0); + GPU_batch_draw(geom); + GPU_texture_unbind(tex); +} + +/** \} */ diff --git a/source/blender/draw/intern/draw_color_management.h b/source/blender/draw/intern/draw_color_management.h new file mode 100644 index 00000000000..9d83eccdce9 --- /dev/null +++ b/source/blender/draw/intern/draw_color_management.h @@ -0,0 +1,28 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +/** \file + * \ingroup draw + */ + +#ifndef __DRAW_COLOR_MANAGEMENT_H__ +#define __DRAW_COLOR_MANAGEMENT_H__ + +void DRW_transform_none(struct GPUTexture *tex); + +#endif /* __DRAW_COLOR_MANAGEMENT_H__ */ diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 65365ef7119..a4e46b3b59f 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -88,6 +88,10 @@ void DRW_globals_update(void) UI_GetThemeColor4fv(TH_FACE_DOT, gb->colorFaceDot); UI_GetThemeColor4fv(TH_SKIN_ROOT, gb->colorSkinRoot); UI_GetThemeColor4fv(TH_BACK, gb->colorBackground); + UI_GetThemeColor4fv(TH_BACK_GRAD, gb->colorBackgroundGradient); + UI_COLOR_RGBA_FROM_U8(0x26, 0x26, 0x26, 0xFF, gb->colorCheckerLow); + UI_COLOR_RGBA_FROM_U8(0x33, 0x33, 0x33, 0xFF, gb->colorCheckerHigh); + UI_GetThemeColor4fv(TH_V3D_CLIPPING_BORDER, gb->colorClippingBorder); /* Custom median color to slightly affect the edit mesh colors. */ interp_v4_v4v4(gb->colorEditMeshMiddle, gb->colorVertexSelect, gb->colorWireEdit, 0.35f); @@ -108,6 +112,26 @@ void DRW_globals_update(void) zero_v4(gb->colorFaceFreestyle); #endif + UI_GetThemeColor4fv(TH_TEXT, gb->colorText); + UI_GetThemeColor4fv(TH_TEXT_HI, gb->colorTextHi); + + /* Bone colors */ + UI_GetThemeColor4fv(TH_BONE_POSE, gb->colorBonePose); + UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, gb->colorBonePoseActive); + UI_GetThemeColorShade4fv(TH_EDGE_SELECT, 60, gb->colorBoneActive); + UI_GetThemeColorShade4fv(TH_EDGE_SELECT, -20, gb->colorBoneSelect); + UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, gb->colorBonePoseActiveUnsel); + UI_GetThemeColorBlendShade3fv(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, gb->colorBoneActiveUnsel); + UI_COLOR_RGBA_FROM_U8(255, 150, 0, 80, gb->colorBonePoseTarget); + UI_COLOR_RGBA_FROM_U8(255, 255, 0, 80, gb->colorBonePoseIK); + UI_COLOR_RGBA_FROM_U8(200, 255, 0, 80, gb->colorBonePoseSplineIK); + UI_COLOR_RGBA_FROM_U8(0, 255, 120, 80, gb->colorBonePoseConstraint); + UI_GetThemeColor4fv(TH_BONE_SOLID, gb->colorBoneSolid); + UI_GetThemeColor4fv(TH_BONE_LOCKED_WEIGHT, gb->colorBoneLocked); + copy_v4_fl4(gb->colorBoneIKLine, 0.8f, 0.5f, 0.0f, 1.0f); + copy_v4_fl4(gb->colorBoneIKLineNoTarget, 0.8f, 0.8f, 0.2f, 1.0f); + copy_v4_fl4(gb->colorBoneIKLineSpline, 0.8f, 0.8f, 0.2f, 1.0f); + /* Curve */ UI_GetThemeColor4fv(TH_HANDLE_FREE, gb->colorHandleFree); UI_GetThemeColor4fv(TH_HANDLE_AUTO, gb->colorHandleAuto); @@ -125,10 +149,14 @@ void DRW_globals_update(void) UI_GetThemeColor4fv(TH_NURB_SEL_VLINE, gb->colorNurbSelVline); UI_GetThemeColor4fv(TH_ACTIVE_SPLINE, gb->colorActiveSpline); - UI_GetThemeColor4fv(TH_BONE_POSE, gb->colorBonePose); - UI_GetThemeColor4fv(TH_CFRAME, gb->colorCurrentFrame); + /* Metaball */ + UI_COLOR_RGBA_FROM_U8(0xA0, 0x30, 0x30, 0xFF, gb->colorMballRadius); + UI_COLOR_RGBA_FROM_U8(0xF0, 0xA0, 0xA0, 0xFF, gb->colorMballRadiusSelect); + UI_COLOR_RGBA_FROM_U8(0x30, 0xA0, 0x30, 0xFF, gb->colorMballStiffness); + UI_COLOR_RGBA_FROM_U8(0xA0, 0xF0, 0xA0, 0xFF, gb->colorMballStiffnessSelect); + /* Grid */ UI_GetThemeColorShade4fv(TH_GRID, 10, gb->colorGrid); /* emphasise division lines lighter instead of darker, if background is darker than grid */ @@ -173,7 +201,7 @@ void DRW_globals_update(void) invert_v2(gb->sizeViewportInv); /* Color management. */ - if (!DRW_state_do_color_management()) { + { float *color = gb->UBO_FIRST_COLOR; do { /* TODO more accurate transform. */ diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 97afb5e6aa4..bea287da4e9 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -79,6 +79,10 @@ typedef struct GlobalsUboStorage { float colorLightNoAlpha[4]; float colorBackground[4]; + float colorBackgroundGradient[4]; + float colorCheckerLow[4]; + float colorCheckerHigh[4]; + float colorClippingBorder[4]; float colorEditMeshMiddle[4]; float colorHandleFree[4]; @@ -98,6 +102,30 @@ typedef struct GlobalsUboStorage { float colorActiveSpline[4]; float colorBonePose[4]; + float colorBonePoseActive[4]; + float colorBonePoseActiveUnsel[4]; + float colorBonePoseConstraint[4]; + float colorBonePoseIK[4]; + float colorBonePoseSplineIK[4]; + float colorBonePoseTarget[4]; + float colorBoneSolid[4]; + float colorBoneLocked[4]; + float colorBoneActive[4]; + float colorBoneActiveUnsel[4]; + float colorBoneSelect[4]; + float colorBoneIKLine[4]; + float colorBoneIKLineNoTarget[4]; + float colorBoneIKLineSpline[4]; + + float colorText[4]; + float colorTextHi[4]; + + float colorBundleSolid[4]; + + float colorMballRadius[4]; + float colorMballRadiusSelect[4]; + float colorMballStiffness[4]; + float colorMballStiffnessSelect[4]; float colorCurrentFrame[4]; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 3dc775f92c4..6ff0da8705c 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -80,6 +80,7 @@ #include "draw_manager_text.h" #include "draw_manager_profiling.h" +#include "draw_color_management.h" /* only for callbacks */ #include "draw_cache_impl.h" @@ -131,33 +132,6 @@ static void drw_state_ensure_not_reused(DRWManager *dst) } #endif -/* -------------------------------------------------------------------- */ - -void DRW_draw_callbacks_pre_scene(void) -{ - RegionView3D *rv3d = DST.draw_ctx.rv3d; - - GPU_matrix_projection_set(rv3d->winmat); - GPU_matrix_set(rv3d->viewmat); -} - -void DRW_draw_callbacks_post_scene(void) -{ - RegionView3D *rv3d = DST.draw_ctx.rv3d; - - GPU_matrix_projection_set(rv3d->winmat); - GPU_matrix_set(rv3d->viewmat); -} - -struct DRWTextStore *DRW_text_cache_ensure(void) -{ - BLI_assert(DST.text_store_p); - if (*DST.text_store_p == NULL) { - *DST.text_store_p = DRW_text_cache_create(); - } - return *DST.text_store_p; -} - /* -------------------------------------------------------------------- */ /** \name Settings * \{ */ @@ -299,199 +273,38 @@ struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob)) /** \name Color Management * \{ */ -/* Use color management profile to draw texture to framebuffer */ -void DRW_transform_to_display(GPUTexture *tex, bool use_view_transform, bool use_render_settings) +static void drw_viewport_colormanagement_set(void) { - drw_state_set(DRW_STATE_WRITE_COLOR); - - GPUVertFormat *vert_format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - const float dither = 1.0f; - - bool use_ocio = false; - - /* Should we apply the view transform */ - if (DRW_state_do_color_management()) { - Scene *scene = DST.draw_ctx.scene; - ColorManagedDisplaySettings *display_settings = &scene->display_settings; - ColorManagedViewSettings view_settings; - if (use_render_settings) { - /* Use full render settings, for renders with scene lighting. */ - view_settings = scene->view_settings; - } - else if (use_view_transform) { - /* Use only view transform + look and nothing else for lookdev without - * scene lighting, as exposure depends on scene light intensity. */ - BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL); - STRNCPY(view_settings.view_transform, scene->view_settings.view_transform); - STRNCPY(view_settings.look, scene->view_settings.look); - } - else { - /* For workbench use only default view transform in configuration, - * using no scene settings. */ - BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL); - } - - use_ocio = IMB_colormanagement_setup_glsl_draw_from_space( - &view_settings, display_settings, NULL, dither, false); - } - - if (!use_ocio) { - /* View transform is already applied for offscreen, don't apply again, see: T52046 */ - if (DST.options.is_image_render && !DST.options.is_scene_render) { - immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); - immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f); - } - else { - immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB); - } - immUniform1i("image", 0); - } - - GPU_texture_bind(tex, 0); /* OCIO texture bind point is 0 */ - - float mat[4][4]; - unit_m4(mat); - immUniformMatrix4fv("ModelViewProjectionMatrix", mat); - - /* Full screen triangle */ - immBegin(GPU_PRIM_TRIS, 3); - immAttr2f(texco, 0.0f, 0.0f); - immVertex2f(pos, -1.0f, -1.0f); - - immAttr2f(texco, 2.0f, 0.0f); - immVertex2f(pos, 3.0f, -1.0f); + Scene *scene = DST.draw_ctx.scene; + View3D *v3d = DST.draw_ctx.v3d; - immAttr2f(texco, 0.0f, 2.0f); - immVertex2f(pos, -1.0f, 3.0f); - immEnd(); + ColorManagedDisplaySettings *display_settings = &scene->display_settings; + ColorManagedViewSettings view_settings; + float dither = 0.0f; - GPU_texture_unbind(tex); + bool use_render_settings = v3d && (v3d->shading.type == OB_RENDER); + bool use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL); - if (use_ocio) { - IMB_colormanagement_finish_glsl_draw(); + if (use_render_settings) { + /* Use full render settings, for renders with scene lighting. */ + view_settings = scene->view_settings; + dither = scene->r.dither_intensity; } - else { - immUnbindProgram(); - } -} - -/* Draw texture to framebuffer without any color transforms */ -void DRW_transform_none(GPUTexture *tex) -{ - drw_state_set(DRW_STATE_WRITE_COLOR); - - /* Draw as texture for final render (without immediate mode). */ - GPUBatch *geom = DRW_cache_fullscreen_quad_get(); - GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR); - - GPU_texture_bind(tex, 0); - - const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - GPU_batch_uniform_4fv(geom, "color", white); - - float mat[4][4]; - unit_m4(mat); - GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); - - GPU_batch_program_use_begin(geom); - GPU_batch_bind(geom); - GPU_batch_draw_advanced(geom, 0, 0, 0, 0); - GPU_batch_program_use_end(geom); - - GPU_texture_unbind(tex); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Multisample Resolve - * \{ */ - -/** - * Use manual multisample resolve pass. - * Much quicker than blitting back and forth. - * Assume destination fb is bound. - */ -void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool use_depth) -{ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL; - - if (use_depth) { - state |= DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; - } - drw_state_set(state); - - int samples = GPU_texture_samples(src_depth); - - BLI_assert(samples > 0); - BLI_assert(GPU_texture_samples(src_color) == samples); - - GPUBatch *geom = DRW_cache_fullscreen_quad_get(); - - int builtin; - if (use_depth) { - switch (samples) { - case 2: - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST; - break; - case 4: - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST; - break; - case 8: - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST; - break; - case 16: - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST; - break; - default: - BLI_assert(!"Mulisample count unsupported by blit shader."); - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST; - break; - } + else if (use_view_transform) { + /* Use only view transform + look and nothing else for lookdev without + * scene lighting, as exposure depends on scene light intensity. */ + BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL); + STRNCPY(view_settings.view_transform, scene->view_settings.view_transform); + STRNCPY(view_settings.look, scene->view_settings.look); + dither = scene->r.dither_intensity; } else { - switch (samples) { - case 2: - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2; - break; - case 4: - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4; - break; - case 8: - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8; - break; - case 16: - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16; - break; - default: - BLI_assert(!"Mulisample count unsupported by blit shader."); - builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2; - break; - } - } - - GPU_batch_program_set_builtin(geom, builtin); - - if (use_depth) { - GPU_texture_bind(src_depth, 0); - GPU_batch_uniform_1i(geom, "depthMulti", 0); + /* For workbench use only default view transform in configuration, + * using no scene settings. */ + BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL); } - GPU_texture_bind(src_color, 1); - GPU_batch_uniform_1i(geom, "colorMulti", 1); - - float mat[4][4]; - unit_m4(mat); - GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat); - - /* avoid gpuMatrix calls */ - GPU_batch_program_use_begin(geom); - GPU_batch_bind(geom); - GPU_batch_draw_advanced(geom, 0, 0, 0, 0); - GPU_batch_program_use_end(geom); + GPU_viewport_colorspace_set(DST.viewport, &view_settings, display_settings, dither); } /** \} */ @@ -1204,39 +1017,6 @@ static void drw_engines_cache_finish(void) MEM_freeN(DST.vedata_array); } -static bool drw_engines_draw_background(void) -{ - for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { - DrawEngineType *engine = link->data; - ViewportEngineData *data = drw_viewport_engine_data_ensure(engine); - - if (engine->draw_background) { - PROFILE_START(stime); - - DRW_stats_group_start(engine->idname); - engine->draw_background(data); - DRW_stats_group_end(); - - PROFILE_END_UPDATE(data->background_time, stime); - 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 - * interfered 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); -} - static void drw_engines_draw_scene(void) { for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { @@ -1492,6 +1272,112 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Callbacks + * \{ */ + +void DRW_draw_callbacks_pre_scene(void) +{ + RegionView3D *rv3d = DST.draw_ctx.rv3d; + + GPU_matrix_projection_set(rv3d->winmat); + GPU_matrix_set(rv3d->viewmat); + + if (DST.draw_ctx.evil_C) { + ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW); + DRW_state_reset(); + } +} + +void DRW_draw_callbacks_post_scene(void) +{ + RegionView3D *rv3d = DST.draw_ctx.rv3d; + ARegion *ar = DST.draw_ctx.ar; + View3D *v3d = DST.draw_ctx.v3d; + Depsgraph *depsgraph = DST.draw_ctx.depsgraph; + + const bool do_annotations = (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && + ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0)); + + if (DST.draw_ctx.evil_C) { + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + + DRW_state_reset(); + + GPU_framebuffer_bind(dfbl->overlay_fb); + /* Disable sRGB encoding from the fixed function pipeline since all the drawing in this + * function is done with sRGB color. Avoid double transform. */ + glDisable(GL_FRAMEBUFFER_SRGB); + + /* annotations - temporary drawing buffer (3d space) */ + /* XXX: Or should we use a proper draw/overlay engine for this case? */ + if (do_annotations) { + GPU_depth_test(false); + /* XXX: as scene->gpd is not copied for COW yet */ + ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true); + GPU_depth_test(true); + } + + drw_debug_draw(); + + GPU_matrix_projection_set(rv3d->winmat); + GPU_matrix_set(rv3d->viewmat); + + GPU_depth_test(false); + ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW); + + /* Callback can be nasty and do whatever they want with the state. + * Don't trust them! */ + DRW_state_reset(); + + /* needed so gizmo isn't obscured */ + if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) { + GPU_depth_test(false); + DRW_draw_gizmo_3d(); + } + + GPU_depth_test(false); + drw_engines_draw_text(); + + DRW_draw_region_info(); + + /* annotations - temporary drawing buffer (screenspace) */ + /* XXX: Or should we use a proper draw/overlay engine for this case? */ + if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) { + GPU_depth_test(false); + /* XXX: as scene->gpd is not copied for COW yet */ + ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false); + } + + if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) { + /* Draw 2D after region info so we can draw on top of the camera passepartout overlay. + * 'DRW_draw_region_info' sets the projection in pixel-space. */ + GPU_depth_test(false); + DRW_draw_gizmo_2d(); + } + + if (G.debug_value > 20 && G.debug_value < 30) { + GPU_depth_test(false); + /* local coordinate visible rect inside region, to accommodate overlapping ui */ + const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar); + DRW_stats_draw(rect); + } + + GPU_depth_test(true); + } +} + +struct DRWTextStore *DRW_text_cache_ensure(void) +{ + BLI_assert(DST.text_store_p); + if (*DST.text_store_p == NULL) { + *DST.text_store_p = DRW_text_cache_create(); + } + return *DST.text_store_p; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Main Draw Loops (DRW_draw) * \{ */ @@ -1533,8 +1419,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, Scene *scene = DEG_get_evaluated_scene(depsgraph); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); RegionView3D *rv3d = ar->regiondata; - const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && - ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0)); DST.draw_ctx.evil_C = evil_C; DST.viewport = viewport; @@ -1554,7 +1438,9 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, .evil_C = DST.draw_ctx.evil_C, }; drw_context_state_init(); + drw_viewport_var_init(); + drw_viewport_colormanagement_set(); const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; /* Check if scene needs to perform the populate loop */ @@ -1622,89 +1508,19 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, /* Start Drawing */ DRW_state_reset(); - DRW_hair_update(); - - const bool background_drawn = drw_engines_draw_background(); - GPU_framebuffer_bind(DST.default_framebuffer); + GPU_framebuffer_clear_depth_stencil(DST.default_framebuffer, 1.0f, 0xFF); + + DRW_hair_update(); DRW_draw_callbacks_pre_scene(); - if (DST.draw_ctx.evil_C) { - ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW); - } drw_engines_draw_scene(); - if (!background_drawn) { - drw_draw_background_alpha_under(); - } - - drw_debug_draw(); - /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */ GPU_flush(); - /* annotations - temporary drawing buffer (3d space) */ - /* XXX: Or should we use a proper draw/overlay engine for this case? */ - if (do_annotations) { - GPU_depth_test(false); - /* XXX: as scene->gpd is not copied for COW yet */ - ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true); - GPU_depth_test(true); - } - DRW_draw_callbacks_post_scene(); - DRW_state_reset(); - - if (DST.draw_ctx.evil_C) { - GPU_depth_test(false); - ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW); - GPU_depth_test(true); - /* Callback can be nasty and do whatever they want with the state. - * Don't trust them! */ - DRW_state_reset(); - } - - GPU_depth_test(false); - drw_engines_draw_text(); - GPU_depth_test(true); - - if (DST.draw_ctx.evil_C) { - /* needed so gizmo isn't obscured */ - if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) { - glDisable(GL_DEPTH_TEST); - DRW_draw_gizmo_3d(); - } - - DRW_draw_region_info(); - - /* annotations - temporary drawing buffer (screenspace) */ - /* XXX: Or should we use a proper draw/overlay engine for this case? */ - if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) { - GPU_depth_test(false); - /* XXX: as scene->gpd is not copied for COW yet */ - ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false); - GPU_depth_test(true); - } - - if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) { - /* Draw 2D after region info so we can draw on top of the camera passepartout overlay. - * 'DRW_draw_region_info' sets the projection in pixel-space. */ - GPU_depth_test(false); - DRW_draw_gizmo_2d(); - GPU_depth_test(true); - } - } - - DRW_stats_reset(); - - if (G.debug_value > 20 && G.debug_value < 30) { - GPU_depth_test(false); - /* local coordinate visible rect inside region, to accommodate overlapping ui */ - const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar); - DRW_stats_draw(rect); - GPU_depth_test(true); - } if (WM_draw_region_get_bound_viewport(ar)) { /* Don't unbind the framebuffer yet in this case and let @@ -1755,10 +1571,10 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph, /* Create temporary viewport if needed. */ GPUViewport *render_viewport = viewport; if (viewport == NULL) { - render_viewport = GPU_viewport_create_from_offscreen(ofs); + render_viewport = GPU_viewport_create(); } - GPU_framebuffer_restore(); + GPU_viewport_bind_from_offscreen(render_viewport, ofs); /* Reset before using it. */ drw_state_prepare_clean_for_draw(&DST); @@ -1767,15 +1583,12 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph, DST.options.draw_background = draw_background; DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, render_viewport, NULL); + GPU_viewport_unbind_from_offscreen(render_viewport, ofs, do_color_management); + /* Free temporary viewport. */ if (viewport == NULL) { - /* don't free data owned by 'ofs' */ - GPU_viewport_clear_from_offscreen(render_viewport); GPU_viewport_free(render_viewport); } - - /* we need to re-bind (annoying!) */ - GPU_offscreen_bind(ofs, false); } /* Helper to check if exit object type to render. */ @@ -2379,8 +2192,6 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, DRW_state_lock(0); - DRW_draw_callbacks_post_scene(); - DRW_state_reset(); drw_engines_disable(); @@ -2477,9 +2288,7 @@ static void drw_draw_depth_loop_imp(struct Depsgraph *depsgraph, DRW_hair_update(); - DRW_draw_callbacks_pre_scene(); drw_engines_draw_scene(); - DRW_draw_callbacks_post_scene(); DRW_state_reset(); diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 75d5a5c73b9..23a3e0b05d4 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -234,11 +234,11 @@ void drw_state_set(DRWState state) /* Blending (all buffer) */ { int test; - if (CHANGED_ANY_STORE_VAR(DRW_STATE_BLEND_ALPHA | DRW_STATE_BLEND_ALPHA_PREMUL | - DRW_STATE_BLEND_ADD | DRW_STATE_BLEND_MUL | - DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_OIT | - DRW_STATE_BLEND_ALPHA_UNDER_PREMUL | DRW_STATE_BLEND_CUSTOM, - test)) { + if (CHANGED_ANY_STORE_VAR( + DRW_STATE_BLEND_ALPHA | DRW_STATE_BLEND_ALPHA_PREMUL | DRW_STATE_BLEND_ADD | + DRW_STATE_BLEND_MUL | DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_OIT | + DRW_STATE_BLEND_BACKGROUND | DRW_STATE_BLEND_CUSTOM | DRW_STATE_LOGIC_INVERT, + test)) { if (test) { glEnable(GL_BLEND); @@ -248,8 +248,12 @@ void drw_state_set(DRWState state) GL_ONE, GL_ONE_MINUS_SRC_ALPHA); /* Alpha */ } - else if ((state & DRW_STATE_BLEND_ALPHA_UNDER_PREMUL) != 0) { - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); + else if ((state & DRW_STATE_BLEND_BACKGROUND) != 0) { + /* Special blend to add color under and multiply dst by alpha. */ + glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, + GL_SRC_ALPHA, /* RGB */ + GL_ZERO, + GL_SRC_ALPHA); /* Alpha */ } else if ((state & DRW_STATE_BLEND_ALPHA_PREMUL) != 0) { glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); @@ -279,6 +283,13 @@ void drw_state_set(DRWState state) * Can only be used with one Draw Buffer. */ glBlendFunc(GL_ONE, GL_SRC1_COLOR); } + else if ((state & DRW_STATE_LOGIC_INVERT) != 0) { + /* Replace logic op by blend func to support floating point framebuffer. */ + glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR, + GL_ZERO, /* RGB */ + GL_ZERO, + GL_ONE); /* Alpha */ + } else { BLI_assert(0); } @@ -324,21 +335,6 @@ void drw_state_set(DRWState state) } } - /* Logic Ops */ - { - int test; - if ((test = CHANGED_TO(DRW_STATE_LOGIC_INVERT))) { - if (test == 1) { - glLogicOp(GL_INVERT); - glEnable(GL_COLOR_LOGIC_OP); - } - else { - glLogicOp(GL_COPY); - glDisable(GL_COLOR_LOGIC_OP); - } - } - } - /* Clip Planes */ { int test; diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 58643eb12a8..80a7760a571 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -57,95 +57,6 @@ void DRW_draw_region_info(void) view3d_draw_region_info(draw_ctx->evil_C, ar); } -/* ************************* 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) -{ - drw_state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL); - if (do_alpha_checker) { - /* Transparent render, do alpha checker. */ - GPU_matrix_push(); - GPU_matrix_identity_set(); - GPU_matrix_identity_projection_set(); - - imm_draw_box_checker_2d(-1.0f, -1.0f, 1.0f, 1.0f); - - GPU_matrix_pop(); - } - else { - float m[4][4]; - unit_m4(m); - - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint color = GPU_vertformat_attr_add( - format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); - uchar col_hi[3], col_lo[3]; - - GPU_matrix_push(); - GPU_matrix_identity_set(); - GPU_matrix_projection_set(m); - - immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR_DITHER); - - 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); - immVertex2f(pos, -1.0f, -1.0f); - immVertex2f(pos, 1.0f, -1.0f); - - immAttr3ubv(color, col_hi); - immVertex2f(pos, 1.0f, 1.0f); - immVertex2f(pos, -1.0f, 1.0f); - immEnd(); - - immUnbindProgram(); - - GPU_matrix_pop(); - } -} - -GPUBatch *DRW_draw_background_clipping_batch_from_rv3d(const RegionView3D *rv3d) -{ - const BoundBox *bb = rv3d->clipbb; - const uint clipping_index[6][4] = { - {0, 1, 2, 3}, - {0, 4, 5, 1}, - {4, 7, 6, 5}, - {7, 3, 2, 6}, - {1, 5, 6, 2}, - {7, 4, 0, 3}, - }; - GPUVertBuf *vbo; - GPUIndexBuf *el; - GPUIndexBufBuilder elb = {0}; - - /* Elements */ - GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, ARRAY_SIZE(clipping_index) * 2, ARRAY_SIZE(bb->vec)); - for (int i = 0; i < ARRAY_SIZE(clipping_index); i++) { - const uint *idx = clipping_index[i]; - GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]); - GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[2], idx[3]); - } - el = GPU_indexbuf_build(&elb); - - GPUVertFormat format = {0}; - uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - - vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, ARRAY_SIZE(bb->vec)); - GPU_vertbuf_attr_fill(vbo, pos_id, bb->vec); - - return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, el, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX); -} - /* **************************** 3D Cursor ******************************** */ static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, ViewLayer *view_layer) diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h index 7be186f1c72..c8f0cd7c11c 100644 --- a/source/blender/draw/intern/draw_view.h +++ b/source/blender/draw/intern/draw_view.h @@ -30,6 +30,4 @@ void DRW_draw_cursor(void); void DRW_draw_gizmo_3d(void); void DRW_draw_gizmo_2d(void); -struct GPUBatch *DRW_draw_background_clipping_batch_from_rv3d(const struct RegionView3D *rv3d); - #endif /* __DRAW_VIEW_H__ */ diff --git a/source/blender/draw/intern/shaders/common_globals_lib.glsl b/source/blender/draw/intern/shaders/common_globals_lib.glsl index 676492f227d..1777b5e23fc 100644 --- a/source/blender/draw/intern/shaders/common_globals_lib.glsl +++ b/source/blender/draw/intern/shaders/common_globals_lib.glsl @@ -42,6 +42,10 @@ layout(std140) uniform globalsBlock vec4 colorLightNoAlpha; vec4 colorBackground; + vec4 colorBackgroundGradient; + vec4 colorCheckerLow; + vec4 colorCheckerHigh; + vec4 colorClippingBorder; vec4 colorEditMeshMiddle; vec4 colorHandleFree; @@ -61,6 +65,30 @@ layout(std140) uniform globalsBlock vec4 colorActiveSpline; vec4 colorBonePose; + vec4 colorBonePoseActive; + vec4 colorBonePoseActiveUnsel; + vec4 colorBonePoseConstraint; + vec4 colorBonePoseIK; + vec4 colorBonePoseSplineIK; + vec4 colorBonePoseTarget; + vec4 colorBoneSolid; + vec4 colorBoneLocked; + vec4 colorBoneActive; + vec4 colorBoneActiveUnsel; + vec4 colorBoneSelect; + vec4 colorBoneIKLine; + vec4 colorBoneIKLineNoTarget; + vec4 colorBoneIKLineSpline; + + vec4 colorText; + vec4 colorTextHi; + + vec4 colorBundleSolid; + + vec4 colorMballRadius; + vec4 colorMballRadiusSelect; + vec4 colorMballStiffness; + vec4 colorMballStiffnessSelect; vec4 colorCurrentFrame; diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index dc435efd86b..94c1f4cfc35 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -577,7 +577,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, if (ibuf->rect_float) { if (ibuf->float_colorspace) { ok = IMB_colormanagement_setup_glsl_draw_from_space( - view_settings, display_settings, ibuf->float_colorspace, ibuf->dither, true); + view_settings, display_settings, ibuf->float_colorspace, ibuf->dither, true, false); } else { ok = IMB_colormanagement_setup_glsl_draw( @@ -586,7 +586,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, } else { ok = IMB_colormanagement_setup_glsl_draw_from_space( - view_settings, display_settings, ibuf->rect_colorspace, ibuf->dither, false); + view_settings, display_settings, ibuf->rect_colorspace, ibuf->dither, false, false); } if (ok) { diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index b6710d8e6a5..e18eb062741 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -646,13 +646,18 @@ static void image_main_region_draw(const bContext *C, ARegion *ar) ar->draw_buffer->viewport[ar->draw_buffer->stereo ? sima->iuser.multiview_eye : 0]; DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport); GPU_framebuffer_bind(fbl->default_fb); + GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); + GPU_clear(GPU_COLOR_BIT); + + GPU_framebuffer_bind(fbl->overlay_fb); + glDisable(GL_FRAMEBUFFER_SRGB); /* XXX not supported yet, disabling for now */ scene->r.scemode &= ~R_COMP_CROP; /* clear and setup matrix */ UI_GetThemeColor3fv(TH_BACK, col); - GPU_clear_color(col[0], col[1], col[2], 0.0f); + GPU_clear_color(col[0], col[1], col[2], 1.0f); GPU_clear(GPU_COLOR_BIT); GPU_depth_test(false); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 25f9ef886e9..ea8bcfda92c 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -168,7 +168,7 @@ data_to_c_simple(shaders/gpu_shader_2D_image_rect_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_image_multi_rect_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_desaturate_frag.glsl SRC) -data_to_c_simple(shaders/gpu_shader_image_linear_frag.glsl SRC) +data_to_c_simple(shaders/gpu_shader_image_overlays_merge_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC) diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h index 3616189e673..fc7dff5d99b 100644 --- a/source/blender/gpu/GPU_batch.h +++ b/source/blender/gpu/GPU_batch.h @@ -126,6 +126,7 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo); void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *); void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *); void GPU_batch_program_set_shader(GPUBatch *, GPUShader *shader); +void GPU_batch_program_set_imm_shader(GPUBatch *batch); void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id); void GPU_batch_program_set_builtin_with_config(GPUBatch *batch, eGPUBuiltinShader shader_id, diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index e877646310b..1339873ec67 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -183,7 +183,7 @@ typedef enum eGPUBuiltinShader { GPU_SHADER_3D_DEPTH_ONLY, GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR, /* basic image drawing */ - GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB, + GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE, GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR, GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR, /** diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 73ea9da0fe6..4e24a3172dc 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -99,6 +99,7 @@ typedef enum eGPUTextureFormat { GPU_R11F_G11F_B10F, GPU_DEPTH32F_STENCIL8, GPU_DEPTH24_STENCIL8, + GPU_SRGB8_A8, /* Texture only format */ GPU_RGB16F, @@ -124,7 +125,6 @@ typedef enum eGPUTextureFormat { /* Special formats texture only */ #if 0 - GPU_SRGB8_A8, GPU_SRGB8, GPU_RGB9_E5, GPU_COMPRESSED_RG_RGTC2, diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index e692262358b..2d125032f47 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -102,8 +102,15 @@ void GPU_viewport_unbind(GPUViewport *viewport); void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect); void GPU_viewport_free(GPUViewport *viewport); -GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs); -void GPU_viewport_clear_from_offscreen(GPUViewport *viewport); +void GPU_viewport_colorspace_set(GPUViewport *viewport, + ColorManagedViewSettings *view_settings, + ColorManagedDisplaySettings *display_settings, + float dither); + +void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs); +void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport, + struct GPUOffScreen *ofs, + bool display_colorspace); ViewportMemoryPool *GPU_viewport_mempool_get(GPUViewport *viewport); struct DRWInstanceDataList *GPU_viewport_instance_data_list_get(GPUViewport *viewport); diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c index 6b5d3053594..75989db9ecf 100644 --- a/source/blender/gpu/intern/gpu_batch.c +++ b/source/blender/gpu/intern/gpu_batch.c @@ -979,6 +979,17 @@ void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id) GPU_batch_program_set_builtin_with_config(batch, shader_id, GPU_SHADER_CFG_DEFAULT); } +/* Bind program bound to IMM to the batch. + * XXX Use this with much care. Drawing with the GPUBatch API is not compatible with IMM. + * DO NOT DRAW WITH THE BATCH BEFORE CALLING immUnbindProgram. */ +void GPU_batch_program_set_imm_shader(GPUBatch *batch) +{ + GLuint program; + GPUShaderInterface *interface; + immGetProgram(&program, &interface); + GPU_batch_program_set(batch, program, interface); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index a531c22365c..b0fbb0eae49 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -513,6 +513,7 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb) if (GPU_framebuffer_active_get() != fb) { glBindFramebuffer(GL_FRAMEBUFFER, fb->object); + glEnable(GL_FRAMEBUFFER_SRGB); } gpu_framebuffer_current_set(fb); @@ -547,6 +548,7 @@ void GPU_framebuffer_restore(void) if (GPU_framebuffer_active_get() != NULL) { glBindFramebuffer(GL_FRAMEBUFFER, GPU_framebuffer_default()); gpu_framebuffer_current_set(NULL); + glDisable(GL_FRAMEBUFFER_SRGB); } } diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index bed7ab25bb9..bd3de96d636 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -168,6 +168,13 @@ void immUnbindProgram(void) imm.bound_program = 0; } +/* XXX do not use it. Special hack to use OCIO with batch API. */ +void immGetProgram(GLuint *program, GPUShaderInterface **shaderface) +{ + *program = imm.bound_program; + *shaderface = (GPUShaderInterface *)imm.shader_interface; +} + #if TRUST_NO_ONE static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType prim_type) { diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index ae2c7864e36..c950a1daaa5 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -80,7 +80,7 @@ extern char datatoc_gpu_shader_2D_nodelink_vert_glsl[]; extern char datatoc_gpu_shader_3D_image_vert_glsl[]; extern char datatoc_gpu_shader_image_frag_glsl[]; -extern char datatoc_gpu_shader_image_linear_frag_glsl[]; +extern char datatoc_gpu_shader_image_overlays_merge_frag_glsl[]; extern char datatoc_gpu_shader_image_color_frag_glsl[]; extern char datatoc_gpu_shader_image_desaturate_frag_glsl[]; extern char datatoc_gpu_shader_image_varying_color_frag_glsl[]; @@ -1008,10 +1008,10 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { .vert = datatoc_gpu_shader_2D_smooth_color_vert_glsl, .frag = datatoc_gpu_shader_2D_smooth_color_dithered_frag_glsl, }, - [GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB] = + [GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE] = { .vert = datatoc_gpu_shader_2D_image_vert_glsl, - .frag = datatoc_gpu_shader_image_linear_frag_glsl, + .frag = datatoc_gpu_shader_image_overlays_merge_frag_glsl, }, [GPU_SHADER_2D_IMAGE] = { diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h index 856a14c6868..e4443e79a8d 100644 --- a/source/blender/gpu/intern/gpu_shader_private.h +++ b/source/blender/gpu/intern/gpu_shader_private.h @@ -44,4 +44,7 @@ struct GPUShader { #endif }; +/* XXX do not use it. Special hack to use OCIO with batch API. */ +void immGetProgram(GLuint *program, GPUShaderInterface **shaderface); + #endif /* __GPU_SHADER_PRIVATE_H__ */ diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 84328b8dfd4..ccafc785526 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -51,7 +51,7 @@ static struct GPUTextureGlobal { } GG = {NULL, NULL, NULL}; /* Maximum number of FBOs a texture can be attached to. */ -#define GPU_TEX_MAX_FBO_ATTACHED 10 +#define GPU_TEX_MAX_FBO_ATTACHED 12 typedef enum eGPUTextureFormatFlag { GPU_FORMAT_DEPTH = (1 << 0), @@ -183,6 +183,7 @@ static int gpu_get_component_count(eGPUTextureFormat format) case GPU_RGBA16F: case GPU_RGBA16: case GPU_RGBA32F: + case GPU_SRGB8_A8: return 4; case GPU_RGB16F: case GPU_R11F_G11F_B10F: @@ -221,7 +222,7 @@ static void gpu_validate_data_format(eGPUTextureFormat tex_format, eGPUDataForma } } /* Byte formats */ - else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8, GPU_RGBA8UI)) { + else if (ELEM(tex_format, GPU_R8, GPU_RG8, GPU_RGBA8, GPU_RGBA8UI, GPU_SRGB8_A8)) { BLI_assert(ELEM(data_format, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT)); } /* Special case */ @@ -349,6 +350,7 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type) case GPU_DEPTH_COMPONENT32F: case GPU_RGBA8UI: case GPU_RGBA8: + case GPU_SRGB8_A8: case GPU_R11F_G11F_B10F: case GPU_R32F: case GPU_R32UI: @@ -398,6 +400,8 @@ static GLenum gpu_get_gl_internalformat(eGPUTextureFormat format) return GL_RGBA8; case GPU_RGBA8UI: return GL_RGBA8UI; + case GPU_SRGB8_A8: + return GL_SRGB8_ALPHA8; case GPU_R32F: return GL_R32F; case GPU_R32UI: diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 972ff87ebcf..a3ee2d11e56 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -27,8 +27,13 @@ #include "BLI_listbase.h" #include "BLI_rect.h" +#include "BLI_math_vector.h" #include "BLI_memblock.h" +#include "BKE_colortools.h" + +#include "IMB_colormanagement.h" + #include "DNA_vec_types.h" #include "DNA_userdef_types.h" @@ -61,7 +66,6 @@ typedef struct ViewportTempTexture { struct GPUViewport { int size[2]; - int samples; int flag; /* If engine_handles mismatch we free all ViewportEngineData in this viewport */ @@ -80,6 +84,14 @@ struct GPUViewport { /* Profiling data */ double cache_time; + + /* Color management. */ + ColorManagedViewSettings view_settings; + ColorManagedDisplaySettings display_settings; + float dither; + /* TODO(fclem) the uvimage display use the viewport but do not set any view transform for the + * moment. The end goal would be to let the GPUViewport do the color management. */ + bool do_color_management; }; enum { @@ -93,7 +105,6 @@ static void gpu_viewport_buffers_free(FramebufferList *fbl, static void gpu_viewport_storage_free(StorageList *stl, int stl_len); static void gpu_viewport_passes_free(PassList *psl, int psl_len); static void gpu_viewport_texture_pool_free(GPUViewport *viewport); -static void gpu_viewport_default_fb_create(GPUViewport *viewport, const bool high_bitdepth); void GPU_viewport_tag_update(GPUViewport *viewport) { @@ -113,67 +124,13 @@ GPUViewport *GPU_viewport_create(void) viewport->fbl = MEM_callocN(sizeof(DefaultFramebufferList), "FramebufferList"); viewport->txl = MEM_callocN(sizeof(DefaultTextureList), "TextureList"); viewport->idatalist = DRW_instance_data_list_create(); + viewport->do_color_management = false; viewport->size[0] = viewport->size[1] = -1; return viewport; } -GPUViewport *GPU_viewport_create_from_offscreen(struct GPUOffScreen *ofs) -{ - GPUViewport *viewport = GPU_viewport_create(); - GPUTexture *color, *depth; - GPUFrameBuffer *fb; - viewport->size[0] = GPU_offscreen_width(ofs); - viewport->size[1] = GPU_offscreen_height(ofs); - - GPU_offscreen_viewport_data_get(ofs, &fb, &color, &depth); - - if (GPU_texture_samples(color)) { - viewport->txl->multisample_color = color; - viewport->txl->multisample_depth = depth; - viewport->fbl->multisample_fb = fb; - gpu_viewport_default_fb_create(viewport, true); - } - else { - viewport->fbl->default_fb = fb; - viewport->txl->color = color; - viewport->txl->depth = depth; - GPU_framebuffer_ensure_config( - &viewport->fbl->color_only_fb, - {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(viewport->txl->color)}); - GPU_framebuffer_ensure_config( - &viewport->fbl->depth_only_fb, - {GPU_ATTACHMENT_TEXTURE(viewport->txl->depth), GPU_ATTACHMENT_NONE}); - /* TODO infront buffer */ - } - - return viewport; -} -/** - * Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`. - */ -void GPU_viewport_clear_from_offscreen(GPUViewport *viewport) -{ - DefaultFramebufferList *dfbl = viewport->fbl; - DefaultTextureList *dtxl = viewport->txl; - - if (dfbl->multisample_fb) { - /* GPUViewport expect the final result to be in default_fb but - * GPUOffscreen wants it in its multisample_fb, so we sync it back. */ - GPU_framebuffer_blit( - dfbl->default_fb, 0, dfbl->multisample_fb, 0, GPU_COLOR_BIT | GPU_DEPTH_BIT); - dfbl->multisample_fb = NULL; - dtxl->multisample_color = NULL; - dtxl->multisample_depth = NULL; - } - else { - viewport->fbl->default_fb = NULL; - dtxl->color = NULL; - dtxl->depth = NULL; - } -} - void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type) { ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData"); @@ -268,8 +225,7 @@ void *GPU_viewport_texture_list_get(GPUViewport *viewport) void GPU_viewport_size_get(const GPUViewport *viewport, int size[2]) { - size[0] = viewport->size[0]; - size[1] = viewport->size[1]; + copy_v2_v2_int(size, viewport->size); } /** @@ -279,8 +235,7 @@ void GPU_viewport_size_get(const GPUViewport *viewport, int size[2]) */ void GPU_viewport_size_set(GPUViewport *viewport, const int size[2]) { - viewport->size[0] = size[0]; - viewport->size[1] = size[1]; + copy_v2_v2_int(viewport->size, size); } double *GPU_viewport_cache_time_get(GPUViewport *viewport) @@ -383,69 +338,61 @@ void GPU_viewport_cache_release(GPUViewport *viewport) } } -static void gpu_viewport_default_fb_create(GPUViewport *viewport, const bool high_bitdepth) +static void gpu_viewport_default_fb_create(GPUViewport *viewport) { DefaultFramebufferList *dfbl = viewport->fbl; DefaultTextureList *dtxl = viewport->txl; int *size = viewport->size; bool ok = true; - dtxl->color = GPU_texture_create_2d( - size[0], size[1], high_bitdepth ? GPU_RGBA16F : GPU_RGBA8, NULL, NULL); - dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL); + dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL); + dtxl->color_overlay = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL); - if (!(dtxl->depth && dtxl->color)) { + /* Can be shared with GPUOffscreen. */ + if (dtxl->depth == NULL) { + dtxl->depth = GPU_texture_create_2d(size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, NULL); + } + + if (!dtxl->depth || !dtxl->color) { ok = false; goto cleanup; } - GPU_framebuffer_ensure_config( - &dfbl->default_fb, - {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)}); + GPU_framebuffer_ensure_config(&dfbl->default_fb, + { + GPU_ATTACHMENT_TEXTURE(dtxl->depth), + GPU_ATTACHMENT_TEXTURE(dtxl->color), + }); + + GPU_framebuffer_ensure_config(&dfbl->overlay_fb, + { + GPU_ATTACHMENT_TEXTURE(dtxl->depth), + GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), + }); GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, - {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE}); + { + GPU_ATTACHMENT_TEXTURE(dtxl->depth), + GPU_ATTACHMENT_NONE, + }); GPU_framebuffer_ensure_config(&dfbl->color_only_fb, - {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)}); + { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(dtxl->color), + }); + + GPU_framebuffer_ensure_config(&dfbl->overlay_only_fb, + { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), + }); ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL); + ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_fb, NULL); ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL); ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL); - -cleanup: - if (!ok) { - GPU_viewport_free(viewport); - DRW_opengl_context_disable(); - return; - } - - GPU_framebuffer_restore(); -} - -static void gpu_viewport_default_multisample_fb_create(GPUViewport *viewport) -{ - DefaultFramebufferList *dfbl = viewport->fbl; - DefaultTextureList *dtxl = viewport->txl; - int *size = viewport->size; - int samples = viewport->samples; - bool ok = true; - - dtxl->multisample_color = GPU_texture_create_2d_multisample( - size[0], size[1], GPU_RGBA8, NULL, samples, NULL); - dtxl->multisample_depth = GPU_texture_create_2d_multisample( - size[0], size[1], GPU_DEPTH24_STENCIL8, NULL, samples, NULL); - - if (!(dtxl->multisample_depth && dtxl->multisample_color)) { - ok = false; - goto cleanup; - } - - GPU_framebuffer_ensure_config(&dfbl->multisample_fb, - {GPU_ATTACHMENT_TEXTURE(dtxl->multisample_depth), - GPU_ATTACHMENT_TEXTURE(dtxl->multisample_color)}); - - ok = ok && GPU_framebuffer_check_valid(dfbl->multisample_fb, NULL); + ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_only_fb, NULL); cleanup: if (!ok) { @@ -462,15 +409,15 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) DefaultFramebufferList *dfbl = viewport->fbl; int fbl_len, txl_len; + int rect_size[2]; /* add one pixel because of scissor test */ - int rect_w = BLI_rcti_size_x(rect) + 1; - int rect_h = BLI_rcti_size_y(rect) + 1; + rect_size[0] = BLI_rcti_size_x(rect) + 1; + rect_size[1] = BLI_rcti_size_y(rect) + 1; DRW_opengl_context_enable(); if (dfbl->default_fb) { - if (rect_w != viewport->size[0] || rect_h != viewport->size[1] || - U.ogl_multisamples != viewport->samples) { + if (!equals_v2v2_int(viewport->size, rect_size)) { gpu_viewport_buffers_free((FramebufferList *)viewport->fbl, default_fbl_len, (TextureList *)viewport->txl, @@ -486,36 +433,115 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) } } - viewport->size[0] = rect_w; - viewport->size[1] = rect_h; - viewport->samples = U.ogl_multisamples; + copy_v2_v2_int(viewport->size, rect_size); gpu_viewport_texture_pool_clear_users(viewport); - /* Multisample Buffer */ - if (viewport->samples > 0) { - if (!dfbl->default_fb) { - gpu_viewport_default_multisample_fb_create(viewport); - } + if (!dfbl->default_fb) { + gpu_viewport_default_fb_create(viewport); } +} + +void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs) +{ + DefaultFramebufferList *dfbl = viewport->fbl; + DefaultTextureList *dtxl = viewport->txl; + GPUTexture *color, *depth; + GPUFrameBuffer *fb; + viewport->size[0] = GPU_offscreen_width(ofs); + viewport->size[1] = GPU_offscreen_height(ofs); + + GPU_offscreen_viewport_data_get(ofs, &fb, &color, &depth); + + /* This is the only texture we can share. */ + dtxl->depth = depth; + + gpu_viewport_texture_pool_clear_users(viewport); if (!dfbl->default_fb) { - gpu_viewport_default_fb_create(viewport, false); + gpu_viewport_default_fb_create(viewport); + } +} + +void GPU_viewport_colorspace_set(GPUViewport *viewport, + ColorManagedViewSettings *view_settings, + ColorManagedDisplaySettings *display_settings, + float dither) +{ + memcpy(&viewport->view_settings, view_settings, sizeof(*view_settings)); + memcpy(&viewport->display_settings, display_settings, sizeof(*display_settings)); + viewport->dither = dither; + viewport->do_color_management = true; +} + +static void gpu_viewport_draw_colormanaged(GPUViewport *viewport, + const rctf *rect_pos, + const rctf *rect_uv, + bool display_colorspace) +{ + DefaultTextureList *dtxl = viewport->txl; + GPUTexture *color = dtxl->color; + GPUTexture *color_overlay = dtxl->color_overlay; + + GPUVertFormat *vert_format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + bool use_ocio = false; + + if (viewport->do_color_management && display_colorspace) { + use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(&viewport->view_settings, + &viewport->display_settings, + NULL, + viewport->dither, + false, + true); + } + + if (!use_ocio) { + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE); + immUniform1i("display_transform", display_colorspace); + immUniform1i("image_texture", 0); + immUniform1i("overlays_texture", 1); + } + + GPU_texture_bind(color, 0); + GPU_texture_bind(color_overlay, 1); + + immBegin(GPU_PRIM_TRI_STRIP, 4); + + immAttr2f(texco, rect_uv->xmin, rect_uv->ymin); + immVertex2f(pos, rect_pos->xmin, rect_pos->ymin); + immAttr2f(texco, rect_uv->xmax, rect_uv->ymin); + immVertex2f(pos, rect_pos->xmax, rect_pos->ymin); + immAttr2f(texco, rect_uv->xmin, rect_uv->ymax); + immVertex2f(pos, rect_pos->xmin, rect_pos->ymax); + immAttr2f(texco, rect_uv->xmax, rect_uv->ymax); + immVertex2f(pos, rect_pos->xmax, rect_pos->ymax); + + immEnd(); + + GPU_texture_unbind(color); + GPU_texture_unbind(color_overlay); + + if (use_ocio) { + IMB_colormanagement_finish_glsl_draw(); + } + else { + immUnbindProgram(); } } void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) { DefaultFramebufferList *dfbl = viewport->fbl; + DefaultTextureList *dtxl = viewport->txl; + GPUTexture *color = dtxl->color; if (dfbl->default_fb == NULL) { return; } - DefaultTextureList *dtxl = viewport->txl; - - GPUTexture *color = dtxl->color; - const float w = (float)GPU_texture_width(color); const float h = (float)GPU_texture_height(color); @@ -526,27 +552,58 @@ void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) const float halfx = GLA_PIXEL_OFS / w; const float halfy = GLA_PIXEL_OFS / h; - float x1 = rect->xmin; - float x2 = rect->xmin + w; - float y1 = rect->ymin; - float y2 = rect->ymin + h; + rctf pos_rect = { + .xmin = rect->xmin, + .ymin = rect->ymin, + .xmax = rect->xmin + w, + .ymax = rect->ymin + h, + }; + + rctf uv_rect = { + .xmin = halfx, + .ymin = halfy, + .xmax = halfx + 1.0f, + .ymax = halfy + 1.0f, + }; + + gpu_viewport_draw_colormanaged(viewport, &pos_rect, &uv_rect, true); +} - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR); - GPU_shader_bind(shader); +/** + * Clear vars assigned from offscreen, so we don't free data owned by `GPUOffScreen`. + */ +void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport, + struct GPUOffScreen *ofs, + bool display_colorspace) +{ + DefaultFramebufferList *dfbl = viewport->fbl; + DefaultTextureList *dtxl = viewport->txl; - GPU_texture_bind(color, 0); - glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0); - glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"), - halfx, - halfy, - 1.0f + halfx, - 1.0f + halfy); - glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"), x1, y1, x2, y2); - glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), 1.0f, 1.0f, 1.0f, 1.0f); + if (dfbl->default_fb == NULL) { + return; + } - GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4); + GPU_depth_test(false); + GPU_offscreen_bind(ofs, false); - GPU_texture_unbind(color); + rctf pos_rect = { + .xmin = -1.0f, + .ymin = -1.0f, + .xmax = 1.0f, + .ymax = 1.0f, + }; + + rctf uv_rect = { + .xmin = 0.0f, + .ymin = 0.0f, + .xmax = 1.0f, + .ymax = 1.0f, + }; + + gpu_viewport_draw_colormanaged(viewport, &pos_rect, &uv_rect, display_colorspace); + + /* This one is from the offscreen. Don't free it with the viewport. */ + dtxl->depth = NULL; } void GPU_viewport_unbind(GPUViewport *UNUSED(viewport)) diff --git a/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl deleted file mode 100644 index e6acdd446d3..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_image_linear_frag.glsl +++ /dev/null @@ -1,33 +0,0 @@ - -/* Display a linear image texture into sRGB space */ - -uniform sampler2D image; - -in vec2 texCoord_interp; - -out vec4 fragColor; - -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -void linearrgb_to_srgb(vec4 col_from, out vec4 col_to) -{ - col_to.r = linearrgb_to_srgb(col_from.r); - col_to.g = linearrgb_to_srgb(col_from.g); - col_to.b = linearrgb_to_srgb(col_from.b); - col_to.a = col_from.a; -} - -void main() -{ - fragColor = texture(image, texCoord_interp.st); - - linearrgb_to_srgb(fragColor, fragColor); -} diff --git a/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl new file mode 100644 index 00000000000..e8323520af5 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_overlays_merge_frag.glsl @@ -0,0 +1,42 @@ + +/* Merge overlays texture on top of image texture and transform to display space (assume sRGB) */ + +uniform sampler2D image_texture; +uniform sampler2D overlays_texture; +uniform bool display_transform; + +in vec2 texCoord_interp; + +out vec4 fragColor; + +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308) { + return (c < 0.0) ? 0.0 : c * 12.92; + } + else { + return 1.055 * pow(c, 1.0 / 2.4) - 0.055; + } +} + +void linearrgb_to_srgb(vec4 col_from, out vec4 col_to) +{ + col_to.r = linearrgb_to_srgb(col_from.r); + col_to.g = linearrgb_to_srgb(col_from.g); + col_to.b = linearrgb_to_srgb(col_from.b); + col_to.a = col_from.a; +} + +void main() +{ + fragColor = texture(image_texture, texCoord_interp.st); + + vec4 overlay_col = texture(overlays_texture, texCoord_interp.st); + + fragColor *= 1.0 - overlay_col.a; + fragColor += overlay_col; + + if (display_transform) { + linearrgb_to_srgb(fragColor, fragColor); + } +} diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index a8434932018..a94a9797a35 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -332,7 +332,8 @@ bool IMB_colormanagement_setup_glsl_draw_from_space( const struct ColorManagedDisplaySettings *display_settings, struct ColorSpace *colorspace, float dither, - bool predivide); + bool predivide, + bool do_overlay_merge); /* Same as setup_glsl_draw, but color management settings are guessing from a given context */ bool IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C, float dither, diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 71e9da70c35..a18764cd6ab 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -105,7 +105,12 @@ typedef struct ColormanageProcessor { static struct global_glsl_state { /* Actual processor used for GLSL baked LUTs. */ - OCIO_ConstProcessorRcPtr *processor; + /* UI colorspace here refers to the display linear color space, + * i.e: The linear color space w.r.t. display chromaticity and radiometry. + * We separate the colormanagement process into two steps to be able to + * merge UI using alpha blending in the correct color space. */ + OCIO_ConstProcessorRcPtr *processor_scene_to_ui; + OCIO_ConstProcessorRcPtr *processor_ui_to_display; /* Settings of processor for comparison. */ char look[MAX_COLORSPACE_NAME]; @@ -121,7 +126,6 @@ static struct global_glsl_state { /* Container for GLSL state needed for OCIO module. */ struct OCIO_GLSLDrawState *ocio_glsl_state; - struct OCIO_GLSLDrawState *transform_ocio_glsl_state; } global_glsl_state = {NULL}; static struct global_color_picking_state { @@ -711,8 +715,12 @@ void colormanagement_init(void) void colormanagement_exit(void) { - if (global_glsl_state.processor) { - OCIO_processorRelease(global_glsl_state.processor); + if (global_glsl_state.processor_scene_to_ui) { + OCIO_processorRelease(global_glsl_state.processor_scene_to_ui); + } + + if (global_glsl_state.processor_ui_to_display) { + OCIO_processorRelease(global_glsl_state.processor_ui_to_display); } if (global_glsl_state.curve_mapping) { @@ -727,10 +735,6 @@ void colormanagement_exit(void) OCIO_freeOGLState(global_glsl_state.ocio_glsl_state); } - if (global_glsl_state.transform_ocio_glsl_state) { - OCIO_freeOGLState(global_glsl_state.transform_ocio_glsl_state); - } - if (global_color_picking_state.processor_to) { OCIO_processorRelease(global_color_picking_state.processor_to); } @@ -837,7 +841,8 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *loo const char *display, float exposure, float gamma, - const char *from_colorspace) + const char *from_colorspace, + const bool linear_output) { OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); OCIO_DisplayTransformRcPtr *dt; @@ -883,14 +888,45 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *loo OCIO_exponentTransformRelease(et); } - processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)dt); + OCIO_GroupTransformRcPtr *gt = OCIO_createGroupTransform(); + OCIO_groupTransformSetDirection(gt, true); + OCIO_groupTransformPushBack(gt, (OCIO_ConstTransformRcPtr *)dt); + + if (linear_output) { + /* TODO use correct function display. */ + OCIO_ExponentTransformRcPtr *et = OCIO_createExponentTransform(); + OCIO_exponentTransformSetValue(et, (float[4]){2.2f, 2.2f, 2.2f, 1.0f}); + OCIO_groupTransformPushBack(gt, (OCIO_ConstTransformRcPtr *)et); + OCIO_exponentTransformRelease(et); + } + + processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)gt); + OCIO_groupTransformRelease(gt); OCIO_displayTransformRelease(dt); OCIO_configRelease(config); return processor; } +static OCIO_ConstProcessorRcPtr *create_display_encoded_buffer_processor( + const char *UNUSED(display)) +{ + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + OCIO_ConstProcessorRcPtr *processor; + + /* TODO use correct function display. */ + OCIO_ExponentTransformRcPtr *et = OCIO_createExponentTransform(); + OCIO_exponentTransformSetValue(et, (float[4]){1.0f / 2.2f, 1.0f / 2.2f, 1.0f / 2.2f, 1.0f}); + + processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)et); + + OCIO_exponentTransformRelease(et); + OCIO_configRelease(config); + + return processor; +} + static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, const char *to_colorspace) { @@ -3725,7 +3761,8 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new( display_settings->display_device, applied_view_settings->exposure, applied_view_settings->gamma, - global_role_scene_linear); + global_role_scene_linear, + false); if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { cm_processor->curve_mapping = BKE_curvemapping_copy(applied_view_settings->curve_mapping); @@ -3934,7 +3971,7 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0; bool need_update = false; - need_update = global_glsl_state.processor == NULL || + need_update = global_glsl_state.processor_scene_to_ui == NULL || check_glsl_display_processor_changed( view_settings, display_settings, from_colorspace) || use_curve_mapping != global_glsl_state.use_curve_mapping; @@ -3989,17 +4026,26 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s } /* Free old processor, if any. */ - if (global_glsl_state.processor) { - OCIO_processorRelease(global_glsl_state.processor); + if (global_glsl_state.processor_scene_to_ui) { + OCIO_processorRelease(global_glsl_state.processor_scene_to_ui); + } + + if (global_glsl_state.processor_ui_to_display) { + OCIO_processorRelease(global_glsl_state.processor_ui_to_display); } /* We're using display OCIO processor, no RGB curves yet. */ - global_glsl_state.processor = create_display_buffer_processor(global_glsl_state.look, - global_glsl_state.view, - global_glsl_state.display, - global_glsl_state.exposure, - global_glsl_state.gamma, - global_glsl_state.input); + global_glsl_state.processor_scene_to_ui = create_display_buffer_processor( + global_glsl_state.look, + global_glsl_state.view, + global_glsl_state.display, + global_glsl_state.exposure, + global_glsl_state.gamma, + global_glsl_state.input, + true); + + global_glsl_state.processor_ui_to_display = create_display_encoded_buffer_processor( + global_glsl_state.display); } } @@ -4026,7 +4072,8 @@ bool IMB_colormanagement_setup_glsl_draw_from_space( const ColorManagedDisplaySettings *display_settings, struct ColorSpace *from_colorspace, float dither, - bool predivide) + bool predivide, + bool do_overlay_merge) { ColorManagedViewSettings default_view_settings; const ColorManagedViewSettings *applied_view_settings; @@ -4047,7 +4094,7 @@ bool IMB_colormanagement_setup_glsl_draw_from_space( from_colorspace ? from_colorspace->name : global_role_scene_linear); - if (global_glsl_state.processor == NULL) { + if (global_glsl_state.processor_scene_to_ui == NULL) { /* Happens when requesting non-existing color space or LUT in the * configuration file does not exist. */ @@ -4056,10 +4103,12 @@ bool IMB_colormanagement_setup_glsl_draw_from_space( return OCIO_setupGLSLDraw( &global_glsl_state.ocio_glsl_state, - global_glsl_state.processor, + global_glsl_state.processor_scene_to_ui, + global_glsl_state.processor_ui_to_display, global_glsl_state.use_curve_mapping ? &global_glsl_state.curve_mapping_settings : NULL, dither, - predivide); + predivide, + do_overlay_merge); } /* Configures GLSL shader for conversion from scene linear to display space */ @@ -4069,7 +4118,7 @@ bool IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_se bool predivide) { return IMB_colormanagement_setup_glsl_draw_from_space( - view_settings, display_settings, NULL, dither, predivide); + view_settings, display_settings, NULL, dither, predivide, false); } /** @@ -4087,7 +4136,7 @@ bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const bContext *C, IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings); return IMB_colormanagement_setup_glsl_draw_from_space( - view_settings, display_settings, from_colorspace, dither, predivide); + view_settings, display_settings, from_colorspace, dither, predivide, false); } /* Same as setup_glsl_draw, but color management settings are guessing from a given context */ diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 90c60c09181..c0daedba95c 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -101,6 +101,7 @@ const EnumPropertyItem rna_enum_bake_pass_type_items[] = { # include "IMB_colormanagement.h" # include "GPU_extensions.h" +# include "GPU_shader.h" # include "DEG_depsgraph_query.h" @@ -126,15 +127,21 @@ static int engine_get_preview_pixel_size(RenderEngine *UNUSED(engine), Scene *sc return BKE_render_preview_pixel_size(&scene->r); } -static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene) +static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *UNUSED(scene)) { - IMB_colormanagement_setup_glsl_draw( - &scene->view_settings, &scene->display_settings, scene->r.dither_intensity, false); + GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_COLOR); + GPU_shader_bind(shader); + + int img_loc = GPU_shader_get_uniform_ensure(shader, "image"); + int color_loc = GPU_shader_get_uniform_ensure(shader, "color"); + + GPU_shader_uniform_int(shader, img_loc, 0); + GPU_shader_uniform_vector(shader, color_loc, 3, 1, (float[3]){1.0f, 1.0f, 1.0f}); } static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine)) { - IMB_colormanagement_finish_glsl_draw(); + GPU_shader_unbind(); } static void engine_update(RenderEngine *engine, Main *bmain, Depsgraph *depsgraph) -- cgit v1.2.3