Skip to content

Commit fc4b640

Browse files
committed
Implement the pixelate effect
1 parent 4045e25 commit fc4b640

File tree

8 files changed

+61
-18
lines changed

8 files changed

+61
-18
lines changed

src/shadermanager.cpp

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,27 @@ static const char *TEXTURE_UNIT_UNIFORM = "u_skin";
3636
static const char *SKIN_SIZE_UNIFORM = "u_skinSize";
3737

3838
static const std::unordered_map<ShaderManager::Effect, const char *> EFFECT_TO_NAME = {
39-
{ ShaderManager::Effect::Color, "color" },
40-
{ ShaderManager::Effect::Brightness, "brightness" },
41-
{ ShaderManager::Effect::Ghost, "ghost" },
42-
{ ShaderManager::Effect::Fisheye, "fisheye" },
43-
{ ShaderManager::Effect::Whirl, "whirl" }
39+
{ ShaderManager::Effect::Color, "color" }, { ShaderManager::Effect::Brightness, "brightness" }, { ShaderManager::Effect::Ghost, "ghost" },
40+
{ ShaderManager::Effect::Fisheye, "fisheye" }, { ShaderManager::Effect::Whirl, "whirl" }, { ShaderManager::Effect::Pixelate, "pixelate" }
4441
};
4542

4643
static const std::unordered_map<ShaderManager::Effect, const char *> EFFECT_UNIFORM_NAME = {
47-
{ ShaderManager::Effect::Color, "u_color" },
48-
{ ShaderManager::Effect::Brightness, "u_brightness" },
49-
{ ShaderManager::Effect::Ghost, "u_ghost" },
50-
{ ShaderManager::Effect::Fisheye, "u_fisheye" },
51-
{ ShaderManager::Effect::Whirl, "u_whirl" }
44+
{ ShaderManager::Effect::Color, "u_color" }, { ShaderManager::Effect::Brightness, "u_brightness" }, { ShaderManager::Effect::Ghost, "u_ghost" },
45+
{ ShaderManager::Effect::Fisheye, "u_fisheye" }, { ShaderManager::Effect::Whirl, "u_whirl" }, { ShaderManager::Effect::Pixelate, "u_pixelate" }
5246
};
5347

5448
static const std::unordered_map<ShaderManager::Effect, ConverterFunc> EFFECT_CONVERTER = {
5549
{ ShaderManager::Effect::Color, [](float x) { return wrapClamp(x / 200.0f, 0.0f, 1.0f); } },
5650
{ ShaderManager::Effect::Brightness, [](float x) { return std::clamp(x, -100.0f, 100.0f) / 100.0f; } },
5751
{ ShaderManager::Effect::Ghost, [](float x) { return 1 - std::clamp(x, 0.0f, 100.0f) / 100.0f; } },
5852
{ ShaderManager::Effect::Fisheye, [](float x) { return std::max(0.0f, (x + 100.0f) / 100.0f); } },
59-
{ ShaderManager::Effect::Whirl, [](float x) { return x * (float)pi / 180.0f; } }
53+
{ ShaderManager::Effect::Whirl, [](float x) { return x * (float)pi / 180.0f; } },
54+
{ ShaderManager::Effect::Pixelate, [](float x) { return std::abs(x) / 10.0f; } }
6055
};
6156

6257
static const std::unordered_map<ShaderManager::Effect, bool> EFFECT_SHAPE_CHANGES = {
63-
{ ShaderManager::Effect::Color, false },
64-
{ ShaderManager::Effect::Brightness, false },
65-
{ ShaderManager::Effect::Ghost, false },
66-
{ ShaderManager::Effect::Fisheye, true },
67-
{ ShaderManager::Effect::Whirl, true }
58+
{ ShaderManager::Effect::Color, false }, { ShaderManager::Effect::Brightness, false }, { ShaderManager::Effect::Ghost, false },
59+
{ ShaderManager::Effect::Fisheye, true }, { ShaderManager::Effect::Whirl, true }, { ShaderManager::Effect::Pixelate, true }
6860
};
6961

7062
Q_GLOBAL_STATIC(ShaderManager, globalInstance)

src/shaders/sprite.frag

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ uniform float u_fisheye;
2626
uniform float u_whirl;
2727
#endif // ENABLE_whirl
2828

