Skip to content

Commit f3c4918

Browse files
committed
RenderedTarget: Cache matrices
1 parent db08870 commit f3c4918

File tree

2 files changed

+50
-47
lines changed

2 files changed

+50
-47
lines changed

src/renderedtarget.cpp

Lines changed: 43 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,9 @@ void RenderedTarget::render(double scale) const
521521
m_glF->initializeOpenGLFunctions();
522522
}
523523

524+
if (!m_cpuTexture.isValid())
525+
return;
526+
524527
const float stageWidth = m_engine->stageWidth() * scale;
525528
const float stageHeight = m_engine->stageHeight() * scale;
526529

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

533-
float angle = 180;
534-
float scaleX = 1;
535-
float scaleY = 1;
536-
537-
if (m_spriteModel) {
538-
libscratchcpp::Sprite *sprite = m_spriteModel->sprite();
539-
540-
switch (sprite->rotationStyle()) {
541-
case libscratchcpp::Sprite::RotationStyle::AllAround:
542-
angle = 270 - sprite->direction();
543-
break;
544-
545-
case libscratchcpp::Sprite::RotationStyle::LeftRight:
546-
scaleX = sgn(sprite->direction());
547-
break;
548-
549-
default:
550-
break;
551-
}
552-
553-
scaleY = sprite->size() / 100;
554-
scaleX *= scaleY;
555-
}
556-
557-
scaleX *= scale;
558-
scaleY *= scale;
559-
560-
const Texture &texture = cpuTexture();
561-
562-
if (!texture.isValid())
563-
return;
564-
565-
const float textureScale = texture.width() / static_cast<float>(costumeWidth());
566-
const float skinWidth = texture.width();
567-
const float skinHeight = texture.height();
568-
569-
QMatrix4x4 projectionMatrix;
570-
const float aspectRatio = skinHeight / skinWidth;
571-
projectionMatrix.ortho(1.0f, -1.0f, aspectRatio, -aspectRatio, 0.1f, 0.0f);
572-
projectionMatrix.scale(skinWidth / bounds.width() / scale, skinHeight / bounds.height() / scale);
573-
574-
QMatrix4x4 modelMatrix;
575-
modelMatrix.rotate(angle, 0, 0, 1);
576-
modelMatrix.scale(scaleX / textureScale, aspectRatio * scaleY / textureScale);
536+
QMatrix4x4 modelMatrix, projectionMatrix;
537+
getMatrices(modelMatrix, projectionMatrix);
538+
modelMatrix.scale(scale);
539+
projectionMatrix.scale(1.0f / scale);
577540

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

588551
shaderProgram->bind();
589552
m_glF->glActiveTexture(GL_TEXTURE0);
590-
m_glF->glBindTexture(GL_TEXTURE_2D, texture.handle());
591-
shaderManager->setUniforms(shaderProgram, 0, texture.size(), m_graphicEffects);
553+
m_glF->glBindTexture(GL_TEXTURE_2D, m_cpuTexture.handle());
554+
shaderManager->setUniforms(shaderProgram, 0, m_cpuTexture.size(), m_graphicEffects);
592555
shaderProgram->setUniformValue("u_projectionMatrix", projectionMatrix);
593556
shaderProgram->setUniformValue("u_modelMatrix", modelMatrix);
594557
m_glF->glDrawArrays(GL_TRIANGLES, 0, 6);
@@ -788,16 +751,19 @@ void RenderedTarget::calculatePos()
788751
setTransformOrigin(QQuickItem::Center);
789752

790753
m_transformedHullDirty = true;
754+
m_matricesDirty = true;
791755
}
792756

