bool blTerrainChunk::write(Stream & stream) { if(!Parent::write(stream)) return(false); if(!mLightmap) return(false); if(!mLightmap->writeBitmap("png",stream)) return(false); return(true); }
void ScreenShot::_singleCapture( GuiCanvas *canvas ) { // Let the canvas render the scene. canvas->renderFrame( false ); // Now grab the current back buffer. GBitmap *bitmap = _captureBackBuffer(); // The current GFX device couldn't capture the backbuffer or it's unable of doing so. if (bitmap == NULL) return; // We captured... clear the flag. mPending = false; // We gotta attach the extension ourselves. char filename[256]; dSprintf( filename, 256, "%s.%s", mFilename, mWriteJPG ? "jpg" : "png" ); // Open up the file on disk. FileStream fs; if ( !fs.open( filename, Torque::FS::File::Write ) ) Con::errorf( "ScreenShot::_singleCapture() - Failed to open output file '%s'!", filename ); else { // Write it and close. if ( mWriteJPG ) bitmap->writeBitmap( "jpg", fs ); else bitmap->writeBitmap( "png", fs ); fs.close(); } // Cleanup. delete bitmap; }
void ImposterCapture::_separateAlpha( GBitmap *imposterOut ) { PROFILE_START(TSShapeInstance_snapshot_sb_separate); // TODO: Remove all this when we get rid of the 'render on black/white'. // now separate the color and alpha channels GBitmap *bmp = new GBitmap; bmp->allocateBitmap(mDim, mDim, false, GFXFormatR8G8B8A8); U8 * wbmp = (U8*)mWhiteBmp->getBits(0); U8 * bbmp = (U8*)mBlackBmp->getBits(0); U8 * dst = (U8*)bmp->getBits(0); const U32 pixCount = mDim * mDim; // simpler, probably faster... for ( U32 i=0; i < pixCount; i++ ) { // Shape on black background is alpha * color, shape on white // background is alpha * color + (1-alpha) * 255 we want 255 * // alpha, or 255 - (white - black). // // JMQ: or more verbosely: // cB = alpha * color + (0 * (1 - alpha)) // cB = alpha * color // cW = alpha * color + (255 * (1 - alpha)) // cW = cB + (255 * (1 - alpha)) // solving for alpha // cW - cB = 255 * (1 - alpha) // (cW - cB)/255 = (1 - alpha) // alpha = 1 - (cW - cB)/255 // since we want alpha*255, multiply through by 255 // alpha * 255 = 255 - cW - cB U32 alpha = 255 - (wbmp[i*3+0] - bbmp[i*3+0]); alpha += 255 - (wbmp[i*3+1] - bbmp[i*3+1]); alpha += 255 - (wbmp[i*3+2] - bbmp[i*3+2]); if ( alpha != 0 ) { F32 floatAlpha = ((F32)alpha)/(3.0f*255.0f); dst[i*4+0] = (U8)(bbmp[i*3+0] / floatAlpha); dst[i*4+1] = (U8)(bbmp[i*3+1] / floatAlpha); dst[i*4+2] = (U8)(bbmp[i*3+2] / floatAlpha); // Before we assign the alpha we "fizzle" the value // if its greater than 84. This causes the imposter // to dissolve instead of popping into view. alpha /= 3; dst[i*4+3] = (U8)alpha; } else { dst[i*4+0] = dst[i*4+1] = dst[i*4+2] = dst[i*4+3] = 0; } } PROFILE_END(); // TSShapeInstance_snapshot_sb_separate PROFILE_START(TSShapeInstance_snapshot_sb_filter); // We now run a special kernel filter over the image that // averages color into the transparent areas. This should // in essence give us a border around the edges of the // imposter silhouette which fixes the artifacts around the // alpha test billboards. U8* dst2 = (U8*)imposterOut->getBits(0); _colorAverageFilter( mDim, dst, dst2 ); if ( 0 ) { FileStream fs; if ( fs.open( "./imposterout.png", Torque::FS::File::Write ) ) imposterOut->writeBitmap( "png", fs ); fs.close(); if ( fs.open( "./temp.png", Torque::FS::File::Write ) ) bmp->writeBitmap( "png", fs ); fs.close(); } PROFILE_END(); // TSShapeInstance_snapshot_sb_filter delete bmp; }