diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2012-06-08 09:39:17 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-20 11:58:16 +0200 |
commit | fc41ee4c92ce703f3e4374bf493505a1d847a657 (patch) | |
tree | d56e6e2dc1bb350ae8bf9c63988a6ed2944f96bb /src/opengl/qglframebufferobject.cpp | |
parent | 799ceebad8a2dbe1ca0e60a11c7d6ca0c2c8b7a9 (diff) |
OpenGL: Use official glext.h and gl2ext.h headers
The Khronos group makes the glext.h (Desktop OpenGL) and gl2ext.h
(OpenGL ES2) headers officially available nowadays. Most (all?)
Linux systems ship this by default. On Windows platforms the
glext.h file needs to be downloaded from
http://www.opengl.org/registry/api/glext.h
and placed alongside the system OpenGL header.
Making use of the official header reduces the maintenance
overhead for OpenGL support in Qt by removing the need to copy
and paste definitions into the Qt sources.
As the Khronos-provided headers are standardised and backwards and
forwards compatible we can utilise these for all platforms rather
than just for Windows. This means that all definitions required
by Qt will be present even if the system ships out-dated
equivalents.
Mac OS X needs special handling in that we should always use the
system-provided headers there. This is because Apple controls the
OpenGL driver and the headers that go along with it. As such there
is no possibility that the driver exposes additional functionality
compared with the system-provided OpenGL headers. Apple has also
decided to make different decisions about some OpenGL typedefs
compared to other implementations. For example, Apple typdefs
GLhandleARB to void* whereas other platforms use unsigned int.
The alternative, which is to use the system provided glext.h (or
gl2ext.h) header means that Qt code would need to check for the
availability of such definitions wherever it is not guaranteed
to be provided by core OpenGL/ES just to compile.
The proposed approach means that Qt can compile regardless of
the system's OpenGL extension support. We just need to be
rigourous in runtime checking of support for extensions but
that is already a requirement (and is missing in a few places,
see TODO's added in this commit).
The official Khronos headers are added to Qt as
qopenglext.h - Desktop OpenGL
qopengles2ext.h - OpenGL ES2
They need to be public but not part of QtGui module include, hence
the headers have been modified by adding
#if 0
#pragma qt_no_master_include
#endif
to them.
This has been tested on:
Gentoo Linux with GCC 4.6.3
Windows 7 with MSVC 2010
Mac OSX 10.8 with Apple clang 4.0 (based on LLVM 3.1svn)
QNX with qcc (based on GCC 4.4)
A small change is needed to QtDeclarative when building for OpenGL
ES 2 after applying this commit. See
https://codereview.qt-project.org/#change,31794
Change-Id: I4b3d2b1680baf4c78be9a87b4d8de076d23e8f82
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/opengl/qglframebufferobject.cpp')
-rw-r--r-- | src/opengl/qglframebufferobject.cpp | 144 |
1 files changed, 90 insertions, 54 deletions
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 680df29f8b..0359de8fa9 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -76,6 +76,32 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool); #define QT_CHECK_GLERROR() {} #endif +// ####TODO Properly #ifdef this class to use #define symbols actually defined +// by OpenGL/ES includes +#ifndef GL_MAX_SAMPLES +#define GL_MAX_SAMPLES 0x8D57 +#endif + +#ifndef GL_RENDERBUFFER_SAMPLES +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#endif + +#ifndef GL_DEPTH24_STENCIL8 +#define GL_DEPTH24_STENCIL8 0x88F0 +#endif + +#ifndef GL_DEPTH_COMPONENT24 +#define GL_DEPTH_COMPONENT24 0x81A6 +#endif + +#ifndef GL_READ_FRAMEBUFFER +#define GL_READ_FRAMEBUFFER 0x8CA8 +#endif + +#ifndef GL_DRAW_FRAMEBUFFER +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#endif + /*! \class QGLFramebufferObjectFormat \brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL @@ -359,41 +385,51 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const QGL_FUNCP_CONTEXT; if (!ctx) return false; // Context no longer exists. - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch(status) { case GL_NO_ERROR: - case GL_FRAMEBUFFER_COMPLETE_EXT: + case GL_FRAMEBUFFER_COMPLETE: return true; break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + case GL_FRAMEBUFFER_UNSUPPORTED: qDebug("QGLFramebufferObject: Unsupported framebuffer format."); break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: qDebug("QGLFramebufferObject: Framebuffer incomplete attachment."); break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: qDebug("QGLFramebufferObject: Framebuffer incomplete, missing attachment."); break; -#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT - case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: +#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT + case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT: qDebug("QGLFramebufferObject: Framebuffer incomplete, duplicate attachment."); break; #endif - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: +#ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same dimensions."); break; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: +#endif +#ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS: qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same format."); break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: +#endif +#ifdef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: qDebug("QGLFramebufferObject: Framebuffer incomplete, missing draw buffer."); break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: +#endif +#ifdef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: qDebug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer."); break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: +#endif +#ifdef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: qDebug("QGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel."); break; +#endif default: qDebug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status; break; @@ -440,7 +476,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, QT_RESET_GLERROR(); // reset error state GLuint fbo = 0; glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLuint texture = 0; GLuint color_buffer = 0; @@ -470,7 +506,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texture, 0); QT_CHECK_GLERROR(); @@ -481,29 +517,29 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, } else { mipmap = false; GLint maxSamples; - glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); samples = qBound(0, int(samples), int(maxSamples)); glGenRenderbuffers(1, &color_buffer); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, color_buffer); if (glRenderbufferStorageMultisampleEXT && samples > 0) { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, internal_format, size.width(), size.height()); } else { samples = 0; - glRenderbufferStorage(GL_RENDERBUFFER_EXT, internal_format, + glRenderbufferStorage(GL_RENDERBUFFER, internal_format, size.width(), size.height()); } - glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_RENDERBUFFER_EXT, color_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, color_buffer); QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); if (valid) - glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_SAMPLES_EXT, &samples); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); } // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a @@ -515,20 +551,20 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, // depth and stencil buffer needs another extension glGenRenderbuffers(1, &depth_buffer); Q_ASSERT(!glIsRenderbuffer(depth_buffer)); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, - GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, + GL_DEPTH24_STENCIL8, size.width(), size.height()); else - glRenderbufferStorage(GL_RENDERBUFFER_EXT, - GL_DEPTH24_STENCIL8_EXT, size.width(), size.height()); + glRenderbufferStorage(GL_RENDERBUFFER, + GL_DEPTH24_STENCIL8, size.width(), size.height()); stencil_buffer = depth_buffer; - glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_buffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, stencil_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, depth_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, stencil_buffer); valid = checkFramebufferStatus(); if (!valid) { @@ -542,36 +578,36 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, { glGenRenderbuffers(1, &depth_buffer); Q_ASSERT(!glIsRenderbuffer(depth_buffer)); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); Q_ASSERT(glIsRenderbuffer(depth_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); } else { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { - glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_OES, + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); } else { - glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size.width(), size.height()); } #else - glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height()); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height()); #endif } - glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depth_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, depth_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &depth_buffer); @@ -582,27 +618,27 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) { glGenRenderbuffers(1, &stencil_buffer); Q_ASSERT(!glIsRenderbuffer(stencil_buffer)); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer); + glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer); Q_ASSERT(glIsRenderbuffer(stencil_buffer)); if (samples != 0 && glRenderbufferStorageMultisampleEXT) { #ifdef QT_OPENGL_ES - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, - GL_STENCIL_INDEX8_EXT, size.width(), size.height()); + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, + GL_STENCIL_INDEX8, size.width(), size.height()); #else - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_STENCIL_INDEX, size.width(), size.height()); #endif } else { #ifdef QT_OPENGL_ES - glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, size.width(), size.height()); #else - glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX, size.width(), size.height()); #endif } - glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, stencil_buffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, stencil_buffer); valid = checkFramebufferStatus(); if (!valid) { glDeleteRenderbuffers(1, &stencil_buffer); @@ -621,7 +657,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, fbo_attachment = QGLFramebufferObject::NoAttachment; } - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo); if (valid) { fbo_guard = createSharedResourceGuard(ctx, fbo, freeFramebufferFunc); if (color_buffer) @@ -947,7 +983,7 @@ bool QGLFramebufferObject::bind() qWarning("QGLFramebufferObject::bind() called from incompatible context"); } #endif - glBindFramebuffer(GL_FRAMEBUFFER_EXT, d->fbo()); + glBindFramebuffer(GL_FRAMEBUFFER, d->fbo()); d->valid = d->checkFramebufferStatus(); if (d->valid && current) current->d_ptr->current_fbo = d->fbo(); @@ -983,7 +1019,7 @@ bool QGLFramebufferObject::release() if (current) { current->d_ptr->current_fbo = current->d_ptr->default_fbo; - glBindFramebuffer(GL_FRAMEBUFFER_EXT, current->d_ptr->default_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, current->d_ptr->default_fbo); } return true; @@ -1094,7 +1130,7 @@ bool QGLFramebufferObject::bindDefault() return false; ctx->d_ptr->current_fbo = ctx->d_ptr->default_fbo; - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->default_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->default_fbo); #ifdef QT_DEBUG } else { qWarning("QGLFramebufferObject::bindDefault() called without current context."); @@ -1316,14 +1352,14 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q const int ty0 = th - (targetRect.top() + targetRect.height()); const int ty1 = th - targetRect.top(); - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, source ? source->handle() : 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, target ? target->handle() : 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0); glBlitFramebufferEXT(sx0, sy0, sx1, sy1, tx0, ty0, tx1, ty1, buffers, filter); - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo); } QT_END_NAMESPACE |