]> git.cworth.org Git - apitrace/commitdiff
Dump bitmaps.
authorJosé Fonseca <jfonseca@vmware.com>
Mon, 29 Nov 2010 14:21:06 +0000 (14:21 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Mon, 29 Nov 2010 14:21:06 +0000 (14:21 +0000)
.gitignore
bmp.hpp [new file with mode: 0644]
glretrace.py

index 8cdc5ca986a715b2707ab07b6302871c13e3d0e2..6f6c7264f9a0fc217e92a003fc758ca8465f7282 100644 (file)
@@ -1,6 +1,7 @@
 .*.sw?
 *~
 *.a
+*.bmp
 *.bz2
 *.dll
 *.exe
diff --git a/bmp.hpp b/bmp.hpp
new file mode 100644 (file)
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 <fstream>
+
+
+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_ */
index 8bdb1ad6f96c869810ccd074b6fce088b99fe26c..15b2c2d44430001227e2209e990aae6aca395d4d 100644 (file)
@@ -89,7 +89,7 @@ class GlRetracer(Retracer):
 
 
 if __name__ == '__main__':
-    print '''
+    print r'''
 #include <string.h>
 #include <iostream>
 
@@ -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;
         }
     }