Skip to content

Commit 10f9639

Browse files
committed
Use effect mask instead of map for enabled effects
1 parent e5fb1cc commit 10f9639

File tree

8 files changed

+107
-93
lines changed

8 files changed

+107
-93
lines changed

src/cputexturemanager.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,16 @@ const std::vector<QPoint> &CpuTextureManager::getTextureConvexHullPoints(const T
5252
return it->second;
5353
}
5454

55-
QRgb CpuTextureManager::getPointColor(const Texture &texture, int x, int y, const std::unordered_map<ShaderManager::Effect, double> &effects)
55+
QRgb CpuTextureManager::getPointColor(const Texture &texture, int x, int y, ShaderManager::Effect effectMask, const std::unordered_map<ShaderManager::Effect, double> &effects)
5656
{
5757
const int width = texture.width();
5858
const int height = texture.height();
5959

60-
if (!effects.empty()) {
60+
if (effectMask != 0) {
6161
// Get local position with effect transform
6262
QVector2D transformedCoords;
6363
const QVector2D localCoords(x / static_cast<float>(width), y / static_cast<float>(height));
64-
EffectTransform::transformPoint(effects, localCoords, transformedCoords);
64+
EffectTransform::transformPoint(effectMask, effects, localCoords, transformedCoords);
6565
x = transformedCoords.x() * width;
6666
y = transformedCoords.y() * height;
6767
}
@@ -72,25 +72,25 @@ QRgb CpuTextureManager::getPointColor(const Texture &texture, int x, int y, cons
7272
GLubyte *pixels = getTextureData(texture);
7373
QRgb color = qRgba(pixels[(y * width + x) * 4], pixels[(y * width + x) * 4 + 1], pixels[(y * width + x) * 4 + 2], pixels[(y * width + x) * 4 + 3]);
7474

75-
if (effects.empty())
75+
if (effectMask == 0)
7676
return color;
7777
else
78-
return EffectTransform::transformColor(effects, color);
78+
return EffectTransform::transformColor(effectMask, effects, color);
7979
}
8080

81-
bool CpuTextureManager::textureContainsPoint(const Texture &texture, const QPointF &localPoint, const std::unordered_map<ShaderManager::Effect, double> &effects)
81+
bool CpuTextureManager::textureContainsPoint(const Texture &texture, const QPointF &localPoint, ShaderManager::Effect effectMask, const std::unordered_map<ShaderManager::Effect, double> &effects)
8282
{
8383
// https://github.com/scratchfoundation/scratch-render/blob/7b823985bc6fe92f572cc3276a8915e550f7c5e6/src/Silhouette.js#L219-L226
8484
const int width = texture.width();
8585
const int height = texture.height();
8686
int x = localPoint.x();
8787
int y = localPoint.y();
8888

89-
if (!effects.empty()) {
89+
if (effectMask != 0) {
9090
// Get local position with effect transform
9191
QVector2D transformedCoords;
9292
const QVector2D localCoords(x / static_cast<float>(width), y / static_cast<float>(height));
93-
EffectTransform::transformPoint(effects, localCoords, transformedCoords);
93+
EffectTransform::transformPoint(effectMask, effects, localCoords, transformedCoords);
9494
x = transformedCoords.x() * width;
9595
y = transformedCoords.y() * height;
9696
}

src/cputexturemanager.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ class CpuTextureManager
2222
GLubyte *getTextureData(const Texture &texture);
2323
const std::vector<QPoint> &getTextureConvexHullPoints(const Texture &texture);
2424

25-
QRgb getPointColor(const Texture &texture, int x, int y, const std::unordered_map<ShaderManager::Effect, double> &effects);
26-
bool textureContainsPoint(const Texture &texture, const QPointF &localPoint, const std::unordered_map<ShaderManager::Effect, double> &effects);
25+
QRgb getPointColor(const Texture &texture, int x, int y, ShaderManager::Effect effectMask, const std::unordered_map<ShaderManager::Effect, double> &effects);
26+
bool textureContainsPoint(const Texture &texture, const QPointF &localPoint, ShaderManager::Effect effectMask, const std::unordered_map<ShaderManager::Effect, double> &effects);
2727

2828
void removeTexture(const Texture &texture);
2929

src/effecttransform.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
using namespace scratchcpprender;
88

9-
QRgb EffectTransform::transformColor(const std::unordered_map<ShaderManager::Effect, double> &effectValues, QRgb color)
9+
QRgb EffectTransform::transformColor(ShaderManager::Effect effectMask, const std::unordered_map<ShaderManager::Effect, double> &effectValues, QRgb color)
1010
{
1111
// https://github.com/scratchfoundation/scratch-render/blob/e075e5f5ebc95dec4a2718551624ad587c56f0a6/src/EffectTransform.js#L40-L119
1212
// If the color is fully transparent, don't bother attempting any transformations.
@@ -18,8 +18,8 @@ QRgb EffectTransform::transformColor(const std::unordered_map<ShaderManager::Eff
1818
std::unordered_map<ShaderManager::Effect, float> uniforms;
1919
ShaderManager::getUniformValuesForEffects(effectValues, uniforms);
2020

21-
const bool enableColor = uniforms[ShaderManager::Effect::Color] != 0;
22-
const bool enableBrightness = uniforms[ShaderManager::Effect::Brightness] != 0;
21+
const bool enableColor = (effectMask & ShaderManager::Effect::Color) != 0;
22+
const bool enableBrightness = (effectMask & ShaderManager::Effect::Brightness) != 0;
2323

2424
if (enableColor || enableBrightness) {
2525
// gl_FragColor.rgb /= gl_FragColor.a + epsilon;
@@ -99,7 +99,7 @@ QRgb EffectTransform::transformColor(const std::unordered_map<ShaderManager::Eff
9999
return inOutColor.rgba();
100100
}
101101

102-
void EffectTransform::transformPoint(const std::unordered_map<ShaderManager::Effect, double> &effectValues, const QVector2D &vec, QVector2D &dst)
102+
void EffectTransform::transformPoint(ShaderManager::Effect effectMask, const std::unordered_map<ShaderManager::Effect, double> &effectValues, const QVector2D &vec, QVector2D &dst)
103103
{
104104
// TODO: Implement remaining effects
105105
dst = vec;

src/effecttransform.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ class EffectTransform
1414
public:
1515
EffectTransform() = delete;
1616

17-
static QRgb transformColor(const std::unordered_map<ShaderManager::Effect, double> &effectValues, QRgb color);
18-
static void transformPoint(const std::unordered_map<ShaderManager::Effect, double> &effectValues, const QVector2D &vec, QVector2D &dst);
17+
static QRgb transformColor(ShaderManager::Effect effectMask, const std::unordered_map<ShaderManager::Effect, double> &effectValues, QRgb color);
18+
static void transformPoint(ShaderManager::Effect effectMask, const std::unordered_map<ShaderManager::Effect, double> &effectValues, const QVector2D &vec, QVector2D &dst);
1919
};
2020

2121
} // namespace scratchcpprender

src/renderedtarget.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -540,18 +540,20 @@ const std::unordered_map<ShaderManager::Effect, double> &RenderedTarget::graphic
540540
void RenderedTarget::setGraphicEffect(ShaderManager::Effect effect, double value)
541541
{
542542
bool changed = false;
543-
auto it = m_graphicEffects.find(effect);
544543

545544
if (value == 0) {
546-
if (it != m_graphicEffects.cend()) {
545+
if ((m_graphicEffectMask & effect) != 0) {
547546
changed = true;
548547
m_graphicEffects.erase(effect);
548+
m_graphicEffectMask &= ~effect;
549549
}
550550
} else {
551-
if (it != m_graphicEffects.cend())
552-
changed = it->second != value;
553-
else
551+
if ((m_graphicEffectMask & effect) != 0)
552+
changed = m_graphicEffects[effect] != value;
553+
else {
554554
changed = true;
555+
m_graphicEffectMask |= effect;
556+
}
555557

556558
m_graphicEffects[effect] = value;
557559
}
@@ -569,6 +571,7 @@ void RenderedTarget::clearGraphicEffects()
569571

570572
// TODO: Set m_convexHullDirty to true if any of the previous effects changed shape
571573
m_graphicEffects.clear();
574+
m_graphicEffectMask = ShaderManager::Effect::NoEffect;
572575
}
573576

574577
const std::vector<QPoint> &RenderedTarget::hullPoints() const
@@ -618,7 +621,7 @@ QRgb RenderedTarget::colorAtScratchPoint(double x, double y) const
618621
if ((x < 0 || x >= width) || (y < 0 || y >= height))
619622
return qRgba(0, 0, 0, 0);
620623

621-
return textureManager()->getPointColor(m_cpuTexture, x, y, m_graphicEffects);
624+
return textureManager()->getPointColor(m_cpuTexture, x, y, m_graphicEffectMask, m_graphicEffects);
622625
}
623626

624627
bool RenderedTarget::touchingClones(const std::vector<libscratchcpp::Sprite *> &clones) const
@@ -806,7 +809,7 @@ const std::vector<QPointF> &RenderedTarget::transformedHullPoints() const
806809

807810
bool RenderedTarget::containsLocalPoint(const QPointF &point) const
808811
{
809-
return textureManager()->textureContainsPoint(m_cpuTexture, point, m_graphicEffects);
812+
return textureManager()->textureContainsPoint(m_cpuTexture, point, m_graphicEffectMask, m_graphicEffects);
810813
}
811814

812815
QPointF RenderedTarget::transformPoint(double scratchX, double scratchY, double originX, double originY, double rot) const
@@ -874,11 +877,10 @@ bool RenderedTarget::touchingColor(const libscratchcpp::Value &color, bool hasMa
874877

875878
if (hasMask) {
876879
// Ignore ghost effect when checking mask
877-
auto it = m_graphicEffects.find(ShaderManager::Effect::Ghost);
878-
879-
if (it != m_graphicEffects.cend()) {
880-
ghostValue = it->second;
880+
if ((m_graphicEffectMask & ShaderManager::Effect::Ghost) != 0) {
881+
ghostValue = m_graphicEffects[ShaderManager::Effect::Ghost];
881882
m_graphicEffects.erase(ShaderManager::Effect::Ghost);
883+
m_graphicEffectMask &= ~ShaderManager::Effect::Ghost;
882884
}
883885

884886
mask3b = convertColor(mask);
@@ -910,8 +912,10 @@ bool RenderedTarget::touchingColor(const libscratchcpp::Value &color, bool hasMa
910912

911913
if (colorMatches(rgb, pixelColor)) {
912914
// Restore ghost effect value
913-
if (hasMask && ghostValue != 0)
915+
if (hasMask && ghostValue != 0) {
914916
m_graphicEffects[ShaderManager::Effect::Ghost] = ghostValue;
917+
m_graphicEffectMask |= ShaderManager::Effect::Ghost;
918+
}
915919

916920
return true;
917921
}
@@ -920,8 +924,10 @@ bool RenderedTarget::touchingColor(const libscratchcpp::Value &color, bool hasMa
920924
}
921925

922926
// Restore ghost effect value
923-
if (hasMask && ghostValue != 0)
927+
if (hasMask && ghostValue != 0) {
924928
m_graphicEffects[ShaderManager::Effect::Ghost] = ghostValue;
929+
m_graphicEffectMask |= ShaderManager::Effect::Ghost;
930+
}
925931

926932
return false;
927933
}

src/renderedtarget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class RenderedTarget : public IRenderedTarget
160160
mutable std::shared_ptr<CpuTextureManager> m_textureManager; // NOTE: Use textureManager()!
161161
std::unique_ptr<QOpenGLFunctions> m_glF;
162162
mutable std::unordered_map<ShaderManager::Effect, double> m_graphicEffects;
163+
mutable ShaderManager::Effect m_graphicEffectMask = ShaderManager::Effect::NoEffect;
163164
double m_size = 1;
164165
double m_x = 0;
165166
double m_y = 0;

test/effecttransform/effecttransform_test.cpp

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,108 +16,112 @@ class EffectTransformTest : public testing::Test
1616
TEST_F(EffectTransformTest, NoEffect)
1717
{
1818
QRgb color = qRgba(0, 0, 0, 0);
19-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), color);
19+
auto mask = ShaderManager::Effect::NoEffect;
20+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), color);
2021

2122
color = qRgba(255, 0, 0, 255);
22-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), color);
23+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), color);
2324

2425
color = qRgba(0, 255, 255, 255);
25-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), color);
26+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), color);
2627

