/*!
\class QGLPixelBuffer
\brief The QGLPixelBuffer class encapsulates an OpenGL pbuffer.
\since 4.1
\ingroup painting-3D
Rendering into a pbuffer is normally done using full hardware
acceleration. This can be significantly faster than rendering
into a QPixmap.
There are three approaches to using this class:
\list 1
\o \bold{We can draw into the pbuffer and convert it to a QImage
using toImage().} This is normally much faster than calling
QGLWidget::renderPixmap().
\o \bold{We can draw into the pbuffer and copy the contents into
an OpenGL texture using updateDynamicTexture().} This allows
us to create dynamic textures and works on all systems
with pbuffer support.
\o \bold{On systems that support it, we can bind the pbuffer to
an OpenGL texture.} The texture is then updated automatically
when the pbuffer contents change, eliminating the need for
additional copy operations. This is supported only on Windows
and Mac OS X systems that provide the \c render_texture
extension.
\endlist
Pbuffers are provided by the OpenGL \c pbuffer extension; call
hasOpenGLPbuffer() to find out if the system provides pbuffers.
\sa {opengl/pbuffers}{Pbuffers Example}
*/
#include <QtCore/qglobal.h>
#if !defined(QT_OPENGL_ES_1)
#include <private/qpaintengineex_opengl2_p.h>
#endif
#include <qglpixelbuffer.h>
#include <private/qglpixelbuffer_p.h>
#include <qimage.h>
#ifndef QT_OPENGL_ES_2
#include <private/qpaintengine_opengl_p.h>
#endif
QT_BEGIN_NAMESPACE
#if !defined(QT_OPENGL_ES_2)
extern void qgl_cleanup_glyph_cache(QGLContext *);
#else
void qgl_cleanup_glyph_cache(QGLContext *) {}
#endif
extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
QGLContext* QGLPBufferGLPaintDevice::context() const
{
return pbuf->d_func()->qctx;
}
void QGLPBufferGLPaintDevice::endPaint() {
glFlush();
QGLPaintDevice::endPaint();
}
void QGLPBufferGLPaintDevice::setPBuffer(QGLPixelBuffer* pb)
{
pbuf = pb;
}
void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget)
{
Q_Q(QGLPixelBuffer);
if(init(size, format, shareWidget)) {
req_size = size;
req_format = format;
req_shareWidget = shareWidget;
invalid = false;
qctx = new QGLContext(format);
qctx->d_func()->sharing = (shareWidget != 0);
if (shareWidget != 0 && shareWidget->d_func()->glcx) {
QGLContextGroup::addShare(qctx, shareWidget->d_func()->glcx);
shareWidget->d_func()->glcx->d_func()->sharing = true;
}
glDevice.setPBuffer(q);
qctx->d_func()->paintDevice = q;
qctx->d_func()->valid = true;
#if defined(Q_WS_WIN) && !defined(QT_OPENGL_ES)
qctx->d_func()->dc = dc;
qctx->d_func()->rc = ctx;
#elif (defined(Q_WS_X11) && defined(QT_NO_EGL))
qctx->d_func()->cx = ctx;
qctx->d_func()->pbuf = (void *) pbuf;
qctx->d_func()->vi = 0;
#elif defined(Q_WS_MAC)
qctx->d_func()->cx = ctx;
qctx->d_func()->vi = 0;
#elif !defined(QT_NO_EGL)
qctx->d_func()->eglContext = ctx;
qctx->d_func()->eglSurface = pbuf;
#endif
}
}
/*!
Constructs an OpenGL pbuffer of the given \a size. If no \a
format is specified, the \l{QGLFormat::defaultFormat()}{default
format} is used. If the \a shareWidget parameter points to a
valid QGLWidget, the pbuffer will share its context with \a
shareWidget.
If you intend to bind this pbuffer as a dynamic texture, the width
and height components of \c size must be powers of two (e.g., 512
x 128).
\sa size(), format()
*/
QGLPixelBuffer::QGLPixelBuffer(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget)
: d_ptr(new QGLPixelBufferPrivate(this))
{
Q_D(QGLPixelBuffer);
d->common_init(size, format, shareWidget);
}
/*! \overload
Constructs an OpenGL pbuffer with the \a width and \a height. If
no \a format is specified, the
\l{QGLFormat::defaultFormat()}{default format} is used. If the \a
shareWidget parameter points to a valid QGLWidget, the pbuffer
will share its context with \a shareWidget.
If you intend to bind this pbuffer as a dynamic texture, the width
and height components of \c size must be powers of two (e.g., 512
x 128).
\sa size(), format()
*/
QGLPixelBuffer::QGLPixelBuffer(int width, int height, const QGLFormat &format, QGLWidget *shareWidget)
: d_ptr(new QGLPixelBufferPrivate(this))
{
Q_D(QGLPixelBuffer);
d->common_init(QSize(width, height), format, shareWidget);
}
/*! \fn QGLPixelBuffer::~QGLPixelBuffer()
Destroys the pbuffer and frees any allocated resources.
*/
QGLPixelBuffer::~QGLPixelBuffer()
{
Q_D(QGLPixelBuffer);
// defined in qpaintengine_opengl.cpp
QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext());
if (current != d->qctx)
makeCurrent();
qgl_cleanup_glyph_cache(d->qctx);
d->cleanup();
delete d->qctx;
if (current && current != d->qctx)
current->makeCurrent();
}
/*! \fn bool QGLPixelBuffer::makeCurrent()
Makes this pbuffer the current OpenGL rendering context. Returns
true on success; otherwise returns false.
\sa QGLContext::makeCurrent(), doneCurrent()
*/
bool QGLPixelBuffer::makeCurrent()
{
Q_D(QGLPixelBuffer);
if (d->invalid)
return false;
d->qctx->makeCurrent();
return true;
}
/*! \fn bool QGLPixelBuffer::doneCurrent()
Makes no context the current OpenGL context. Returns true on
success; otherwise returns false.
*/
bool QGLPixelBuffer::doneCurrent()
{
Q_D(QGLPixelBuffer);
if (d->invalid)
return false;
d->qctx->doneCurrent();
return true;
}
/*!
Generates and binds a 2D GL texture that is the same size as the
pbuffer, and returns the texture's ID. This can be used in
conjunction with bindToDynamicTexture() and
updateDynamicTexture().
\sa size()
*/
#if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && defined(QT_NO_EGL)
GLuint QGLPixelBuffer::generateDynamicTexture() const
{
Q_D(const QGLPixelBuffer);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return texture;
}
#endif
/*! \fn bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
Binds the texture specified by \a texture_id to this pbuffer.
Returns true on success; otherwise returns false.
The texture must be of the same size and format as the pbuffer.
To unbind the texture, call releaseFromDynamicTexture(). While
the texture is bound, it is updated automatically when the
pbuffer contents change, eliminating the need for additional copy
operations.
Example:
\snippet doc/src/snippets/code/src_opengl_qglpixelbuffer.cpp 0
\warning This function uses the \c {render_texture} extension,
which is currently not supported under X11. An alternative that
works on all systems (including X11) is to manually copy the
pbuffer contents to a texture using updateDynamicTexture().
\warning For the bindToDynamicTexture() call to succeed on the
Mac OS X, the pbuffer needs a shared context, i.e. the
QGLPixelBuffer must be created with a share widget.
\sa generateDynamicTexture(), releaseFromDynamicTexture()
*/
/*! \fn void QGLPixelBuffer::releaseFromDynamicTexture()
Releases the pbuffer from any previously bound texture.
\sa bindToDynamicTexture()
*/
/*! \fn bool QGLPixelBuffer::hasOpenGLPbuffers()
Returns true if the OpenGL \c pbuffer extension is present on
this system; otherwise returns
qglpixelbuffer.rar_The Class
版权申诉
64 浏览量
2022-09-24
19:22:22
上传
评论
收藏 4KB RAR 举报
林当时
- 粉丝: 99
- 资源: 1万+
最新资源
- 基于matlab的虫害侵蚀系统带Gui界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的教室人数统计系统 可以统计正脸情况下的人数+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计
- 基于MATLAB的水果分级系统,带GUI界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB的车票发票识别系统带GUI界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 微信小程序电商实战课程SpringBoot2+Vue3+Element plus.rar
- 4.mht
- vulnhub靶场实战系列-DC-1实战流程图
- 使用python绘制一个笑脸
- Java 23种设计模式全归纳
- python完整代码-汉诺塔
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