aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/opengl/opengl-graphics.cpp
diff options
context:
space:
mode:
authorJohannes Schickel2013-10-19 20:39:01 +0200
committerJohannes Schickel2013-10-19 22:18:22 +0200
commit05c347fc8ad8edc990c9d6e7c15a12d93bd8a3a3 (patch)
treeb799e0558717fc4ee57bfbaef8aed71dcea2539d /backends/graphics/opengl/opengl-graphics.cpp
parent37f71235529f8fd4a4c90389dc6a3b41e355f4a9 (diff)
downloadscummvm-rg350-05c347fc8ad8edc990c9d6e7c15a12d93bd8a3a3.tar.gz
scummvm-rg350-05c347fc8ad8edc990c9d6e7c15a12d93bd8a3a3.tar.bz2
scummvm-rg350-05c347fc8ad8edc990c9d6e7c15a12d93bd8a3a3.zip
OPENGL/SDL: Add screenshot support.
Diffstat (limited to 'backends/graphics/opengl/opengl-graphics.cpp')
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index e3c56dccca..00e8dc358e 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -29,6 +29,7 @@
#include "common/textconsole.h"
#include "common/translation.h"
#include "common/algorithm.h"
+#include "common/file.h"
#ifdef USE_OSD
#include "common/tokenizer.h"
#include "common/rect.h"
@@ -849,6 +850,11 @@ void OpenGLGraphicsManager::notifyContextChange(const Graphics::PixelFormat &def
GLCALL(glEnable(GL_TEXTURE_2D));
+ // We use a "pack" alignment (when reading from textures) to 4 here,
+ // since the only place where we really use it is the BMP screenshot
+ // code and that requires the same alignment too.
+ GLCALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
+
// Query information needed by textures.
Texture::queryTextureInformation();
@@ -1082,4 +1088,61 @@ const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
}
#endif
+void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
+ const uint width = _outputScreenWidth;
+ const uint height = _outputScreenHeight;
+
+ // A line of a BMP image must have a size divisible by 4.
+ // We calculate the padding bytes needed here.
+ // Since we use a 3 byte per pixel mode, we can use width % 4 here, since
+ // it is equal to 4 - (width * 3) % 4. (4 - (width * Bpp) % 4, is the
+ // usual way of computing the padding bytes required).
+ const uint linePaddingSize = width % 4;
+ const uint lineSize = width * 3 + linePaddingSize;
+
+ // Allocate memory for screenshot
+ uint8 *pixels = new uint8[lineSize * height];
+
+ // Get pixel data from OpenGL buffer
+ GLCALL(glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels));
+
+ // BMP stores as BGR. Since we can't assume that GL_BGR is supported we
+ // will swap the components from the RGB we read to BGR on our own.
+ for (uint y = height; y-- > 0;) {
+ uint8 *line = pixels + y * lineSize;
+
+ for (uint x = width; x > 0; --x, line += 3) {
+ SWAP(line[0], line[2]);
+ }
+ }
+
+ // Open file
+ Common::DumpFile out;
+ out.open(filename);
+
+ // Write BMP header
+ out.writeByte('B');
+ out.writeByte('M');
+ out.writeUint32LE(height * lineSize + 54);
+ out.writeUint32LE(0);
+ out.writeUint32LE(54);
+ out.writeUint32LE(40);
+ out.writeUint32LE(width);
+ out.writeUint32LE(height);
+ out.writeUint16LE(1);
+ out.writeUint16LE(24);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+ out.writeUint32LE(0);
+
+ // Write pixel data to BMP
+ out.write(pixels, lineSize * height);
+
+ // Free allocated memory
+ delete[] pixels;
+}
+
} // End of namespace OpenGL