Qt 4.8
qglframebufferobject.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtOpenGL module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qglframebufferobject.h"
43 #include "qglframebufferobject_p.h"
44 
45 #include <qdebug.h>
46 #include <private/qgl_p.h>
47 #include <private/qfont_p.h>
48 #if !defined(QT_OPENGL_ES_1)
49 #include <private/qpaintengineex_opengl2_p.h>
50 #endif
51 
52 #ifndef QT_OPENGL_ES_2
53 #include <private/qpaintengine_opengl_p.h>
54 #endif
55 
56 #include <qglframebufferobject.h>
57 #include <qlibrary.h>
58 #include <qimage.h>
59 
61 
62 extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
63 
64 #define QGL_FUNC_CONTEXT const QGLContext *ctx = d_ptr->fbo_guard.context();
65 #define QGL_FUNCP_CONTEXT const QGLContext *ctx = fbo_guard.context();
66 
67 #ifndef QT_NO_DEBUG
68 #define QT_RESET_GLERROR() \
69 { \
70  while (glGetError() != GL_NO_ERROR) {} \
71 }
72 #define QT_CHECK_GLERROR() \
73 { \
74  GLenum err = glGetError(); \
75  if (err != GL_NO_ERROR) { \
76  qDebug("[%s line %d] GL Error: %d", \
77  __FILE__, __LINE__, (int)err); \
78  } \
79 }
80 #else
81 #define QT_RESET_GLERROR() {}
82 #define QT_CHECK_GLERROR() {}
83 #endif
84 
117 {
118  if (d->ref != 1) {
121  if (!d->ref.deref())
122  delete d;
123  d = newd;
124  }
125 }
126 
139 {
141 }
142 
148 {
149  d = other.d;
150  d->ref.ref();
151 }
152 
158 {
159  if (d != other.d) {
160  other.d->ref.ref();
161  if (!d->ref.deref())
162  delete d;
163  d = other.d;
164  }
165  return *this;
166 }
167 
172 {
173  if (!d->ref.deref())
174  delete d;
175 }
176 
191 {
192  detach();
193  d->samples = samples;
194 }
195 
204 {
205  return d->samples;
206 }
207 
226 {
227  detach();
228  d->mipmap = enabled;
229 }
230 
242 {
243  return d->mipmap;
244 }
245 
252 {
253  detach();
255 }
256 
264 {
265  return d->attachment;
266 }
267 
275 {
276  detach();
277  d->target = target;
278 }
279 
288 {
289  return d->target;
290 }
291 
300 {
301  detach();
303 }
304 
314 {
315  return d->internal_format;
316 }
317 
318 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
319 
320 void QGLFramebufferObjectFormat::setTextureTarget(QMacCompatGLenum target)
321 {
322  detach();
323  d->target = target;
324 }
325 
328 {
329  detach();
331 }
332 #endif
333 
339 {
340  if (d == other.d)
341  return true;
342  else
343  return d->equals(other.d);
344 }
345 
351 {
352  return !(*this == other);
353 }
354 
357 {
358  fbo = f;
359  m_thisFBO = fbo->d_func()->fbo(); // This shouldn't be needed
360 
361  // The context that the fbo was created in may not have depth
362  // and stencil buffers, but the fbo itself might.
363  fboFormat = QGLContext::currentContext()->format();
364  if (attachment == QGLFramebufferObject::CombinedDepthStencil) {
365  fboFormat.setDepth(true);
366  fboFormat.setStencil(true);
367  } else if (attachment == QGLFramebufferObject::Depth) {
368  fboFormat.setDepth(true);
369  fboFormat.setStencil(false);
370  } else {
371  fboFormat.setDepth(false);
372  fboFormat.setStencil(false);
373  }
374 
376  reqAlpha = (format != GL_RGB
377 #ifndef QT_OPENGL_ES
378  && format != GL_RGB5 && format != GL_RGB8
379 #endif
380  );
381 }
382 
384 {
385  QGLContext *fboContext = const_cast<QGLContext *>(fbo->d_ptr->fbo_guard.context());
386  QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext());
387 
388  if (QGLContextPrivate::contextGroup(fboContext) == QGLContextPrivate::contextGroup(currentContext))
389  return currentContext;
390  else
391  return fboContext;
392 }
393 
395 {
397  if (!ctx)
398  return false; // Context no longer exists.
400  switch(status) {
401  case GL_NO_ERROR:
403  return true;
404  break;
406  qDebug("QGLFramebufferObject: Unsupported framebuffer format.");
407  break;
409  qDebug("QGLFramebufferObject: Framebuffer incomplete attachment.");
410  break;
412  qDebug("QGLFramebufferObject: Framebuffer incomplete, missing attachment.");
413  break;
414 #ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
416  qDebug("QGLFramebufferObject: Framebuffer incomplete, duplicate attachment.");
417  break;
418 #endif
420  qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same dimensions.");
421  break;
423  qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same format.");
424  break;
426  qDebug("QGLFramebufferObject: Framebuffer incomplete, missing draw buffer.");
427  break;
429  qDebug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer.");
430  break;
432  qDebug("QGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel.");
433  break;
434  default:
435  qDebug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status;
436  break;
437  }
438  return false;
439 }
440 
443  GLenum texture_target, GLenum internal_format,
444  GLint samples, bool mipmap)
445 {
447  fbo_guard.setContext(ctx);
448 
450  if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
451  return;
452 
453  size = sz;
454  target = texture_target;
455  // texture dimensions
456 
457  QT_RESET_GLERROR(); // reset error state
458  GLuint fbo = 0;
459  glGenFramebuffers(1, &fbo);
461  fbo_guard.setId(fbo);
462 
463  glDevice.setFBO(q, attachment);
464 
466  // init texture
467  if (samples == 0) {
468  glGenTextures(1, &texture);
469  glBindTexture(target, texture);
470  glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
471  GL_RGBA, GL_UNSIGNED_BYTE, NULL);
472  if (mipmap)
474 #ifndef QT_OPENGL_ES
475  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
476  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
477  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
478  glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
479 #else
480  glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
481  glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
482  glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
483  glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
484 #endif
486  target, texture, 0);
487 
489  valid = checkFramebufferStatus();
490  glBindTexture(target, 0);
491 
492  color_buffer = 0;
493  } else {
494  mipmap = false;
495  GLint maxSamples;
496  glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples);
497 
498  samples = qBound(0, int(samples), int(maxSamples));
499 
500  glGenRenderbuffers(1, &color_buffer);
502  if (glRenderbufferStorageMultisampleEXT && samples > 0) {
504  internal_format, size.width(), size.height());
505  } else {
506  samples = 0;
508  size.width(), size.height());
509  }
510 
512  GL_RENDERBUFFER_EXT, color_buffer);
513 
515  valid = checkFramebufferStatus();
516 
517  if (valid)
519  }
520 
521  // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
522  // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer
523  // might not be supported while separate buffers are, according to QTBUG-12861.
524 
527  // depth and stencil buffer needs another extension
528  glGenRenderbuffers(1, &depth_buffer);
529  Q_ASSERT(!glIsRenderbuffer(depth_buffer));
531  Q_ASSERT(glIsRenderbuffer(depth_buffer));
532  if (samples != 0 && glRenderbufferStorageMultisampleEXT)
534  GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
535  else
537  GL_DEPTH24_STENCIL8_EXT, size.width(), size.height());
538 
539  stencil_buffer = depth_buffer;
541  GL_RENDERBUFFER_EXT, depth_buffer);
543  GL_RENDERBUFFER_EXT, stencil_buffer);
544 
545  valid = checkFramebufferStatus();
546  if (!valid) {
547  glDeleteRenderbuffers(1, &depth_buffer);
548  stencil_buffer = depth_buffer = 0;
549  }
550  }
551 
552  if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil
553  || (attachment == QGLFramebufferObject::Depth)))
554  {
555  glGenRenderbuffers(1, &depth_buffer);
556  Q_ASSERT(!glIsRenderbuffer(depth_buffer));
558  Q_ASSERT(glIsRenderbuffer(depth_buffer));
559  if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
560 #ifdef QT_OPENGL_ES
563  GL_DEPTH_COMPONENT24_OES, size.width(), size.height());
564  } else {
566  GL_DEPTH_COMPONENT16, size.width(), size.height());
567  }
568 #else
570  GL_DEPTH_COMPONENT, size.width(), size.height());
571 #endif
572  } else {
573 #ifdef QT_OPENGL_ES
576  size.width(), size.height());
577  } else {
579  size.width(), size.height());
580  }
581 #else
582  glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, size.width(), size.height());
583 #endif
584  }
586  GL_RENDERBUFFER_EXT, depth_buffer);
587  valid = checkFramebufferStatus();
588  if (!valid) {
589  glDeleteRenderbuffers(1, &depth_buffer);
590  depth_buffer = 0;
591  }
592  }
593 
594  if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) {
595  glGenRenderbuffers(1, &stencil_buffer);
596  Q_ASSERT(!glIsRenderbuffer(stencil_buffer));
597  glBindRenderbuffer(GL_RENDERBUFFER_EXT, stencil_buffer);
598  Q_ASSERT(glIsRenderbuffer(stencil_buffer));
599  if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
600 #ifdef QT_OPENGL_ES
602  GL_STENCIL_INDEX8_EXT, size.width(), size.height());
603 #else
605  GL_STENCIL_INDEX, size.width(), size.height());
606 #endif
607  } else {
608 #ifdef QT_OPENGL_ES
610  size.width(), size.height());
611 #else
613  size.width(), size.height());
614 #endif
615  }
617  GL_RENDERBUFFER_EXT, stencil_buffer);
618  valid = checkFramebufferStatus();
619  if (!valid) {
620  glDeleteRenderbuffers(1, &stencil_buffer);
621  stencil_buffer = 0;
622  }
623  }
624 
625  // The FBO might have become valid after removing the depth or stencil buffer.
626  valid = checkFramebufferStatus();
627 
628  if (depth_buffer && stencil_buffer) {
630  } else if (depth_buffer) {
631  fbo_attachment = QGLFramebufferObject::Depth;
632  } else {
633  fbo_attachment = QGLFramebufferObject::NoAttachment;
634  }
635 
637  if (!valid) {
638  if (color_buffer)
639  glDeleteRenderbuffers(1, &color_buffer);
640  else
641  glDeleteTextures(1, &texture);
642  if (depth_buffer)
643  glDeleteRenderbuffers(1, &depth_buffer);
644  if (stencil_buffer && depth_buffer != stencil_buffer)
645  glDeleteRenderbuffers(1, &stencil_buffer);
646  glDeleteFramebuffers(1, &fbo);
647  fbo_guard.setId(0);
648  }
650 
651  format.setTextureTarget(target);
652  format.setSamples(int(samples));
653  format.setAttachment(fbo_attachment);
654  format.setInternalTextureFormat(internal_format);
655  format.setMipmap(mipmap);
656 }
657 
795  : d_ptr(new QGLFramebufferObjectPrivate)
796 {
798  d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
799 }
800 
801 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
802 
803 QGLFramebufferObject::QGLFramebufferObject(const QSize &size, QMacCompatGLenum target)
805 {
807  d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
808 }
809 #endif
810 
823 {
825  d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
826 }
827 
839 {
841  d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(),
842  format.samples(), format.mipmap());
843 }
844 
856 {
858  d->init(this, QSize(width, height), format.attachment(), format.textureTarget(),
859  format.internalTextureFormat(), format.samples(), format.mipmap());
860 }
861 
862 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
863 
864 QGLFramebufferObject::QGLFramebufferObject(int width, int height, QMacCompatGLenum target)
866 {
868  d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
869 }
870 #endif
871 
889  GLenum target, GLenum internal_format)
891 {
893  d->init(this, QSize(width, height), attachment, target, internal_format);
894 }
895 
896 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
897 
899  QMacCompatGLenum target, QMacCompatGLenum internal_format)
901 {
903  d->init(this, QSize(width, height), attachment, target, internal_format);
904 }
905 #endif
906 
924  GLenum target, GLenum internal_format)
926 {
928  d->init(this, size, attachment, target, internal_format);
929 }
930 
931 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
932 
934  QMacCompatGLenum target, QMacCompatGLenum internal_format)
936 {
938  d->init(this, size, attachment, target, internal_format);
939 }
940 #endif
941 
951 {
954 
955  delete d->engine;
956 
957  if (isValid() && ctx) {
958  QGLShareContextScope scope(ctx);
959  if (d->texture)
960  glDeleteTextures(1, &d->texture);
961  if (d->color_buffer)
962  glDeleteRenderbuffers(1, &d->color_buffer);
963  if (d->depth_buffer)
964  glDeleteRenderbuffers(1, &d->depth_buffer);
965  if (d->stencil_buffer && d->stencil_buffer != d->depth_buffer)
966  glDeleteRenderbuffers(1, &d->stencil_buffer);
967  GLuint fbo = d->fbo();
968  glDeleteFramebuffers(1, &fbo);
969  }
970 }
971 
994 {
995  Q_D(const QGLFramebufferObject);
996  return d->valid && d->fbo_guard.context();
997 }
998 
1012 {
1013  if (!isValid())
1014  return false;
1017  if (!ctx)
1018  return false; // Context no longer exists.
1019  const QGLContext *current = QGLContext::currentContext();
1020 #ifdef QT_DEBUG
1021  if (!current ||
1023  {
1024  qWarning("QGLFramebufferObject::bind() called from incompatible context");
1025  }
1026 #endif
1028  d->valid = d->checkFramebufferStatus();
1029  if (d->valid && current)
1030  current->d_ptr->current_fbo = d->fbo();
1031  return d->valid;
1032 }
1033 
1047 {
1048  if (!isValid())
1049  return false;
1051  if (!ctx)
1052  return false; // Context no longer exists.
1053 
1054  const QGLContext *current = QGLContext::currentContext();
1055 
1056 #ifdef QT_DEBUG
1057  if (!current ||
1059  {
1060  qWarning("QGLFramebufferObject::release() called from incompatible context");
1061  }
1062 #endif
1063 
1064  if (current) {
1065  current->d_ptr->current_fbo = current->d_ptr->default_fbo;
1067  }
1068 
1069  return true;
1070 }
1071 
1086 {
1087  Q_D(const QGLFramebufferObject);
1088  return d->texture;
1089 }
1090 
1101 {
1102  Q_D(const QGLFramebufferObject);
1103  return d->size;
1104 }
1105 
1110 {
1111  Q_D(const QGLFramebufferObject);
1112  return d->format;
1113 }
1114 
1124 {
1125  Q_D(const QGLFramebufferObject);
1126  if (!d->valid)
1127  return QImage();
1128 
1129  // qt_gl_read_framebuffer doesn't work on a multisample FBO
1130  if (format().samples() != 0) {
1132 
1133  QRect rect(QPoint(0, 0), size());
1134  blitFramebuffer(&temp, rect, const_cast<QGLFramebufferObject *>(this), rect);
1135 
1136  return temp.toImage();
1137  }
1138 
1139  bool wasBound = isBound();
1140  if (!wasBound)
1141  const_cast<QGLFramebufferObject *>(this)->bind();
1142  QImage image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat() != GL_RGB, true);
1143  if (!wasBound)
1144  const_cast<QGLFramebufferObject *>(this)->release();
1145 
1146  return image;
1147 }
1148 
1149 #if !defined(QT_OPENGL_ES_1)
1151 #endif
1152 
1153 #ifndef QT_OPENGL_ES_2
1155 #endif
1156 
1159 {
1160  Q_D(const QGLFramebufferObject);
1161  if (d->engine)
1162  return d->engine;
1163 
1164 #if !defined(QT_OPENGL_ES_1)
1165 #if !defined (QT_OPENGL_ES_2)
1166  if (qt_gl_preferGL2Engine()) {
1167 #endif
1168  QPaintEngine *engine = qt_buffer_2_engine()->engine();
1169  if (engine->isActive() && engine->paintDevice() != this) {
1170  d->engine = new QGL2PaintEngineEx;
1171  return d->engine;
1172  }
1173  return engine;
1174 #if !defined (QT_OPENGL_ES_2)
1175  }
1176 #endif
1177 #endif
1178 
1179 #if !defined(QT_OPENGL_ES_2)
1180  QPaintEngine *engine = qt_buffer_engine()->engine();
1181  if (engine->isActive() && engine->paintDevice() != this) {
1182  d->engine = new QOpenGLPaintEngine;
1183  return d->engine;
1184  }
1185  return engine;
1186 #endif
1187 }
1188 
1203 {
1205 
1206  if (ctx) {
1208  if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
1209  return false;
1210 
1211  ctx->d_ptr->current_fbo = ctx->d_ptr->default_fbo;
1213 #ifdef QT_DEBUG
1214  } else {
1215  qWarning("QGLFramebufferObject::bindDefault() called without current context.");
1216 #endif
1217  }
1218 
1219  return ctx != 0;
1220 }
1221 
1232 {
1234 }
1235 
1250 void QGLFramebufferObject::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
1251 {
1252  const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
1253 }
1254 
1255 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
1256 
1257 void QGLFramebufferObject::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
1258 {
1259  const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
1260 }
1261 #endif
1262 
1276 void QGLFramebufferObject::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
1277 {
1278  const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
1279 }
1280 
1281 #ifdef Q_MAC_COMPAT_GL_FUNCTIONS
1282 
1283 void QGLFramebufferObject::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
1284 {
1285  const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
1286 }
1287 #endif
1288 
1291 {
1292  Q_D(const QGLFramebufferObject);
1293 
1294  float dpmx = qt_defaultDpiX()*100./2.54;
1295  float dpmy = qt_defaultDpiY()*100./2.54;
1296  int w = d->size.width();
1297  int h = d->size.height();
1298  switch (metric) {
1299  case PdmWidth:
1300  return w;
1301 
1302  case PdmHeight:
1303  return h;
1304 
1305  case PdmWidthMM:
1306  return qRound(w * 1000 / dpmx);
1307 
1308  case PdmHeightMM:
1309  return qRound(h * 1000 / dpmy);
1310 
1311  case PdmNumColors:
1312  return 0;
1313 
1314  case PdmDepth:
1315  return 32;//d->depth;
1316 
1317  case PdmDpiX:
1318  return qRound(dpmx * 0.0254);
1319 
1320  case PdmDpiY:
1321  return qRound(dpmy * 0.0254);
1322 
1323  case PdmPhysicalDpiX:
1324  return qRound(dpmx * 0.0254);
1325 
1326  case PdmPhysicalDpiY:
1327  return qRound(dpmy * 0.0254);
1328 
1329  default:
1330  qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric);
1331  break;
1332  }
1333  return 0;
1334 }
1335 
1349 {
1350  Q_D(const QGLFramebufferObject);
1351  return d->fbo();
1352 }
1353 
1365 {
1366  Q_D(const QGLFramebufferObject);
1367  if (d->valid)
1368  return d->fbo_attachment;
1369  return NoAttachment;
1370 }
1371 
1383 {
1384  Q_D(const QGLFramebufferObject);
1385  const QGLContext *current = QGLContext::currentContext();
1386  return current ? current->d_ptr->current_fbo == d->fbo() : false;
1387 }
1388 
1403 {
1405 }
1406 
1443  QGLFramebufferObject *source, const QRect &sourceRect,
1444  GLbitfield buffers,
1445  GLenum filter)
1446 {
1448  return;
1449 
1451  if (!ctx)
1452  return;
1453 
1454  const int height = ctx->device()->height();
1455 
1456  const int sh = source ? source->height() : height;
1457  const int th = target ? target->height() : height;
1458 
1459  const int sx0 = sourceRect.left();
1460  const int sx1 = sourceRect.left() + sourceRect.width();
1461  const int sy0 = sh - (sourceRect.top() + sourceRect.height());
1462  const int sy1 = sh - sourceRect.top();
1463 
1464  const int tx0 = targetRect.left();
1465  const int tx1 = targetRect.left() + targetRect.width();
1466  const int ty0 = th - (targetRect.top() + targetRect.height());
1467  const int ty1 = th - targetRect.top();
1468 
1469  glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, source ? source->handle() : 0);
1470  glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, target ? target->handle() : 0);
1471 
1472  glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
1473  tx0, ty0, tx1, ty1,
1474  buffers, filter);
1475 
1477 }
1478 
double d
Definition: qnumeric_p.h:62
#define GL_RENDERBUFFER_SAMPLES_EXT
bool mipmap() const
Returns true if mipmapping is enabled.
static bool hasOpenGLFramebufferObjects()
Returns true if the OpenGL GL_EXT_framebuffer_object extension is present on this system; otherwise r...
bool equals(const QGLFramebufferObjectFormatPrivate *other)
QPaintEngine * paintEngine() const
Reimplemented Function
QSize size() const
Returns the size of the texture attached to this framebuffer object.
int metric(PaintDeviceMetric metric) const
Reimplemented Function
~QGLFramebufferObjectFormat()
Destroys the QGLFramebufferObjectFormat.
QGLFramebufferObject(const QSize &size, GLenum target=GL_TEXTURE_2D)
Constructs an OpenGL framebuffer object and binds a 2D GL texture to the buffer of the size size...
GLuint texture() const
Returns the texture id for the texture attached as the default rendering target in this framebuffer o...
int samples() const
Returns the number of samples per pixel if a framebuffer object is a multisample framebuffer object...
QScopedPointer< QGLContextPrivate > d_ptr
Definition: qgl.h:430
void setAttachment(QGLFramebufferObject::Attachment attachment)
Sets the attachment configuration of a framebuffer object to attachment.
#define GL_RGB
#define GL_CLAMP_TO_EDGE
Definition: glfunctions.h:62
#define GL_TEXTURE_MIN_FILTER
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QGLFramebufferObjectFormat & operator=(const QGLFramebufferObjectFormat &other)
Assigns other to this object.
QPaintDevice * paintDevice() const
Returns the device that this engine is painting on, if painting is active; otherwise returns 0...
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
static bool bindDefault()
Switches rendering back to the default, windowing system provided framebuffer.
#define GL_STENCIL_INDEX
#define GL_DEPTH_COMPONENT
Q_GUI_EXPORT int qt_defaultDpiY()
Definition: qfont.cpp:201
QImage toImage() const
Returns the contents of this framebuffer object as a QImage.
The QGLFramebufferObject class encapsulates an OpenGL framebuffer object.
bool isValid() const
Returns true if the framebuffer object is valid.
int height() const
Definition: qpaintdevice.h:92
#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
void setInternalTextureFormat(GLenum internalTextureFormat)
Sets the internal format of a framebuffer object&#39;s texture or multisample framebuffer object&#39;s color ...
Q_GUI_EXPORT int qt_defaultDpiX()
Definition: qfont.cpp:162
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
bool operator!=(const QGLFramebufferObjectFormat &other) const
Returns false if all the options of this framebuffer object format are the same as other; otherwise r...
#define glGenRenderbuffers
QGLFramebufferObject::Attachment attachment
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
bool qt_resolve_framebufferobject_extensions(QGLContext *ctx)
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
#define GL_TEXTURE_WRAP_S
bool ref()
Atomically increments the value of this QAtomicInt.
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
#define GL_FRAMEBUFFER_EXT
#define GL_DEPTH24_STENCIL8_EXT
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define glBindFramebuffer
#define Q_D(Class)
Definition: qglobal.h:2482
#define glRenderbufferStorageMultisampleEXT
#define QT_RESET_GLERROR()
#define GL_TEXTURE_2D
Attachment
This enum type is used to configure the depth and stencil buffers attached to the framebuffer object ...
#define glDeleteRenderbuffers
#define GL_COLOR_ATTACHMENT0_EXT
static const QGLContext * currentContext()
Returns the current context, i.e.
Definition: qgl.cpp:3545
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
#define glBlitFramebufferEXT
Q_CORE_EXPORT void qDebug(const char *,...)
#define GL_STENCIL_ATTACHMENT_EXT
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
#define QT_CHECK_GLERROR()
int width() const
Definition: qpaintdevice.h:91
bool isActive() const
Returns true if the paint engine is actively drawing; otherwise returns false.
Definition: qpaintengine.h:154
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QGLFramebufferObject::Attachment attachment() const
Returns the configuration of the depth and stencil buffers attached to a framebuffer object...
QScopedPointer< QGLFramebufferObjectPrivate > d_ptr
QGLFormat format() const
Returns the frame buffer format that was obtained (this may be a subset of what was requested)...
Definition: qgl.cpp:3495
The QGLContext class encapsulates an OpenGL rendering context.
Definition: qgl.h:310
#define GL_DEPTH_COMPONENT16
#define glCheckFramebufferStatus
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT
#define GL_RENDERBUFFER_EXT
virtual QGLContext * context() const
#define glDeleteFramebuffers
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
#define glIsRenderbuffer
bool deref()
Atomically decrements the value of this QAtomicInt.
void setSamples(int samples)
Sets the number of samples per pixel for a multisample framebuffer object to samples.
QGLFramebufferObjectFormat format() const
Returns the format of this framebuffer object.
static void blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect, QGLFramebufferObject *source, const QRect &sourceRect, GLbitfield buffers=GL_COLOR_BUFFER_BIT, GLenum filter=GL_NEAREST)
Blits from the sourceRect rectangle in the source framebuffer object to the targetRect rectangle in t...
Q_CORE_EXPORT void qWarning(const char *,...)
#define glGenFramebuffers
GLenum internalTextureFormat() const
Returns the internal format of a framebuffer object&#39;s texture or multisample framebuffer object&#39;s col...
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
#define GL_DEPTH_ATTACHMENT_EXT
#define GL_FRAMEBUFFER_UNSUPPORTED_EXT
QPaintDevice * device() const
Returns the paint device set for this context.
Definition: qgl.cpp:3507
void setDepth(bool enable)
If enable is true enables the depth buffer; otherwise disables the depth buffer.
Definition: qgl.cpp:599
The QPaintEngine class provides an abstract definition of how QPainter draws to a given device on a g...
Definition: qpaintengine.h:90
#define glGetRenderbufferParameteriv
GLuint handle() const
Returns the GL framebuffer object handle for this framebuffer object (returned by the glGenFrameBuffe...
#define GL_DRAW_FRAMEBUFFER_EXT
#define glBindRenderbuffer
bool qt_gl_preferGL2Engine()
Definition: qgl.cpp:218
void setMipmap(bool enabled)
Enables mipmapping if enabled is true; otherwise disables it.
#define GL_READ_FRAMEBUFFER_EXT
#define DEFAULT_FORMAT
QImage qt_gl_read_framebuffer(const QSize &, bool, bool)
Definition: qgl.cpp:1860
void setTextureTarget(GLenum target)
Sets the texture target of the texture attached to a framebuffer object to target.
#define GL_TEXTURE_WRAP_T
GLuint current_fbo
Definition: qgl_p.h:456
static QGLContextGroup * contextGroup(const QGLContext *ctx)
Definition: qgl_p.h:464
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
#define GL_MAX_SAMPLES_EXT
#define GL_STENCIL_INDEX8_EXT
void init(QGLFramebufferObject *q, const QSize &sz, QGLFramebufferObject::Attachment attachment, GLenum internal_format, GLenum texture_target, GLint samples=0, bool mipmap=false)
GLenum textureTarget() const
Returns the texture target of the texture attached to a framebuffer object.
unsigned int GLenum
Definition: main.cpp:50
bool bind()
Switches rendering from the default, windowing system provided framebuffer to this framebuffer object...
bool operator==(const QGLFramebufferObjectFormat &other) const
Returns true if all the options of this framebuffer object format are the same as other; otherwise re...
#define GL_UNSIGNED_BYTE
#define ctx
Definition: qgl.cpp:6094
QGLFramebufferObjectFormatPrivate * d
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
Q_DECL_CONSTEXPR const T & qBound(const T &min, const T &val, const T &max)
Definition: qglobal.h:1219
void setFBO(QGLFramebufferObject *f, QGLFramebufferObject::Attachment attachment)
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget=GL_TEXTURE_2D)
Draws the given texture, textureId, to the given target rectangle, target, in OpenGL model space...
GLuint default_fbo
Definition: qgl_p.h:457
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
QFuture< void > filter(Sequence &sequence, FilterFunction filterFunction)
bool release()
Switches rendering back to the default, windowing system provided framebuffer.
#define GL_FRAMEBUFFER_COMPLETE_EXT
static Extensions glExtensions()
Definition: qgl.cpp:5781
typedef GLint
Definition: glfunctions.h:67
#define GL_RGBA
#define glFramebufferRenderbuffer
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
#define QGL_FUNC_CONTEXT
virtual ~QGLFramebufferObject()
Destroys the framebuffer object and frees any allocated resources.
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QGLFramebufferObjectFormat()
Creates a QGLFramebufferObjectFormat object for specifying the format of an OpenGL framebuffer object...
bool isBound() const
Returns true if the framebuffer object is currently bound to a context, otherwise false is returned...
#define GL_TEXTURE_MAG_FILTER
#define glFramebufferTexture2D
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
The QGLFramebufferObjectFormat class specifies the format of an OpenGL framebuffer object...
#define glGenerateMipmap
Definition: glfunctions.h:70
static bool hasOpenGLFramebufferBlit()
Returns true if the OpenGL GL_EXT_framebuffer_blit extension is present on this system; otherwise ret...
#define QGL_FUNCP_CONTEXT
#define GL_NO_ERROR
#define glRenderbufferStorage
#define GL_DEPTH_COMPONENT24_OES
#define enabled
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
#define GL_NEAREST
Attachment attachment() const
Returns the status of the depth and stencil buffers attached to this framebuffer object.