Use the ResourcePool to allocate RTT textures in EffectChain.
[movit] / glow_effect_test.cpp
1 // Unit tests for GlowEffect.
2
3 #include <math.h>
4
5 #include "effect_chain.h"
6 #include "glow_effect.h"
7 #include "gtest/gtest.h"
8 #include "image_format.h"
9 #include "test_util.h"
10
11 TEST(GlowEffectTest, NoAmountDoesNothing) {
12         const int size = 4;
13
14         float data[size * size] = {
15                 0.0, 1.0, 0.0, 1.0,
16                 0.0, 1.0, 1.0, 0.0,
17                 0.0, 0.5, 1.0, 0.5,
18                 0.0, 0.0, 0.0, 0.0,
19         };
20         float out_data[size * size];
21
22         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
23         Effect *glow_effect = tester.get_chain()->add_effect(new GlowEffect());
24         ASSERT_TRUE(glow_effect->set_float("radius", 2.0f));
25         ASSERT_TRUE(glow_effect->set_float("blurred_mix_amount", 0.0f));
26         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
27
28         expect_equal(data, out_data, size, size);
29 }
30
31 TEST(GlowEffectTest, SingleDot) {
32         const int size = 13;
33         const float sigma = 0.5f;
34         const float amount = 0.2f;
35
36         float data[] = {  // One single dot in the middle.
37                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
38                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
39                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
40                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
41                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
42                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
43                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
44                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
45                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
46                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
47                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
48                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
49                 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 
50         };
51         float expected_data[size * size], out_data[size * size];
52
53         // The output should be equal to the input, plus approximately a logistic blob.
54         // From http://en.wikipedia.org/wiki/Logistic_distribution#Alternative_parameterization.
55         const float c1 = M_PI / (sigma * 4 * sqrt(3.0f));
56         const float c2 = M_PI / (sigma * 2.0 * sqrt(3.0f));
57
58         for (int y = 0; y < size; ++y) {
59                 for (int x = 0; x < size; ++x) {
60                         float xd = c2 * (x - 6);
61                         float yd = c2 * (y - 6);
62                         expected_data[y * size + x] = data[y * size + x] +
63                                 (amount * c1 * c1) / (cosh(xd) * cosh(xd) * cosh(yd) * cosh(yd));
64                 }
65         }
66
67         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
68         Effect *glow_effect = tester.get_chain()->add_effect(new GlowEffect());
69         ASSERT_TRUE(glow_effect->set_float("radius", sigma));
70         ASSERT_TRUE(glow_effect->set_float("blurred_mix_amount", amount));
71         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
72
73         expect_equal(expected_data, out_data, size, size, 0.1f, 1e-3);
74 }
75
76 TEST(GlowEffectTest, GlowsOntoZeroAlpha) {
77         const int size = 7;
78         const float sigma = 1.0f;
79         const float amount = 1.0f;
80
81         float data[4 * size] = {
82                 0.0, 0.0, 0.0, 0.0,
83                 0.0, 0.0, 0.0, 0.0,
84                 0.0, 0.0, 0.0, 0.0,
85                 0.0, 1.0, 0.0, 0.5,
86                 0.0, 0.0, 0.0, 0.0,
87                 0.0, 0.0, 0.0, 0.0,
88                 0.0, 0.0, 0.0, 0.0,
89         };
90         float expected_data[4 * size] = {
91                 0.0, 1.0, 0.0, 0.002, 
92                 0.0, 1.0, 0.0, 0.014,
93                 0.0, 1.0, 0.0, 0.065, 
94                 0.0, 1.0, 0.0, 0.635, 
95                 0.0, 1.0, 0.0, 0.065, 
96                 0.0, 1.0, 0.0, 0.014,
97                 0.0, 1.0, 0.0, 0.002, 
98         };
99
100         float out_data[4 * size];
101
102         EffectChainTester tester(data, 1, size, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
103         Effect *glow_effect = tester.get_chain()->add_effect(new GlowEffect());
104         ASSERT_TRUE(glow_effect->set_float("radius", sigma));
105         ASSERT_TRUE(glow_effect->set_float("blurred_mix_amount", amount));
106         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
107
108         expect_equal(expected_data, out_data, 4, size);
109 }