screenshot: get rid of the 3*w*h+18 TGA buffer; instead however always capture as...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 9 May 2010 10:28:26 +0000 (10:28 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 9 May 2010 10:28:26 +0000 (10:28 +0000)
also cvar: r_drawworld (when 0, turns off world drawing), and scr_screenshot_alpha (try to save alpha channel with screenshot).
Together, with this one can make nice alpha transparent screenshots of player models.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10180 d7cf8633-e32d-0410-b094-e92efae38249

12 files changed:
cl_main.c
cl_screen.c
clvm_cmds.c
fs.c
fs.h
gl_backend.h
gl_rmain.c
image.c
image.h
image_png.c
image_png.h
render.h

index 357250e..b6c293c 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -122,7 +122,7 @@ void CL_ClearState(void)
        cl.sensitivityscale = 1.0f;
 
        // enable rendering of the world and such
-       cl.csqc_vidvars.drawworld = true;
+       cl.csqc_vidvars.drawworld = r_drawworld.integer;
        cl.csqc_vidvars.drawenginesbar = true;
        cl.csqc_vidvars.drawcrosshair = true;
 
index 9050ab0..fe6f765 100644 (file)
@@ -37,6 +37,7 @@ cvar_t scr_screenshot_jpeg_quality = {CVAR_SAVE, "scr_screenshot_jpeg_quality","
 cvar_t scr_screenshot_png = {CVAR_SAVE, "scr_screenshot_png","0", "save png instead of targa"};
 cvar_t scr_screenshot_gammaboost = {CVAR_SAVE, "scr_screenshot_gammaboost","1", "gamma correction on saved screenshots and videos, 1.0 saves unmodified images"};
 cvar_t scr_screenshot_hwgamma = {CVAR_SAVE, "scr_screenshot_hwgamma","1", "apply the video gamma ramp to saved screenshots and videos"};
+cvar_t scr_screenshot_alpha = {CVAR_SAVE, "scr_screenshot_alpha","0", "try to write an alpha channel to screenshots (debugging feature)"};
 // scr_screenshot_name is defined in fs.c
 cvar_t cl_capturevideo = {0, "cl_capturevideo", "0", "enables saving of video to a .avi file using uncompressed I420 colorspace and PCM audio, note that scr_screenshot_gammaboost affects the brightness of the output)"};
 cvar_t cl_capturevideo_printfps = {CVAR_SAVE, "cl_capturevideo_printfps", "1", "prints the frames per second captured in capturevideo (is only written to the log file, not to the console, as that would be visible on the video)"};
@@ -874,6 +875,7 @@ void CL_Screen_Init(void)
        Cvar_RegisterVariable (&scr_screenshot_gammaboost);
        Cvar_RegisterVariable (&scr_screenshot_hwgamma);
        Cvar_RegisterVariable (&scr_screenshot_name_in_mapdir);
+       Cvar_RegisterVariable (&scr_screenshot_alpha);
        Cvar_RegisterVariable (&cl_capturevideo);
        Cvar_RegisterVariable (&cl_capturevideo_printfps);
        Cvar_RegisterVariable (&cl_capturevideo_width);
@@ -926,7 +928,6 @@ void SCR_ScreenShot_f (void)
        char mapname[MAX_QPATH];
        unsigned char *buffer1;
        unsigned char *buffer2;
-       unsigned char *buffer3;
        qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
        qboolean png = (scr_screenshot_png.integer != 0) && !jpeg;
 
@@ -988,18 +989,17 @@ void SCR_ScreenShot_f (void)
                dpsnprintf(filename, sizeof(filename), "screenshots/%s%06d.%s", prefix_name, shotnumber, jpeg ? "jpg" : png ? "png" : "tga");
        }
 
-       buffer1 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
-       buffer2 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
-       buffer3 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3 + 18);
+       buffer1 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 4);
+       buffer2 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * (scr_screenshot_alpha.integer ? 4 : 3));
 
