summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2017-02-20 15:19:49 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2017-02-26 20:06:07 +0000
commit5bb4d064945db43d62ea24b5d23bf4b0b4420e38 (patch)
treec9f01a6beec73a040d03445a4e34b94f4b9e4ddd
parent931e4ae66504f5d0be9d097565b4e9f49a92c69a (diff)
Add support for custom texture format in QOpenGLWidget
...in order to support sRGB framebuffers. Add a --srgb option to the qopenglwidget example to allow testing. [ChangeLog][QtWidgets][QOpenGLWidget] Added support for specifying custom internal texture formats in QOpenGLWidget in order to make it possible to have the widget backed by an sRGB-capable framebuffer. Task-number: QTBUG-50987 Change-Id: I112e2f0ab0b1478c69e601031aa0bafaa87fa847 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r--examples/opengl/qopenglwidget/glwidget.cpp6
-rw-r--r--examples/opengl/qopenglwidget/main.cpp2
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp54
-rw-r--r--src/widgets/kernel/qopenglwidget.h3
-rw-r--r--tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp2
5 files changed, 64 insertions, 3 deletions
diff --git a/examples/opengl/qopenglwidget/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp
index 21d922d713..bb7c952a26 100644
--- a/examples/opengl/qopenglwidget/glwidget.cpp
+++ b/examples/opengl/qopenglwidget/glwidget.cpp
@@ -61,6 +61,10 @@
const int bubbleNum = 8;
+#ifndef GL_SRGB8_ALPHA8
+#define GL_SRGB8_ALPHA8 0x8C43
+#endif
+
GLWidget::GLWidget(MainWindow *mw, bool button, const QColor &background)
: m_mainWindow(mw),
m_showBubbles(true),
@@ -75,6 +79,8 @@ GLWidget::GLWidget(MainWindow *mw, bool button, const QColor &background)
m_background(background)
{
setMinimumSize(300, 250);
+ if (QCoreApplication::arguments().contains(QStringLiteral("--srgb")))
+ setTextureFormat(GL_SRGB8_ALPHA8);
}
GLWidget::~GLWidget()
diff --git a/examples/opengl/qopenglwidget/main.cpp b/examples/opengl/qopenglwidget/main.cpp
index d7aa791142..f9b5731b8f 100644
--- a/examples/opengl/qopenglwidget/main.cpp
+++ b/examples/opengl/qopenglwidget/main.cpp
@@ -61,6 +61,8 @@ int main( int argc, char ** argv )
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
+ if (QCoreApplication::arguments().contains(QStringLiteral("--srgb")))
+ format.setColorSpace(QSurfaceFormat::sRGBColorSpace);
if (QCoreApplication::arguments().contains(QStringLiteral("--multisample")))
format.setSamples(4);
QSurfaceFormat::setDefaultFormat(format);
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 147e0774e7..fd45abc8a2 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -566,7 +566,8 @@ public:
paintDevice(0),
updateBehavior(QOpenGLWidget::NoPartialUpdate),
requestedSamples(0),
- inPaintGL(false)
+ inPaintGL(false),
+ textureFormat(0)
{
requestedFormat = QSurfaceFormat::defaultFormat();
}
@@ -610,6 +611,7 @@ public:
QOpenGLWidget::UpdateBehavior updateBehavior;
int requestedSamples;
bool inPaintGL;
+ GLenum textureFormat;
};
void QOpenGLWidgetPaintDevicePrivate::beginPaint()
@@ -703,12 +705,16 @@ void QOpenGLWidgetPrivate::recreateFbo()
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(samples);
+ if (textureFormat)
+ format.setInternalTextureFormat(textureFormat);
const QSize deviceSize = q->size() * q->devicePixelRatioF();
fbo = new QOpenGLFramebufferObject(deviceSize, format);
if (samples > 0)
resolvedFbo = new QOpenGLFramebufferObject(deviceSize);
+ textureFormat = fbo->format().internalTextureFormat();
+
fbo->bind();
context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
@@ -767,7 +773,9 @@ void QOpenGLWidgetPrivate::initialize()
return;
}
- // Propagate settings that make sense only for the tlw.
+ // Propagate settings that make sense only for the tlw. Note that this only
+ // makes sense for properties that get picked up even after the native
+ // window is created.
QSurfaceFormat tlwFormat = tlw->windowHandle()->format();
if (requestedFormat.swapInterval() != tlwFormat.swapInterval()) {
// Most platforms will pick up the changed swap interval on the next
@@ -990,7 +998,6 @@ QOpenGLWidget::UpdateBehavior QOpenGLWidget::updateBehavior() const
*/
void QOpenGLWidget::setFormat(const QSurfaceFormat &format)
{
- Q_UNUSED(format);
Q_D(QOpenGLWidget);
if (Q_UNLIKELY(d->initialized)) {
qWarning("QOpenGLWidget: Already initialized, setting the format has no effect");
@@ -1023,6 +1030,47 @@ QSurfaceFormat QOpenGLWidget::format() const
}
/*!
+ Sets a custom internal texture format.
+
+ When working with sRGB framebuffers, it will be necessary to specify a
+ format like \c{GL_SRGB8_ALPHA8}. This can be achieved by calling this
+ function.
+
+ \note This function has no effect if called after the widget has already
+ been shown and thus it performed initialization.
+
+ \note This function will typically have to be used in combination with a
+ QSurfaceFormat::setDefaultFormat() call that sets the color space to
+ QSurfaceFormat::sRGBColorSpace.
+
+ \since 5.10
+ */
+void QOpenGLWidget::setTextureFormat(GLenum texFormat)
+{
+ Q_D(QOpenGLWidget);
+ if (Q_UNLIKELY(d->initialized)) {
+ qWarning("QOpenGLWidget: Already initialized, setting the internal texture format has no effect");
+ return;
+ }
+
+ d->textureFormat = texFormat;
+}
+
+/*!
+ \return the active internal texture format if the widget has already
+ initialized, the requested format if one was set but the widget has not yet
+ been made visible, or 0 if setTextureFormat() was not called and the widget
+ has not yet been made visible.
+
+ \since 5.10
+ */
+GLenum QOpenGLWidget::textureFormat() const
+{
+ Q_D(const QOpenGLWidget);
+ return d->textureFormat;
+}
+
+/*!
\return \e true if the widget and OpenGL resources, like the context, have
been successfully initialized. Note that the return value is always false
until the widget is shown.
diff --git a/src/widgets/kernel/qopenglwidget.h b/src/widgets/kernel/qopenglwidget.h
index b60d79bedb..c0a6e41522 100644
--- a/src/widgets/kernel/qopenglwidget.h
+++ b/src/widgets/kernel/qopenglwidget.h
@@ -72,6 +72,9 @@ public:
void setFormat(const QSurfaceFormat &format);
QSurfaceFormat format() const;
+ GLenum textureFormat() const;
+ void setTextureFormat(GLenum texFormat);
+
bool isValid() const;
void makeCurrent();
diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
index e3e26d612f..a1b585d0d3 100644
--- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
+++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
@@ -64,6 +64,7 @@ void tst_QOpenGLWidget::create()
{
QScopedPointer<QOpenGLWidget> w(new QOpenGLWidget);
QVERIFY(!w->isValid());
+ QVERIFY(w->textureFormat() == 0);
QSignalSpy frameSwappedSpy(w.data(), SIGNAL(frameSwapped()));
w->show();
QTest::qWaitForWindowExposed(w.data());
@@ -73,6 +74,7 @@ void tst_QOpenGLWidget::create()
QVERIFY(w->context());
QCOMPARE(w->context()->format(), w->format());
QVERIFY(w->defaultFramebufferObject() != 0);
+ QVERIFY(w->textureFormat() != 0);
}
class ClearWidget : public QOpenGLWidget, protected QOpenGLFunctions