793757
void RenderedTarget::calculateRotation()
794758
{
795759
// Direction
796760
bool oldMirrorHorizontally = m_mirrorHorizontally;
761+
m_renderAngle = 180.0f;
797762

798763
switch (m_rotationStyle) {
799764
case Sprite::RotationStyle::AllAround:
800765
setRotation(m_direction - 90);
766+
m_renderAngle = 270.0f - m_direction;
801767
m_mirrorHorizontally = (false);
802768

803769
break;
@@ -819,6 +785,7 @@ void RenderedTarget::calculateRotation()
819785
emit mirrorHorizontallyChanged();
820786

821787
m_transformedHullDirty = true;
788+
m_matricesDirty = true;
822789
}
823790

824791
void RenderedTarget::calculateSize()
@@ -836,6 +803,7 @@ void RenderedTarget::calculateSize()
836803
m_convexHullDirty = true;
837804

838805
m_transformedHullDirty = true;
806+
m_matricesDirty = true;
839807
}
840808
}
841809

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

1175+
void RenderedTarget::getMatrices(QMatrix4x4 &modelMatrix, QMatrix4x4 &projectionMatrix) const
1176+
{
1177+
if (m_matricesDirty) {
1178+
float scaleY = m_size;
1179+
float scaleX = scaleY * (m_mirrorHorizontally * (-2) + 1);
1180+
1181+
float width = m_cpuTexture.width();
1182+
float height = m_cpuTexture.height();
1183+
const float textureScale = width / static_cast<float>(costumeWidth());
1184+
const float aspectRatio = height / width;
1185+
1186+
libscratchcpp::Rect bounds = getFastBounds();
1187+
bounds.snapToInt();
1188+
1189+
m_projectionMatrix = QMatrix4x4();
1190+
m_projectionMatrix.ortho(1.0f, -1.0f, aspectRatio, -aspectRatio, 0.1f, 0.0f);
1191+
m_projectionMatrix.scale(width / bounds.width(), height / bounds.height());
1192+
1193+
m_modelMatrix = QMatrix4x4();
1194+
m_modelMatrix.rotate(m_renderAngle, 0, 0, 1);
1195+
m_modelMatrix.scale(scaleX / textureScale, aspectRatio * scaleY / textureScale);
1196+
1197+
m_matricesDirty = false;
1198+
}
1199+
1200+
modelMatrix = m_modelMatrix;
1201+
projectionMatrix = m_projectionMatrix;
1202+
}
1203+
12071204
bool RenderedTarget::mirrorHorizontally() const
12081205
{
12091206
return m_mirrorHorizontally;

src/renderedtarget.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ class RenderedTarget : public IRenderedTarget
145145
static bool maskMatches(QRgb a, QRgb b);
146146
QRgb sampleColor3b(double x, double y, const std::vector<IRenderedTarget *> &targets) const;
147147

148+
void getMatrices(QMatrix4x4 &modelMatrix, QMatrix4x4 &projectionMatrix) const;
149+
148150
libscratchcpp::IEngine *m_engine = nullptr;
149151
libscratchcpp::Costume *m_costume = nullptr;
150152
StageModel *m_stageModel = nullptr;
@@ -168,6 +170,7 @@ class RenderedTarget : public IRenderedTarget
168170
double m_width = 1;
169171
double m_height = 1;
170172
double m_direction = 90;
173+
float m_renderAngle = 180.0f;
171174
libscratchcpp::Sprite::RotationStyle m_rotationStyle = libscratchcpp::Sprite::RotationStyle::AllAround;
172175
bool m_mirrorHorizontally = false;
173176
double m_stageScale = 1;
@@ -177,7 +180,10 @@ class RenderedTarget : public IRenderedTarget
177180
std::vector<QPoint> m_hullPoints;
178181
mutable bool m_transformedHullDirty = true;
179182
mutable std::vector<QPointF> m_transformedHullPoints; // NOTE: Use transformedHullPoints();
180-
bool m_clicked = false; // left mouse button only!
183+
mutable bool m_matricesDirty = false;
184+
mutable QMatrix4x4 m_modelMatrix; // NOTE: Use getMatrices()!
185+
mutable QMatrix4x4 m_projectionMatrix; // NOTE: Use getMatrices()!
186+
bool m_clicked = false; // left mouse button only!
181187
double m_dragX = 0;
182188
double m_dragY = 0;
183189
double m_dragDeltaX = 0;

0 commit comments

Comments
 (0)