2728
color = qRgba(255, 255, 255, 128);
28-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), color);
29+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), color);
2930

3031
QVector2D dst;
31-
EffectTransform::transformPoint(m_effects, QVector2D(0.5, -0.3), dst);
32+
EffectTransform::transformPoint(mask, m_effects, QVector2D(0.5, -0.3), dst);
3233
ASSERT_EQ(dst, QVector2D(0.5, -0.3));
3334
}
3435

3536
TEST_F(EffectTransformTest, ColorEffect)
3637
{
3738
// 100
3839
m_effects[ShaderManager::Effect::Color] = 100;
40+
auto mask = ShaderManager::Effect::Color;
3941
QRgb color = qRgba(0, 0, 0, 0);
40-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), color);
42+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), color);
4143

4244
color = qRgba(255, 0, 0, 255);
43-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgb(0, 255, 255));
45+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgb(0, 255, 255));
4446

4547
color = qRgba(100, 255, 200, 128);
46-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(128, 100, 100, 128));
48+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(128, 100, 100, 128));
4749

4850
// 175
4951
m_effects[ShaderManager::Effect::Color] = 175;
5052
color = qRgba(255, 0, 0, 255);
51-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgb(255, 0, 191));
53+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgb(255, 0, 191));
5254

5355
color = qRgba(100, 255, 200, 128);
54-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(100, 128, 107, 128));
56+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(100, 128, 107, 128));
5557
}
5658

