diff options
Diffstat (limited to 'source/blender/imbuf/intern/rasterizer_test.cc')
-rw-r--r-- | source/blender/imbuf/intern/rasterizer_test.cc | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/source/blender/imbuf/intern/rasterizer_test.cc b/source/blender/imbuf/intern/rasterizer_test.cc new file mode 100644 index 00000000000..ccc61d55ed9 --- /dev/null +++ b/source/blender/imbuf/intern/rasterizer_test.cc @@ -0,0 +1,429 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include "testing/testing.h" + +#include "BLI_float4x4.hh" +#include "BLI_path_util.h" + +#include "IMB_rasterizer.hh" + +namespace blender::imbuf::rasterizer::tests { + +const uint32_t IMBUF_SIZE = 256; + +struct VertexInput { + float2 uv; + float value; + + VertexInput(float2 uv, float value) : uv(uv), value(value) + { + } +}; + +class VertexShader : public AbstractVertexShader<VertexInput, float4> { + public: + float2 image_size; + float4x4 vp_mat; + void vertex(const VertexInputType &input, VertexOutputType *r_output) override + { + float2 coord = float2(vp_mat * float3(input.uv[0], input.uv[1], 0.0)); + r_output->coord = coord * image_size; + r_output->data = float4(input.value, input.value, input.value, 1.0); + } +}; + +class FragmentShader : public AbstractFragmentShader<float4, float4> { + public: + void fragment(const FragmentInputType &input, FragmentOutputType *r_output) override + { + *r_output = input; + } +}; + +using RasterizerType = Rasterizer<VertexShader, + FragmentShader, + CopyBlendMode, + ImageBufferDrawingTarget, + DefaultRasterlinesBufferSize, + Stats>; + +/* Draw 2 triangles that fills the entire image buffer and see if each pixel is touched. */ +TEST(imbuf_rasterizer, draw_triangle_edge_alignment_quality) +{ + ImBuf image_buffer; + IMB_initImBuf(&image_buffer, IMBUF_SIZE, IMBUF_SIZE, 32, IB_rectfloat); + + RasterizerType rasterizer; + rasterizer.activate_drawing_target(&image_buffer); + + VertexShader &vertex_shader = rasterizer.vertex_shader(); + vertex_shader.image_size = float2(image_buffer.x, image_buffer.y); + + float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + float3 location(0.5, 0.5, 0.0); + float3 rotation(0.0, 0.0, 0.0); + float3 scale(1.0, 1.0, 1.0); + + for (int i = 0; i < 1000; i++) { + rasterizer.stats.reset(); + + IMB_rectfill(&image_buffer, clear_color); + rotation[2] = (i / 1000.0) * M_PI * 2; + + vertex_shader.vp_mat = float4x4::from_loc_eul_scale(location, rotation, scale); + rasterizer.draw_triangle(VertexInput(float2(-1.0, -1.0), 0.2), + VertexInput(float2(-1.0, 1.0), 0.5), + VertexInput(float2(1.0, -1.0), 1.0)); + rasterizer.draw_triangle(VertexInput(float2(1.0, 1.0), 0.2), + VertexInput(float2(-1.0, 1.0), 0.5), + VertexInput(float2(1.0, -1.0), 1.0)); + rasterizer.flush(); + + /* Check if each pixel has been drawn exactly once. */ + EXPECT_EQ(rasterizer.stats.drawn_fragments, IMBUF_SIZE * IMBUF_SIZE) << i; + +#ifdef DEBUG_SAVE + char file_name[FILE_MAX]; + BLI_path_sequence_encode(file_name, "/tmp/test_", ".png", 4, i); + IMB_saveiff(&image_buffer, file_name, IB_rectfloat); + imb_freerectImBuf(&image_buffer); +#endif + } + + imb_freerectImbuf_all(&image_buffer); +} + +/** + * This test case renders 3 images that should have the same coverage. But using a different edge. + * + * The results should be identical. + */ +TEST(imbuf_rasterizer, edge_pixel_clamping) +{ + float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + ImBuf image_buffer_a; + ImBuf image_buffer_b; + ImBuf image_buffer_c; + int fragments_drawn_a; + int fragments_drawn_b; + int fragments_drawn_c; + + RasterizerType rasterizer; + + { + IMB_initImBuf(&image_buffer_a, IMBUF_SIZE, IMBUF_SIZE, 32, IB_rectfloat); + + rasterizer.stats.reset(); + rasterizer.activate_drawing_target(&image_buffer_a); + VertexShader &vertex_shader = rasterizer.vertex_shader(); + vertex_shader.image_size = float2(image_buffer_a.x, image_buffer_a.y); + vertex_shader.vp_mat = float4x4::identity(); + IMB_rectfill(&image_buffer_a, clear_color); + rasterizer.draw_triangle(VertexInput(float2(0.2, -0.2), 1.0), + VertexInput(float2(1.2, 1.2), 1.0), + VertexInput(float2(1.5, -0.3), 1.0)); + rasterizer.flush(); + fragments_drawn_a = rasterizer.stats.drawn_fragments; + } + { + IMB_initImBuf(&image_buffer_b, IMBUF_SIZE, IMBUF_SIZE, 32, IB_rectfloat); + + rasterizer.stats.reset(); + rasterizer.activate_drawing_target(&image_buffer_b); + VertexShader &vertex_shader = rasterizer.vertex_shader(); + vertex_shader.image_size = float2(image_buffer_b.x, image_buffer_b.y); + vertex_shader.vp_mat = float4x4::identity(); + IMB_rectfill(&image_buffer_b, clear_color); + rasterizer.draw_triangle(VertexInput(float2(0.2, -0.2), 1.0), + VertexInput(float2(1.2, 1.2), 1.0), + VertexInput(float2(1.5, -0.3), 1.0)); + rasterizer.flush(); + fragments_drawn_b = rasterizer.stats.drawn_fragments; + } + + { + IMB_initImBuf(&image_buffer_c, IMBUF_SIZE, IMBUF_SIZE, 32, IB_rectfloat); + + rasterizer.stats.reset(); + rasterizer.activate_drawing_target(&image_buffer_c); + VertexShader &vertex_shader = rasterizer.vertex_shader(); + vertex_shader.image_size = float2(image_buffer_c.x, image_buffer_c.y); + vertex_shader.vp_mat = float4x4::identity(); + IMB_rectfill(&image_buffer_c, clear_color); + rasterizer.draw_triangle(VertexInput(float2(0.2, -0.2), 1.0), + VertexInput(float2(1.2, 1.2), 1.0), + VertexInput(float2(10.0, 1.3), 1.0)); + rasterizer.flush(); + fragments_drawn_c = rasterizer.stats.drawn_fragments; + } + + EXPECT_EQ(fragments_drawn_a, fragments_drawn_b); + EXPECT_EQ(memcmp(image_buffer_a.rect_float, + image_buffer_b.rect_float, + sizeof(float) * 4 * IMBUF_SIZE * IMBUF_SIZE), + 0); + EXPECT_EQ(fragments_drawn_a, fragments_drawn_c); + EXPECT_EQ(memcmp(image_buffer_a.rect_float, + image_buffer_c.rect_float, + sizeof(float) * 4 * IMBUF_SIZE * IMBUF_SIZE), + 0); + EXPECT_EQ(fragments_drawn_b, fragments_drawn_c); + EXPECT_EQ(memcmp(image_buffer_b.rect_float, + image_buffer_c.rect_float, + sizeof(float) * 4 * IMBUF_SIZE * IMBUF_SIZE), + 0); + + imb_freerectImbuf_all(&image_buffer_a); + imb_freerectImbuf_all(&image_buffer_b); + imb_freerectImbuf_all(&image_buffer_c); +} + +/** Use one rasterizer and switch between multiple drawing targets. */ +TEST(imbuf_rasterizer, switch_drawing_target) +{ + float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + ImBuf image_buffer_a; + ImBuf image_buffer_b; + ImBuf image_buffer_c; + + RasterizerType rasterizer; + + IMB_initImBuf(&image_buffer_a, IMBUF_SIZE, IMBUF_SIZE, 32, IB_rectfloat); + IMB_rectfill(&image_buffer_a, clear_color); + + VertexShader &vertex_shader = rasterizer.vertex_shader(); + vertex_shader.image_size = float2(image_buffer_a.x, image_buffer_a.y); + vertex_shader.vp_mat = float4x4::identity(); + + rasterizer.activate_drawing_target(&image_buffer_a); + rasterizer.draw_triangle(VertexInput(float2(0.2, -0.2), 1.0), + VertexInput(float2(1.2, 1.2), 1.0), + VertexInput(float2(1.5, -0.3), 1.0)); + + IMB_initImBuf(&image_buffer_b, IMBUF_SIZE, IMBUF_SIZE, 32, IB_rectfloat); + IMB_rectfill(&image_buffer_b, clear_color); + rasterizer.activate_drawing_target(&image_buffer_b); + rasterizer.draw_triangle(VertexInput(float2(0.2, -0.2), 1.0), + VertexInput(float2(1.2, 1.2), 1.0), + VertexInput(float2(1.5, -0.3), 1.0)); + + IMB_initImBuf(&image_buffer_c, IMBUF_SIZE, IMBUF_SIZE, 32, IB_rectfloat); + IMB_rectfill(&image_buffer_c, clear_color); + rasterizer.activate_drawing_target(&image_buffer_c); + rasterizer.draw_triangle(VertexInput(float2(0.2, -0.2), 1.0), + VertexInput(float2(1.2, 1.2), 1.0), + VertexInput(float2(10.0, 1.3), 1.0)); + rasterizer.flush(); + + EXPECT_EQ(memcmp(image_buffer_a.rect_float, + image_buffer_b.rect_float, + sizeof(float) * 4 * IMBUF_SIZE * IMBUF_SIZE), + 0); + EXPECT_EQ(memcmp(image_buffer_a.rect_float, + image_buffer_c.rect_float, + sizeof(float) * 4 * IMBUF_SIZE * IMBUF_SIZE), + 0); + EXPECT_EQ(memcmp(image_buffer_b.rect_float, + image_buffer_c.rect_float, + sizeof(float) * 4 * IMBUF_SIZE * IMBUF_SIZE), + 0); + + imb_freerectImbuf_all(&image_buffer_a); + imb_freerectImbuf_all(&image_buffer_b); + imb_freerectImbuf_all(&image_buffer_c); +} + +TEST(imbuf_rasterizer, center_pixel_clamper_scanline_for) +{ + CenterPixelClampingMethod clamper; + + EXPECT_EQ(clamper.scanline_for(-2.0f), -2); + EXPECT_EQ(clamper.scanline_for(-1.9f), -2); + EXPECT_EQ(clamper.scanline_for(-1.8f), -2); + EXPECT_EQ(clamper.scanline_for(-1.7f), -2); + EXPECT_EQ(clamper.scanline_for(-1.6f), -2); + EXPECT_EQ(clamper.scanline_for(-1.5f), -2); + EXPECT_EQ(clamper.scanline_for(-1.4f), -1); + EXPECT_EQ(clamper.scanline_for(-1.3f), -1); + EXPECT_EQ(clamper.scanline_for(-1.2f), -1); + EXPECT_EQ(clamper.scanline_for(-1.1f), -1); + EXPECT_EQ(clamper.scanline_for(-1.0f), -1); + EXPECT_EQ(clamper.scanline_for(-0.9f), -1); + EXPECT_EQ(clamper.scanline_for(-0.8f), -1); + EXPECT_EQ(clamper.scanline_for(-0.7f), -1); + EXPECT_EQ(clamper.scanline_for(-0.6f), -1); + EXPECT_EQ(clamper.scanline_for(-0.5f), -1); + EXPECT_EQ(clamper.scanline_for(-0.4f), 0); + EXPECT_EQ(clamper.scanline_for(-0.3f), 0); + EXPECT_EQ(clamper.scanline_for(-0.2f), 0); + EXPECT_EQ(clamper.scanline_for(-0.1f), 0); + EXPECT_EQ(clamper.scanline_for(0.0f), 0); + EXPECT_EQ(clamper.scanline_for(0.1f), 0); + EXPECT_EQ(clamper.scanline_for(0.2f), 0); + EXPECT_EQ(clamper.scanline_for(0.3f), 0); + EXPECT_EQ(clamper.scanline_for(0.4f), 0); + EXPECT_EQ(clamper.scanline_for(0.5f), 0); + EXPECT_EQ(clamper.scanline_for(0.6f), 1); + EXPECT_EQ(clamper.scanline_for(0.7f), 1); + EXPECT_EQ(clamper.scanline_for(0.8f), 1); + EXPECT_EQ(clamper.scanline_for(0.9f), 1); + EXPECT_EQ(clamper.scanline_for(1.0f), 1); + EXPECT_EQ(clamper.scanline_for(1.0f), 1); + EXPECT_EQ(clamper.scanline_for(1.1f), 1); + EXPECT_EQ(clamper.scanline_for(1.2f), 1); + EXPECT_EQ(clamper.scanline_for(1.3f), 1); + EXPECT_EQ(clamper.scanline_for(1.4f), 1); + EXPECT_EQ(clamper.scanline_for(1.5f), 1); + EXPECT_EQ(clamper.scanline_for(1.6f), 2); + EXPECT_EQ(clamper.scanline_for(1.7f), 2); + EXPECT_EQ(clamper.scanline_for(1.8f), 2); + EXPECT_EQ(clamper.scanline_for(1.9f), 2); + EXPECT_EQ(clamper.scanline_for(2.0f), 2); +} + +TEST(imbuf_rasterizer, center_pixel_clamper_column_for) +{ + CenterPixelClampingMethod clamper; + + EXPECT_EQ(clamper.column_for(-2.0f), -2); + EXPECT_EQ(clamper.column_for(-1.9f), -2); + EXPECT_EQ(clamper.column_for(-1.8f), -2); + EXPECT_EQ(clamper.column_for(-1.7f), -2); + EXPECT_EQ(clamper.column_for(-1.6f), -2); + EXPECT_EQ(clamper.column_for(-1.5f), -2); + EXPECT_EQ(clamper.column_for(-1.4f), -1); + EXPECT_EQ(clamper.column_for(-1.3f), -1); + EXPECT_EQ(clamper.column_for(-1.2f), -1); + EXPECT_EQ(clamper.column_for(-1.1f), -1); + EXPECT_EQ(clamper.column_for(-1.0f), -1); + EXPECT_EQ(clamper.column_for(-0.9f), -1); + EXPECT_EQ(clamper.column_for(-0.8f), -1); + EXPECT_EQ(clamper.column_for(-0.7f), -1); + EXPECT_EQ(clamper.column_for(-0.6f), -1); + EXPECT_EQ(clamper.column_for(-0.5f), -1); + EXPECT_EQ(clamper.column_for(-0.4f), 0); + EXPECT_EQ(clamper.column_for(-0.3f), 0); + EXPECT_EQ(clamper.column_for(-0.2f), 0); + EXPECT_EQ(clamper.column_for(-0.1f), 0); + EXPECT_EQ(clamper.column_for(0.0f), 0); + EXPECT_EQ(clamper.column_for(0.1f), 0); + EXPECT_EQ(clamper.column_for(0.2f), 0); + EXPECT_EQ(clamper.column_for(0.3f), 0); + EXPECT_EQ(clamper.column_for(0.4f), 0); + EXPECT_EQ(clamper.column_for(0.5f), 0); + EXPECT_EQ(clamper.column_for(0.6f), 1); + EXPECT_EQ(clamper.column_for(0.7f), 1); + EXPECT_EQ(clamper.column_for(0.8f), 1); + EXPECT_EQ(clamper.column_for(0.9f), 1); + EXPECT_EQ(clamper.column_for(1.0f), 1); + EXPECT_EQ(clamper.column_for(1.0f), 1); + EXPECT_EQ(clamper.column_for(1.1f), 1); + EXPECT_EQ(clamper.column_for(1.2f), 1); + EXPECT_EQ(clamper.column_for(1.3f), 1); + EXPECT_EQ(clamper.column_for(1.4f), 1); + EXPECT_EQ(clamper.column_for(1.5f), 1); + EXPECT_EQ(clamper.column_for(1.6f), 2); + EXPECT_EQ(clamper.column_for(1.7f), 2); + EXPECT_EQ(clamper.column_for(1.8f), 2); + EXPECT_EQ(clamper.column_for(1.9f), 2); + EXPECT_EQ(clamper.column_for(2.0f), 2); +} + +TEST(imbuf_rasterizer, center_pixel_clamper_distance_to_scanline_anchorpoint) +{ + CenterPixelClampingMethod clamper; + + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-2.0f), 0.5f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.9f), 0.4f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.8f), 0.3f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.7f), 0.2f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.6f), 0.1f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.5f), 0.0f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.4f), 0.9f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.3f), 0.8f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.2f), 0.7f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.1f), 0.6f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-1.0f), 0.5f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.9f), 0.4f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.8f), 0.3f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.7f), 0.2f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.6f), 0.1f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.5f), 0.0f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.4f), 0.9f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.3f), 0.8f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.2f), 0.7f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(-0.1f), 0.6f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.0f), 0.5f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.1f), 0.4f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.2f), 0.3f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.3f), 0.2f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.4f), 0.1f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.5f), 0.0f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.6f), 0.9f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.7f), 0.8f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.8f), 0.7f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(0.9f), 0.6f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.0f), 0.5f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.1f), 0.4f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.2f), 0.3f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.3f), 0.2f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.4f), 0.1f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.5f), 0.0f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.6f), 0.9f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.7f), 0.8f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.8f), 0.7f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(1.9f), 0.6f); + EXPECT_FLOAT_EQ(clamper.distance_to_scanline_anchor(2.0f), 0.5f); +} + +TEST(imbuf_rasterizer, center_pixel_clamper_distance_to_column_anchorpoint) +{ + CenterPixelClampingMethod clamper; + + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-2.0f), 0.5f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.9f), 0.4f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.8f), 0.3f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.7f), 0.2f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.6f), 0.1f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.5f), 0.0f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.4f), 0.9f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.3f), 0.8f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.2f), 0.7f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.1f), 0.6f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-1.0f), 0.5f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.9f), 0.4f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.8f), 0.3f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.7f), 0.2f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.6f), 0.1f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.5f), 0.0f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.4f), 0.9f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.3f), 0.8f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.2f), 0.7f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(-0.1f), 0.6f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.0f), 0.5f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.1f), 0.4f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.2f), 0.3f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.3f), 0.2f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.4f), 0.1f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.5f), 0.0f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.6f), 0.9f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.7f), 0.8f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.8f), 0.7f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(0.9f), 0.6f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.0f), 0.5f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.1f), 0.4f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.2f), 0.3f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.3f), 0.2f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.4f), 0.1f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.5f), 0.0f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.6f), 0.9f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.7f), 0.8f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.8f), 0.7f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(1.9f), 0.6f); + EXPECT_FLOAT_EQ(clamper.distance_to_column_anchor(2.0f), 0.5f); +} + +} // namespace blender::imbuf::rasterizer::tests |