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;
}