diff options
author | Jeroen Bakker <jeroen@blender.org> | 2022-01-31 11:57:51 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2022-01-31 11:57:51 +0300 |
commit | cfa235b89d686e00456e6d7af99442e5a73ffed8 (patch) | |
tree | 10c6bc17f305fc0b384fca8eb93c1445db525538 /source/blender/draw/engines/image/image_drawing_mode.hh | |
parent | 07514def194a78fbb70931d5fbd002248e8f3c34 (diff) |
Image Editor: Fix background drawing of empty tiles.
Empty (UDIM) tiles where drawn with a transparency checkerboard. They
should be rendered with a border background. The cause is that the image
engine would select a single area that contained all tiles and draw them
as being part of an image.
The fix is to separate the color and depth part of the image engine
shader and only draw the depths of tiles that are enabled.
Diffstat (limited to 'source/blender/draw/engines/image/image_drawing_mode.hh')
-rw-r--r-- | source/blender/draw/engines/image/image_drawing_mode.hh | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index f501bc78b11..d5a4a317a22 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -26,6 +26,8 @@ #include "IMB_imbuf_types.h" +#include "BLI_math_vec_types.hh" + #include "image_batches.hh" #include "image_private.hh" #include "image_wrappers.hh" @@ -80,13 +82,19 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD private: DRWPass *create_image_pass() const { - /* Write depth is needed for background overlay rendering. Near depth is used for - * transparency checker and Far depth is used for indicating the image size. */ - DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | - DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL); + DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | + DRW_STATE_BLEND_ALPHA_PREMUL); return DRW_pass_create("Image", state); } + DRWPass *create_depth_pass() const + { + /* Depth is needed for background overlay rendering. Near depth is used for + * transparency checker and Far depth is used for indicating the image size. */ + DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); + return DRW_pass_create("Depth", state); + } + void add_shgroups(const IMAGE_InstanceData *instance_data) const { const ShaderParameters &sh_params = instance_data->sh_params; @@ -97,7 +105,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD DRW_shgroup_uniform_vec4_copy(shgrp, "shuffle", sh_params.shuffle); DRW_shgroup_uniform_int_copy(shgrp, "drawFlags", sh_params.flags); DRW_shgroup_uniform_bool_copy(shgrp, "imgPremultiplied", sh_params.use_premul_alpha); - DRW_shgroup_uniform_vec2_copy(shgrp, "maxUv", instance_data->max_uv); float image_mat[4][4]; unit_m4(image_mat); for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) { @@ -113,6 +120,37 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD } /** + * \brief add depth drawing calls. + * + * The depth is used to identify if the tile exist or transparent. + */ + void add_depth_shgroups(IMAGE_InstanceData &instance_data, + Image *image, + ImageUser *UNUSED(image_user)) const + { + GPUShader *shader = IMAGE_shader_depth_get(); + DRWShadingGroup *shgrp = DRW_shgroup_create(shader, instance_data.passes.depth_pass); + float image_mat[4][4]; + unit_m4(image_mat); + for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) { + const TextureInfo &info = instance_data.texture_infos[i]; + if (!info.visible) { + continue; + } + + LISTBASE_FOREACH (ImageTile *, image_tile_ptr, &image->tiles) { + DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp); + const ImageTileWrapper image_tile(image_tile_ptr); + const int tile_x = image_tile.get_tile_x_offset(); + const int tile_y = image_tile.get_tile_y_offset(); + float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1); + DRW_shgroup_uniform_vec4_copy(shsub, "min_max_uv", min_max_uv); + DRW_shgroup_call_obmat(shsub, info.batch, image_mat); + } + } + } + + /** * \brief Update GPUTextures for drawing the image. * * GPUTextures that are marked dirty are rebuild. GPUTextures that aren't marked dirty are @@ -367,6 +405,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD { IMAGE_InstanceData *instance_data = vedata->instance_data; instance_data->passes.image_pass = create_image_pass(); + instance_data->passes.depth_pass = create_depth_pass(); } void cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser) const override @@ -376,7 +415,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD TextureMethod method(instance_data); instance_data->partial_update.ensure_image(image); - instance_data->max_uv_update(); instance_data->clear_dirty_flag(); // Step: Find out which screen space textures are needed to draw on the screen. Remove the @@ -391,6 +429,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD // Step: Add the GPU textures to the shgroup. instance_data->update_batches(); + add_depth_shgroups(*instance_data, image, iuser); add_shgroups(instance_data); } @@ -408,6 +447,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD GPU_framebuffer_clear_color_depth(dfbl->default_fb, clear_col, 1.0); DRW_view_set_active(instance_data->view); + DRW_draw_pass(instance_data->passes.depth_pass); DRW_draw_pass(instance_data->passes.image_pass); DRW_view_set_active(nullptr); } |