Skip to content

Commit

Permalink
Implement the pixelate effect
Browse files Browse the repository at this point in the history
  • Loading branch information
adazem009 committed Oct 27, 2024
1 parent 4045e25 commit fc4b640
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 18 deletions.
24 changes: 8 additions & 16 deletions src/shadermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,35 +36,27 @@ static const char *TEXTURE_UNIT_UNIFORM = "u_skin";
static const char *SKIN_SIZE_UNIFORM = "u_skinSize";

static const std::unordered_map<ShaderManager::Effect, const char *> EFFECT_TO_NAME = {
{ ShaderManager::Effect::Color, "color" },
{ ShaderManager::Effect::Brightness, "brightness" },
{ ShaderManager::Effect::Ghost, "ghost" },
{ ShaderManager::Effect::Fisheye, "fisheye" },
{ ShaderManager::Effect::Whirl, "whirl" }
{ ShaderManager::Effect::Color, "color" }, { ShaderManager::Effect::Brightness, "brightness" }, { ShaderManager::Effect::Ghost, "ghost" },
{ ShaderManager::Effect::Fisheye, "fisheye" }, { ShaderManager::Effect::Whirl, "whirl" }, { ShaderManager::Effect::Pixelate, "pixelate" }
};

static const std::unordered_map<ShaderManager::Effect, const char *> EFFECT_UNIFORM_NAME = {
{ ShaderManager::Effect::Color, "u_color" },
{ ShaderManager::Effect::Brightness, "u_brightness" },
{ ShaderManager::Effect::Ghost, "u_ghost" },
{ ShaderManager::Effect::Fisheye, "u_fisheye" },
{ ShaderManager::Effect::Whirl, "u_whirl" }
{ ShaderManager::Effect::Color, "u_color" }, { ShaderManager::Effect::Brightness, "u_brightness" }, { ShaderManager::Effect::Ghost, "u_ghost" },
{ ShaderManager::Effect::Fisheye, "u_fisheye" }, { ShaderManager::Effect::Whirl, "u_whirl" }, { ShaderManager::Effect::Pixelate, "u_pixelate" }
};

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

static const std::unordered_map<ShaderManager::Effect, bool> EFFECT_SHAPE_CHANGES = {
{ ShaderManager::Effect::Color, false },
{ ShaderManager::Effect::Brightness, false },
{ ShaderManager::Effect::Ghost, false },
{ ShaderManager::Effect::Fisheye, true },
{ ShaderManager::Effect::Whirl, true }
{ ShaderManager::Effect::Color, false }, { ShaderManager::Effect::Brightness, false }, { ShaderManager::Effect::Ghost, false },
{ ShaderManager::Effect::Fisheye, true }, { ShaderManager::Effect::Whirl, true }, { ShaderManager::Effect::Pixelate, true }
};

Q_GLOBAL_STATIC(ShaderManager, globalInstance)
Expand Down
13 changes: 13 additions & 0 deletions src/shaders/sprite.frag
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ uniform float u_fisheye;
uniform float u_whirl;
#endif // ENABLE_whirl

#ifdef ENABLE_pixelate
uniform float u_pixelate;
uniform vec2 u_skinSize;
#endif // ENABLE_pixelate

varying vec2 v_texCoord;
uniform sampler2D u_skin;

Expand Down Expand Up @@ -97,6 +102,14 @@ void main()
{
vec2 texcoord0 = v_texCoord;

#ifdef ENABLE_pixelate
{
// TODO: clean up "pixel" edges
vec2 pixelTexelSize = u_skinSize / u_pixelate;
texcoord0 = (floor(texcoord0 * pixelTexelSize) + kCenter) / pixelTexelSize;
}
#endif // ENABLE_pixelate

#ifdef ENABLE_whirl
{
const float kRadius = 0.5;
Expand Down
1 change: 1 addition & 0 deletions test/penlayer/penlayer_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ TEST_F(PenLayerTest, Stamp)
targets.back()->updateCostume(sprite->sprite()->currentCostume().get());
targets.back()->setGraphicEffect(ShaderManager::Effect::Color, i * 25);
targets.back()->setGraphicEffect(ShaderManager::Effect::Ghost, i * 5);
targets.back()->setGraphicEffect(ShaderManager::Effect::Pixelate, i * 25);
sprite->setRenderedTarget(targets.back().get());
i++;
}
Expand Down
37 changes: 37 additions & 0 deletions test/shadermanager/shadermanager_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,40 @@ TEST_F(ShaderManagerTest, WhirlEffectValue)

program->release();
}

TEST_F(ShaderManagerTest, PixelateEffectValue)
{
static const QString effectName = "pixelate";
static const QString uniformName = "u_" + effectName;
static const ShaderManager::Effect effect = ShaderManager::Effect::Pixelate;

std::unordered_map<ShaderManager::Effect, float> values;

QOpenGLFunctions glF(&m_context);
glF.initializeOpenGLFunctions();
ShaderManager manager;

// In range
std::unordered_map<ShaderManager::Effect, double> effects = { { effect, 58.5 } };
QOpenGLShaderProgram *program = manager.getShaderProgram(effects);
program->bind();
manager.setUniforms(program, 0, QSize(), effects);
manager.getUniformValuesForEffects(effects, values);

GLfloat value = 0.0f;
glF.glGetUniformfv(program->programId(), program->uniformLocation(uniformName), &value);
ASSERT_EQ(value, 5.85f);
ASSERT_EQ(values.at(effect), value);

effects[effect] = -20.8;
program->bind();
manager.setUniforms(program, 0, QSize(), effects);
manager.getUniformValuesForEffects(effects, values);

value = 0.0f;
glF.glGetUniformfv(program->programId(), program->uniformLocation(uniformName), &value);
ASSERT_EQ(value, 2.08f);
ASSERT_EQ(values.at(effect), value);

program->release();
}
Binary file modified test/shape_changing_effects.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/stamp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/stamp_hq.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions test/targetpainter/targetpainter_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ TEST_F(TargetPainterTest, Paint)
effects.clear();
effects[ShaderManager::Effect::Fisheye] = 46;
effects[ShaderManager::Effect::Whirl] = 50;
/*effects[ShaderManager::Effect::Pixelate] = 25;
effects[ShaderManager::Effect::Mosaic] = 30;*/
effects[ShaderManager::Effect::Pixelate] = 25;
// effects[ShaderManager::Effect::Mosaic] = 30;
EXPECT_CALL(target, texture()).WillOnce(Return(texture));
EXPECT_CALL(target, cpuTexture()).WillOnce(ReturnRef(texture));
EXPECT_CALL(target, graphicEffects()).WillOnce(ReturnRef(effects));
Expand Down

0 comments on commit fc4b640

Please sign in to comment.