[Bf-blender-cvs] [6df6e537a3f] temp-image-engine: Recalculate bounds when textures go offscreen.
Jeroen Bakker
noreply at git.blender.org
Wed Dec 7 14:28:46 CET 2022
Commit: 6df6e537a3fc305a89420b9938d960a117e38330
Author: Jeroen Bakker
Date: Wed Dec 7 14:28:39 2022 +0100
Branches: temp-image-engine
https://developer.blender.org/rB6df6e537a3fc305a89420b9938d960a117e38330
Recalculate bounds when textures go offscreen.
===================================================================
M source/blender/draw/engines/image/image_drawing_mode.hh
M source/blender/draw/engines/image/image_instance_data.hh
M source/blender/draw/engines/image/image_texture_info.hh
===================================================================
diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index dcc869a9217..05004bed53c 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -22,7 +22,7 @@ namespace blender::draw::image_engine {
constexpr float EPSILON_UV_BOUNDS = 0.00001f;
/**
- * \brief Screen space method using a single texture spawning the whole screen.
+ * \brief Screen space method using a 4 textures spawning the whole screen.
*/
struct FullScreenTextures {
IMAGE_InstanceData *instance_data;
@@ -32,65 +32,112 @@ struct FullScreenTextures {
}
/**
- * \brief Update the texture slot uv and screen space bounds.
+ * \brief Update the uv and region bounds of all texture_infos of instance_data.
*
- * Using 4 textures to cover the screen space.
+ * - calculate the uv span of the area.
+ * - compare the uv span with the uv span of a single texture to determine if the textures should
+ * be regenerated.
*/
- void update_screen_space_bounds(const ARegion *region)
+ void update_bounds(const ARegion *region)
{
- // we should find the
- int2 region_size(region->winx, region->winy);
- int2 region_half_size = region_size / int2(2, 2);
- int2 min_co = -region_half_size;
- int2 mid_co = region_half_size;
- int2 max_co = region_size + region_half_size;
-
- BLI_rctf_init(
- &instance_data->texture_infos[0].clipping_bounds, min_co.x, mid_co.x, min_co.y, mid_co.y);
- BLI_rctf_init(
- &instance_data->texture_infos[1].clipping_bounds, mid_co.x, max_co.x, min_co.y, mid_co.y);
- BLI_rctf_init(
- &instance_data->texture_infos[2].clipping_bounds, min_co.x, mid_co.x, mid_co.y, max_co.y);
+ // determine uv_area of the region.
+ float4x4 mat = float4x4(instance_data->ss_to_texture).inverted();
+ float2 region_uv_min = float2(mat * float3(0.0f, 0.0f, 0.0f));
+ float2 region_uv_max = float2(mat * float3(1.0f, 1.0f, 0.0f));
+ float2 region_uv_span = region_uv_max - region_uv_min;
+ rctf region_uv_bounds;
BLI_rctf_init(
- &instance_data->texture_infos[3].clipping_bounds, mid_co.x, max_co.x, mid_co.y, max_co.y);
- }
+ ®ion_uv_bounds, region_uv_min.x, region_uv_max.x, region_uv_min.y, region_uv_max.y);
+
+ /* Calculate 9 coordinates that will be used as uv bounds of the 4 textures. */
+ float2 onscreen_multiple = (blender::math::floor(region_uv_min / region_uv_span) +
+ float2(1.0f)) *
+ region_uv_span;
+ BLI_assert(onscreen_multiple.x > region_uv_min.x);
+ BLI_assert(onscreen_multiple.y > region_uv_min.y);
+ BLI_assert(onscreen_multiple.x < region_uv_max.x);
+ BLI_assert(onscreen_multiple.y < region_uv_max.y);
+ float2 uv_coords[3][3];
+ uv_coords[0][0] = onscreen_multiple + float2(-region_uv_span.x, -region_uv_span.y);
+ uv_coords[0][1] = onscreen_multiple + float2(-region_uv_span.x, 0.0);
+ uv_coords[0][2] = onscreen_multiple + float2(-region_uv_span.x, region_uv_span.y);
+ uv_coords[1][0] = onscreen_multiple + float2(0.0f, -region_uv_span.y);
+ uv_coords[1][1] = onscreen_multiple + float2(0.0f, 0.0);
+ uv_coords[1][2] = onscreen_multiple + float2(0.0f, region_uv_span.y);
+ uv_coords[2][0] = onscreen_multiple + float2(region_uv_span.x, -region_uv_span.y);
+ uv_coords[2][1] = onscreen_multiple + float2(region_uv_span.x, 0.0);
+ uv_coords[2][2] = onscreen_multiple + float2(region_uv_span.x, region_uv_span.y);
+
+ /* Construct the uv bounds of the 4 textures that are needed to fill the region. */
+ Vector<TextureInfo *> unassigned_textures;
+ struct TextureInfoBounds {
+ TextureInfo *info = nullptr;
+ rctf uv_bounds;
+ };
+ TextureInfoBounds bottom_left;
+ TextureInfoBounds bottom_right;
+ TextureInfoBounds top_left;
+ TextureInfoBounds top_right;
+
+ BLI_rctf_init(&bottom_left.uv_bounds,
+ uv_coords[0][0].x,
+ uv_coords[1][1].x,
+ uv_coords[0][0].y,
+ uv_coords[1][1].y);
+ BLI_rctf_init(&bottom_right.uv_bounds,
+ uv_coords[1][0].x,
+ uv_coords[2][1].x,
+ uv_coords[1][0].y,
+ uv_coords[2][1].y);
+ BLI_rctf_init(&top_left.uv_bounds,
+ uv_coords[0][1].x,
+ uv_coords[1][2].x,
+ uv_coords[0][1].y,
+ uv_coords[1][2].y);
+ BLI_rctf_init(&top_right.uv_bounds,
+ uv_coords[1][1].x,
+ uv_coords[2][2].x,
+ uv_coords[1][1].y,
+ uv_coords[2][2].y);
+ Vector<TextureInfoBounds *> info_bounds;
+ info_bounds.append(&bottom_left);
+ info_bounds.append(&bottom_right);
+ info_bounds.append(&top_left);
+ info_bounds.append(&top_right);
+
+ /* Assign any existing texture that matches uv bounds. */
+ for (TextureInfo &info : instance_data->texture_infos) {
+ bool assigned = false;
+ for (TextureInfoBounds *info_bound : info_bounds) {
+ if (info_bound->info == nullptr &&
+ BLI_rctf_compare(&info_bound->uv_bounds, &info.clipping_uv_bounds, 0.001)) {
+ info_bound->info = &info;
+ assigned = true;
+ break;
+ }
+ }
+ if (!assigned) {
+ unassigned_textures.append(&info);
+ }
+ }
- void update_screen_uv_bounds()
- {
- float3 screen_co(1.0f, 1.0f, 0.0f);
- float3 screen_half = screen_co * float3(0.5f, 0.5f, 0.5f);
-
- float4x4 mat(instance_data->ss_to_texture);
- float4x4 mat_inv = mat.inverted();
-
- float3 min_co = mat_inv * -screen_half;
- float3 mid_co = mat_inv * screen_half;
- float3 max_co = mat_inv * (screen_co + screen_half);
-
- BLI_rctf_init(&instance_data->texture_infos[0].clipping_uv_bounds,
- min_co.x,
- mid_co.x,
- min_co.y,
- mid_co.y);
- BLI_rctf_init(&instance_data->texture_infos[1].clipping_uv_bounds,
- mid_co.x,
- max_co.x,
- min_co.y,
- mid_co.y);
- BLI_rctf_init(&instance_data->texture_infos[2].clipping_uv_bounds,
- min_co.x,
- mid_co.x,
- mid_co.y,
- max_co.y);
- BLI_rctf_init(&instance_data->texture_infos[3].clipping_uv_bounds,
- mid_co.x,
- max_co.x,
- mid_co.y,
- max_co.y);
- instance_data->texture_infos[0].need_full_update = true;
- instance_data->texture_infos[1].need_full_update = true;
- instance_data->texture_infos[2].need_full_update = true;
- instance_data->texture_infos[3].need_full_update = true;
+ /* Assign free textures to bounds that weren't found. */
+ for (TextureInfoBounds *info_bound : info_bounds) {
+ if (info_bound->info == nullptr) {
+ info_bound->info = unassigned_textures.pop_last();
+ info_bound->info->need_full_update = true;
+ info_bound->info->clipping_uv_bounds = info_bound->uv_bounds;
+ }
+ }
+
+ /* Calculate the region bounds from the uv bounds. */
+ rctf region_bounds;
+ BLI_rctf_init(®ion_bounds, 0.0, region->winx, 0.0, region->winy);
+ float4x4 uv_to_screen;
+ BLI_rctf_transform_calc_m4_pivot_min(®ion_uv_bounds, ®ion_bounds, uv_to_screen.ptr());
+ for (TextureInfo &info : instance_data->texture_infos) {
+ info.calc_region_bounds_from_uv_bounds(uv_to_screen);
+ }
}
};
@@ -476,8 +523,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
/* Step: Find out which screen space textures are needed to draw on the screen. Remove the
* screen space textures that aren't needed. */
const ARegion *region = draw_ctx->region;
- method.update_screen_space_bounds(region);
- method.update_screen_uv_bounds();
+ method.update_bounds(region);
/* Check for changes in the image user compared to the last time. */
instance_data->update_image_usage(iuser);
diff --git a/source/blender/draw/engines/image/image_instance_data.hh b/source/blender/draw/engines/image/image_instance_data.hh
index 8eb5d4f80a4..00dbf991724 100644
--- a/source/blender/draw/engines/image/image_instance_data.hh
+++ b/source/blender/draw/engines/image/image_instance_data.hh
@@ -100,9 +100,6 @@ struct IMAGE_InstanceData {
{
for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
TextureInfo &info = texture_infos[i];
- if (!info.need_full_update) {
- continue;
- }
BatchUpdater batch_updater(info);
batch_updater.update_batch();
}
diff --git a/source/blender/draw/engines/image/image_texture_info.hh b/source/blender/draw/engines/image/image_texture_info.hh
index e4545d8b81f..b2ceabfc2c4 100644
--- a/source/blender/draw/engines/image/image_texture_info.hh
+++ b/source/blender/draw/engines/image/image_texture_info.hh
@@ -66,9 +66,19 @@ struct TextureInfo {
return int2(clipping_bounds.xmin, clipping_bounds.ymin);
}
- void print_debug()
+ /**
+ * \brief Update the region bounds from the uv bounds by applying the given transform matrix.
+ */
+ void calc_region_bounds_from_uv_bounds(const float4x4 &uv_to_region)
{
- print_rctf_id(&clipping_bounds);
- print_rctf_id(&clipping_uv_bounds);
+ float3 bottom_left_uv = float3(clipping_uv_bounds.xmin, clipping_uv_bounds.ymin, 0.0f);
+ float3 top_right_uv = float3(clipping_uv_bounds.xmax, clipping_uv_bounds.ymax, 0.0f);
+ float3 bottom_left_region = uv_to_region * bottom_left_uv;
+ float3 top_right_region = uv_to_region * top_right_uv;
+ BLI_rctf_init(&clipping_bounds,
+ bottom_left_region.x,
+ top_right_region.x,
+ bottom_left_region.y,
+ top_right_region.y);
}
};
More information about the Bf-blender-cvs
mailing list