00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qdebug.h>
00025 #include <private/qgl_p.h>
00026 #include <private/qpaintengine_opengl_p.h>
00027 #include <qglframebufferobject.h>
00028 #include <qlibrary.h>
00029 #include <qimage.h>
00030
00031
00032
00033 #ifndef GL_EXT_framebuffer_object
00034 #define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
00035 #define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
00036 #define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
00037 #define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
00038 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
00039 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
00040 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
00041 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
00042 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
00043 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
00044 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
00045 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
00046 #define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8
00047 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
00048 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
00049 #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
00050 #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
00051 #define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
00052 #define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
00053 #define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
00054 #define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
00055 #define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
00056 #define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
00057 #define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
00058 #define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
00059 #define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
00060 #define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
00061 #define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
00062 #define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
00063 #define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
00064 #define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
00065 #define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
00066 #define GL_COLOR_ATTACHMENT13_EXT 0x8CED
00067 #define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
00068 #define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
00069 #define GL_DEPTH_ATTACHMENT_EXT 0x8D00
00070 #define GL_STENCIL_ATTACHMENT_EXT 0x8D20
00071 #define GL_FRAMEBUFFER_EXT 0x8D40
00072 #define GL_RENDERBUFFER_EXT 0x8D41
00073 #define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
00074 #define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
00075 #define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
00076 #define GL_STENCIL_INDEX_EXT 0x8D45
00077 #define GL_STENCIL_INDEX1_EXT 0x8D46
00078 #define GL_STENCIL_INDEX4_EXT 0x8D47
00079 #define GL_STENCIL_INDEX8_EXT 0x8D48
00080 #define GL_STENCIL_INDEX16_EXT 0x8D49
00081 #define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
00082 #define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
00083 #define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
00084 #define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
00085 #define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
00086 #define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
00087 #endif
00088
00089
00090 #ifndef GL_CLAMP_TO_EDGE
00091 #define GL_CLAMP_TO_EDGE 0x812F
00092 #endif
00093
00094 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
00095
00096 #define QGL_FUNC_CONTEXT
00097
00098 PFNGLISRENDERBUFFEREXTPROC qt_glIsRenderbufferEXT;
00099 PFNGLBINDRENDERBUFFEREXTPROC qt_glBindRenderbufferEXT;
00100 PFNGLDELETERENDERBUFFERSEXTPROC qt_glDeleteRenderbuffersEXT;
00101 PFNGLGENRENDERBUFFERSEXTPROC qt_glGenRenderbuffersEXT;
00102 PFNGLRENDERBUFFERSTORAGEEXTPROC qt_glRenderbufferStorageEXT;
00103 PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC qt_glGetRenderbufferParameterivEXT;
00104 PFNGLISFRAMEBUFFEREXTPROC qt_glIsFramebufferEXT;
00105 PFNGLBINDFRAMEBUFFEREXTPROC qt_glBindFramebufferEXT;
00106 PFNGLDELETEFRAMEBUFFERSEXTPROC qt_glDeleteFramebuffersEXT;
00107 PFNGLGENFRAMEBUFFERSEXTPROC qt_glGenFramebuffersEXT;
00108 PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC qt_glCheckFramebufferStatusEXT;
00109 PFNGLFRAMEBUFFERTEXTURE1DEXTPROC qt_glFramebufferTexture1DEXT;
00110 PFNGLFRAMEBUFFERTEXTURE2DEXTPROC qt_glFramebufferTexture2DEXT;
00111 PFNGLFRAMEBUFFERTEXTURE3DEXTPROC qt_glFramebufferTexture3DEXT;
00112 PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC qt_glFramebufferRenderbufferEXT;
00113 PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC qt_glGetFramebufferAttachmentParameterivEXT;
00114 PFNGLGENERATEMIPMAPEXTPROC qt_glGenerateMipmapEXT;
00115
00116 #define glIsRenderbufferEXT qt_glIsRenderbufferEXT
00117 #define glBindRenderbufferEXT qt_glBindRenderbufferEXT
00118 #define glDeleteRenderbuffersEXT qt_glDeleteRenderbuffersEXT
00119 #define glGenRenderbuffersEXT qt_glGenRenderbuffersEXT
00120 #define glRenderbufferStorageEXT qt_glRenderbufferStorageEXT
00121 #define glGetRenderbufferParameterivEXT qt_glGetRenderbufferParameterivEXT
00122 #define glIsFramebufferEXT qt_glIsFramebufferEXT
00123 #define glBindFramebufferEXT qt_glBindFramebufferEXT
00124 #define glDeleteFramebuffersEXT qt_glDeleteFramebuffersEXT
00125 #define glGenFramebuffersEXT qt_glGenFramebuffersEXT
00126 #define glCheckFramebufferStatusEXT qt_glCheckFramebufferStatusEXT
00127 #define glFramebufferTexture1DEXT qt_glFramebufferTexture1DEXT
00128 #define glFramebufferTexture2DEXT qt_glFramebufferTexture2DEXT
00129 #define glFramebufferTexture3DEXT qt_glFramebufferTexture3DEXT
00130 #define glFramebufferRenderbufferEXT qt_glFramebufferRenderbufferEXT
00131 #define glGetFramebufferAttachmentParameterivEXT qt_glGetFramebufferAttachmentParameterivEXT
00132 #define glGenerateMipmapEXT qt_glGenerateMipmapEXT
00133
00134 static bool qt_resolve_framebufferobject_extensions(QGLContext *)
00135 {
00136 static bool resolved = false;
00137 if (resolved && qt_glIsRenderbufferEXT)
00138 return true;
00139 else if (resolved)
00140 return false;
00141
00142 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
00143 QLibrary lib(QLatin1String("GL"));
00144 #else // Q_WS_MAC
00145 QLibrary lib(QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"));
00146 #endif
00147
00148 qt_glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) lib.resolve("glIsRenderbufferEXT");
00149 qt_glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) lib.resolve("glBindRenderbufferEXT");
00150 qt_glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) lib.resolve("glDeleteRenderbuffersEXT");
00151 qt_glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) lib.resolve("glGenRenderbuffersEXT");
00152 qt_glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) lib.resolve("glRenderbufferStorageEXT");
00153 qt_glGetRenderbufferParameterivEXT =
00154 (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) lib.resolve("glGetRenderbufferParameterivEXT");
00155 qt_glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) lib.resolve("glIsFramebufferEXT");
00156 qt_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) lib.resolve("glBindFramebufferEXT");
00157 qt_glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) lib.resolve("glDeleteFramebuffersEXT");
00158 qt_glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) lib.resolve("glGenFramebuffersEXT");
00159 qt_glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) lib.resolve("glCheckFramebufferStatusEXT");
00160 qt_glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) lib.resolve("glFramebufferTexture1DEXT");
00161 qt_glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) lib.resolve("glFramebufferTexture2DEXT");
00162 qt_glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) lib.resolve("glFramebufferTexture3DEXT");
00163 qt_glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) lib.resolve("glFramebufferRenderbufferEXT");
00164 qt_glGetFramebufferAttachmentParameterivEXT =
00165 (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) lib.resolve("glGetFramebufferAttachmentParameterivEXT");
00166 qt_glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) lib.resolve("glGenerateMipmapEXT");
00167 resolved = true;
00168 return qt_glIsRenderbufferEXT;
00169 }
00170 #elif defined(Q_WS_WIN)
00171
00172 #define QGL_FUNC_CONTEXT QGLContext *ctx = d_ptr->ctx;
00173
00174 #define glIsRenderbufferEXT ctx->d_ptr->qt_glIsRenderbufferEXT
00175 #define glBindRenderbufferEXT ctx->d_ptr->qt_glBindRenderbufferEXT
00176 #define glDeleteRenderbuffersEXT ctx->d_ptr->qt_glDeleteRenderbuffersEXT
00177 #define glGenRenderbuffersEXT ctx->d_ptr->qt_glGenRenderbuffersEXT
00178 #define glRenderbufferStorageEXT ctx->d_ptr->qt_glRenderbufferStorageEXT
00179 #define glGetRenderbufferParameterivEXT ctx->d_ptr->qt_glGetRenderbufferParameterivEXT
00180 #define glIsFramebufferEXT ctx->d_ptr->qt_glIsFramebufferEXT
00181 #define glBindFramebufferEXT ctx->d_ptr->qt_glBindFramebufferEXT
00182 #define glDeleteFramebuffersEXT ctx->d_ptr->qt_glDeleteFramebuffersEXT
00183 #define glGenFramebuffersEXT ctx->d_ptr->qt_glGenFramebuffersEXT
00184 #define glCheckFramebufferStatusEXT ctx->d_ptr->qt_glCheckFramebufferStatusEXT
00185 #define glFramebufferTexture1DEXT ctx->d_ptr->qt_glFramebufferTexture1DEXT
00186 #define glFramebufferTexture2DEXT ctx->d_ptr->qt_glFramebufferTexture2DEXT
00187 #define glFramebufferTexture3DEXT ctx->d_ptr->qt_glFramebufferTexture3DEXT
00188 #define glFramebufferRenderbufferEXT ctx->d_ptr->qt_glFramebufferRenderbufferEXT
00189 #define glGetFramebufferAttachmentParameterivEXT ctx->d_ptr->qt_glGetFramebufferAttachmentParameterivEXT
00190 #define glGenerateMipmapEXT ctx->d_ptr->qt_glGenerateMipmapEXT
00191
00192 bool qt_resolve_framebufferobject_extensions(QGLContext *ctx)
00193 {
00194 if (glIsRenderbufferEXT != 0)
00195 return true;
00196
00197 if (ctx == 0) {
00198 qWarning("QGLFramebufferObject: Unable to resolve framebuffer object extensions -"
00199 " make sure there is a current context when creating the framebuffer object.");
00200 return false;
00201 }
00202
00203 glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) wglGetProcAddress("glIsRenderbufferEXT");
00204 glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) wglGetProcAddress("glBindRenderbufferEXT");
00205 glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) wglGetProcAddress("glDeleteRenderbuffersEXT");
00206 glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) wglGetProcAddress("glGenRenderbuffersEXT");
00207 glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) wglGetProcAddress("glRenderbufferStorageEXT");
00208 glGetRenderbufferParameterivEXT =
00209 (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) wglGetProcAddress("glGetRenderbufferParameterivEXT");
00210 glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) wglGetProcAddress("glIsFramebufferEXT");
00211 glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT");
00212 glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) wglGetProcAddress("glDeleteFramebuffersEXT");
00213 glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT");
00214 glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) wglGetProcAddress("glCheckFramebufferStatusEXT");
00215 glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) wglGetProcAddress("glFramebufferTexture1DEXT");
00216 glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) wglGetProcAddress("glFramebufferTexture2DEXT");
00217 glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) wglGetProcAddress("glFramebufferTexture3DEXT");
00218 glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) wglGetProcAddress("glFramebufferRenderbufferEXT");
00219 glGetFramebufferAttachmentParameterivEXT =
00220 (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT");
00221 glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) wglGetProcAddress("glGenerateMipmapEXT");
00222 return glIsRenderbufferEXT;
00223 }
00224 #endif
00225
00226 #define QT_CHECK_GLERROR() \
00227 { \
00228 GLenum err = glGetError(); \
00229 if (err != GL_NO_ERROR) { \
00230 qDebug("[%s line %d] GL Error: %d", \
00231 __FILE__, __LINE__, err); \
00232 } \
00233 }
00234
00235 class QGLFramebufferObjectPrivate
00236 {
00237 public:
00238 QGLFramebufferObjectPrivate() : valid(false), ctx(0) {}
00239 ~QGLFramebufferObjectPrivate() {}
00240
00241 void init(const QSize& sz, GLenum texture_target);
00242 bool checkFramebufferStatus() const;
00243 GLuint texture;
00244 GLuint fbo;
00245 GLuint depth_buffer;
00246 GLenum target;
00247 QSize size;
00248 uint valid : 1;
00249 QGLContext *ctx;
00250 };
00251
00252 bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
00253 {
00254 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00255 switch(status) {
00256 case GL_NO_ERROR:
00257 case GL_FRAMEBUFFER_COMPLETE_EXT:
00258 return true;
00259 break;
00260 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00261 qDebug("QGLFramebufferObject: Unsupported framebuffer format.");
00262 break;
00263 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
00264 qDebug("QGLFramebufferObject: Framebuffer incomplete attachment.");
00265 break;
00266 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
00267 qDebug("QGLFramebufferObject: Framebuffer incomplete, missing attachment.");
00268 break;
00269 #ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
00270 case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
00271 qDebug("QGLFramebufferObject: Framebuffer incomplete, duplicate attachment.");
00272 break;
00273 #endif
00274 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00275 qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same dimensions.");
00276 break;
00277 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00278 qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same format.");
00279 break;
00280 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
00281 qDebug("QGLFramebufferObject: Framebuffer incomplete, missing draw buffer.");
00282 break;
00283 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
00284 qDebug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer.");
00285 break;
00286 default:
00287 qDebug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status;
00288 break;
00289 }
00290 return false;
00291 }
00292
00293 void QGLFramebufferObjectPrivate::init(const QSize &sz, GLenum texture_target)
00294 {
00295 ctx = const_cast<QGLContext *>(QGLContext::currentContext());
00296 bool ext_detected = (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject);
00297 if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
00298 return;
00299
00300 size = sz;
00301 target = texture_target;
00302
00303
00304 glGetError();
00305 glGenFramebuffersEXT(1, &fbo);
00306 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
00307
00308 QT_CHECK_GLERROR();
00309
00310 glGenTextures(1, &texture);
00311 glBindTexture(target, texture);
00312 #ifndef Q_WS_QWS
00313 glTexImage2D(target, 0, GL_RGBA8, size.width(), size.height(), 0,
00314 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
00315 #else
00316 glTexImage2D(target, 0, GL_RGBA, size.width(), size.height(), 0,
00317 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
00318 #endif
00319 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00320 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00321 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00322 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00323
00324 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
00325 target, texture, 0);
00326
00327 QT_CHECK_GLERROR();
00328 valid = checkFramebufferStatus();
00329
00330 #ifdef DEPTH_BUFFER
00331
00332 glGenRenderbuffersEXT(1, &depth_buffer);
00333 Q_ASSERT(!glIsRenderbufferEXT(depth_buffer));
00334 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_buffer);
00335 Q_ASSERT(glIsRenderbufferEXT(depth_buffer));
00336 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
00337 int i = 0;
00338 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
00339 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
00340 GL_RENDERBUFFER_EXT, depth_buffer);
00341
00342 #endif
00343 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00344 checkFramebufferStatus();
00345 QT_CHECK_GLERROR();
00346 }
00347
00422 QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
00423 : d_ptr(new QGLFramebufferObjectPrivate)
00424 {
00425 Q_D(QGLFramebufferObject);
00426 d->init(size, target);
00427 }
00428
00429
00437 QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target)
00438 : d_ptr(new QGLFramebufferObjectPrivate)
00439 {
00440 Q_D(QGLFramebufferObject);
00441 d->init(QSize(width, height), target);
00442 }
00443
00449 QGLFramebufferObject::~QGLFramebufferObject()
00450 {
00451 Q_D(QGLFramebufferObject);
00452 QGL_FUNC_CONTEXT;
00453
00454 if (isValid()) {
00455 glDeleteTextures(1, &d->texture);
00456 #ifdef DEPTH_BUFFER
00457 glDeleteRenderbuffersEXT(1, &d->depth_buffer);
00458 #endif
00459 glDeleteFramebuffersEXT(1, &d->fbo);
00460 }
00461 delete d_ptr;
00462 }
00463
00474 bool QGLFramebufferObject::isValid() const
00475 {
00476 Q_D(const QGLFramebufferObject);
00477 return d->valid;
00478 }
00479
00487 bool QGLFramebufferObject::bind()
00488 {
00489 if (!isValid())
00490 return false;
00491 Q_D(QGLFramebufferObject);
00492 QGL_FUNC_CONTEXT;
00493 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, d->fbo);
00494 return d->checkFramebufferStatus();
00495 }
00496
00504 bool QGLFramebufferObject::release()
00505 {
00506 if (!isValid())
00507 return false;
00508 Q_D(QGLFramebufferObject);
00509 QGL_FUNC_CONTEXT;
00510 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00511 return d->checkFramebufferStatus();
00512 }
00513
00521 GLuint QGLFramebufferObject::texture() const
00522 {
00523 Q_D(const QGLFramebufferObject);
00524 return d->texture;
00525 }
00526
00533 QSize QGLFramebufferObject::size() const
00534 {
00535 Q_D(const QGLFramebufferObject);
00536 return d->size;
00537 }
00538
00544 QImage QGLFramebufferObject::toImage() const
00545 {
00546 Q_D(const QGLFramebufferObject);
00547 if (!d->valid)
00548 return QImage();
00549
00550 const_cast<QGLFramebufferObject *>(this)->bind();
00551 QImage::Format image_format = QImage::Format_RGB32;
00552 if (d->ctx->format().alpha())
00553 image_format = QImage::Format_ARGB32_Premultiplied;
00554 QImage img(d->size, image_format);
00555 int w = d->size.width();
00556 int h = d->size.height();
00557
00558 glReadPixels(0, 0, d->size.width(), d->size.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
00559 if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
00560
00561 uint *p = (uint*)img.bits();
00562 uint *end = p + w*h;
00563 if (1) {
00564 while (p < end) {
00565 uint a = *p << 24;
00566 *p = (*p >> 8) | a;
00567 p++;
00568 }
00569 } else {
00570 while (p < end) {
00571 *p = 0xFF000000 | (*p>>8);
00572 ++p;
00573 }
00574 }
00575 } else {
00576
00577 img = img.rgbSwapped();
00578 }
00579 const_cast<QGLFramebufferObject *>(this)->release();
00580 return img.mirrored();
00581 }
00582
00583 Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine)
00584
00585
00586 QPaintEngine *QGLFramebufferObject::paintEngine() const
00587 {
00588 return qt_buffer_paintengine();
00589 }
00590
00597 bool QGLFramebufferObject::hasOpenGLFramebufferObjects()
00598 {
00599 QGLWidget dmy;
00600 return (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject);
00601 }
00602
00603 extern int qt_defaultDpi();
00604
00606 int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
00607 {
00608 Q_D(const QGLFramebufferObject);
00609
00610 float dpmx = qt_defaultDpi()*100./2.54;
00611 float dpmy = qt_defaultDpi()*100./2.54;
00612 int w = d->size.width();
00613 int h = d->size.height();
00614 switch (metric) {
00615 case PdmWidth:
00616 return w;
00617
00618 case PdmHeight:
00619 return h;
00620
00621 case PdmWidthMM:
00622 return qRound(w * 1000 / dpmx);
00623
00624 case PdmHeightMM:
00625 return qRound(h * 1000 / dpmy);
00626
00627 case PdmNumColors:
00628 return 0;
00629
00630 case PdmDepth:
00631 return 32;
00632
00633 case PdmDpiX:
00634 return (int)(dpmx * 0.0254);
00635
00636 case PdmDpiY:
00637 return (int)(dpmy * 0.0254);
00638
00639 case PdmPhysicalDpiX:
00640 return (int)(dpmx * 0.0254);
00641
00642 case PdmPhysicalDpiY:
00643 return (int)(dpmy * 0.0254);
00644
00645 default:
00646 qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric);
00647 break;
00648 }
00649 return 0;
00650 }
00651
00661 GLuint QGLFramebufferObject::handle() const
00662 {
00663 Q_D(const QGLFramebufferObject);
00664 return d->fbo;
00665 }
00666