📄 qglframebufferobject.cpp
字号:
#endifQGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) : d_ptr(new QGLFramebufferObjectPrivate){ Q_D(QGLFramebufferObject); d->init(size, NoAttachment, target, DEFAULT_FORMAT);}/*! \overload Constructs an OpenGL framebuffer object and binds a 2D GL texture to the buffer of the given \a width and \a height. \sa size(), texture()*/QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target) : d_ptr(new QGLFramebufferObjectPrivate){ Q_D(QGLFramebufferObject); d->init(QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);}/*! \overload Constructs an OpenGL framebuffer object and binds a texture to the buffer of the given \a width and \a height. The \a attachment parameter describes the depth/stencil buffer configuration, \a target the texture target and \a internal_format the internal texture format. The default texture target is \c GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8. \sa size(), texture(), attachment()*/QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment attachment, GLenum target, GLenum internal_format) : d_ptr(new QGLFramebufferObjectPrivate){ Q_D(QGLFramebufferObject); d->init(QSize(width, height), attachment, target, internal_format);}/*! \overload Constructs an OpenGL framebuffer object and binds a texture to the buffer of the given \a size. The \a attachment parameter describes the depth/stencil buffer configuration, \a target the texture target and \a internal_format the internal texture format. The default texture target is \c GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8. \sa size(), texture(), attachment()*/QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachment, GLenum target, GLenum internal_format) : d_ptr(new QGLFramebufferObjectPrivate){ Q_D(QGLFramebufferObject); d->init(size, attachment, target, internal_format);}/*! \fn QGLFramebufferObject::~QGLFramebufferObject() Destroys the framebuffer object and frees any allocated resources.*/QGLFramebufferObject::~QGLFramebufferObject(){ Q_D(QGLFramebufferObject); QGL_FUNC_CONTEXT; if (isValid() && (d->ctx == QGLContext::currentContext() || qgl_share_reg()->checkSharing(d->ctx, QGLContext::currentContext()))) { glDeleteTextures(1, &d->texture); if (d->depth_stencil_buffer) glDeleteRenderbuffersEXT(1, &d->depth_stencil_buffer); glDeleteFramebuffersEXT(1, &d->fbo); } delete d_ptr;}/*! \fn bool QGLFramebufferObject::isValid() const Returns true if the framebuffer object is valid. The framebuffer can become invalid if the initialization process fails, the user attaches an invalid buffer to the framebuffer object, or a non-power of 2 width/height is specified as the texture size if the texture target is \c{GL_TEXTURE_2D}.*/bool QGLFramebufferObject::isValid() const{ Q_D(const QGLFramebufferObject); return d->valid;}/*! \fn bool QGLFramebufferObject::bind() Switches rendering from the default, windowing system provided framebuffer to this framebuffer object. Returns true upon success, false otherwise.*/bool QGLFramebufferObject::bind(){ if (!isValid()) return false; Q_D(QGLFramebufferObject); QGL_FUNC_CONTEXT; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, d->fbo); d->valid = d->checkFramebufferStatus(); return d->valid;}/*! \fn bool QGLFramebufferObject::release() Switches rendering back to the default, windowing system provided framebuffer. Returns true upon success, false otherwise.*/bool QGLFramebufferObject::release(){ if (!isValid()) return false; Q_D(QGLFramebufferObject); QGL_FUNC_CONTEXT; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); d->valid = d->checkFramebufferStatus(); return d->valid;}/*! \fn GLuint QGLFramebufferObject::texture() const Returns the texture id for the texture attached as the default rendering target in this framebuffer object. This texture id can be bound as a normal texture in your own GL code.*/GLuint QGLFramebufferObject::texture() const{ Q_D(const QGLFramebufferObject); return d->texture;}/*! \fn QSize QGLFramebufferObject::size() const Returns the size of the texture attached to this framebuffer object.*/QSize QGLFramebufferObject::size() const{ Q_D(const QGLFramebufferObject); return d->size;}/*! \fn QImage QGLFramebufferObject::toImage() const Returns the contents of this framebuffer object as a QImage.*/QImage QGLFramebufferObject::toImage() const{ Q_D(const QGLFramebufferObject); if (!d->valid) return QImage(); const_cast<QGLFramebufferObject *>(this)->bind(); QImage::Format image_format = QImage::Format_RGB32; if (d->ctx->format().alpha()) image_format = QImage::Format_ARGB32_Premultiplied; QImage img(d->size, image_format); int w = d->size.width(); int h = d->size.height(); // ### fix the read format so that we don't have to do all the byte swapping glReadPixels(0, 0, d->size.width(), d->size.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { // OpenGL gives RGBA; Qt wants ARGB uint *p = (uint*)img.bits(); uint *end = p + w*h; if (1) { while (p < end) { uint a = *p << 24; *p = (*p >> 8) | a; p++; } } else { while (p < end) { *p = 0xFF000000 | (*p>>8); ++p; } } } else { // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB img = img.rgbSwapped(); } const_cast<QGLFramebufferObject *>(this)->release(); return img.mirrored();}Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_buffer_paintengine)/*! \reimp */QPaintEngine *QGLFramebufferObject::paintEngine() const{ return qt_buffer_paintengine();}/*! \fn bool QGLFramebufferObject::hasOpenGLFramebufferObjects() Returns true if the OpenGL \c{GL_EXT_framebuffer_object} extension is present on this system; otherwise returns false.*/bool QGLFramebufferObject::hasOpenGLFramebufferObjects(){ QGLWidget dmy; // needed to detect and init the QGLExtensions object return (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject);}extern int qt_defaultDpi();/*! \reimp */int QGLFramebufferObject::metric(PaintDeviceMetric metric) const{ Q_D(const QGLFramebufferObject); float dpmx = qt_defaultDpi()*100./2.54; float dpmy = qt_defaultDpi()*100./2.54; int w = d->size.width(); int h = d->size.height(); switch (metric) { case PdmWidth: return w; case PdmHeight: return h; case PdmWidthMM: return qRound(w * 1000 / dpmx); case PdmHeightMM: return qRound(h * 1000 / dpmy); case PdmNumColors: return 0; case PdmDepth: return 32;//d->depth; case PdmDpiX: return (int)(dpmx * 0.0254); case PdmDpiY: return (int)(dpmy * 0.0254); case PdmPhysicalDpiX: return (int)(dpmx * 0.0254); case PdmPhysicalDpiY: return (int)(dpmy * 0.0254); default: qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric); break; } return 0;}/*! \fn GLuint QGLFramebufferObject::handle() const Returns the GL framebuffer object handle for this framebuffer object (returned by the \c{glGenFrameBuffersEXT()} function). This handle can be used to attach new images or buffers to the framebuffer. The user is responsible for cleaning up and destroying these objects.*/GLuint QGLFramebufferObject::handle() const{ Q_D(const QGLFramebufferObject); return d->fbo;}/*! \fn int QGLFramebufferObject::devType() const \reimp*//*! Returns the status of the depth and stencil buffers attached to this framebuffer object.*/QGLFramebufferObject::Attachment QGLFramebufferObject::attachment() const{ Q_D(const QGLFramebufferObject); if (d->valid) return d->fbo_attachment; return NoAttachment;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -