From 41cd425f91f3ac88f6d00597daa06ebfb3a2b7d0 Mon Sep 17 00:00:00 2001 From: Wilhansen Li Date: Thu, 14 Feb 2019 23:00:03 +0800 Subject: [PATCH] Fix screenshot saving from wrong buffer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For double-buffered setups, the screenshot feature does not work because glReadPixels is reading from the back buffer, which has already been swapped by the time the process exits. There are some cases it works though, in particular, if onScreenshot is triggered by the drawDone event because it’s called before the buffer swap is done. This fixes the problem by ensuring that the front buffer is what always gets read for screenshot saving. --- src/main.cpp | 6 +++--- src/sandbox.cpp | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0ec7403f..a9b9a35a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1102,12 +1102,12 @@ int main(int argc, char **argv){ // Draw Cursor and 2D Debug elements sandbox.drawDebug2D(); - // Finish drawing - sandbox.drawDone(); - // Swap the buffers renderGL(); + // Finish drawing + sandbox.drawDone(); + if ( timeLimit >= 0.0 && getTime() >= timeLimit ) { bRun.store(false); } diff --git a/src/sandbox.cpp b/src/sandbox.cpp index a8d925cf..8078c09d 100644 --- a/src/sandbox.cpp +++ b/src/sandbox.cpp @@ -1037,8 +1037,22 @@ void Sandbox::onViewportResize(int _newWidth, int _newHeight) { void Sandbox::onScreenshot(std::string _file) { if (_file != "" && isGL()) { unsigned char* pixels = new unsigned char[getWindowWidth() * getWindowHeight()*4]; - glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pixels); - savePixels(_file, pixels, getWindowWidth(), getWindowHeight()); + + glGetError(); + GLint currentBuffer; + glGetIntegerv(GL_READ_BUFFER, ¤tBuffer); + + glReadBuffer(GL_FRONT); + { + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pixels); + GLenum err; + while ( (err = glGetError()) != GL_NO_ERROR ) { + std::cout << "// Error in saving screenshot: 0x" << std::hex << err << std::endl; + } + savePixels(_file, pixels, getWindowWidth(), getWindowHeight()); + } + glReadBuffer(currentBuffer); if (!m_record) { std::cout << "// Screenshot saved to " << _file << std::endl;