diff options
12 files changed, 93 insertions, 68 deletions
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cc b/source/blender/compositor/operations/COM_ViewerOperation.cc index bc7e08ee98a..7f0eaecfff7 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cc +++ b/source/blender/compositor/operations/COM_ViewerOperation.cc @@ -10,9 +10,9 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -namespace blender::compositor { +#include "DNA_node_types.h" -static int MAX_VIEWER_TRANSLATION_PADDING = 12000; +namespace blender::compositor { ViewerOperation::ViewerOperation() { @@ -137,23 +137,12 @@ void ViewerOperation::init_image() return; } - int padding_x = abs(canvas_.xmin) * 2; - int padding_y = abs(canvas_.ymin) * 2; - if (padding_x > MAX_VIEWER_TRANSLATION_PADDING) { - padding_x = MAX_VIEWER_TRANSLATION_PADDING; - } - if (padding_y > MAX_VIEWER_TRANSLATION_PADDING) { - padding_y = MAX_VIEWER_TRANSLATION_PADDING; - } - - display_width_ = get_width() + padding_x; - display_height_ = get_height() + padding_y; - if (ibuf->x != display_width_ || ibuf->y != display_height_) { + if (ibuf->x != get_width() || ibuf->y != get_height()) { imb_freerectImBuf(ibuf); imb_freerectfloatImBuf(ibuf); IMB_freezbuffloatImBuf(ibuf); - ibuf->x = display_width_; - ibuf->y = display_height_; + ibuf->x = get_width(); + ibuf->y = get_height(); /* zero size can happen if no image buffers exist to define a sensible resolution */ if (ibuf->x > 0 && ibuf->y > 0) { imb_addrectfloatImBuf(ibuf); @@ -187,11 +176,13 @@ void ViewerOperation::update_image(const rcti *rect) return; } + image_->display_offset_x = canvas_.xmin; + image_->display_offset_y = canvas_.ymin; float *buffer = output_buffer_; IMB_partial_display_buffer_update(ibuf_, buffer, nullptr, - display_width_, + get_width(), 0, 0, view_settings_, @@ -224,32 +215,23 @@ void ViewerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output), return; } - const int offset_x = area.xmin + (canvas_.xmin > 0 ? canvas_.xmin * 2 : 0); - const int offset_y = area.ymin + (canvas_.ymin > 0 ? canvas_.ymin * 2 : 0); MemoryBuffer output_buffer( - output_buffer_, COM_DATA_TYPE_COLOR_CHANNELS, display_width_, display_height_); + output_buffer_, COM_DATA_TYPE_COLOR_CHANNELS, get_width(), get_height()); const MemoryBuffer *input_image = inputs[0]; - output_buffer.copy_from(input_image, area, offset_x, offset_y); + output_buffer.copy_from(input_image, area); if (use_alpha_input_) { const MemoryBuffer *input_alpha = inputs[1]; - output_buffer.copy_from( - input_alpha, area, 0, COM_DATA_TYPE_VALUE_CHANNELS, offset_x, offset_y, 3); + output_buffer.copy_from(input_alpha, area, 0, COM_DATA_TYPE_VALUE_CHANNELS, 3); } if (depth_buffer_) { MemoryBuffer depth_buffer( - depth_buffer_, COM_DATA_TYPE_VALUE_CHANNELS, display_width_, display_height_); + depth_buffer_, COM_DATA_TYPE_VALUE_CHANNELS, get_width(), get_height()); const MemoryBuffer *input_depth = inputs[2]; - depth_buffer.copy_from(input_depth, area, offset_x, offset_y); + depth_buffer.copy_from(input_depth, area); } - rcti display_area; - BLI_rcti_init(&display_area, - offset_x, - offset_x + BLI_rcti_size_x(&area), - offset_y, - offset_y + BLI_rcti_size_y(&area)); - update_image(&display_area); + update_image(&area); } void ViewerOperation::clear_display_buffer() diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h index 1ad6cc51269..ed9e5871eae 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.h +++ b/source/blender/compositor/operations/COM_ViewerOperation.h @@ -35,9 +35,6 @@ class ViewerOperation : public MultiThreadedOperation { SocketReader *alpha_input_; SocketReader *depth_input_; - int display_width_; - int display_height_; - public: ViewerOperation(); void init_execution() override; diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index 46482ab6668..af3ec24d085 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -129,7 +129,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD { 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); diff --git a/source/blender/draw/engines/image/image_engine.cc b/source/blender/draw/engines/image/image_engine.cc index e972d21cda4..09efaea3e71 100644 --- a/source/blender/draw/engines/image/image_engine.cc +++ b/source/blender/draw/engines/image/image_engine.cc @@ -99,8 +99,11 @@ class ImageEngine { /* Setup the matrix to go from screen UV coordinates to UV texture space coordinates. */ float image_resolution[2] = {image_buffer ? image_buffer->x : 1024.0f, image_buffer ? image_buffer->y : 1024.0f}; - space->init_ss_to_texture_matrix( - draw_ctx->region, image_resolution, instance_data->ss_to_texture); + float image_display_offset[2] = {(float)instance_data->image->display_offset_x, + (float)instance_data->image->display_offset_y}; + space->init_ss_to_texture_matrix(draw_ctx->region, + image_display_offset, + image_resolution, instance_data->ss_to_texture); const Scene *scene = DRW_context_state_get()->scene; instance_data->sh_params.update(space.get(), scene, instance_data->image, image_buffer); diff --git a/source/blender/draw/engines/image/image_instance_data.hh b/source/blender/draw/engines/image/image_instance_data.hh index 682b93a80b3..02ca86312c6 100644 --- a/source/blender/draw/engines/image/image_instance_data.hh +++ b/source/blender/draw/engines/image/image_instance_data.hh @@ -21,7 +21,7 @@ /** * \brief max allowed textures to use by the ScreenSpaceDrawingMode. * - * 4 textures are used to reduce uploading screen space textures when translating the image. + * 1 texture is used to reduce uploading screen space textures when translating the image. */ constexpr int SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN = 1; diff --git a/source/blender/draw/engines/image/image_space.hh b/source/blender/draw/engines/image/image_space.hh index 7a11d14b567..a2f923a7118 100644 --- a/source/blender/draw/engines/image/image_space.hh +++ b/source/blender/draw/engines/image/image_space.hh @@ -77,6 +77,7 @@ class AbstractSpaceAccessor { * (0..1) to texture space UV coordinates. */ virtual void init_ss_to_texture_matrix(const ARegion *region, + const float image_display_offset[2], const float image_resolution[2], float r_uv_to_texture[4][4]) const = 0; diff --git a/source/blender/draw/engines/image/image_space_image.hh b/source/blender/draw/engines/image/image_space_image.hh index 40aa117514c..7c15d780d07 100644 --- a/source/blender/draw/engines/image/image_space_image.hh +++ b/source/blender/draw/engines/image/image_space_image.hh @@ -148,20 +148,29 @@ class SpaceImageAccessor : public AbstractSpaceAccessor { } void init_ss_to_texture_matrix(const ARegion *region, - const float UNUSED(image_resolution[2]), + const float image_display_offset[2], + const float image_resolution[2], float r_uv_to_texture[4][4]) const override { - unit_m4(r_uv_to_texture); - float scale_x = 1.0 / BLI_rctf_size_x(®ion->v2d.cur); - float scale_y = 1.0 / BLI_rctf_size_y(®ion->v2d.cur); - float translate_x = scale_x * -region->v2d.cur.xmin; - float translate_y = scale_y * -region->v2d.cur.ymin; - - r_uv_to_texture[0][0] = scale_x; - r_uv_to_texture[1][1] = scale_y; - r_uv_to_texture[3][0] = translate_x; - r_uv_to_texture[3][1] = translate_y; - } + float zoom_x = image_resolution[0] * sima->zoom; + float zoom_y = image_resolution[1] * sima ->zoom; + float image_offset_x = (region->winx - zoom_x) / 2 + sima->xof + image_display_offset[0]; + float image_offset_y = (region->winy - zoom_y) / 2 + sima->yof + image_display_offset[1]; + + unit_m4(r_uv_to_texture); + float scale_x = 1.0 / BLI_rctf_size_x(®ion->v2d.cur); + float scale_y = 1.0 / BLI_rctf_size_y(®ion->v2d.cur); + float offset_x = 1.0 / image_resolution[0] * image_offset_x; + float offset_y = 1.0 / image_resolution[1] * image_offset_y; + + float translate_x = scale_x * (-region->v2d.cur.xmin + offset_x); + float translate_y = scale_y * (-region->v2d.cur.ymin + offset_y); + + r_uv_to_texture[0][0] = scale_x; + r_uv_to_texture[1][1] = scale_y; + r_uv_to_texture[3][0] = translate_x; + r_uv_to_texture[3][1] = translate_y; + } }; } // namespace blender::draw::image_engine diff --git a/source/blender/draw/engines/image/image_space_node.hh b/source/blender/draw/engines/image/image_space_node.hh index 6f38dcb86aa..4057f7b78cf 100644 --- a/source/blender/draw/engines/image/image_space_node.hh +++ b/source/blender/draw/engines/image/image_space_node.hh @@ -99,6 +99,7 @@ class SpaceNodeAccessor : public AbstractSpaceAccessor { * screen. */ void init_ss_to_texture_matrix(const ARegion *region, + const float image_display_offset[2], const float image_resolution[2], float r_uv_to_texture[4][4]) const override { @@ -107,10 +108,10 @@ class SpaceNodeAccessor : public AbstractSpaceAccessor { mul_v2_v2fl(display_resolution, image_resolution, snode->zoom); const float scale_x = display_resolution[0] / region->winx; const float scale_y = display_resolution[1] / region->winy; - const float translate_x = ((region->winx - display_resolution[0]) * 0.5f + snode->xof) / - region->winx; - const float translate_y = ((region->winy - display_resolution[1]) * 0.5f + snode->yof) / - region->winy; + const float translate_x = ((region->winx - display_resolution[0]) * 0.5f + snode->xof + image_display_offset[0]) / + region->winx ; + const float translate_y = ((region->winy - display_resolution[1]) * 0.5f + snode->yof + image_display_offset[1]) / + region->winy; r_uv_to_texture[0][0] = scale_x; r_uv_to_texture[1][1] = scale_y; diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 365a17c0a04..ad647cf019d 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1499,8 +1499,10 @@ void draw_nodespace_back_pix(const bContext &C, if (ibuf) { /* somehow the offset has to be calculated inverse */ wmOrtho2_region_pixelspace(®ion); - const float x = (region.winx - snode.zoom * ibuf->x) / 2 + snode.xof; - const float y = (region.winy - snode.zoom * ibuf->y) / 2 + snode.yof; + const float offset_x = snode.xof + ima->display_offset_x; + const float offset_y = snode.yof + ima->display_offset_y; + const float x = (region.winx - snode.zoom * ibuf->x) / 2 + offset_x; + const float y = (region.winy - snode.zoom * ibuf->y) / 2 + offset_y; /** \note draw selected info on backdrop */ if (snode.edittree) { diff --git a/source/blender/editors/space_node/node_gizmo.cc b/source/blender/editors/space_node/node_gizmo.cc index 4f27f9baabc..832ec36ab34 100644 --- a/source/blender/editors/space_node/node_gizmo.cc +++ b/source/blender/editors/space_node/node_gizmo.cc @@ -38,25 +38,39 @@ namespace blender::ed::space_node { static void node_gizmo_calc_matrix_space(const SpaceNode *snode, const ARegion *region, + const float image_offset[2], float matrix_space[4][4]) { unit_m4(matrix_space); mul_v3_fl(matrix_space[0], snode->zoom); mul_v3_fl(matrix_space[1], snode->zoom); - matrix_space[3][0] = (region->winx / 2) + snode->xof; - matrix_space[3][1] = (region->winy / 2) + snode->yof; + const float offset_x = snode->xof + image_offset[0]; + const float offset_y = snode->yof + image_offset[1]; + matrix_space[3][0] = (region->winx / 2) + offset_x; + matrix_space[3][1] = (region->winy / 2) + offset_y; } static void node_gizmo_calc_matrix_space_with_image_dims(const SpaceNode *snode, const ARegion *region, + const float image_offset[2], const float image_dims[2], float matrix_space[4][4]) { unit_m4(matrix_space); mul_v3_fl(matrix_space[0], snode->zoom * image_dims[0]); mul_v3_fl(matrix_space[1], snode->zoom * image_dims[1]); - matrix_space[3][0] = ((region->winx / 2) + snode->xof) - ((image_dims[0] / 2.0f) * snode->zoom); - matrix_space[3][1] = ((region->winy / 2) + snode->yof) - ((image_dims[1] / 2.0f) * snode->zoom); + const float offset_x = snode->xof + image_offset[0]; + const float offset_y = snode->yof + image_offset[1]; + matrix_space[3][0] = ((region->winx / 2) + offset_x) - ((image_dims[0] / 2.0f) * snode->zoom); + matrix_space[3][1] = ((region->winy / 2) + offset_y) - ((image_dims[1] / 2.0f) * snode->zoom); +} + +static void get_viewer_image_offset(const bContext *C, float r_offset[2]) +{ + Main *bmain = CTX_data_main(C); + const Image *image = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); + r_offset[0] = image->display_offset_x; + r_offset[1] = image->display_offset_y; } /** \} */ @@ -127,11 +141,13 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup * Main *bmain = CTX_data_main(C); wmGizmo *cage = ((wmGizmoWrapper *)gzgroup->customdata)->gizmo; const ARegion *region = CTX_wm_region(C); - /* center is always at the origin */ - const float origin[3] = {float(region->winx / 2), float(region->winy / 2), 0.0f}; - void *lock; Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); + /* Center is always at the origin. */ + const float origin[3] ={ (region->winx / 2) + (float)ima->display_offset_x, + (region->winy / 2) + (float)ima->display_offset_y}; + + void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock); if (ibuf) { @@ -340,7 +356,9 @@ static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmGizmoGroup * SpaceNode *snode = CTX_wm_space_node(C); - node_gizmo_calc_matrix_space(snode, region, gz->matrix_space); + float image_offset[2]; + get_viewer_image_offset(C, image_offset); + node_gizmo_calc_matrix_space(snode, region, image_offset, gz->matrix_space); } static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *gzgroup) @@ -453,8 +471,10 @@ static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmGizmoGroup SpaceNode *snode = CTX_wm_space_node(C); + float image_offset[2]; + get_viewer_image_offset(C, image_offset); node_gizmo_calc_matrix_space_with_image_dims( - snode, region, sbeam_group->state.dims, gz->matrix_space); + snode, region, image_offset, sbeam_group->state.dims, gz->matrix_space); } static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *gzgroup) @@ -560,9 +580,12 @@ static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoG SpaceNode *snode = CTX_wm_space_node(C); + float image_offset[2]; + get_viewer_image_offset(C, image_offset); + float matrix_space[4][4]; node_gizmo_calc_matrix_space_with_image_dims( - snode, region, cpin_group->state.dims, matrix_space); + snode, region, image_offset, cpin_group->state.dims, matrix_space); for (int i = 0; i < 4; i++) { wmGizmo *gz = cpin_group->gizmos[i]; diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index 82b850653be..af93c4d823c 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -352,9 +352,14 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params) case ND_FRAME: ED_area_tag_refresh(area); break; - case ND_COMPO_RESULT: + case ND_COMPO_RESULT: { ED_area_tag_redraw(area); + /* Backdrop image offset is calculated during compositing so gizmos need to be updated + * afterwards. */ + const ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); + WM_gizmomap_tag_refresh(region->gizmo_map); break; + } case ND_TRANSFORM_DONE: if (ED_node_is_compositor(snode)) { if (snode->flag & SNODE_AUTO_RENDER) { diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 06b589d4f76..8f327d12735 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -199,6 +199,9 @@ typedef struct Image { char eye; char views_format; + /** Displayed offset in backdrop for viewer nodes in pixel space. */ + int display_offset_x, display_offset_y; + /* ImageTile list for UDIMs. */ int active_tile_index; ListBase tiles; |