568 lines
17 KiB
C++
568 lines
17 KiB
C++
//====== Copyright © 1996-2004, Valve Corporation, All rights reserved. =======
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "importkeyvaluebase.h"
|
|
#include "dmserializers.h"
|
|
#include "datamodel/idatamodel.h"
|
|
#include "datamodel/dmelement.h"
|
|
#include "datamodel/dmattributevar.h"
|
|
#include "tier1/KeyValues.h"
|
|
#include "tier1/UtlBuffer.h"
|
|
#include "datamodel/dmattribute.h"
|
|
#include "filesystem.h"
|
|
#include "tier2/tier2.h"
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Serialization class for make sheet files
|
|
//-----------------------------------------------------------------------------
|
|
class CImportTex : public IDmSerializer
|
|
{
|
|
public:
|
|
virtual const char *GetName() const { return "tex_source1"; }
|
|
virtual const char *GetDescription() const { return "Valve Texture Configuration File"; }
|
|
virtual bool IsBinaryFormat() const { return false; }
|
|
virtual bool StoresVersionInFile() const { return false; }
|
|
virtual int GetCurrentVersion() const { return 0; } // doesn't store a version
|
|
virtual const char *GetImportedFormat() const { return "tex"; }
|
|
virtual int GetImportedVersion() const { return 1; }
|
|
|
|
bool Serialize( CUtlBuffer &outBuf, CDmElement *pRoot ) { return false; }
|
|
// Read from the UtlBuffer, return true if successful, and return the read-in root in ppRoot.
|
|
bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, const char *pSourceFormatName,
|
|
int nSourceFormatVersion, DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot );
|
|
|
|
private:
|
|
bool ParseOptionKey( const char *pKeyName, const char *pKeyValue, CDmElement *pTexture );
|
|
const char *GetPossiblyQuotedWord( const char *pInBuf, char *pOutbuf );
|
|
bool GetKeyValueFromBuffer( CUtlBuffer &buffer, char *key, char *val );
|
|
CDmElement *AddProcessor( CDmElement *pElement, const char *pProcessorType, const char *pName );
|
|
CDmElement *FindProcessor( CDmElement *pElement, const char *pProcessorType, const char *pName );
|
|
|
|
// Information for the mipmap processor
|
|
bool m_bNoNice;
|
|
bool m_bAlphatestMipmapping;
|
|
float m_flAlphatestMipmapThreshhold;
|
|
float m_flAlphatestMipmapHiFreqThreshhold;
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Singleton instance
|
|
//-----------------------------------------------------------------------------
|
|
static CImportTex s_ImportTex;
|
|
|
|
void InstallTEXImporter( IDataModel *pFactory )
|
|
{
|
|
pFactory->AddSerializer( &s_ImportTex );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Processors
|
|
//-----------------------------------------------------------------------------
|
|
CDmElement *CImportTex::AddProcessor( CDmElement *pElement, const char *pProcessorType, const char *pName )
|
|
{
|
|
CDmrElementArray< CDmElement > processors( pElement, "processors", true );
|
|
CDmElement* pProcessor = CreateElement< CDmElement >( pProcessorType, pName, pElement->GetFileId() );
|
|
processors.AddToTail( pProcessor );
|
|
return pProcessor;
|
|
}
|
|
|
|
CDmElement *CImportTex::FindProcessor( CDmElement *pElement, const char *pProcessorType, const char *pName )
|
|
{
|
|
CDmrElementArrayConst< CDmElement > processors( pElement, "processors" );
|
|
for ( int i = 0; i < processors.Count(); ++i )
|
|
{
|
|
if ( !Q_stricmp( pProcessorType, processors[i]->GetTypeString() ) && !Q_stricmp( pName, processors[i]->GetName() ) )
|
|
return processors[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Parses key values out of the txt file
|
|
//-----------------------------------------------------------------------------
|
|
bool CImportTex::ParseOptionKey( const char *pKeyName, const char *pKeyValue, CDmElement *pTexture )
|
|
{
|
|
int iValue = atoi( pKeyValue ); // To properly have "clamps 0" and not enable the clamping
|
|
|
|
if( !Q_stricmp( pKeyName, "startframe" ) )
|
|
{
|
|
pTexture->SetValue( "startFrame", iValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "endframe" ) )
|
|
{
|
|
pTexture->SetValue( "endFrame", iValue );
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "cubemap" ) )
|
|
{
|
|
pTexture->SetValue( "textureType", iValue ? 1 : 0 );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "volumetexture" ) )
|
|
{
|
|
pTexture->SetValue( "volumeTextureDepth", iValue );
|
|
|
|
/*
|
|
// FIXME: Volume textures don't currently support DXT compression
|
|
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_NOCOMPRESS;
|
|
*/
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "clamps" ) )
|
|
{
|
|
pTexture->SetValue( "clamps", iValue ? true : false );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "clampt" ) )
|
|
{
|
|
pTexture->SetValue( "clampt", iValue ? true : false );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "clampu" ) )
|
|
{
|
|
pTexture->SetValue( "clampu", iValue ? true : false );
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "nodebug" ) )
|
|
{
|
|
pTexture->SetValue( "noDebugOverride", iValue ? true : false );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "pointsample" ) )
|
|
{
|
|
if ( iValue != 0 )
|
|
{
|
|
pTexture->SetValue( "filterType", 4 );
|
|
}
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "trilinear" ) )
|
|
{
|
|
if ( iValue != 0 )
|
|
{
|
|
pTexture->SetValue( "filterType", 2 );
|
|
}
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "anisotropic" ) )
|
|
{
|
|
if ( iValue != 0 )
|
|
{
|
|
pTexture->SetValue( "filterType", 1 );
|
|
}
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "nomip" ) )
|
|
{
|
|
pTexture->SetValue( "noMip", iValue ? true : false );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "nolod" ) )
|
|
{
|
|
pTexture->SetValue( "noLod", iValue ? true : false );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "nonice" ) )
|
|
{
|
|
m_bNoNice = iValue ? true : false;
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "alphatest" ) )
|
|
{
|
|
m_bAlphatestMipmapping = iValue ? true : false;
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "alphatest_threshhold" ) )
|
|
{
|
|
m_flAlphatestMipmapThreshhold = (float)atof( pKeyValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "alphatest_hifreq_threshhold" ) )
|
|
{
|
|
m_flAlphatestMipmapHiFreqThreshhold = (float)atof( pKeyValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "dxt5" ) )
|
|
{
|
|
pTexture->SetValue( "hintDxt5Compression", iValue ? true : false );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "nocompress" ) )
|
|
{
|
|
pTexture->SetValue( "noCompression", iValue ? true : false );
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "numchannels" ) )
|
|
{
|
|
CDmElement *pProcessor = AddProcessor( pTexture, "DmeTP_ChangeColorChannels", "changeColorChannels" );
|
|
pProcessor->SetValue( "maxChannels", iValue );
|
|
}
|
|
else
|
|
{
|
|
Warning("unrecognized option in text file - %s\n", pKeyName );
|
|
}
|
|
|
|
return true;
|
|
#if 0
|
|
else if ( !Q_stricmp( pKeyName, "skybox" ) )
|
|
{
|
|
// We're going to treat it like a cubemap until the very end (we have to load and process all cubemap
|
|
// faces at once, so we can match their edges with the texture compression and mipmapping).
|
|
m_bIsSkyBox = iValue ? true : false;
|
|
m_bIsCubeMap = iValue ? true : false;
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "skyboxcropped" ) )
|
|
{
|
|
m_bIsCroppedSkyBox = iValue ? true : false;
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "bumpscale" ) )
|
|
{
|
|
m_flBumpScale = atof( pKeyValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "border" ) )
|
|
{
|
|
SetFlagValue( m_nFlags, TEXTUREFLAGS_BORDER, iValue );
|
|
// Gets applied to s, t and u We currently assume black border color
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "normal" ) )
|
|
{
|
|
SetFlagValue( m_nFlags, TEXTUREFLAGS_NORMAL, iValue );
|
|
|
|
// Normal maps not supported for manual mip painting
|
|
m_bManualMip = false;
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "normalga" ) )
|
|
{
|
|
m_bNormalToDXT5GA = iValue ? true : false;
|
|
SetFlagValue( m_vtfProcOptions.flags0, VtfProcessingOptions::OPT_NORMAL_GA, iValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "invertgreen" ) )
|
|
{
|
|
m_bNormalInvertGreen = iValue ? true : false;
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "ssbump" ) )
|
|
{
|
|
SetFlagValue( m_nFlags, TEXTUREFLAGS_SSBUMP, iValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "allmips" ) )
|
|
{
|
|
SetFlagValue( m_nFlags, TEXTUREFLAGS_ALL_MIPS, iValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "rendertarget" ) )
|
|
{
|
|
SetFlagValue( m_nFlags, TEXTUREFLAGS_RENDERTARGET, iValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "oneovermiplevelinalpha" ) )
|
|
{
|
|
SetFlagValue( m_vtfProcOptions.flags0, VtfProcessingOptions::OPT_SET_ALPHA_ONEOVERMIP, iValue );
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "premultcolorbyoneovermiplevel" ) )
|
|
{
|
|
SetFlagValue( m_vtfProcOptions.flags0, VtfProcessingOptions::OPT_PREMULT_COLOR_ONEOVERMIP, iValue );
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "normaltodudv" ) )
|
|
{
|
|
m_bNormalToDuDv = iValue ? true : false;
|
|
SetFlagValue( m_vtfProcOptions.flags0, VtfProcessingOptions::OPT_NORMAL_DUDV, iValue );
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "stripalphachannel" ) )
|
|
{
|
|
m_bStripAlphaChannel = iValue ? true : false;
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "stripcolorchannel" ) )
|
|
{
|
|
m_bStripColorChannel = iValue ? true : false;
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "normalalphatodudvluminance" ) )
|
|
{
|
|
m_bAlphaToLuminance = iValue ? true : false;
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "dudv" ) )
|
|
{
|
|
m_bDuDv = iValue ? true : false;
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "reduce" ) )
|
|
{
|
|
m_nReduceX = atoi(pKeyValue);
|
|
m_nReduceY = m_nReduceX;
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "reducex" ) )
|
|
{
|
|
m_nReduceX = atoi(pKeyValue);
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "reducey" ) )
|
|
{
|
|
m_nReduceY = atoi(pKeyValue);
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "maxwidth" ) )
|
|
{
|
|
m_nMaxDimensionX = atoi(pKeyValue);
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "maxwidth_360" ) )
|
|
{
|
|
m_nMaxDimensionX_360 = atoi(pKeyValue);
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "maxheight" ) )
|
|
{
|
|
m_nMaxDimensionY = atoi(pKeyValue);
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "maxheight_360" ) )
|
|
{
|
|
m_nMaxDimensionY_360 = atoi(pKeyValue);
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "alphatodistance" ) )
|
|
{
|
|
m_bAlphaToDistance = iValue ? true : false;
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "distancespread" ) )
|
|
{
|
|
m_flDistanceSpread = atof(pKeyValue);
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "pfmscale" ) )
|
|
{
|
|
m_pfmscale=atof(pKeyValue);
|
|
VTexMsg( "pfmscale = %.2f\n", m_pfmscale );
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "pfm" ) )
|
|
{
|
|
if ( iValue )
|
|
g_eMode = BITMAP_FILE_TYPE_PFM;
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "specvar" ) )
|
|
{
|
|
int iDecayChannel = -1;
|
|
|
|
if ( !Q_stricmp( pKeyValue, "red" ) || !Q_stricmp( pKeyValue, "r" ) )
|
|
iDecayChannel = 0;
|
|
if ( !Q_stricmp( pKeyValue, "green" ) || !Q_stricmp( pKeyValue, "g" ) )
|
|
iDecayChannel = 1;
|
|
if ( !Q_stricmp( pKeyValue, "blue" ) || !Q_stricmp( pKeyValue, "b" ) )
|
|
iDecayChannel = 2;
|
|
if ( !Q_stricmp( pKeyValue, "alpha" ) || !Q_stricmp( pKeyValue, "a" ) )
|
|
iDecayChannel = 3;
|
|
|
|
if ( iDecayChannel >= 0 && iDecayChannel < 4 )
|
|
{
|
|
m_vtfProcOptions.flags0 |= ( VtfProcessingOptions::OPT_DECAY_R | VtfProcessingOptions::OPT_DECAY_EXP_R ) << iDecayChannel;
|
|
m_vtfProcOptions.numNotDecayMips[iDecayChannel] = 0;
|
|
m_vtfProcOptions.clrDecayGoal[iDecayChannel] = 0;
|
|
m_vtfProcOptions.fDecayExponentBase[iDecayChannel] = 0.75;
|
|
m_bManualMip = false;
|
|
SetFlagValue( m_nFlags, TEXTUREFLAGS_ALL_MIPS, 1 );
|
|
}
|
|
}
|
|
else if ( Q_stricmp( pKeyName, "manualmip" ) == 0 )
|
|
{
|
|
if ( ( m_nVolumeTextureDepth == 1 ) && !( m_nFlags & ( TEXTUREFLAGS_NORMAL | TEXTUREFLAGS_NOMIP ) ) )
|
|
{
|
|
m_bManualMip = true;
|
|
}
|
|
}
|
|
else if ( !Q_stricmp( pKeyName, "mipblend" ) )
|
|
{
|
|
SetFlagValue( m_nFlags, TEXTUREFLAGS_ALL_MIPS, 1 );
|
|
|
|
// Possible values
|
|
if ( !Q_stricmp( pKeyValue, "detail" ) ) // Skip 2 mips and fade to gray -> (128, 128, 128, -)
|
|
{
|
|
for( int ch = 0; ch < 3; ++ ch )
|
|
{
|
|
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_R << ch;
|
|
// m_vtfProcOptions.flags0 &= ~(VtfProcessingOptions::OPT_DECAY_EXP_R << ch);
|
|
m_vtfProcOptions.numNotDecayMips[ch] = 2;
|
|
m_vtfProcOptions.clrDecayGoal[ch] = 128;
|
|
}
|
|
}
|
|
/*
|
|
else if ( !Q_stricmp( pKeyValue, "additive" ) ) // Skip 2 mips and fade to black -> (0, 0, 0, -)
|
|
{
|
|
for( int ch = 0; ch < 3; ++ ch )
|
|
{
|
|
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_R << ch;
|
|
m_vtfProcOptions.flags0 &= ~(VtfProcessingOptions::OPT_DECAY_EXP_R << ch);
|
|
m_vtfProcOptions.numDecayMips[ch] = 2;
|
|
m_vtfProcOptions.clrDecayGoal[ch] = 0;
|
|
}
|
|
}
|
|
else if ( !Q_stricmp( pKeyValue, "alphablended" ) ) // Skip 2 mips and fade out alpha to 0
|
|
{
|
|
for( int ch = 3; ch < 4; ++ ch )
|
|
{
|
|
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_R << ch;
|
|
m_vtfProcOptions.flags0 &= ~(VtfProcessingOptions::OPT_DECAY_EXP_R << ch);
|
|
m_vtfProcOptions.numDecayMips[ch] = 2;
|
|
m_vtfProcOptions.clrDecayGoal[ch] = 0;
|
|
}
|
|
}
|
|
*/
|
|
else
|
|
{
|
|
// Parse the given value:
|
|
// skip=3:r=255:g=255:b=255:a=255 - linear decay
|
|
// r=0e.75 - exponential decay targeting 0 with exponent base 0.75
|
|
|
|
int nSteps = 0; // default
|
|
|
|
for ( char const *szParse = pKeyValue; szParse; szParse = strchr( szParse, ':' ), szParse ? ++ szParse : 0 )
|
|
{
|
|
if ( char const *sz = StringAfterPrefix( szParse, "skip=" ) )
|
|
{
|
|
szParse = sz;
|
|
nSteps = atoi(sz);
|
|
}
|
|
else if ( StringHasPrefix( szParse, "r=" ) ||
|
|
StringHasPrefix( szParse, "g=" ) ||
|
|
StringHasPrefix( szParse, "b=" ) ||
|
|
StringHasPrefix( szParse, "a=" ) )
|
|
{
|
|
int ch = 0;
|
|
switch ( *szParse )
|
|
{
|
|
case 'g': case 'G': ch = 1; break;
|
|
case 'b': case 'B': ch = 2; break;
|
|
case 'a': case 'A': ch = 3; break;
|
|
}
|
|
|
|
szParse += 2;
|
|
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_R << ch;
|
|
m_vtfProcOptions.flags0 &= ~(VtfProcessingOptions::OPT_DECAY_EXP_R << ch);
|
|
m_vtfProcOptions.numNotDecayMips[ch] = nSteps;
|
|
m_vtfProcOptions.clrDecayGoal[ch] = atoi( szParse );
|
|
|
|
while ( isdigit( *szParse ) )
|
|
++ szParse;
|
|
|
|
// Exponential decay
|
|
if ( ( *szParse == 'e' || *szParse == 'E' ) && ( szParse[1] == '.' ) )
|
|
{
|
|
m_vtfProcOptions.flags0 |= VtfProcessingOptions::OPT_DECAY_EXP_R << ch;
|
|
m_vtfProcOptions.fDecayExponentBase[ch] = ( float ) atof( szParse + 1 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Warning( "invalid mipblend setting \"%s\"\n", pKeyValue );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if( !Q_stricmp( pKeyName, "srgb" ) )
|
|
{
|
|
// Do nothing for now...this will be removed shortly
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
const char *CImportTex::GetPossiblyQuotedWord( const char *pInBuf, char *pOutbuf )
|
|
{
|
|
pInBuf += strspn( pInBuf, " \t" ); // skip whitespace
|
|
|
|
const char *pWordEnd;
|
|
bool bQuote = false;
|
|
if (pInBuf[0]=='"')
|
|
{
|
|
pInBuf++;
|
|
pWordEnd=strchr(pInBuf,'"');
|
|
bQuote = true;
|
|
}
|
|
else
|
|
{
|
|
pWordEnd=strchr(pInBuf,' ');
|
|
if (! pWordEnd )
|
|
pWordEnd = strchr(pInBuf,'\t' );
|
|
if (! pWordEnd )
|
|
pWordEnd = pInBuf+strlen(pInBuf);
|
|
}
|
|
if ((! pWordEnd ) || (pWordEnd == pInBuf ) )
|
|
return NULL; // no word found
|
|
memcpy( pOutbuf, pInBuf, pWordEnd-pInBuf );
|
|
pOutbuf[pWordEnd-pInBuf]=0;
|
|
|
|
pInBuf = pWordEnd;
|
|
if ( bQuote )
|
|
pInBuf++;
|
|
return pInBuf;
|
|
}
|
|
|
|
// GetKeyValueFromBuffer:
|
|
// fills in "key" and "val" respectively and returns "true" if succeeds.
|
|
// returns false if:
|
|
// a) end-of-buffer is reached (then "val" is empty)
|
|
// b) error occurs (then "val" is the error message)
|
|
//
|
|
bool CImportTex::GetKeyValueFromBuffer( CUtlBuffer &buffer, char *key, char *val )
|
|
{
|
|
char buf[2048];
|
|
|
|
while( buffer.GetBytesRemaining() )
|
|
{
|
|
buffer.GetLine( buf, sizeof( buf ) );
|
|
|
|
// Scanning algorithm
|
|
char *pComment = strpbrk( buf, "#\n\r" );
|
|
if ( pComment )
|
|
*pComment = 0;
|
|
|
|
pComment = strstr( buf, "//" );
|
|
if ( pComment)
|
|
*pComment = 0;
|
|
|
|
const char *scan = buf;
|
|
scan=GetPossiblyQuotedWord( scan, key );
|
|
if ( scan )
|
|
{
|
|
scan=GetPossiblyQuotedWord( scan, val );
|
|
if ( scan )
|
|
return true;
|
|
else
|
|
{
|
|
sprintf( val, "parameter %s has no value", key );
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
val[0] = 0;
|
|
return false;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Main entry point for the unserialization
|
|
//-----------------------------------------------------------------------------
|
|
bool CImportTex::Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, const char *pSourceFormatName,
|
|
int nSourceFormatVersion, DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot )
|
|
{
|
|
*ppRoot = NULL;
|
|
|
|
m_bNoNice = m_bAlphatestMipmapping = false;
|
|
m_flAlphatestMipmapThreshhold = m_flAlphatestMipmapHiFreqThreshhold = 0.0f;
|
|
|
|
CDmElement *pTexture = CreateElement< CDmElement >( "DmePrecompiledTexture", "root", DMFILEID_INVALID );
|
|
pTexture->SetValue( "imageFileName", "__unspecified_texture" );
|
|
|
|
char pKey[2048];
|
|
char pVal[2048];
|
|
while( GetKeyValueFromBuffer( buf, pKey, pVal ) )
|
|
{
|
|
ParseOptionKey( pKey, pVal, pTexture );
|
|
}
|
|
|
|
if ( pVal[0] )
|
|
{
|
|
Warning( "Error importing txt file! %s\n", pVal );
|
|
return false;
|
|
}
|
|
|
|
// Prefer to do mipmapping as one of the final processors
|
|
if ( !pTexture->GetValue< bool >( "noMip" ) || !pTexture->GetValue< bool >( "noLod" ) )
|
|
{
|
|
CDmElement *pProcessor = AddProcessor( pTexture, "DmeTP_ComputeMipmaps", "computeMipmaps" );
|
|
pProcessor->SetValue( "noNiceFiltering", m_bNoNice );
|
|
pProcessor->SetValue( "alphaTestDownsampling", m_bAlphatestMipmapping );
|
|
pProcessor->SetValue( "alphaTestDownsampleThreshhold", m_flAlphatestMipmapThreshhold );
|
|
pProcessor->SetValue( "alphaTestDownsampleHiFreqThreshhold" , m_flAlphatestMipmapHiFreqThreshhold );
|
|
}
|
|
|
|
*ppRoot = pTexture;
|
|
bool bOk = g_pDataModel->UpdateUnserializedElements( pSourceFormatName, nSourceFormatVersion, fileid, idConflictResolution, ppRoot );
|
|
if ( !bOk )
|
|
{
|
|
*ppRoot = NULL;
|
|
}
|
|
return bOk;
|
|
}
|
|
|
|
|
|
|