mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 07:04:36 +00:00
Merge remote-tracking branch 'GG-Github/development' into fix_opengl_new_terrain_blend
This commit is contained in:
commit
ff83e8c209
1455 changed files with 98353 additions and 15020 deletions
|
|
@ -30,15 +30,16 @@
|
|||
#include "shaderGen/langElement.h"
|
||||
#include "shaderGen/shaderOp.h"
|
||||
#include "shaderGen/featureMgr.h"
|
||||
#include "shaderGen/shaderGen.h"
|
||||
#include "core/module.h"
|
||||
|
||||
|
||||
MODULE_BEGIN( TerrainFeatHLSL )
|
||||
|
||||
MODULE_INIT_AFTER( ShaderGenFeatureMgr )
|
||||
|
||||
MODULE_INIT
|
||||
namespace
|
||||
{
|
||||
void register_hlsl_shader_features_for_terrain(GFXAdapterType type)
|
||||
{
|
||||
if(type != Direct3D9 && type != Direct3D9_360)
|
||||
return;
|
||||
|
||||
FEATUREMGR->registerFeature( MFT_TerrainBaseMap, new TerrainBaseMapFeatHLSL );
|
||||
FEATUREMGR->registerFeature( MFT_TerrainParallaxMap, new NamedFeatureHLSL( "Terrain Parallax Texture" ) );
|
||||
FEATUREMGR->registerFeature( MFT_TerrainDetailMap, new TerrainDetailMapFeatHLSL );
|
||||
|
|
@ -49,6 +50,17 @@ MODULE_BEGIN( TerrainFeatHLSL )
|
|||
FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MODULE_BEGIN( TerrainFeatHLSL )
|
||||
|
||||
MODULE_INIT_AFTER( ShaderGen )
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
SHADERGEN->getFeatureInitSignal().notify(®ister_hlsl_shader_features_for_terrain);
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
|
||||
|
|
@ -446,7 +458,7 @@ void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &component
|
|||
}
|
||||
|
||||
// Add to the blend total.
|
||||
meta->addStatement( new GenOp( " @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
|
||||
meta->addStatement( new GenOp( " @ += @;\r\n", blendTotal, detailBlend ) );
|
||||
|
||||
// If we had a parallax feature... then factor in the parallax
|
||||
// amount so that it fades out with the layer blending.
|
||||
|
|
|
|||
|
|
@ -46,6 +46,27 @@ AFTER_MODULE_INIT( MaterialManager )
|
|||
|
||||
Vector<TerrainCellMaterial*> TerrainCellMaterial::smAllMaterials;
|
||||
|
||||
Vector<String> _initSamplerNames()
|
||||
{
|
||||
Vector<String> samplerNames;
|
||||
samplerNames.push_back("$baseTexMap");
|
||||
samplerNames.push_back("$layerTex");
|
||||
samplerNames.push_back("$macrolayerTex");
|
||||
samplerNames.push_back("$lightMapTex");
|
||||
samplerNames.push_back("$lightInfoBuffer");
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
samplerNames.push_back(avar("$normalMap%d",i));
|
||||
samplerNames.push_back(avar("$detailMap%d",i));
|
||||
samplerNames.push_back(avar("$macroMap%d",i));
|
||||
}
|
||||
|
||||
return samplerNames;
|
||||
}
|
||||
|
||||
|
||||
const Vector<String> TerrainCellMaterial::mSamplerNames = _initSamplerNames();
|
||||
|
||||
TerrainCellMaterial::TerrainCellMaterial()
|
||||
: mCurrPass( 0 ),
|
||||
mTerrain( NULL ),
|
||||
|
|
@ -460,7 +481,7 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
|
|||
const bool logErrors = matCount == 1;
|
||||
GFXShader::setLogging( logErrors, true );
|
||||
|
||||
pass->shader = SHADERGEN->getShader( featureData, getGFXVertexFormat<TerrVertex>(), NULL );
|
||||
pass->shader = SHADERGEN->getShader( featureData, getGFXVertexFormat<TerrVertex>(), NULL, mSamplerNames );
|
||||
}
|
||||
|
||||
// If we got a shader then we can continue.
|
||||
|
|
@ -499,14 +520,7 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
|
|||
pass->oneOverTerrainSize = pass->shader->getShaderConstHandle( "$oneOverTerrainSize" );
|
||||
pass->squareSize = pass->shader->getShaderConstHandle( "$squareSize" );
|
||||
|
||||
// NOTE: We're assuming rtParams0 here as we know its the only
|
||||
// render target we currently get in a terrain material and the
|
||||
// DeferredRTLightingFeatHLSL will always use 0.
|
||||
//
|
||||
// This could change in the future and we would need to fix
|
||||
// the ShaderFeature API to allow us to do this right.
|
||||
//
|
||||
pass->lightParamsConst = pass->shader->getShaderConstHandle( "$rtParams0" );
|
||||
pass->lightParamsConst = pass->shader->getShaderConstHandle( "$rtParamslightInfoBuffer" );
|
||||
|
||||
// Now prepare the basic stateblock.
|
||||
GFXStateBlockDesc desc;
|
||||
|
|
@ -528,10 +542,7 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
|
|||
|
||||
// We write to the zbuffer if this is a prepass
|
||||
// material or if the prepass is disabled.
|
||||
// We also write the zbuffer if we're using OpenGL, because in OpenGL the prepass
|
||||
// cannot share the same zbuffer as the backbuffer.
|
||||
desc.setZReadWrite( true, !MATMGR->getPrePassEnabled() ||
|
||||
GFX->getAdapterType() == OpenGL ||
|
||||
prePassMat ||
|
||||
reflectMat );
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,8 @@ protected:
|
|||
|
||||
U32 mCurrPass;
|
||||
|
||||
static const Vector<String> mSamplerNames;
|
||||
|
||||
GFXTexHandle mBaseMapTexture;
|
||||
|
||||
GFXTexHandle mLayerMapTexture;
|
||||
|
|
|
|||
|
|
@ -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." );
|
||||
|
|
@ -1161,6 +1199,8 @@ U32 TerrainBlock::packUpdate(NetConnection* con, U32 mask, BitStream *stream)
|
|||
if ( stream->writeFlag( mask & MiscMask ) )
|
||||
stream->write( mScreenError );
|
||||
|
||||
stream->writeInt(mBaseTexFormat, 32);
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
|
|
@ -1200,7 +1240,7 @@ void TerrainBlock::unpackUpdate(NetConnection* con, BitStream *stream)
|
|||
{
|
||||
mBaseTexSize = baseTexSize;
|
||||
if ( isProperlyAdded() )
|
||||
_updateBaseTexture( false );
|
||||
_updateBaseTexture( NONE );
|
||||
}
|
||||
|
||||
U32 lightMapSize;
|
||||
|
|
@ -1227,6 +1267,8 @@ void TerrainBlock::unpackUpdate(NetConnection* con, BitStream *stream)
|
|||
|
||||
if ( stream->readFlag() ) // MiscMask
|
||||
stream->read( &mScreenError );
|
||||
|
||||
mBaseTexFormat = (BaseTexFormat)stream->readInt(32);
|
||||
}
|
||||
|
||||
void TerrainBlock::getMinMaxHeight( F32 *minHeight, F32 *maxHeight ) const
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ ConsoleMethod( TerrainBlock, exportHeightMap, bool, 3, 4, "(string filename, [st
|
|||
UTF8 fileName[1024];
|
||||
String format = "png";
|
||||
if( argc > 3 )
|
||||
format = argv[ 3 ];
|
||||
format = (const char*)argv[ 3 ];
|
||||
|
||||
Con::expandScriptFilename( fileName, sizeof( fileName ), argv[2] );
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ ConsoleMethod( TerrainBlock, exportLayerMaps, bool, 3, 4, "(string filePrefix, [
|
|||
UTF8 filePrefix[1024];
|
||||
String format = "png";
|
||||
if( argc > 3 )
|
||||
format = argv[3];
|
||||
format = (const char*)argv[3];
|
||||
|
||||
Con::expandScriptFilename( filePrefix, sizeof( filePrefix ), argv[2] );
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ void TerrainBlock::_updateLayerTexture()
|
|||
if ( mLayerTex.isNull() ||
|
||||
mLayerTex.getWidth() != layerSize ||
|
||||
mLayerTex.getHeight() != layerSize )
|
||||
mLayerTex.set( layerSize, layerSize, GFXFormatR8G8B8A8, &TerrainLayerTexProfile, "" );
|
||||
mLayerTex.set( layerSize, layerSize, GFXFormatB8G8R8A8, &TerrainLayerTexProfile, "" );
|
||||
|
||||
AssertFatal( mLayerTex.getWidth() == layerSize &&
|
||||
mLayerTex.getHeight() == layerSize,
|
||||
|
|
@ -170,15 +170,16 @@ bool TerrainBlock::_initBaseShader()
|
|||
desc.zDefined = true;
|
||||
desc.zWriteEnable = false;
|
||||
desc.zEnable = false;
|
||||
desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha );
|
||||
desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendOne );
|
||||
desc.cullDefined = true;
|
||||
desc.cullMode = GFXCullNone;
|
||||
desc.colorWriteAlpha = false;
|
||||
mBaseShaderSB = GFX->createStateBlock( desc );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TerrainBlock::_updateBaseTexture( bool writeToCache )
|
||||
void TerrainBlock::_updateBaseTexture(bool writeToCache)
|
||||
{
|
||||
if ( !mBaseShader && !_initBaseShader() )
|
||||
return;
|
||||
|
|
@ -206,17 +207,15 @@ void TerrainBlock::_updateBaseTexture( bool writeToCache )
|
|||
F32 copyOffsetX = 2.0f * GFX->getFillConventionOffset() / (F32)destSize.x;
|
||||
F32 copyOffsetY = 2.0f * GFX->getFillConventionOffset() / (F32)destSize.y;
|
||||
|
||||
const bool needsYFlip = GFX->getAdapterType() == OpenGL;
|
||||
|
||||
GFXVertexPT points[4];
|
||||
points[0].point = Point3F( -1.0 - copyOffsetX, -1.0 + copyOffsetY, 0.0 );
|
||||
points[0].texCoord = Point2F( 0.0, needsYFlip ? 0.0f : 1.0f );
|
||||
points[0].texCoord = Point2F( 0.0, 1.0f );
|
||||
points[1].point = Point3F( -1.0 - copyOffsetX, 1.0 + copyOffsetY, 0.0 );
|
||||
points[1].texCoord = Point2F( 0.0, needsYFlip ? 1.0f : 0.0f );
|
||||
points[1].texCoord = Point2F( 0.0, 0.0f );
|
||||
points[2].point = Point3F( 1.0 - copyOffsetX, 1.0 + copyOffsetY, 0.0 );
|
||||
points[2].texCoord = Point2F( 1.0, needsYFlip ? 1.0f : 0.0f );
|
||||
points[2].texCoord = Point2F( 1.0, 0.0f );
|
||||
points[3].point = Point3F( 1.0 - copyOffsetX, -1.0 + copyOffsetY, 0.0 );
|
||||
points[3].texCoord = Point2F( 1.0, needsYFlip ? 0.0f : 1.0f );
|
||||
points[3].texCoord = Point2F( 1.0, 1.0f );
|
||||
|
||||
vb.set( GFX, 4, GFXBufferTypeVolatile );
|
||||
GFXVertexPT *ptr = vb.lock();
|
||||
|
|
@ -251,6 +250,8 @@ void TerrainBlock::_updateBaseTexture( bool writeToCache )
|
|||
mBaseTarget->attachTexture( GFXTextureTarget::Color0, blendTex );
|
||||
GFX->setActiveRenderTarget( mBaseTarget );
|
||||
|
||||
GFX->clear( GFXClearTarget, ColorI(0,0,0,255), 1.0f, 0 );
|
||||
|
||||
GFX->setTexture( 0, mLayerTex );
|
||||
mBaseShaderConsts->setSafe( mBaseLayerSizeConst, (F32)mLayerTex->getWidth() );
|
||||
|
||||
|
|
@ -290,7 +291,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 +335,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue