Merge branch 'blender-v3.1-release'

This commit is contained in:
Jacques Lucke 2022-02-04 13:11:18 +01:00
commit f9aab6717b
7 changed files with 56 additions and 36 deletions

View File

@ -71,7 +71,7 @@ class BatchUpdater {
float pos[4][2];
fill_tri_fan_from_rctf(pos, info.clipping_bounds);
float uv[4][2];
fill_tri_fan_from_rctf(uv, info.uv_bounds);
fill_tri_fan_from_rctf(uv, info.clipping_uv_bounds);
for (int i = 0; i < 4; i++) {
GPU_vertbuf_attr_set(vbo, pos_id, i, pos[i]);

View File

@ -26,6 +26,7 @@
#include "IMB_imbuf_types.h"
#include "BLI_float4x4.hh"
#include "BLI_math_vec_types.hh"
#include "image_batches.hh"
@ -61,11 +62,11 @@ struct OneTextureMethod {
}
}
void update_uv_bounds(const ARegion *region)
void update_region_uv_bounds(const ARegion *region)
{
TextureInfo &info = instance_data->texture_infos[0];
if (!BLI_rctf_compare(&info.uv_bounds, &region->v2d.cur, EPSILON_UV_BOUNDS)) {
info.uv_bounds = region->v2d.cur;
if (!BLI_rctf_compare(&info.region_uv_bounds, &region->v2d.cur, EPSILON_UV_BOUNDS)) {
info.region_uv_bounds = region->v2d.cur;
info.dirty = true;
}
@ -74,6 +75,25 @@ struct OneTextureMethod {
BLI_rctf_init_minmax(&instance_data->texture_infos[i].clipping_bounds);
}
}
void update_screen_uv_bounds()
{
for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
update_screen_uv_bounds(instance_data->texture_infos[0]);
}
}
void update_screen_uv_bounds(TextureInfo &info)
{
/* Although this works, computing an inverted matrix adds some precision issues and leads to
* tearing artifacts. This should be modified to use the scaling and transformation from the
* not inverted matrix.*/
float4x4 mat(instance_data->ss_to_texture);
float4x4 mat_inv = mat.inverted();
float3 min_uv = mat_inv * float3(0.0f, 0.0f, 0.0f);
float3 max_uv = mat_inv * float3(1.0f, 1.0f, 0.0f);
BLI_rctf_init(&info.clipping_uv_bounds, min_uv[0], max_uv[0], min_uv[1], max_uv[1]);
}
};
using namespace blender::bke::image::partial_update;
@ -247,8 +267,9 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
static_cast<float>(iterator.tile_data.tile_buffer->y) +
tile_offset_y);
rctf changed_overlapping_region_in_uv_space;
const bool region_overlap = BLI_rctf_isect(
&info.uv_bounds, &changed_region_in_uv_space, &changed_overlapping_region_in_uv_space);
const bool region_overlap = BLI_rctf_isect(&info.region_uv_bounds,
&changed_region_in_uv_space,
&changed_overlapping_region_in_uv_space);
if (!region_overlap) {
continue;
}
@ -256,15 +277,16 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
* TODO: first convert to ss_pixel space as integer based. and from there go back to texel
* space. But perhaps this isn't needed and we could use an extraction offset somehow. */
rcti gpu_texture_region_to_update;
BLI_rcti_init(&gpu_texture_region_to_update,
floor((changed_overlapping_region_in_uv_space.xmin - info.uv_bounds.xmin) *
texture_width / BLI_rctf_size_x(&info.uv_bounds)),
floor((changed_overlapping_region_in_uv_space.xmax - info.uv_bounds.xmin) *
texture_width / BLI_rctf_size_x(&info.uv_bounds)),
ceil((changed_overlapping_region_in_uv_space.ymin - info.uv_bounds.ymin) *
texture_height / BLI_rctf_size_y(&info.uv_bounds)),
ceil((changed_overlapping_region_in_uv_space.ymax - info.uv_bounds.ymin) *
texture_height / BLI_rctf_size_y(&info.uv_bounds)));
BLI_rcti_init(
&gpu_texture_region_to_update,
floor((changed_overlapping_region_in_uv_space.xmin - info.region_uv_bounds.xmin) *
texture_width / BLI_rctf_size_x(&info.region_uv_bounds)),
floor((changed_overlapping_region_in_uv_space.xmax - info.region_uv_bounds.xmin) *
texture_width / BLI_rctf_size_x(&info.region_uv_bounds)),
ceil((changed_overlapping_region_in_uv_space.ymin - info.region_uv_bounds.ymin) *
texture_height / BLI_rctf_size_y(&info.region_uv_bounds)),
ceil((changed_overlapping_region_in_uv_space.ymax - info.region_uv_bounds.ymin) *
texture_height / BLI_rctf_size_y(&info.region_uv_bounds)));
rcti tile_region_to_extract;
BLI_rcti_init(
@ -288,11 +310,13 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
for (int y = gpu_texture_region_to_update.ymin; y < gpu_texture_region_to_update.ymax;
y++) {
float yf = y / (float)texture_height;
float v = info.uv_bounds.ymax * yf + info.uv_bounds.ymin * (1.0 - yf) - tile_offset_y;
float v = info.region_uv_bounds.ymax * yf + info.region_uv_bounds.ymin * (1.0 - yf) -
tile_offset_y;
for (int x = gpu_texture_region_to_update.xmin; x < gpu_texture_region_to_update.xmax;
x++) {
float xf = x / (float)texture_width;
float u = info.uv_bounds.xmax * xf + info.uv_bounds.xmin * (1.0 - xf) - tile_offset_x;
float u = info.region_uv_bounds.xmax * xf + info.region_uv_bounds.xmin * (1.0 - xf) -
tile_offset_x;
nearest_interpolation_color(tile_buffer,
nullptr,
&extracted_buffer.rect_float[offset * 4],
@ -404,8 +428,10 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
static_cast<float>(texture_height) / static_cast<float>(tile_buffer.y),
1.0f};
rescale_m4(uv_to_texel, scale);
uv_to_texel[3][0] += image_tile.get_tile_x_offset() / BLI_rctf_size_x(&texture_info.uv_bounds);
uv_to_texel[3][1] += image_tile.get_tile_y_offset() / BLI_rctf_size_y(&texture_info.uv_bounds);
uv_to_texel[3][0] += image_tile.get_tile_x_offset() /
BLI_rctf_size_x(&texture_info.region_uv_bounds);
uv_to_texel[3][1] += image_tile.get_tile_y_offset() /
BLI_rctf_size_y(&texture_info.region_uv_bounds);
uv_to_texel[3][0] *= texture_width;
uv_to_texel[3][1] *= texture_height;
invert_m4(uv_to_texel);
@ -456,7 +482,8 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
* screen space textures that aren't needed. */
const ARegion *region = draw_ctx->region;
method.update_screen_space_bounds(region);
method.update_uv_bounds(region);
method.update_region_uv_bounds(region);
method.update_screen_uv_bounds();
/* Step: Update the GPU textures based on the changes in the image. */
instance_data->update_gpu_texture_allocations();

View File

@ -54,8 +54,6 @@ struct IMAGE_Data {
#define IMAGE_DRAW_FLAG_APPLY_ALPHA (1 << 1)
#define IMAGE_DRAW_FLAG_SHUFFLING (1 << 2)
#define IMAGE_DRAW_FLAG_DEPTH (1 << 3)
/** Flag to disable depth testing (used for node editor back drop drawing).*/
#define IMAGE_DRAW_FLAG_DEPTH_ALWAYS (1 << 4)
/**
* Abstract class for a drawing mode of the image engine.

View File

@ -56,7 +56,6 @@ class SpaceNodeAccessor : public AbstractSpaceAccessor {
void get_shader_parameters(ShaderParameters &r_shader_parameters, ImBuf *ibuf) override
{
r_shader_parameters.flags |= IMAGE_DRAW_FLAG_DEPTH_ALWAYS;
if ((snode->flag & SNODE_USE_ALPHA) != 0) {
/* Show RGBA */
r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHOW_ALPHA | IMAGE_DRAW_FLAG_APPLY_ALPHA;

View File

@ -44,8 +44,10 @@ struct TextureInfo {
/** \brief area of the texture in screen space. */
rctf clipping_bounds;
/** \brief uv area of the texture. */
rctf uv_bounds;
/** \brief uv area of the texture (copy from ARegion). */
rctf region_uv_bounds;
/** \brief uv area of the texture in screen space. */
rctf clipping_uv_bounds;
/**
* \brief Batch to draw the associated text on the screen.

View File

@ -5,7 +5,6 @@
#define IMAGE_DRAW_FLAG_APPLY_ALPHA (1 << 1)
#define IMAGE_DRAW_FLAG_SHUFFLING (1 << 2)
#define IMAGE_DRAW_FLAG_DEPTH (1 << 3)
#define IMAGE_DRAW_FLAG_DEPTH_ALWAYS (1 << 4)
#define FAR_DISTANCE farNearDistances.x
#define NEAR_DISTANCE farNearDistances.y
@ -13,11 +12,9 @@
void main()
{
ivec2 uvs_clamped = ivec2(uv_screen);
if ((drawFlags & IMAGE_DRAW_FLAG_DEPTH_ALWAYS) == 0) {
float depth = texelFetch(depth_texture, uvs_clamped, 0).r;
if (depth == 1.0) {
discard;
}
float depth = texelFetch(depth_texture, uvs_clamped, 0).r;
if (depth == 1.0) {
discard;
}
vec4 tex_color = texelFetch(imageTexture, uvs_clamped, 0);

View File

@ -1031,21 +1031,18 @@ static void store_computed_output_attributes(
{
for (const OutputAttributeToStore &store : attributes_to_store) {
GeometryComponent &component = geometry.get_component_for_write(store.component_type);
/* Try deleting an existing attribute, so that we can just use `attribute_try_create` to pass
* in the data directly. */
component.attribute_try_delete(store.name);
if (component.attribute_exists(store.name)) {
/* Copy the data into an existing attribute. */
blender::bke::WriteAttributeLookup write_attribute = component.attribute_try_get_for_write(
store.name);
if (write_attribute) {
write_attribute.varray.set_all(store.data.data());
store.data.type().destruct_n(store.data.data(), store.data.size());
MEM_freeN(store.data.data());
if (write_attribute.tag_modified_fn) {
write_attribute.tag_modified_fn();
}
}
store.data.type().destruct_n(store.data.data(), store.data.size());
MEM_freeN(store.data.data());
}
else {
component.attribute_try_create(store.name,