From 870fae3e47a8c9f8bfe1535d1963fa7a774d4503 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 30 Nov 2023 14:02:06 +0000 Subject: [PATCH] Update screenshot.cpp Screenshot now works with stb: gBitmap outbuffer holds the whole image anyway so just use writeBitmap when its done. --- Engine/source/gfx/screenshot.cpp | 130 ++++++++++++++----------------- 1 file changed, 58 insertions(+), 72 deletions(-) diff --git a/Engine/source/gfx/screenshot.cpp b/Engine/source/gfx/screenshot.cpp index 8d629db22..8c62456c5 100644 --- a/Engine/source/gfx/screenshot.cpp +++ b/Engine/source/gfx/screenshot.cpp @@ -126,89 +126,75 @@ void ScreenShot::capture( GuiCanvas *canvas ) // Open up the file on disk. dSprintf( filename, 256, "%s.%s", mFilename, "png" ); - FileStream fs; - if ( !fs.open( filename, Torque::FS::File::Write ) ) - Con::errorf( "ScreenShot::capture() - Failed to open output file '%s'!", filename ); - //// Open a PNG stream for the final image - //DeferredPNGWriter pngWriter; - //pngWriter.begin(outBuffer->getFormat(), outBuffer->getWidth(), canvasSize.y * mTiles - overlapPixels.y * mTiles * 2, fs, 0); - // //// Render each tile to generate a huge screenshot. - //for( U32 ty=0; ty < mTiles; ty++ ) - //{ - // for( S32 tx=0; tx < mTiles; tx++ ) - // { - // // Set the current tile offset for tileFrustum(). - // mCurrTile.set( tx, mTiles - ty - 1 ); + for (U32 ty = 0; ty < mTiles; ty++) + { + for (S32 tx = 0; tx < mTiles; tx++) + { + // Set the current tile offset for tileFrustum(). + mCurrTile.set(tx, mTiles - ty - 1); - // // Let the canvas render the scene. - // canvas->renderFrame( false ); + // Let the canvas render the scene. + canvas->renderFrame(false); + // Now grab the current back buffer. + GBitmap* gb = _captureBackBuffer(); - // // Now grab the current back buffer. - // GBitmap *gb = _captureBackBuffer(); + // The current GFX device couldn't capture the backbuffer or it's unable of doing so. + if (gb == NULL) + return; - //// The current GFX device couldn't capture the backbuffer or it's unable of doing so. - //if (gb == NULL) - // return; + // Copy the captured bitmap into its tile + // within the output bitmap. + const U32 inStride = gb->getWidth() * gb->getBytesPerPixel(); + const U8* inColor = gb->getBits() + inStride * overlapPixels.y; + const U32 outStride = outBuffer->getWidth() * outBuffer->getBytesPerPixel(); + const U32 inOverlapOffset = overlapPixels.x * gb->getBytesPerPixel(); + const U32 inOverlapStride = overlapPixels.x * gb->getBytesPerPixel() * 2; + const U32 outOffset = (tx * (gb->getWidth() - overlapPixels.x * 2)) * gb->getBytesPerPixel(); + U8 * outColor = outBuffer->getWritableBits() + outOffset; + for (U32 row = 0; row < gb->getHeight() - overlapPixels.y; row++) + { + dMemcpy(outColor, inColor + inOverlapOffset, inStride - inOverlapStride); - // - // // Copy the captured bitmap into its tile - // // within the output bitmap. - // const U32 inStride = gb->getWidth() * gb->getBytesPerPixel(); - // const U8 *inColor = gb->getBits() + inStride * overlapPixels.y; - // const U32 outStride = outBuffer->getWidth() * outBuffer->getBytesPerPixel(); - // const U32 inOverlapOffset = overlapPixels.x * gb->getBytesPerPixel(); - // const U32 inOverlapStride = overlapPixels.x * gb->getBytesPerPixel()*2; - // const U32 outOffset = (tx * (gb->getWidth() - overlapPixels.x*2 )) * gb->getBytesPerPixel(); - // U8 *outColor = outBuffer->getWritableBits() + outOffset; - // for( U32 row=0; row < gb->getHeight() - overlapPixels.y; row++ ) - // { - // dMemcpy( outColor, inColor + inOverlapOffset, inStride - inOverlapStride ); - // - // //Grandient blend the left overlap area of this tile over the previous tile left border - // if (tx && !(ty && row < overlapPixels.y)) - // { - // U8 *blendOverlapSrc = (U8*)inColor; - // U8 *blendOverlapDst = outColor - inOverlapOffset; - // for ( U32 px=0; px < overlapPixels.x; px++) - // { - // F32 blendFactor = (F32)px / (F32)overlapPixels.x; - // sBlendPixelRGB888(blendOverlapSrc, blendOverlapDst, blendFactor); + //Grandient blend the left overlap area of this tile over the previous tile left borde + if (tx && !(ty && row < overlapPixels.y)) + { + U8* blendOverlapSrc = (U8*)inColor; + U8* blendOverlapDst = outColor - inOverlapOffset; + for (U32 px = 0; px < overlapPixels.x; px++) + { + F32 blendFactor = (F32)px / (F32)overlapPixels.x; + sBlendPixelRGB888(blendOverlapSrc, blendOverlapDst, blendFactor); - // blendOverlapSrc += gb->getBytesPerPixel(); - // blendOverlapDst += outBuffer->getBytesPerPixel(); - // } - // } + blendOverlapSrc += gb->getBytesPerPixel(); + blendOverlapDst += outBuffer->getBytesPerPixel(); + } + } - // //Gradient blend against the rows the excess overlap rows already in the buffer - // if (ty && row < overlapPixels.y) - // { - // F32 rowBlendFactor = (F32)row / (F32)overlapPixels.y; - // U8 *blendSrc = outColor + outStride * (outBuffer->getHeight() - overlapPixels.y); - // U8 *blendDst = outColor; - // for ( U32 px=0; px < gb->getWidth() - overlapPixels.x*2; px++) - // { - // sBlendPixelRGB888(blendSrc, blendDst, 1.0-rowBlendFactor); - // blendSrc += gb->getBytesPerPixel(); - // blendDst += outBuffer->getBytesPerPixel(); - // } - // } + //Gradient blend against the rows the excess overlap rows already in the buffer + if (ty && row < overlapPixels.y) + { + F32 rowBlendFactor = (F32)row / (F32)overlapPixels.y; + U8* blendSrc = outColor + outStride * (outBuffer->getHeight() - overlapPixels.y); + U8* blendDst = outColor; + for (U32 px = 0; px < gb->getWidth() - overlapPixels.x * 2; px++) + { + sBlendPixelRGB888(blendSrc, blendDst, 1.0 - rowBlendFactor); + blendSrc += gb->getBytesPerPixel(); + blendDst += outBuffer->getBytesPerPixel(); + } + } - // - // inColor += inStride; - // outColor += outStride; - // } + inColor += inStride; + outColor += outStride; + } - // delete gb; - // } + delete gb; + } + } - // // Write the captured tile row into the PNG stream - // pngWriter.append(outBuffer, outBuffer->getHeight()-overlapPixels.y); - //} - - ////Close the PNG stream - //pngWriter.end(); + outBuffer->writeBitmap("png", filename); // We captured... clear the flag. mPending = false;