summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/qgl.cpp1
-rw-r--r--src/opengl/qgl.h2
-rw-r--r--src/opengl/qgl_p.h4
-rw-r--r--src/opengl/qglframebufferobject.cpp32
-rw-r--r--src/opengl/qpixmapdata_gl.cpp8
-rw-r--r--src/opengl/qpixmapdata_gl_p.h2
6 files changed, 46 insertions, 3 deletions
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 2d90342..4c152e2 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1297,6 +1297,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
max_texture_size = -1;
version_flags_cached = false;
version_flags = QGLFormat::OpenGL_Version_None;
+ current_fbo = 0;
}
QGLContext* QGLContext::currentCtx = 0;
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 01b1d6f..32fbce2 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -371,8 +371,8 @@ private:
friend class QMacGLWindowChangeEvent;
friend QGLContextPrivate *qt_phonon_get_dptr(const QGLContext *);
#endif
-#ifdef Q_WS_WIN
friend class QGLFramebufferObject;
+#ifdef Q_WS_WIN
friend class QGLFramebufferObjectPrivate;
friend bool qt_resolve_GLSL_functions(QGLContext *ctx);
friend bool qt_createGLSLProgram(QGLContext *ctx, GLuint &program, const char *shader_src, GLuint &shader);
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index b8bbeaf..b15eebc 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -254,6 +254,8 @@ public:
QGLExtensionFuncs extensionFuncs;
GLint max_texture_size;
+ GLuint current_fbo;
+
#ifdef Q_WS_WIN
static inline QGLExtensionFuncs& qt_get_extension_funcs(const QGLContext *ctx) { return ctx->d_ptr->extensionFuncs; }
#endif
@@ -267,7 +269,7 @@ public:
};
// ### make QGLContext a QObject in 5.0 and remove the proxy stuff
-class QGLSignalProxy : public QObject
+class Q_OPENGL_EXPORT QGLSignalProxy : public QObject
{
Q_OBJECT
public:
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index fb22272..8524dfa 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -66,7 +66,7 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
class QGLFramebufferObjectPrivate
{
public:
- QGLFramebufferObjectPrivate() : depth_stencil_buffer(0), valid(false), bound(false), ctx(0) {}
+ QGLFramebufferObjectPrivate() : depth_stencil_buffer(0), valid(false), bound(false), ctx(0), previous_fbo(0) {}
~QGLFramebufferObjectPrivate() {}
void init(const QSize& sz, QGLFramebufferObject::Attachment attachment,
@@ -81,6 +81,7 @@ public:
uint bound : 1;
QGLFramebufferObject::Attachment fbo_attachment;
QGLContext *ctx; // for Windows extension ptrs
+ GLuint previous_fbo;
};
bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
@@ -469,6 +470,15 @@ bool QGLFramebufferObject::isValid() const
Switches rendering from the default, windowing system provided
framebuffer to this framebuffer object.
Returns true upon success, false otherwise.
+
+ Since 4.6: if another QGLFramebufferObject instance was already bound
+ to the current context, then its handle() will be remembered and
+ automatically restored when release() is called. This allows multiple
+ framebuffer rendering targets to be stacked up. It is important that
+ release() is called on the stacked framebuffer objects in the reverse
+ order of the calls to bind().
+
+ \sa release()
*/
bool QGLFramebufferObject::bind()
{
@@ -478,6 +488,12 @@ bool QGLFramebufferObject::bind()
QGL_FUNC_CONTEXT;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, d->fbo);
d->bound = d->valid = d->checkFramebufferStatus();
+ const QGLContext *context = QGLContext::currentContext();
+ if (d->valid && context) {
+ // Save the previous setting to automatically restore in release().
+ d->previous_fbo = context->d_ptr->current_fbo;
+ context->d_ptr->current_fbo = d->fbo;
+ }
return d->valid;
}
@@ -487,6 +503,12 @@ bool QGLFramebufferObject::bind()
Switches rendering back to the default, windowing system provided
framebuffer.
Returns true upon success, false otherwise.
+
+ Since 4.6: if another QGLFramebufferObject instance was already bound
+ to the current context when bind() was called, then this function will
+ automatically re-bind it to the current context.
+
+ \sa bind()
*/
bool QGLFramebufferObject::release()
{
@@ -497,6 +519,14 @@ bool QGLFramebufferObject::release()
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
d->valid = d->checkFramebufferStatus();
d->bound = false;
+ const QGLContext *context = QGLContext::currentContext();
+ if (d->valid && context) {
+ // Restore the previous setting for stacked framebuffer objects.
+ context->d_ptr->current_fbo = d->previous_fbo;
+ if (d->previous_fbo)
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, d->previous_fbo);
+ d->previous_fbo = 0;
+ }
return d->valid;
}
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 5d668cd..b079557 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -205,6 +205,14 @@ void QGLPixmapData::fromImage(const QImage &image,
m_dirty = true;
}
+bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
+{
+ Q_UNUSED(dx);
+ Q_UNUSED(dy);
+ Q_UNUSED(rect);
+ return false;
+}
+
void QGLPixmapData::fill(const QColor &color)
{
if (!isValid())
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index 63703fd..e450f01 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -73,6 +73,8 @@ public:
void fromImage(const QImage &image,
Qt::ImageConversionFlags flags);
+ bool scroll(int dx, int dy, const QRect &rect);
+
void fill(const QColor &color);
bool hasAlphaChannel() const;
QImage toImage() const;