5759
TEST_F(EffectTransformTest, BrightnessEffect)
5860
{
5961
// -100
6062
m_effects[ShaderManager::Effect::Brightness] = -100;
63+
auto mask = ShaderManager::Effect::Brightness;
6164
QRgb color = qRgba(0, 0, 0, 0);
62-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), color);
65+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), color);
6366

6467
color = qRgba(255, 0, 0, 255);
65-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgb(0, 0, 0));
68+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgb(0, 0, 0));
6669

6770
color = qRgba(100, 255, 200, 128);
68-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(0, 0, 0, 128));
71+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(0, 0, 0, 128));
6972

7073
// -50
7174
m_effects[ShaderManager::Effect::Brightness] = -50;
7275
color = qRgba(255, 0, 0, 255);
73-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgb(127, 0, 0));
76+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgb(127, 0, 0));
7477

7578
color = qRgba(100, 255, 200, 128);
76-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(36, 64, 64, 128));
79+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(36, 64, 64, 128));
7780

7881
// 50
7982
m_effects[ShaderManager::Effect::Brightness] = 50;
8083
color = qRgba(255, 0, 0, 255);
81-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgb(255, 127, 127));
84+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgb(255, 127, 127));
8285

8386
color = qRgba(100, 255, 200, 128);
84-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(128, 128, 128, 128));
87+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(128, 128, 128, 128));
8588

