QOpenGLTextureBlitter: Remove Origin location for the Target rect

The Origin for Target rect was deemed a confusing concept. The current
implementation would translate the target rect to the coordinate system
specified. However, the order and "direction" of the vertices would
always be the same. So drawing a texture in for one target rect defined in
one coordinate system would paint the texture the same way as it would
when a texture was drawn for a target rect drawn in the "opposite"
coordinate system. The point with this was that if you wanted to "flip"
the texture you would specify that with the source coordinate system.

However, this approach breaks on different levels, such as QRect has functions
which expects a top left coordinate system (ie. top() and bottom()).

In the end Qt uses a top left coordinate system, hence QWindow specifies
a top left coordinate system, and hence the api becomes easier if it is
not possible to define the coordinate system of the target viewport.

Change-Id: I7dd59b3718380876e87a4bff88381d7a1c7d58c1
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
This commit is contained in:
Jørgen Lind 2014-02-13 22:03:52 +01:00 committed by The Qt Project
parent 6fbef080a0
commit 937a4f5443
6 changed files with 57 additions and 47 deletions

View File

@ -344,25 +344,23 @@ void QOpenGLTextureBlitter::blit(GLuint texture,
}
QMatrix4x4 QOpenGLTextureBlitter::targetTransform(const QRectF &target,
const QRect &viewport,
Origin origin)
const QRect &viewport)
{
qreal x_scale = target.size().width() / viewport.width();
qreal y_scale = target.size().height() / viewport.height();
qreal x_scale = target.width() / viewport.width();
qreal y_scale = target.height() / viewport.height();
const QPointF relative_to_viewport = target.topLeft() - viewport.topLeft();
qreal x_translate = ((relative_to_viewport.x() / viewport.width()) + (x_scale / 2)) * 2 - 1;
qreal y_translate = ((relative_to_viewport.y() / viewport.height()) + (y_scale / 2)) * 2 - 1;
qreal x_translate = x_scale - 1 + ((relative_to_viewport.x() / viewport.width()) * 2);
qreal y_translate = -y_scale + 1 - ((relative_to_viewport.y() / viewport.height()) * 2);
if (origin == OriginTopLeft) {
y_translate = -y_translate;
}
QMatrix4x4 matrix;
matrix(0,3) = x_translate;
matrix(1,3) = y_translate;
QMatrix4x4 vertexMatrix;
matrix(0,0) = x_scale;
matrix(1,1) = y_scale;
vertexMatrix.translate(x_translate, y_translate);
vertexMatrix.scale(x_scale, y_scale);
return vertexMatrix;
return matrix;
}
QMatrix3x3 QOpenGLTextureBlitter::sourceTransform(const QRectF &subTexture,

View File

@ -72,7 +72,7 @@ public:
void blit(GLuint texture, const QMatrix4x4 &targetTransform, Origin sourceOrigin);
void blit(GLuint texture, const QMatrix4x4 &targetTransform, const QMatrix3x3 &sourceTransform);
static QMatrix4x4 targetTransform(const QRectF &target, const QRect &viewport, Origin origin);
static QMatrix4x4 targetTransform(const QRectF &target, const QRect &viewport);
static QMatrix3x3 sourceTransform(const QRectF &subTexture, const QSize &textureSize, Origin origin);
private:

View File

@ -218,8 +218,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
GLuint textureId = textures->textureId(i);
glBindTexture(GL_TEXTURE_2D, textureId);
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), windowRect,
QOpenGLTextureBlitter::OriginTopLeft);
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), windowRect);
d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
}
@ -230,8 +229,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect,
QOpenGLTextureBlitter::OriginTopLeft);
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);
d_ptr->blitter->setSwizzleRB(true);
d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
d_ptr->blitter->setSwizzleRB(false);

View File

