Переглянути джерело

Merge pull request #793 from lukaspj/Terrain-Basetex-Formats

Terrain basetex formats
Daniel Buckmaster 11 роки тому
батько
коміт
97ae3445c9

+ 2 - 2
Engine/source/gfx/D3D9/gfxD3D9TextureObject.cpp

@@ -205,8 +205,8 @@ bool GFXD3D9TextureObject::copyToBmp(GBitmap* bmp)
    // check format limitations
    // at the moment we only support RGBA for the source (other 4 byte formats should
    // be easy to add though)
-   AssertFatal(mFormat == GFXFormatR8G8B8A8, "copyToBmp: invalid format");
-   if (mFormat != GFXFormatR8G8B8A8)
+   AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8, "copyToBmp: invalid format");
+   if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8)
       return false;
 
    PROFILE_START(GFXD3D9TextureObject_copyToBmp);

+ 40 - 2
Engine/source/terrain/terrData.cpp

@@ -174,6 +174,18 @@ ConsoleFunction(getTerrainUnderWorldPoint, S32, 2, 4, "(Point3F x/y/z) Gets the
 }
 
 
+typedef TerrainBlock::BaseTexFormat baseTexFormat;
+DefineEnumType(baseTexFormat);
+
+ImplementEnumType(baseTexFormat,
+   "Description\n"
+   "@ingroup ?\n\n")
+{ TerrainBlock::NONE, "NONE", "No cached terrain.\n" },
+{ TerrainBlock::DDS, "DDS", "Cache the terrain in a DDS format.\n" },
+{ TerrainBlock::PNG, "PNG", "Cache the terrain in a PNG format.\n" },
+{ TerrainBlock::JPG, "JPG", "Cache the terrain in a JPG format.\n" },
+EndImplementEnumType;
+
 TerrainBlock::TerrainBlock()
  : mSquareSize( 1.0f ),
    mCastShadows( true ),
@@ -186,6 +198,7 @@ TerrainBlock::TerrainBlock()
    mCell( NULL ),
    mCRC( 0 ),
    mBaseTexSize( 1024 ),
+   mBaseTexFormat( TerrainBlock::JPG ),
    mBaseMaterial( NULL ),
    mDefaultMatInst( NULL ),
    mBaseTexScaleConst( NULL ),
@@ -269,6 +282,27 @@ bool TerrainBlock::_setBaseTexSize( void *obj, const char *index, const char *da
    return false;
 }
 
+bool TerrainBlock::_setBaseTexFormat(void *obj, const char *index, const char *data)
+{
+   TerrainBlock *terrain = static_cast<TerrainBlock*>(obj);
+
+   EngineEnumTable eTable = _baseTexFormat::_sEnumTable;
+
+   for (U8 i = 0; i < eTable.getNumValues(); i++)
+   {
+      if (strcasecmp(eTable[i].mName, data) == 0)
+      {
+         terrain->mBaseTexFormat = (BaseTexFormat)eTable[i].mInt;
+         terrain->_updateMaterials();
+         terrain->_updateLayerTexture();
+         terrain->_updateBaseTexture(true);
+         break;
+      }
+   }
+
+   return false;
+}
+
 bool TerrainBlock::_setLightMapSize( void *obj, const char *index, const char *data )
 {
    TerrainBlock *terrain = static_cast<TerrainBlock*>(obj);
@@ -961,7 +995,7 @@ String TerrainBlock::_getBaseTexCacheFileName() const
 {
    Torque::Path basePath( mTerrFileName );
    basePath.setFileName( basePath.getFileName() + "_basetex" );
-   basePath.setExtension( "dds" );
+   basePath.setExtension( formatToExtension(mBaseTexFormat) );
    return basePath.getFullPath();
 }
 
@@ -1104,6 +1138,10 @@ void TerrainBlock::initPersistFields()
          &TerrainBlock::_setBaseTexSize, &defaultProtectedGetFn,
          "Size of base texture size per meter." );
 
