From 796a304479d66aefcc468ce62ad15aaafee993e5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 29 Nov 2010 14:21:06 +0000 Subject: [PATCH] Dump bitmaps. --- .gitignore | 1 + bmp.hpp | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++ glretrace.py | 37 ++++++++++---- 3 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 bmp.hpp diff --git a/.gitignore b/.gitignore index 8cdc5ca..6f6c726 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .*.sw? *~ *.a +*.bmp *.bz2 *.dll *.exe diff --git a/bmp.hpp b/bmp.hpp new file mode 100644 index 0000000..cc5a773 --- /dev/null +++ b/bmp.hpp @@ -0,0 +1,135 @@ +/************************************************************************** + * + * Copyright 2008-2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _BMP_HPP_ +#define _BMP_HPP_ + + +#include + + +namespace BMP { + +#pragma pack(push,2) +struct FileHeader { + uint16_t bfType; + uint32_t bfSize; + uint16_t bfReserved1; + uint16_t bfReserved2; + uint32_t bfOffBits; +}; +#pragma pack(pop) + +struct InfoHeader { + uint32_t biSize; + int32_t biWidth; + int32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + int32_t biXPelsPerMeter; + int32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; +}; + +struct Pixel { + uint8_t rgbBlue; + uint8_t rgbGreen; + uint8_t rgbRed; + uint8_t rgbAlpha; +}; + + +static inline void +write(const char *filename, + const unsigned char *rgba, + unsigned width, unsigned height, + unsigned stride, + bool flip = false) +{ + struct FileHeader bmfh; + struct InfoHeader bmih; + unsigned x, y; + + bmfh.bfType = 0x4d42; + bmfh.bfSize = 14 + 40 + height*width*4; + bmfh.bfReserved1 = 0; + bmfh.bfReserved2 = 0; + bmfh.bfOffBits = 14 + 40; + + bmih.biSize = 40; + bmih.biWidth = width; + bmih.biHeight = height; + bmih.biPlanes = 1; + bmih.biBitCount = 32; + bmih.biCompression = 0; + bmih.biSizeImage = height*width*4; + bmih.biXPelsPerMeter = 0; + bmih.biYPelsPerMeter = 0; + bmih.biClrUsed = 0; + bmih.biClrImportant = 0; + + std::ofstream stream(filename, std::ofstream::binary); + + stream.write((const char *)&bmfh, 14); + stream.write((const char *)&bmih, 40); + + if (flip) { + y = height; + while (y--) { + const unsigned char *ptr = rgba + y * stride; + for (x = 0; x < width; ++x) { + struct Pixel pixel; + pixel.rgbRed = ptr[x*4 + 0]; + pixel.rgbGreen = ptr[x*4 + 1]; + pixel.rgbBlue = ptr[x*4 + 2]; + pixel.rgbAlpha = ptr[x*4 + 3]; + stream.write((const char *)&pixel, 4); + } + } + } else { + for (y = 0; y < height; ++y) { + const unsigned char *ptr = rgba + y * stride; + for (x = 0; x < width; ++x) { + struct Pixel pixel; + pixel.rgbRed = ptr[x*4 + 0]; + pixel.rgbGreen = ptr[x*4 + 1]; + pixel.rgbBlue = ptr[x*4 + 2]; + pixel.rgbAlpha = ptr[x*4 + 3]; + stream.write((const char *)&pixel, 4); + } + } + } + + stream.close(); +} + + +} /* namespace BMP */ + + +#endif /* _BMP_HPP_ */ diff --git a/glretrace.py b/glretrace.py index 8bdb1ad..15b2c2d 100644 --- a/glretrace.py +++ b/glretrace.py @@ -89,7 +89,7 @@ class GlRetracer(Retracer): if __name__ == '__main__': - print ''' + print r''' #include #include @@ -104,6 +104,8 @@ bool __reshape_window = false; unsigned __frame = 0; long long __startTime = 0; +bool __screenshots = 0; + static void checkGlError(void) { @@ -146,19 +148,34 @@ checkGlError(void) { std::cerr << error; break; } - std::cerr << "\\n"; + std::cerr << "\n"; } ''' api = glapi.glapi retracer = GlRetracer() retracer.retrace_api(glapi.glapi) - print ''' + print r''' static Trace::Parser parser; static void display_noop(void) { } +#include "bmp.hpp" + +static void frame_complete(void) { + ++__frame; + + if (__screenshots && !__reshape_window) { + char filename[PATH_MAX]; + snprintf(filename, sizeof filename, "screenshot_%04u.bmp", __frame); + unsigned char *pixels = new unsigned char[__window_height*__window_width*4]; + glReadPixels(0, 0, __window_width, __window_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + BMP::write(filename, pixels, __window_width, __window_height, __window_width*4); + } + +} + static void display(void) { Trace::Call *call; @@ -166,8 +183,7 @@ static void display(void) { if (call->name() == "glFlush") { glFlush(); if (!double_buffer) { - ++__frame; - return; + frame_complete(); } } @@ -178,7 +194,7 @@ static void display(void) { glutSwapBuffers(); else glFlush(); - ++__frame; + frame_complete(); return; } } @@ -193,7 +209,7 @@ static void display(void) { std::cout << "Rendered " << __frame << " frames" " in " << timeInterval << " secs," - " average of " << (__frame/timeInterval) << " fps\\n"; + " average of " << (__frame/timeInterval) << " fps\n"; glutDisplayFunc(&display_noop); glutIdleFunc(NULL); @@ -221,13 +237,14 @@ int main(int argc, char **argv) if (!strcmp(arg, "--")) { break; - } - else if (!strcmp(arg, "-db")) { + } else if (!strcmp(arg, "-db")) { double_buffer = true; + } else if (!strcmp(arg, "-s")) { + __screenshots = true; } else if (!strcmp(arg, "-v")) { ++verbosity; } else { - std::cerr << "error: unknown option " << arg << "\\n"; + std::cerr << "error: unknown option " << arg << "\n"; return 1; } } -- 2.45.2