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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
|
||||
: QImage::Format_RGB32);
|
||||
int w = size.width();
|
||||
int h = size.height();
|
||||
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
convertFromGLImage(img, w, h, alpha_format, include_alpha);
|
||||
return img;
|
||||
|
||||
#ifdef QT_OPENGL_ES
|
||||
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…
Reference in New Issue
Block a user