+      addProtectedField("baseTexFormat", TYPEID<baseTexFormat>(), Offset(mBaseTexFormat, TerrainBlock),
+         &TerrainBlock::_setBaseTexFormat, &defaultProtectedGetFn,
+         "");
+
       addProtectedField( "lightMapSize", TypeS32, Offset( mLightMapSize, TerrainBlock ),
          &TerrainBlock::_setLightMapSize, &defaultProtectedGetFn,
          "Light map dimensions in pixels." );
@@ -1200,7 +1238,7 @@ void TerrainBlock::unpackUpdate(NetConnection* con, BitStream *stream)
       {
          mBaseTexSize = baseTexSize;
          if ( isProperlyAdded() )
-            _updateBaseTexture( false );
+            _updateBaseTexture( NONE );
       }
 
       U32 lightMapSize;

+ 28 - 1
Engine/source/terrain/terrData.h

@@ -74,6 +74,30 @@ protected:
       NextFreeMask = Parent::NextFreeMask << 6,
    };
 
+public:
+
+   enum BaseTexFormat
+   {
+      NONE, DDS, PNG, JPG
+   };
+
+   static const char* formatToExtension(BaseTexFormat format)
+   {
+      switch (format)
+      {
+      case DDS:
+         return "dds";
+      case PNG:
+         return "png";
+      case JPG:
+         return "jpg";
+      default:
+         return "";
+      }
+   };
+
+protected:
+
    Box3F mBounds;
 
    ///
@@ -132,6 +156,8 @@ protected:
    /// The desired size for the base texture.
    U32 mBaseTexSize;
 
+   BaseTexFormat mBaseTexFormat;
+
    ///
    TerrCell *mCell;
 
@@ -213,7 +239,8 @@ protected:
    // Protected fields
    static bool _setTerrainFile( void *obj, const char *index, const char *data );
    static bool _setSquareSize( void *obj, const char *index, const char *data );
-   static bool _setBaseTexSize( void *obj, const char *index, const char *data );
+   static bool _setBaseTexSize(void *obj, const char *index, const char *data);
+   static bool _setBaseTexFormat(void *obj, const char *index, const char *data);
    static bool _setLightMapSize( void *obj, const char *index, const char *data );
 
 public:

+ 19 - 6
Engine/source/terrain/terrRender.cpp

@@ -178,7 +178,7 @@ bool TerrainBlock::_initBaseShader()
    return true;
 }
 
-void TerrainBlock::_updateBaseTexture( bool writeToCache )
+void TerrainBlock::_updateBaseTexture(bool writeToCache)
 {
    if ( !mBaseShader && !_initBaseShader() )
       return;
@@ -290,7 +290,14 @@ void TerrainBlock::_updateBaseTexture( bool writeToCache )
       GFX->endScene();
 
    /// Do we cache this sucker?
-   if ( writeToCache )
+   if (mBaseTexFormat == NONE || !writeToCache)
+   {
+      // We didn't cache the result, so set the base texture
+      // to the render target we updated.  This should be good
+      // for realtime painting cases.
+      mBaseTex = blendTex;
+   }
+   else if (mBaseTexFormat == DDS)
    {
       String cachePath = _getBaseTexCacheFileName();
 
@@ -327,10 +334,16 @@ void TerrainBlock::_updateBaseTexture( bool writeToCache )
    }
    else
    {
-      // We didn't cache the result, so set the base texture
-      // to the render target we updated.  This should be good
-      // for realtime painting cases.
-      mBaseTex = blendTex;
+      FileStream stream;
+      if (!stream.open(_getBaseTexCacheFileName(), Torque::FS::File::Write))
+      {
+         mBaseTex = blendTex;
+         return;
+      }
+
+      GBitmap bitmap(blendTex->getWidth(), blendTex->getHeight(), false, GFXFormatR8G8B8);
+      blendTex->copyToBmp(&bitmap);
+      bitmap.writeBitmap(formatToExtension(mBaseTexFormat), stream);
    }
 }