summaryrefslogtreecommitdiffstats
path: root/src/opengl/qglpixelbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/qglpixelbuffer.cpp')
-rw-r--r--src/opengl/qglpixelbuffer.cpp117
1 files changed, 106 insertions, 11 deletions
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index d9480c4994..135f2edd01 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -92,7 +92,10 @@
\sa {opengl/pbuffers}{Pbuffers Example}
*/
+#include <private/qopenglextensions_p.h>
+
#include <QtCore/qglobal.h>
+#include <QtGui/qopenglframebufferobject.h>
#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
@@ -129,16 +132,7 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form
req_format = format;
req_shareWidget = shareWidget;
invalid = false;
- qctx = new QGLContext(format);
- qctx->d_func()->sharing = (shareWidget != 0);
- if (shareWidget != 0 && shareWidget->d_func()->glcx) {
- QGLContextGroup::addShare(qctx, shareWidget->d_func()->glcx);
- shareWidget->d_func()->glcx->d_func()->sharing = true;
- }
-
glDevice.setPBuffer(q);
- qctx->d_func()->paintDevice = q;
- qctx->d_func()->valid = true;
}
}
@@ -198,7 +192,6 @@ QGLPixelBuffer::~QGLPixelBuffer()
if (current != d->qctx)
makeCurrent();
d->cleanup();
- delete d->qctx;
if (current && current != d->qctx)
current->makeCurrent();
}
@@ -217,6 +210,17 @@ bool QGLPixelBuffer::makeCurrent()
if (d->invalid)
return false;
d->qctx->makeCurrent();
+ if (!d->fbo) {
+ QOpenGLFramebufferObjectFormat format;
+ if (d->req_format.stencil())
+ format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ else if (d->req_format.depth())
+ format.setAttachment(QOpenGLFramebufferObject::Depth);
+ if (d->req_format.sampleBuffers())
+ format.setSamples(d->req_format.samples());
+ d->fbo = new QOpenGLFramebufferObject(d->req_size, format);
+ d->fbo->bind();
+ }
return true;
}
@@ -306,14 +310,39 @@ bool QGLPixelBuffer::doneCurrent()
void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
{
Q_D(const QGLPixelBuffer);
- if (d->invalid)
+ if (d->invalid || !d->fbo)
+ return;
+
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx)
return;
+
+#undef glBindFramebuffer
+
+#ifndef GL_READ_FRAMEBUFFER
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#endif
+
+#ifndef GL_DRAW_FRAMEBUFFER
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#endif
+
+ QOpenGLExtensions extensions(ctx);
+
+ if (d->blit_fbo) {
+ QOpenGLFramebufferObject::blitFramebuffer(d->blit_fbo, d->fbo);
+ extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, d->blit_fbo->handle());
+ }
+
glBindTexture(GL_TEXTURE_2D, texture_id);
#ifndef QT_OPENGL_ES
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, d->req_size.width(), d->req_size.height(), 0);
#else
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
#endif
+
+ if (d->blit_fbo)
+ extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->d_func()->current_fbo);
}
/*!
@@ -521,4 +550,70 @@ QGLFormat QGLPixelBuffer::format() const
\internal
*/
+bool QGLPixelBufferPrivate::init(const QSize &, const QGLFormat &f, QGLWidget *shareWidget)
+{
+ widget = new QGLWidget(f, 0, shareWidget);
+ widget->resize(1, 1);
+ qctx = const_cast<QGLContext *>(widget->context());
+ return widget->isValid();
+}
+
+bool QGLPixelBufferPrivate::cleanup()
+{
+ delete fbo;
+ fbo = 0;
+ delete blit_fbo;
+ blit_fbo = 0;
+ delete widget;
+ widget = 0;
+ return true;
+}
+
+bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
+{
+ Q_UNUSED(texture_id);
+ return false;
+}
+
+void QGLPixelBuffer::releaseFromDynamicTexture()
+{
+}
+
+GLuint QGLPixelBuffer::generateDynamicTexture() const
+{
+ Q_D(const QGLPixelBuffer);
+ if (!d->fbo)
+ return 0;
+
+ if (d->fbo->format().samples() > 0
+ && QOpenGLExtensions(QOpenGLContext::currentContext())
+ .hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit))
+ {
+ if (!d->blit_fbo)
+ const_cast<QOpenGLFramebufferObject *&>(d->blit_fbo) = new QOpenGLFramebufferObject(d->req_size);
+ } else {
+ return d->fbo->texture();
+ }
+
+ GLuint texture;
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0);
+
+ return texture;
+}
+
+bool QGLPixelBuffer::hasOpenGLPbuffers()
+{
+ return QOpenGLFramebufferObject::hasOpenGLFramebufferObjects();
+}
+
QT_END_NAMESPACE