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>
This commit is contained in:
parent
931e4ae665
commit
5bb4d06494
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
@ -1022,6 +1029,47 @@ QSurfaceFormat QOpenGLWidget::format() const
|
||||
return d->initialized ? d->context->format() : d->requestedFormat;
|
||||
}
|
||||
|
||||
/*!
|
||||
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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user