Simplify and speed up OpenGL framebuffer grabbing.
If possible, let glReadPixels() itself provide the pixel format that QImage requires, so we can drop the pixel manipulation afterwards. Change-Id: I6c9226003c15d49548fa00696f31d0b2e26c0783 Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
This commit is contained in:
parent
89ccb0a699
commit
0d519164f2
@ -1014,66 +1014,25 @@ QOpenGLFramebufferObjectFormat QOpenGLFramebufferObject::format() const
|
|||||||
return d->format;
|
return d->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
/*
|
|
||||||
Read back the contents of the currently bound framebuffer, used in
|
|
||||||
QGLWidget::grabFrameBuffer(), QGLPixelbuffer::toImage() and
|
|
||||||
QGLFramebufferObject::toImage()
|
|
||||||
*/
|
|
||||||
|
|
||||||
void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha)
|
|
||||||
{
|
|
||||||
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
|
|
||||||
// OpenGL gives RGBA; Qt wants ARGB
|
|
||||||
uint *p = (uint*)img.bits();
|
|
||||||
uint *end = p + w*h;
|
|
||||||
if (alpha_format && include_alpha) {
|
|
||||||
while (p < end) {
|
|
||||||
uint a = *p << 24;
|
|
||||||
*p = (*p >> 8) | a;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This is an old legacy fix for PowerPC based Macs, which
|
|
||||||
// we shouldn't remove
|
|
||||||
while (p < end) {
|
|
||||||
*p = 0xff000000 | (*p>>8);
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB
|
|
||||||
for (int y = 0; y < h; y++) {
|
|
||||||
uint *q = (uint*)img.scanLine(y);
|
|
||||||
for (int x=0; x < w; ++x) {
|
|
||||||
const uint pixel = *q;
|
|
||||||
if (alpha_format && include_alpha) {
|
|
||||||
*q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff)
|
|
||||||
| (pixel & 0xff00ff00);
|
|
||||||
} else {
|
|
||||||
*q = 0xff000000 | ((pixel << 16) & 0xff0000)
|
|
||||||
| ((pixel >> 16) & 0xff) | (pixel & 0x00ff00);
|
|
||||||
}
|
|
||||||
|
|
||||||
q++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
img = img.mirrored();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
|
Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
|
||||||
{
|
{
|
||||||
QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
|
QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
|
||||||
: QImage::Format_RGB32);
|
: QImage::Format_RGB32);
|
||||||
int w = size.width();
|
int w = size.width();
|
||||||
int h = size.height();
|
int h = size.height();
|
||||||
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
|
||||||
convertFromGLImage(img, w, h, alpha_format, include_alpha);
|
#ifdef QT_OPENGL_ES
|
||||||
return img;
|
GLint fmt = GL_BGRA_EXT;
|
||||||
|
#else
|
||||||
|
GLint fmt = GL_BGRA;
|
||||||
|
#endif
|
||||||
|
while (glGetError());
|
||||||
|
glReadPixels(0, 0, w, h, fmt, GL_UNSIGNED_BYTE, img.bits());
|
||||||
|
if (glGetError()) {
|
||||||
|
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||||
|
img = img.rgbSwapped();
|
||||||
|
}
|
||||||
|
return img.mirrored();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user