201 qWarning(
"Attempted to initialize QOpenGLWindow without a platform window");
203 context.reset(
new QOpenGLContext);
204 context->setShareContext(shareContext);
205 context->setFormat(q->requestedFormat());
206 if (!context->create())
207 qWarning(
"QOpenGLWindow::beginPaint: Failed to create context");
208 if (!context->makeCurrent(q))
209 qWarning(
"QOpenGLWindow::beginPaint: Failed to make context current");
211 paintDevice.reset(
new QOpenGLWindowPaintDevice(q));
212 if (updateBehavior == QOpenGLWindow::PartialUpdateBlit)
213 hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit();
224 context->makeCurrent(q);
226 const int deviceWidth = q->width() * q->devicePixelRatio();
227 const int deviceHeight = q->height() * q->devicePixelRatio();
228 const QSize deviceSize(deviceWidth, deviceHeight);
229 if (updateBehavior > QOpenGLWindow::NoPartialUpdate) {
230 if (!fbo || fbo->size() != deviceSize) {
231 QOpenGLFramebufferObjectFormat fboFormat;
232 fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
233 const int samples = q->requestedFormat().samples();
235 if (updateBehavior != QOpenGLWindow::PartialUpdateBlend)
236 fboFormat.setSamples(samples);
238 qWarning(
"QOpenGLWindow: PartialUpdateBlend does not support multisampling");
240 fbo.reset(
new QOpenGLFramebufferObject(deviceSize, fboFormat));
247 paintDevice->setSize(QSize(deviceWidth, deviceHeight));
248 paintDevice->setDevicePixelRatio(q->devicePixelRatio());
249 context->functions()->glViewport(0, 0, deviceWidth, deviceHeight);
251 context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject());
255 if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
263 if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
266 context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject());
268 if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) {
269 const int deviceWidth = q->width() * q->devicePixelRatio();
270 const int deviceHeight = q->height() * q->devicePixelRatio();
271 QOpenGLExtensions extensions(context.data());
274 extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight,
275 0, 0, deviceWidth, deviceHeight,
276 GL_COLOR_BUFFER_BIT, GL_NEAREST);
277 }
else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) {
278 if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) {
279 context->functions()->glEnable(GL_BLEND);
280 context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
282 if (!blitter.isCreated())
285 QRect windowRect(QPoint(0, 0), fbo->size());
286 QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);
288 blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft);
291 if (updateBehavior == QOpenGLWindow::PartialUpdateBlend)
292 context->functions()->glDisable(GL_BLEND);
324QOpenGLWindow::QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior, QWindow *parent)
325 : QPaintDeviceWindow(*(
new QOpenGLWindowPrivate(
nullptr, updateBehavior)), parent)
327 setSurfaceType(QSurface::OpenGLSurface);
335QOpenGLWindow::QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior, QWindow *parent)
336 : QPaintDeviceWindow(*(
new QOpenGLWindowPrivate(shareContext, updateBehavior)), parent)
338 setSurfaceType(QSurface::OpenGLSurface);
413void QOpenGLWindow::makeCurrent()
423 d->context->makeCurrent(
this);
425 if (!d->offscreenSurface) {
426 d->offscreenSurface.reset(
new QOffscreenSurface(screen()));
427 d->offscreenSurface->setFormat(d->context->format());
428 d->offscreenSurface->create();
430 d->context->makeCurrent(d->offscreenSurface.data());
509QImage QOpenGLWindow::grabFramebuffer()
516 const bool hasAlpha = format().hasAlpha();
517 QImage img = qt_gl_read_framebuffer(size() * devicePixelRatio(), hasAlpha, hasAlpha);
518 img.setDevicePixelRatio(devicePixelRatio());