summaryrefslogtreecommitdiffstats
path: root/src/gui/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/opengl')
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp36
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp28
-rw-r--r--src/gui/opengl/qopenglpaintengine_p.h2
-rw-r--r--src/gui/opengl/qopengltexture.cpp4
-rw-r--r--src/gui/opengl/qopengltexture.h4
5 files changed, 56 insertions, 18 deletions
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index cbc992b7e8..6351b8a1e3 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -469,6 +469,8 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
funcs.glGenFramebuffers(1, &fbo);
funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true;
+
GLuint color_buffer = 0;
QT_CHECK_GLERROR();
@@ -995,7 +997,11 @@ bool QOpenGLFramebufferObject::bind()
if (current->shareGroup() != d->fbo_guard->group())
qWarning("QOpenGLFramebufferObject::bind() called from incompatible context");
#endif
+
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
+
+ QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true;
+
if (d->texture_guard || d->format.samples() != 0)
d->valid = d->checkFramebufferStatus(current);
else
@@ -1027,9 +1033,12 @@ bool QOpenGLFramebufferObject::release()
qWarning("QOpenGLFramebufferObject::release() called from incompatible context");
#endif
- if (current)
+ if (current) {
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->defaultFramebufferObject());
+ QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true;
+ }
+
return true;
}
@@ -1192,9 +1201,23 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
If used together with QOpenGLPaintDevice, \a flipped should be the opposite of the value
of QOpenGLPaintDevice::paintFlipped().
- Will try to return a premultiplied ARBG32 or RGB32 image. Since 5.2 it will fall back to
- a premultiplied RGBA8888 or RGBx8888 image when reading to ARGB32 is not supported. Since 5.4 an
- A2BGR30 image is returned if the internal format is RGB10_A2.
+ The returned image has a format of premultiplied ARGB32 or RGB32. The latter is used
+ only when internalTextureFormat() is set to \c GL_RGB.
+
+ If the rendering in the framebuffer was not done with premultiplied alpha in mind,
+ create a wrapper QImage with a non-premultiplied format. This is necessary before
+ performing operations like QImage::save() because otherwise the image data would get
+ unpremultiplied, even though it was not premultiplied in the first place. To create
+ such a wrapper without performing a copy of the pixel data, do the following:
+
+ \code
+ QImage fboImage(fbo.toImage());
+ QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_ARGB32);
+ \endcode
+
+ Since Qt 5.2 the function will fall back to premultiplied RGBA8888 or RGBx8888 when
+ reading to (A)RGB32 is not supported. Since 5.4 an A2BGR30 image is returned if the
+ internal format is RGB10_A2.
For multisampled framebuffer objects the samples are resolved using the
\c{GL_EXT_framebuffer_blit} extension. If the extension is not available, the contents
@@ -1270,8 +1293,10 @@ bool QOpenGLFramebufferObject::bindDefault()
{
QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
- if (ctx)
+ if (ctx) {
ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
+ QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true;
+ }
#ifdef QT_DEBUG
else
qWarning("QOpenGLFramebufferObject::bindDefault() called without current context.");
@@ -1340,6 +1365,7 @@ void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachmen
qWarning("QOpenGLFramebufferObject::setAttachment() called from incompatible context");
#endif
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
+ QOpenGLContextPrivate::get(current)->qgl_current_fbo_invalid = true;
d->initAttachments(current, attachment);
}
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index c490726359..b18d2cc42a 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -107,7 +107,7 @@ QOpenGL2PaintEngineExPrivate::~QOpenGL2PaintEngineExPrivate()
}
}
-void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
+void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
{
// funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit?
if (id != GLuint(-1) && id == lastTextureUsed)
@@ -115,6 +115,8 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra
lastTextureUsed = id;
+ static const GLenum target = GL_TEXTURE_2D;
+
if (smoothPixmapTransform) {
funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -122,6 +124,7 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra
funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
+
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode);
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode);
}
@@ -185,7 +188,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, texImage);
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ updateTextureFilter(GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
// Gradiant brush: All the gradiants use the same texture
@@ -199,12 +202,13 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
funcs.glBindTexture(GL_TEXTURE_2D, texId);
+ GLenum wrapMode = GL_CLAMP_TO_EDGE;
if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient)
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ wrapMode = GL_REPEAT;
else if (g->spread() == QGradient::ReflectSpread)
- updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
- else
- updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ wrapMode = GL_MIRRORED_REPEAT;
+
+ updateTextureFilter(wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style == Qt::TexturePattern) {
currentBrushImage = currentBrush.textureImage();
@@ -223,7 +227,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushImage);
- updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ updateTextureFilter(wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
textureInvertedY = false;
}
brushTextureDirty = false;
@@ -1386,7 +1390,7 @@ void QOpenGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixma
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && !pixmap.hasAlpha();
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->shaderManager->setSrcPixelType(isBitmap ? QOpenGLEngineShaderManager::PatternSrc : QOpenGLEngineShaderManager::ImageSrc);
@@ -1429,7 +1433,7 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image, bindOption);
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
@@ -1476,7 +1480,7 @@ bool QOpenGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, co
QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
d->drawTexture(dest, srcRect, size, false);
@@ -1807,7 +1811,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
funcs.glBindTexture(GL_TEXTURE_2D, cache->texture());
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
+ updateTextureFilter(GL_REPEAT, false);
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
@@ -1957,7 +1961,7 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque;
- updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
+ updateTextureFilter(GL_CLAMP_TO_EDGE,
q->state()->renderHints & QPainter::SmoothPixmapTransform, id);
// Setup for texture drawing
diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h
index 5ef0366284..a5f3cc2894 100644
--- a/src/gui/opengl/qopenglpaintengine_p.h
+++ b/src/gui/opengl/qopenglpaintengine_p.h
@@ -193,7 +193,7 @@ public:
void updateBrushUniforms();
void updateMatrix();
void updateCompositionMode();
- void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1));
+ void updateTextureFilter(GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1));
void resetGLState();
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index f6083b8cf9..b96bc6f346 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -2591,6 +2591,7 @@ void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
d->setData(0, 0, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
}
+#if QT_DEPRECATED_SINCE(5, 3)
/*!
\obsolete
\overload
@@ -2648,6 +2649,7 @@ void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
Q_ASSERT(d->textureId);
d->setData(0, 0, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
}
+#endif
/*!
This overload of setData() will allocate storage for you.
@@ -2736,6 +2738,7 @@ void QOpenGLTexture::setCompressedData(int dataSize, const void *data,
d->setCompressedData(0, 0, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
}
+#if QT_DEPRECATED_SINCE(5, 3)
/*!
\obsolete
\overload
@@ -2789,6 +2792,7 @@ void QOpenGLTexture::setCompressedData(int dataSize, void *data,
Q_ASSERT(d->textureId);
d->setCompressedData(0, 0, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
}
+#endif
/*!
Returns \c true if your OpenGL implementation and version supports the texture
diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h
index a53b1730b7..a0b23c211c 100644
--- a/src/gui/opengl/qopengltexture.h
+++ b/src/gui/opengl/qopengltexture.h
@@ -342,6 +342,7 @@ public:
// Pixel transfer
// ### Qt 6: remove the non-const void * overloads
+#if QT_DEPRECATED_SINCE(5, 3)
QT_DEPRECATED void setData(int mipLevel, int layer, CubeMapFace cubeFace,
PixelFormat sourceFormat, PixelType sourceType,
void *data, const QOpenGLPixelTransferOptions * const options = 0);
@@ -353,6 +354,7 @@ public:
void *data, const QOpenGLPixelTransferOptions * const options = 0);
QT_DEPRECATED void setData(PixelFormat sourceFormat, PixelType sourceType,
void *data, const QOpenGLPixelTransferOptions * const options = 0);
+#endif // QT_DEPRECATED_SINCE(5, 3)
void setData(int mipLevel, int layer, CubeMapFace cubeFace,
PixelFormat sourceFormat, PixelType sourceType,
@@ -368,6 +370,7 @@ public:
// Compressed data upload
// ### Qt 6: remove the non-const void * overloads
+#if QT_DEPRECATED_SINCE(5, 3)
QT_DEPRECATED void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
int dataSize, void *data,
const QOpenGLPixelTransferOptions * const options = 0);
@@ -378,6 +381,7 @@ public:
const QOpenGLPixelTransferOptions * const options = 0);
QT_DEPRECATED void setCompressedData(int dataSize, void *data,
const QOpenGLPixelTransferOptions * const options = 0);
+#endif // QT_DEPRECATED_SINCE(5, 3)
void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
int dataSize, const void *data,