diff --git a/Engine/source/gfx/D3D9/gfxD3D9TextureObject.cpp b/Engine/source/gfx/D3D9/gfxD3D9TextureObject.cpp index ff9c69096..bdf0ef449 100644 --- a/Engine/source/gfx/D3D9/gfxD3D9TextureObject.cpp +++ b/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); diff --git a/Engine/source/terrain/terrData.cpp b/Engine/source/terrain/terrData.cpp index 9db97f28a..913232298 100644 --- a/Engine/source/terrain/terrData.cpp +++ b/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(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(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(), 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; diff --git a/Engine/source/terrain/terrData.h b/Engine/source/terrain/terrData.h index 967bfa0d1..91618df73 100644 --- a/Engine/source/terrain/terrData.h +++ b/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: diff --git a/Engine/source/terrain/terrRender.cpp b/Engine/source/terrain/terrRender.cpp index 4b03ac812..61b844380 100644 --- a/Engine/source/terrain/terrRender.cpp +++ b/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); } }