Solved glReadPixels works fine in Linux but not in Windows 10
-
I'm trying to save an image drawn in an QOpenGLWindow. The code is simple
void XYScene::CreateTIFF() { emit AlertMsg("Creating Screenshot image as TIFF ....",' '); int nNoRGBABytes = XImageSize*YImageSize*4; GLubyte* ScreenData=nullptr; try{ ScreenData = new GLubyte[size_t(nNoRGBABytes)]; } catch (std::bad_alloc& ba) { emit AlertMsg(QString("Unable to allocate memory for TIFF creation<br>Reason: %1").arg(ba.what()),'r'); return; } glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, XImageSize, YImageSize, GL_RGBA, GL_UNSIGNED_BYTE, ScreenData); .........
This code works perfectly in Linux (Fedora using XWindows and g++) but not in Windows (Win10 using MSVC 2019). When I look at ScreenData in Windows it's filled with zero's which would seem to indicate that something is being transferred but not from the right place. Is there some code that I need to insert for it to work on Windows?
This is on a dual-boot machine so that all that differs is the Operating system and the NVIDIA drivers (and whatever difference there is in how OpenGL is implemented). In Windows Qt::AA_UseDesktopOpenGL is set via QCoreApplication.
-
I did, but same problem - it turns out that in Windows, with my setup, the image is on the back buffer, not the front, so the solution was:
void XYScene::CreateTIFF() { emit AlertMsg("Creating Screenshot image as TIFF ....",' '); int nNoRGBABytes = XImageSize*YImageSize*4; GLubyte* ScreenData=nullptr; try{ ScreenData = new GLubyte[size_t(nNoRGBABytes)]; } catch (std::bad_alloc& ba) { emit AlertMsg(QString("Unable to allocate memory for TIFF creation<br>Reason: %1").arg(ba.what()),'r'); return; } #ifdef WIN32 QOpenGLContext* ctx = context(); QSurface* ctsurf = ctx->surface(); ctx->swapBuffers(ctsurf); // swap buffers to bring image to the front buffer to be read. #endif glReadPixels(0, 0, XImageSize, YImageSize, GL_RGBA, GL_UNSIGNED_BYTE, ScreenData); #ifdef WIN32 ctx->swapBuffers(ctsurf); // need this to see the image otherwise screen is black makeCurrent(); #endif
Why this happening in my setup and whether it would occur on other Window systems, I don't know.
-
Hi,
Why not use QOpenGLWindow::grabFramebuffer ?
-
I did, but same problem - it turns out that in Windows, with my setup, the image is on the back buffer, not the front, so the solution was:
void XYScene::CreateTIFF() { emit AlertMsg("Creating Screenshot image as TIFF ....",' '); int nNoRGBABytes = XImageSize*YImageSize*4; GLubyte* ScreenData=nullptr; try{ ScreenData = new GLubyte[size_t(nNoRGBABytes)]; } catch (std::bad_alloc& ba) { emit AlertMsg(QString("Unable to allocate memory for TIFF creation<br>Reason: %1").arg(ba.what()),'r'); return; } #ifdef WIN32 QOpenGLContext* ctx = context(); QSurface* ctsurf = ctx->surface(); ctx->swapBuffers(ctsurf); // swap buffers to bring image to the front buffer to be read. #endif glReadPixels(0, 0, XImageSize, YImageSize, GL_RGBA, GL_UNSIGNED_BYTE, ScreenData); #ifdef WIN32 ctx->swapBuffers(ctsurf); // need this to see the image otherwise screen is black makeCurrent(); #endif
Why this happening in my setup and whether it would occur on other Window systems, I don't know.