summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-18 17:03:58 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-05-26 18:00:01 +0200
commit93cd9130d6d8d30e901dd3b2f2546dbc63754e2e (patch)
tree3def7382cd1e4edd4ff380587deee775e48a2e4b /src/opengl
parente51831260a759b58cb089cac089c202a795fc584 (diff)
Introduce float QImage formats and rendering
Useful for some HDR representations and HDR rendering. Change-Id: If6e8a661faa3d2afdf17b6ed4d8ff5c5b2aeb30e Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/qopenglframebufferobject.cpp44
-rw-r--r--src/opengl/qopenglpaintengine.cpp2
-rw-r--r--src/opengl/qopengltextureuploader.cpp39
3 files changed, 85 insertions, 0 deletions
diff --git a/src/opengl/qopenglframebufferobject.cpp b/src/opengl/qopenglframebufferobject.cpp
index 78b192b630..aa1c396892 100644
--- a/src/opengl/qopenglframebufferobject.cpp
+++ b/src/opengl/qopenglframebufferobject.cpp
@@ -152,6 +152,25 @@ QT_BEGIN_NAMESPACE
#define GL_DEPTH_STENCIL 0x84F9
#endif
+#ifndef GL_HALF_FLOAT
+#define GL_HALF_FLOAT 0x140B
+#endif
+
+#ifndef GL_RGBA32F
+#define GL_RGBA32F 0x8814
+#endif
+
+#ifndef GL_RGB32F
+#define GL_RGB32F 0x8815
+#endif
+
+#ifndef GL_RGBA16F
+#define GL_RGBA16F 0x881A
+#endif
+
+#ifndef GL_RGB16F
+#define GL_RGB16F 0x881B
+#endif
/*!
@@ -554,6 +573,8 @@ void QOpenGLFramebufferObjectPrivate::initTexture(int idx)
pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
else if (color.internalFormat == GL_RGB16 || color.internalFormat == GL_RGBA16)
pixelType = GL_UNSIGNED_SHORT;
+ else if (color.internalFormat == GL_RGB16F || color.internalFormat == GL_RGBA16F)
+ pixelType = GL_HALF_FLOAT;
funcs.glTexImage2D(target, 0, color.internalFormat, color.size.width(), color.size.height(), 0,
GL_RGBA, pixelType, nullptr);
@@ -1379,6 +1400,21 @@ static inline QImage qt_gl_read_framebuffer_rgba16(const QSize &size, bool inclu
return img;
}
+static inline QImage qt_gl_read_framebuffer_rgba16f(const QSize &size, bool include_alpha, QOpenGLContext *context)
+{
+ // We assume OpenGL (ES) 3.0+ here.
+ QImage img(size, include_alpha ? QImage::Format_RGBA16FPx4_Premultiplied : QImage::Format_RGBX16FPx4);
+ context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_HALF_FLOAT, img.bits());
+ return img;
+}
+
+static inline QImage qt_gl_read_framebuffer_rgba32f(const QSize &size, bool include_alpha, QOpenGLContext *context)
+{
+ QImage img(size, include_alpha ? QImage::Format_RGBA32FPx4_Premultiplied : QImage::Format_RGBX32FPx4);
+ context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_FLOAT, img.bits());
+ return img;
+}
+
static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format, bool include_alpha, bool flip)
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
@@ -1400,6 +1436,14 @@ static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format,
return qt_gl_read_framebuffer_rgba16(size, false, ctx).mirrored(false, flip);
case GL_RGBA16:
return qt_gl_read_framebuffer_rgba16(size, include_alpha, ctx).mirrored(false, flip);
+ case GL_RGB16F:
+ return qt_gl_read_framebuffer_rgba16f(size, false, ctx).mirrored(false, flip);
+ case GL_RGBA16F:
+ return qt_gl_read_framebuffer_rgba16f(size, include_alpha, ctx).mirrored(false, flip);
+ case GL_RGB32F:
+ return qt_gl_read_framebuffer_rgba32f(size, false, ctx).mirrored(false, flip);
+ case GL_RGBA32F:
+ return qt_gl_read_framebuffer_rgba32f(size, include_alpha, ctx).mirrored(false, flip);
case GL_RGBA:
case GL_RGBA8:
default:
diff --git a/src/opengl/qopenglpaintengine.cpp b/src/opengl/qopenglpaintengine.cpp
index 7da9bf143d..8606a2e7ef 100644
--- a/src/opengl/qopenglpaintengine.cpp
+++ b/src/opengl/qopenglpaintengine.cpp
@@ -1572,6 +1572,8 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c
case QImage::Format_RGBA8888:
case QImage::Format_ARGB32:
case QImage::Format_RGBA64:
+ case QImage::Format_RGBA16FPx4:
+ case QImage::Format_RGBA32FPx4:
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::NonPremultipliedImageSrc);
bindOption = { };
break;
diff --git a/src/opengl/qopengltextureuploader.cpp b/src/opengl/qopengltextureuploader.cpp
index 469ddc56c1..488baf32ad 100644
--- a/src/opengl/qopengltextureuploader.cpp
+++ b/src/opengl/qopengltextureuploader.cpp
@@ -45,6 +45,10 @@
#include <private/qopenglcontext_p.h>
#include <private/qopenglextensions_p.h>
+#ifndef GL_HALF_FLOAT
+#define GL_HALF_FLOAT 0x140B
+#endif
+
#ifndef GL_RED
#define GL_RED 0x1903
#endif
@@ -81,6 +85,14 @@
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#endif
+#ifndef GL_RGBA16F
+#define GL_RGBA16F 0x881A
+#endif
+
+#ifndef GL_RGBA32F
+#define GL_RGBA32F 0x8814
+#endif
+
#ifndef GL_TEXTURE_SWIZZLE_R
#define GL_TEXTURE_SWIZZLE_R 0x8E42
#endif
@@ -236,6 +248,25 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
pixelType = GL_UNSIGNED_SHORT;
targetFormat = image.format();
break;
+ case QImage::Format_RGBX16FPx4:
+ case QImage::Format_RGBA16FPx4:
+ case QImage::Format_RGBA16FPx4_Premultiplied:
+ if (context->format().majorVersion() >= 3) {
+ externalFormat = GL_RGBA;
+ internalFormat = GL_RGBA16F;
+ pixelType = GL_HALF_FLOAT;
+ targetFormat = image.format();
+ }
+ break;
+ case QImage::Format_RGBX32FPx4:
+ case QImage::Format_RGBA32FPx4:
+ case QImage::Format_RGBA32FPx4_Premultiplied:
+ externalFormat = internalFormat = GL_RGBA;
+ if (context->format().majorVersion() >= 3)
+ internalFormat = GL_RGBA32F;
+ pixelType = GL_FLOAT;
+ targetFormat = image.format();
+ break;
case QImage::Format_Indexed8:
if (sRgbBinding) {
// Always needs conversion
@@ -333,6 +364,10 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
targetFormat = QImage::Format_RGBA8888_Premultiplied;
else if (targetFormat == QImage::Format_RGBA64)
targetFormat = QImage::Format_RGBA64_Premultiplied;
+ else if (targetFormat == QImage::Format_RGBA16FPx4)
+ targetFormat = QImage::Format_RGBA16FPx4_Premultiplied;
+ else if (targetFormat == QImage::Format_RGBA32FPx4)
+ targetFormat = QImage::Format_RGBA32FPx4_Premultiplied;
} else {
if (targetFormat == QImage::Format_ARGB32_Premultiplied)
targetFormat = QImage::Format_ARGB32;
@@ -340,6 +375,10 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
targetFormat = QImage::Format_RGBA8888;
else if (targetFormat == QImage::Format_RGBA64_Premultiplied)
targetFormat = QImage::Format_RGBA64;
+ else if (targetFormat == QImage::Format_RGBA16FPx4_Premultiplied)
+ targetFormat = QImage::Format_RGBA16FPx4;
+ else if (targetFormat == QImage::Format_RGBA32FPx4_Premultiplied)
+ targetFormat = QImage::Format_RGBA32FPx4;
}
if (sRgbBinding) {