opengl/qopenglframebufferobject.cpp

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

Generated by Squish Coco Non-Commercial