Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9f3d979
Prepare code for pen blocks
adazem009 Mar 21, 2026
8a09468
Switch to shared library
adazem009 Mar 21, 2026
98b0ead
Implement pen_clear block
adazem009 Mar 21, 2026
52855ea
Implement pen_stamp block
adazem009 Mar 21, 2026
fcb8cf6
Implement pen_penDown block
adazem009 Mar 21, 2026
c0f7013
Implement pen_penUp block
adazem009 Mar 21, 2026
d6def8f
Fix pen blocks extension name
adazem009 Mar 21, 2026
887823d
Fix precision issues in ShaderManager test suite
adazem009 Mar 22, 2026
77b4d1c
Refactor pen frame state management
adazem009 Mar 22, 2026
381b4c8
PenLayer: Remove unused variables
adazem009 Mar 22, 2026
8e8abc1
PenLayer: Drop stamp FBO
adazem009 Mar 22, 2026
db08870
Move stamp rendering to RenderedTarget
adazem009 Mar 22, 2026
f3c4918
RenderedTarget: Cache matrices
adazem009 Mar 22, 2026
ab64766
ShaderManager: Make setUniforms() static
adazem009 Mar 22, 2026
9c8640d
RenderedTarget: Cache shader program
adazem009 Mar 22, 2026
2f627e6
Implement pen_setPenColorToColor block
adazem009 Mar 27, 2026
3919ddc
Optimize color constants in set pen color block
adazem009 Mar 27, 2026
7baf07a
Implement pen_changePenColorParamBy block
adazem009 Mar 28, 2026
9da34e4
Optimize constant param names in change color param block
adazem009 Mar 28, 2026
ed691ee
Implement pen_setPenColorParamTo block
adazem009 Mar 28, 2026
544f4d3
Add missing pen block stage test cases
adazem009 Mar 28, 2026
7efdd13
Implement pen_changePenSizeBy block
adazem009 Mar 28, 2026
d153557
Implement pen_setPenSizeTo block
adazem009 Mar 28, 2026
e7b3ea7
Implement pen_changePenShadeBy block
adazem009 Mar 28, 2026
2773b4b
Implement pen_setPenShadeToNumber block
adazem009 Mar 28, 2026
0087806
Implement pen_changePenHueBy block
adazem009 Mar 28, 2026
a005131
Implement pen_setPenHueToNumber block
adazem009 Mar 28, 2026
3ea17ae
ProjectLoader: Add missing pen layer null check
adazem009 Mar 28, 2026
fb92ade
PenLayer: Make sure FBO is bound when clearing in setEngine()
adazem009 Mar 28, 2026
db269be
Add missing include guard to pen blocks
adazem009 Mar 28, 2026
b27b72c
Refactor shader program cache
adazem009 Mar 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
RenderedTarget: Cache matrices
  • Loading branch information
adazem009 committed Mar 22, 2026
commit f3c4918c4f53135b724b1419d2bdd333ab8b20c2
89 changes: 43 additions & 46 deletions src/renderedtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,9 @@ void RenderedTarget::render(double scale) const
m_glF->initializeOpenGLFunctions();
}

if (!m_cpuTexture.isValid())
return;

const float stageWidth = m_engine->stageWidth() * scale;
const float stageHeight = m_engine->stageHeight() * scale;

Expand All @@ -530,50 +533,10 @@ void RenderedTarget::render(double scale) const
if (!bounds.intersects(libscratchcpp::Rect(-stageWidth / 2, stageHeight / 2, stageWidth / 2, -stageHeight / 2)))
return;

float angle = 180;
float scaleX = 1;
float scaleY = 1;

if (m_spriteModel) {
libscratchcpp::Sprite *sprite = m_spriteModel->sprite();

switch (sprite->rotationStyle()) {
case libscratchcpp::Sprite::RotationStyle::AllAround:
angle = 270 - sprite->direction();
break;

case libscratchcpp::Sprite::RotationStyle::LeftRight:
scaleX = sgn(sprite->direction());
break;

default:
break;
}

scaleY = sprite->size() / 100;
scaleX *= scaleY;
}

scaleX *= scale;
scaleY *= scale;

const Texture &texture = cpuTexture();

if (!texture.isValid())
return;

const float textureScale = texture.width() / static_cast<float>(costumeWidth());
const float skinWidth = texture.width();
const float skinHeight = texture.height();

QMatrix4x4 projectionMatrix;
const float aspectRatio = skinHeight / skinWidth;
projectionMatrix.ortho(1.0f, -1.0f, aspectRatio, -aspectRatio, 0.1f, 0.0f);
projectionMatrix.scale(skinWidth / bounds.width() / scale, skinHeight / bounds.height() / scale);

QMatrix4x4 modelMatrix;
modelMatrix.rotate(angle, 0, 0, 1);
modelMatrix.scale(scaleX / textureScale, aspectRatio * scaleY / textureScale);
QMatrix4x4 modelMatrix, projectionMatrix;
getMatrices(modelMatrix, projectionMatrix);
modelMatrix.scale(scale);
projectionMatrix.scale(1.0f / scale);

m_glF->glEnable(GL_BLEND);
m_glF->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Expand All @@ -587,8 +550,8 @@ void RenderedTarget::render(double scale) const

shaderProgram->bind();
m_glF->glActiveTexture(GL_TEXTURE0);
m_glF->glBindTexture(GL_TEXTURE_2D, texture.handle());
shaderManager->setUniforms(shaderProgram, 0, texture.size(), m_graphicEffects);
m_glF->glBindTexture(GL_TEXTURE_2D, m_cpuTexture.handle());
shaderManager->setUniforms(shaderProgram, 0, m_cpuTexture.size(), m_graphicEffects);
shaderProgram->setUniformValue("u_projectionMatrix", projectionMatrix);
shaderProgram->setUniformValue("u_modelMatrix", modelMatrix);
m_glF->glDrawArrays(GL_TRIANGLES, 0, 6);
Expand Down Expand Up @@ -788,16 +751,19 @@ void RenderedTarget::calculatePos()
setTransformOrigin(QQuickItem::Center);

m_transformedHullDirty = true;
m_matricesDirty = true;
}

void RenderedTarget::calculateRotation()
{
// Direction
bool oldMirrorHorizontally = m_mirrorHorizontally;
m_renderAngle = 180.0f;

switch (m_rotationStyle) {
case Sprite::RotationStyle::AllAround:
setRotation(m_direction - 90);
m_renderAngle = 270.0f - m_direction;
m_mirrorHorizontally = (false);

break;
Expand All @@ -819,6 +785,7 @@ void RenderedTarget::calculateRotation()
emit mirrorHorizontallyChanged();

m_transformedHullDirty = true;
m_matricesDirty = true;
}

void RenderedTarget::calculateSize()
Expand All @@ -836,6 +803,7 @@ void RenderedTarget::calculateSize()
m_convexHullDirty = true;

m_transformedHullDirty = true;
m_matricesDirty = true;
}
}

Expand Down Expand Up @@ -1204,6 +1172,35 @@ QRgb RenderedTarget::sampleColor3b(double x, double y, const std::vector<IRender
return qRgb(r, g, b);
}

void RenderedTarget::getMatrices(QMatrix4x4 &modelMatrix, QMatrix4x4 &projectionMatrix) const
{
if (m_matricesDirty) {
float scaleY = m_size;
float scaleX = scaleY * (m_mirrorHorizontally * (-2) + 1);

float width = m_cpuTexture.width();
float height = m_cpuTexture.height();
const float textureScale = width / static_cast<float>(costumeWidth());
const float aspectRatio = height / width;

libscratchcpp::Rect bounds = getFastBounds();
bounds.snapToInt();

m_projectionMatrix = QMatrix4x4();
m_projectionMatrix.ortho(1.0f, -1.0f, aspectRatio, -aspectRatio, 0.1f, 0.0f);
m_projectionMatrix.scale(width / bounds.width(), height / bounds.height());

m_modelMatrix = QMatrix4x4();
m_modelMatrix.rotate(m_renderAngle, 0, 0, 1);
m_modelMatrix.scale(scaleX / textureScale, aspectRatio * scaleY / textureScale);

m_matricesDirty = false;
}

modelMatrix = m_modelMatrix;
projectionMatrix = m_projectionMatrix;
}

bool RenderedTarget::mirrorHorizontally() const
{
return m_mirrorHorizontally;
Expand Down
8 changes: 7 additions & 1 deletion src/renderedtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ class RenderedTarget : public IRenderedTarget
static bool maskMatches(QRgb a, QRgb b);
QRgb sampleColor3b(double x, double y, const std::vector<IRenderedTarget *> &targets) const;

void getMatrices(QMatrix4x4 &modelMatrix, QMatrix4x4 &projectionMatrix) const;

libscratchcpp::IEngine *m_engine = nullptr;
libscratchcpp::Costume *m_costume = nullptr;
StageModel *m_stageModel = nullptr;
Expand All @@ -168,6 +170,7 @@ class RenderedTarget : public IRenderedTarget
double m_width = 1;
double m_height = 1;
double m_direction = 90;
float m_renderAngle = 180.0f;
libscratchcpp::Sprite::RotationStyle m_rotationStyle = libscratchcpp::Sprite::RotationStyle::AllAround;
bool m_mirrorHorizontally = false;
double m_stageScale = 1;
Expand All @@ -177,7 +180,10 @@ class RenderedTarget : public IRenderedTarget
std::vector<QPoint> m_hullPoints;
mutable bool m_transformedHullDirty = true;
mutable std::vector<QPointF> m_transformedHullPoints; // NOTE: Use transformedHullPoints();
bool m_clicked = false; // left mouse button only!
mutable bool m_matricesDirty = false;
mutable QMatrix4x4 m_modelMatrix; // NOTE: Use getMatrices()!
mutable QMatrix4x4 m_projectionMatrix; // NOTE: Use getMatrices()!
bool m_clicked = false; // left mouse button only!
double m_dragX = 0;
double m_dragY = 0;
double m_dragDeltaX = 0;
Expand Down
Loading