29+
#ifdef ENABLE_pixelate
30+
uniform float u_pixelate;
31+
uniform vec2 u_skinSize;
32+
#endif // ENABLE_pixelate
33+
2934
varying vec2 v_texCoord;
3035
uniform sampler2D u_skin;
3136

@@ -97,6 +102,14 @@ void main()
97102
{
98103
vec2 texcoord0 = v_texCoord;
99104

105+
#ifdef ENABLE_pixelate
106+
{
107+
// TODO: clean up "pixel" edges
108+
vec2 pixelTexelSize = u_skinSize / u_pixelate;
109+
texcoord0 = (floor(texcoord0 * pixelTexelSize) + kCenter) / pixelTexelSize;
110+
}
111+
#endif // ENABLE_pixelate
112+
100113
#ifdef ENABLE_whirl
101114
{
102115
const float kRadius = 0.5;

test/penlayer/penlayer_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ TEST_F(PenLayerTest, Stamp)
393393
targets.back()->updateCostume(sprite->sprite()->currentCostume().get());
394394
targets.back()->setGraphicEffect(ShaderManager::Effect::Color, i * 25);
395395
targets.back()->setGraphicEffect(ShaderManager::Effect::Ghost, i * 5);
396+
targets.back()->setGraphicEffect(ShaderManager::Effect::Pixelate, i * 25);
396397
sprite->setRenderedTarget(targets.back().get());
397398
i++;
398399
}

test/shadermanager/shadermanager_test.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,40 @@ TEST_F(ShaderManagerTest, WhirlEffectValue)
351351

352352
program->release();
353353
}
354+
355+
TEST_F(ShaderManagerTest, PixelateEffectValue)
356+
{
357+
static const QString effectName = "pixelate";
358+
static const QString uniformName = "u_" + effectName;
359+
static const ShaderManager::Effect effect = ShaderManager::Effect::Pixelate;
360+
361+
std::unordered_map<ShaderManager::Effect, float> values;
362+
363+
QOpenGLFunctions glF(&m_context);
364+
glF.initializeOpenGLFunctions();
365+
ShaderManager manager;
366+
367+
// In range
368+
std::unordered_map<ShaderManager::Effect, double> effects = { { effect, 58.5 } };
369+
QOpenGLShaderProgram *program = manager.getShaderProgram(effects);
370+
program->bind();
371+
manager.setUniforms(program, 0, QSize(), effects);
372+
manager.getUniformValuesForEffects(effects, values);
373+
374+
GLfloat value = 0.0f;
375+
glF.glGetUniformfv(program->programId(), program->uniformLocation(uniformName), &value);
376+
ASSERT_EQ(value, 5.85f);
377+
ASSERT_EQ(values.at(effect), value);
378+
379+
effects[effect] = -20.8;
380+
program->bind();
381+
manager.setUniforms(program, 0, QSize(), effects);
382+
manager.getUniformValuesForEffects(effects, values);
383+
384+
value = 0.0f;
385+
glF.glGetUniformfv(program->programId(), program->uniformLocation(uniformName), &value);
386+
ASSERT_EQ(value, 2.08f);
387+
ASSERT_EQ(values.at(effect), value);
388+
389+
program->release();
390+
}

test/shape_changing_effects.png

22 Bytes
Loading

test/stamp.png

336 Bytes
Loading

test/stamp_hq.png

-3.83 KB
Loading

test/targetpainter/targetpainter_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ TEST_F(TargetPainterTest, Paint)
111111
effects.clear();
112112
effects[ShaderManager::Effect::Fisheye] = 46;
113113
effects[ShaderManager::Effect::Whirl] = 50;
114-
/*effects[ShaderManager::Effect::Pixelate] = 25;
115-
effects[ShaderManager::Effect::Mosaic] = 30;*/
114+
effects[ShaderManager::Effect::Pixelate] = 25;
115+
// effects[ShaderManager::Effect::Mosaic] = 30;
116116
EXPECT_CALL(target, texture()).WillOnce(Return(texture));
117117
EXPECT_CALL(target, cpuTexture()).WillOnce(ReturnRef(texture));
118118
EXPECT_CALL(target, graphicEffects()).WillOnce(ReturnRef(effects));

0 commit comments

Comments
 (0)