8689
// 100
8790
m_effects[ShaderManager::Effect::Brightness] = 100;
8891
color = qRgba(255, 0, 0, 255);
89-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgb(255, 255, 255));
92+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgb(255, 255, 255));
9093

9194
color = qRgba(100, 255, 200, 128);
92-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(128, 128, 128, 128));
95+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(128, 128, 128, 128));
9396
}
9497

9598
TEST_F(EffectTransformTest, GhostEffect)
9699
{
97100
// 25
98101
m_effects[ShaderManager::Effect::Ghost] = 25;
102+
auto mask = ShaderManager::Effect::Ghost;
99103
QRgb color = qRgba(0, 0, 0, 0);
100-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), color);
104+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), color);
101105

102106
color = qRgba(255, 0, 0, 255);
103-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(191, 0, 0, 191));
107+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(191, 0, 0, 191));
104108

105109
color = qRgba(100, 255, 200, 128);
106-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(75, 191, 150, 96));
110+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(75, 191, 150, 96));
107111

108112
// 50
109113
m_effects[ShaderManager::Effect::Ghost] = 50;
110114
color = qRgba(255, 0, 0, 255);
111-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(128, 0, 0, 128));
115+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(128, 0, 0, 128));
112116

113117
color = qRgba(100, 255, 200, 128);
114-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(50, 128, 100, 64));
118+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(50, 128, 100, 64));
115119

116120
// 100
117121
m_effects[ShaderManager::Effect::Ghost] = 100;
118122
color = qRgba(255, 0, 0, 255);
119-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(0, 0, 0, 0));
123+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(0, 0, 0, 0));
120124

121125
color = qRgba(100, 255, 200, 128);
122-
ASSERT_EQ(EffectTransform::transformColor(m_effects, color), qRgba(0, 0, 0, 0));
126+
ASSERT_EQ(EffectTransform::transformColor(mask, m_effects, color), qRgba(0, 0, 0, 0));
123127
}

0 commit comments

Comments
 (0)