Fullframe compositor: support backdrop offset for viewer node
Translating an image in fullframe compositor now also translates the backdrop image for the viewer node. Attached gif shows the behavior. Notice how gizmo moves with correct values with the image but the frame stays to indicate what will get rendered. Note: This patch is a continuation of [D12750] (https://archive.blender.org/developer/D12750). In a previous patch, display offset on screen was not computed correctly. This has now been fixed. Pull Request: https://projects.blender.org/blender/blender/pulls/105677
This commit is contained in:
committed by
Jeroen Bakker
parent
439beb20c3
commit
8bfe34b285
@@ -137,23 +137,13 @@ 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;
|
||||
}
|
||||
if (ibuf->x != get_width() || ibuf->y != get_height()) {
|
||||
|
||||
display_width_ = get_width() + padding_x;
|
||||
display_height_ = get_height() + padding_y;
|
||||
if (ibuf->x != display_width_ || ibuf->y != display_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, 4);
|
||||
@@ -187,11 +177,13 @@ void ViewerOperation::update_image(const rcti *rect)
|
||||
return;
|
||||
}
|
||||
|
||||
image_->offset_x = canvas_.xmin;
|
||||
image_->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 +216,23 @@ void ViewerOperation::update_memory_buffer_partial(MemoryBuffer * /*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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -99,8 +99,10 @@ 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};
|
||||
float image_offset[2] = {(float)instance_data->image->offset_x,
|
||||
(float)instance_data->image->offset_y};
|
||||
space->init_ss_to_texture_matrix(
|
||||
draw_ctx->region, image_resolution, instance_data->ss_to_texture);
|
||||
draw_ctx->region, image_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);
|
||||
|
||||
@@ -69,6 +69,7 @@ class AbstractSpaceAccessor {
|
||||
* (0..1) to texture space UV coordinates.
|
||||
*/
|
||||
virtual void init_ss_to_texture_matrix(const ARegion *region,
|
||||
const float image_offset[2],
|
||||
const float image_resolution[2],
|
||||
float r_uv_to_texture[4][4]) const = 0;
|
||||
};
|
||||
|
||||
@@ -88,14 +88,19 @@ class SpaceImageAccessor : public AbstractSpaceAccessor {
|
||||
}
|
||||
|
||||
void init_ss_to_texture_matrix(const ARegion *region,
|
||||
const float /*image_resolution*/[2],
|
||||
const float image_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;
|
||||
|
||||
float display_offset_x = scale_x * image_offset[0] / image_resolution[0];
|
||||
float display_offset_y = scale_y * image_offset[1] / image_resolution[1];
|
||||
|
||||
float translate_x = scale_x * -region->v2d.cur.xmin + display_offset_x;
|
||||
float translate_y = scale_y * -region->v2d.cur.ymin + display_offset_y;
|
||||
|
||||
r_uv_to_texture[0][0] = scale_x;
|
||||
r_uv_to_texture[1][1] = scale_y;
|
||||
|
||||
@@ -87,17 +87,22 @@ class SpaceNodeAccessor : public AbstractSpaceAccessor {
|
||||
* screen.
|
||||
*/
|
||||
void init_ss_to_texture_matrix(const ARegion *region,
|
||||
const float image_offset[2],
|
||||
const float image_resolution[2],
|
||||
float r_uv_to_texture[4][4]) const override
|
||||
{
|
||||
unit_m4(r_uv_to_texture);
|
||||
float display_resolution[2];
|
||||
float image_display_offset[2];
|
||||
mul_v2_v2fl(display_resolution, image_resolution, snode->zoom);
|
||||
mul_v2_v2fl(image_display_offset, image_offset, 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) /
|
||||
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) /
|
||||
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;
|
||||
|
||||
@@ -1547,8 +1547,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->offset_x * snode.zoom;
|
||||
const float offset_y = snode.yof + ima->offset_y * snode.zoom;
|
||||
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) {
|
||||
|
||||
@@ -402,9 +402,14 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params)
|
||||
case ND_FRAME:
|
||||
node_area_tag_tree_recalc(snode, 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:
|
||||
node_area_tag_recalc_auto_compositing(snode, area);
|
||||
break;
|
||||
|
||||
@@ -196,6 +196,9 @@ typedef struct Image {
|
||||
char eye;
|
||||
char views_format;
|
||||
|
||||
/** Offset caused by translation. Used in compositor backdrop for viewer nodes in image space. */
|
||||
int offset_x, offset_y;
|
||||
|
||||
/* ImageTile list for UDIMs. */
|
||||
int active_tile_index;
|
||||
ListBase tiles;
|
||||
|
||||
Reference in New Issue
Block a user