Fix #34863: bge.render.makeScreenshot from Blender was only saving PNG files,
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 4 Apr 2013 14:00:31 +0000 (14:00 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 4 Apr 2013 14:00:31 +0000 (14:00 +0000)
while the docs said it followed the settings in the Output panel, other file
formats work now.

Benderplayer still only saves PNG now as documented, but I cleaned up the code
there to reuse existing imbuf functions rather than using own libpng code.

doc/python_api/rst/bge.render.rst
source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
source/gameengine/BlenderRoutines/KX_BlenderGL.h
source/gameengine/GamePlayer/common/GPC_Canvas.cpp

index d07d7a8734fe78139de3f59fa201bbce88c371a2..e203826d318d5cecaf8c7b05a9c8b2cc768078c6 100644 (file)
@@ -97,7 +97,7 @@ Functions
    The standalone player saves .png files. It does not support color space conversion 
    or gamma correction.
    
-   When run from Blender, makeScreenshot supports Iris, IrisZ, TGA, Raw TGA, PNG, HamX, and Jpeg.
+   When run from Blender, makeScreenshot supports all Blender image file formats like PNG, TGA, Jpeg and OpenEXR.
    Gamma, Colorspace conversion and Jpeg compression are taken from the Render settings panels.
    
    :type filename: string
index e51daf615b8869c4b01395204e5f547dc073afb2..e15b8ac942fcc0624d03a1e32497448efd57c2c8 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "KX_BlenderCanvas.h"
 #include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
 #include <stdio.h>
 #include <assert.h>
 
@@ -256,5 +257,5 @@ void KX_BlenderCanvas::MakeScreenShot(const char *filename)
        area_dummy.totrct.ymin = m_frame_rect.GetBottom();
        area_dummy.totrct.ymax = m_frame_rect.GetTop();
 
-       BL_MakeScreenShot(&area_dummy, filename);
+       BL_MakeScreenShot(m_win->screen, &area_dummy, filename);
 }
index f808b1b72721dbc83b7613839049587ae9755b7a..ebf788024c51903eaa6a1e116d38ca768cd0d76a 100644 (file)
@@ -60,6 +60,7 @@
 #include "DNA_image_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_material_types.h"
+#include "DNA_space_types.h"
 #include "DNA_windowmanager_types.h"
 
 #include "BKE_global.h"
@@ -68,6 +69,7 @@
 #include "BKE_image.h"
 
 #include "BLI_path_util.h"
