diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-02-11 17:18:55 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-02-11 17:19:04 +0300 |
commit | 804e90b42d728ecb1073af8d0bae15a91b13a469 (patch) | |
tree | 309de25d99c92286b10c9d27e547fd43a69299c1 /source/blender/draw/intern | |
parent | 58cdab8b9759dd59b55895f2f76b9624addbb324 (diff) |
DRW: Color Management improvement
Reviewed By: brecht sergey jbakker
Differential Revision: http://developer.blender.org/D6729
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 14 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 28 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_color_management.c | 63 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_color_management.h | 28 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.c | 34 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 28 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 469 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 40 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_view.c | 89 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_view.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/common_globals_lib.glsl | 28 |
11 files changed, 358 insertions, 465 deletions
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 <stdio.h> + +#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" @@ -132,33 +133,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) { @@ -1493,6 +1273,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; |