-       if (SCR_ScreenShot (filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, jpeg, png, true))
+       if (SCR_ScreenShot (filename, buffer1, buffer2, 0, 0, vid.width, vid.height, false, false, false, jpeg, png, true, scr_screenshot_alpha.integer))
                Con_Printf("Wrote %s\n", filename);
        else
        {
                Con_Printf("Unable to write %s\n", filename);
                if(jpeg || png)
                {
-                       if(SCR_ScreenShot (filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, false, false, true))
+                       if(SCR_ScreenShot (filename, buffer1, buffer2, 0, 0, vid.width, vid.height, false, false, false, false, false, true, scr_screenshot_alpha.integer))
                        {
                                strlcpy(filename + strlen(filename) - 3, "tga", 4);
                                Con_Printf("Wrote %s\n", filename);
@@ -1009,7 +1009,6 @@ void SCR_ScreenShot_f (void)
 
        Mem_Free (buffer1);
        Mem_Free (buffer2);
-       Mem_Free (buffer3);
 
        shotnumber++;
 }
@@ -1216,7 +1215,6 @@ void SCR_CaptureVideo_VideoFrame(int newframestepframenum)
                return;
 
        CHECKGLERROR
-       //return SCR_ScreenShot(filename, cls.capturevideo.buffer, cls.capturevideo.buffer + vid.width * vid.height * 3, cls.capturevideo.buffer + vid.width * vid.height * 6, 0, 0, vid.width, vid.height, false, false, false, jpeg, true);
        // speed is critical here, so do saving as directly as possible
 
        qglReadPixels (x, y, vid.width, vid.height, GL_BGRA, GL_UNSIGNED_BYTE, cls.capturevideo.screenbuffer);CHECKGLERROR
@@ -1327,7 +1325,6 @@ static void R_Envmap_f (void)
        char filename[MAX_QPATH], basename[MAX_QPATH];
        unsigned char *buffer1;
        unsigned char *buffer2;
-       unsigned char *buffer3;
 
        if (Cmd_Argc() != 3)
        {
@@ -1364,9 +1361,8 @@ static void R_Envmap_f (void)
        r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0);
        r_refdef.view.frustum_y = 1; // tan(45 * M_PI / 180.0);
 
-       buffer1 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
+       buffer1 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 4);
        buffer2 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
-       buffer3 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3 + 18);
 
        for (j = 0;j < 12;j++)
        {
@@ -1377,12 +1373,11 @@ static void R_Envmap_f (void)
                R_Mesh_Start();
                R_RenderView();
                R_Mesh_Finish();
-               SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, vid.height - (r_refdef.view.y + r_refdef.view.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false, false);
+               SCR_ScreenShot(filename, buffer1, buffer2, 0, vid.height - (r_refdef.view.y + r_refdef.view.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false, false, false);
        }
 
        Mem_Free (buffer1);
        Mem_Free (buffer2);
-       Mem_Free (buffer3);
 
        r_refdef.envmap = false;
 }
@@ -1460,13 +1455,15 @@ void SHOWLMP_drawall(void)
 ==============================================================================
 */
 
-qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, unsigned char *buffer3, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean png, qboolean gammacorrect)
+// buffer1: 4*w*h
+// buffer2: 3*w*h (or 4*w*h if screenshotting alpha too)
+qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean png, qboolean gammacorrect, qboolean keep_alpha)
 {
-       int     indices[3] = {0,1,2};
+       int     indices[4] = {0,1,2,3}; // BGRA
        qboolean ret;
 
        CHECKGLERROR
-       qglReadPixels (x, y, width, height, jpeg ? GL_RGB : GL_BGR, GL_UNSIGNED_BYTE, buffer1);CHECKGLERROR
+       qglReadPixels (x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, buffer1);CHECKGLERROR
 
        if(gammacorrect && (scr_screenshot_gammaboost.value != 1 || WANT_SCREENSHOT_HWGAMMA))
        {
@@ -1489,22 +1486,40 @@ qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *b
                        for (i = 0;i < 256 * 3;i++)
                                vidramp[i] = (unsigned short) (0.5 + pow(vidramp[i] * (1.0 / 65535.0), igamma) * 65535.0);
                }
-               for (i = 0;i < width*height*3;i += 3)
+               for (i = 0;i < width*height*4;i += 4)
                {
-                       buffer1[i] = (unsigned char) (vidramp[buffer1[i]] * 255.0 / 65535.0 + 0.5);
-                       buffer1[i+1] = (unsigned char) (vidramp[buffer1[i+1] + 256] * 255.0 / 65535.0 + 0.5);
-                       buffer1[i+2] = (unsigned char) (vidramp[buffer1[i+2] + 512] * 255.0 / 65535.0 + 0.5);
+                       buffer1[i] = (unsigned char) (vidramp[buffer1[i] + 512] * 255.0 / 65535.0 + 0.5); // B
+                       buffer1[i+1] = (unsigned char) (vidramp[buffer1[i+1] + 256] * 255.0 / 65535.0 + 0.5); // G
+                       buffer1[i+2] = (unsigned char) (vidramp[buffer1[i+2]] * 255.0 / 65535.0 + 0.5); // R
+                       // A
                }
        }
 