+#include "BLI_string.h"
 
 extern "C" {
 #include "IMB_imbuf_types.h"
@@ -270,8 +272,6 @@ void BL_NormalMouse(wmWindow *win)
 {
        WM_cursor_set(win, CURSOR_STD);
 }
-#define MAX_FILE_LENGTH 512
-
 /* get shot from frontbuffer sort of a copy from screendump.c */
 static unsigned int *screenshot(ScrArea *curarea, int *dumpsx, int *dumpsy)
 {
@@ -296,27 +296,36 @@ static unsigned int *screenshot(ScrArea *curarea, int *dumpsx, int *dumpsy)
 }
 
 /* based on screendump.c::screenshot_exec */
-void BL_MakeScreenShot(ScrArea *curarea, const char *filename)
+void BL_MakeScreenShot(bScreen *screen, ScrArea *curarea, const char *filename)
 {
-       char path[MAX_FILE_LENGTH];
-       strcpy(path,filename);
-
        unsigned int *dumprect;
        int dumpsx, dumpsy;
        
-       dumprect= screenshot(curarea, &dumpsx, &dumpsy);
+       dumprect = screenshot(curarea, &dumpsx, &dumpsy);
+
        if (dumprect) {
-               ImBuf *ibuf;
+               /* initialize image file format data */
+               Scene *scene = (screen)? screen->scene: NULL;
+               ImageFormatData im_format;
+
+               if(scene)
+                       im_format = scene->r.im_format;
+               else
+                       BKE_imformat_defaults(&im_format);
+
+               /* create file path */
+               char path[FILE_MAX];
+               BLI_strncpy(path, filename, sizeof(path));
                BLI_path_abs(path, G.main->name);
-               /* BKE_add_image_extension() checks for if extension was already set */
-               BKE_add_image_extension_from_type(path, R_IMF_IMTYPE_PNG); /* scene->r.im_format.imtype */
-               ibuf= IMB_allocImBuf(dumpsx, dumpsy, 24, 0);
-               ibuf->rect= dumprect;
-               ibuf->ftype= PNG;
+               BKE_add_image_extension_from_type(path, im_format.imtype);
+
+               /* create and save imbuf */
+               ImBuf *ibuf = IMB_allocImBuf(dumpsx, dumpsy, 24, 0);
+               ibuf->rect = dumprect;
 
-               IMB_saveiff(ibuf, path, IB_rect);
+               BKE_imbuf_write_as(ibuf, path, &im_format, false);
 
-               ibuf->rect= NULL;
+               ibuf->rect = NULL;
                IMB_freeImBuf(ibuf);
                MEM_freeN(dumprect);
        }
index 2545cd34acb692a5473eab45cdb4102b95c4ee8e..0f35494c73a0b5366e924c0c32dba6fc3078de7a 100644 (file)
@@ -38,13 +38,14 @@ extern "C" {
 
 struct wmWindow;
 struct ARegion;
+struct bScreen;
 
 // special swapbuffers, that takes care of which area (viewport) needs to be swapped
 void   BL_SwapBuffers(struct wmWindow *win);
 
 void   BL_warp_pointer(struct wmWindow *win,int x,int y);
 
-void   BL_MakeScreenShot(struct ScrArea *curarea, const char *filename);
+void   BL_MakeScreenShot(struct bScreen *screen, struct ScrArea *curarea, const char *filename);
 
 void   BL_HideMouse(struct wmWindow *win);
 void   BL_NormalMouse(struct wmWindow *win);
index 058454ca3520c18dd65826117298e3fae454ea73..8a6a41f3f9997003ecd4d9480040251bbd8eaa02 100644 (file)
 #include "RAS_IPolygonMaterial.h"
 #include "GPC_Canvas.h"
 
+#include "BLI_string.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_image.h"
+
+extern "C" {
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+}
+
 GPC_Canvas::TBannerId GPC_Canvas::s_bannerId = 0;
 
 
@@ -425,114 +437,35 @@ GPC_Canvas::
 MakeScreenShot(
        const char* filename
 ) {
-       png_structp png_ptr;
-       png_infop info_ptr;
-       unsigned char *pixels = 0;
-       png_bytepp row_pointers = 0;
-       int i, bytesperpixel = 3, color_type = PNG_COLOR_TYPE_RGB;
-       FILE *fp = 0;
-
-       png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-       if (!png_ptr) 
-       {
-               std::cout << "Cannot png_create_write_struct." << std::endl;
-               return;
-       }
-
-       info_ptr = png_create_info_struct(png_ptr);
-       if (!info_ptr) 
-       {
-               png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
-               std::cout << "Cannot png_create_info_struct." << std::endl;
-               return;
-       }
-
-       if (setjmp(png_jmpbuf(png_ptr))) {
-               png_destroy_write_struct(&png_ptr, &info_ptr);
-               delete [] pixels;
-               delete [] row_pointers;
-               // printf("Aborting\n");
-               if (fp) {
-                       fflush(fp);
-                       fclose(fp);
-               }
-               return;
-       }
-
        // copy image data
+       unsigned char *pixels = new unsigned char[GetWidth() * GetHeight() * 4];
 
-       pixels = new unsigned char[GetWidth() * GetHeight() * bytesperpixel * sizeof(unsigned char)];
        if (!pixels) {
                std::cout << "Cannot allocate pixels array" << std::endl;
                return;
        }
 
-       glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, pixels);
-
-       fp = fopen(filename, "wb");
-       if (!fp)
-       {
-               std::cout << "Couldn't open " << filename << " for writing." << std::endl;
-               longjmp(png_jmpbuf(png_ptr), 1);
-       }
-
-       png_init_io(png_ptr, fp);
+       glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 
-#if 0
-       png_set_filter(png_ptr, 0,
-                      PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE |
-                      PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB  |
-                      PNG_FILTER_UP    | PNG_FILTER_VALUE_UP   |
-                      PNG_FILTER_AVG   | PNG_FILTER_VALUE_AVG  |
-                      PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
-                      PNG_ALL_FILTERS);
-
-       png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
-#endif
+       // initialize image file format data
+       ImageFormatData im_format;
+       BKE_imformat_defaults(&im_format);
 
-       // png image settings
-       png_set_IHDR(png_ptr,
-                    info_ptr,
-                    GetWidth(),
-                    GetHeight(),
-                    8,
-                    color_type,
-                    PNG_INTERLACE_NONE,
-                    PNG_COMPRESSION_TYPE_DEFAULT,
-                    PNG_FILTER_TYPE_DEFAULT);
-
-       // write the file header information
-       png_write_info(png_ptr, info_ptr);
-
-       // allocate memory for an array of row-pointers
-       row_pointers = new png_bytep [(GetHeight() * sizeof(png_bytep))];
-       if (!row_pointers) 
-       {
-               std::cout << "Cannot allocate row-pointers array" << std::endl;
-               longjmp(png_jmpbuf(png_ptr), 1);
-       }
+       // create file path 
+       char path[FILE_MAX];
+       BLI_strncpy(path, filename, sizeof(path));
+       BKE_add_image_extension_from_type(path, im_format.imtype);
 
-       // set the individual row-pointers to point at the correct offsets
-       for (i = 0; i < GetHeight(); i++) {
-               row_pointers[GetHeight()-1-i] = (png_bytep)
-                       ((unsigned char *)pixels + (i * GetWidth()) * bytesperpixel * sizeof(unsigned char));
-       }
+       // create and save imbuf 
+       ImBuf *ibuf = IMB_allocImBuf(GetWidth(), GetHeight(), 24, 0);
+       ibuf->rect = (unsigned int*)pixels;
 
-       // write out the entire image data in one call
-       png_write_image(png_ptr, row_pointers);
+       BKE_imbuf_write_as(ibuf, path, &im_format, false);
 
-       // write the additional chunks to the PNG file (not really needed)
-       png_write_end(png_ptr, info_ptr);
+       ibuf->rect = NULL;
+       IMB_freeImBuf(ibuf);
 
        // clean up
        delete [] (pixels);
-       delete [] (row_pointers);
-       png_destroy_write_struct(&png_ptr, &info_ptr);
-
-       if (fp) 
-       {
-               fflush(fp);
-               fclose(fp);
-       }
 }