qglframebufferobject.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 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#include "gl2paintengineex/qpaintengineex_opengl2_p.h" -
49 -
50#include <qlibrary.h> -
51#include <qimage.h> -
52#include <qwindow.h> -
53 -
54QT_BEGIN_NAMESPACE -
55 -
56extern QImage qt_gl_read_frame_buffer(const QSize&, bool, bool); -
57 -
58#define QGL_FUNC_CONTEXT const QGLContext *ctx = QGLContext::currentContext(); -
59#define QGL_FUNCP_CONTEXT const QGLContext *ctx = QGLContext::currentContext(); -
60 -
61#ifndef QT_NO_DEBUG -
62#define QT_RESET_GLERROR() \ -
63{ \ -
64 while (glGetError() != GL_NO_ERROR) {} \ -
65} -
66#define QT_CHECK_GLERROR() \ -
67{ \ -
68 GLenum err = glGetError(); \ -
69 if (err != GL_NO_ERROR) { \ -
70 qDebug("[%s line %d] GL Error: %d", \ -
71 __FILE__, __LINE__, (int)err); \ -
72 } \ -
73} -
74#else -
75#define QT_RESET_GLERROR() {} -
76#define QT_CHECK_GLERROR() {} -
77#endif -
78 -
79// ####TODO Properly #ifdef this class to use #define symbols actually defined -
80// by OpenGL/ES includes -
81#ifndef GL_MAX_SAMPLES -
82#define GL_MAX_SAMPLES 0x8D57 -
83#endif -
84 -
85#ifndef GL_RENDERBUFFER_SAMPLES -
86#define GL_RENDERBUFFER_SAMPLES 0x8CAB -
87#endif -
88 -
89#ifndef GL_DEPTH24_STENCIL8 -
90#define GL_DEPTH24_STENCIL8 0x88F0 -
91#endif -
92 -
93#ifndef GL_DEPTH_COMPONENT24 -
94#define GL_DEPTH_COMPONENT24 0x81A6 -
95#endif -
96 -
97#ifndef GL_READ_FRAMEBUFFER -
98#define GL_READ_FRAMEBUFFER 0x8CA8 -
99#endif -
100 -
101#ifndef GL_DRAW_FRAMEBUFFER -
102#define GL_DRAW_FRAMEBUFFER 0x8CA9 -
103#endif -
104 -
105/*! -
106 \class QGLFramebufferObjectFormat -
107 \inmodule QtOpenGL -
108 \brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL -
109 framebuffer object. -
110 -
111 \since 4.6 -
112 \obsolete -
113 -
114 \ingroup painting-3D -
115 -
116 A framebuffer object has several characteristics: -
117 \list -
118 \li \l{setSamples()}{Number of samples per pixels.} -
119 \li \l{setAttachment()}{Depth and/or stencil attachments.} -
120 \li \l{setTextureTarget()}{Texture target.} -
121 \li \l{setInternalTextureFormat()}{Internal texture format.} -
122 \endlist -
123 -
124 Note that the desired attachments or number of samples per pixels might not -
125 be supported by the hardware driver. Call QGLFramebufferObject::format() -
126 after creating a QGLFramebufferObject to find the exact format that was -
127 used to create the frame buffer object. -
128 -
129 \note This class has been deprecated in favor of QOpenGLFramebufferObjectFormat. -
130 -
131 \sa QGLFramebufferObject -
132*/ -
133 -
134/*! -
135 \internal -
136*/ -
137void QGLFramebufferObjectFormat::detach() -
138{ -
139 if (d->ref.load() != 1) {
never evaluated: d->ref.load() != 1
0
140 QGLFramebufferObjectFormatPrivate *newd
never executed (the execution status of this line is deduced): QGLFramebufferObjectFormatPrivate *newd
-
141 = new QGLFramebufferObjectFormatPrivate(d);
never executed (the execution status of this line is deduced): = new QGLFramebufferObjectFormatPrivate(d);
-
142 if (!d->ref.deref())
never evaluated: !d->ref.deref()
0
143 delete d;
never executed: delete d;
0
144 d = newd;
never executed (the execution status of this line is deduced): d = newd;
-
145 }
never executed: }
0
146}
never executed: }
0
147 -
148/*! -
149 Creates a QGLFramebufferObjectFormat object for specifying -
150 the format of an OpenGL framebuffer object. -
151 -
152 By default the format specifies a non-multisample framebuffer object with no -
153 attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8. -
154 On OpenGL/ES systems, the default internal format is \c GL_RGBA. -
155 -
156 \sa samples(), attachment(), internalTextureFormat() -
157*/ -
158 -
159QGLFramebufferObjectFormat::QGLFramebufferObjectFormat() -
160{ -
161 d = new QGLFramebufferObjectFormatPrivate;
never executed (the execution status of this line is deduced): d = new QGLFramebufferObjectFormatPrivate;
-
162}
never executed: }
0
163 -
164/*! -
165 Constructs a copy of \a other. -
166*/ -
167 -
168QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other) -
169{ -
170 d = other.d;
never executed (the execution status of this line is deduced): d = other.d;
-
171 d->ref.ref();
never executed (the execution status of this line is deduced): d->ref.ref();
-
172}
never executed: }
0
173 -
174/*! -
175 Assigns \a other to this object. -
176*/ -
177 -
178QGLFramebufferObjectFormat &QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other) -
179{ -
180 if (d != other.d) {
never evaluated: d != other.d
0
181 other.d->ref.ref();
never executed (the execution status of this line is deduced): other.d->ref.ref();
-
182 if (!d->ref.deref())
never evaluated: !d->ref.deref()
0
183 delete d;
never executed: delete d;
0
184 d = other.d;
never executed (the execution status of this line is deduced): d = other.d;
-
185 }
never executed: }
0
186 return *this;
never executed: return *this;
0
187} -
188 -
189/*! -
190 Destroys the QGLFramebufferObjectFormat. -
191*/ -
192QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat() -
193{ -
194 if (!d->ref.deref())
never evaluated: !d->ref.deref()
0
195 delete d;
never executed: delete d;
0
196}
never executed: }
0
197 -
198/*! -
199 Sets the number of samples per pixel for a multisample framebuffer object -
200 to \a samples. The default sample count of 0 represents a regular -
201 non-multisample framebuffer object. -
202 -
203 If the desired amount of samples per pixel is not supported by the hardware -
204 then the maximum number of samples per pixel will be used. Note that -
205 multisample framebuffer objects can not be bound as textures. Also, the -
206 \c{GL_EXT_framebuffer_multisample} extension is required to create a -
207 framebuffer with more than one sample per pixel. -
208 -
209 \sa samples() -
210*/ -
211void QGLFramebufferObjectFormat::setSamples(int samples) -
212{ -
213 detach();
never executed (the execution status of this line is deduced): detach();
-
214 d->samples = samples;
never executed (the execution status of this line is deduced): d->samples = samples;
-
215}
never executed: }
0
216 -
217/*! -
218 Returns the number of samples per pixel if a framebuffer object -
219 is a multisample framebuffer object. Otherwise, returns 0. -
220 The default value is 0. -
221 -
222 \sa setSamples() -
223*/ -
224int QGLFramebufferObjectFormat::samples() const -
225{ -
226 return d->samples;
never executed: return d->samples;
0
227} -
228 -
229/*! -
230 \since 4.8 -
231 -
232 Enables mipmapping if \a enabled is true; otherwise disables it. -
233 -
234 Mipmapping is disabled by default. -
235 -
236 If mipmapping is enabled, additional memory will be allocated for -
237 the mipmap levels. The mipmap levels can be updated by binding the -
238 texture and calling glGenerateMipmap(). Mipmapping cannot be enabled -
239 for multisampled framebuffer objects. -
240 -
241 \sa mipmap(), QGLFramebufferObject::texture() -
242*/ -
243void QGLFramebufferObjectFormat::setMipmap(bool enabled) -
244{ -
245 detach();
never executed (the execution status of this line is deduced): detach();
-
246 d->mipmap = enabled;
never executed (the execution status of this line is deduced): d->mipmap = enabled;
-
247}
never executed: }
0
248 -
249/*! -
250 \since 4.8 -
251 -
252 Returns true if mipmapping is enabled. -
253 -
254 \sa setMipmap() -
255*/ -
256bool QGLFramebufferObjectFormat::mipmap() const -
257{ -
258 return d->mipmap;
never executed: return d->mipmap;
0
259} -
260 -
261/*! -
262 Sets the attachment configuration of a framebuffer object to \a attachment. -
263 -
264 \sa attachment() -
265*/ -
266void QGLFramebufferObjectFormat::setAttachment(QGLFramebufferObject::Attachment attachment) -
267{ -
268 detach();
never executed (the execution status of this line is deduced): detach();
-
269 d->attachment = attachment;
never executed (the execution status of this line is deduced): d->attachment = attachment;
-
270}
never executed: }
0
271 -
272/*! -
273 Returns the configuration of the depth and stencil buffers attached to -
274 a framebuffer object. The default is QGLFramebufferObject::NoAttachment. -
275 -
276 \sa setAttachment() -
277*/ -
278QGLFramebufferObject::Attachment QGLFramebufferObjectFormat::attachment() const -
279{ -
280 return d->attachment;
never executed: return d->attachment;
0
281} -
282 -
283/*! -
284 Sets the texture target of the texture attached to a framebuffer object to -
285 \a target. Ignored for multisample framebuffer objects. -
286 -
287 \sa textureTarget(), samples() -
288*/ -
289void QGLFramebufferObjectFormat::setTextureTarget(GLenum target) -
290{ -
291 detach();
never executed (the execution status of this line is deduced): detach();
-
292 d->target = target;
never executed (the execution status of this line is deduced): d->target = target;
-
293}
never executed: }
0
294 -
295/*! -
296 Returns the texture target of the texture attached to a framebuffer object. -
297 Ignored for multisample framebuffer objects. The default is -
298 \c GL_TEXTURE_2D. -
299 -
300 \sa setTextureTarget(), samples() -
301*/ -
302GLenum QGLFramebufferObjectFormat::textureTarget() const -
303{ -
304 return d->target;
never executed: return d->target;
0
305} -
306 -
307/*! -
308 Sets the internal format of a framebuffer object's texture or -
309 multisample framebuffer object's color buffer to -
310 \a internalTextureFormat. -
311 -
312 \sa internalTextureFormat() -
313*/ -
314void QGLFramebufferObjectFormat::setInternalTextureFormat(GLenum internalTextureFormat) -
315{ -
316 detach();
never executed (the execution status of this line is deduced): detach();
-
317 d->internal_format = internalTextureFormat;
never executed (the execution status of this line is deduced): d->internal_format = internalTextureFormat;
-
318}
never executed: }
0
319 -
320/*! -
321 Returns the internal format of a framebuffer object's texture or -
322 multisample framebuffer object's color buffer. The default is -
323 \c GL_RGBA8 on desktop OpenGL systems, and \c GL_RGBA on -
324 OpenGL/ES systems. -
325 -
326 \sa setInternalTextureFormat() -
327*/ -
328GLenum QGLFramebufferObjectFormat::internalTextureFormat() const -
329{ -
330 return d->internal_format;
never executed: return d->internal_format;
0
331} -
332 -
333/*! -
334 Returns true if all the options of this framebuffer object format -
335 are the same as \a other; otherwise returns false. -
336*/ -
337bool QGLFramebufferObjectFormat::operator==(const QGLFramebufferObjectFormat& other) const -
338{ -
339 if (d == other.d)
never evaluated: d == other.d
0
340 return true;
never executed: return true;
0
341 else -
342 return d->equals(other.d);
never executed: return d->equals(other.d);
0
343} -
344 -
345/*! -
346 Returns false if all the options of this framebuffer object format -
347 are the same as \a other; otherwise returns true. -
348*/ -
349bool QGLFramebufferObjectFormat::operator!=(const QGLFramebufferObjectFormat& other) const -
350{ -
351 return !(*this == other);
never executed: return !(*this == other);
0
352} -
353 -
354void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f, -
355 QGLFramebufferObject::Attachment attachment) -
356{ -
357 fbo = f;
never executed (the execution status of this line is deduced): fbo = f;
-
358 m_thisFBO = fbo->d_func()->fbo(); // This shouldn't be needed
never executed (the execution status of this line is deduced): m_thisFBO = fbo->d_func()->fbo();
-
359 -
360 // The context that the fbo was created in may not have depth -
361 // and stencil buffers, but the fbo itself might. -
362 fboFormat = QGLContext::currentContext()->format();
never executed (the execution status of this line is deduced): fboFormat = QGLContext::currentContext()->format();
-
363 if (attachment == QGLFramebufferObject::CombinedDepthStencil) {
never evaluated: attachment == QGLFramebufferObject::CombinedDepthStencil
0
364 fboFormat.setDepth(true);
never executed (the execution status of this line is deduced): fboFormat.setDepth(true);
-
365 fboFormat.setStencil(true);
never executed (the execution status of this line is deduced): fboFormat.setStencil(true);
-
366 } else if (attachment == QGLFramebufferObject::Depth) {
never executed: }
never evaluated: attachment == QGLFramebufferObject::Depth
0
367 fboFormat.setDepth(true);
never executed (the execution status of this line is deduced): fboFormat.setDepth(true);
-
368 fboFormat.setStencil(false);
never executed (the execution status of this line is deduced): fboFormat.setStencil(false);
-
369 } else {
never executed: }
0
370 fboFormat.setDepth(false);
never executed (the execution status of this line is deduced): fboFormat.setDepth(false);
-
371 fboFormat.setStencil(false);
never executed (the execution status of this line is deduced): fboFormat.setStencil(false);
-
372 }
never executed: }
0
373 -
374 GLenum format = f->format().internalTextureFormat();
never executed (the execution status of this line is deduced): GLenum format = f->format().internalTextureFormat();
-
375 reqAlpha = (format != GL_RGB
never evaluated: format != 0x1907
0
376#ifndef QT_OPENGL_ES
never executed (the execution status of this line is deduced):
-
377 && format != GL_RGB5 && format != GL_RGB8
never evaluated: format != 0x8050
never evaluated: format != 0x8051
0
378#endif
never executed (the execution status of this line is deduced):
-
379 );
never executed (the execution status of this line is deduced): );
-
380}
never executed: }
0
381 -
382QGLContext *QGLFBOGLPaintDevice::context() const -
383{ -
384 return const_cast<QGLContext *>(QGLContext::currentContext());
never executed: return const_cast<QGLContext *>(QGLContext::currentContext());
0
385} -
386 -
387bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const -
388{ -
389 QGL_FUNCP_CONTEXT;
never executed (the execution status of this line is deduced): const QGLContext *ctx = QGLContext::currentContext();;
-
390 if (!ctx)
never evaluated: !ctx
0
391 return false; // Context no longer exists.
never executed: return false;
0
392 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
never executed (the execution status of this line is deduced): GLenum status = QGLContextPrivate::extensionFuncs(ctx).qt_glCheckFramebufferStatus(0x8D40);
-
393 switch(status) { -
394 case GL_NO_ERROR: -
395 case GL_FRAMEBUFFER_COMPLETE: -
396 return true;
never executed: return true;
0
397 case GL_FRAMEBUFFER_UNSUPPORTED: -
398 qDebug("QGLFramebufferObject: Unsupported framebuffer format.");
never executed (the execution status of this line is deduced): QMessageLogger("qglframebufferobject.cpp", 398, __PRETTY_FUNCTION__).debug("QGLFramebufferObject: Unsupported framebuffer format.");
-
399 break;
never executed: break;
0
400 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: -
401 qDebug("QGLFramebufferObject: Framebuffer incomplete attachment.");
never executed (the execution status of this line is deduced): QMessageLogger("qglframebufferobject.cpp", 401, __PRETTY_FUNCTION__).debug("QGLFramebufferObject: Framebuffer incomplete attachment.");
-
402 break;
never executed: break;
0
403 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: -
404 qDebug("QGLFramebufferObject: Framebuffer incomplete, missing attachment.");
never executed (the execution status of this line is deduced): QMessageLogger("qglframebufferobject.cpp", 404, __PRETTY_FUNCTION__).debug("QGLFramebufferObject: Framebuffer incomplete, missing attachment.");
-
405 break;
never executed: break;
0
406#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT -
407 case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT: -
408 qDebug("QGLFramebufferObject: Framebuffer incomplete, duplicate attachment."); -
409 break; -
410#endif -
411#ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS -
412 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: -
413 qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same dimensions."); -
414 break; -
415#endif -
416#ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS -
417 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS: -
418 qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same format."); -
419 break; -
420#endif -
421#ifdef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER -
422 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: -
423 qDebug("QGLFramebufferObject: Framebuffer incomplete, missing draw buffer.");
never executed (the execution status of this line is deduced): QMessageLogger("qglframebufferobject.cpp", 423, __PRETTY_FUNCTION__).debug("QGLFramebufferObject: Framebuffer incomplete, missing draw buffer.");
-
424 break;
never executed: break;
0
425#endif -
426#ifdef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER -
427 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: -
428 qDebug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer.");
never executed (the execution status of this line is deduced): QMessageLogger("qglframebufferobject.cpp", 428, __PRETTY_FUNCTION__).debug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer.");
-
429 break;
never executed: break;
0
430#endif -
431#ifdef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE -
432 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: -
433 qDebug("QGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel.");
never executed (the execution status of this line is deduced): QMessageLogger("qglframebufferobject.cpp", 433, __PRETTY_FUNCTION__).debug("QGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel.");
-
434 break;
never executed: break;
0
435#endif -
436 default: -
437 qDebug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status;
never executed (the execution status of this line is deduced): QMessageLogger("qglframebufferobject.cpp", 437, __PRETTY_FUNCTION__).debug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status;
-
438 break;
never executed: break;
0
439 } -
440 return false;
never executed: return false;
0
441} -
442 -
443namespace -
444{ -
445 void freeFramebufferFunc(QGLContext *ctx, GLuint id) -
446 { -
447 Q_UNUSED(ctx);
never executed (the execution status of this line is deduced): (void)ctx;;
-
448 glDeleteFramebuffers(1, &id);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteFramebuffers(1, &id);
-
449 }
never executed: }
0
450 -
451 void freeRenderbufferFunc(QGLContext *ctx, GLuint id) -
452 { -
453 Q_UNUSED(ctx);
never executed (the execution status of this line is deduced): (void)ctx;;
-
454 glDeleteRenderbuffers(1, &id);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteRenderbuffers(1, &id);
-
455 }
never executed: }
0
456 -
457 void freeTextureFunc(QGLContext *ctx, GLuint id) -
458 { -
459 Q_UNUSED(ctx);
never executed (the execution status of this line is deduced): (void)ctx;;
-
460 glDeleteTextures(1, &id);
never executed (the execution status of this line is deduced): glDeleteTextures(1, &id);
-
461 }
never executed: }
0
462} -
463 -
464void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, -
465 QGLFramebufferObject::Attachment attachment, -
466 GLenum texture_target, GLenum internal_format, -
467 GLint samples, bool mipmap) -
468{ -
469 QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
never executed (the execution status of this line is deduced): QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
-
470 -
471 bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
never executed (the execution status of this line is deduced): bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
-
472 if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
never evaluated: !ext_detected
never evaluated: ext_detected
never evaluated: !qt_resolve_framebufferobject_extensions(ctx)
0
473 return;
never executed: return;
0
474 -
475 size = sz;
never executed (the execution status of this line is deduced): size = sz;
-
476 target = texture_target;
never executed (the execution status of this line is deduced): target = texture_target;
-
477 // texture dimensions -
478 -
479 QT_RESET_GLERROR(); // reset error state -
480 GLuint fbo = 0;
never executed (the execution status of this line is deduced): GLuint fbo = 0;
-
481 glGenFramebuffers(1, &fbo);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glGenFramebuffers(1, &fbo);
-
482 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer(0x8D40, fbo);
-
483 -
484 GLuint texture = 0;
never executed (the execution status of this line is deduced): GLuint texture = 0;
-
485 GLuint color_buffer = 0;
never executed (the execution status of this line is deduced): GLuint color_buffer = 0;
-
486 GLuint depth_buffer = 0;
never executed (the execution status of this line is deduced): GLuint depth_buffer = 0;
-
487 GLuint stencil_buffer = 0;
never executed (the execution status of this line is deduced): GLuint stencil_buffer = 0;
-
488 -
489 QT_CHECK_GLERROR(); -
490 // init texture -
491 if (samples == 0) {
never evaluated: samples == 0
0
492 glGenTextures(1, &texture);
never executed (the execution status of this line is deduced): glGenTextures(1, &texture);
-
493 glBindTexture(target, texture);
never executed (the execution status of this line is deduced): glBindTexture(target, texture);
-
494 glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
never executed (the execution status of this line is deduced): glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
-
495 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
never executed (the execution status of this line is deduced): 0x1908, 0x1401, __null);
-
496 if (mipmap) {
never evaluated: mipmap
0
497 int width = size.width();
never executed (the execution status of this line is deduced): int width = size.width();
-
498 int height = size.height();
never executed (the execution status of this line is deduced): int height = size.height();
-
499 int level = 0;
never executed (the execution status of this line is deduced): int level = 0;
-
500 while (width > 1 || height > 1) {
never evaluated: width > 1
never evaluated: height > 1
0
501 width = qMax(1, width >> 1);
never executed (the execution status of this line is deduced): width = qMax(1, width >> 1);
-
502 height = qMax(1, height >> 1);
never executed (the execution status of this line is deduced): height = qMax(1, height >> 1);
-
503 ++level;
never executed (the execution status of this line is deduced): ++level;
-
504 glTexImage2D(target, level, internal_format, width, height, 0,
never executed (the execution status of this line is deduced): glTexImage2D(target, level, internal_format, width, height, 0,
-
505 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
never executed (the execution status of this line is deduced): 0x1908, 0x1401, __null);
-
506 }
never executed: }
0
507 }
never executed: }
0
508 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
never executed (the execution status of this line is deduced): glTexParameteri(target, 0x2801, 0x2600);
-
509 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
never executed (the execution status of this line is deduced): glTexParameteri(target, 0x2800, 0x2600);
-
510 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
never executed (the execution status of this line is deduced): glTexParameteri(target, 0x2802, 0x812F);
-
511 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
never executed (the execution status of this line is deduced): glTexParameteri(target, 0x2803, 0x812F);
-
512 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferTexture2D(0x8D40, 0x8CE0,
-
513 target, texture, 0);
never executed (the execution status of this line is deduced): target, texture, 0);
-
514 -
515 QT_CHECK_GLERROR(); -
516 valid = checkFramebufferStatus();
never executed (the execution status of this line is deduced): valid = checkFramebufferStatus();
-
517 glBindTexture(target, 0);
never executed (the execution status of this line is deduced): glBindTexture(target, 0);
-
518 -
519 color_buffer = 0;
never executed (the execution status of this line is deduced): color_buffer = 0;
-
520 } else {
never executed: }
0
521 mipmap = false;
never executed (the execution status of this line is deduced): mipmap = false;
-
522 GLint maxSamples;
never executed (the execution status of this line is deduced): GLint maxSamples;
-
523 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
never executed (the execution status of this line is deduced): glGetIntegerv(0x8D57, &maxSamples);
-
524 -
525 samples = qBound(0, int(samples), int(maxSamples));
never executed (the execution status of this line is deduced): samples = qBound(0, int(samples), int(maxSamples));
-
526 -
527 glGenRenderbuffers(1, &color_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glGenRenderbuffers(1, &color_buffer);
-
528 glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindRenderbuffer(0x8D41, color_buffer);
-
529 if (glRenderbufferStorageMultisampleEXT && samples > 0) {
never evaluated: QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT
never evaluated: samples > 0
0
530 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT(0x8D41, samples,
-
531 internal_format, size.width(), size.height());
never executed (the execution status of this line is deduced): internal_format, size.width(), size.height());
-
532 } else {
never executed: }
0
533 samples = 0;
never executed (the execution status of this line is deduced): samples = 0;
-
534 glRenderbufferStorage(GL_RENDERBUFFER, internal_format,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorage(0x8D41, internal_format,
-
535 size.width(), size.height());
never executed (the execution status of this line is deduced): size.width(), size.height());
-
536 }
never executed: }
0
537 -
538 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferRenderbuffer(0x8D40, 0x8CE0,
-
539 GL_RENDERBUFFER, color_buffer);
never executed (the execution status of this line is deduced): 0x8D41, color_buffer);
-
540 -
541 QT_CHECK_GLERROR(); -
542 valid = checkFramebufferStatus();
never executed (the execution status of this line is deduced): valid = checkFramebufferStatus();
-
543 -
544 if (valid)
never evaluated: valid
0
545 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
never executed: QGLContextPrivate::extensionFuncs(ctx).qt_glGetRenderbufferParameteriv(0x8D41, 0x8CAB, &samples);
0
546 }
never executed: }
0
547 -
548 // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a -
549 // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer -
550 // might not be supported while separate buffers are, according to QTBUG-12861. -
551 -
552 if (attachment == QGLFramebufferObject::CombinedDepthStencil
never evaluated: attachment == QGLFramebufferObject::CombinedDepthStencil
0
553 && (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)) {
never evaluated: (QGLExtensions::glExtensions() & QGLExtensions::PackedDepthStencil)
0
554 // depth and stencil buffer needs another extension -
555 glGenRenderbuffers(1, &depth_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glGenRenderbuffers(1, &depth_buffer);
-
556 Q_ASSERT(!glIsRenderbuffer(depth_buffer));
never executed (the execution status of this line is deduced): qt_noop();
-
557 glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindRenderbuffer(0x8D41, depth_buffer);
-
558 Q_ASSERT(glIsRenderbuffer(depth_buffer));
never executed (the execution status of this line is deduced): qt_noop();
-
559 if (samples != 0 && glRenderbufferStorageMultisampleEXT)
never evaluated: samples != 0
never evaluated: QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT
0
560 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
never executed: QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT(0x8D41, samples, 0x88F0, size.width(), size.height());
0
561 GL_DEPTH24_STENCIL8, size.width(), size.height());
never executed: QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT(0x8D41, samples, 0x88F0, size.width(), size.height());
0
562 else -
563 glRenderbufferStorage(GL_RENDERBUFFER,
never executed: QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorage(0x8D41, 0x88F0, size.width(), size.height());
0
564 GL_DEPTH24_STENCIL8, size.width(), size.height());
never executed: QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorage(0x8D41, 0x88F0, size.width(), size.height());
0
565 -
566 stencil_buffer = depth_buffer;
never executed (the execution status of this line is deduced): stencil_buffer = depth_buffer;
-
567 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferRenderbuffer(0x8D40, 0x8D00,
-
568 GL_RENDERBUFFER, depth_buffer);
never executed (the execution status of this line is deduced): 0x8D41, depth_buffer);
-
569 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferRenderbuffer(0x8D40, 0x8D20,
-
570 GL_RENDERBUFFER, stencil_buffer);
never executed (the execution status of this line is deduced): 0x8D41, stencil_buffer);
-
571 -
572 valid = checkFramebufferStatus();
never executed (the execution status of this line is deduced): valid = checkFramebufferStatus();
-
573 if (!valid) {
never evaluated: !valid
0
574 glDeleteRenderbuffers(1, &depth_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteRenderbuffers(1, &depth_buffer);
-
575 stencil_buffer = depth_buffer = 0;
never executed (the execution status of this line is deduced): stencil_buffer = depth_buffer = 0;
-
576 }
never executed: }
0
577 }
never executed: }
0
578 -
579 if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil
never evaluated: depth_buffer == 0
never evaluated: attachment == QGLFramebufferObject::CombinedDepthStencil
0
580 || (attachment == QGLFramebufferObject::Depth)))
never evaluated: (attachment == QGLFramebufferObject::Depth)
0
581 { -
582 glGenRenderbuffers(1, &depth_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glGenRenderbuffers(1, &depth_buffer);
-
583 Q_ASSERT(!glIsRenderbuffer(depth_buffer));
never executed (the execution status of this line is deduced): qt_noop();
-
584 glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindRenderbuffer(0x8D41, depth_buffer);
-
585 Q_ASSERT(glIsRenderbuffer(depth_buffer));
never executed (the execution status of this line is deduced): qt_noop();
-
586 if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
never evaluated: samples != 0
never evaluated: QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT
0
587#ifdef QT_OPENGL_ES -
588 if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { -
589 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, -
590 GL_DEPTH_COMPONENT24_OES, size.width(), size.height()); -
591 } else { -
592 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, -
593 GL_DEPTH_COMPONENT16, size.width(), size.height()); -
594 } -
595#else -
596 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT(0x8D41, samples,
-
597 GL_DEPTH_COMPONENT, size.width(), size.height());
never executed (the execution status of this line is deduced): 0x1902, size.width(), size.height());
-
598#endif -
599 } else {
never executed: }
0
600#ifdef QT_OPENGL_ES -
601 if (QGLExtensions::glExtensions() & QGLExtensions::Depth24) { -
602 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, -
603 size.width(), size.height()); -
604 } else { -
605 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, -
606 size.width(), size.height()); -
607 } -
608#else -
609 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorage(0x8D41, 0x1902, size.width(), size.height());
-
610#endif -
611 }
never executed: }
0
612 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferRenderbuffer(0x8D40, 0x8D00,
-
613 GL_RENDERBUFFER, depth_buffer);
never executed (the execution status of this line is deduced): 0x8D41, depth_buffer);
-
614 valid = checkFramebufferStatus();
never executed (the execution status of this line is deduced): valid = checkFramebufferStatus();
-
615 if (!valid) {
never evaluated: !valid
0
616 glDeleteRenderbuffers(1, &depth_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteRenderbuffers(1, &depth_buffer);
-
617 depth_buffer = 0;
never executed (the execution status of this line is deduced): depth_buffer = 0;
-
618 }
never executed: }
0
619 }
never executed: }
0
620 -
621 if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) {
never evaluated: stencil_buffer == 0
never evaluated: (attachment == QGLFramebufferObject::CombinedDepthStencil)
0
622 glGenRenderbuffers(1, &stencil_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glGenRenderbuffers(1, &stencil_buffer);
-
623 Q_ASSERT(!glIsRenderbuffer(stencil_buffer));
never executed (the execution status of this line is deduced): qt_noop();
-
624 glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindRenderbuffer(0x8D41, stencil_buffer);
-
625 Q_ASSERT(glIsRenderbuffer(stencil_buffer));
never executed (the execution status of this line is deduced): qt_noop();
-
626 if (samples != 0 && glRenderbufferStorageMultisampleEXT) {
never evaluated: samples != 0
never evaluated: QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT
0
627#ifdef QT_OPENGL_ES -
628 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, -
629 GL_STENCIL_INDEX8, size.width(), size.height()); -
630#else -
631 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorageMultisampleEXT(0x8D41, samples,
-
632 GL_STENCIL_INDEX, size.width(), size.height());
never executed (the execution status of this line is deduced): 0x1901, size.width(), size.height());
-
633#endif -
634 } else {
never executed: }
0
635#ifdef QT_OPENGL_ES -
636 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, -
637 size.width(), size.height()); -
638#else -
639 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glRenderbufferStorage(0x8D41, 0x1901,
-
640 size.width(), size.height());
never executed (the execution status of this line is deduced): size.width(), size.height());
-
641#endif -
642 }
never executed: }
0
643 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glFramebufferRenderbuffer(0x8D40, 0x8D20,
-
644 GL_RENDERBUFFER, stencil_buffer);
never executed (the execution status of this line is deduced): 0x8D41, stencil_buffer);
-
645 valid = checkFramebufferStatus();
never executed (the execution status of this line is deduced): valid = checkFramebufferStatus();
-
646 if (!valid) {
never evaluated: !valid
0
647 glDeleteRenderbuffers(1, &stencil_buffer);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteRenderbuffers(1, &stencil_buffer);
-
648 stencil_buffer = 0;
never executed (the execution status of this line is deduced): stencil_buffer = 0;
-
649 }
never executed: }
0
650 }
never executed: }
0
651 -
652 // The FBO might have become valid after removing the depth or stencil buffer. -
653 valid = checkFramebufferStatus();
never executed (the execution status of this line is deduced): valid = checkFramebufferStatus();
-
654 -
655 if (depth_buffer && stencil_buffer) {
never evaluated: depth_buffer
never evaluated: stencil_buffer
0
656 fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;
never executed (the execution status of this line is deduced): fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;
-
657 } else if (depth_buffer) {
never executed: }
never evaluated: depth_buffer
0
658 fbo_attachment = QGLFramebufferObject::Depth;
never executed (the execution status of this line is deduced): fbo_attachment = QGLFramebufferObject::Depth;
-
659 } else {
never executed: }
0
660 fbo_attachment = QGLFramebufferObject::NoAttachment;
never executed (the execution status of this line is deduced): fbo_attachment = QGLFramebufferObject::NoAttachment;
-
661 }
never executed: }
0
662 -
663 glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer(0x8D40, ctx->d_ptr->current_fbo);
-
664 if (valid) {
never evaluated: valid
0
665 fbo_guard = createSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
never executed (the execution status of this line is deduced): fbo_guard = createSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
-
666 if (color_buffer)
never evaluated: color_buffer
0
667 color_buffer_guard = createSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
never executed: color_buffer_guard = createSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
0
668 else -
669 texture_guard = createSharedResourceGuard(ctx, texture, freeTextureFunc);
never executed: texture_guard = createSharedResourceGuard(ctx, texture, freeTextureFunc);
0
670 if (depth_buffer)
never evaluated: depth_buffer
0
671 depth_buffer_guard = createSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc);
never executed: depth_buffer_guard = createSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc);
0
672 if (stencil_buffer) {
never evaluated: stencil_buffer
0
673 if (stencil_buffer == depth_buffer)
never evaluated: stencil_buffer == depth_buffer
0
674 stencil_buffer_guard = depth_buffer_guard;
never executed: stencil_buffer_guard = depth_buffer_guard;
0
675 else -
676 stencil_buffer_guard = createSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc);
never executed: stencil_buffer_guard = createSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc);
0
677 } -
678 } else {
never executed: }
0
679 if (color_buffer)
never evaluated: color_buffer
0
680 glDeleteRenderbuffers(1, &color_buffer);
never executed: QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteRenderbuffers(1, &color_buffer);
0
681 else -
682 glDeleteTextures(1, &texture);
never executed: glDeleteTextures(1, &texture);
0
683 if (depth_buffer)
never evaluated: depth_buffer
0
684 glDeleteRenderbuffers(1, &depth_buffer);
never executed: QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteRenderbuffers(1, &depth_buffer);
0
685 if (stencil_buffer && depth_buffer != stencil_buffer)
never evaluated: stencil_buffer
never evaluated: depth_buffer != stencil_buffer
0
686 glDeleteRenderbuffers(1, &stencil_buffer);
never executed: QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteRenderbuffers(1, &stencil_buffer);
0
687 glDeleteFramebuffers(1, &fbo);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glDeleteFramebuffers(1, &fbo);
-
688 }
never executed: }
0
689 QT_CHECK_GLERROR(); -
690 -
691 format.setTextureTarget(target);
never executed (the execution status of this line is deduced): format.setTextureTarget(target);
-
692 format.setSamples(int(samples));
never executed (the execution status of this line is deduced): format.setSamples(int(samples));
-
693 format.setAttachment(fbo_attachment);
never executed (the execution status of this line is deduced): format.setAttachment(fbo_attachment);
-
694 format.setInternalTextureFormat(internal_format);
never executed (the execution status of this line is deduced): format.setInternalTextureFormat(internal_format);
-
695 format.setMipmap(mipmap);
never executed (the execution status of this line is deduced): format.setMipmap(mipmap);
-
696 -
697 glDevice.setFBO(q, attachment);
never executed (the execution status of this line is deduced): glDevice.setFBO(q, attachment);
-
698}
never executed: }
0
699 -
700/*! -
701 \class QGLFramebufferObject -
702 \inmodule QtOpenGL -
703 \brief The QGLFramebufferObject class encapsulates an OpenGL framebuffer object. -
704 \since 4.2 -
705 -
706 \obsolete -
707 -
708 \ingroup painting-3D -
709 -
710 The QGLFramebufferObject class encapsulates an OpenGL framebuffer -
711 object, defined by the \c{GL_EXT_framebuffer_object} extension. In -
712 addition it provides a rendering surface that can be painted on -
713 with a QPainter, rendered to using native GL calls, or both. This -
714 surface can be bound and used as a regular texture in your own GL -
715 drawing code. By default, the QGLFramebufferObject class -
716 generates a 2D GL texture (using the \c{GL_TEXTURE_2D} target), -
717 which is used as the internal rendering target. -
718 -
719 \b{It is important to have a current GL context when creating a -
720 QGLFramebufferObject, otherwise initialization will fail.} -
721 -
722 OpenGL framebuffer objects and pbuffers (see -
723 \l{QGLPixelBuffer}{QGLPixelBuffer}) can both be used to render to -
724 offscreen surfaces, but there are a number of advantages with -
725 using framebuffer objects instead of pbuffers: -
726 -
727 \list 1 -
728 \li A framebuffer object does not require a separate rendering -
729 context, so no context switching will occur when switching -
730 rendering targets. There is an overhead involved in switching -
731 targets, but in general it is cheaper than a context switch to a -
732 pbuffer. -
733 -
734 \li Rendering to dynamic textures (i.e. render-to-texture -
735 functionality) works on all platforms. No need to do explicit copy -
736 calls from a render buffer into a texture, as was necessary on -
737 systems that did not support the \c{render_texture} extension. -
738 -
739 \li It is possible to attach several rendering buffers (or texture -
740 objects) to the same framebuffer object, and render to all of them -
741 without doing a context switch. -
742 -
743 \li The OpenGL framebuffer extension is a pure GL extension with no -
744 system dependant WGL, CGL, or GLX parts. This makes using -
745 framebuffer objects more portable. -
746 \endlist -
747 -
748 When using a QPainter to paint to a QGLFramebufferObject you should take -
749 care that the QGLFramebufferObject is created with the CombinedDepthStencil -
750 attachment for QPainter to be able to render correctly. -
751 Note that you need to create a QGLFramebufferObject with more than one -
752 sample per pixel for primitives to be antialiased when drawing using a -
753 QPainter. To create a multisample framebuffer object you should use one of -
754 the constructors that take a QGLFramebufferObjectFormat parameter, and set -
755 the QGLFramebufferObjectFormat::samples() property to a non-zero value. -
756 -
757 When painting to a QGLFramebufferObject using QPainter, the state of -
758 the current GL context will be altered by the paint engine to reflect -
759 its needs. Applications should not rely upon the GL state being reset -
760 to its original conditions, particularly the current shader program, -
761 GL viewport, texture units, and drawing modes. -
762 -
763 For multisample framebuffer objects a color render buffer is created, -
764 otherwise a texture with the specified texture target is created. -
765 The color render buffer or texture will have the specified internal -
766 format, and will be bound to the \c GL_COLOR_ATTACHMENT0 -
767 attachment in the framebuffer object. -
768 -
769 If you want to use a framebuffer object with multisampling enabled -
770 as a texture, you first need to copy from it to a regular framebuffer -
771 object using QGLContext::blitFramebuffer(). -
772 -
773 \section1 Threading -
774 -
775 As of Qt 4.8, it's possible to draw into a QGLFramebufferObject -
776 using a QPainter in a separate thread. Note that OpenGL 2.0 or -
777 OpenGL ES 2.0 is required for this to work. -
778 -
779 \note This class has been deprecated in favor of QOpenGLFramebufferObject. -
780 -
781 \sa {Framebuffer Object Example} -
782*/ -
783 -
784 -
785/*! -
786 \enum QGLFramebufferObject::Attachment -
787 \since 4.3 -
788 -
789 This enum type is used to configure the depth and stencil buffers -
790 attached to the framebuffer object when it is created. -
791 -
792 \value NoAttachment No attachment is added to the framebuffer object. Note that the -
793 OpenGL depth and stencil tests won't work when rendering to a -
794 framebuffer object without any depth or stencil buffers. -
795 This is the default value. -
796 -
797 \value CombinedDepthStencil If the \c GL_EXT_packed_depth_stencil extension is present, -
798 a combined depth and stencil buffer is attached. -
799 If the extension is not present, only a depth buffer is attached. -
800 -
801 \value Depth A depth buffer is attached to the framebuffer object. -
802 -
803 \sa attachment() -
804*/ -
805 -
806 -
807/*! \fn QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) -
808 -
809 Constructs an OpenGL framebuffer object and binds a 2D GL texture -
810 to the buffer of the size \a size. The texture is bound to the -
811 \c GL_COLOR_ATTACHMENT0 target in the framebuffer object. -
812 -
813 The \a target parameter is used to specify the GL texture -
814 target. The default target is \c GL_TEXTURE_2D. Keep in mind that -
815 \c GL_TEXTURE_2D textures must have a power of 2 width and height -
816 (e.g. 256x512), unless you are using OpenGL 2.0 or higher. -
817 -
818 By default, no depth and stencil buffers are attached. This behavior -
819 can be toggled using one of the overloaded constructors. -
820 -
821 The default internal texture format is \c GL_RGBA8 for desktop -
822 OpenGL, and \c GL_RGBA for OpenGL/ES. -
823 -
824 It is important that you have a current GL context set when -
825 creating the QGLFramebufferObject, otherwise the initialization -
826 will fail. -
827 -
828 \sa size(), texture(), attachment() -
829*/ -
830 -
831QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) -
832 : d_ptr(new QGLFramebufferObjectPrivate) -
833{ -
834 Q_D(QGLFramebufferObject);
never executed (the execution status of this line is deduced): QGLFramebufferObjectPrivate * const d = d_func();
-
835 d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
never executed (the execution status of this line is deduced): d->init(this, size, NoAttachment, target, 0x8058);
-
836}
never executed: }
0
837 -
838/*! \overload -
839 -
840 Constructs an OpenGL framebuffer object and binds a 2D GL texture -
841 to the buffer of the given \a width and \a height. -
842 -
843 \sa size(), texture() -
844*/ -
845QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target) -
846 : d_ptr(new QGLFramebufferObjectPrivate) -
847{ -
848 Q_D(QGLFramebufferObject);
never executed (the execution status of this line is deduced): QGLFramebufferObjectPrivate * const d = d_func();
-
849 d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
never executed (the execution status of this line is deduced): d->init(this, QSize(width, height), NoAttachment, target, 0x8058);
-
850}
never executed: }
0
851 -
852/*! \overload -
853 -
854 Constructs an OpenGL framebuffer object of the given \a size based on the -
855 supplied \a format. -
856*/ -
857 -
858QGLFramebufferObject::QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format) -
859 : d_ptr(new QGLFramebufferObjectPrivate) -
860{ -
861 Q_D(QGLFramebufferObject);
never executed (the execution status of this line is deduced): QGLFramebufferObjectPrivate * const d = d_func();
-
862 d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(),
never executed (the execution status of this line is deduced): d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(),
-
863 format.samples(), format.mipmap());
never executed (the execution status of this line is deduced): format.samples(), format.mipmap());
-
864}
never executed: }
0
865 -
866/*! \overload -
867 -
868 Constructs an OpenGL framebuffer object of the given \a width and \a height -
869 based on the supplied \a format. -
870*/ -
871 -
872QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format) -
873 : d_ptr(new QGLFramebufferObjectPrivate) -
874{ -
875 Q_D(QGLFramebufferObject);
never executed (the execution status of this line is deduced): QGLFramebufferObjectPrivate * const d = d_func();
-
876 d->init(this, QSize(width, height), format.attachment(), format.textureTarget(),
never executed (the execution status of this line is deduced): d->init(this, QSize(width, height), format.attachment(), format.textureTarget(),
-
877 format.internalTextureFormat(), format.samples(), format.mipmap());
never executed (the execution status of this line is deduced): format.internalTextureFormat(), format.samples(), format.mipmap());
-
878}
never executed: }
0
879 -
880/*! \overload -
881 -
882 Constructs an OpenGL framebuffer object and binds a texture to the -
883 buffer of the given \a width and \a height. -
884 -
885 The \a attachment parameter describes the depth/stencil buffer -
886 configuration, \a target the texture target and \a internal_format -
887 the internal texture format. The default texture target is \c -
888 GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8 -
889 for desktop OpenGL and \c GL_RGBA for OpenGL/ES. -
890 -
891 \sa size(), texture(), attachment() -
892*/ -
893QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment attachment, -
894 GLenum target, GLenum internal_format) -
895 : d_ptr(new QGLFramebufferObjectPrivate) -
896{ -
897 Q_D(QGLFramebufferObject);
never executed (the execution status of this line is deduced): QGLFramebufferObjectPrivate * const d = d_func();
-
898 d->init(this, QSize(width, height), attachment, target, internal_format);
never executed (the execution status of this line is deduced): d->init(this, QSize(width, height), attachment, target, internal_format);
-
899}
never executed: }
0
900 -
901/*! \overload -
902 -
903 Constructs an OpenGL framebuffer object and binds a texture to the -
904 buffer of the given \a size. -
905 -
906 The \a attachment parameter describes the depth/stencil buffer -
907 configuration, \a target the texture target and \a internal_format -
908 the internal texture format. The default texture target is \c -
909 GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8 -
910 for desktop OpenGL and \c GL_RGBA for OpenGL/ES. -
911 -
912 \sa size(), texture(), attachment() -
913*/ -
914QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachment, -
915 GLenum target, GLenum internal_format) -
916 : d_ptr(new QGLFramebufferObjectPrivate) -
917{ -
918 Q_D(QGLFramebufferObject);
never executed (the execution status of this line is deduced): QGLFramebufferObjectPrivate * const d = d_func();
-
919 d->init(this, size, attachment, target, internal_format);
never executed (the execution status of this line is deduced): d->init(this, size, attachment, target, internal_format);
-
920}
never executed: }
0
921 -
922/*! -
923 \fn QGLFramebufferObject::~QGLFramebufferObject() -
924 -
925 Destroys the framebuffer object and frees any allocated resources. -
926*/ -
927QGLFramebufferObject::~QGLFramebufferObject() -
928{ -
929 Q_D(QGLFramebufferObject);
never executed (the execution status of this line is deduced): QGLFramebufferObjectPrivate * const d = d_func();
-
930 -
931 delete d->engine;
never executed (the execution status of this line is deduced): delete d->engine;
-
932 -
933 if (d->texture_guard)
never evaluated: d->texture_guard
0
934 d->texture_guard->free();
never executed: d->texture_guard->free();
0
935 if (d->color_buffer_guard)
never evaluated: d->color_buffer_guard
0
936 d->color_buffer_guard->free();
never executed: d->color_buffer_guard->free();
0
937 if (d->depth_buffer_guard)
never evaluated: d->depth_buffer_guard
0
938 d->depth_buffer_guard->free();
never executed: d->depth_buffer_guard->free();
0
939 if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard)
never evaluated: d->stencil_buffer_guard
never evaluated: d->stencil_buffer_guard != d->depth_buffer_guard
0
940 d->stencil_buffer_guard->free();
never executed: d->stencil_buffer_guard->free();
0
941 if (d->fbo_guard)
never evaluated: d->fbo_guard
0
942 d->fbo_guard->free();
never executed: d->fbo_guard->free();
0
943}
never executed: }
0
944 -
945/*! -
946 \fn bool QGLFramebufferObject::isValid() const -
947 -
948 Returns true if the framebuffer object is valid. -
949 -
950 The framebuffer can become invalid if the initialization process -
951 fails, the user attaches an invalid buffer to the framebuffer -
952 object, or a non-power of two width/height is specified as the -
953 texture size if the texture target is \c{GL_TEXTURE_2D}. -
954 The non-power of two limitation does not apply if the OpenGL version -
955 is 2.0 or higher, or if the GL_ARB_texture_non_power_of_two extension -
956 is present. -
957 -
958 The framebuffer can also become invalid if the QGLContext that -
959 the framebuffer was created within is destroyed and there are -
960 no other shared contexts that can take over ownership of the -
961 framebuffer. -
962*/ -
963bool QGLFramebufferObject::isValid() const -
964{ -
965 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
966 return d->valid && d->fbo_guard && d->fbo_guard->id();
never executed: return d->valid && d->fbo_guard && d->fbo_guard->id();
0
967} -
968 -
969/*! -
970 \fn bool QGLFramebufferObject::bind() -
971 -
972 Switches rendering from the default, windowing system provided -
973 framebuffer to this framebuffer object. -
974 Returns true upon success, false otherwise. -
975 -
976 \sa release() -
977*/ -
978bool QGLFramebufferObject::bind() -
979{ -
980 if (!isValid())
never evaluated: !isValid()
0
981 return false;
never executed: return false;
0
982 Q_D(QGLFramebufferObject);
never executed (the execution status of this line is deduced): QGLFramebufferObjectPrivate * const d = d_func();
-
983 QGL_FUNC_CONTEXT;
never executed (the execution status of this line is deduced): const QGLContext *ctx = QGLContext::currentContext();;
-
984 if (!ctx)
never evaluated: !ctx
0
985 return false; // Context no longer exists.
never executed: return false;
0
986 const QGLContext *current = QGLContext::currentContext();
never executed (the execution status of this line is deduced): const QGLContext *current = QGLContext::currentContext();
-
987#ifdef QT_DEBUG -
988 if (!current || -
989 QGLContextPrivate::contextGroup(current) != QGLContextPrivate::contextGroup(ctx)) -
990 { -
991 qWarning("QGLFramebufferObject::bind() called from incompatible context"); -
992 } -
993#endif -
994 glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer(0x8D40, d->fbo());
-
995 d->valid = d->checkFramebufferStatus();
never executed (the execution status of this line is deduced): d->valid = d->checkFramebufferStatus();
-
996 if (d->valid && current)
never evaluated: d->valid
never evaluated: current
0
997 current->d_ptr->current_fbo = d->fbo();
never executed: current->d_ptr->current_fbo = d->fbo();
0
998 return d->valid;
never executed: return d->valid;
0
999} -
1000 -
1001/*! -
1002 \fn bool QGLFramebufferObject::release() -
1003 -
1004 Switches rendering back to the default, windowing system provided -
1005 framebuffer. -
1006 Returns true upon success, false otherwise. -
1007 -
1008 \sa bind() -
1009*/ -
1010bool QGLFramebufferObject::release() -
1011{ -
1012 if (!isValid())
never evaluated: !isValid()
0
1013 return false;
never executed: return false;
0
1014 QGL_FUNC_CONTEXT;
never executed (the execution status of this line is deduced): const QGLContext *ctx = QGLContext::currentContext();;
-
1015 if (!ctx)
never evaluated: !ctx
0
1016 return false; // Context no longer exists.
never executed: return false;
0
1017 -
1018 const QGLContext *current = QGLContext::currentContext();
never executed (the execution status of this line is deduced): const QGLContext *current = QGLContext::currentContext();
-
1019 -
1020#ifdef QT_DEBUG -
1021 if (!current || -
1022 QGLContextPrivate::contextGroup(current) != QGLContextPrivate::contextGroup(ctx)) -
1023 { -
1024 qWarning("QGLFramebufferObject::release() called from incompatible context"); -
1025 } -
1026#endif -
1027 -
1028 if (current) {
never evaluated: current
0
1029 current->d_ptr->current_fbo = current->d_ptr->default_fbo;
never executed (the execution status of this line is deduced): current->d_ptr->current_fbo = current->d_ptr->default_fbo;
-
1030 glBindFramebuffer(GL_FRAMEBUFFER, current->d_ptr->default_fbo);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer(0x8D40, current->d_ptr->default_fbo);
-
1031 }
never executed: }
0
1032 -
1033 return true;
never executed: return true;
0
1034} -
1035 -
1036/*! -
1037 \fn GLuint QGLFramebufferObject::texture() const -
1038 -
1039 Returns the texture id for the texture attached as the default -
1040 rendering target in this framebuffer object. This texture id can -
1041 be bound as a normal texture in your own GL code. -
1042 -
1043 If a multisample framebuffer object is used then the value returned -
1044 from this function will be invalid. -
1045*/ -
1046GLuint QGLFramebufferObject::texture() const -
1047{ -
1048 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1049 return d->texture_guard ? d->texture_guard->id() : 0;
never executed: return d->texture_guard ? d->texture_guard->id() : 0;
0
1050} -
1051 -
1052/*! -
1053 \fn QSize QGLFramebufferObject::size() const -
1054 -
1055 Returns the size of the texture attached to this framebuffer -
1056 object. -
1057*/ -
1058QSize QGLFramebufferObject::size() const -
1059{ -
1060 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1061 return d->size;
never executed: return d->size;
0
1062} -
1063 -
1064/*! -
1065 Returns the format of this framebuffer object. -
1066*/ -
1067QGLFramebufferObjectFormat QGLFramebufferObject::format() const -
1068{ -
1069 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1070 return d->format;
never executed: return d->format;
0
1071} -
1072 -
1073/*! -
1074 \fn QImage QGLFramebufferObject::toImage() const -
1075 -
1076 Returns the contents of this framebuffer object as a QImage. -
1077*/ -
1078QImage QGLFramebufferObject::toImage() const -
1079{ -
1080 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1081 if (!d->valid)
never evaluated: !d->valid
0
1082 return QImage();
never executed: return QImage();
0
1083 -
1084 // qt_gl_read_frame_buffer doesn't work on a multisample FBO -
1085 if (format().samples() != 0) {
never evaluated: format().samples() != 0
0
1086 QGLFramebufferObject temp(size(), QGLFramebufferObjectFormat());
never executed (the execution status of this line is deduced): QGLFramebufferObject temp(size(), QGLFramebufferObjectFormat());
-
1087 -
1088 QRect rect(QPoint(0, 0), size());
never executed (the execution status of this line is deduced): QRect rect(QPoint(0, 0), size());
-
1089 blitFramebuffer(&temp, rect, const_cast<QGLFramebufferObject *>(this), rect);
never executed (the execution status of this line is deduced): blitFramebuffer(&temp, rect, const_cast<QGLFramebufferObject *>(this), rect);
-
1090 -
1091 return temp.toImage();
never executed: return temp.toImage();
0
1092 } -
1093 -
1094 bool wasBound = isBound();
never executed (the execution status of this line is deduced): bool wasBound = isBound();
-
1095 if (!wasBound)
never evaluated: !wasBound
0
1096 const_cast<QGLFramebufferObject *>(this)->bind();
never executed: const_cast<QGLFramebufferObject *>(this)->bind();
0
1097 QImage image = qt_gl_read_frame_buffer(d->size, format().internalTextureFormat() != GL_RGB, true);
never executed (the execution status of this line is deduced): QImage image = qt_gl_read_frame_buffer(d->size, format().internalTextureFormat() != 0x1907, true);
-
1098 if (!wasBound)
never evaluated: !wasBound
0
1099 const_cast<QGLFramebufferObject *>(this)->release();
never executed: const_cast<QGLFramebufferObject *>(this)->release();
0
1100 -
1101 return image;
never executed: return image;
0
1102} -
1103 -
1104Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
never executed: delete x;
never executed: return thisGlobalStatic.pointer.load();
never evaluated: !thisGlobalStatic.pointer.testAndSetOrdered(0, x)
never evaluated: !thisGlobalStatic.pointer.load()
never evaluated: !thisGlobalStatic.destroyed
0
1105 -
1106/*! \reimp */ -
1107QPaintEngine *QGLFramebufferObject::paintEngine() const -
1108{ -
1109 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1110 if (d->engine)
never evaluated: d->engine
0
1111 return d->engine;
never executed: return d->engine;
0
1112 -
1113 QPaintEngine *engine = qt_buffer_2_engine()->engine();
never executed (the execution status of this line is deduced): QPaintEngine *engine = qt_buffer_2_engine()->engine();
-
1114 if (engine->isActive() && engine->paintDevice() != this) {
never evaluated: engine->isActive()
never evaluated: engine->paintDevice() != this
0
1115 d->engine = new QGL2PaintEngineEx;
never executed (the execution status of this line is deduced): d->engine = new QGL2PaintEngineEx;
-
1116 return d->engine;
never executed: return d->engine;
0
1117 } -
1118 return engine;
never executed: return engine;
0
1119} -
1120 -
1121/*! -
1122 \fn bool QGLFramebufferObject::bindDefault() -
1123 \internal -
1124 -
1125 Switches rendering back to the default, windowing system provided -
1126 framebuffer. -
1127 Returns true upon success, false otherwise. -
1128 -
1129 \sa bind(), release() -
1130*/ -
1131bool QGLFramebufferObject::bindDefault() -
1132{ -
1133 QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
never executed (the execution status of this line is deduced): QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
-
1134 -
1135 if (ctx) {
never evaluated: ctx
0
1136 bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
never executed (the execution status of this line is deduced): bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
-
1137 if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
never evaluated: !ext_detected
never evaluated: ext_detected
never evaluated: !qt_resolve_framebufferobject_extensions(ctx)
0
1138 return false;
never executed: return false;
0
1139 -
1140 ctx->d_ptr->current_fbo = ctx->d_ptr->default_fbo;
never executed (the execution status of this line is deduced): ctx->d_ptr->current_fbo = ctx->d_ptr->default_fbo;
-
1141 glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->default_fbo);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer(0x8D40, ctx->d_ptr->default_fbo);
-
1142#ifdef QT_DEBUG -
1143 } else { -
1144 qWarning("QGLFramebufferObject::bindDefault() called without current context."); -
1145#endif -
1146 }
never executed: }
0
1147 -
1148 return ctx != 0;
never executed: return ctx != 0;
0
1149} -
1150 -
1151/*! -
1152 \fn bool QGLFramebufferObject::hasOpenGLFramebufferObjects() -
1153 -
1154 Returns true if the OpenGL \c{GL_EXT_framebuffer_object} extension -
1155 is present on this system; otherwise returns false. -
1156*/ -
1157bool QGLFramebufferObject::hasOpenGLFramebufferObjects() -
1158{ -
1159 return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
never executed: return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
0
1160} -
1161 -
1162/*! -
1163 \since 4.4 -
1164 -
1165 Draws the given texture, \a textureId, to the given target rectangle, -
1166 \a target, in OpenGL model space. The \a textureTarget should be a 2D -
1167 texture target. -
1168 -
1169 The framebuffer object should be bound when calling this function. -
1170 -
1171 Equivalent to the corresponding QGLContext::drawTexture(). -
1172*/ -
1173void QGLFramebufferObject::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) -
1174{ -
1175 const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
never executed (the execution status of this line is deduced): const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
-
1176}
never executed: }
0
1177 -
1178/*! -
1179 \since 4.4 -
1180 -
1181 Draws the given texture, \a textureId, at the given \a point in OpenGL -
1182 model space. The \a textureTarget should be a 2D texture target. -
1183 -
1184 The framebuffer object should be bound when calling this function. -
1185 -
1186 Equivalent to the corresponding QGLContext::drawTexture(). -
1187*/ -
1188void QGLFramebufferObject::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) -
1189{ -
1190 const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
never executed (the execution status of this line is deduced): const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
-
1191}
never executed: }
0
1192 -
1193/*! \reimp */ -
1194int QGLFramebufferObject::metric(PaintDeviceMetric metric) const -
1195{ -
1196 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1197 -
1198 float dpmx = qt_defaultDpiX()*100./2.54;
never executed (the execution status of this line is deduced): float dpmx = qt_defaultDpiX()*100./2.54;
-
1199 float dpmy = qt_defaultDpiY()*100./2.54;
never executed (the execution status of this line is deduced): float dpmy = qt_defaultDpiY()*100./2.54;
-
1200 int w = d->size.width();
never executed (the execution status of this line is deduced): int w = d->size.width();
-
1201 int h = d->size.height();
never executed (the execution status of this line is deduced): int h = d->size.height();
-
1202 switch (metric) { -
1203 case PdmWidth: -
1204 return w;
never executed: return w;
0
1205 -
1206 case PdmHeight: -
1207 return h;
never executed: return h;
0
1208 -
1209 case PdmWidthMM: -
1210 return qRound(w * 1000 / dpmx);
never executed: return qRound(w * 1000 / dpmx);
0
1211 -
1212 case PdmHeightMM: -
1213 return qRound(h * 1000 / dpmy);
never executed: return qRound(h * 1000 / dpmy);
0
1214 -
1215 case PdmNumColors: -
1216 return 0;
never executed: return 0;
0
1217 -
1218 case PdmDepth: -
1219 return 32;//d->depth;
never executed: return 32;
0
1220 -
1221 case PdmDpiX: -
1222 return qRound(dpmx * 0.0254);
never executed: return qRound(dpmx * 0.0254);
0
1223 -
1224 case PdmDpiY: -
1225 return qRound(dpmy * 0.0254);
never executed: return qRound(dpmy * 0.0254);
0
1226 -
1227 case PdmPhysicalDpiX: -
1228 return qRound(dpmx * 0.0254);
never executed: return qRound(dpmx * 0.0254);
0
1229 -
1230 case PdmPhysicalDpiY: -
1231 return qRound(dpmy * 0.0254);
never executed: return qRound(dpmy * 0.0254);
0
1232 -
1233 default: -
1234 qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric);
never executed (the execution status of this line is deduced): QMessageLogger("qglframebufferobject.cpp", 1234, __PRETTY_FUNCTION__).warning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric);
-
1235 break;
never executed: break;
0
1236 } -
1237 return 0;
never executed: return 0;
0
1238} -
1239 -
1240/*! -
1241 \fn GLuint QGLFramebufferObject::handle() const -
1242 -
1243 Returns the GL framebuffer object handle for this framebuffer -
1244 object (returned by the \c{glGenFrameBuffersEXT()} function). This -
1245 handle can be used to attach new images or buffers to the -
1246 framebuffer. The user is responsible for cleaning up and -
1247 destroying these objects. -
1248*/ -
1249GLuint QGLFramebufferObject::handle() const -
1250{ -
1251 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1252 return d->fbo();
never executed: return d->fbo();
0
1253} -
1254 -
1255/*! \fn int QGLFramebufferObject::devType() const -
1256 \internal -
1257*/ -
1258 -
1259 -
1260/*! -
1261 Returns the status of the depth and stencil buffers attached to -
1262 this framebuffer object. -
1263*/ -
1264 -
1265QGLFramebufferObject::Attachment QGLFramebufferObject::attachment() const -
1266{ -
1267 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1268 if (d->valid)
never evaluated: d->valid
0
1269 return d->fbo_attachment;
never executed: return d->fbo_attachment;
0
1270 return NoAttachment;
never executed: return NoAttachment;
0
1271} -
1272 -
1273/*! -
1274 \since 4.5 -
1275 -
1276 Returns true if the framebuffer object is currently bound to a context, -
1277 otherwise false is returned. -
1278*/ -
1279 -
1280bool QGLFramebufferObject::isBound() const -
1281{ -
1282 Q_D(const QGLFramebufferObject);
never executed (the execution status of this line is deduced): const QGLFramebufferObjectPrivate * const d = d_func();
-
1283 const QGLContext *current = QGLContext::currentContext();
never executed (the execution status of this line is deduced): const QGLContext *current = QGLContext::currentContext();
-
1284 return current ? current->d_ptr->current_fbo == d->fbo() : false;
never executed: return current ? current->d_ptr->current_fbo == d->fbo() : false;
0
1285} -
1286 -
1287/*! -
1288 \fn bool QGLFramebufferObject::hasOpenGLFramebufferBlit() -
1289 -
1290 \since 4.6 -
1291 -
1292 Returns true if the OpenGL \c{GL_EXT_framebuffer_blit} extension -
1293 is present on this system; otherwise returns false. -
1294 -
1295 \sa blitFramebuffer() -
1296*/ -
1297bool QGLFramebufferObject::hasOpenGLFramebufferBlit() -
1298{ -
1299 return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit);
never executed: return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit);
0
1300} -
1301 -
1302/*! -
1303 \since 4.6 -
1304 -
1305 Blits from the \a sourceRect rectangle in the \a source framebuffer -
1306 object to the \a targetRect rectangle in the \a target framebuffer object. -
1307 -
1308 If \a source or \a target is 0, the default framebuffer will be used -
1309 instead of a framebuffer object as source or target respectively. -
1310 -
1311 The \a buffers parameter should be a mask consisting of any combination of -
1312 \c GL_COLOR_BUFFER_BIT, \c GL_DEPTH_BUFFER_BIT, and -
1313 \c GL_STENCIL_BUFFER_BIT. Any buffer type that is not present both -
1314 in the source and target buffers is ignored. -
1315 -
1316 The \a sourceRect and \a targetRect rectangles may have different sizes; -
1317 in this case \a buffers should not contain \c GL_DEPTH_BUFFER_BIT or -
1318 \c GL_STENCIL_BUFFER_BIT. The \a filter parameter should be set to -
1319 \c GL_LINEAR or \c GL_NEAREST, and specifies whether linear or nearest -
1320 interpolation should be used when scaling is performed. -
1321 -
1322 If \a source equals \a target a copy is performed within the same buffer. -
1323 Results are undefined if the source and target rectangles overlap and -
1324 have different sizes. The sizes must also be the same if any of the -
1325 framebuffer objects are multisample framebuffers. -
1326 -
1327 Note that the scissor test will restrict the blit area if enabled. -
1328 -
1329 This function will have no effect unless hasOpenGLFramebufferBlit() returns -
1330 true. -
1331 -
1332 \sa hasOpenGLFramebufferBlit() -
1333*/ -
1334void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect, -
1335 QGLFramebufferObject *source, const QRect &sourceRect, -
1336 GLbitfield buffers, -
1337 GLenum filter) -
1338{ -
1339 if (!(QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit))
never evaluated: !(QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit)
0
1340 return;
never executed: return;
0
1341 -
1342 const QGLContext *ctx = QGLContext::currentContext();
never executed (the execution status of this line is deduced): const QGLContext *ctx = QGLContext::currentContext();
-
1343 if (!ctx || !ctx->contextHandle())
never evaluated: !ctx
never evaluated: !ctx->contextHandle()
0
1344 return;
never executed: return;
0
1345 -
1346 QSurface *surface = ctx->contextHandle()->surface();
never executed (the execution status of this line is deduced): QSurface *surface = ctx->contextHandle()->surface();
-
1347 -
1348 const int height = static_cast<QWindow *>(surface)->height();
never executed (the execution status of this line is deduced): const int height = static_cast<QWindow *>(surface)->height();
-
1349 -
1350 const int sh = source ? source->height() : height;
never evaluated: source
0
1351 const int th = target ? target->height() : height;
never evaluated: target
0
1352 -
1353 const int sx0 = sourceRect.left();
never executed (the execution status of this line is deduced): const int sx0 = sourceRect.left();
-
1354 const int sx1 = sourceRect.left() + sourceRect.width();
never executed (the execution status of this line is deduced): const int sx1 = sourceRect.left() + sourceRect.width();
-
1355 const int sy0 = sh - (sourceRect.top() + sourceRect.height());
never executed (the execution status of this line is deduced): const int sy0 = sh - (sourceRect.top() + sourceRect.height());
-
1356 const int sy1 = sh - sourceRect.top();
never executed (the execution status of this line is deduced): const int sy1 = sh - sourceRect.top();
-
1357 -
1358 const int tx0 = targetRect.left();
never executed (the execution status of this line is deduced): const int tx0 = targetRect.left();
-
1359 const int tx1 = targetRect.left() + targetRect.width();
never executed (the execution status of this line is deduced): const int tx1 = targetRect.left() + targetRect.width();
-
1360 const int ty0 = th - (targetRect.top() + targetRect.height());
never executed (the execution status of this line is deduced): const int ty0 = th - (targetRect.top() + targetRect.height());
-
1361 const int ty1 = th - targetRect.top();
never executed (the execution status of this line is deduced): const int ty1 = th - targetRect.top();
-
1362 -
1363 glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer(0x8CA8, source ? source->handle() : 0);
-
1364 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer(0x8CA9, target ? target->handle() : 0);
-
1365 -
1366 glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
-
1367 tx0, ty0, tx1, ty1,
never executed (the execution status of this line is deduced): tx0, ty0, tx1, ty1,
-
1368 buffers, filter);
never executed (the execution status of this line is deduced): buffers, filter);
-
1369 -
1370 glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
never executed (the execution status of this line is deduced): QGLContextPrivate::extensionFuncs(ctx).qt_glBindFramebuffer(0x8D40, ctx->d_ptr->current_fbo);
-
1371}
never executed: }
0
1372 -
1373QT_END_NAMESPACE -
1374 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial