effects: Honor transforms in OffscreenEffect

This ensures that transforms are honored with effects such as wobbly
windows.
This commit is contained in:
Vlad Zahorodnii 2022-07-29 11:08:59 +00:00 committed by Marco Martin
parent 15fbddc3d6
commit 40044f21e1
4 changed files with 28 additions and 29 deletions

View file

@ -204,6 +204,26 @@ void PaintData::setRotationOrigin(const QVector3D &origin)
d->rotationOrigin = origin;
}
QMatrix4x4 PaintData::toMatrix() const
{
QMatrix4x4 ret;
if (d->translation != QVector3D(0, 0, 0)) {
ret.translate(d->translation);
}
if (d->scale != QVector3D(1, 1, 1)) {
ret.scale(d->scale);
}
if (d->rotationAngle != 0) {
ret.translate(d->rotationOrigin);
const QVector3D axis = d->rotationAxis;
ret.rotate(d->rotationAngle, axis.x(), axis.y(), axis.z());
ret.translate(-d->rotationOrigin);
}
return ret;
}
class WindowPaintDataPrivate
{
public:

View file

@ -3092,6 +3092,11 @@ public:
*/
QVector3D rotationAxis() const;
/**
* Returns the corresponding transform matrix.
*/
QMatrix4x4 toMatrix() const;
protected:
PaintData();
PaintData(const PaintData &other);

View file

@ -160,7 +160,8 @@ void OffscreenEffectPrivate::paint(EffectWindow *window, GLTexture *texture, con
QMatrix4x4 mvp = data.screenProjectionMatrix();
mvp.translate(window->x(), window->y());
shader->setUniform(GLShader::ModelViewProjectionMatrix, mvp);
shader->setUniform(GLShader::ModelViewProjectionMatrix, mvp * data.toMatrix());
shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
shader->setUniform(GLShader::Saturation, data.saturation());
shader->setUniform(GLShader::TextureWidth, texture->width());

View file

@ -409,33 +409,6 @@ QMatrix4x4 SceneOpenGL::modelViewProjectionMatrix(const WindowPaintData &data) c
}
}
static QMatrix4x4 transformForPaintData(int mask, const WindowPaintData &data)
{
// TODO: Switch to QTransform.
QMatrix4x4 matrix;
if (!(mask & Scene::PAINT_WINDOW_TRANSFORMED)) {
return matrix;
}
matrix.translate(data.translation());
const QVector3D scale = data.scale();
matrix.scale(scale.x(), scale.y(), scale.z());
if (data.rotationAngle() == 0.0) {
return matrix;
}
// Apply the rotation
// cannot use data.rotation.applyTo(&matrix) as QGraphicsRotation uses projectedRotate to map back to 2D
matrix.translate(data.rotationOrigin());
const QVector3D axis = data.rotationAxis();
matrix.rotate(data.rotationAngle(), axis.x(), axis.y(), axis.z());
matrix.translate(-data.rotationOrigin());
return matrix;
}
void SceneOpenGL::render(Item *item, int mask, const QRegion &region, const WindowPaintData &data)
{
if (region.isEmpty()) {
@ -450,7 +423,7 @@ void SceneOpenGL::render(Item *item, int mask, const QRegion &region, const Wind
renderContext.transformStack.push(QMatrix4x4());
renderContext.opacityStack.push(data.opacity());
item->setTransform(transformForPaintData(mask, data));
item->setTransform(data.toMatrix());
createRenderNode(item, &renderContext);