From 095cf836c62c23a4347690f048d84020e5e22824 Mon Sep 17 00:00:00 2001 From: BielBdeLuna <7318.tk@gmail.com> Date: Tue, 19 Aug 2014 11:35:50 +0200 Subject: [PATCH] screen shots are PNG and envshots are TGA, but still envshots come out somewhat wrong --- neo/framework/common_frame.cpp | 6 +- neo/renderer/Image.h | 7 +++ neo/renderer/RenderSystem.h | 2 +- neo/renderer/RenderSystem_init.cpp | 90 ++++++++++++++++++++++-------- neo/renderer/tr_local.h | 2 +- 5 files changed, 79 insertions(+), 28 deletions(-) diff --git a/neo/framework/common_frame.cpp b/neo/framework/common_frame.cpp index a23e83d9..6971bb6c 100644 --- a/neo/framework/common_frame.cpp +++ b/neo/framework/common_frame.cpp @@ -530,14 +530,14 @@ void idCommonLocal::Frame() // save the screenshot and audio from the last draw if needed if( aviCaptureMode ) { - idStr name = va( "demos/%s/%s_%05i.tga", aviDemoShortName.c_str(), aviDemoShortName.c_str(), aviDemoFrameCount++ ); - renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL ); + idStr name = va( "demos/%s/%s_%05i", aviDemoShortName.c_str(), aviDemoShortName.c_str(), aviDemoFrameCount++ ); + renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL, TGA ); // remove any printed lines at the top before taking the screenshot console->ClearNotifyLines(); // this will call Draw, possibly multiple times if com_aviDemoSamples is > 1 - renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL ); + renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL, TGA ); } //-------------------------------------------- diff --git a/neo/renderer/Image.h b/neo/renderer/Image.h index 6a90561f..e4e8aae8 100644 --- a/neo/renderer/Image.h +++ b/neo/renderer/Image.h @@ -69,6 +69,13 @@ typedef enum CF_2D_ARRAY // not a cube map but not a single 2d texture either } cubeFiles_t; +enum fileType_t +{ + TGA, + PNG, + JPG +}; + #include "ImageOpts.h" #include "BinaryImage.h" diff --git a/neo/renderer/RenderSystem.h b/neo/renderer/RenderSystem.h index a9e757d7..c21088fd 100644 --- a/neo/renderer/RenderSystem.h +++ b/neo/renderer/RenderSystem.h @@ -332,7 +332,7 @@ public: // This will perform swapbuffers, so it is NOT an approppriate way to // generate image files that happen during gameplay, as for savegame // markers. Use WriteRender() instead. - virtual void TakeScreenshot( int width, int height, const char* fileName, int samples, struct renderView_s* ref ) = 0; + virtual void TakeScreenshot( int width, int height, const char* fileName, int samples, struct renderView_s* ref, int exten ) = 0; // the render output can be cropped down to a subset of the real screen, as // for save-game reviews and split-screen multiplayer. Users of the renderer diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 015db1bc..7a8077b1 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -1223,20 +1223,34 @@ If ref == NULL, common->UpdateScreen will be used ================== */ // RB: changed .tga to .png -void idRenderSystemLocal::TakeScreenshot( int width, int height, const char* fileName, int blends, renderView_t* ref ) +void idRenderSystemLocal::TakeScreenshot( int width, int height, const char* fileName, int blends, renderView_t* ref, int exten ) { byte* buffer; - int i, j; - + int i, j, c, temp; + const char *formatName[3] = { ".tga", ".png", ".jpg" }; + idStr finalFileName; + + sprintf( finalFileName, "%s%s", fileName, formatName[exten] ); + takingScreenshot = true; - - int pix = width * height; - - buffer = ( byte* )R_StaticAlloc( pix * 3 ); + + int pix = width * height; + const int bufferSize = pix * 3 + 18; + + if ( exten == PNG ) { + buffer = ( byte* )R_StaticAlloc( pix * 3 ); + } else if ( exten == TGA ) { + buffer = (byte *)R_StaticAlloc( bufferSize ); + memset( buffer, 0, bufferSize ); + } if( blends <= 1 ) { - R_ReadTiledPixels( width, height, buffer, ref ); + if ( exten == PNG ) { + R_ReadTiledPixels( width, height, buffer, ref ); + } else if ( exten == TGA ) { + R_ReadTiledPixels( width, height, buffer + 18, ref ); + } } else { @@ -1248,25 +1262,57 @@ void idRenderSystemLocal::TakeScreenshot( int width, int height, const char* fil for( i = 0 ; i < blends ; i++ ) { - R_ReadTiledPixels( width, height, buffer, ref ); + if ( exten == PNG ) { + R_ReadTiledPixels( width, height, buffer, ref ); + } else if ( exten == TGA ) { + R_ReadTiledPixels( width, height, buffer + 18, ref ); + } for( j = 0 ; j < pix * 3 ; j++ ) { - shortBuffer[j] += buffer[j]; + if ( exten == PNG ) { + shortBuffer[j] += buffer[j]; + } else if ( exten == TGA ) { + shortBuffer[j] += buffer[18 + j]; + } } } // divide back to bytes for( i = 0 ; i < pix * 3 ; i++ ) { - buffer[i] = shortBuffer[i] / blends; + if ( exten == PNG ) { + buffer[i] = shortBuffer[i] / blends; + } else if ( exten == TGA ) { + buffer[18 + i] = shortBuffer[i] / blends; + } } R_StaticFree( shortBuffer ); r_jitter.SetBool( false ); } - - R_WritePNG( fileName, buffer, 3, width, height, false ); + if ( exten == PNG ) { + R_WritePNG( finalFileName, buffer, 3, width, height, false ); + } else { + // fill in the header (this is vertically flipped, which qglReadPixels emits) + buffer[2] = 2; // uncompressed type + buffer[12] = width & 255; + buffer[13] = width >> 8; + buffer[14] = height & 255; + buffer[15] = height >> 8; + buffer[16] = 24; // pixel size + + // swap rgb to bgr + c = 18 + width * height * 3; + + for (i=18 ; iWriteFile( finalFileName, buffer, c ); + } R_StaticFree( buffer ); @@ -1317,7 +1363,7 @@ void R_ScreenshotFilename( int& lastNumber, const char* base, idStr& fileName ) time( &aclock ); struct tm* t = localtime( &aclock ); - sprintf( fileName, "%s%s-%04d%02d%02d-%02d%02d%02d-%03d.png", base, "rbdoom-3-bfg", + sprintf( fileName, "%s%s-%04d%02d%02d-%02d%02d%02d-%03d", base, "rbdoom-3-bfg", 1900 + t->tm_year, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, lastNumber ); #endif // RB end @@ -1397,7 +1443,7 @@ void R_ScreenShot_f( const idCmdArgs& args ) // put the console away console->Close(); - tr.TakeScreenshot( width, height, checkname, blends, NULL ); + tr.TakeScreenshot( width, height, checkname, blends, NULL, PNG ); common->Printf( "Wrote %s\n", checkname.c_str() ); } @@ -1461,8 +1507,7 @@ void R_EnvShot_f( const idCmdArgs &args ) { renderView_t ref; viewDef_t primary; int blends; - const char *extensions[6] = { "_px.png", "_nx.png", "_py.png", "_ny.png", - "_pz.png", "_nz.png" }; + const char *extensions[6] = { "_px", "_nx", "_py", "_ny", "_pz", "_nz" }; int size; int res_w, res_h; @@ -1519,23 +1564,22 @@ void R_EnvShot_f( const idCmdArgs &args ) { axis[5][1][0] = 1; axis[5][2][1] = 1; - // let's gain the "size" resolution - // FIXME that's a hack!! + // let's get the game window to a "size" resolution if ( ( res_w != size ) || ( res_h != size ) ) { cvarSystem->SetCVarInteger( "r_windowWidth", size ); cvarSystem->SetCVarInteger( "r_windowHeight", size ); R_SetNewMode( false ); // the same as "vid_restart" - } + } // FIXME that's a hack!! for ( i = 0 ; i < 6 ; i++ ) { ref = primary.renderView; - //ref.x = ref.y = 0; + //ref.x = ref.y = 0; // this no longer serves any purpose ref.fov_x = ref.fov_y = 90; - //ref.width = glConfig.vidWidth; + //ref.width = glConfig.vidWidth; // this no longer serves any purpose //ref.height = glConfig.vidHeight; ref.viewaxis = axis[i]; sprintf( fullname, "env/%s%s", baseName, extensions[i] ); - tr.TakeScreenshot( size, size, fullname, blends, &ref ); + tr.TakeScreenshot( size, size, fullname, blends, &ref, TGA ); } // restore the original resolution diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h index 8944973c..26c0d89d 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/tr_local.h @@ -814,7 +814,7 @@ public: virtual const emptyCommand_t* SwapCommandBuffers_FinishCommandBuffers(); virtual void RenderCommandBuffers( const emptyCommand_t* commandBuffers ); - virtual void TakeScreenshot( int width, int height, const char* fileName, int downSample, renderView_t* ref ); + virtual void TakeScreenshot( int width, int height, const char* fileName, int downSample, renderView_t* ref, int exten ); virtual void CropRenderSize( int width, int height ); virtual void CaptureRenderToImage( const char* imageName, bool clearColorAfterCopy = false ); virtual void CaptureRenderToFile( const char* fileName, bool fixAlpha );