// Note that this also contains the tests for some of the simpler effects.
#include <GL/glew.h>
+#include <assert.h>
+#include "effect.h"
#include "effect_chain.h"
#include "flat_input.h"
#include "gtest/gtest.h"
+#include "input.h"
#include "mirror_effect.h"
+#include "multiply_effect.h"
#include "resize_effect.h"
#include "test_util.h"
+#include "util.h"
TEST(EffectChainTest, EmptyChain) {
float data[] = {
expect_equal(data, out_data, 4, size);
}
+// An effect that does nothing, and specifies that it preserves blank alpha.
+class BlankAlphaPreservingEffect : public Effect {
+public:
+ BlankAlphaPreservingEffect() {}
+ virtual std::string effect_type_id() const { return "BlankAlphaPreservingEffect"; }
+ std::string output_fragment_shader() { return read_file("identity.frag"); }
+ virtual AlphaHandling alpha_handling() const { return INPUT_PREMULTIPLIED_ALPHA_KEEP_BLANK; }
+};
+
+TEST(EffectChainTest, NoAlphaConversionsWithBlankAlphaPreservingEffect) {
+ const int size = 3;
+ float data[4 * size] = {
+ 0.0f, 0.0f, 1.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 1.0f,
+ };
+ float out_data[4 * size];
+ EffectChainTester tester(NULL, size, 1);
+ tester.get_chain()->add_input(new BlueInput());
+ tester.get_chain()->add_effect(new BlankAlphaPreservingEffect());
+ RewritingEffect<MirrorEffect> *effect = new RewritingEffect<MirrorEffect>();
+ tester.get_chain()->add_effect(effect);
+ tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
+
+ Node *node = effect->replaced_node;
+ EXPECT_EQ(1, node->incoming_links.size());
+ EXPECT_EQ(0, node->outgoing_links.size());
+
+ expect_equal(data, out_data, 4, size);
+}
+
+// This is the counter-test to NoAlphaConversionsWithBlankAlphaPreservingEffect;
+// just to be sure that with a normal INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA effect,
+// an alpha conversion _should_ be inserted at the very end. (There is some overlap
+// with other tests.)
+TEST(EffectChainTest, AlphaConversionsWithNonBlankAlphaPreservingEffect) {
+ const int size = 3;
+ float data[4 * size] = {
+ 0.0f, 0.0f, 1.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 1.0f,
+ };
+ float out_data[4 * size];
+ EffectChainTester tester(NULL, size, 1);
+ tester.get_chain()->add_input(new BlueInput());
+ tester.get_chain()->add_effect(new IdentityEffect()); // Not BlankAlphaPreservingEffect.
+ RewritingEffect<MirrorEffect> *effect = new RewritingEffect<MirrorEffect>();
+ tester.get_chain()->add_effect(effect);
+ tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
+
+ Node *node = effect->replaced_node;
+ EXPECT_EQ(1, node->incoming_links.size());
+ EXPECT_EQ(1, node->outgoing_links.size());
+ EXPECT_EQ("AlphaDivisionEffect", node->outgoing_links[0]->effect->effect_type_id());
+
+ expect_equal(data, out_data, 4, size);
+}
+
// Effectively scales down its input linearly by 4x (and repeating it),
// which is not attainable without mipmaps.
class MipmapNeedingEffect : public Effect {
expect_equal(expected_data, out_data, 4, 16);
}
-// An effect that multiplies with a constant. Used below.
-class MultiplyEffect : public Effect {
-public:
- MultiplyEffect() { register_float("factor", &factor); }
- virtual std::string effect_type_id() const { return "MultiplyEffect"; }
- std::string output_fragment_shader() { return read_file("multiply.frag"); }
- virtual AlphaHandling alpha_handling() const { return DONT_CARE_ALPHA_TYPE; }
-
-private:
- float factor;
-};
-
// An effect that adds its two inputs together. Used below.
class AddEffect : public Effect {
public:
};
float out_data[2 * 2];
+ const float half[] = { 0.5f, 0.5f, 0.5f, 0.5f };
+ const float two[] = { 2.0f, 2.0f, 2.0f, 0.5f };
+
MultiplyEffect *mul_half = new MultiplyEffect();
- ASSERT_TRUE(mul_half->set_float("factor", 0.5f));
+ ASSERT_TRUE(mul_half->set_vec4("factor", half));
MultiplyEffect *mul_two = new MultiplyEffect();
- ASSERT_TRUE(mul_two->set_float("factor", 2.0f));
+ ASSERT_TRUE(mul_two->set_vec4("factor", two));
EffectChainTester tester(NULL, 2, 2);
};
float out_data[2 * 2];
+ const float half[] = { 0.5f, 0.5f, 0.5f, 0.5f };
+ const float two[] = { 2.0f, 2.0f, 2.0f, 0.5f };
+
MultiplyEffect *mul_half = new MultiplyEffect();
- ASSERT_TRUE(mul_half->set_float("factor", 0.5f));
+ ASSERT_TRUE(mul_half->set_vec4("factor", half));
MultiplyEffect *mul_two = new MultiplyEffect();
- ASSERT_TRUE(mul_two->set_float("factor", 2.0f));
+ ASSERT_TRUE(mul_two->set_vec4("factor", two));
BouncingIdentityEffect *bounce = new BouncingIdentityEffect();