-       Image_CopyMux (buffer2, buffer1, width, height, flipx, flipy, flipdiagonal, 3, 3, indices);
-
-       if (jpeg)
-               ret = JPEG_SaveImage_preflipped (filename, width, height, buffer2);
-       else if (png)
-               ret = PNG_SaveImage_preflipped (filename, width, height, buffer2);
+       if(keep_alpha && !jpeg)
+       {
+               if(!png)
+                       flipy = !flipy; // TGA: not preflipped
+               Image_CopyMux (buffer2, buffer1, width, height, flipx, flipy, flipdiagonal, 4, 4, indices);
+               if (png)
+                       ret = PNG_SaveImage_preflipped (filename, width, height, true, buffer2);
+               else
+                       ret = Image_WriteTGABGRA(filename, width, height, buffer2);
+       }
        else
-               ret = Image_WriteTGABGR_preflipped (filename, width, height, buffer2, buffer3);
+       {
+               if(jpeg)
+               {
+                       indices[0] = 2;
+                       indices[2] = 0; // RGB
+               }
+               Image_CopyMux (buffer2, buffer1, width, height, flipx, flipy, flipdiagonal, 3, 4, indices);
+               if (jpeg)
+                       ret = JPEG_SaveImage_preflipped (filename, width, height, buffer2);
+               else if (png)
+                       ret = PNG_SaveImage_preflipped (filename, width, height, false, buffer2);
+               else
+                       ret = Image_WriteTGABGR_preflipped (filename, width, height, buffer2);
+       }
 
        return ret;
 }
@@ -1666,15 +1681,12 @@ void SCR_DrawScreen (void)
                        char filename[MAX_QPATH];
                        unsigned char *buffer1;
                        unsigned char *buffer2;
-                       unsigned char *buffer3;
                        dpsnprintf(filename, sizeof(filename), "timedemoscreenshots/%s%06d.tga", cls.demoname, cls.td_frames);
-                       buffer1 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
+                       buffer1 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 4);
                        buffer2 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
-                       buffer3 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3 + 18);
-                       SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, false, false, true);
+                       SCR_ScreenShot(filename, buffer1, buffer2, 0, 0, vid.width, vid.height, false, false, false, false, false, true, false);
                        Mem_Free(buffer1);
                        Mem_Free(buffer2);
-                       Mem_Free(buffer3);
                }
        }
 
index 06d1d64..b167146 100644 (file)
@@ -724,7 +724,7 @@ void VM_CL_R_ClearScene (void)
        r_refdef.view.isoverlay = false;
        // FIXME: restore cl.csqc_origin
        // FIXME: restore cl.csqc_angles
-       cl.csqc_vidvars.drawworld = true;
+       cl.csqc_vidvars.drawworld = r_drawworld.integer;
        cl.csqc_vidvars.drawenginesbar = false;
        cl.csqc_vidvars.drawcrosshair = false;
 }
@@ -858,7 +858,7 @@ void VM_CL_R_SetView (void)
                CSQC_R_RecalcView();
                break;
        case VF_DRAWWORLD:
-               cl.csqc_vidvars.drawworld = k != 0;
+               cl.csqc_vidvars.drawworld = ((k != 0) && r_drawworld.integer);
                break;
        case VF_DRAWENGINESBAR:
                cl.csqc_vidvars.drawenginesbar = k != 0;
diff --git a/fs.c b/fs.c
index 0158198..a2f057c 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -2920,9 +2920,11 @@ FS_WriteFile
 The filename will be prefixed by the current game directory
 ============
 */
