Game Development Community

Storing the heightmap as a texture?

by Matt Vitelli · in Torque Game Engine · 04/26/2008 (6:12 pm) · 1 replies

I was wondering what would be involved in converting the heightmap on a legacy terrain to a texture handle. I've been looking into the terrain code and the heightmap is stored as a U16 value. I'm just curious if this is possible or if it is something difficult to do.

Thanks,

Matt Vitelli

#1
04/26/2008 (8:57 pm)
There are programs to create them (16 bit bitmaps, sometimes called .raw) and which can read them in again (then you could save it in your favorite format.) (AFAIK, older PhotoShops didn't do too well with 16 bit textures, however.) I don't immediately recall what I used. Perhaps "Wilbur" (Google it).

Saving it from the game is pretty easy. I may have made another post on that subject. Essentially, I just stopped writing the usual save terrain file after the first couple of data sets.

Here is some code to save the height bitmap (I may have left something out, if so, please ask.)
Sorry, have things to do this weekend so can't gather this up much better right now.

//--------------------------------------------------------------------------
// MVJ: save terrain height bitmap (only). 
// (This is a portion of the .ter file after the one byte version and before the rest of the file.) 
// It is essentially a 16 bit ".raw" file format for DEM data. 
// WARNING: path portion is required. e.g.: "./filename.raw"
bool TerrainBlock::saveBitmapOnly(const char *filename)
{
   return mFile->saveBitmapOnly(filename);
}

//--------------------------------------
// MVJ: save terrain height bitmap (only). (Slight modification from TerrainFile::save)
// (This is a portion of the .ter file after the one byte version and before the rest of the file.) 
// It is essentially a 16 bit ".raw" file format for DEM data. 
// WARNING: path portion is required. e.g.: "./filename.raw"
bool TerrainFile::saveBitmapOnly(const char *filename)
{
   FileStream writeFile;
   if (!ResourceManager->openFileForWrite(writeFile, filename))
      return false;

   // write the VERSION and HeightField
//not desired in the saveBitmapOnly version of TerrainFile::save:   writeFile.write((U8)FILE_VERSION);


//#define SAVE_SLOPING_PLANE_BITMAP // save a special tilted plane instead for various studies
#ifdef  SAVE_SLOPING_PLANE_BITMAP 
   U16 row = 0;
   U16 pixel = 0;
   U16 ht;
   for (S32 i=0; i < (TerrainBlock::BlockSize * TerrainBlock::BlockSize); i++) {
	   if (pixel == 256) {
		   row++;
		   pixel = 0;
	   }
	   ht = 256 * row;
      writeFile.write(ht);
	  pixel++;
   }

#else
   for (S32 i=0; i < (TerrainBlock::BlockSize * TerrainBlock::BlockSize); i++) {
      writeFile.write(mHeightMap[i]);
   }
#endif

   return (writeFile.getStatus() == FileStream::Ok);
}

//--------------------------------------
// MVJ: console method to save JUST the bitmap portion of the .ter file as .raw
// in script, can call this as:  Terrain.saveBitmapOnly("./fileName.raw");
// WARNING: path portion is required. 
ConsoleMethod(TerrainBlock, saveBitmapOnly, bool, 3, 3, "(string fileName.raw) - saves the terrain block's terrain file to the specified path.")
{
   char filename[256];
   dStrcpy(filename,argv[2]);
   char *ext = dStrrchr(filename, '.');
   if (!ext || dStricmp(ext, ".raw") != 0)
      dStrcat(filename, ".raw");
   return object->saveBitmapOnly(filename);
}

//--------------------------------------
// MVJ: ConsoleFunction to save JUST the bitmap portion of the .ter file
// in script, can call this as:  terrainSaveBitmapOnly("./fileName.raw");
// WARNING: path portion is required. 
ConsoleFunction(terrainSaveBitmapOnly, void, 2, 2, "(string fileName.raw) - saves the terrain block's height bitmap to the specified path.")
{
   char filename[256];
   dStrcpy(filename,argv[1]);
   char *ext = dStrrchr(filename, '.');
   if (!ext || dStricmp(ext, ".raw") != 0)
      dStrcat(filename, ".raw");


   Point2F pos;
   F32 height = 0.0f;
   dSscanf(argv[1],"%g %g",&pos.x,&pos.y);
   TerrainBlock * terrain = dynamic_cast<TerrainBlock*>(Sim::findObject("Terrain"));
   if(terrain) {
	   if(terrain->isServerObject()) {
		  terrain->saveBitmapOnly(filename);
       }
   }

}