diff --git a/eglonxbackend.cpp b/eglonxbackend.cpp
index 5d66f950d0..733a6bc0c3 100644
--- a/eglonxbackend.cpp
+++ b/eglonxbackend.cpp
@@ -376,6 +376,7 @@ bool EglTexture::loadTexture(const Pixmap &pix, const QSize &size, int depth)
checkGLError("load texture");
q->setYInverted(true);
m_size = size;
+ updateMatrix();
return true;
}
diff --git a/glxbackend.cpp b/glxbackend.cpp
index f265e5532e..7bfceeec48 100644
--- a/glxbackend.cpp
+++ b/glxbackend.cpp
@@ -612,6 +612,9 @@ bool GlxTexture::loadTexture(const Pixmap& pix, const QSize& size, int depth)
#ifdef CHECK_GL_ERROR
checkGLError("TextureLoad0");
#endif
+
+ updateMatrix();
+
unbind();
return true;
}
diff --git a/libkwineffects/kwingltexture.cpp b/libkwineffects/kwingltexture.cpp
index a94d835af4..322cfa9766 100644
--- a/libkwineffects/kwingltexture.cpp
+++ b/libkwineffects/kwingltexture.cpp
@@ -92,6 +92,8 @@ GLTexture::GLTexture(int width, int height)
d->m_size = QSize(width, height);
d->m_canUseMipmaps = true;
+ d->updateMatrix();
+
glGenTextures(1, &d->m_texture);
bind();
#ifdef KWIN_HAVE_OPENGLES
@@ -204,6 +206,8 @@ bool GLTexture::load(const QImage& image, GLenum target)
d->m_size = img.size();
d->m_yInverted = true;
+ d->updateMatrix();
+
img = d->convertToGLFormat(img);
if (isNull()) {
@@ -526,6 +530,27 @@ QImage GLTexturePrivate::convertToGLFormat(const QImage& img) const
return res;
}
+void GLTexturePrivate::updateMatrix()
+{
+ m_matrix[NormalizedCoordinates].setToIdentity();
+ m_matrix[UnnormalizedCoordinates].setToIdentity();
+
+#ifndef KWIN_HAVE_OPENGLES
+ if (m_target == GL_TEXTURE_RECTANGLE_ARB)
+ m_matrix[NormalizedCoordinates].scale(m_size.width(), m_size.height());
+ else
+#endif
+ m_matrix[UnnormalizedCoordinates].scale(1.0 / m_size.width(), 1.0 / m_size.height());
+
+ if (!m_yInverted) {
+ m_matrix[NormalizedCoordinates].translate(0.0, 1.0);
+ m_matrix[NormalizedCoordinates].scale(1.0, -1.0);
+
+ m_matrix[UnnormalizedCoordinates].translate(0.0, m_size.height());
+ m_matrix[UnnormalizedCoordinates].scale(1.0, -1.0);
+ }
+}
+
bool GLTexture::isYInverted() const
{
Q_D(const GLTexture);
@@ -536,6 +561,7 @@ void GLTexture::setYInverted(bool inverted)
{
Q_D(GLTexture);
d->m_yInverted = inverted;
+ d->updateMatrix();
}
int GLTexture::width() const
@@ -550,6 +576,12 @@ int GLTexture::height() const
return d->m_size.height();
}
+QMatrix4x4 GLTexture::matrix(TextureCoordinateType type) const
+{
+ Q_D(const GLTexture);
+ return d->m_matrix[type];
+}
+
bool GLTexture::NPOTTextureSupported()
{
return GLTexturePrivate::sNPOTTextureSupported;
diff --git a/libkwineffects/kwingltexture.h b/libkwineffects/kwingltexture.h
index 71b8078775..18e0a80081 100644
--- a/libkwineffects/kwingltexture.h
+++ b/libkwineffects/kwingltexture.h
@@ -28,6 +28,7 @@ along with this program. If not, see .
#include
#include
#include
+#include
class QImage;
class QPixmap;
@@ -41,6 +42,11 @@ namespace KWin
class GLVertexBuffer;
class GLTexturePrivate;
+enum TextureCoordinateType {
+ NormalizedCoordinates = 0,
+ UnnormalizedCoordinates
+};
+
class KWIN_EXPORT GLTexture
{
public:
@@ -67,6 +73,14 @@ public:
**/
void setYInverted(bool inverted);
+ /**
+ * Returns a matrix that transforms texture coordinates of the given type,
+ * taking the texture target and the y-inversion flag into account.
+ *
+ * @since 4.11
+ */
+ QMatrix4x4 matrix(TextureCoordinateType type) const;
+
virtual bool load(const QImage& image, GLenum target = GL_TEXTURE_2D);
virtual bool load(const QPixmap& pixmap, GLenum target = GL_TEXTURE_2D);
virtual bool load(const QString& fileName);
diff --git a/libkwineffects/kwingltexture_p.h b/libkwineffects/kwingltexture_p.h
index e3916ef553..2afc9aa7a4 100644
--- a/libkwineffects/kwingltexture_p.h
+++ b/libkwineffects/kwingltexture_p.h
@@ -48,13 +48,16 @@ public:
QImage convertToGLFormat(const QImage& img) const;
+ void updateMatrix();
+
GLuint m_texture;
GLenum m_target;
GLenum m_filter;
GLenum m_wrapMode;
QSize m_size;
QSizeF m_scale; // to un-normalize GL_TEXTURE_2D
- bool m_yInverted; // texture has y inverted
+ QMatrix4x4 m_matrix[2];
+ bool m_yInverted; // texture is y-inverted
bool m_canUseMipmaps;
bool m_markedDirty;
bool m_filterChanged;