@ -118,8 +118,7 @@ void QEGLCompositor::render(QEGLPlatformWindow *window)
uint textureId = textures->textureId(i);
glBindTexture(GL_TEXTURE_2D, textureId);
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i),
targetWindowRect,
QOpenGLTextureBlitter::OriginTopLeft);
targetWindowRect);
m_blitter->setSwizzleRB(window->isRaster());
if (textures->count() > 1 && i == textures->count() - 1) {

View File

@ -83,44 +83,57 @@ void QOpenGLTextureBlitWindow::render()
QOpenGLTexture texture(m_image);
texture.create();
QRectF topLeft(QPointF(0,0), QPointF(dWidth()/2.0, dHeight()/2.0));
QRectF topRight(QPointF(dWidth()/2.0,0), QPointF(dWidth(), dHeight()/2.0));
QRectF bottomLeft(QPointF(0, dHeight()/2.0), QPointF(dWidth() /2.0, dHeight()));
QRectF bottomRight(QPoint(dWidth()/2.0, dHeight()/2.0), QPointF(dWidth(), dHeight()));
QOpenGLTexture texture_mirrored(m_image_mirrord);
texture_mirrored.setWrapMode(QOpenGLTexture::ClampToEdge);
texture_mirrored.create();
QRectF topLeftOriginTopLeft(QPointF(0,0), QPointF(dWidth()/2.0, dHeight()/2.0));
QRectF topRightOriginTopLeft(QPointF(dWidth()/2.0,0), QPointF(dWidth(), dHeight()/2.0));
QRectF bottomLeftOriginTopLeft(QPointF(0, dHeight()/2.0), QPointF(dWidth() /2.0, dHeight()));
QRectF bottomRightOriginTopLeft(QPoint(dWidth()/2.0, dHeight()/2.0), QPointF(dWidth(), dHeight()));
QRectF topLeftOriginBottomLeft = bottomLeftOriginTopLeft; Q_UNUSED(topLeftOriginBottomLeft);
QRectF topRightOriginBottomLeft = bottomRightOriginTopLeft; Q_UNUSED(topRightOriginBottomLeft);
QRectF bottomLeftOriginBottomLeft = topLeftOriginTopLeft;
QRectF bottomRightOriginBottomLeft = topRightOriginTopLeft;
QOpenGLTextureBlitter::Origin topLeftOrigin = QOpenGLTextureBlitter::OriginTopLeft;
QOpenGLTextureBlitter::Origin bottomLeftOrigin = QOpenGLTextureBlitter::OriginBottomLeft;
QMatrix4x4 topRightVertexFlipped = QOpenGLTextureBlitter::targetTransform(topRight, viewport, topLeftOrigin);
QMatrix4x4 bottomLeftVertex = QOpenGLTextureBlitter::targetTransform(bottomLeft, viewport, topLeftOrigin);
QMatrix4x4 bottomRightVertexFlipped = QOpenGLTextureBlitter::targetTransform(bottomRight, viewport, topLeftOrigin);
QMatrix3x3 texTopLeft = QOpenGLTextureBlitter::sourceTransform(topLeft, m_image.size(), topLeftOrigin);
QMatrix3x3 texTopRight = QOpenGLTextureBlitter::sourceTransform(topRight, m_image.size(), topLeftOrigin);
QMatrix3x3 texBottomLeft = QOpenGLTextureBlitter::sourceTransform(bottomLeft, m_image.size(), topLeftOrigin);
QMatrix3x3 texBottomRight = QOpenGLTextureBlitter::sourceTransform(bottomRight, m_image.size(), bottomLeftOrigin);
QMatrix4x4 topRightOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(topRightOriginTopLeft, viewport);
QMatrix4x4 bottomLeftOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(bottomLeftOriginTopLeft, viewport);
QMatrix4x4 bottomRightOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(bottomRightOriginTopLeft, viewport);
QSizeF subSize(topLeft.width()/2, topLeft.height()/2);
QRectF subTopLeft(topLeft.topLeft(), subSize);
QRectF subTopRight(QPointF(topLeft.topLeft().x() + topLeft.width() / 2, topLeft.topLeft().y()),subSize);
QRectF subBottomLeft(QPointF(topLeft.topLeft().x(), topLeft.topLeft().y() + topLeft.height() / 2), subSize);
QRectF subBottomRight(QPointF(topLeft.topLeft().x() + topLeft.width() / 2, topLeft.topLeft().y() + topLeft.height() / 2), subSize);
QMatrix3x3 texTopLeftOriginTopLeft = QOpenGLTextureBlitter::sourceTransform(topLeftOriginTopLeft, m_image.size(), topLeftOrigin);
QMatrix3x3 texTopRightOriginBottomLeft = QOpenGLTextureBlitter::sourceTransform(topRightOriginBottomLeft, m_image.size(), bottomLeftOrigin);
QMatrix3x3 texBottomLeftOriginBottomLeft = QOpenGLTextureBlitter::sourceTransform(bottomLeftOriginBottomLeft, m_image.size(), bottomLeftOrigin);
QMatrix3x3 texBottomRightOriginBottomLeft = QOpenGLTextureBlitter::sourceTransform(bottomRightOriginBottomLeft, m_image.size(), bottomLeftOrigin);
QMatrix4x4 subTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subTopLeft, viewport, topLeftOrigin);
QMatrix4x4 subTopRightVertex = QOpenGLTextureBlitter::targetTransform(subTopRight, viewport, topLeftOrigin);
QMatrix4x4 subBottomLeftVertex = QOpenGLTextureBlitter::targetTransform(subBottomLeft, viewport, topLeftOrigin);
QMatrix4x4 subBottomRightVertex = QOpenGLTextureBlitter::targetTransform(subBottomRight, viewport, topLeftOrigin);
QSizeF subSize(topLeftOriginTopLeft.width()/2, topLeftOriginTopLeft.height()/2);
QRectF subTopLeftOriginTopLeft(topLeftOriginTopLeft.topLeft(), subSize);
QRectF subTopRightOriginTopLeft(QPointF(topLeftOriginTopLeft.topLeft().x() + topLeftOriginTopLeft.width() / 2,
topLeftOriginTopLeft.topLeft().y()), subSize);
QRectF subBottomLeftOriginTopLeft(QPointF(topLeftOriginTopLeft.topLeft().x(),
topLeftOriginTopLeft.topLeft().y() + topLeftOriginTopLeft.height() / 2), subSize);
QRectF subBottomRightOriginTopLeft(QPointF(topLeftOriginTopLeft.topLeft().x() + topLeftOriginTopLeft.width() / 2,
topLeftOriginTopLeft.topLeft().y() + topLeftOriginTopLeft.height() / 2), subSize);
QMatrix4x4 subTopLeftOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subTopLeftOriginTopLeft, viewport);
QMatrix4x4 subTopRightOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subTopRightOriginTopLeft, viewport);
QMatrix4x4 subBottomLeftOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subBottomLeftOriginTopLeft, viewport);
QMatrix4x4 subBottomRightOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subBottomRightOriginTopLeft, viewport);
m_blitter.bind();
m_blitter.blit(texture.textureId(), subTopLeftVertex, texBottomRight);
m_blitter.blit(texture.textureId(), subTopRightVertex, texBottomLeft);
m_blitter.blit(texture.textureId(), subBottomLeftVertex, texTopRight);
m_blitter.blit(texture.textureId(), subBottomRightVertex, texTopLeft);
m_blitter.blit(texture_mirrored.textureId(), subTopLeftOriginTopLeftVertex, texBottomRightOriginBottomLeft);
m_blitter.blit(texture_mirrored.textureId(), subTopRightOriginTopLeftVertex, texBottomLeftOriginBottomLeft);
m_blitter.blit(texture.textureId(), subBottomLeftOriginTopLeftVertex, texTopRightOriginBottomLeft);
m_blitter.blit(texture.textureId(), subBottomRightOriginTopLeftVertex, texTopLeftOriginTopLeft);
m_blitter.blit(texture.textureId(), topRightVertexFlipped, topLeftOrigin);
m_blitter.blit(texture.textureId(), bottomLeftVertex, bottomLeftOrigin);
m_blitter.blit(texture.textureId(), topRightOriginTopLeftVertex, topLeftOrigin);
m_blitter.blit(texture_mirrored.textureId(), bottomLeftOriginTopLeftVertex, topLeftOrigin);
m_blitter.setSwizzleRB(true);
m_blitter.blit(texture.textureId(), bottomRightVertexFlipped, texTopLeft);
m_blitter.blit(texture.textureId(), bottomRightOriginTopLeftVertex, texTopLeftOriginTopLeft);
m_blitter.setSwizzleRB(false);
m_blitter.release();
@ -163,5 +176,6 @@ void QOpenGLTextureBlitWindow::resizeEvent(QResizeEvent *event)
p.drawRect(QRectF(2.5,2.5,dWidth() - 5, dHeight() - 5));
m_image_mirrord = m_image.mirrored(false,true);
}

View File

@ -64,6 +64,7 @@ private:
QScopedPointer<QOpenGLContext> m_context;
QOpenGLTextureBlitter m_blitter;
QImage m_image;
QImage m_image_mirrord;
};
#endif