-qboolean FS_WriteFile (const char *filename, void *data, fs_offset_t len)
+qboolean FS_WriteFileInBlocks (const char *filename, const void *const *data, const fs_offset_t *len, size_t count)
 {
        qfile_t *file;
+       size_t i;
+       fs_offset_t lentotal;
 
        file = FS_OpenRealFile(filename, "wb", false);
        if (!file)
@@ -2931,12 +2933,21 @@ qboolean FS_WriteFile (const char *filename, void *data, fs_offset_t len)
                return false;
        }
 
-       Con_DPrintf("FS_WriteFile: %s (%u bytes)\n", filename, (unsigned int)len);
-       FS_Write (file, data, len);
+       lentotal = 0;
+       for(i = 0; i < count; ++i)
+               lentotal += len[i];
+       Con_DPrintf("FS_WriteFile: %s (%u bytes)\n", filename, (unsigned int)lentotal);
+       for(i = 0; i < count; ++i)
+               FS_Write (file, data[i], len[i]);
        FS_Close (file);
        return true;
 }
 
+qboolean FS_WriteFile (const char *filename, const void *data, fs_offset_t len)
+{
+       return FS_WriteFileInBlocks(filename, &data, &len, 1);
+}
+
 
 /*
 =============================================================================
diff --git a/fs.h b/fs.h
index f8d813c..42be6a7 100644 (file)
--- a/fs.h
+++ b/fs.h
@@ -108,7 +108,8 @@ fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet);
 void FS_FreeSearch(fssearch_t *search);
 
 unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer);
-qboolean FS_WriteFile (const char *filename, void *data, fs_offset_t len);
+qboolean FS_WriteFileInBlocks (const char *filename, const void *const *data, const fs_offset_t *len, size_t count);
+qboolean FS_WriteFile (const char *filename, const void *data, fs_offset_t len);
 
 
 // ------ Other functions ------ //
index 2e93c89..952cecd 100644 (file)
@@ -106,7 +106,7 @@ void R_Mesh_ResetTextureState(void);
 void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const r_meshbuffer_t *element3i_indexbuffer, size_t element3i_bufferoffset, const unsigned short *element3s, const r_meshbuffer_t *element3s_indexbuffer, size_t element3s_bufferoffset);
 
 // saves a section of the rendered frame to a .tga or .jpg file
-qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, unsigned char *buffer3, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean png, qboolean gammacorrect);
+qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean png, qboolean gammacorrect, qboolean keep_alpha);
 // used by R_Envmap_f and internally in backend, clears the frame
 void R_ClearScreen(qboolean fogcolor);
 
index 02e9e57..2ae129d 100644 (file)
@@ -76,6 +76,7 @@ cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygo
 cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"};
 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
+cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
 cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
@@ -6371,6 +6372,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_showdisabledepthtest);
        Cvar_RegisterVariable(&r_drawportals);
        Cvar_RegisterVariable(&r_drawentities);
+       Cvar_RegisterVariable(&r_drawworld);
        Cvar_RegisterVariable(&r_cullentities_trace);
        Cvar_RegisterVariable(&r_cullentities_trace_samples);
        Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
diff --git a/image.c b/image.c
index 4fccb16..ccc59f2 100644 (file)
--- a/image.c
+++ b/image.c
@@ -1142,9 +1142,12 @@ void Image_FixTransparentPixels_f(void)
        FS_FreeSearch(search);
 }
 
-qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int height, const unsigned char *data, unsigned char *buffer)
+qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int height, const unsigned char *data)
 {
        qboolean ret;
+       unsigned char buffer[18];
+       const void *buffers[2];
+       fs_offset_t sizes[2];
 
        memset (buffer, 0, 18);
        buffer[2] = 2;          // uncompressed type
@@ -1154,18 +1157,21 @@ qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int heig
        buffer[15] = (height >> 8) & 0xFF;
        buffer[16] = 24;        // pixel size
 
-       // swap rgb to bgr
-       memcpy(buffer + 18, data, width*height*3);
-       ret = FS_WriteFile (filename, buffer, width*height*3 + 18 );
+       buffers[0] = buffer;
+       sizes[0] = 18;
+       buffers[1] = data;
+       sizes[1] = width*height*3;
+       ret = FS_WriteFileInBlocks(filename, buffers, sizes, 2);
 
        return ret;
 }
 
-void Image_WriteTGABGRA (const char *filename, int width, int height, const unsigned char *data)
+qboolean Image_WriteTGABGRA (const char *filename, int width, int height, const unsigned char *data)
 {
        int y;
        unsigned char *buffer, *out;
        const unsigned char *in, *end;
+       qboolean ret;
 
        buffer = (unsigned char *)Mem_Alloc(tempmempool, width*height*4 + 18);
 
@@ -1214,9 +1220,11 @@ void Image_WriteTGABGRA (const char *filename, int width, int height, const unsi
                        }
                }
        }
-       FS_WriteFile (filename, buffer, out - buffer);
+       ret = FS_WriteFile (filename, buffer, out - buffer);
 
        Mem_Free(buffer);
+
+       return ret;
 }
 
 static void Image_Resample32LerpLine (const unsigned char *in, unsigned char *out, int inwidth, int outwidth)
diff --git a/image.h b/image.h
index 61bcc9c..1309ffe 100644 (file)
--- a/image.h
+++ b/image.h
@@ -32,10 +32,10 @@ qboolean LoadPCX_QWSkin(const unsigned char *f, int filesize, unsigned char *pix
 rtexture_t *loadtextureimage (rtexturepool_t *pool, const char *filename, qboolean complain, int flags, qboolean allowFixtrans, qboolean convertsRGB);
 
 // writes an upside down BGR image into a TGA
-qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int height, const unsigned char *data, unsigned char *buffer);
+qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int height, const unsigned char *data);
 
 // writes a BGRA image into a TGA file
-void Image_WriteTGABGRA (const char *filename, int width, int height, const unsigned char *data);
+qboolean Image_WriteTGABGRA (const char *filename, int width, int height, const unsigned char *data);
 
 // resizes the image (in can not be the same as out)
 void Image_Resample32(const void *indata, int inwidth, int inheight, int indepth, void *outdata, int outwidth, int outheight, int outdepth, int quality);
index d194931..b97e9c6 100644 (file)
@@ -443,7 +443,7 @@ PNG_SaveImage_preflipped
 Save a preflipped PNG image to a file
 ====================
 */
-qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, unsigned char *data)
+qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, qboolean has_alpha, unsigned char *data)
 {
        unsigned int offset, linesize;
        qfile_t* file = NULL;
@@ -497,8 +497,7 @@ qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height,
 
        //qpng_set_compression_level(png, Z_BEST_COMPRESSION);
        qpng_set_compression_level(png, Z_BEST_SPEED);
-       qpng_set_IHDR(png, pnginfo, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-       //qpng_set_IHDR(png, pnginfo, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+       qpng_set_IHDR(png, pnginfo, width, height, 8, has_alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
        qpng_set_filter(png, 0, PNG_NO_FILTERS);
        qpng_write_info(png, pnginfo);
        qpng_set_packing(png);
@@ -506,7 +505,7 @@ qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height,
 
        passes = qpng_set_interlace_handling(png);
 
-       linesize = width * 3;
+       linesize = width * (has_alpha ? 4 : 3);
        offset = linesize * (height - 1);
        for(i = 0; i < passes; ++i)
                for(j = 0; j < height; ++j)
index c521afd..e83d8cb 100644 (file)
@@ -27,7 +27,7 @@
 qboolean PNG_OpenLibrary (void);
 void PNG_CloseLibrary (void);
 unsigned char* PNG_LoadImage_BGRA (const unsigned char *f, int filesize);
-qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, unsigned char *data);
+qboolean PNG_SaveImage_preflipped (const char *filename, int width, int height, qboolean has_alpha, unsigned char *data);
 
 #endif
 
index 753fc92..aa90252 100644 (file)
--- a/render.h
+++ b/render.h
@@ -115,6 +115,7 @@ extern cvar_t r_showdisabledepthtest;
 //
 extern cvar_t r_drawentities;
 extern cvar_t r_drawviewmodel;
+extern cvar_t r_drawworld;
 extern cvar_t r_speeds;
 extern cvar_t r_fullbright;
 extern cvar_t r_wateralpha;