Clamp alpha in MixEffect.
[movit] / mix_effect_test.cpp
1 // Unit tests for MixEffect.
2
3 #include "test_util.h"
4 #include "gtest/gtest.h"
5 #include "mix_effect.h"
6
7 TEST(MixEffectTest, FiftyFiftyMix) {
8         float data_a[] = {
9                 0.0f, 0.25f,
10                 0.75f, 1.0f,
11         };
12         float data_b[] = {
13                 1.0f, 0.5f,
14                 0.75f, 0.6f,
15         };
16         float expected_data[] = {
17                 0.5f, 0.375f,
18                 0.75f, 0.8f,
19         };
20         float out_data[4];
21         EffectChainTester tester(data_a, 2, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
22         Effect *input1 = tester.get_chain()->last_added_effect();
23         Effect *input2 = tester.add_input(data_b, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
24
25         Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
26         ASSERT_TRUE(mix_effect->set_float("strength_first", 0.5f));
27         ASSERT_TRUE(mix_effect->set_float("strength_second", 0.5f));
28         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
29
30         expect_equal(expected_data, out_data, 2, 2);
31 }
32
33 TEST(MixEffectTest, OnlyA) {
34         float data_a[] = {
35                 0.0f, 0.25f,
36                 0.75f, 1.0f,
37         };
38         float data_b[] = {
39                 1.0f, 0.5f,
40                 0.75f, 0.6f,
41         };
42         float out_data[4];
43         EffectChainTester tester(data_a, 2, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
44         Effect *input1 = tester.get_chain()->last_added_effect();
45         Effect *input2 = tester.add_input(data_b, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
46
47         Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
48         ASSERT_TRUE(mix_effect->set_float("strength_first", 1.0f));
49         ASSERT_TRUE(mix_effect->set_float("strength_second", 0.0f));
50         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
51
52         expect_equal(data_a, out_data, 2, 2);
53 }
54
55 TEST(MixEffectTest, DoesNotSumToOne) {
56         float data_a[] = {
57                 1.0f, 0.5f, 0.75f, 0.333f,
58         };
59         float data_b[] = {
60                 1.0f, 0.25f, 0.15f, 0.333f,
61         };
62
63         // The fact that the RGB values don't sum but get averaged here might
64         // actually be a surprising result, but when you think of it,
65         // it does make physical sense.
66         float expected_data[] = {
67                 1.0f, 0.375f, 0.45f, 0.666f,
68         };
69
70         float out_data[4];
71         EffectChainTester tester(data_a, 1, 1, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
72         Effect *input1 = tester.get_chain()->last_added_effect();
73         Effect *input2 = tester.add_input(data_b, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
74
75         Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
76         ASSERT_TRUE(mix_effect->set_float("strength_first", 1.0f));
77         ASSERT_TRUE(mix_effect->set_float("strength_second", 1.0f));
78         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
79
80         expect_equal(expected_data, out_data, 4, 1);
81 }
82
83 TEST(MixEffectTest, AdditiveBlendingWorksForBothTotallyOpaqueAndPartiallyTranslucent) {
84         float data_a[] = {
85                 0.0f, 0.5f, 0.75f, 1.0f,
86                 1.0f, 1.0f, 1.0f, 0.2f,
87         };
88         float data_b[] = {
89                 1.0f, 0.25f, 0.15f, 1.0f,
90                 1.0f, 1.0f, 1.0f, 0.5f,
91         };
92
93         float expected_data[] = {
94                 1.0f, 0.75f, 0.9f, 1.0f,
95                 1.0f, 1.0f, 1.0f, 0.7f,
96         };
97
98         float out_data[4];
99         EffectChainTester tester(data_a, 1, 2, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
100         Effect *input1 = tester.get_chain()->last_added_effect();
101         Effect *input2 = tester.add_input(data_b, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
102
103         Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
104         ASSERT_TRUE(mix_effect->set_float("strength_first", 1.0f));
105         ASSERT_TRUE(mix_effect->set_float("strength_second", 1.0f));
106         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
107
108         expect_equal(expected_data, out_data, 4, 2);
109 }
110
111 TEST(MixEffectTest, MixesLinearlyDespitesRGBInputsAndOutputs) {
112         float data_a[] = {
113                 0.0f, 0.25f,
114                 0.75f, 1.0f,
115         };
116         float data_b[] = {
117                 0.0f, 0.0f,
118                 0.0f, 0.0f,
119         };
120         float expected_data[] = {  // sRGB(0.5 * inv_sRGB(a)).
121                 0.00000f, 0.17349f,
122                 0.54807f, 0.73536f,
123         };
124         float out_data[4];
125         EffectChainTester tester(data_a, 2, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB);
126         Effect *input1 = tester.get_chain()->last_added_effect();
127         Effect *input2 = tester.add_input(data_b, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB);
128
129         Effect *mix_effect = tester.get_chain()->add_effect(new MixEffect(), input1, input2);
130         ASSERT_TRUE(mix_effect->set_float("strength_first", 0.5f));
131         ASSERT_TRUE(mix_effect->set_float("strength_second", 0.5f));
132         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB);
133
134         expect_equal(expected_data, out_data, 2, 2);
135 }