Skip to content

Commit 7b3d3a3

Browse files
committed
Add colorAtScratchPoint() method
1 parent ac18bca commit 7b3d3a3

File tree

5 files changed

+50
-1
lines changed

5 files changed

+50
-1
lines changed

src/irenderedtarget.h

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class IRenderedTarget : public QNanoQuickItem
8686
virtual const std::vector<QPoint> &hullPoints() const = 0;
8787

8888
virtual bool containsScratchPoint(double x, double y) const = 0;
89+
virtual QRgb colorAtScratchPoint(double x, double y) const = 0;
8990

9091
virtual bool touchingClones(const std::vector<libscratchcpp::Sprite *> &clones) const = 0;
9192
};

src/renderedtarget.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,30 @@ bool RenderedTarget::containsScratchPoint(double x, double y) const
582582
return containsLocalPoint(mapFromScratchToLocal(QPointF(x, y)));
583583
}
584584

585+
QRgb RenderedTarget::colorAtScratchPoint(double x, double y) const
586+
{
587+
if (!m_engine || !m_cpuTexture.isValid())
588+
return qRgba(0, 0, 0, 0);
589+
590+
// Translate the coordinates
591+
QPointF point = mapFromScratchToLocal(QPointF(x, y));
592+
x = point.x();
593+
y = point.y();
594+
595+
const double width = m_cpuTexture.width();
596+
const double height = m_cpuTexture.height();
597+
598+
// If the point is outside the texture, return fully transparent color
599+
if ((x < 0 || x >= width) || (y < 0 || y >= height))
600+
return qRgba(0, 0, 0, 0);
601+
602+
GLubyte *data = textureManager()->getTextureData(m_cpuTexture);
603+
const int index = (y * width + x) * 4; // RGBA channels
604+
Q_ASSERT(index >= 0 && index < width * height * 4);
605+
// TODO: Apply graphic effects (#117)
606+
return qRgba(data[index], data[index + 1], data[index + 2], data[index + 3]);
607+
}
608+
585609
bool RenderedTarget::touchingClones(const std::vector<libscratchcpp::Sprite *> &clones) const
586610
{
587611
// https://github.com/scratchfoundation/scratch-render/blob/941562438fe3dd6e7d98d9387607d535dcd68d24/src/RenderWebGL.js#L967-L1002

src/renderedtarget.h

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class RenderedTarget : public IRenderedTarget
9494

9595
Q_INVOKABLE bool contains(const QPointF &point) const override;
9696
bool containsScratchPoint(double x, double y) const override;
97+
QRgb colorAtScratchPoint(double x, double y) const override;
9798

9899
bool touchingClones(const std::vector<libscratchcpp::Sprite *> &) const override;
99100

test/mocks/renderedtargetmock.h

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class RenderedTargetMock : public IRenderedTarget
7171

7272
MOCK_METHOD(bool, contains, (const QPointF &), (const, override));
7373
MOCK_METHOD(bool, containsScratchPoint, (double, double), (const, override));
74+
MOCK_METHOD(QRgb, colorAtScratchPoint, (double, double), (const, override));
7475

7576
MOCK_METHOD(bool, touchingClones, (const std::vector<libscratchcpp::Sprite *> &), (const, override));
7677

test/renderedtarget/renderedtarget_test.cpp

+23-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ TEST_F(RenderedTargetTest, DeinitClone)
299299
ASSERT_EQ(mouseArea.draggedSprite(), nullptr);
300300
}
301301

302-
TEST_F(RenderedTargetTest, HullPoints)
302+
TEST_F(RenderedTargetTest, CpuRendering)
303303
{
304304
EngineMock engine;
305305
Sprite sprite;
@@ -392,6 +392,28 @@ TEST_F(RenderedTargetTest, HullPoints)
392392
ASSERT_TRUE(target.containsScratchPoint(-224.5, 162)); // [3, 3]
393393
ASSERT_FALSE(target.containsScratchPoint(-224.2, 161.5)); // [3.3, 3.5]
394394

395+
// Test colorAtScratchPoint()
396+
ASSERT_EQ(target.colorAtScratchPoint(-227.5, 165), 0); // [0, 0]
397+
ASSERT_EQ(target.colorAtScratchPoint(-226.5, 165), 0); // [1, 0]
398+
ASSERT_EQ(target.colorAtScratchPoint(-225.5, 165), 0); // [2, 0]
399+
ASSERT_EQ(target.colorAtScratchPoint(-224.5, 165), 0); // [3, 0]
400+
401+
ASSERT_EQ(target.colorAtScratchPoint(-227.5, 164), 0); // [0, 1]
402+
ASSERT_EQ(target.colorAtScratchPoint(-226.5, 164), 4278190335); // [1, 1]
403+
ASSERT_EQ(target.colorAtScratchPoint(-226.1, 163.75), 4278255615); // [1.4, 1.25]
404+
ASSERT_EQ(target.colorAtScratchPoint(-225.5, 164), 4294902015); // [2, 1]
405+
ASSERT_EQ(target.colorAtScratchPoint(-224.5, 164), 4294934656); // [3, 1]
406+
407+
ASSERT_EQ(target.colorAtScratchPoint(-226.5, 163), 4278190208); // [1, 2]
408+
ASSERT_EQ(target.colorAtScratchPoint(-225.5, 163), 0); // [2, 2]
409+
ASSERT_EQ(target.colorAtScratchPoint(-224.5, 163), 2505545047); // [3, 2]
410+
ASSERT_EQ(target.colorAtScratchPoint(-224, 162.9), 9764864); // [3.5, 2.1]
411+
412+
ASSERT_EQ(target.colorAtScratchPoint(-226.5, 162), 4286578816); // [1, 3]
413+
ASSERT_EQ(target.colorAtScratchPoint(-225.5, 162), 4286611711); // [2, 3]
414+
ASSERT_EQ(target.colorAtScratchPoint(-224.5, 162), 4286611456); // [3, 3]
415+
ASSERT_EQ(target.colorAtScratchPoint(-224.2, 161.5), 0); // [3.3, 3.5]
416+
395417
// Cleanup
396418
context.doneCurrent();
397419
}

0 commit comments

Comments
 (0)