mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-11 22:54:34 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
80
Engine/source/materials/baseMatInstance.cpp
Normal file
80
Engine/source/materials/baseMatInstance.cpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/baseMatInstance.h"
|
||||
|
||||
#include "core/util/safeDelete.h"
|
||||
|
||||
|
||||
BaseMatInstance::~BaseMatInstance()
|
||||
{
|
||||
deleteAllHooks();
|
||||
}
|
||||
|
||||
void BaseMatInstance::addHook( MatInstanceHook *hook )
|
||||
{
|
||||
AssertFatal( hook, "BaseMatInstance::addHook() - Got null hook!" );
|
||||
|
||||
const MatInstanceHookType &type = hook->getType();
|
||||
|
||||
while ( mHooks.size() <= type )
|
||||
mHooks.push_back( NULL );
|
||||
|
||||
delete mHooks[type];
|
||||
mHooks[type] = hook;
|
||||
}
|
||||
|
||||
MatInstanceHook* BaseMatInstance::getHook( const MatInstanceHookType &type ) const
|
||||
{
|
||||
if ( type >= mHooks.size() )
|
||||
return NULL;
|
||||
|
||||
return mHooks[ type ];
|
||||
}
|
||||
|
||||
void BaseMatInstance::deleteHook( const MatInstanceHookType &type )
|
||||
{
|
||||
if ( type >= mHooks.size() )
|
||||
return;
|
||||
|
||||
delete mHooks[ type ];
|
||||
mHooks[ type ] = NULL;
|
||||
}
|
||||
|
||||
U32 BaseMatInstance::deleteAllHooks()
|
||||
{
|
||||
U32 deleteCount = 0;
|
||||
|
||||
Vector<MatInstanceHook*>::iterator iter = mHooks.begin();
|
||||
for ( ; iter != mHooks.end(); iter++ )
|
||||
{
|
||||
if ( *iter )
|
||||
{
|
||||
delete (*iter);
|
||||
(*iter) = NULL;
|
||||
++deleteCount;
|
||||
}
|
||||
}
|
||||
|
||||
return deleteCount;
|
||||
}
|
||||
254
Engine/source/materials/baseMatInstance.h
Normal file
254
Engine/source/materials/baseMatInstance.h
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _BASEMATINSTANCE_H_
|
||||
#define _BASEMATINSTANCE_H_
|
||||
|
||||
#ifndef _TSIGNAL_H_
|
||||
#include "core/util/tSignal.h"
|
||||
#endif
|
||||
#ifndef _BASEMATERIALDEFINITION_H_
|
||||
#include "materials/baseMaterialDefinition.h"
|
||||
#endif
|
||||
#ifndef _MATERIALPARAMETERS_H_
|
||||
#include "materials/materialParameters.h"
|
||||
#endif
|
||||
#ifndef _MMATRIX_H_
|
||||
#include "math/mMatrix.h"
|
||||
#endif
|
||||
#ifndef _GFXENUMS_H_
|
||||
#include "gfx/gfxEnums.h"
|
||||
#endif
|
||||
#ifndef _GFXSHADER_H_
|
||||
#include "gfx/gfxShader.h"
|
||||
#endif
|
||||
#ifndef _MATERIALFEATUREDATA_H_
|
||||
#include "materials/materialFeatureData.h"
|
||||
#endif
|
||||
#ifndef _MATINSTANCEHOOK_H_
|
||||
#include "materials/matInstanceHook.h"
|
||||
#endif
|
||||
#ifndef _MATSTATEHINT_H_
|
||||
#include "materials/matStateHint.h"
|
||||
#endif
|
||||
|
||||
struct RenderPassData;
|
||||
class GFXVertexBufferHandleBase;
|
||||
class GFXPrimitiveBufferHandle;
|
||||
struct SceneData;
|
||||
class SceneRenderState;
|
||||
struct GFXStateBlockDesc;
|
||||
class GFXVertexFormat;
|
||||
class MatrixSet;
|
||||
class ProcessedMaterial;
|
||||
|
||||
|
||||
///
|
||||
class BaseMatInstance
|
||||
{
|
||||
protected:
|
||||
|
||||
/// The array of active material hooks indexed
|
||||
/// by a MatInstanceHookType.
|
||||
Vector<MatInstanceHook*> mHooks;
|
||||
|
||||
///
|
||||
MatFeaturesDelegate mFeaturesDelegate;
|
||||
|
||||
/// Should be true if init has been called and it succeeded.
|
||||
/// It is up to the derived class to set this variable appropriately.
|
||||
bool mIsValid;
|
||||
|
||||
/// This is set by initialization and used by the prepass.
|
||||
bool mHasNormalMaps;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~BaseMatInstance();
|
||||
|
||||
/// @param features The features you want to allow for this material.
|
||||
///
|
||||
/// @param vertexFormat The vertex format on which this material will be rendered.
|
||||
///
|
||||
/// @see GFXVertexFormat
|
||||
/// @see FeatureSet
|
||||
virtual bool init( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat ) = 0;
|
||||
|
||||
/// Reinitializes the material using the previous
|
||||
/// initialization parameters.
|
||||
/// @see init
|
||||
virtual bool reInit() = 0;
|
||||
|
||||
/// Returns true if init has been successfully called.
|
||||
/// It is up to the derived class to set this value properly.
|
||||
bool isValid() { return mIsValid; }
|
||||
|
||||
/// Adds this stateblock to the base state block
|
||||
/// used during initialization.
|
||||
/// @see init
|
||||
virtual void addStateBlockDesc(const GFXStateBlockDesc& desc) = 0;
|
||||
|
||||
/// Updates the state blocks for this material.
|
||||
virtual void updateStateBlocks() = 0;
|
||||
|
||||
/// Adds a shader macro which will be passed to the shader
|
||||
/// during initialization.
|
||||
/// @see init
|
||||
virtual void addShaderMacro( const String &name, const String &value ) = 0;
|
||||
|
||||
/// Get a MaterialParameters block for this BaseMatInstance,
|
||||
/// caller is responsible for freeing it.
|
||||
virtual MaterialParameters* allocMaterialParameters() = 0;
|
||||
|
||||
/// Set the current parameters for this BaseMatInstance
|
||||
virtual void setMaterialParameters(MaterialParameters* param) = 0;
|
||||
|
||||
/// Get the current parameters for this BaseMatInstance (BaseMatInstances are created with a default active
|
||||
/// MaterialParameters which is managed by BaseMatInstance.
|
||||
virtual MaterialParameters* getMaterialParameters() = 0;
|
||||
|
||||
/// Returns a MaterialParameterHandle for name.
|
||||
virtual MaterialParameterHandle* getMaterialParameterHandle(const String& name) = 0;
|
||||
|
||||
/// Sets up the next rendering pass for this material. It is
|
||||
/// typically called like so...
|
||||
///
|
||||
///@code
|
||||
/// while( mat->setupPass( state, sgData ) )
|
||||
/// {
|
||||
/// mat->setTransforms(...);
|
||||
/// mat->setSceneInfo(...);
|
||||
/// ...
|
||||
/// GFX->drawPrimitive();
|
||||
/// }
|
||||
///@endcode
|
||||
///
|
||||
virtual bool setupPass( SceneRenderState *state, const SceneData &sgData ) = 0;
|
||||
|
||||
/// This initializes the material transforms and should be
|
||||
/// called after setupPass() within the pass loop.
|
||||
/// @see setupPass
|
||||
virtual void setTransforms( const MatrixSet &matrixSet, SceneRenderState *state ) = 0;
|
||||
|
||||
/// This initializes various material scene state settings and
|
||||
/// should be called after setupPass() within the pass loop.
|
||||
/// @see setupPass
|
||||
virtual void setSceneInfo( SceneRenderState *state, const SceneData &sgData ) = 0;
|
||||
|
||||
/// This is normally called from within setupPass() automatically, so its
|
||||
/// unnecessary to do so manually unless a texture stage has changed. If
|
||||
/// so it should be called after setupPass() within the pass loop.
|
||||
/// @see setupPass
|
||||
virtual void setTextureStages(SceneRenderState *, const SceneData &sgData ) = 0;
|
||||
|
||||
/// Sets the vertex and primitive buffers as well as the instancing
|
||||
/// stream buffer for the current material if the material is instanced.
|
||||
virtual void setBuffers( GFXVertexBufferHandleBase *vertBuffer, GFXPrimitiveBufferHandle *primBuffer ) = 0;
|
||||
|
||||
/// Returns true if this material is instanced.
|
||||
virtual bool isInstanced() const = 0;
|
||||
|
||||
/// Used to increment the instance buffer for this material.
|
||||
virtual bool stepInstance() = 0;
|
||||
|
||||
/// Returns true if the material is forward lit and requires
|
||||
/// a list of lights which affect it when rendering.
|
||||
virtual bool isForwardLit() const = 0;
|
||||
|
||||
/// Sets a SimObject which will passed into ShaderFeature::createConstHandles.
|
||||
/// Normal features do not make use of this, it is for special class specific
|
||||
/// or user designed features.
|
||||
virtual void setUserObject( SimObject *userObject ) = 0;
|
||||
virtual SimObject* getUserObject() const = 0;
|
||||
|
||||
/// Returns the material this instance is based on.
|
||||
virtual BaseMaterialDefinition* getMaterial() = 0;
|
||||
|
||||
// BTRTODO: This stuff below should probably not be in BaseMatInstance
|
||||
virtual bool hasGlow() = 0;
|
||||
|
||||
virtual U32 getCurPass() = 0;
|
||||
|
||||
virtual U32 getCurStageNum() = 0;
|
||||
|
||||
virtual RenderPassData *getPass(U32 pass) = 0;
|
||||
|
||||
/// Returns the state hint which can be used for
|
||||
/// sorting and fast comparisions of the equality
|
||||
/// of a material instance.
|
||||
virtual const MatStateHint& getStateHint() const = 0;
|
||||
|
||||
/// Returns the active features in use by this material.
|
||||
/// @see getRequestedFeatures
|
||||
virtual const FeatureSet& getFeatures() const = 0;
|
||||
|
||||
/// Returns the features that were requested at material
|
||||
/// creation time which may differ from the active features.
|
||||
/// @see getFeatures
|
||||
virtual const FeatureSet& getRequestedFeatures() const = 0;
|
||||
|
||||
virtual const GFXVertexFormat* getVertexFormat() const = 0;
|
||||
|
||||
virtual void dumpShaderInfo() const = 0;
|
||||
|
||||
/// Fast test for use of normal maps in this material.
|
||||
bool hasNormalMap() const { return mHasNormalMaps; }
|
||||
|
||||
///
|
||||
MatFeaturesDelegate& getFeaturesDelegate() { return mFeaturesDelegate; }
|
||||
|
||||
/// Returns true if this MatInstance is built from a CustomMaterial.
|
||||
virtual bool isCustomMaterial() const = 0;
|
||||
|
||||
/// @name Material Hook functions
|
||||
/// @{
|
||||
|
||||
///
|
||||
void addHook( MatInstanceHook *hook );
|
||||
|
||||
/// Helper function for getting a hook.
|
||||
/// @see getHook
|
||||
template <class HOOK>
|
||||
inline HOOK* getHook() { return (HOOK*)getHook( HOOK::Type ); }
|
||||
|
||||
///
|
||||
MatInstanceHook* getHook( const MatInstanceHookType &type ) const;
|
||||
|
||||
///
|
||||
void deleteHook( const MatInstanceHookType &type );
|
||||
|
||||
///
|
||||
U32 deleteAllHooks();
|
||||
|
||||
/// @}
|
||||
|
||||
virtual const GFXStateBlockDesc &getUserStateBlock() const = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif /// _BASEMATINSTANCE_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
42
Engine/source/materials/baseMaterialDefinition.h
Normal file
42
Engine/source/materials/baseMaterialDefinition.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _BASEMATERIALDEFINITION_H_
|
||||
#define _BASEMATERIALDEFINITION_H_
|
||||
|
||||
#ifndef _SIMOBJECT_H_
|
||||
#include "console/simObject.h"
|
||||
#endif
|
||||
|
||||
class BaseMatInstance;
|
||||
|
||||
class BaseMaterialDefinition : public SimObject
|
||||
{
|
||||
typedef SimObject Parent;
|
||||
public:
|
||||
virtual BaseMatInstance* createMatInstance() = 0;
|
||||
virtual bool isTranslucent() const = 0;
|
||||
virtual bool isDoubleSided() const = 0;
|
||||
virtual bool isLightmapped() const = 0;
|
||||
virtual bool castsShadows() const = 0;
|
||||
};
|
||||
|
||||
#endif // _BASEMATERIALDEFINITION_H_
|
||||
179
Engine/source/materials/customMaterialDefinition.cpp
Normal file
179
Engine/source/materials/customMaterialDefinition.cpp
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/customMaterialDefinition.h"
|
||||
|
||||
#include "materials/materialManager.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "materials/shaderData.h"
|
||||
#include "gfx/sim/cubemapData.h"
|
||||
#include "gfx/gfxCubemap.h"
|
||||
#include "gfx/sim/gfxStateBlockData.h"
|
||||
|
||||
|
||||
//****************************************************************************
|
||||
// Custom Material
|
||||
//****************************************************************************
|
||||
IMPLEMENT_CONOBJECT(CustomMaterial);
|
||||
|
||||
ConsoleDocClass( CustomMaterial,
|
||||
"@brief Material object which provides more control over surface properties.\n\n"
|
||||
|
||||
"CustomMaterials allow the user to specify their own shaders via the ShaderData datablock. "
|
||||
"Because CustomMaterials are derived from Materials, they can hold a lot of the same properties. "
|
||||
"It is up to the user to code how these properties are used.\n\n"
|
||||
|
||||
"@tsexample\n"
|
||||
"singleton CustomMaterial( WaterBasicMat )\n"
|
||||
"{\n"
|
||||
" sampler[\"reflectMap\"] = \"$reflectbuff\";\n"
|
||||
" sampler[\"refractBuff\"] = \"$backbuff\";\n\n"
|
||||
" cubemap = NewLevelSkyCubemap;\n"
|
||||
" shader = WaterBasicShader;\n"
|
||||
" stateBlock = WaterBasicStateBlock;\n"
|
||||
" version = 2.0;\n"
|
||||
"};\n"
|
||||
"@endtsexample\n\n"
|
||||
|
||||
"@see Material, GFXStateBlockData, ShaderData\n\n"
|
||||
|
||||
"@ingroup Materials\n"
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//----------------------------------------------------------------------------
|
||||
CustomMaterial::CustomMaterial()
|
||||
{
|
||||
mFallback = NULL;
|
||||
mMaxTex = 0;
|
||||
mVersion = 1.1f;
|
||||
mTranslucent = false;
|
||||
dMemset( mFlags, 0, sizeof( mFlags ) );
|
||||
mShaderData = NULL;
|
||||
mRefract = false;
|
||||
mStateBlockData = NULL;
|
||||
mForwardLit = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Init fields
|
||||
//--------------------------------------------------------------------------
|
||||
void CustomMaterial::initPersistFields()
|
||||
{
|
||||
addField("version", TypeF32, Offset(mVersion, CustomMaterial),
|
||||
"@brief Specifies pixel shader version for hardware.\n\n"
|
||||
"Valid pixel shader versions include 2.0, 3.0, etc. "
|
||||
"@note All features aren't compatible with all pixel shader versions.");
|
||||
addField("fallback", TYPEID< Material >(), Offset(mFallback, CustomMaterial),
|
||||
"@brief Alternate material for targeting lower end hardware.\n\n"
|
||||
"If the CustomMaterial requires a higher pixel shader version than the one "
|
||||
"it's using, it's fallback Material will be processed instead. "
|
||||
"If the fallback material wasn't defined, Torque 3D will assert and attempt to use a very "
|
||||
"basic material in it's place.\n\n");
|
||||
addField("shader", TypeRealString, Offset(mShaderDataName, CustomMaterial),
|
||||
"@brief Name of the ShaderData to use for this effect.\n\n");
|
||||
addField("stateBlock", TYPEID< GFXStateBlockData >(), Offset(mStateBlockData, CustomMaterial),
|
||||
"@brief Name of a GFXStateBlockData for this effect.\n\n");
|
||||
addField("target", TypeRealString, Offset(mOutputTarget, CustomMaterial),
|
||||
"@brief String identifier of this material's target texture.");
|
||||
addField("forwardLit", TypeBool, Offset(mForwardLit, CustomMaterial),
|
||||
"@brief Determines if the material should recieve lights in Basic Lighting. "
|
||||
"Has no effect in Advanced Lighting.\n\n");
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// On add - verify data settings
|
||||
//--------------------------------------------------------------------------
|
||||
bool CustomMaterial::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
mShaderData = dynamic_cast<ShaderData*>(Sim::findObject( mShaderDataName ) );
|
||||
if(mShaderDataName.isNotEmpty() && mShaderData == NULL)
|
||||
{
|
||||
logError("Failed to find ShaderData %s", mShaderDataName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* samplerDecl = "sampler";
|
||||
S32 i = 0;
|
||||
for (SimFieldDictionaryIterator itr(getFieldDictionary()); *itr; ++itr)
|
||||
{
|
||||
SimFieldDictionary::Entry* entry = *itr;
|
||||
if (dStrStartsWith(entry->slotName, samplerDecl))
|
||||
{
|
||||
if (i >= MAX_TEX_PER_PASS)
|
||||
{
|
||||
logError("Too many sampler declarations, you may only have %i", MAX_TEX_PER_PASS);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dStrlen(entry->slotName) == dStrlen(samplerDecl))
|
||||
{
|
||||
logError("sampler declarations must have a sampler name, e.g. sampler[\"diffuseMap\"]");
|
||||
return false;
|
||||
}
|
||||
|
||||
mSamplerNames[i] = entry->slotName + dStrlen(samplerDecl);
|
||||
mSamplerNames[i].insert(0, '$');
|
||||
mTexFilename[i] = entry->value;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// On remove
|
||||
//--------------------------------------------------------------------------
|
||||
void CustomMaterial::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Map this material to the texture specified in the "mapTo" data variable
|
||||
//--------------------------------------------------------------------------
|
||||
void CustomMaterial::_mapMaterial()
|
||||
{
|
||||
if( String(getName()).isEmpty() )
|
||||
{
|
||||
Con::warnf( "Unnamed Material! Could not map to: %s", mMapTo.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
if( mMapTo.isEmpty() )
|
||||
return;
|
||||
|
||||
MATMGR->mapMaterial(mMapTo, getName());
|
||||
}
|
||||
|
||||
const GFXStateBlockData* CustomMaterial::getStateBlockData() const
|
||||
{
|
||||
return mStateBlockData;
|
||||
}
|
||||
78
Engine/source/materials/customMaterialDefinition.h
Normal file
78
Engine/source/materials/customMaterialDefinition.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _CUSTOMMATERIALDEFINITION_H_
|
||||
#define _CUSTOMMATERIALDEFINITION_H_
|
||||
|
||||
#ifndef _MATERIALDEFINITION_H_
|
||||
#include "materials/materialDefinition.h"
|
||||
#endif
|
||||
|
||||
class ShaderData;
|
||||
class GFXStateBlockData;
|
||||
|
||||
//**************************************************************************
|
||||
// Custom Material
|
||||
//**************************************************************************
|
||||
class CustomMaterial : public Material
|
||||
{
|
||||
typedef Material Parent;
|
||||
public:
|
||||
enum CustomConsts
|
||||
{
|
||||
MAX_PASSES = 8,
|
||||
NUM_FALLBACK_VERSIONS = 2,
|
||||
};
|
||||
|
||||
FileName mTexFilename[MAX_TEX_PER_PASS];
|
||||
String mSamplerNames[MAX_TEX_PER_PASS];
|
||||
String mOutputTarget;
|
||||
Material* mFallback;
|
||||
bool mForwardLit;
|
||||
|
||||
F32 mVersion; // 0 = legacy, 1 = DX 8.1, 2 = DX 9.0
|
||||
bool mRefract;
|
||||
ShaderData* mShaderData;
|
||||
|
||||
CustomMaterial();
|
||||
const GFXStateBlockData* getStateBlockData() const;
|
||||
|
||||
//
|
||||
// SimObject interface
|
||||
//
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
|
||||
//
|
||||
// ConsoleObject interface
|
||||
//
|
||||
static void initPersistFields();
|
||||
DECLARE_CONOBJECT(CustomMaterial);
|
||||
protected:
|
||||
U32 mMaxTex;
|
||||
String mShaderDataName;
|
||||
U32 mFlags[MAX_TEX_PER_PASS];
|
||||
GFXStateBlockData* mStateBlockData;
|
||||
|
||||
virtual void _mapMaterial();
|
||||
};
|
||||
|
||||
#endif
|
||||
561
Engine/source/materials/matInstance.cpp
Normal file
561
Engine/source/materials/matInstance.cpp
Normal file
|
|
@ -0,0 +1,561 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/matInstance.h"
|
||||
|
||||
#include "materials/materialManager.h"
|
||||
#include "materials/customMaterialDefinition.h"
|
||||
#include "materials/processedMaterial.h"
|
||||
#include "materials/processedFFMaterial.h"
|
||||
#include "materials/processedShaderMaterial.h"
|
||||
#include "materials/processedCustomMaterial.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
#include "shaderGen/featureMgr.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/sim/cubemapData.h"
|
||||
#include "gfx/gfxCubemap.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
|
||||
class MatInstParameters;
|
||||
|
||||
class MatInstanceParameterHandle : public MaterialParameterHandle
|
||||
{
|
||||
public:
|
||||
virtual ~MatInstanceParameterHandle() {}
|
||||
MatInstanceParameterHandle(const String& name);
|
||||
|
||||
void loadHandle(ProcessedMaterial* pmat);
|
||||
|
||||
// MaterialParameterHandle interface
|
||||
const String& getName() const { return mName; }
|
||||
virtual bool isValid() const;
|
||||
virtual S32 getSamplerRegister( U32 pass ) const;
|
||||
private:
|
||||
friend class MatInstParameters;
|
||||
String mName;
|
||||
MaterialParameterHandle* mProcessedHandle;
|
||||
};
|
||||
|
||||
MatInstanceParameterHandle::MatInstanceParameterHandle(const String& name)
|
||||
{
|
||||
mName = name;
|
||||
mProcessedHandle = NULL;
|
||||
}
|
||||
|
||||
bool MatInstanceParameterHandle::isValid() const
|
||||
{
|
||||
return mProcessedHandle && mProcessedHandle->isValid();
|
||||
}
|
||||
|
||||
S32 MatInstanceParameterHandle::getSamplerRegister( U32 pass ) const
|
||||
{
|
||||
if ( !mProcessedHandle )
|
||||
return -1;
|
||||
return mProcessedHandle->getSamplerRegister( pass );
|
||||
}
|
||||
|
||||
void MatInstanceParameterHandle::loadHandle(ProcessedMaterial* pmat)
|
||||
{
|
||||
mProcessedHandle = pmat->getMaterialParameterHandle(mName);
|
||||
}
|
||||
|
||||
MatInstParameters::MatInstParameters()
|
||||
{
|
||||
mOwnParameters = false;
|
||||
mParameters = NULL;
|
||||
}
|
||||
|
||||
MatInstParameters::MatInstParameters(MaterialParameters* matParams)
|
||||
{
|
||||
mOwnParameters = false;
|
||||
mParameters = matParams;
|
||||
}
|
||||
|
||||
void MatInstParameters::loadParameters(ProcessedMaterial* pmat)
|
||||
{
|
||||
mOwnParameters = true;
|
||||
mParameters = pmat->allocMaterialParameters();
|
||||
}
|
||||
|
||||
MatInstParameters::~MatInstParameters()
|
||||
{
|
||||
if (mOwnParameters)
|
||||
SAFE_DELETE(mParameters);
|
||||
}
|
||||
|
||||
const Vector<GFXShaderConstDesc>& MatInstParameters::getShaderConstDesc() const
|
||||
{
|
||||
return mParameters->getShaderConstDesc();
|
||||
}
|
||||
|
||||
U32 MatInstParameters::getAlignmentValue(const GFXShaderConstType constType)
|
||||
{
|
||||
return mParameters->getAlignmentValue(constType);
|
||||
}
|
||||
|
||||
#define MATINSTPARAMSET(handle, f) \
|
||||
if (!mParameters) \
|
||||
return; \
|
||||
AssertFatal(dynamic_cast<MatInstanceParameterHandle*>(handle), "Invalid handle type!"); \
|
||||
MatInstanceParameterHandle* mph = static_cast<MatInstanceParameterHandle*>(handle); \
|
||||
mParameters->set(mph->mProcessedHandle, f); \
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const F32 f)
|
||||
{
|
||||
MATINSTPARAMSET(handle, f);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const Point2F& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const Point3F& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const Point4F& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const ColorF& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const S32 f)
|
||||
{
|
||||
MATINSTPARAMSET(handle, f);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const Point2I& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const Point3I& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const Point4I& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<F32>& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point2F>& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point3F>& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point4F>& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<S32>& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point2I>& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point3I>& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point4I>& fv)
|
||||
{
|
||||
MATINSTPARAMSET(handle, fv);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType)
|
||||
{
|
||||
AssertFatal(dynamic_cast<MatInstanceParameterHandle*>(handle), "Invalid handle type!");
|
||||
MatInstanceParameterHandle* mph = static_cast<MatInstanceParameterHandle*>(handle);
|
||||
mParameters->set(mph->mProcessedHandle, mat, matrixType);
|
||||
}
|
||||
|
||||
void MatInstParameters::set(MaterialParameterHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType)
|
||||
{
|
||||
AssertFatal(dynamic_cast<MatInstanceParameterHandle*>(handle), "Invalid handle type!");
|
||||
MatInstanceParameterHandle* mph = static_cast<MatInstanceParameterHandle*>(handle);
|
||||
mParameters->set(mph->mProcessedHandle, mat, arraySize, matrixType);
|
||||
}
|
||||
#undef MATINSTPARAMSET
|
||||
|
||||
//****************************************************************************
|
||||
// Material Instance
|
||||
//****************************************************************************
|
||||
MatInstance::MatInstance( Material &mat )
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mCurrentHandles );
|
||||
VECTOR_SET_ASSOCIATION( mCurrentParameters );
|
||||
|
||||
mMaterial = &mat;
|
||||
|
||||
mCreatedFromCustomMaterial = (dynamic_cast<CustomMaterial *>(&mat) != NULL);
|
||||
|
||||
construct();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Construct
|
||||
//----------------------------------------------------------------------------
|
||||
void MatInstance::construct()
|
||||
{
|
||||
mUserObject = NULL;
|
||||
mCurPass = -1;
|
||||
mProcessedMaterial = false;
|
||||
mVertexFormat = NULL;
|
||||
mMaxStages = 1;
|
||||
mActiveParameters = NULL;
|
||||
mDefaultParameters = NULL;
|
||||
mHasNormalMaps = false;
|
||||
mIsForwardLit = false;
|
||||
mIsValid = false;
|
||||
|
||||
MATMGR->_track(this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//----------------------------------------------------------------------------
|
||||
MatInstance::~MatInstance()
|
||||
{
|
||||
SAFE_DELETE(mProcessedMaterial);
|
||||
SAFE_DELETE(mDefaultParameters);
|
||||
for (U32 i = 0; i < mCurrentHandles.size(); i++)
|
||||
SAFE_DELETE(mCurrentHandles[i]);
|
||||
|
||||
MATMGR->_untrack(this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Init
|
||||
//----------------------------------------------------------------------------
|
||||
bool MatInstance::init( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat )
|
||||
{
|
||||
AssertFatal( vertexFormat, "MatInstance::init - Got null vertex format!" );
|
||||
|
||||
mFeatureList = features;
|
||||
mVertexFormat = vertexFormat;
|
||||
|
||||
SAFE_DELETE(mProcessedMaterial);
|
||||
mIsValid = processMaterial();
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// reInitialize
|
||||
//----------------------------------------------------------------------------
|
||||
bool MatInstance::reInit()
|
||||
{
|
||||
SAFE_DELETE(mProcessedMaterial);
|
||||
deleteAllHooks();
|
||||
mIsValid = processMaterial();
|
||||
|
||||
if ( mIsValid )
|
||||
{
|
||||
for (U32 i = 0; i < mCurrentHandles.size(); i++)
|
||||
mCurrentHandles[i]->loadHandle(mProcessedMaterial);
|
||||
|
||||
for (U32 i = 0; i < mCurrentParameters.size(); i++)
|
||||
mCurrentParameters[i]->loadParameters(mProcessedMaterial);
|
||||
}
|
||||
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Process stages
|
||||
//----------------------------------------------------------------------------
|
||||
bool MatInstance::processMaterial()
|
||||
{
|
||||
AssertFatal( mMaterial, "MatInstance::processMaterial - Got null material!" );
|
||||
//AssertFatal( mVertexFormat, "MatInstance::processMaterial - Got null vertex format!" );
|
||||
if ( !mMaterial || !mVertexFormat )
|
||||
return false;
|
||||
|
||||
SAFE_DELETE(mDefaultParameters);
|
||||
|
||||
CustomMaterial *custMat = NULL;
|
||||
|
||||
if( dynamic_cast<CustomMaterial*>(mMaterial) )
|
||||
{
|
||||
F32 pixVersion = GFX->getPixelShaderVersion();
|
||||
custMat = static_cast<CustomMaterial*>(mMaterial);
|
||||
if ((custMat->mVersion > pixVersion) || (custMat->mVersion == 0.0))
|
||||
{
|
||||
if(custMat->mFallback)
|
||||
{
|
||||
mMaterial = custMat->mFallback;
|
||||
return processMaterial();
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertWarn(custMat->mVersion == 0.0f, avar("Can't load CustomMaterial %s for %s, using generic FF fallback",
|
||||
String(mMaterial->getName()).isEmpty() ? "Unknown" : mMaterial->getName(), custMat->mMapTo.c_str()));
|
||||
mProcessedMaterial = new ProcessedFFMaterial(*mMaterial);
|
||||
}
|
||||
}
|
||||
else
|
||||
mProcessedMaterial = new ProcessedCustomMaterial(*mMaterial);
|
||||
}
|
||||
else if(GFX->getPixelShaderVersion() > 0.001)
|
||||
mProcessedMaterial = getShaderMaterial();
|
||||
else
|
||||
mProcessedMaterial = new ProcessedFFMaterial(*mMaterial);
|
||||
|
||||
if (mProcessedMaterial)
|
||||
{
|
||||
mProcessedMaterial->addStateBlockDesc( mUserDefinedState );
|
||||
mProcessedMaterial->setShaderMacros( mUserMacros );
|
||||
mProcessedMaterial->setUserObject( mUserObject );
|
||||
|
||||
FeatureSet features( mFeatureList );
|
||||
features.exclude( MATMGR->getExclusionFeatures() );
|
||||
|
||||
if( !mProcessedMaterial->init(features, mVertexFormat, mFeaturesDelegate) )
|
||||
{
|
||||
Con::errorf( "Failed to initialize material '%s'", getMaterial()->getName() );
|
||||
SAFE_DELETE( mProcessedMaterial );
|
||||
return false;
|
||||
}
|
||||
|
||||
mDefaultParameters = new MatInstParameters(mProcessedMaterial->getDefaultMaterialParameters());
|
||||
mActiveParameters = mDefaultParameters;
|
||||
|
||||
const FeatureSet &finalFeatures = mProcessedMaterial->getFeatures();
|
||||
mHasNormalMaps = finalFeatures.hasFeature( MFT_NormalMap );
|
||||
|
||||
mIsForwardLit = ( custMat && custMat->mForwardLit ) ||
|
||||
( !finalFeatures.hasFeature( MFT_IsEmissive ) &&
|
||||
finalFeatures.hasFeature( MFT_ForwardShading ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const MatStateHint& MatInstance::getStateHint() const
|
||||
{
|
||||
if ( mProcessedMaterial )
|
||||
return mProcessedMaterial->getStateHint();
|
||||
else
|
||||
return MatStateHint::Default;
|
||||
}
|
||||
|
||||
ProcessedMaterial* MatInstance::getShaderMaterial()
|
||||
{
|
||||
return new ProcessedShaderMaterial(*mMaterial);
|
||||
}
|
||||
|
||||
void MatInstance::addStateBlockDesc(const GFXStateBlockDesc& desc)
|
||||
{
|
||||
mUserDefinedState = desc;
|
||||
}
|
||||
|
||||
void MatInstance::updateStateBlocks()
|
||||
{
|
||||
if ( mProcessedMaterial )
|
||||
mProcessedMaterial->updateStateBlocks();
|
||||
}
|
||||
|
||||
void MatInstance::addShaderMacro( const String &name, const String &value )
|
||||
{
|
||||
// Check to see if we already have this macro.
|
||||
Vector<GFXShaderMacro>::iterator iter = mUserMacros.begin();
|
||||
for ( ; iter != mUserMacros.end(); iter++ )
|
||||
{
|
||||
if ( iter->name == name )
|
||||
{
|
||||
iter->value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new macro.
|
||||
mUserMacros.increment();
|
||||
mUserMacros.last().name = name;
|
||||
mUserMacros.last().value = value;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Setup pass - needs scenegraph data because the lightmap will change across
|
||||
// several materials.
|
||||
//----------------------------------------------------------------------------
|
||||
bool MatInstance::setupPass(SceneRenderState * state, const SceneData &sgData )
|
||||
{
|
||||
PROFILE_SCOPE( MatInstance_SetupPass );
|
||||
|
||||
if( !mProcessedMaterial )
|
||||
return false;
|
||||
|
||||
++mCurPass;
|
||||
|
||||
if ( !mProcessedMaterial->setupPass( state, sgData, mCurPass ) )
|
||||
{
|
||||
mCurPass = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MatInstance::setTransforms(const MatrixSet &matrixSet, SceneRenderState *state)
|
||||
{
|
||||
PROFILE_SCOPE(MatInstance_setTransforms);
|
||||
mProcessedMaterial->setTransforms(matrixSet, state, getCurPass());
|
||||
}
|
||||
|
||||
void MatInstance::setSceneInfo(SceneRenderState * state, const SceneData& sgData)
|
||||
{
|
||||
PROFILE_SCOPE(MatInstance_setSceneInfo);
|
||||
mProcessedMaterial->setSceneInfo(state, sgData, getCurPass());
|
||||
}
|
||||
|
||||
void MatInstance::setBuffers(GFXVertexBufferHandleBase* vertBuffer, GFXPrimitiveBufferHandle* primBuffer)
|
||||
{
|
||||
mProcessedMaterial->setBuffers(vertBuffer, primBuffer);
|
||||
}
|
||||
|
||||
void MatInstance::setTextureStages(SceneRenderState * state, const SceneData &sgData )
|
||||
{
|
||||
PROFILE_SCOPE(MatInstance_setTextureStages);
|
||||
mProcessedMaterial->setTextureStages(state, sgData, getCurPass());
|
||||
}
|
||||
|
||||
bool MatInstance::isInstanced() const
|
||||
{
|
||||
return mProcessedMaterial->getFeatures().hasFeature( MFT_UseInstancing );
|
||||
}
|
||||
|
||||
bool MatInstance::stepInstance()
|
||||
{
|
||||
AssertFatal( isInstanced(), "MatInstance::stepInstance - This material isn't instanced!" );
|
||||
AssertFatal( mCurPass >= 0, "MatInstance::stepInstance - Must be within material setup pass!" );
|
||||
|
||||
return mProcessedMaterial->stepInstance();
|
||||
}
|
||||
|
||||
U32 MatInstance::getCurStageNum()
|
||||
{
|
||||
return mProcessedMaterial->getStageFromPass(getCurPass());
|
||||
}
|
||||
|
||||
RenderPassData* MatInstance::getPass(U32 pass)
|
||||
{
|
||||
return mProcessedMaterial->getPass(pass);
|
||||
}
|
||||
|
||||
bool MatInstance::hasGlow()
|
||||
{
|
||||
if( mProcessedMaterial )
|
||||
return mProcessedMaterial->hasGlow();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
const FeatureSet& MatInstance::getFeatures() const
|
||||
{
|
||||
return mProcessedMaterial->getFeatures();
|
||||
}
|
||||
|
||||
MaterialParameterHandle* MatInstance::getMaterialParameterHandle(const String& name)
|
||||
{
|
||||
AssertFatal(mProcessedMaterial, "Not init'ed!");
|
||||
for (U32 i = 0; i < mCurrentHandles.size(); i++)
|
||||
{
|
||||
if (mCurrentHandles[i]->getName().equal(name))
|
||||
{
|
||||
return mCurrentHandles[i];
|
||||
}
|
||||
}
|
||||
MatInstanceParameterHandle* mph = new MatInstanceParameterHandle(name);
|
||||
mph->loadHandle(mProcessedMaterial);
|
||||
mCurrentHandles.push_back(mph);
|
||||
return mph;
|
||||
}
|
||||
|
||||
MaterialParameters* MatInstance::allocMaterialParameters()
|
||||
{
|
||||
AssertFatal(mProcessedMaterial, "Not init'ed!");
|
||||
MatInstParameters* mip = new MatInstParameters();
|
||||
mip->loadParameters(mProcessedMaterial);
|
||||
mCurrentParameters.push_back(mip);
|
||||
return mip;
|
||||
}
|
||||
|
||||
void MatInstance::setMaterialParameters(MaterialParameters* param)
|
||||
{
|
||||
AssertFatal(mProcessedMaterial, "Not init'ed!");
|
||||
mProcessedMaterial->setMaterialParameters(param, mCurPass);
|
||||
AssertFatal(dynamic_cast<MatInstParameters*>(param), "Incorrect param type!");
|
||||
mActiveParameters = static_cast<MatInstParameters*>(param);
|
||||
}
|
||||
|
||||
MaterialParameters* MatInstance::getMaterialParameters()
|
||||
{
|
||||
AssertFatal(mProcessedMaterial, "Not init'ed!");
|
||||
return mActiveParameters;
|
||||
}
|
||||
|
||||
void MatInstance::dumpShaderInfo() const
|
||||
{
|
||||
if ( mMaterial == NULL )
|
||||
{
|
||||
Con::errorf( "Trying to get Material information on an invalid MatInstance" );
|
||||
return;
|
||||
}
|
||||
|
||||
Con::printf( "Material Info for object %s - %s", mMaterial->getName(), mMaterial->mMapTo.c_str() );
|
||||
|
||||
if ( mProcessedMaterial == NULL )
|
||||
{
|
||||
Con::printf( " [no processed material!]" );
|
||||
return;
|
||||
}
|
||||
|
||||
mProcessedMaterial->dumpMaterialInfo();
|
||||
}
|
||||
180
Engine/source/materials/matInstance.h
Normal file
180
Engine/source/materials/matInstance.h
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _MATINSTANCE_H_
|
||||
#define _MATINSTANCE_H_
|
||||
|
||||
#ifndef _MATERIALDEFINITION_H_
|
||||
#include "materials/materialDefinition.h"
|
||||
#endif
|
||||
#ifndef _BASEMATINSTANCE_H_
|
||||
#include "materials/baseMatInstance.h"
|
||||
#endif
|
||||
#ifndef _SCENEDATA_H_
|
||||
#include "materials/sceneData.h"
|
||||
#endif
|
||||
#ifndef _GFXSTATEBLOCK_H_
|
||||
#include "gfx/gfxStateBlock.h"
|
||||
#endif
|
||||
#ifndef _FEATURESET_H_
|
||||
#include "shaderGen/featureSet.h"
|
||||
#endif
|
||||
|
||||
class GFXShader;
|
||||
class GFXCubemap;
|
||||
class ShaderFeature;
|
||||
class MatInstanceParameterHandle;
|
||||
class MatInstParameters;
|
||||
class ProcessedMaterial;
|
||||
|
||||
|
||||
///
|
||||
class MatInstance : public BaseMatInstance
|
||||
{
|
||||
public:
|
||||
virtual ~MatInstance();
|
||||
|
||||
// BaseMatInstance
|
||||
virtual bool init( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat );
|
||||
virtual bool reInit();
|
||||
virtual void addStateBlockDesc(const GFXStateBlockDesc& desc);
|
||||
virtual void updateStateBlocks();
|
||||
virtual void addShaderMacro( const String &name, const String &value );
|
||||
virtual MaterialParameters* allocMaterialParameters();
|
||||
virtual void setMaterialParameters(MaterialParameters* param);
|
||||
virtual MaterialParameters* getMaterialParameters();
|
||||
virtual MaterialParameterHandle* getMaterialParameterHandle(const String& name);
|
||||
virtual bool setupPass(SceneRenderState *, const SceneData &sgData );
|
||||
virtual void setTransforms(const MatrixSet &matrixSet, SceneRenderState *state);
|
||||
virtual void setSceneInfo(SceneRenderState *, const SceneData& sgData);
|
||||
virtual void setTextureStages(SceneRenderState * state, const SceneData &sgData );
|
||||
virtual void setBuffers(GFXVertexBufferHandleBase* vertBuffer, GFXPrimitiveBufferHandle* primBuffer);
|
||||
virtual bool isInstanced() const;
|
||||
virtual bool stepInstance();
|
||||
virtual bool isForwardLit() const { return mIsForwardLit; }
|
||||
virtual void setUserObject( SimObject *userObject ) { mUserObject = userObject; }
|
||||
virtual SimObject* getUserObject() const { return mUserObject; }
|
||||
virtual Material *getMaterial() { return mMaterial; }
|
||||
virtual bool hasGlow();
|
||||
virtual U32 getCurPass() { return getMax( mCurPass, 0 ); }
|
||||
virtual U32 getCurStageNum();
|
||||
virtual RenderPassData *getPass(U32 pass);
|
||||
virtual const MatStateHint& getStateHint() const;
|
||||
virtual const GFXVertexFormat* getVertexFormat() const { return mVertexFormat; }
|
||||
virtual const FeatureSet& getFeatures() const;
|
||||
virtual const FeatureSet& getRequestedFeatures() const { return mFeatureList; }
|
||||
virtual void dumpShaderInfo() const;
|
||||
|
||||
|
||||
ProcessedMaterial *getProcessedMaterial() const { return mProcessedMaterial; }
|
||||
|
||||
virtual const GFXStateBlockDesc &getUserStateBlock() const { return mUserDefinedState; }
|
||||
|
||||
virtual bool isCustomMaterial() const { return mCreatedFromCustomMaterial; }
|
||||
protected:
|
||||
|
||||
friend class Material;
|
||||
|
||||
/// Create a material instance by reference to a Material.
|
||||
MatInstance( Material &mat );
|
||||
|
||||
virtual bool processMaterial();
|
||||
virtual ProcessedMaterial* getShaderMaterial();
|
||||
|
||||
Material* mMaterial;
|
||||
ProcessedMaterial* mProcessedMaterial;
|
||||
|
||||
/// The features requested at material creation time.
|
||||
FeatureSet mFeatureList;
|
||||
|
||||
/// The vertex format on which this material will render.
|
||||
const GFXVertexFormat *mVertexFormat;
|
||||
|
||||
/// If the processed material requires forward lighting or not.
|
||||
bool mIsForwardLit;
|
||||
|
||||
S32 mCurPass;
|
||||
U32 mMaxStages;
|
||||
|
||||
GFXStateBlockDesc mUserDefinedState;
|
||||
|
||||
Vector<GFXShaderMacro> mUserMacros;
|
||||
|
||||
SimObject *mUserObject;
|
||||
|
||||
Vector<MatInstanceParameterHandle*> mCurrentHandles;
|
||||
Vector<MatInstParameters*> mCurrentParameters;
|
||||
MatInstParameters* mActiveParameters;
|
||||
MatInstParameters* mDefaultParameters;
|
||||
|
||||
bool mCreatedFromCustomMaterial;
|
||||
private:
|
||||
void construct();
|
||||
};
|
||||
|
||||
//
|
||||
// MatInstParameters
|
||||
//
|
||||
class MatInstParameters : public MaterialParameters
|
||||
{
|
||||
public:
|
||||
MatInstParameters();
|
||||
MatInstParameters(MaterialParameters* matParams);
|
||||
virtual ~MatInstParameters();
|
||||
|
||||
void loadParameters(ProcessedMaterial* pmat);
|
||||
|
||||
/// Returns our list of shader constants, the material can get this and just set the constants it knows about
|
||||
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
|
||||
|
||||
/// @name Set shader constant values
|
||||
/// @{
|
||||
/// Actually set shader constant values
|
||||
/// @param name Name of the constant, this should be a name contained in the array returned in getShaderConstDesc,
|
||||
/// if an invalid name is used, it is ignored.
|
||||
virtual void set(MaterialParameterHandle* handle, const F32 f);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point2F& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point3F& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point4F& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const ColorF& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const S32 f);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point2I& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point3I& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point4I& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<F32>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point2F>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point3F>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point4F>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<S32>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point2I>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point3I>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point4I>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
|
||||
virtual void set(MaterialParameterHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
|
||||
virtual U32 getAlignmentValue(const GFXShaderConstType constType);
|
||||
private:
|
||||
MaterialParameters* mParameters;
|
||||
bool mOwnParameters;
|
||||
};
|
||||
|
||||
|
||||
#endif // _MATINSTANCE_H_
|
||||
35
Engine/source/materials/matInstanceHook.cpp
Normal file
35
Engine/source/materials/matInstanceHook.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/matInstanceHook.h"
|
||||
|
||||
|
||||
MatInstanceHookType::MatInstanceHookType( const char *type )
|
||||
{
|
||||
TypeMap::Iterator iter = getTypeMap().find( type );
|
||||
if ( iter == getTypeMap().end() )
|
||||
iter = getTypeMap().insertUnique( type, getTypeMap().size() );
|
||||
|
||||
mTypeIndex = iter->value;
|
||||
}
|
||||
|
||||
87
Engine/source/materials/matInstanceHook.h
Normal file
87
Engine/source/materials/matInstanceHook.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATINSTANCEHOOK_H_
|
||||
#define _MATINSTANCEHOOK_H_
|
||||
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
|
||||
|
||||
/// The hook type wrapper object
|
||||
class MatInstanceHookType
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef HashTable<String,U32> TypeMap;
|
||||
|
||||
/// Returns the map of all the hook types. We create
|
||||
/// it as a method static so that its available to other
|
||||
/// statics regardless of initialization order.
|
||||
static inline TypeMap& getTypeMap()
|
||||
{
|
||||
static TypeMap smTypeMap;
|
||||
return smTypeMap;
|
||||
}
|
||||
|
||||
/// The hook type index for this type.
|
||||
U32 mTypeIndex;
|
||||
|
||||
public:
|
||||
|
||||
MatInstanceHookType( const char *type );
|
||||
|
||||
inline MatInstanceHookType( const MatInstanceHookType &type )
|
||||
: mTypeIndex( type.mTypeIndex )
|
||||
{
|
||||
}
|
||||
|
||||
inline operator U32 () const { return mTypeIndex; }
|
||||
};
|
||||
|
||||
|
||||
/// This class is used to define hook objects attached to
|
||||
/// material instances and provide a registration system
|
||||
/// for different hook types.
|
||||
///
|
||||
/// @see BaseMatInstance
|
||||
/// @see MaterialManager
|
||||
///
|
||||
class MatInstanceHook
|
||||
{
|
||||
public:
|
||||
|
||||
///
|
||||
virtual ~MatInstanceHook() {}
|
||||
|
||||
///
|
||||
virtual const MatInstanceHookType& getType() const = 0;
|
||||
};
|
||||
|
||||
#endif // _MATINSTANCEHOOK_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
61
Engine/source/materials/matStateHint.cpp
Normal file
61
Engine/source/materials/matStateHint.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/matStateHint.h"
|
||||
|
||||
#include "materials/processedMaterial.h"
|
||||
|
||||
|
||||
const MatStateHint MatStateHint::Default( "Default" );
|
||||
|
||||
void MatStateHint::init( const ProcessedMaterial *mat )
|
||||
{
|
||||
PROFILE_SCOPE( MatStateHint_init );
|
||||
|
||||
mState.clear();
|
||||
|
||||
// Write the material identifier so that we batch by material
|
||||
// specific data like diffuse color and parallax scale.
|
||||
//
|
||||
// NOTE: This doesn't actually cause more draw calls, but it
|
||||
// can cause some extra unnessasary material setup when materials
|
||||
// are different by their properties are the same.
|
||||
//
|
||||
const Material *material = mat->getMaterial();
|
||||
mState += String::ToString( "Material: '%s', %d\n", material->getName(), material->getId() );
|
||||
|
||||
// Go thru each pass and write its state into
|
||||
// the string in the most compact but uniquely
|
||||
// identifiable way.
|
||||
U32 passes = mat->getNumPasses();
|
||||
for ( U32 i=0; i < passes; i++ )
|
||||
mState += mat->getPass( i )->describeSelf();
|
||||
|
||||
// Finally intern the state string for
|
||||
// fast pointer comparisions.
|
||||
mState = mState.intern();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
77
Engine/source/materials/matStateHint.h
Normal file
77
Engine/source/materials/matStateHint.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATSTATEHINT_H_
|
||||
#define _MATSTATEHINT_H_
|
||||
|
||||
#ifndef _TORQUE_STRING_H_
|
||||
#include "core/util/str.h"
|
||||
#endif
|
||||
|
||||
class ProcessedMaterial;
|
||||
|
||||
|
||||
/// A simple object for generating and comparing string based
|
||||
/// hints used for sorting and identifying materials uniquely
|
||||
/// by its shaders and states.
|
||||
class MatStateHint
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor.
|
||||
MatStateHint() {}
|
||||
|
||||
/// Constructor for building special hints.
|
||||
MatStateHint( const String &state )
|
||||
: mState( state.intern() )
|
||||
{
|
||||
}
|
||||
|
||||
/// Initialize the state hint from a ProcessMaterial. This
|
||||
/// assumes that the ProcessedMaterial has properly initialized
|
||||
/// its passes to describe the material uniquely.
|
||||
void init( const ProcessedMaterial *mat );
|
||||
|
||||
/// Clears the hint.
|
||||
void clear() { mState.clear(); }
|
||||
|
||||
/// Returns a 32bit hash key used for sorting by material state.
|
||||
operator U32() const { return mState.getHashCaseSensitive(); }
|
||||
|
||||
/// Fast comparision of state for equality.
|
||||
bool operator ==( const MatStateHint& hint ) const { return mState == hint.mState; }
|
||||
|
||||
/// Fast comparision of state for inequality.
|
||||
bool operator !=( const MatStateHint& hint ) const { return mState != hint.mState; }
|
||||
|
||||
/// A default state hint.
|
||||
static const MatStateHint Default;
|
||||
|
||||
protected:
|
||||
|
||||
/// An interned string of the combined material shader and state info
|
||||
/// for evert pass of the processed material.
|
||||
String mState;
|
||||
|
||||
};
|
||||
|
||||
#endif // _MATSTATEHINT_H_
|
||||
141
Engine/source/materials/matTextureTarget.cpp
Normal file
141
Engine/source/materials/matTextureTarget.cpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/matTextureTarget.h"
|
||||
|
||||
#include "console/console.h"
|
||||
#include "platform/profiler.h"
|
||||
#include "shaderGen/conditionerFeature.h"
|
||||
#include "gfx/gfxTextureObject.h"
|
||||
#include "gfx/gfxStructs.h"
|
||||
|
||||
|
||||
NamedTexTarget::TargetMap NamedTexTarget::smTargets;
|
||||
|
||||
|
||||
bool NamedTexTarget::registerWithName( const String &name )
|
||||
{
|
||||
if ( mIsRegistered )
|
||||
{
|
||||
// If we're already registered with
|
||||
// this name then do nothing.
|
||||
if ( mName == name )
|
||||
return true;
|
||||
|
||||
// Else unregister ourselves first.
|
||||
unregister();
|
||||
}
|
||||
|
||||
// Make sure the target name isn't empty or already taken.
|
||||
if ( name.isEmpty() || smTargets.contains( name ) )
|
||||
return false;
|
||||
|
||||
mName = name;
|
||||
mIsRegistered = true;
|
||||
smTargets.insert( mName, this );
|
||||
return true;
|
||||
}
|
||||
|
||||
void NamedTexTarget::unregister()
|
||||
{
|
||||
if ( !mIsRegistered )
|
||||
return;
|
||||
|
||||
TargetMap::Iterator iter = smTargets.find( mName );
|
||||
|
||||
AssertFatal( iter != smTargets.end() &&
|
||||
iter->value == this,
|
||||
"NamedTexTarget::unregister - Bad registration!" );
|
||||
|
||||
mIsRegistered = false;
|
||||
mName = String::EmptyString;
|
||||
smTargets.erase( iter );
|
||||
}
|
||||
|
||||
NamedTexTarget* NamedTexTarget::find( const String &name )
|
||||
{
|
||||
PROFILE_SCOPE( NamedTexTarget_find );
|
||||
|
||||
TargetMap::Iterator iter = smTargets.find( name );
|
||||
if ( iter != smTargets.end() )
|
||||
return iter->value;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NamedTexTarget::NamedTexTarget()
|
||||
: mViewport( RectI::One ),
|
||||
mIsRegistered( false ),
|
||||
mConditioner( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
NamedTexTarget::~NamedTexTarget()
|
||||
{
|
||||
unregister();
|
||||
}
|
||||
|
||||
void NamedTexTarget::setTexture( U32 index, GFXTextureObject *tex )
|
||||
{
|
||||
AssertFatal( index < 4, "NamedTexTarget::setTexture - Got invalid index!" );
|
||||
mTex[index] = tex;
|
||||
}
|
||||
|
||||
void NamedTexTarget::release()
|
||||
{
|
||||
mTex[0] = NULL;
|
||||
mTex[1] = NULL;
|
||||
mTex[2] = NULL;
|
||||
mTex[3] = NULL;
|
||||
}
|
||||
|
||||
void NamedTexTarget::getShaderMacros( Vector<GFXShaderMacro> *outMacros )
|
||||
{
|
||||
ConditionerFeature *cond = getConditioner();
|
||||
if ( !cond )
|
||||
return;
|
||||
|
||||
// TODO: No check for duplicates is
|
||||
// going on here which might be a problem?
|
||||
|
||||
String targetName = String::ToLower( mName );
|
||||
|
||||
// Add both the condition and uncondition macros.
|
||||
const String &condMethod = cond->getShaderMethodName( ConditionerFeature::ConditionMethod );
|
||||
if ( condMethod.isNotEmpty() )
|
||||
{
|
||||
GFXShaderMacro macro;
|
||||
macro.name = targetName + "Condition";
|
||||
macro.value = condMethod;
|
||||
outMacros->push_back( macro );
|
||||
}
|
||||
|
||||
const String &uncondMethod = cond->getShaderMethodName( ConditionerFeature::UnconditionMethod );
|
||||
if ( uncondMethod.isNotEmpty() )
|
||||
{
|
||||
GFXShaderMacro macro;
|
||||
macro.name = targetName + "Uncondition";
|
||||
macro.value = uncondMethod;
|
||||
outMacros->push_back( macro );
|
||||
}
|
||||
}
|
||||
163
Engine/source/materials/matTextureTarget.h
Normal file
163
Engine/source/materials/matTextureTarget.h
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATTEXTURETARGET_H_
|
||||
#define _MATTEXTURETARGET_H_
|
||||
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
#ifndef _REFBASE_H_
|
||||
#include "core/util/refBase.h"
|
||||
#endif
|
||||
#ifndef _GFXTEXTUREHANDLE_H_
|
||||
#include "gfx/gfxTextureHandle.h"
|
||||
#endif
|
||||
#ifndef _MRECT_H_
|
||||
#include "math/mRect.h"
|
||||
#endif
|
||||
#ifndef _GFXSTATEBLOCK_H_
|
||||
#include "gfx/gfxStateBlock.h"
|
||||
#endif
|
||||
#ifndef _UTIL_DELEGATE_H_
|
||||
#include "core/util/delegate.h"
|
||||
#endif
|
||||
|
||||
struct GFXShaderMacro;
|
||||
class ConditionerFeature;
|
||||
|
||||
|
||||
///
|
||||
class NamedTexTarget : public WeakRefBase
|
||||
{
|
||||
public:
|
||||
|
||||
///
|
||||
static NamedTexTarget* find( const String &name );
|
||||
|
||||
///
|
||||
NamedTexTarget();
|
||||
|
||||
///
|
||||
virtual ~NamedTexTarget();
|
||||
|
||||
///
|
||||
bool registerWithName( const String &name );
|
||||
|
||||
///
|
||||
void unregister();
|
||||
|
||||
///
|
||||
bool isRegistered() const { return mIsRegistered; }
|
||||
|
||||
/// Returns the target name we were registered with.
|
||||
const String& getName() const { return mName; }
|
||||
|
||||
// Register the passed texture with our name, unregistering "anyone"
|
||||
// priorly registered with that name.
|
||||
// Pass NULL to only unregister.
|
||||
void setTexture( GFXTextureObject *tex ) { setTexture( 0, tex ); }
|
||||
|
||||
///
|
||||
void setTexture( U32 index, GFXTextureObject *tex );
|
||||
|
||||
///
|
||||
GFXTextureObject* getTexture( U32 index = 0 ) const;
|
||||
|
||||
/// The delegate used to override the getTexture method.
|
||||
/// @see getTexture
|
||||
typedef Delegate<GFXTextureObject*(U32)> TexDelegate;
|
||||
|
||||
///
|
||||
/// @see getTexture
|
||||
TexDelegate& getTextureDelegate() { return mTexDelegate; }
|
||||
const TexDelegate& getTextureDelegate() const { return mTexDelegate; }
|
||||
|
||||
/// Release all the textures.
|
||||
void release();
|
||||
|
||||
// NOTE:
|
||||
//
|
||||
// The following members are here to support the existing conditioner
|
||||
// and target system used for the deferred gbuffer and lighting.
|
||||
//
|
||||
// We will refactor that system as part of material2 removing the concept
|
||||
// of conditioners from C++ (moving them to HLSL/GLSL) and make the shader
|
||||
// features which use the texture responsible for setting the correct sampler
|
||||
// states.
|
||||
//
|
||||
// It could be that at this time this class could completely
|
||||
// be removed and instead these textures can be registered
|
||||
// with the TEXMGR and looked up there exclusively.
|
||||
//
|
||||
void setViewport( const RectI &viewport ) { mViewport = viewport; }
|
||||
const RectI& getViewport() const { return mViewport; }
|
||||
void setSamplerState( const GFXSamplerStateDesc &desc ) { mSamplerDesc = desc; }
|
||||
void setupSamplerState( GFXSamplerStateDesc *desc ) const { *desc = mSamplerDesc; }
|
||||
void setConditioner( ConditionerFeature *cond ) { mConditioner = cond; }
|
||||
ConditionerFeature* getConditioner() const { return mConditioner; }
|
||||
void getShaderMacros( Vector<GFXShaderMacro> *outMacros );
|
||||
|
||||
protected:
|
||||
|
||||
typedef Map<String,NamedTexTarget*> TargetMap;
|
||||
|
||||
///
|
||||
static TargetMap smTargets;
|
||||
|
||||
///
|
||||
bool mIsRegistered;
|
||||
|
||||
/// The target name we were registered with.
|
||||
String mName;
|
||||
|
||||
/// The held textures.
|
||||
GFXTexHandle mTex[4];
|
||||
|
||||
///
|
||||
TexDelegate mTexDelegate;
|
||||
|
||||
///
|
||||
RectI mViewport;
|
||||
|
||||
///
|
||||
GFXSamplerStateDesc mSamplerDesc;
|
||||
|
||||
///
|
||||
ConditionerFeature *mConditioner;
|
||||
};
|
||||
|
||||
|
||||
inline GFXTextureObject* NamedTexTarget::getTexture( U32 index ) const
|
||||
{
|
||||
AssertFatal( index < 4, "NamedTexTarget::getTexture - Got invalid index!" );
|
||||
if ( mTexDelegate.empty() )
|
||||
return mTex[index];
|
||||
|
||||
return mTexDelegate( index );
|
||||
}
|
||||
|
||||
|
||||
/// A weak reference to a texture target.
|
||||
typedef WeakRefPtr<NamedTexTarget> NamedTexTargetRef;
|
||||
|
||||
#endif // _MATTEXTURETARGET_H_
|
||||
668
Engine/source/materials/materialDefinition.cpp
Normal file
668
Engine/source/materials/materialDefinition.cpp
Normal file
|
|
@ -0,0 +1,668 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/materialDefinition.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "math/mathTypes.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "sceneData.h"
|
||||
#include "gfx/sim/cubemapData.h"
|
||||
#include "gfx/gfxCubemap.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "materials/matInstance.h"
|
||||
#include "sfx/sfxTrack.h"
|
||||
#include "sfx/sfxTypes.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
|
||||
|
||||
IMPLEMENT_CONOBJECT( Material );
|
||||
|
||||
ConsoleDocClass( Material,
|
||||
"@brief A material in Torque 3D is a data structure that describes a surface.\n\n"
|
||||
|
||||
"It contains many different types of information for rendering properties. "
|
||||
"Torque 3D generates shaders from Material definitions. The shaders are compiled "
|
||||
"at runtime and output into the example/shaders directory. Any errors or warnings "
|
||||
"generated from compiling the procedurally generated shaders are output to the console "
|
||||
"as well as the output window in the Visual C IDE.\n\n"
|
||||
|
||||
"@tsexample\n"
|
||||
"singleton Material(DECAL_scorch)\n"
|
||||
"{\n"
|
||||
" baseTex[0] = \"./scorch_decal.png\";\n"
|
||||
" vertColor[ 0 ] = true;\n\n"
|
||||
" translucent = true;\n"
|
||||
" translucentBlendOp = None;\n"
|
||||
" translucentZWrite = true;\n"
|
||||
" alphaTest = true;\n"
|
||||
" alphaRef = 84;\n"
|
||||
"};\n"
|
||||
"@endtsexample\n\n"
|
||||
|
||||
"@see Rendering\n"
|
||||
"@see ShaderData\n"
|
||||
|
||||
"@ingroup GFX\n");
|
||||
|
||||
ImplementBitfieldType( MaterialAnimType,
|
||||
"The type of animation effect to apply to this material.\n"
|
||||
"@ingroup GFX\n\n")
|
||||
{ Material::Scroll, "Scroll", "Scroll the material along the X/Y axis.\n" },
|
||||
{ Material::Rotate, "Rotate" , "Rotate the material around a point.\n"},
|
||||
{ Material::Wave, "Wave" , "Warps the material with an animation using Sin, Triangle or Square mathematics.\n"},
|
||||
{ Material::Scale, "Scale", "Scales the material larger and smaller with a pulsing effect.\n" },
|
||||
{ Material::Sequence, "Sequence", "Enables the material to have multiple frames of animation in its imagemap.\n" }
|
||||
EndImplementBitfieldType;
|
||||
|
||||
ImplementEnumType( MaterialBlendOp,
|
||||
"The type of graphical blending operation to apply to this material\n"
|
||||
"@ingroup GFX\n\n")
|
||||
{ Material::None, "None", "Disable blending for this material." },
|
||||
{ Material::Mul, "Mul", "Multiplicative blending." },
|
||||
{ Material::Add, "Add", "Adds the color of the material to the frame buffer with full alpha for each pixel." },
|
||||
{ Material::AddAlpha, "AddAlpha", "The color is modulated by the alpha channel before being added to the frame buffer." },
|
||||
{ Material::Sub, "Sub", "Subtractive Blending. Reverses the color model, causing dark colors to have a stronger visual effect." },
|
||||
{ Material::LerpAlpha, "LerpAlpha", "Linearly interpolates between Material color and frame buffer color based on alpha." }
|
||||
EndImplementEnumType;
|
||||
|
||||
ImplementEnumType( MaterialWaveType,
|
||||
"When using the Wave material animation, one of these Wave Types will be used to determine the type of wave to display.\n"
|
||||
"@ingroup GFX\n")
|
||||
{ Material::Sin, "Sin", "Warps the material along a curved Sin Wave." },
|
||||
{ Material::Triangle, "Triangle", "Warps the material along a sharp Triangle Wave." },
|
||||
{ Material::Square, "Square", "Warps the material along a wave which transitions between two oppposite states. As a Square Wave, the transition is quick and sudden." },
|
||||
EndImplementEnumType;
|
||||
|
||||
|
||||
bool Material::sAllowTextureTargetAssignment = false;
|
||||
|
||||
GFXCubemap * Material::GetNormalizeCube()
|
||||
{
|
||||
if(smNormalizeCube)
|
||||
return smNormalizeCube;
|
||||
smNormalizeCube = GFX->createCubemap();
|
||||
smNormalizeCube->initNormalize(64);
|
||||
return smNormalizeCube;
|
||||
}
|
||||
|
||||
GFXCubemapHandle Material::smNormalizeCube;
|
||||
|
||||
Material::Material()
|
||||
{
|
||||
for( U32 i=0; i<MAX_STAGES; i++ )
|
||||
{
|
||||
mDiffuse[i].set( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
mSpecular[i].set( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
|
||||
mSpecularPower[i] = 8.0f;
|
||||
mPixelSpecular[i] = false;
|
||||
|
||||
mParallaxScale[i] = 0.0f;
|
||||
|
||||
mVertLit[i] = false;
|
||||
mVertColor[ i ] = false;
|
||||
|
||||
mGlow[i] = false;
|
||||
mEmissive[i] = false;
|
||||
|
||||
mDetailScale[i].set( 2.0f, 2.0f );
|
||||
|
||||
mDetailNormalMapStrength[i] = 1.0f;
|
||||
|
||||
mMinnaertConstant[i] = -1.0f;
|
||||
mSubSurface[i] = false;
|
||||
mSubSurfaceColor[i].set( 1.0f, 0.2f, 0.2f, 1.0f );
|
||||
mSubSurfaceRolloff[i] = 0.2f;
|
||||
|
||||
mAnimFlags[i] = 0;
|
||||
|
||||
mScrollDir[i].set( 0.0f, 0.0f );
|
||||
mScrollSpeed[i] = 0.0f;
|
||||
mScrollOffset[i].set( 0.0f, 0.0f );
|
||||
|
||||
mRotSpeed[i] = 0.0f;
|
||||
mRotPivotOffset[i].set( 0.0f, 0.0f );
|
||||
mRotPos[i] = 0.0f;
|
||||
|
||||
mWavePos[i] = 0.0f;
|
||||
mWaveFreq[i] = 0.0f;
|
||||
mWaveAmp[i] = 0.0f;
|
||||
mWaveType[i] = 0;
|
||||
|
||||
mSeqFramePerSec[i] = 0.0f;
|
||||
mSeqSegSize[i] = 0.0f;
|
||||
}
|
||||
|
||||
dMemset(mCellIndex, 0, sizeof(mCellIndex));
|
||||
dMemset(mCellLayout, 0, sizeof(mCellLayout));
|
||||
dMemset(mCellSize, 0, sizeof(mCellSize));
|
||||
dMemset(mNormalMapAtlas, 0, sizeof(mNormalMapAtlas));
|
||||
dMemset(mUseAnisotropic, 0, sizeof(mUseAnisotropic));
|
||||
|
||||
mImposterLimits = Point4F::Zero;
|
||||
|
||||
mDoubleSided = false;
|
||||
|
||||
mTranslucent = false;
|
||||
mTranslucentBlendOp = LerpAlpha;
|
||||
mTranslucentZWrite = false;
|
||||
|
||||
mAlphaTest = false;
|
||||
mAlphaRef = 1;
|
||||
|
||||
mCastShadows = true;
|
||||
|
||||
mPlanarReflection = false;
|
||||
|
||||
mCubemapData = NULL;
|
||||
mDynamicCubemap = NULL;
|
||||
|
||||
mLastUpdateTime = 0;
|
||||
|
||||
mAutoGenerated = false;
|
||||
|
||||
mShowDust = false;
|
||||
mShowFootprints = true;
|
||||
|
||||
dMemset( mEffectColor, 0, sizeof( mEffectColor ) );
|
||||
|
||||
mFootstepSoundId = -1; mImpactSoundId = -1;
|
||||
mFootstepSoundCustom = 0; mImpactSoundCustom = 0;
|
||||
mFriction = 0.0;
|
||||
|
||||
mDirectSoundOcclusion = 1.f;
|
||||
mReverbSoundOcclusion = 1.0;
|
||||
}
|
||||
|
||||
void Material::initPersistFields()
|
||||
{
|
||||
addField("mapTo", TypeRealString, Offset(mMapTo, Material),
|
||||
"Used to map this material to the material name used by TSShape." );
|
||||
|
||||
addArray( "Stages", MAX_STAGES );
|
||||
|
||||
addField("diffuseColor", TypeColorF, Offset(mDiffuse, Material), MAX_STAGES,
|
||||
"This color is multiplied against the diffuse texture color. If no diffuse texture "
|
||||
"is present this is the material color." );
|
||||
|
||||
addField("diffuseMap", TypeImageFilename, Offset(mDiffuseMapFilename, Material), MAX_STAGES,
|
||||
"The diffuse color texture map." );
|
||||
|
||||
addField("overlayMap", TypeImageFilename, Offset(mOverlayMapFilename, Material), MAX_STAGES,
|
||||
"A secondary diffuse color texture map which will use the second texcoord of a mesh." );
|
||||
|
||||
addField("lightMap", TypeImageFilename, Offset(mLightMapFilename, Material), MAX_STAGES,
|
||||
"The lightmap texture used with pureLight." );
|
||||
|
||||
addField("toneMap", TypeImageFilename, Offset(mToneMapFilename, Material), MAX_STAGES,
|
||||
"The tonemap texture used with pureLight.");
|
||||
|
||||
addField("detailMap", TypeImageFilename, Offset(mDetailMapFilename, Material), MAX_STAGES,
|
||||
"A typically greyscale detail texture additively blended into the material." );
|
||||
|
||||
addField("detailScale", TypePoint2F, Offset(mDetailScale, Material), MAX_STAGES,
|
||||
"The scale factor for the detail map." );
|
||||
|
||||
addField( "normalMap", TypeImageFilename, Offset(mNormalMapFilename, Material), MAX_STAGES,
|
||||
"The normal map texture. You can use the DXTnm format only when per-pixel "
|
||||
"specular highlights are disabled, or a specular map is in use." );
|
||||
|
||||
addField( "detailNormalMap", TypeImageFilename, Offset(mDetailNormalMapFilename, Material), MAX_STAGES,
|
||||
"A second normal map texture applied at the detail scale. You can use the DXTnm "
|
||||
"format only when per-pixel specular highlights are disabled." );
|
||||
|
||||
addField( "detailNormalMapStrength", TypeF32, Offset(mDetailNormalMapStrength, Material), MAX_STAGES,
|
||||
"Used to scale the strength of the detail normal map when blended with the base normal map." );
|
||||
|
||||
addField("specular", TypeColorF, Offset(mSpecular, Material), MAX_STAGES,
|
||||
"The color of the specular highlight when not using a specularMap." );
|
||||
|
||||
addField("specularPower", TypeF32, Offset(mSpecularPower, Material), MAX_STAGES,
|
||||
"The intensity of the specular highlight when not using a specularMap." );
|
||||
|
||||
addField("pixelSpecular", TypeBool, Offset(mPixelSpecular, Material), MAX_STAGES,
|
||||
"This enables per-pixel specular highlights controlled by the alpha channel of the "
|
||||
"normal map texture. Note that if pixel specular is enabled the DXTnm format will not "
|
||||
"work with your normal map, unless you are also using a specular map." );
|
||||
|
||||
addField( "specularMap", TypeImageFilename, Offset(mSpecularMapFilename, Material), MAX_STAGES,
|
||||
"The specular map texture. The RGB channels of this texture provide a per-pixel replacement for the 'specular' parameter on the material. "
|
||||
"If this texture contains alpha information, the alpha channel of the texture will be used as the gloss map. "
|
||||
"This provides a per-pixel replacement for the 'specularPower' on the material" );
|
||||
|
||||
addField( "parallaxScale", TypeF32, Offset(mParallaxScale, Material), MAX_STAGES,
|
||||
"Enables parallax mapping and defines the scale factor for the parallax effect. Typically "
|
||||
"this value is less than 0.4 else the effect breaks down." );
|
||||
|
||||
addField( "useAnisotropic", TypeBool, Offset(mUseAnisotropic, Material), MAX_STAGES,
|
||||
"Use anisotropic filtering for the textures of this stage." );
|
||||
|
||||
addField("envMap", TypeImageFilename, Offset(mEnvMapFilename, Material), MAX_STAGES,
|
||||
"The name of an environment map cube map to apply to this material." );
|
||||
|
||||
addField("vertLit", TypeBool, Offset(mVertLit, Material), MAX_STAGES,
|
||||
"If true the vertex color is used for lighting." );
|
||||
|
||||
addField( "vertColor", TypeBool, Offset( mVertColor, Material ), MAX_STAGES,
|
||||
"If enabled, vertex colors are premultiplied with diffuse colors." );
|
||||
|
||||
addField("minnaertConstant", TypeF32, Offset(mMinnaertConstant, Material), MAX_STAGES,
|
||||
"The Minnaert shading constant value. Must be greater than 0 to enable the effect." );
|
||||
|
||||
addField("subSurface", TypeBool, Offset(mSubSurface, Material), MAX_STAGES,
|
||||
"Enables the subsurface scattering approximation." );
|
||||
|
||||
addField("subSurfaceColor", TypeColorF, Offset(mSubSurfaceColor, Material), MAX_STAGES,
|
||||
"The color used for the subsurface scattering approximation." );
|
||||
|
||||
addField("subSurfaceRolloff", TypeF32, Offset(mSubSurfaceRolloff, Material), MAX_STAGES,
|
||||
"The 0 to 1 rolloff factor used in the subsurface scattering approximation." );
|
||||
|
||||
addField("glow", TypeBool, Offset(mGlow, Material), MAX_STAGES,
|
||||
"Enables rendering this material to the glow buffer." );
|
||||
|
||||
addField("emissive", TypeBool, Offset(mEmissive, Material), MAX_STAGES,
|
||||
"Enables emissive lighting for the material." );
|
||||
|
||||
addField("doubleSided", TypeBool, Offset(mDoubleSided, Material),
|
||||
"Disables backface culling casing surfaces to be double sided. "
|
||||
"Note that the lighting on the backside will be a mirror of the front "
|
||||
"side of the surface." );
|
||||
|
||||
addField("animFlags", TYPEID< AnimType >(), Offset(mAnimFlags, Material), MAX_STAGES,
|
||||
"The types of animation to play on this material." );
|
||||
|
||||
addField("scrollDir", TypePoint2F, Offset(mScrollDir, Material), MAX_STAGES,
|
||||
"The scroll direction in UV space when scroll animation is enabled." );
|
||||
|
||||
addField("scrollSpeed", TypeF32, Offset(mScrollSpeed, Material), MAX_STAGES,
|
||||
"The speed to scroll the texture in UVs per second when scroll animation is enabled." );
|
||||
|
||||
addField("rotSpeed", TypeF32, Offset(mRotSpeed, Material), MAX_STAGES,
|
||||
"The speed to rotate the texture in degrees per second when rotation animation is enabled." );
|
||||
|
||||
addField("rotPivotOffset", TypePoint2F, Offset(mRotPivotOffset, Material), MAX_STAGES,
|
||||
"The piviot position in UV coordinates to center the rotation animation." );
|
||||
|
||||
addField("waveType", TYPEID< WaveType >(), Offset(mWaveType, Material), MAX_STAGES,
|
||||
"The type of wave animation to perform when wave animation is enabled." );
|
||||
|
||||
addField("waveFreq", TypeF32, Offset(mWaveFreq, Material), MAX_STAGES,
|
||||
"The wave frequency when wave animation is enabled." );
|
||||
|
||||
addField("waveAmp", TypeF32, Offset(mWaveAmp, Material), MAX_STAGES,
|
||||
"The wave amplitude when wave animation is enabled." );
|
||||
|
||||
addField("sequenceFramePerSec", TypeF32, Offset(mSeqFramePerSec, Material), MAX_STAGES,
|
||||
"The number of frames per second for frame based sequence animations if greater than zero." );
|
||||
|
||||
addField("sequenceSegmentSize", TypeF32, Offset(mSeqSegSize, Material), MAX_STAGES,
|
||||
"The size of each frame in UV units for sequence animations." );
|
||||
|
||||
// Texture atlasing
|
||||
addField("cellIndex", TypePoint2I, Offset(mCellIndex, Material), MAX_STAGES,
|
||||
"@internal" );
|
||||
addField("cellLayout", TypePoint2I, Offset(mCellLayout, Material), MAX_STAGES,
|
||||
"@internal");
|
||||
addField("cellSize", TypeS32, Offset(mCellSize, Material), MAX_STAGES,
|
||||
"@internal");
|
||||
addField("bumpAtlas", TypeBool, Offset(mNormalMapAtlas, Material), MAX_STAGES,
|
||||
"@internal");
|
||||
|
||||
// For backwards compatibility.
|
||||
//
|
||||
// They point at the new 'map' fields, but reads always return
|
||||
// an empty string and writes only apply if the value is not empty.
|
||||
//
|
||||
addProtectedField("baseTex", TypeImageFilename, Offset(mDiffuseMapFilename, Material),
|
||||
defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
|
||||
"For backwards compatibility.\n@see diffuseMap\n" );
|
||||
addProtectedField("detailTex", TypeImageFilename, Offset(mDetailMapFilename, Material),
|
||||
defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
|
||||
"For backwards compatibility.\n@see detailMap\n");
|
||||
addProtectedField("overlayTex", TypeImageFilename, Offset(mOverlayMapFilename, Material),
|
||||
defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
|
||||
"For backwards compatibility.\n@see overlayMap\n");
|
||||
addProtectedField("bumpTex", TypeImageFilename, Offset(mNormalMapFilename, Material),
|
||||
defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
|
||||
"For backwards compatibility.\n@see normalMap\n");
|
||||
addProtectedField("envTex", TypeImageFilename, Offset(mEnvMapFilename, Material),
|
||||
defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
|
||||
"For backwards compatibility.\n@see envMap\n");
|
||||
addProtectedField("colorMultiply", TypeColorF, Offset(mDiffuse, Material),
|
||||
defaultProtectedSetNotEmptyFn, emptyStringProtectedGetFn, MAX_STAGES,
|
||||
"For backwards compatibility.\n@see diffuseColor\n");
|
||||
|
||||
endArray( "Stages" );
|
||||
|
||||
addField( "castShadows", TypeBool, Offset(mCastShadows, Material),
|
||||
"If set to false the lighting system will not cast shadows from this material." );
|
||||
|
||||
addField("planarReflection", TypeBool, Offset(mPlanarReflection, Material), "@internal" );
|
||||
|
||||
addField("translucent", TypeBool, Offset(mTranslucent, Material),
|
||||
"If true this material is translucent blended." );
|
||||
|
||||
addField("translucentBlendOp", TYPEID< BlendOp >(), Offset(mTranslucentBlendOp, Material),
|
||||
"The type of blend operation to use when the material is translucent." );
|
||||
|
||||
addField("translucentZWrite", TypeBool, Offset(mTranslucentZWrite, Material),
|
||||
"If enabled and the material is translucent it will write into the depth buffer." );
|
||||
|
||||
addField("alphaTest", TypeBool, Offset(mAlphaTest, Material),
|
||||
"Enables alpha test when rendering the material.\n@see alphaRef\n" );
|
||||
|
||||
addField("alphaRef", TypeS32, Offset(mAlphaRef, Material),
|
||||
"The alpha reference value for alpha testing. Must be between 0 to 255.\n@see alphaTest\n" );
|
||||
|
||||
addField("cubemap", TypeRealString, Offset(mCubemapName, Material),
|
||||
"The name of a CubemapData for environment mapping." );
|
||||
|
||||
addField("dynamicCubemap", TypeBool, Offset(mDynamicCubemap, Material),
|
||||
"Enables the material to use the dynamic cubemap from the ShapeBase object its applied to." );
|
||||
|
||||
addGroup( "Behavioral" );
|
||||
|
||||
addField( "showFootprints", TypeBool, Offset( mShowFootprints, Material ),
|
||||
"Whether to show player footprint decals on this material.\n\n"
|
||||
"@see PlayerData::decalData" );
|
||||
|
||||
addField( "showDust", TypeBool, Offset( mShowDust, Material ),
|
||||
"Whether to emit dust particles from a shape moving over the material. This is, for example, used by "
|
||||
"vehicles or players to decide whether to show dust trails." );
|
||||
|
||||
addField( "effectColor", TypeColorF, Offset( mEffectColor, Material ), NUM_EFFECT_COLOR_STAGES,
|
||||
"If #showDust is true, this is the set of colors to use for the ParticleData of the dust "
|
||||
"emitter.\n\n"
|
||||
"@see ParticleData::colors" );
|
||||
|
||||
addField( "footstepSoundId", TypeS32, Offset( mFootstepSoundId, Material ),
|
||||
"What sound to play from the PlayerData sound list when the player walks over the material. -1 (default) to not play any sound.\n"
|
||||
"\n"
|
||||
"The IDs are:\n\n"
|
||||
"- 0: PlayerData::FootSoftSound\n"
|
||||
"- 1: PlayerData::FootHardSound\n"
|
||||
"- 2: PlayerData::FootMetalSound\n"
|
||||
"- 3: PlayerData::FootSnowSound\n"
|
||||
"- 4: PlayerData::FootShallowSound\n"
|
||||
"- 5: PlayerData::FootWadingSound\n"
|
||||
"- 6: PlayerData::FootUnderwaterSound\n"
|
||||
"- 7: PlayerData::FootBubblesSound\n"
|
||||
"- 8: PlayerData::movingBubblesSound\n"
|
||||
"- 9: PlayerData::waterBreathSound\n"
|
||||
"- 10: PlayerData::impactSoftSound\n"
|
||||
"- 11: PlayerData::impactHardSound\n"
|
||||
"- 12: PlayerData::impactMetalSound\n"
|
||||
"- 13: PlayerData::impactSnowSound\n"
|
||||
"- 14: PlayerData::impactWaterEasy\n"
|
||||
"- 15: PlayerData::impactWaterMedium\n"
|
||||
"- 16: PlayerData::impactWaterHard\n"
|
||||
"- 17: PlayerData::exitingWater\n" );
|
||||
|
||||
addField( "customFootstepSound", TypeSFXTrackName, Offset( mFootstepSoundCustom, Material ),
|
||||
"The sound to play when the player walks over the material. If this is set, it overrides #footstepSoundId. This field is "
|
||||
"useful for directly assigning custom footstep sounds to materials without having to rely on the PlayerData sound assignment.\n\n"
|
||||
"@warn Be aware that materials are client-side objects. This means that the SFXTracks assigned to materials must be client-side, too." );
|
||||
addField( "impactSoundId", TypeS32, Offset( mImpactSoundId, Material ),
|
||||
"What sound to play from the PlayerData sound list when the player impacts on the surface with a velocity equal or greater "
|
||||
"than PlayerData::groundImpactMinSpeed.\n\n"
|
||||
"For a list of IDs, see #footstepSoundId" );
|
||||
addField( "customImpactSound", TypeSFXTrackName, Offset( mImpactSoundCustom, Material ),
|
||||
"The sound to play when the player impacts on the surface with a velocity equal or greater than PlayerData::groundImpactMinSpeed. "
|
||||
"If this is set, it overrides #impactSoundId. This field is useful for directly assigning custom impact sounds to materials "
|
||||
"without having to rely on the PlayerData sound assignment.\n\n"
|
||||
"@warn Be aware that materials are client-side objects. This means that the SFXTracks assigned to materials must be client-side, too." );
|
||||
|
||||
//Deactivate these for the moment as they are not used.
|
||||
|
||||
#if 0
|
||||
addField( "friction", TypeF32, Offset( mFriction, Material ) );
|
||||
addField( "directSoundOcclusion", TypeF32, Offset( mDirectSoundOcclusion, Material ) );
|
||||
addField( "reverbSoundOcclusion", TypeF32, Offset( mReverbSoundOcclusion, Material ) );
|
||||
#endif
|
||||
|
||||
endGroup( "Behavioral" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool Material::writeField( StringTableEntry fieldname, const char *value )
|
||||
{
|
||||
// Never allow the old field names to be written.
|
||||
if ( fieldname == StringTable->insert("baseTex") ||
|
||||
fieldname == StringTable->insert("detailTex") ||
|
||||
fieldname == StringTable->insert("overlayTex") ||
|
||||
fieldname == StringTable->insert("bumpTex") ||
|
||||
fieldname == StringTable->insert("envTex") ||
|
||||
fieldname == StringTable->insert("colorMultiply") )
|
||||
return false;
|
||||
|
||||
return Parent::writeField( fieldname, value );
|
||||
}
|
||||
|
||||
bool Material::onAdd()
|
||||
{
|
||||
if (Parent::onAdd() == false)
|
||||
return false;
|
||||
|
||||
mCubemapData = dynamic_cast<CubemapData*>(Sim::findObject( mCubemapName ) );
|
||||
|
||||
if( mTranslucentBlendOp >= NumBlendTypes || mTranslucentBlendOp < 0 )
|
||||
{
|
||||
Con::errorf( "Invalid blend op in material: %s", getName() );
|
||||
mTranslucentBlendOp = LerpAlpha;
|
||||
}
|
||||
|
||||
SimSet *matSet = MATMGR->getMaterialSet();
|
||||
if( matSet )
|
||||
matSet->addObject( (SimObject*)this );
|
||||
|
||||
// save the current script path for texture lookup later
|
||||
const String scriptFile = Con::getVariable("$Con::File"); // current script file - local materials.cs
|
||||
|
||||
String::SizeType slash = scriptFile.find( '/', scriptFile.length(), String::Right );
|
||||
if ( slash != String::NPos )
|
||||
mPath = scriptFile.substr( 0, slash + 1 );
|
||||
|
||||
_mapMaterial();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Material::onRemove()
|
||||
{
|
||||
smNormalizeCube = NULL;
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
void Material::inspectPostApply()
|
||||
{
|
||||
Parent::inspectPostApply();
|
||||
|
||||
// Reload the material instances which
|
||||
// use this material.
|
||||
if ( isProperlyAdded() )
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
bool Material::isLightmapped() const
|
||||
{
|
||||
bool ret = false;
|
||||
for( U32 i=0; i<MAX_STAGES; i++ )
|
||||
ret |= mLightMapFilename[i].isNotEmpty() || mToneMapFilename[i].isNotEmpty() || mVertLit[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Material::updateTimeBasedParams()
|
||||
{
|
||||
U32 lastTime = MATMGR->getLastUpdateTime();
|
||||
F32 dt = MATMGR->getDeltaTime();
|
||||
if (mLastUpdateTime != lastTime)
|
||||
{
|
||||
for (U32 i = 0; i < MAX_STAGES; i++)
|
||||
{
|
||||
mScrollOffset[i] += mScrollDir[i] * mScrollSpeed[i] * dt;
|
||||
mRotPos[i] += mRotSpeed[i] * dt;
|
||||
mWavePos[i] += mWaveFreq[i] * dt;
|
||||
}
|
||||
mLastUpdateTime = lastTime;
|
||||
}
|
||||
}
|
||||
|
||||
void Material::_mapMaterial()
|
||||
{
|
||||
if( String(getName()).isEmpty() )
|
||||
{
|
||||
Con::warnf( "[Material::mapMaterial] - Cannot map unnamed Material" );
|
||||
return;
|
||||
}
|
||||
|
||||
// If mapTo not defined in script, try to use the base texture name instead
|
||||
if( mMapTo.isEmpty() )
|
||||
{
|
||||
if ( mDiffuseMapFilename[0].isEmpty() )
|
||||
return;
|
||||
|
||||
else
|
||||
{
|
||||
// extract filename from base texture
|
||||
if ( mDiffuseMapFilename[0].isNotEmpty() )
|
||||
{
|
||||
U32 slashPos = mDiffuseMapFilename[0].find('/',0,String::Right);
|
||||
if (slashPos == String::NPos)
|
||||
// no '/' character, must be no path, just the filename
|
||||
mMapTo = mDiffuseMapFilename[0];
|
||||
else
|
||||
// use everything after the last slash
|
||||
mMapTo = mDiffuseMapFilename[0].substr(slashPos+1, mDiffuseMapFilename[0].length() - slashPos - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add mapping
|
||||
MATMGR->mapMaterial(mMapTo,getName());
|
||||
}
|
||||
|
||||
BaseMatInstance* Material::createMatInstance()
|
||||
{
|
||||
return new MatInstance(*this);
|
||||
}
|
||||
|
||||
void Material::flush()
|
||||
{
|
||||
MATMGR->flushInstance( this );
|
||||
}
|
||||
|
||||
void Material::reload()
|
||||
{
|
||||
MATMGR->reInitInstance( this );
|
||||
}
|
||||
|
||||
void Material::StageData::getFeatureSet( FeatureSet *outFeatures ) const
|
||||
{
|
||||
TextureTable::ConstIterator iter = mTextures.begin();
|
||||
for ( ; iter != mTextures.end(); iter++ )
|
||||
{
|
||||
if ( iter->value.isValid() )
|
||||
outFeatures->addFeature( *iter->key );
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleMethod( Material, flush, void, 2, 2,
|
||||
"Flushes all material instances that use this material." )
|
||||
{
|
||||
object->flush();
|
||||
}
|
||||
|
||||
ConsoleMethod( Material, reload, void, 2, 2,
|
||||
"Reloads all material instances that use this material." )
|
||||
{
|
||||
object->reload();
|
||||
}
|
||||
|
||||
ConsoleMethod( Material, dumpInstances, void, 2, 2,
|
||||
"Dumps a formatted list of the currently allocated material instances for this material to the console." )
|
||||
{
|
||||
MATMGR->dumpMaterialInstances( object );
|
||||
}
|
||||
|
||||
ConsoleMethod( Material, getAnimFlags, const char*, 3, 3, "" )
|
||||
{
|
||||
char * animFlags = Con::getReturnBuffer(512);
|
||||
|
||||
if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Scroll)
|
||||
{
|
||||
if(dStrcmp( animFlags, "" ) == 0)
|
||||
dStrcpy( animFlags, "$Scroll" );
|
||||
}
|
||||
if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Rotate)
|
||||
{
|
||||
if(dStrcmp( animFlags, "" ) == 0)
|
||||
dStrcpy( animFlags, "$Rotate" );
|
||||
else
|
||||
dStrcat( animFlags, " | $Rotate");
|
||||
}
|
||||
if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Wave)
|
||||
{
|
||||
if(dStrcmp( animFlags, "" ) == 0)
|
||||
dStrcpy( animFlags, "$Wave" );
|
||||
else
|
||||
dStrcat( animFlags, " | $Wave");
|
||||
}
|
||||
if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Scale)
|
||||
{
|
||||
if(dStrcmp( animFlags, "" ) == 0)
|
||||
dStrcpy( animFlags, "$Scale" );
|
||||
else
|
||||
dStrcat( animFlags, " | $Scale");
|
||||
}
|
||||
if(object->mAnimFlags[ dAtoi(argv[2]) ] & Material::Sequence)
|
||||
{
|
||||
if(dStrcmp( animFlags, "" ) == 0)
|
||||
dStrcpy( animFlags, "$Sequence" );
|
||||
else
|
||||
dStrcat( animFlags, " | $Sequence");
|
||||
}
|
||||
|
||||
return animFlags;
|
||||
}
|
||||
|
||||
ConsoleMethod(Material, getFilename, const char*, 2, 2, "Get filename of material")
|
||||
{
|
||||
SimObject *material = static_cast<SimObject *>(object);
|
||||
return material->getFilename();
|
||||
}
|
||||
|
||||
ConsoleMethod( Material, isAutoGenerated, bool, 2, 2,
|
||||
"Returns true if this Material was automatically generated by MaterialList::mapMaterials()" )
|
||||
{
|
||||
return object->isAutoGenerated();
|
||||
}
|
||||
|
||||
ConsoleMethod( Material, setAutoGenerated, void, 3, 3,
|
||||
"setAutoGenerated(bool isAutoGenerated): Set whether or not the Material is autogenerated." )
|
||||
{
|
||||
object->setAutoGenerated(dAtob(argv[2]));
|
||||
}
|
||||
401
Engine/source/materials/materialDefinition.h
Normal file
401
Engine/source/materials/materialDefinition.h
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _MATERIALDEFINITION_H_
|
||||
#define _MATERIALDEFINITION_H_
|
||||
|
||||
#ifndef _BASEMATERIALDEFINITION_H_
|
||||
#include "materials/baseMaterialDefinition.h"
|
||||
#endif
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
#ifndef _GFXTEXTUREHANDLE_H_
|
||||
#include "gfx/gfxTextureHandle.h"
|
||||
#endif
|
||||
#ifndef _GFXSTRUCTS_H_
|
||||
#include "gfx/gfxStructs.h"
|
||||
#endif
|
||||
#ifndef _GFXCUBEMAP_H_
|
||||
#include "gfx/gfxCubemap.h"
|
||||
#endif
|
||||
#ifndef _DYNAMIC_CONSOLETYPES_H_
|
||||
#include "console/dynamicTypes.h"
|
||||
#endif
|
||||
|
||||
|
||||
class CubemapData;
|
||||
class SFXTrack;
|
||||
struct SceneData;
|
||||
class FeatureSet;
|
||||
class FeatureType;
|
||||
class MaterialSoundProfile;
|
||||
class MaterialPhysicsProfile;
|
||||
|
||||
|
||||
/// The basic material definition.
|
||||
class Material : public BaseMaterialDefinition
|
||||
{
|
||||
typedef BaseMaterialDefinition Parent;
|
||||
public:
|
||||
static GFXCubemap *GetNormalizeCube();
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Enums
|
||||
//-----------------------------------------------------------------------
|
||||
enum Constants
|
||||
{
|
||||
MAX_TEX_PER_PASS = 8, ///< Number of textures per pass
|
||||
MAX_STAGES = 4,
|
||||
NUM_EFFECT_COLOR_STAGES = 2, ///< Number of effect color definitions for transitioning effects.
|
||||
};
|
||||
|
||||
enum TexType
|
||||
{
|
||||
NoTexture = 0,
|
||||
Standard = 1,
|
||||
Detail,
|
||||
Bump,
|
||||
DetailBump,
|
||||
Env,
|
||||
Cube,
|
||||
SGCube, // scene graph cube - probably dynamic
|
||||
Lightmap,
|
||||
ToneMapTex,
|
||||
Mask,
|
||||
BackBuff,
|
||||
ReflectBuff,
|
||||
Misc,
|
||||
DynamicLight,
|
||||
DynamicLightMask,
|
||||
NormalizeCube,
|
||||
TexTarget,
|
||||
};
|
||||
|
||||
enum BlendOp
|
||||
{
|
||||
None = 0,
|
||||
Mul,
|
||||
Add,
|
||||
AddAlpha, // add modulated with alpha channel
|
||||
Sub,
|
||||
LerpAlpha, // linear interpolation modulated with alpha channel
|
||||
ToneMap,
|
||||
NumBlendTypes
|
||||
};
|
||||
|
||||
enum AnimType
|
||||
{
|
||||
Scroll = 1,
|
||||
Rotate = 2,
|
||||
Wave = 4,
|
||||
Scale = 8,
|
||||
Sequence = 16,
|
||||
};
|
||||
|
||||
enum WaveType
|
||||
{
|
||||
Sin = 0,
|
||||
Triangle,
|
||||
Square,
|
||||
};
|
||||
|
||||
class StageData
|
||||
{
|
||||
protected:
|
||||
|
||||
///
|
||||
typedef HashTable<const FeatureType*,GFXTexHandle> TextureTable;
|
||||
|
||||
/// The sparse table of textures by feature index.
|
||||
/// @see getTex
|
||||
/// @see setTex
|
||||
TextureTable mTextures;
|
||||
|
||||
/// The cubemap for this stage.
|
||||
GFXCubemap *mCubemap;
|
||||
|
||||
public:
|
||||
|
||||
StageData()
|
||||
: mCubemap( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
/// Returns the texture object or NULL if there is no
|
||||
/// texture entry for that feature type in the table.
|
||||
inline GFXTextureObject* getTex( const FeatureType &type ) const
|
||||
{
|
||||
TextureTable::ConstIterator iter = mTextures.find( &type );
|
||||
if ( iter == mTextures.end() )
|
||||
return NULL;
|
||||
|
||||
return iter->value.getPointer();
|
||||
}
|
||||
|
||||
/// Assigns a texture object by feature type.
|
||||
inline void setTex( const FeatureType &type, GFXTextureObject *tex )
|
||||
{
|
||||
if ( !tex )
|
||||
{
|
||||
TextureTable::Iterator iter = mTextures.find( &type );
|
||||
if ( iter != mTextures.end() )
|
||||
mTextures.erase( iter );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
TextureTable::Iterator iter = mTextures.findOrInsert( &type );
|
||||
iter->value = tex;
|
||||
}
|
||||
|
||||
/// Returns true if we have a valid texture assigned to
|
||||
/// any feature in the texture table.
|
||||
inline bool hasValidTex() const
|
||||
{
|
||||
TextureTable::ConstIterator iter = mTextures.begin();
|
||||
for ( ; iter != mTextures.end(); iter++ )
|
||||
{
|
||||
if ( iter->value.isValid() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns the active texture features.
|
||||
void getFeatureSet( FeatureSet *outFeatures ) const;
|
||||
|
||||
/// Returns the stage cubemap.
|
||||
GFXCubemap* getCubemap() const { return mCubemap; }
|
||||
|
||||
/// Set the stage cubemap.
|
||||
void setCubemap( GFXCubemap *cubemap ) { mCubemap = cubemap; }
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Data
|
||||
//-----------------------------------------------------------------------
|
||||
FileName mDiffuseMapFilename[MAX_STAGES];
|
||||
FileName mOverlayMapFilename[MAX_STAGES];
|
||||
FileName mLightMapFilename[MAX_STAGES];
|
||||
FileName mToneMapFilename[MAX_STAGES];
|
||||
FileName mDetailMapFilename[MAX_STAGES];
|
||||
FileName mNormalMapFilename[MAX_STAGES];
|
||||
|
||||
FileName mSpecularMapFilename[MAX_STAGES];
|
||||
|
||||
/// A second normal map which repeats at the detail map
|
||||
/// scale and blended with the base normal map.
|
||||
FileName mDetailNormalMapFilename[MAX_STAGES];
|
||||
|
||||
/// The strength scalar for the detail normal map.
|
||||
F32 mDetailNormalMapStrength[MAX_STAGES];
|
||||
|
||||
FileName mEnvMapFilename[MAX_STAGES];
|
||||
|
||||
/// This color is the diffuse color of the material
|
||||
/// or if it has a texture it is multiplied against
|
||||
/// the diffuse texture color.
|
||||
ColorF mDiffuse[MAX_STAGES];
|
||||
|
||||
ColorF mSpecular[MAX_STAGES];
|
||||
|
||||
F32 mSpecularPower[MAX_STAGES];
|
||||
bool mPixelSpecular[MAX_STAGES];
|
||||
|
||||
bool mVertLit[MAX_STAGES];
|
||||
|
||||
/// If true for a stage, vertex colors are multiplied
|
||||
/// against diffuse colors.
|
||||
bool mVertColor[ MAX_STAGES ];
|
||||
|
||||
F32 mParallaxScale[MAX_STAGES];
|
||||
|
||||
F32 mMinnaertConstant[MAX_STAGES];
|
||||
bool mSubSurface[MAX_STAGES];
|
||||
ColorF mSubSurfaceColor[MAX_STAGES];
|
||||
F32 mSubSurfaceRolloff[MAX_STAGES];
|
||||
|
||||
/// The repetition scale of the detail texture
|
||||
/// over the base texture.
|
||||
Point2F mDetailScale[MAX_STAGES];
|
||||
|
||||
U32 mAnimFlags[MAX_STAGES];
|
||||
Point2F mScrollDir[MAX_STAGES];
|
||||
F32 mScrollSpeed[MAX_STAGES];
|
||||
Point2F mScrollOffset[MAX_STAGES];
|
||||
|
||||
F32 mRotSpeed[MAX_STAGES];
|
||||
Point2F mRotPivotOffset[MAX_STAGES];
|
||||
F32 mRotPos[MAX_STAGES];
|
||||
|
||||
F32 mWavePos[MAX_STAGES];
|
||||
F32 mWaveFreq[MAX_STAGES];
|
||||
F32 mWaveAmp[MAX_STAGES];
|
||||
U32 mWaveType[MAX_STAGES];
|
||||
|
||||
F32 mSeqFramePerSec[MAX_STAGES];
|
||||
F32 mSeqSegSize[MAX_STAGES];
|
||||
|
||||
bool mGlow[MAX_STAGES]; // entire stage glows
|
||||
bool mEmissive[MAX_STAGES];
|
||||
|
||||
Point2I mCellIndex[MAX_STAGES];
|
||||
Point2I mCellLayout[MAX_STAGES];
|
||||
U32 mCellSize[MAX_STAGES];
|
||||
bool mNormalMapAtlas[MAX_STAGES];
|
||||
|
||||
/// Special array of UVs for imposter rendering.
|
||||
/// @see TSLastDetail
|
||||
Vector<RectF> mImposterUVs;
|
||||
|
||||
/// Specual imposter rendering paramters.
|
||||
/// @see TSLastDetail
|
||||
Point4F mImposterLimits;
|
||||
|
||||
/// If the stage should use anisotropic filtering.
|
||||
bool mUseAnisotropic[MAX_STAGES];
|
||||
|
||||
bool mDoubleSided;
|
||||
|
||||
String mCubemapName;
|
||||
CubemapData* mCubemapData;
|
||||
bool mDynamicCubemap;
|
||||
|
||||
bool mTranslucent;
|
||||
BlendOp mTranslucentBlendOp;
|
||||
bool mTranslucentZWrite;
|
||||
|
||||
/// A generic setting which tells the system to skip
|
||||
/// generation of shadows from this material.
|
||||
bool mCastShadows;
|
||||
|
||||
bool mAlphaTest;
|
||||
U32 mAlphaRef;
|
||||
|
||||
bool mPlanarReflection;
|
||||
|
||||
bool mAutoGenerated;
|
||||
|
||||
static bool sAllowTextureTargetAssignment;
|
||||
|
||||
///@{
|
||||
/// Behavioral properties.
|
||||
|
||||
bool mShowFootprints; ///< If true, show footprints when walking on surface with this material. Defaults to false.
|
||||
bool mShowDust; ///< If true, show dust emitters (footpuffs, hover trails, etc) when on surface with this material. Defaults to false.
|
||||
|
||||
/// Color to use for particle effects and such when located on this material.
|
||||
ColorF mEffectColor[ NUM_EFFECT_COLOR_STAGES ];
|
||||
|
||||
/// Footstep sound to play when walking on surface with this material.
|
||||
/// Numeric ID of footstep sound defined on player datablock (0 == soft,
|
||||
/// 1 == hard, 2 == metal, 3 == snow).
|
||||
/// Defaults to -1 which deactivates default sound.
|
||||
/// @see mFootstepSoundCustom
|
||||
S32 mFootstepSoundId;
|
||||
S32 mImpactSoundId;
|
||||
|
||||
/// Sound effect to play when walking on surface with this material.
|
||||
/// If defined, overrides mFootstepSoundId.
|
||||
/// @see mFootstepSoundId
|
||||
SFXTrack* mFootstepSoundCustom;
|
||||
SFXTrack* mImpactSoundCustom;
|
||||
|
||||
F32 mFriction; ///< Friction coefficient when moving along surface.
|
||||
|
||||
F32 mDirectSoundOcclusion; ///< Amount of volume occlusion on direct sounds.
|
||||
F32 mReverbSoundOcclusion; ///< Amount of volume occlusion on reverb sounds.
|
||||
|
||||
///@}
|
||||
|
||||
String mMapTo; // map Material to this texture name
|
||||
|
||||
///
|
||||
/// Material interface
|
||||
///
|
||||
Material();
|
||||
|
||||
/// Allocates and returns a BaseMatInstance for this material. Caller is responsible
|
||||
/// for freeing the instance
|
||||
virtual BaseMatInstance* createMatInstance();
|
||||
virtual bool isTranslucent() const { return mTranslucent && mTranslucentBlendOp != Material::None; }
|
||||
virtual bool isDoubleSided() const { return mDoubleSided; }
|
||||
virtual bool isAutoGenerated() const { return mAutoGenerated; }
|
||||
virtual void setAutoGenerated(bool isAutoGenerated) { mAutoGenerated = isAutoGenerated; }
|
||||
virtual bool isLightmapped() const;
|
||||
virtual bool castsShadows() const { return mCastShadows; }
|
||||
const String &getPath() const { return mPath; }
|
||||
|
||||
void flush();
|
||||
|
||||
/// Re-initializes all the material instances
|
||||
/// that use this material.
|
||||
void reload();
|
||||
|
||||
/// Called to update time based parameters for a material. Ensures
|
||||
/// that it only happens once per tick.
|
||||
void updateTimeBasedParams();
|
||||
|
||||
// SimObject
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual void inspectPostApply();
|
||||
virtual bool writeField( StringTableEntry fieldname, const char *value );
|
||||
|
||||
//
|
||||
// ConsoleObject interface
|
||||
//
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT(Material);
|
||||
protected:
|
||||
|
||||
// Per material animation parameters
|
||||
U32 mLastUpdateTime;
|
||||
|
||||
String mPath;
|
||||
|
||||
static EnumTable mAnimFlagTable;
|
||||
static EnumTable mBlendOpTable;
|
||||
static EnumTable mWaveTypeTable;
|
||||
|
||||
/// Map this material to the texture specified
|
||||
/// in the "mapTo" data variable.
|
||||
virtual void _mapMaterial();
|
||||
|
||||
private:
|
||||
static GFXCubemapHandle smNormalizeCube;
|
||||
};
|
||||
|
||||
typedef Material::AnimType MaterialAnimType;
|
||||
typedef Material::BlendOp MaterialBlendOp;
|
||||
typedef Material::WaveType MaterialWaveType;
|
||||
|
||||
DefineBitfieldType( MaterialAnimType );
|
||||
DefineEnumType( MaterialBlendOp );
|
||||
DefineEnumType( MaterialWaveType );
|
||||
|
||||
#endif // _MATERIALDEFINITION_H_
|
||||
46
Engine/source/materials/materialFeatureData.cpp
Normal file
46
Engine/source/materials/materialFeatureData.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/materialFeatureData.h"
|
||||
|
||||
|
||||
MaterialFeatureData::MaterialFeatureData()
|
||||
{
|
||||
}
|
||||
|
||||
MaterialFeatureData::MaterialFeatureData( const MaterialFeatureData &data )
|
||||
: features( data.features ),
|
||||
materialFeatures( data.materialFeatures )
|
||||
{
|
||||
}
|
||||
|
||||
MaterialFeatureData::MaterialFeatureData( const FeatureSet &handle )
|
||||
: features( handle )
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialFeatureData::clear()
|
||||
{
|
||||
features.clear();
|
||||
materialFeatures.clear();
|
||||
}
|
||||
75
Engine/source/materials/materialFeatureData.h
Normal file
75
Engine/source/materials/materialFeatureData.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATERIALFEATUREDATA_H_
|
||||
#define _MATERIALFEATUREDATA_H_
|
||||
|
||||
#ifndef _UTIL_DELEGATE_H_
|
||||
#include "core/util/delegate.h"
|
||||
#endif
|
||||
#ifndef _FEATURESET_H_
|
||||
#include "shaderGen/featureSet.h"
|
||||
#endif
|
||||
|
||||
|
||||
class ProcessedMaterial;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MaterialFeatureData, this is basically a series of flags which a material can
|
||||
// ask for. Shader processed materials will use the shadergen system to accomplish this,
|
||||
// FF processed materials will do the best they can.
|
||||
//-----------------------------------------------------------------------------
|
||||
struct MaterialFeatureData
|
||||
{
|
||||
public:
|
||||
|
||||
// General feature data for a pass or for other purposes.
|
||||
FeatureSet features;
|
||||
|
||||
// This is to give hints to shader creation code. It contains
|
||||
// all the features that are in a material stage instead of just
|
||||
// the current pass.
|
||||
FeatureSet materialFeatures;
|
||||
|
||||
public:
|
||||
|
||||
MaterialFeatureData();
|
||||
|
||||
MaterialFeatureData( const MaterialFeatureData &data );
|
||||
|
||||
MaterialFeatureData( const FeatureSet &handle );
|
||||
|
||||
void clear();
|
||||
|
||||
const FeatureSet& codify() const { return features; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
typedef Delegate< void( ProcessedMaterial *mat,
|
||||
U32 stageNum,
|
||||
MaterialFeatureData &fd,
|
||||
const FeatureSet &features) > MatFeaturesDelegate;
|
||||
|
||||
#endif // _MATERIALFEATUREDATA_H_
|
||||
86
Engine/source/materials/materialFeatureTypes.cpp
Normal file
86
Engine/source/materials/materialFeatureTypes.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
|
||||
|
||||
ImplementFeatureType( MFT_UseInstancing, U32(-1), -1, false );
|
||||
|
||||
ImplementFeatureType( MFT_VertTransform, MFG_Transform, 0, true );
|
||||
|
||||
ImplementFeatureType( MFT_TexAnim, MFG_PreTexture, 1.0f, true );
|
||||
ImplementFeatureType( MFT_Parallax, MFG_PreTexture, 2.0f, true );
|
||||
ImplementFeatureType( MFT_DiffuseVertColor, MFG_PreTexture, 3.0f, true );
|
||||
|
||||
ImplementFeatureType( MFT_DiffuseMap, MFG_Texture, 2.0f, true );
|
||||
ImplementFeatureType( MFT_OverlayMap, MFG_Texture, 3.0f, true );
|
||||
ImplementFeatureType( MFT_DetailMap, MFG_Texture, 4.0f, true );
|
||||
ImplementFeatureType( MFT_DiffuseColor, MFG_Texture, 5.0f, true );
|
||||
ImplementFeatureType( MFT_AlphaTest, MFG_Texture, 7.0f, true );
|
||||
ImplementFeatureType( MFT_SpecularMap, MFG_Texture, 8.0f, true );
|
||||
ImplementFeatureType( MFT_NormalMap, MFG_Texture, 9.0f, true );
|
||||
ImplementFeatureType( MFT_DetailNormalMap, MFG_Texture, 10.0f, true );
|
||||
|
||||
ImplementFeatureType( MFT_RTLighting, MFG_Lighting, 2.0f, true );
|
||||
ImplementFeatureType( MFT_SubSurface, MFG_Lighting, 3.0f, true );
|
||||
ImplementFeatureType( MFT_LightMap, MFG_Lighting, 4.0f, true );
|
||||
ImplementFeatureType( MFT_ToneMap, MFG_Lighting, 5.0f, true );
|
||||
ImplementFeatureType( MFT_VertLitTone, MFG_Lighting, 6.0f, false );
|
||||
ImplementFeatureType( MFT_VertLit, MFG_Lighting, 7.0f, true );
|
||||
ImplementFeatureType( MFT_EnvMap, MFG_Lighting, 8.0f, true );
|
||||
ImplementFeatureType( MFT_CubeMap, MFG_Lighting, 9.0f, true );
|
||||
ImplementFeatureType( MFT_PixSpecular, MFG_Lighting, 10.0f, true );
|
||||
ImplementFeatureType( MFT_MinnaertShading, MFG_Lighting, 12.0f, true );
|
||||
|
||||
ImplementFeatureType( MFT_GlowMask, MFG_PostLighting, 1.0f, true );
|
||||
ImplementFeatureType( MFT_Visibility, MFG_PostLighting, 2.0f, true );
|
||||
ImplementFeatureType( MFT_Fog, MFG_PostProcess, 3.0f, true );
|
||||
|
||||
ImplementFeatureType( MFT_HDROut, MFG_PostProcess, 999.0f, true );
|
||||
|
||||
ImplementFeatureType( MFT_IsDXTnm, U32(-1), -1, true );
|
||||
ImplementFeatureType( MFT_IsTranslucent, U32(-1), -1, true );
|
||||
ImplementFeatureType( MFT_IsTranslucentZWrite, U32(-1), -1, true );
|
||||
ImplementFeatureType( MFT_IsEmissive, U32(-1), -1, true );
|
||||
ImplementFeatureType( MFT_GlossMap, U32(-1), -1, true );
|
||||
ImplementFeatureType( MFT_DiffuseMapAtlas, U32(-1), -1, true );
|
||||
ImplementFeatureType( MFT_NormalMapAtlas, U32(-1), -1, true );
|
||||
ImplementFeatureType( MFT_InterlacedPrePass, U32(-1), -1, true );
|
||||
|
||||
ImplementFeatureType( MFT_ParaboloidVertTransform, MFG_Transform, -1, false );
|
||||
ImplementFeatureType( MFT_IsSinglePassParaboloid, U32(-1), -1, false );
|
||||
ImplementFeatureType( MFT_EyeSpaceDepthOut, MFG_PostLighting, 2.0f, false );
|
||||
ImplementFeatureType( MFT_DepthOut, MFG_PostLighting, 3.0f, false );
|
||||
ImplementFeatureType( MFT_PrePassConditioner, MFG_PostProcess, 1.0f, false );
|
||||
ImplementFeatureType( MFT_NormalsOut, MFG_PreLighting, 1.0f, false );
|
||||
|
||||
ImplementFeatureType( MFT_LightbufferMRT, MFG_PreLighting, 1.0f, false );
|
||||
ImplementFeatureType( MFT_RenderTarget1_Zero, MFG_PreTexture, 1.0f, false );
|
||||
|
||||
ImplementFeatureType( MFT_Foliage, MFG_PreTransform, 1.0f, false );
|
||||
|
||||
ImplementFeatureType( MFT_ParticleNormal, MFG_PreTransform, 2.0f, false );
|
||||
|
||||
ImplementFeatureType( MFT_ForwardShading, U32(-1), -1, true );
|
||||
|
||||
ImplementFeatureType( MFT_ImposterVert, MFG_PreTransform, 1.0, false );
|
||||
174
Engine/source/materials/materialFeatureTypes.h
Normal file
174
Engine/source/materials/materialFeatureTypes.h
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATERIALFEATURETYPES_H_
|
||||
#define _MATERIALFEATURETYPES_H_
|
||||
|
||||
#ifndef _FEATURETYPE_H_
|
||||
#include "shaderGen/featureType.h"
|
||||
#endif
|
||||
|
||||
|
||||
///
|
||||
enum MaterialFeatureGroup
|
||||
{
|
||||
/// One or more pre-transform features are
|
||||
/// allowed at any one time and are executed
|
||||
/// in order to each other.
|
||||
MFG_PreTransform,
|
||||
|
||||
/// Only one transform feature is allowed at
|
||||
/// any one time.
|
||||
MFG_Transform,
|
||||
|
||||
///
|
||||
MFG_PostTransform,
|
||||
|
||||
/// The features that need to occur before texturing
|
||||
/// takes place. Usually these are features that will
|
||||
/// manipulate or generate texture coords.
|
||||
MFG_PreTexture,
|
||||
|
||||
/// The different diffuse color features including
|
||||
/// textures and colors.
|
||||
MFG_Texture,
|
||||
|
||||
///
|
||||
MFG_PreLighting,
|
||||
|
||||
///
|
||||
MFG_Lighting,
|
||||
|
||||
///
|
||||
MFG_PostLighting,
|
||||
|
||||
/// Final features like fogging.
|
||||
MFG_PostProcess,
|
||||
|
||||
/// Miscellaneous features that require no specialized
|
||||
/// ShaderFeature object and are just queried as flags.
|
||||
MFG_Misc = -1,
|
||||
};
|
||||
|
||||
/// If defined then this shader should use hardware mesh instancing.
|
||||
DeclareFeatureType( MFT_UseInstancing );
|
||||
|
||||
/// The standard vertex transform.
|
||||
DeclareFeatureType( MFT_VertTransform );
|
||||
|
||||
/// A special transform with paraboloid warp used
|
||||
/// in shadow and reflection rendering.
|
||||
DeclareFeatureType( MFT_ParaboloidVertTransform );
|
||||
|
||||
/// This feature is queried from the MFT_ParaboloidVertTransform
|
||||
/// feature to detect if it needs to generate a single pass.
|
||||
DeclareFeatureType( MFT_IsSinglePassParaboloid );
|
||||
|
||||
/// This feature does normal map decompression for DXT1/5.
|
||||
DeclareFeatureType( MFT_IsDXTnm );
|
||||
|
||||
DeclareFeatureType( MFT_TexAnim );
|
||||
DeclareFeatureType( MFT_Parallax );
|
||||
|
||||
DeclareFeatureType( MFT_DiffuseMap );
|
||||
DeclareFeatureType( MFT_OverlayMap );
|
||||
DeclareFeatureType( MFT_DetailMap );
|
||||
DeclareFeatureType( MFT_DiffuseColor );
|
||||
DeclareFeatureType( MFT_DetailNormalMap );
|
||||
|
||||
/// This feature enables vertex coloring for the diffuse channel.
|
||||
DeclareFeatureType( MFT_DiffuseVertColor );
|
||||
|
||||
/// This feature is used to do alpha test clipping in
|
||||
/// the shader which can be faster on SM3 and is needed
|
||||
/// when the render state alpha test is not available.
|
||||
DeclareFeatureType( MFT_AlphaTest );
|
||||
|
||||
DeclareFeatureType( MFT_NormalMap );
|
||||
DeclareFeatureType( MFT_RTLighting );
|
||||
|
||||
DeclareFeatureType( MFT_IsEmissive );
|
||||
DeclareFeatureType( MFT_SubSurface );
|
||||
DeclareFeatureType( MFT_LightMap );
|
||||
DeclareFeatureType( MFT_ToneMap );
|
||||
DeclareFeatureType( MFT_VertLit );
|
||||
DeclareFeatureType( MFT_VertLitTone );
|
||||
|
||||
DeclareFeatureType( MFT_EnvMap );
|
||||
DeclareFeatureType( MFT_CubeMap );
|
||||
DeclareFeatureType( MFT_PixSpecular );
|
||||
DeclareFeatureType( MFT_SpecularMap );
|
||||
DeclareFeatureType( MFT_GlossMap );
|
||||
|
||||
/// This feature is only used to detect alpha transparency
|
||||
/// and does not have any code associtated with it.
|
||||
DeclareFeatureType( MFT_IsTranslucent );
|
||||
|
||||
///
|
||||
DeclareFeatureType( MFT_IsTranslucentZWrite );
|
||||
|
||||
/// This feature causes MFT_NormalMap to set the world
|
||||
/// space normal vector to the output color rgb.
|
||||
DeclareFeatureType( MFT_NormalsOut );
|
||||
|
||||
DeclareFeatureType( MFT_MinnaertShading );
|
||||
DeclareFeatureType( MFT_GlowMask );
|
||||
DeclareFeatureType( MFT_Visibility );
|
||||
DeclareFeatureType( MFT_EyeSpaceDepthOut );
|
||||
DeclareFeatureType( MFT_DepthOut );
|
||||
DeclareFeatureType( MFT_Fog );
|
||||
|
||||
/// This should be the last feature of any material that
|
||||
/// renders to a HDR render target. It converts the high
|
||||
/// dynamic range color into the correct HDR encoded format.
|
||||
DeclareFeatureType( MFT_HDROut );
|
||||
|
||||
///
|
||||
DeclareFeatureType( MFT_PrePassConditioner );
|
||||
DeclareFeatureType( MFT_InterlacedPrePass );
|
||||
|
||||
/// This feature causes MFT_ToneMap and MFT_LightMap to output their light color
|
||||
/// to the second render-target
|
||||
DeclareFeatureType( MFT_LightbufferMRT );
|
||||
|
||||
/// This feature outputs black to RenderTarget1
|
||||
DeclareFeatureType( MFT_RenderTarget1_Zero );
|
||||
|
||||
DeclareFeatureType( MFT_Foliage );
|
||||
|
||||
// Texture atlasing features
|
||||
DeclareFeatureType( MFT_DiffuseMapAtlas );
|
||||
DeclareFeatureType( MFT_NormalMapAtlas );
|
||||
|
||||
// Particle features
|
||||
DeclareFeatureType( MFT_ParticleNormal );
|
||||
|
||||
/// This feature is used to indicate that the material should use forward shading
|
||||
/// instead of deferred shading (if applicable)
|
||||
DeclareFeatureType( MFT_ForwardShading );
|
||||
|
||||
/// A special vertex feature which unpacks the imposter vertex
|
||||
/// so that the rest of the material features can work on it.
|
||||
DeclareFeatureType( MFT_ImposterVert );
|
||||
|
||||
|
||||
#endif // _MATERIALFEATURETYPES_H_
|
||||
412
Engine/source/materials/materialList.cpp
Normal file
412
Engine/source/materials/materialList.cpp
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/materialList.h"
|
||||
|
||||
#include "materials/matInstance.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
#include "materials/processedMaterial.h"
|
||||
#include "core/volume.h"
|
||||
#include "console/simSet.h"
|
||||
|
||||
|
||||
MaterialList::MaterialList()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION(mMatInstList);
|
||||
VECTOR_SET_ASSOCIATION(mMaterialNames);
|
||||
}
|
||||
|
||||
MaterialList::MaterialList(const MaterialList* pCopy)
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION(mMatInstList);
|
||||
VECTOR_SET_ASSOCIATION(mMaterialNames);
|
||||
|
||||
mMaterialNames.setSize(pCopy->mMaterialNames.size());
|
||||
S32 i;
|
||||
for (i = 0; i < mMaterialNames.size(); i++)
|
||||
{
|
||||
mMaterialNames[i] = pCopy->mMaterialNames[i];
|
||||
}
|
||||
|
||||
clearMatInstList();
|
||||
mMatInstList.setSize(pCopy->size());
|
||||
for( i = 0; i < mMatInstList.size(); i++ )
|
||||
{
|
||||
if( i < pCopy->mMatInstList.size() && pCopy->mMatInstList[i] )
|
||||
{
|
||||
mMatInstList[i] = pCopy->mMatInstList[i]->getMaterial()->createMatInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
mMatInstList[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
MaterialList::MaterialList(U32 materialCount, const char **materialNames)
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION(mMaterialNames);
|
||||
|
||||
set(materialCount, materialNames);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
void MaterialList::set(U32 materialCount, const char **materialNames)
|
||||
{
|
||||
free();
|
||||
mMaterialNames.setSize(materialCount);
|
||||
clearMatInstList();
|
||||
mMatInstList.setSize(materialCount);
|
||||
for(U32 i = 0; i < materialCount; i++)
|
||||
{
|
||||
mMaterialNames[i] = materialNames[i];
|
||||
mMatInstList[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
MaterialList::~MaterialList()
|
||||
{
|
||||
free();
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
void MaterialList::setMaterialName(U32 index, const String& name)
|
||||
{
|
||||
if (index < mMaterialNames.size())
|
||||
mMaterialNames[index] = name;
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
GFXTextureObject *MaterialList::getDiffuseTexture(U32 index)
|
||||
{
|
||||
AssertFatal(index < (U32) mMatInstList.size(), "MaterialList::getDiffuseTex: index lookup out of range.");
|
||||
|
||||
MatInstance *matInst = dynamic_cast<MatInstance*>(mMatInstList[index]);
|
||||
if (matInst && matInst->getProcessedMaterial())
|
||||
return matInst->getProcessedMaterial()->getStageTexture(0, MFT_DiffuseMap);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
void MaterialList::free()
|
||||
{
|
||||
clearMatInstList();
|
||||
mMatInstList.clear();
|
||||
mMaterialNames.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
//--------------------------------------
|
||||
U32 MaterialList::push_back(GFXTexHandle textureHandle, const String &filename)
|
||||
{
|
||||
mMaterialNames.push_back(filename);
|
||||
mMatInstList.push_back(NULL);
|
||||
|
||||
// return the index
|
||||
return mMaterialNames.size()-1;
|
||||
}
|
||||
*/
|
||||
|
||||
//--------------------------------------
|
||||
U32 MaterialList::push_back(const String &filename, Material* material)
|
||||
{
|
||||
mMaterialNames.push_back(filename);
|
||||
mMatInstList.push_back(material ? material->createMatInstance() : NULL);
|
||||
|
||||
// return the index
|
||||
return mMaterialNames.size()-1;
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
bool MaterialList::read(Stream &stream)
|
||||
{
|
||||
free();
|
||||
|
||||
// check the stream version
|
||||
U8 version;
|
||||
if ( stream.read(&version) && version != BINARY_FILE_VERSION)
|
||||
return readText(stream,version);
|
||||
|
||||
// how many materials?
|
||||
U32 count;
|
||||
if ( !stream.read(&count) )
|
||||
return false;
|
||||
|
||||
// pre-size the vectors for efficiency
|
||||
mMaterialNames.reserve(count);
|
||||
|
||||
// read in the materials
|
||||
for (U32 i=0; i<count; i++)
|
||||
{
|
||||
// Load the bitmap name
|
||||
char buffer[256];
|
||||
stream.readString(buffer);
|
||||
if( !buffer[0] )
|
||||
{
|
||||
AssertWarn(0, "MaterialList::read: error reading stream");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Material paths are a legacy of Tribes tools,
|
||||
// strip them off...
|
||||
char *name = &buffer[dStrlen(buffer)];
|
||||
while (name != buffer && name[-1] != '/' && name[-1] != '\\')
|
||||
name--;
|
||||
|
||||
// Add it to the list
|
||||
mMaterialNames.push_back(name);
|
||||
mMatInstList.push_back(NULL);
|
||||
}
|
||||
|
||||
return (stream.getStatus() == Stream::Ok);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
bool MaterialList::write(Stream &stream)
|
||||
{
|
||||
stream.write((U8)BINARY_FILE_VERSION); // version
|
||||
stream.write((U32)mMaterialNames.size()); // material count
|
||||
|
||||
for(S32 i=0; i < mMaterialNames.size(); i++) // material names
|
||||
stream.writeString(mMaterialNames[i]);
|
||||
|
||||
return (stream.getStatus() == Stream::Ok);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
bool MaterialList::readText(Stream &stream, U8 firstByte)
|
||||
{
|
||||
free();
|
||||
|
||||
if (!firstByte)
|
||||
return (stream.getStatus() == Stream::Ok || stream.getStatus() == Stream::EOS);
|
||||
|
||||
char buf[1024];
|
||||
buf[0] = firstByte;
|
||||
U32 offset = 1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
stream.readLine((U8*)(buf+offset), sizeof(buf)-offset);
|
||||
if(!buf[0])
|
||||
break;
|
||||
offset = 0;
|
||||
|
||||
// Material paths are a legacy of Tribes tools,
|
||||
// strip them off...
|
||||
char *name = &buf[dStrlen(buf)];
|
||||
while (name != buf && name[-1] != '/' && name[-1] != '\\')
|
||||
name--;
|
||||
|
||||
// Add it to the list
|
||||
mMaterialNames.push_back(name);
|
||||
mMatInstList.push_back(NULL);
|
||||
}
|
||||
|
||||
return (stream.getStatus() == Stream::Ok || stream.getStatus() == Stream::EOS);
|
||||
}
|
||||
|
||||
bool MaterialList::readText(Stream &stream)
|
||||
{
|
||||
U8 firstByte;
|
||||
stream.read(&firstByte);
|
||||
return readText(stream,firstByte);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
bool MaterialList::writeText(Stream &stream)
|
||||
{
|
||||
for(S32 i=0; i < mMaterialNames.size(); i++)
|
||||
stream.writeLine((U8*)(mMaterialNames[i].c_str()));
|
||||
stream.writeLine((U8*)"");
|
||||
|
||||
return (stream.getStatus() == Stream::Ok);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Clear all materials in the mMatInstList member variable
|
||||
//--------------------------------------------------------------------------
|
||||
void MaterialList::clearMatInstList()
|
||||
{
|
||||
// clear out old materials. any non null element of the list should be pointing at deletable memory,
|
||||
// although multiple indexes may be pointing at the same memory so we have to be careful (see
|
||||
// comment in loop body)
|
||||
for (U32 i=0; i<mMatInstList.size(); i++)
|
||||
{
|
||||
if (mMatInstList[i])
|
||||
{
|
||||
BaseMatInstance* current = mMatInstList[i];
|
||||
delete current;
|
||||
mMatInstList[i] = NULL;
|
||||
|
||||
// ok, since ts material lists can remap difference indexes to the same object
|
||||
// we need to make sure that we don't delete the same memory twice. walk the
|
||||
// rest of the list and null out any pointers that match the one we deleted.
|
||||
for (U32 j=0; j<mMatInstList.size(); j++)
|
||||
if (mMatInstList[j] == current)
|
||||
mMatInstList[j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Map materials - map materials to the textures in the list
|
||||
//--------------------------------------------------------------------------
|
||||
void MaterialList::mapMaterials()
|
||||
{
|
||||
mMatInstList.setSize( mMaterialNames.size() );
|
||||
|
||||
for( U32 i=0; i<mMaterialNames.size(); i++ )
|
||||
mapMaterial( i );
|
||||
}
|
||||
|
||||
/// Map the material name at the given index to a material instance.
|
||||
///
|
||||
/// @note The material instance that is created will <em>not be initialized.</em>
|
||||
|
||||
void MaterialList::mapMaterial( U32 i )
|
||||
{
|
||||
AssertFatal( i < size(), "MaterialList::mapMaterialList - index out of bounds" );
|
||||
|
||||
if( mMatInstList[i] != NULL )
|
||||
return;
|
||||
|
||||
// lookup a material property entry
|
||||
const String &matName = getMaterialName(i);
|
||||
|
||||
// JMQ: this code assumes that all materials have names.
|
||||
if( matName.isEmpty() )
|
||||
{
|
||||
mMatInstList[i] = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
String materialName = MATMGR->getMapEntry(matName);
|
||||
|
||||
// IF we didn't find it, then look for a PolyStatic generated Material
|
||||
// [a little cheesy, but we need to allow for user override of generated Materials]
|
||||
if ( materialName.isEmpty() )
|
||||
materialName = MATMGR->getMapEntry( String::ToString( "polyMat_%s", matName.c_str() ) );
|
||||
|
||||
if ( materialName.isNotEmpty() )
|
||||
{
|
||||
Material * mat = MATMGR->getMaterialDefinitionByName( materialName );
|
||||
mMatInstList[i] = mat ? mat->createMatInstance() : MATMGR->createWarningMatInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Con::getBoolVariable( "$Materials::createMissing", true ) )
|
||||
{
|
||||
// No Material found, create new "default" material with just a diffuseMap
|
||||
|
||||
// First see if there is a valid diffuse texture
|
||||
GFXTexHandle texHandle;
|
||||
if (mLookupPath.isEmpty())
|
||||
{
|
||||
texHandle.set( mMaterialNames[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - handle (line %d)", __FUNCTION__, __LINE__) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Should we strip off the extension of the path here before trying
|
||||
// to load the texture?
|
||||
String fullPath = String::ToString( "%s/%s", mLookupPath.c_str(), mMaterialNames[i].c_str() );
|
||||
texHandle.set( fullPath, &GFXDefaultStaticDiffuseProfile, avar("%s() - handle (line %d)", __FUNCTION__, __LINE__) );
|
||||
}
|
||||
|
||||
if ( texHandle.isValid() )
|
||||
{
|
||||
String newMatName = Sim::getUniqueName( "DefaultMaterial" );
|
||||
Material *newMat = MATMGR->allocateAndRegister( newMatName, mMaterialNames[i] );
|
||||
|
||||
// Flag this as an autogenerated Material
|
||||
newMat->mAutoGenerated = true;
|
||||
|
||||
// Overwrite diffuseMap in new material
|
||||
newMat->mDiffuseMapFilename[0] = texHandle->mTextureLookupName;
|
||||
|
||||
// Set up some defaults for transparent textures
|
||||
if (texHandle->mHasTransparency)
|
||||
{
|
||||
newMat->mTranslucent = true;
|
||||
newMat->mTranslucentBlendOp = Material::LerpAlpha;
|
||||
newMat->mTranslucentZWrite = true;
|
||||
newMat->mAlphaRef = 20;
|
||||
}
|
||||
|
||||
// create a MatInstance for the new material
|
||||
mMatInstList[i] = newMat->createMatInstance();
|
||||
|
||||
#ifndef TORQUE_SHIPPING
|
||||
Con::warnf( "[MaterialList::mapMaterials] Creating missing material for texture: %s", texHandle->mTextureLookupName.c_str() );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::errorf( "[MaterialList::mapMaterials] Unable to find material for texture: %s", mMaterialNames[i].c_str() );
|
||||
mMatInstList[i] = MATMGR->createWarningMatInstance();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mMatInstList[i] = MATMGR->createWarningMatInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialList::initMatInstances( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat )
|
||||
{
|
||||
for( U32 i=0; i < mMatInstList.size(); i++ )
|
||||
{
|
||||
BaseMatInstance *matInst = mMatInstList[i];
|
||||
if ( !matInst )
|
||||
continue;
|
||||
|
||||
if ( !matInst->init( features, vertexFormat ) )
|
||||
{
|
||||
Con::errorf( "MaterialList::initMatInstances - failed to initialize material instance for '%s'",
|
||||
matInst->getMaterial()->getName() );
|
||||
|
||||
// Fall back to warning material.
|
||||
|
||||
SAFE_DELETE( matInst );
|
||||
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
||||
matInst->init( MATMGR->getDefaultFeatures(), vertexFormat );
|
||||
mMatInstList[ i ] = matInst;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MaterialList::setMaterialInst( BaseMatInstance *matInst, U32 texIndex )
|
||||
{
|
||||
AssertFatal( texIndex < mMatInstList.size(), "MaterialList::setMaterialInst - index out of bounds" );
|
||||
mMatInstList[texIndex] = matInst;
|
||||
}
|
||||
106
Engine/source/materials/materialList.h
Normal file
106
Engine/source/materials/materialList.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATERIALLIST_H_
|
||||
#define _MATERIALLIST_H_
|
||||
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef _GFXTEXTUREHANDLE_H_
|
||||
#include "gfx/gfxTextureHandle.h"
|
||||
#endif
|
||||
|
||||
|
||||
class Material;
|
||||
class BaseMatInstance;
|
||||
class Stream;
|
||||
class GFXVertexFormat;
|
||||
class FeatureSet;
|
||||
|
||||
|
||||
class MaterialList
|
||||
{
|
||||
public:
|
||||
MaterialList();
|
||||
MaterialList(U32 materialCount, const char **materialNames);
|
||||
virtual ~MaterialList();
|
||||
|
||||
/// Note: this is not to be confused with MaterialList(const MaterialList&). Copying
|
||||
/// a material list in the middle of it's lifetime is not a good thing, so we force
|
||||
/// it to copy at construction time by restricting the copy syntax to
|
||||
/// ML* pML = new ML(©);
|
||||
explicit MaterialList(const MaterialList*);
|
||||
|
||||
const Vector<String> &getMaterialNameList() const { return mMaterialNames; }
|
||||
const String &getMaterialName(U32 index) const { return mMaterialNames[index]; }
|
||||
GFXTextureObject *getDiffuseTexture(U32 index);
|
||||
|
||||
void setTextureLookupPath(const String& path) { mLookupPath = path; }
|
||||
void setMaterialName(U32 index, const String& name);
|
||||
|
||||
void set(U32 materialCount, const char **materialNames);
|
||||
U32 push_back(const String &filename, Material* = 0);
|
||||
|
||||
virtual void free();
|
||||
void clearMatInstList();
|
||||
|
||||
bool empty() const { return mMaterialNames.empty(); }
|
||||
U32 size() const { return (U32)mMaterialNames.size(); }
|
||||
|
||||
bool read(Stream &stream);
|
||||
bool write(Stream &stream);
|
||||
|
||||
bool readText(Stream &stream, U8 firstByte);
|
||||
bool readText(Stream &stream);
|
||||
bool writeText(Stream &stream);
|
||||
|
||||
void mapMaterials();
|
||||
|
||||
/// Initialize material instances in material list.
|
||||
void initMatInstances( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat );
|
||||
|
||||
/// Return the material instance or NULL if the
|
||||
/// index is out of bounds.
|
||||
inline BaseMatInstance* getMaterialInst( U32 index ) const
|
||||
{
|
||||
return index < mMatInstList.size() ? mMatInstList[index] : NULL;
|
||||
}
|
||||
|
||||
void setMaterialInst( BaseMatInstance *matInst, U32 index );
|
||||
|
||||
// Needs to be accessible if were going to freely edit instances
|
||||
Vector<BaseMatInstance*> mMatInstList;
|
||||
|
||||
protected:
|
||||
|
||||
String mLookupPath;
|
||||
Vector<String> mMaterialNames; //!< Material 'mapTo' targets
|
||||
|
||||
virtual void mapMaterial( U32 index );
|
||||
|
||||
private:
|
||||
enum Constants { BINARY_FILE_VERSION = 1 };
|
||||
};
|
||||
|
||||
#endif // _MATERIALLIST_H_
|
||||
491
Engine/source/materials/materialManager.cpp
Normal file
491
Engine/source/materials/materialManager.cpp
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/materialManager.h"
|
||||
|
||||
#include "materials/matInstance.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
#include "lighting/lightManager.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "shaderGen/shaderGen.h"
|
||||
#include "core/module.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
|
||||
MODULE_BEGIN( MaterialManager )
|
||||
|
||||
MODULE_INIT_BEFORE( GFX )
|
||||
MODULE_SHUTDOWN_BEFORE( GFX )
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
MaterialManager::createSingleton();
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
MaterialManager::deleteSingleton();
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
|
||||
MaterialManager::MaterialManager()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mMatInstanceList );
|
||||
|
||||
mDt = 0.0f;
|
||||
mAccumTime = 0.0f;
|
||||
mLastTime = 0;
|
||||
mWarningInst = NULL;
|
||||
|
||||
GFXDevice::getDeviceEventSignal().notify( this, &MaterialManager::_handleGFXEvent );
|
||||
|
||||
// Make sure we get activation signals
|
||||
// and that we're the last to get them.
|
||||
LightManager::smActivateSignal.notify( this, &MaterialManager::_onLMActivate, 9999 );
|
||||
|
||||
mMaterialSet = NULL;
|
||||
|
||||
mUsingPrePass = false;
|
||||
|
||||
mFlushAndReInit = false;
|
||||
|
||||
mDefaultAnisotropy = 1;
|
||||
Con::addVariable( "$pref::Video::defaultAnisotropy", TypeS32, &mDefaultAnisotropy,
|
||||
"@brief Global variable defining the default anisotropy value.\n\n"
|
||||
"Controls the default anisotropic texture filtering level for all materials, including the terrain. "
|
||||
"This value can be changed at runtime to see its affect without reloading.\n\n "
|
||||
"@ingroup Materials");
|
||||
Con::NotifyDelegate callabck( this, &MaterialManager::_updateDefaultAnisotropy );
|
||||
Con::addVariableNotify( "$pref::Video::defaultAnisotropy", callabck );
|
||||
|
||||
Con::NotifyDelegate callabck2( this, &MaterialManager::_onDisableMaterialFeature );
|
||||
Con::setVariable( "$pref::Video::disableNormalMapping", false );
|
||||
Con::addVariableNotify( "$pref::Video::disableNormalMapping", callabck2 );
|
||||
Con::setVariable( "$pref::Video::disablePixSpecular", false );
|
||||
Con::addVariableNotify( "$pref::Video::disablePixSpecular", callabck2 );
|
||||
Con::setVariable( "$pref::Video::disableCubemapping", false );
|
||||
Con::addVariableNotify( "$pref::Video::disableCubemapping", callabck2 );
|
||||
Con::setVariable( "$pref::Video::disableParallaxMapping", false );
|
||||
Con::addVariableNotify( "$pref::Video::disableParallaxMapping", callabck2 );
|
||||
}
|
||||
|
||||
MaterialManager::~MaterialManager()
|
||||
{
|
||||
GFXDevice::getDeviceEventSignal().remove( this, &MaterialManager::_handleGFXEvent );
|
||||
LightManager::smActivateSignal.remove( this, &MaterialManager::_onLMActivate );
|
||||
|
||||
SAFE_DELETE( mWarningInst );
|
||||
|
||||
#ifndef TORQUE_SHIPPING
|
||||
DebugMaterialMap::Iterator itr = mMeshDebugMaterialInsts.begin();
|
||||
|
||||
for ( ; itr != mMeshDebugMaterialInsts.end(); itr++ )
|
||||
delete itr->value;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MaterialManager::_onLMActivate( const char *lm, bool activate )
|
||||
{
|
||||
if ( !activate )
|
||||
return;
|
||||
|
||||
// Since the light manager usually swaps shadergen features
|
||||
// and changes system wide shader defines we need to completely
|
||||
// flush and rebuild all the material instances.
|
||||
|
||||
mFlushAndReInit = true;
|
||||
}
|
||||
|
||||
void MaterialManager::_updateDefaultAnisotropy()
|
||||
{
|
||||
// Update all the materials.
|
||||
Vector<BaseMatInstance*>::iterator iter = mMatInstanceList.begin();
|
||||
for ( ; iter != mMatInstanceList.end(); iter++ )
|
||||
(*iter)->updateStateBlocks();
|
||||
}
|
||||
|
||||
Material * MaterialManager::allocateAndRegister(const String &objectName, const String &mapToName)
|
||||
{
|
||||
Material *newMat = new Material();
|
||||
|
||||
if ( mapToName.isNotEmpty() )
|
||||
newMat->mMapTo = mapToName;
|
||||
|
||||
bool registered = newMat->registerObject(objectName );
|
||||
AssertFatal( registered, "Unable to register material" );
|
||||
|
||||
if (registered)
|
||||
Sim::getRootGroup()->addObject( newMat );
|
||||
else
|
||||
{
|
||||
delete newMat;
|
||||
newMat = NULL;
|
||||
}
|
||||
|
||||
return newMat;
|
||||
}
|
||||
|
||||
Material * MaterialManager::getMaterialDefinitionByName(const String &matName)
|
||||
{
|
||||
// Get the material
|
||||
Material * foundMat;
|
||||
|
||||
if(!Sim::findObject(matName, foundMat))
|
||||
{
|
||||
Con::errorf("MaterialManager: Unable to find material '%s'", matName.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return foundMat;
|
||||
}
|
||||
|
||||
BaseMatInstance* MaterialManager::createMatInstance(const String &matName)
|
||||
{
|
||||
BaseMaterialDefinition* mat = NULL;
|
||||
if (Sim::findObject(matName, mat))
|
||||
return mat->createMatInstance();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BaseMatInstance* MaterialManager::createMatInstance( const String &matName,
|
||||
const GFXVertexFormat *vertexFormat )
|
||||
{
|
||||
return createMatInstance( matName, getDefaultFeatures(), vertexFormat );
|
||||
}
|
||||
|
||||
BaseMatInstance* MaterialManager::createMatInstance( const String &matName,
|
||||
const FeatureSet& features,
|
||||
const GFXVertexFormat *vertexFormat )
|
||||
{
|
||||
BaseMatInstance* mat = createMatInstance(matName);
|
||||
if (mat)
|
||||
{
|
||||
mat->init( features, vertexFormat );
|
||||
return mat;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BaseMatInstance * MaterialManager::createWarningMatInstance()
|
||||
{
|
||||
Material *warnMat = static_cast<Material*>(Sim::findObject("WarningMaterial"));
|
||||
|
||||
BaseMatInstance *warnMatInstance = NULL;
|
||||
|
||||
if( warnMat != NULL )
|
||||
{
|
||||
warnMatInstance = warnMat->createMatInstance();
|
||||
|
||||
GFXStateBlockDesc desc;
|
||||
desc.setCullMode(GFXCullNone);
|
||||
warnMatInstance->addStateBlockDesc(desc);
|
||||
|
||||
warnMatInstance->init( getDefaultFeatures(),
|
||||
getGFXVertexFormat<GFXVertexPNTTB>() );
|
||||
}
|
||||
|
||||
return warnMatInstance;
|
||||
}
|
||||
|
||||
// Gets the global warning material instance, callers should not free this copy
|
||||
BaseMatInstance * MaterialManager::getWarningMatInstance()
|
||||
{
|
||||
if (!mWarningInst)
|
||||
mWarningInst = createWarningMatInstance();
|
||||
|
||||
return mWarningInst;
|
||||
}
|
||||
|
||||
#ifndef TORQUE_SHIPPING
|
||||
BaseMatInstance * MaterialManager::createMeshDebugMatInstance(const ColorF &meshColor)
|
||||
{
|
||||
String meshDebugStr = String::ToString( "Torque_MeshDebug_%d", meshColor.getRGBAPack() );
|
||||
|
||||
Material *debugMat;
|
||||
if (!Sim::findObject(meshDebugStr,debugMat))
|
||||
{
|
||||
debugMat = allocateAndRegister( meshDebugStr );
|
||||
|
||||
debugMat->mDiffuse[0] = meshColor;
|
||||
debugMat->mEmissive[0] = true;
|
||||
}
|
||||
|
||||
BaseMatInstance *debugMatInstance = NULL;
|
||||
|
||||
if( debugMat != NULL )
|
||||
{
|
||||
debugMatInstance = debugMat->createMatInstance();
|
||||
|
||||
GFXStateBlockDesc desc;
|
||||
desc.setCullMode(GFXCullNone);
|
||||
desc.fillMode = GFXFillWireframe;
|
||||
debugMatInstance->addStateBlockDesc(desc);
|
||||
|
||||
// Disable fog and other stuff.
|
||||
FeatureSet debugFeatures;
|
||||
debugFeatures.addFeature( MFT_DiffuseColor );
|
||||
debugMatInstance->init( debugFeatures, getGFXVertexFormat<GFXVertexPCN>() );
|
||||
}
|
||||
|
||||
return debugMatInstance;
|
||||
}
|
||||
|
||||
// Gets the global material instance for a given color, callers should not free this copy
|
||||
BaseMatInstance *MaterialManager::getMeshDebugMatInstance(const ColorF &meshColor)
|
||||
{
|
||||
DebugMaterialMap::Iterator itr = mMeshDebugMaterialInsts.find( meshColor.getRGBAPack() );
|
||||
|
||||
BaseMatInstance *inst = NULL;
|
||||
|
||||
if ( itr == mMeshDebugMaterialInsts.end() )
|
||||
inst = createMeshDebugMatInstance( meshColor );
|
||||
else
|
||||
inst = itr->value;
|
||||
|
||||
mMeshDebugMaterialInsts.insert( meshColor.getRGBAPack(), inst );
|
||||
|
||||
return inst;
|
||||
}
|
||||
#endif
|
||||
|
||||
void MaterialManager::mapMaterial(const String & textureName, const String & materialName)
|
||||
{
|
||||
if (getMapEntry(textureName).isNotEmpty())
|
||||
{
|
||||
if (!textureName.equal("unmapped_mat", String::NoCase))
|
||||
Con::warnf(ConsoleLogEntry::General, "Warning, overwriting material for: %s", textureName.c_str());
|
||||
}
|
||||
|
||||
mMaterialMap[String::ToLower(textureName)] = materialName;
|
||||
}
|
||||
|
||||
String MaterialManager::getMapEntry(const String & textureName) const
|
||||
{
|
||||
MaterialMap::ConstIterator iter = mMaterialMap.find(String::ToLower(textureName));
|
||||
if ( iter == mMaterialMap.end() )
|
||||
return String();
|
||||
return iter->value;
|
||||
}
|
||||
|
||||
void MaterialManager::flushAndReInitInstances()
|
||||
{
|
||||
// Clear the flag if its set.
|
||||
mFlushAndReInit = false;
|
||||
|
||||
// Check to see if any shader preferences have changed.
|
||||
recalcFeaturesFromPrefs();
|
||||
|
||||
// First we flush all the shader gen shaders which will
|
||||
// invalidate all GFXShader* to them.
|
||||
SHADERGEN->flushProceduralShaders();
|
||||
mFlushSignal.trigger();
|
||||
|
||||
// First do a pass deleting all hooks as they can contain
|
||||
// materials themselves. This means we have to restart the
|
||||
// loop every time we delete any hooks... lame.
|
||||
Vector<BaseMatInstance*>::iterator iter = mMatInstanceList.begin();
|
||||
while ( iter != mMatInstanceList.end() )
|
||||
{
|
||||
if ( (*iter)->deleteAllHooks() != 0 )
|
||||
{
|
||||
// Restart the loop.
|
||||
iter = mMatInstanceList.begin();
|
||||
continue;
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
// Now do a pass re-initializing materials.
|
||||
iter = mMatInstanceList.begin();
|
||||
for ( ; iter != mMatInstanceList.end(); iter++ )
|
||||
(*iter)->reInit();
|
||||
}
|
||||
|
||||
// Used in the materialEditor. This flushes the material preview object so it can be reloaded easily.
|
||||
void MaterialManager::flushInstance( BaseMaterialDefinition *target )
|
||||
{
|
||||
Vector<BaseMatInstance*>::iterator iter = mMatInstanceList.begin();
|
||||
while ( iter != mMatInstanceList.end() )
|
||||
{
|
||||
if ( (*iter)->getMaterial() == target )
|
||||
{
|
||||
(*iter)->deleteAllHooks();
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialManager::reInitInstance( BaseMaterialDefinition *target )
|
||||
{
|
||||
Vector<BaseMatInstance*>::iterator iter = mMatInstanceList.begin();
|
||||
for ( ; iter != mMatInstanceList.end(); iter++ )
|
||||
{
|
||||
if ( (*iter)->getMaterial() == target )
|
||||
(*iter)->reInit();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialManager::updateTime()
|
||||
{
|
||||
U32 curTime = Sim::getCurrentTime();
|
||||
if(curTime > mLastTime)
|
||||
{
|
||||
mDt = (curTime - mLastTime) / 1000.0f;
|
||||
mLastTime = curTime;
|
||||
mAccumTime += mDt;
|
||||
}
|
||||
else
|
||||
mDt = 0.0f;
|
||||
}
|
||||
|
||||
SimSet * MaterialManager::getMaterialSet()
|
||||
{
|
||||
if(!mMaterialSet)
|
||||
mMaterialSet = static_cast<SimSet*>( Sim::findObject( "MaterialSet" ) );
|
||||
|
||||
AssertFatal( mMaterialSet, "MaterialSet not found" );
|
||||
return mMaterialSet;
|
||||
}
|
||||
|
||||
void MaterialManager::dumpMaterialInstances( BaseMaterialDefinition *target ) const
|
||||
{
|
||||
if ( !mMatInstanceList.size() )
|
||||
return;
|
||||
|
||||
if ( target )
|
||||
Con::printf( "--------------------- %s MatInstances ---------------------", target->getName() );
|
||||
else
|
||||
Con::printf( "--------------------- MatInstances %d ---------------------", mMatInstanceList.size() );
|
||||
|
||||
for( U32 i=0; i<mMatInstanceList.size(); i++ )
|
||||
{
|
||||
BaseMatInstance *inst = mMatInstanceList[i];
|
||||
|
||||
if ( target && inst->getMaterial() != target )
|
||||
continue;
|
||||
|
||||
inst->dumpShaderInfo();
|
||||
|
||||
Con::printf( "" );
|
||||
}
|
||||
|
||||
Con::printf( "---------------------- Dump complete ----------------------");
|
||||
}
|
||||
|
||||
void MaterialManager::_track( MatInstance *matInstance )
|
||||
{
|
||||
mMatInstanceList.push_back( matInstance );
|
||||
}
|
||||
|
||||
void MaterialManager::_untrack( MatInstance *matInstance )
|
||||
{
|
||||
mMatInstanceList.remove( matInstance );
|
||||
}
|
||||
|
||||
void MaterialManager::recalcFeaturesFromPrefs()
|
||||
{
|
||||
mDefaultFeatures.clear();
|
||||
FeatureType::addDefaultTypes( &mDefaultFeatures );
|
||||
|
||||
mExclusionFeatures.setFeature( MFT_NormalMap,
|
||||
Con::getBoolVariable( "$pref::Video::disableNormalMapping", false ) );
|
||||
|
||||
mExclusionFeatures.setFeature( MFT_PixSpecular,
|
||||
Con::getBoolVariable( "$pref::Video::disablePixSpecular", false ) );
|
||||
|
||||
mExclusionFeatures.setFeature( MFT_CubeMap,
|
||||
Con::getBoolVariable( "$pref::Video::disableCubemapping", false ) );
|
||||
|
||||
mExclusionFeatures.setFeature( MFT_Parallax,
|
||||
Con::getBoolVariable( "$pref::Video::disableParallaxMapping", false ) );
|
||||
}
|
||||
|
||||
bool MaterialManager::_handleGFXEvent( GFXDevice::GFXDeviceEventType event_ )
|
||||
{
|
||||
switch ( event_ )
|
||||
{
|
||||
case GFXDevice::deInit:
|
||||
recalcFeaturesFromPrefs();
|
||||
break;
|
||||
|
||||
case GFXDevice::deDestroy :
|
||||
SAFE_DELETE( mWarningInst );
|
||||
break;
|
||||
|
||||
case GFXDevice::deStartOfFrame:
|
||||
if ( mFlushAndReInit )
|
||||
flushAndReInitInstances();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ConsoleFunction( reInitMaterials, void, 1, 1,
|
||||
"@brief Flushes all procedural shaders and re-initializes all active material instances.\n\n"
|
||||
"@ingroup Materials")
|
||||
{
|
||||
MATMGR->flushAndReInitInstances();
|
||||
}
|
||||
|
||||
ConsoleFunction( addMaterialMapping, void, 3, 3, "(string texName, string matName)\n"
|
||||
"@brief Maps the given texture to the given material.\n\n"
|
||||
"Generates a console warning before overwriting.\n\n"
|
||||
"Material maps are used by terrain and interiors for triggering "
|
||||
"effects when an object moves onto a terrain "
|
||||
"block or interior surface using the associated texture.\n\n"
|
||||
"@ingroup Materials")
|
||||
{
|
||||
MATMGR->mapMaterial(argv[1],argv[2]);
|
||||
}
|
||||
|
||||
ConsoleFunction( getMaterialMapping, const char*, 2, 2, "(string texName)\n"
|
||||
"@brief Returns the name of the material mapped to this texture.\n\n"
|
||||
"If no materials are found, an empty string is returned.\n\n"
|
||||
"@param texName Name of the texture\n\n"
|
||||
"@ingroup Materials")
|
||||
{
|
||||
return MATMGR->getMapEntry(argv[1]).c_str();
|
||||
}
|
||||
|
||||
ConsoleFunction( dumpMaterialInstances, void, 1, 1,
|
||||
"@brief Dumps a formatted list of currently allocated material instances to the console.\n\n"
|
||||
"@ingroup Materials")
|
||||
{
|
||||
MATMGR->dumpMaterialInstances();
|
||||
}
|
||||
|
||||
ConsoleFunction( getMapEntry, const char *, 2, 2,
|
||||
"@hide")
|
||||
{
|
||||
return MATMGR->getMapEntry( String(argv[1]) );
|
||||
}
|
||||
184
Engine/source/materials/materialManager.h
Normal file
184
Engine/source/materials/materialManager.h
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _MATERIAL_MGR_H_
|
||||
#define _MATERIAL_MGR_H_
|
||||
|
||||
#ifndef _MATERIALDEFINITION_H_
|
||||
#include "materials/materialDefinition.h"
|
||||
#endif
|
||||
#ifndef _FEATURESET_H_
|
||||
#include "shaderGen/featureSet.h"
|
||||
#endif
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
#ifndef _TSINGLETON_H_
|
||||
#include "core/util/tSingleton.h"
|
||||
#endif
|
||||
|
||||
class SimSet;
|
||||
class MatInstance;
|
||||
|
||||
class MaterialManager : public ManagedSingleton<MaterialManager>
|
||||
{
|
||||
public:
|
||||
MaterialManager();
|
||||
~MaterialManager();
|
||||
|
||||
// ManagedSingleton
|
||||
static const char* getSingletonName() { return "MaterialManager"; }
|
||||
|
||||
Material * allocateAndRegister(const String &objectName, const String &mapToName = String());
|
||||
Material * getMaterialDefinitionByName(const String &matName);
|
||||
SimSet * getMaterialSet();
|
||||
|
||||
// map textures to materials
|
||||
void mapMaterial(const String & textureName, const String & materialName);
|
||||
String getMapEntry(const String & textureName) const;
|
||||
|
||||
// Return instance of named material caller is responsible for memory
|
||||
BaseMatInstance * createMatInstance( const String &matName );
|
||||
|
||||
// Create a BaseMatInstance with the default feature flags.
|
||||
BaseMatInstance * createMatInstance( const String &matName, const GFXVertexFormat *vertexFormat );
|
||||
BaseMatInstance * createMatInstance( const String &matName, const FeatureSet &features, const GFXVertexFormat *vertexFormat );
|
||||
|
||||
/// The default feature set for materials.
|
||||
const FeatureSet& getDefaultFeatures() const { return mDefaultFeatures; }
|
||||
|
||||
/// The feature exclusion list for disabling features.
|
||||
const FeatureSet& getExclusionFeatures() const { return mExclusionFeatures; }
|
||||
|
||||
void recalcFeaturesFromPrefs();
|
||||
|
||||
/// Get the default texture anisotropy.
|
||||
U32 getDefaultAnisotropy() const { return mDefaultAnisotropy; }
|
||||
|
||||
/// Allocate and return an instance of special materials. Caller is responsible for the memory.
|
||||
BaseMatInstance * createWarningMatInstance();
|
||||
|
||||
/// Gets the global warning material instance, callers should not free this copy
|
||||
BaseMatInstance * getWarningMatInstance();
|
||||
|
||||
/// Set the prepass enabled state.
|
||||
void setPrePassEnabled( bool enabled ) { mUsingPrePass = enabled; }
|
||||
|
||||
/// Get the prepass enabled state.
|
||||
bool getPrePassEnabled() const { return mUsingPrePass; }
|
||||
|
||||
#ifndef TORQUE_SHIPPING
|
||||
|
||||
// Allocate and return an instance of mesh debugging materials. Caller is responsible for the memory.
|
||||
BaseMatInstance * createMeshDebugMatInstance(const ColorF &meshColor);
|
||||
|
||||
// Gets the global material instance for a given color, callers should not free this copy
|
||||
BaseMatInstance * getMeshDebugMatInstance(const ColorF &meshColor);
|
||||
|
||||
#endif
|
||||
|
||||
void dumpMaterialInstances( BaseMaterialDefinition *target = NULL ) const;
|
||||
|
||||
void updateTime();
|
||||
F32 getTotalTime() const { return mAccumTime; }
|
||||
F32 getDeltaTime() const { return mDt; }
|
||||
U32 getLastUpdateTime() const { return mLastTime; }
|
||||
|
||||
/// Signal used to notify systems that
|
||||
/// procedural shaders have been flushed.
|
||||
typedef Signal<void()> FlushSignal;
|
||||
|
||||
/// Returns the signal used to notify systems that the
|
||||
/// procedural shaders have been flushed.
|
||||
FlushSignal& getFlushSignal() { return mFlushSignal; }
|
||||
|
||||
/// Flushes all the procedural shaders and re-initializes all
|
||||
/// the active materials instances immediately.
|
||||
void flushAndReInitInstances();
|
||||
|
||||
// Flush the instance
|
||||
void flushInstance( BaseMaterialDefinition *target );
|
||||
|
||||
/// Re-initializes the material instances for a specific target material.
|
||||
void reInitInstance( BaseMaterialDefinition *target );
|
||||
|
||||
protected:
|
||||
|
||||
// MatInstance tracks it's instances here
|
||||
friend class MatInstance;
|
||||
void _track(MatInstance*);
|
||||
void _untrack(MatInstance*);
|
||||
|
||||
/// @see LightManager::smActivateSignal
|
||||
void _onLMActivate( const char *lm, bool activate );
|
||||
|
||||
bool _handleGFXEvent(GFXDevice::GFXDeviceEventType event);
|
||||
|
||||
SimSet* mMaterialSet;
|
||||
Vector<BaseMatInstance*> mMatInstanceList;
|
||||
|
||||
/// The default material features.
|
||||
FeatureSet mDefaultFeatures;
|
||||
|
||||
/// The feature exclusion set.
|
||||
FeatureSet mExclusionFeatures;
|
||||
|
||||
/// Signal used to notify systems that
|
||||
/// procedural shaders have been flushed.
|
||||
FlushSignal mFlushSignal;
|
||||
|
||||
/// If set we flush and reinitialize all materials at the
|
||||
/// start of the next rendered frame.
|
||||
bool mFlushAndReInit;
|
||||
|
||||
// material map
|
||||
typedef Map<String, String> MaterialMap;
|
||||
MaterialMap mMaterialMap;
|
||||
|
||||
bool mUsingPrePass;
|
||||
|
||||
// time tracking
|
||||
F32 mDt;
|
||||
F32 mAccumTime;
|
||||
U32 mLastTime;
|
||||
|
||||
BaseMatInstance* mWarningInst;
|
||||
|
||||
/// The default max anisotropy used in texture filtering.
|
||||
S32 mDefaultAnisotropy;
|
||||
|
||||
/// Called when $pref::Video::defaultAnisotropy is changed.
|
||||
void _updateDefaultAnisotropy();
|
||||
|
||||
/// Called when one of the feature disabling $pref::s are changed.
|
||||
void _onDisableMaterialFeature() { mFlushAndReInit = true; }
|
||||
|
||||
#ifndef TORQUE_SHIPPING
|
||||
typedef Map<U32, BaseMatInstance *> DebugMaterialMap;
|
||||
DebugMaterialMap mMeshDebugMaterialInsts;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/// Helper for accessing MaterialManager singleton.
|
||||
#define MATMGR MaterialManager::instance()
|
||||
|
||||
#endif // _MATERIAL_MGR_H_
|
||||
99
Engine/source/materials/materialParameters.h
Normal file
99
Engine/source/materials/materialParameters.h
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _MATERIALPARAMETERS_H_
|
||||
#define _MATERIALPARAMETERS_H_
|
||||
|
||||
#ifndef _GFXSHADER_H_
|
||||
#include "gfx/gfxShader.h"
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Similar class to GFXShaderConsts, but this is to describe generic material parameters.
|
||||
///
|
||||
class MaterialParameterHandle
|
||||
{
|
||||
public:
|
||||
virtual ~MaterialParameterHandle() {}
|
||||
virtual const String& getName() const = 0;
|
||||
// This is similar to GFXShaderConstHandle, but a Material will always return a handle when
|
||||
// asked for one. Even if it doesn't have that material parameter. This is because after a
|
||||
// reInitMaterials call, the constants can change underneath the MatInstance.
|
||||
// Note: GFXShaderConstHandle actually works this way too, now.
|
||||
virtual bool isValid() const = 0;
|
||||
/// Returns -1 if this handle does not point to a Sampler.
|
||||
virtual S32 getSamplerRegister( U32 pass ) const = 0;
|
||||
};
|
||||
|
||||
class MaterialParameters
|
||||
{
|
||||
public:
|
||||
MaterialParameters()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mShaderConstDesc );
|
||||
}
|
||||
virtual ~MaterialParameters() {}
|
||||
|
||||
/// Returns our list of shader constants, the material can get this and just set the constants it knows about
|
||||
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const { return mShaderConstDesc; }
|
||||
|
||||
/// An inline helper which ensures the handle is valid
|
||||
/// before the virtual set method is called.
|
||||
template< typename VALUE >
|
||||
inline void setSafe( MaterialParameterHandle *handle, const VALUE& v )
|
||||
{
|
||||
if ( handle->isValid() )
|
||||
set( handle, v );
|
||||
}
|
||||
|
||||
/// @name Set shader constant values
|
||||
/// @{
|
||||
/// Actually set shader constant values
|
||||
/// @param name Name of the constant, this should be a name contained in the array returned in getShaderConstDesc,
|
||||
/// if an invalid name is used, it is ignored.
|
||||
virtual void set(MaterialParameterHandle* handle, const F32 f) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const Point2F& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const Point3F& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const Point4F& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const ColorF& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const S32 f) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const Point2I& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const Point3I& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const Point4I& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<F32>& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point2F>& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point3F>& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point4F>& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<S32>& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point2I>& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point3I>& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point4I>& fv) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType = GFXSCT_Float4x4) {}
|
||||
virtual void set(MaterialParameterHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4) {}
|
||||
|
||||
/// Returns the alignment value for the constType in bytes.
|
||||
virtual U32 getAlignmentValue(const GFXShaderConstType constType) { return 0; }
|
||||
|
||||
protected:
|
||||
Vector<GFXShaderConstDesc> mShaderConstDesc;
|
||||
};
|
||||
|
||||
#endif
|
||||
57
Engine/source/materials/miscShdrDat.h
Normal file
57
Engine/source/materials/miscShdrDat.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _MISCSHDRDAT_H_
|
||||
#define _MISCSHDRDAT_H_
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
|
||||
//**************************************************************************
|
||||
// This file is an attempt to keep certain classes from having to know about
|
||||
// the ShaderGen class
|
||||
//**************************************************************************
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Enums
|
||||
//-----------------------------------------------------------------------
|
||||
enum RegisterType
|
||||
{
|
||||
RT_POSITION = 0,
|
||||
RT_NORMAL,
|
||||
RT_BINORMAL,
|
||||
RT_TANGENT,
|
||||
RT_COLOR,
|
||||
RT_TEXCOORD,
|
||||
RT_VPOS,
|
||||
};
|
||||
|
||||
enum Components
|
||||
{
|
||||
C_VERT_STRUCT = 0,
|
||||
C_CONNECTOR,
|
||||
C_VERT_MAIN,
|
||||
C_PIX_MAIN,
|
||||
};
|
||||
|
||||
#endif // _MISCSHDRDAT_H_
|
||||
498
Engine/source/materials/processedCustomMaterial.cpp
Normal file
498
Engine/source/materials/processedCustomMaterial.cpp
Normal file
|
|
@ -0,0 +1,498 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/processedCustomMaterial.h"
|
||||
|
||||
#include "gfx/sim/cubemapData.h"
|
||||
#include "materials/sceneData.h"
|
||||
#include "shaderGen/shaderGenVars.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "materials/customMaterialDefinition.h"
|
||||
#include "materials/shaderData.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "materials/matTextureTarget.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
#include "materials/materialParameters.h"
|
||||
#include "gfx/sim/gfxStateBlockData.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "gfx/genericConstBuffer.h"
|
||||
#include "console/simFieldDictionary.h"
|
||||
#include "console/propertyParsing.h"
|
||||
#include "gfx/util/screenspace.h"
|
||||
|
||||
|
||||
ProcessedCustomMaterial::ProcessedCustomMaterial(Material &mat)
|
||||
{
|
||||
mMaterial = &mat;
|
||||
AssertFatal(dynamic_cast<CustomMaterial*>(mMaterial), "Incompatible Material type!");
|
||||
mCustomMaterial = static_cast<CustomMaterial*>(mMaterial);
|
||||
mHasSetStageData = false;
|
||||
mHasGlow = false;
|
||||
mMaxStages = 0;
|
||||
mMaxTex = 0;
|
||||
}
|
||||
|
||||
ProcessedCustomMaterial::~ProcessedCustomMaterial()
|
||||
{
|
||||
}
|
||||
|
||||
void ProcessedCustomMaterial::_setStageData()
|
||||
{
|
||||
// Only do this once
|
||||
if ( mHasSetStageData )
|
||||
return;
|
||||
mHasSetStageData = true;
|
||||
|
||||
ShaderRenderPassData* rpd = _getRPD(0);
|
||||
mConditionerMacros.clear();
|
||||
|
||||
// Loop through all the possible textures, set the right flags, and load them if needed
|
||||
for(U32 i=0; i<CustomMaterial::MAX_TEX_PER_PASS; i++ )
|
||||
{
|
||||
rpd->mTexType[i] = Material::NoTexture; // Set none as the default in case none of the cases below catch it.
|
||||
String filename = mCustomMaterial->mTexFilename[i];
|
||||
|
||||
if(filename.isEmpty())
|
||||
continue;
|
||||
|
||||
if(filename.equal(String("$dynamiclight"), String::NoCase))
|
||||
{
|
||||
rpd->mTexType[i] = Material::DynamicLight;
|
||||
mMaxTex = i+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(filename.equal(String("$dynamiclightmask"), String::NoCase))
|
||||
{
|
||||
rpd->mTexType[i] = Material::DynamicLightMask;
|
||||
mMaxTex = i+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(filename.equal(String("$lightmap"), String::NoCase))
|
||||
{
|
||||
rpd->mTexType[i] = Material::Lightmap;
|
||||
mMaxTex = i+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(filename.equal(String("$cubemap"), String::NoCase))
|
||||
{
|
||||
if( mCustomMaterial->mCubemapData )
|
||||
{
|
||||
rpd->mTexType[i] = Material::Cube;
|
||||
mMaxTex = i+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCustomMaterial->logError( "Could not find CubemapData - %s", mCustomMaterial->mCubemapName.c_str());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(filename.equal(String("$dynamicCubemap"), String::NoCase))
|
||||
{
|
||||
rpd->mTexType[i] = Material::SGCube;
|
||||
mMaxTex = i+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(filename.equal(String("$backbuff"), String::NoCase))
|
||||
{
|
||||
rpd->mTexType[i] = Material::BackBuff;
|
||||
mMaxTex = i+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(filename.equal(String("$reflectbuff"), String::NoCase))
|
||||
{
|
||||
rpd->mTexType[i] = Material::ReflectBuff;
|
||||
mMaxTex = i+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(filename.equal(String("$miscbuff"), String::NoCase))
|
||||
{
|
||||
rpd->mTexType[i] = Material::Misc;
|
||||
mMaxTex = i+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for a RenderTexTargetBin assignment
|
||||
if (filename.substr( 0, 1 ).equal("#"))
|
||||
{
|
||||
String texTargetBufferName = filename.substr(1, filename.length() - 1);
|
||||
NamedTexTarget *texTarget = NamedTexTarget::find( texTargetBufferName );
|
||||
rpd->mTexSlot[i].texTarget = texTarget;
|
||||
|
||||
// Get the conditioner macros.
|
||||
if ( texTarget )
|
||||
texTarget->getShaderMacros( &mConditionerMacros );
|
||||
|
||||
rpd->mTexType[i] = Material::TexTarget;
|
||||
mMaxTex = i+1;
|
||||
continue;
|
||||
}
|
||||
|
||||
rpd->mTexSlot[i].texObject = _createTexture( filename, &GFXDefaultStaticDiffuseProfile );
|
||||
if ( !rpd->mTexSlot[i].texObject )
|
||||
{
|
||||
mMaterial->logError("Failed to load texture %s", _getTexturePath(filename).c_str());
|
||||
continue;
|
||||
}
|
||||
rpd->mTexType[i] = Material::Standard;
|
||||
mMaxTex = i+1;
|
||||
}
|
||||
|
||||
// We only get one cubemap
|
||||
if( mCustomMaterial->mCubemapData )
|
||||
{
|
||||
mCustomMaterial->mCubemapData->createMap();
|
||||
rpd->mCubeMap = mMaterial->mCubemapData->mCubemap; // BTRTODO ?
|
||||
if ( !rpd->mCubeMap )
|
||||
mMaterial->logError("Failed to load cubemap");
|
||||
}
|
||||
|
||||
// If this has a output target defined, it may be writing
|
||||
// to a tex target bin with a conditioner, so search for
|
||||
// one and add its macros.
|
||||
if ( mCustomMaterial->mOutputTarget.isNotEmpty() )
|
||||
{
|
||||
NamedTexTarget *texTarget = NamedTexTarget::find( mCustomMaterial->mOutputTarget );
|
||||
if ( texTarget )
|
||||
texTarget->getShaderMacros( &mConditionerMacros );
|
||||
}
|
||||
|
||||
// Copy the glow state over.
|
||||
mHasGlow = mCustomMaterial->mGlow[0];
|
||||
}
|
||||
|
||||
bool ProcessedCustomMaterial::init( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
const MatFeaturesDelegate &featuresDelegate )
|
||||
{
|
||||
// If we don't have a shader data... we have nothing to do.
|
||||
if ( !mCustomMaterial->mShaderData )
|
||||
return true;
|
||||
|
||||
// Custom materials only do one pass at the moment... so
|
||||
// add one for the stage data to fill in.
|
||||
ShaderRenderPassData *rpd = new ShaderRenderPassData();
|
||||
mPasses.push_back( rpd );
|
||||
|
||||
_setStageData();
|
||||
_initPassStateBlocks();
|
||||
mStateHint.clear();
|
||||
|
||||
// Note: We don't use the vertex format in a custom
|
||||
// material at all right now.
|
||||
//
|
||||
// Maybe we can add some required semantics and
|
||||
// validate that the format fits the shader?
|
||||
|
||||
// Build a composite list of shader macros from
|
||||
// the conditioner and the user defined lists.
|
||||
Vector<GFXShaderMacro> macros;
|
||||
macros.merge( mConditionerMacros );
|
||||
macros.merge( mUserMacros );
|
||||
|
||||
// Ask the shader data to give us a shader instance.
|
||||
rpd->shader = mCustomMaterial->mShaderData->getShader( macros );
|
||||
if ( !rpd->shader )
|
||||
{
|
||||
delete rpd;
|
||||
mPasses.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
rpd->shaderHandles.init( rpd->shader, mCustomMaterial );
|
||||
_initMaterialParameters();
|
||||
mDefaultParameters = allocMaterialParameters();
|
||||
setMaterialParameters( mDefaultParameters, 0 );
|
||||
mStateHint.init( this );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessedCustomMaterial::_initPassStateBlock( RenderPassData *rpd, GFXStateBlockDesc &result )
|
||||
{
|
||||
Parent::_initPassStateBlock( rpd, result );
|
||||
|
||||
if (mCustomMaterial->getStateBlockData())
|
||||
result.addDesc(mCustomMaterial->getStateBlockData()->getState());
|
||||
}
|
||||
|
||||
void ProcessedCustomMaterial::_initPassStateBlocks()
|
||||
{
|
||||
AssertFatal(mHasSetStageData, "State data must be set before initializing state block!");
|
||||
ShaderRenderPassData* rpd = _getRPD(0);
|
||||
_initRenderStateStateBlocks( rpd );
|
||||
}
|
||||
|
||||
bool ProcessedCustomMaterial::_hasCubemap(U32 pass)
|
||||
{
|
||||
// If the material doesn't have a cubemap, we don't
|
||||
if( mMaterial->mCubemapData ) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool ProcessedCustomMaterial::setupPass( SceneRenderState *state, const SceneData& sgData, U32 pass )
|
||||
{
|
||||
PROFILE_SCOPE( ProcessedCustomMaterial_SetupPass );
|
||||
|
||||
// Make sure we have a pass.
|
||||
if ( pass >= mPasses.size() )
|
||||
return false;
|
||||
|
||||
ShaderRenderPassData* rpd = _getRPD( pass );
|
||||
U32 currState = _getRenderStateIndex( state, sgData );
|
||||
GFX->setStateBlock(rpd->mRenderStates[currState]);
|
||||
|
||||
// activate shader
|
||||
if ( rpd->shader )
|
||||
GFX->setShader( rpd->shader );
|
||||
else
|
||||
GFX->disableShaders();
|
||||
|
||||
// Set our textures
|
||||
setTextureStages( state, sgData, pass );
|
||||
|
||||
GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
|
||||
GFX->setShaderConstBuffer(shaderConsts);
|
||||
|
||||
// Set our shader constants.
|
||||
_setTextureTransforms(pass);
|
||||
_setShaderConstants(state, sgData, pass);
|
||||
|
||||
LightManager* lm = state ? LIGHTMGR : NULL;
|
||||
if (lm)
|
||||
lm->setLightInfo(this, NULL, sgData, state, pass, shaderConsts);
|
||||
|
||||
shaderConsts->setSafe(rpd->shaderHandles.mAccumTimeSC, MATMGR->getTotalTime());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessedCustomMaterial::setTextureStages( SceneRenderState *state, const SceneData &sgData, U32 pass )
|
||||
{
|
||||
LightManager* lm = state ? LIGHTMGR : NULL;
|
||||
ShaderRenderPassData* rpd = _getRPD(pass);
|
||||
ShaderConstHandles* handles = _getShaderConstHandles(pass);
|
||||
GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
|
||||
|
||||
const NamedTexTarget *texTarget;
|
||||
GFXTextureObject *texObject;
|
||||
|
||||
for( U32 i=0; i<mMaxTex; i++ )
|
||||
{
|
||||
U32 currTexFlag = rpd->mTexType[i];
|
||||
if ( !lm || !lm->setTextureStage(sgData, currTexFlag, i, shaderConsts, handles ) )
|
||||
{
|
||||
GFXShaderConstHandle* handle = handles->mTexHandlesSC[i];
|
||||
if ( !handle->isValid() )
|
||||
continue;
|
||||
|
||||
S32 samplerRegister = handle->getSamplerRegister();
|
||||
|
||||
switch( currTexFlag )
|
||||
{
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
|
||||
case Material::Mask:
|
||||
case Material::Standard:
|
||||
case Material::Bump:
|
||||
case Material::Detail:
|
||||
{
|
||||
GFX->setTexture( samplerRegister, rpd->mTexSlot[i].texObject );
|
||||
break;
|
||||
}
|
||||
|
||||
case Material::Lightmap:
|
||||
{
|
||||
GFX->setTexture( samplerRegister, sgData.lightmap );
|
||||
break;
|
||||
}
|
||||
case Material::Cube:
|
||||
{
|
||||
GFX->setCubeTexture( samplerRegister, rpd->mCubeMap );
|
||||
break;
|
||||
}
|
||||
case Material::SGCube:
|
||||
{
|
||||
GFX->setCubeTexture( samplerRegister, sgData.cubemap );
|
||||
break;
|
||||
}
|
||||
case Material::BackBuff:
|
||||
{
|
||||
GFX->setTexture( samplerRegister, sgData.backBuffTex );
|
||||
break;
|
||||
}
|
||||
case Material::ReflectBuff:
|
||||
{
|
||||
GFX->setTexture( samplerRegister, sgData.reflectTex );
|
||||
break;
|
||||
}
|
||||
case Material::Misc:
|
||||
{
|
||||
GFX->setTexture( samplerRegister, sgData.miscTex );
|
||||
break;
|
||||
}
|
||||
case Material::TexTarget:
|
||||
{
|
||||
texTarget = rpd->mTexSlot[i].texTarget;
|
||||
if ( !texTarget )
|
||||
{
|
||||
GFX->setTexture( samplerRegister, NULL );
|
||||
break;
|
||||
}
|
||||
|
||||
texObject = texTarget->getTexture();
|
||||
|
||||
// If no texture is available then map the default 2x2
|
||||
// black texture to it. This at least will ensure that
|
||||
// we get consistant behavior across GPUs and platforms.
|
||||
if ( !texObject )
|
||||
texObject = GFXTexHandle::ZERO;
|
||||
|
||||
if ( handles->mRTParamsSC[samplerRegister]->isValid() && texObject )
|
||||
{
|
||||
const Point3I &targetSz = texObject->getSize();
|
||||
const RectI &targetVp = texTarget->getViewport();
|
||||
Point4F rtParams;
|
||||
|
||||
ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);
|
||||
shaderConsts->set(handles->mRTParamsSC[samplerRegister], rtParams);
|
||||
}
|
||||
|
||||
GFX->setTexture( samplerRegister, texObject );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ProcessedCustomMaterial::setMaterialParameter(MaterialParameters* param,
|
||||
MaterialParameterHandle* handle,
|
||||
const String& value)
|
||||
{
|
||||
T typedValue;
|
||||
if (PropertyInfo::default_scan(value, typedValue))
|
||||
{
|
||||
param->set(handle, typedValue);
|
||||
} else {
|
||||
Con::errorf("Error setting %s, parse error: %s", handle->getName().c_str(), value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessedCustomMaterial::setMatrixParameter(MaterialParameters* param,
|
||||
MaterialParameterHandle* handle,
|
||||
const String& value, GFXShaderConstType matrixType)
|
||||
{
|
||||
MatrixF result(true);
|
||||
F32* m = result;
|
||||
switch (matrixType)
|
||||
{
|
||||
case GFXSCT_Float2x2 :
|
||||
dSscanf(value.c_str(),"%g %g %g %g",
|
||||
m[result.idx(0,0)], m[result.idx(0,1)],
|
||||
m[result.idx(1,0)], m[result.idx(1,1)]);
|
||||
break;
|
||||
case GFXSCT_Float3x3 :
|
||||
dSscanf(value.c_str(),"%g %g %g %g %g %g %g %g %g",
|
||||
m[result.idx(0,0)], m[result.idx(0,1)], m[result.idx(0,2)],
|
||||
m[result.idx(1,0)], m[result.idx(1,1)], m[result.idx(1,2)],
|
||||
m[result.idx(2,0)], m[result.idx(2,1)], m[result.idx(2,2)]);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid type!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// BTRTODO: Support arrays!?
|
||||
MaterialParameters* ProcessedCustomMaterial::allocMaterialParameters()
|
||||
{
|
||||
MaterialParameters* ret = Parent::allocMaterialParameters();
|
||||
// See if any of the dynamic fields match up with shader constants we have.
|
||||
SimFieldDictionary* fields = mMaterial->getFieldDictionary();
|
||||
if (!fields || fields->getNumFields() == 0)
|
||||
return ret;
|
||||
|
||||
const Vector<GFXShaderConstDesc>& consts = ret->getShaderConstDesc();
|
||||
for (U32 i = 0; i < consts.size(); i++)
|
||||
{
|
||||
// strip the dollar sign from the front.
|
||||
String stripped(consts[i].name);
|
||||
stripped.erase(0, 1);
|
||||
|
||||
SimFieldDictionary::Entry* field = fields->findDynamicField(stripped);
|
||||
if (field)
|
||||
{
|
||||
MaterialParameterHandle* handle = getMaterialParameterHandle(consts[i].name);
|
||||
switch (consts[i].constType)
|
||||
{
|
||||
case GFXSCT_Float :
|
||||
setMaterialParameter<F32>(ret, handle, field->value);
|
||||
break;
|
||||
case GFXSCT_Float2:
|
||||
setMaterialParameter<Point2F>(ret, handle, field->value);
|
||||
break;
|
||||
case GFXSCT_Float3:
|
||||
setMaterialParameter<Point3F>(ret, handle, field->value);
|
||||
break;
|
||||
case GFXSCT_Float4:
|
||||
setMaterialParameter<Point4F>(ret, handle, field->value);
|
||||
break;
|
||||
case GFXSCT_Float2x2:
|
||||
case GFXSCT_Float3x3:
|
||||
setMatrixParameter(ret, handle, field->value, consts[i].constType);
|
||||
break;
|
||||
case GFXSCT_Float4x4:
|
||||
setMaterialParameter<MatrixF>(ret, handle, field->value);
|
||||
break;
|
||||
case GFXSCT_Int:
|
||||
setMaterialParameter<S32>(ret, handle, field->value);
|
||||
break;
|
||||
case GFXSCT_Int2:
|
||||
setMaterialParameter<Point2I>(ret, handle, field->value);
|
||||
break;
|
||||
case GFXSCT_Int3:
|
||||
setMaterialParameter<Point3I>(ret, handle, field->value);
|
||||
break;
|
||||
case GFXSCT_Int4:
|
||||
setMaterialParameter<Point4I>(ret, handle, field->value);
|
||||
break;
|
||||
// Do we want to ignore these?
|
||||
case GFXSCT_Sampler:
|
||||
case GFXSCT_SamplerCube:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
72
Engine/source/materials/processedCustomMaterial.h
Normal file
72
Engine/source/materials/processedCustomMaterial.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATERIALS_PROCESSEDCUSTOMMATERIAL_H_
|
||||
#define _MATERIALS_PROCESSEDCUSTOMMATERIAL_H_
|
||||
|
||||
#ifndef _MATERIALS_PROCESSEDSHADERMATERIAL_H_
|
||||
#include "materials/processedShaderMaterial.h"
|
||||
#endif
|
||||
#ifndef _CUSTOMMATERIALDEFINITION_H_
|
||||
#include "materials/customMaterialDefinition.h"
|
||||
#endif
|
||||
|
||||
|
||||
///
|
||||
class ProcessedCustomMaterial : public ProcessedShaderMaterial
|
||||
{
|
||||
typedef ProcessedShaderMaterial Parent;
|
||||
public:
|
||||
ProcessedCustomMaterial(Material &mat);
|
||||
~ProcessedCustomMaterial();
|
||||
|
||||
virtual bool setupPass(SceneRenderState *, const SceneData& sgData, U32 pass);
|
||||
virtual bool init( const FeatureSet &features, const GFXVertexFormat *vertexFormat, const MatFeaturesDelegate &featuresDelegate );
|
||||
virtual void setTextureStages(SceneRenderState *, const SceneData &sgData, U32 pass );
|
||||
virtual MaterialParameters* allocMaterialParameters();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void _setStageData();
|
||||
virtual bool _hasCubemap(U32 pass);
|
||||
void _initPassStateBlock( RenderPassData *rpd, GFXStateBlockDesc &result );
|
||||
virtual void _initPassStateBlocks();
|
||||
|
||||
private:
|
||||
|
||||
CustomMaterial* mCustomMaterial;
|
||||
|
||||
/// The conditioner macros passed to the
|
||||
/// shader on construction.
|
||||
Vector<GFXShaderMacro> mConditionerMacros;
|
||||
|
||||
/// How many texture slots are we using.
|
||||
U32 mMaxTex;
|
||||
|
||||
template <typename T>
|
||||
void setMaterialParameter(MaterialParameters* param, MaterialParameterHandle* handle,
|
||||
const String& value);
|
||||
void setMatrixParameter(MaterialParameters* param,
|
||||
MaterialParameterHandle* handle, const String& value, GFXShaderConstType matrixType);
|
||||
};
|
||||
|
||||
#endif // _MATERIALS_PROCESSEDCUSTOMMATERIAL_H_
|
||||
378
Engine/source/materials/processedFFMaterial.cpp
Normal file
378
Engine/source/materials/processedFFMaterial.cpp
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/processedFFMaterial.h"
|
||||
|
||||
#include "gfx/sim/cubemapData.h"
|
||||
#include "materials/sceneData.h"
|
||||
#include "materials/customMaterialDefinition.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
#include "gfx/sim/gfxStateBlockData.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "gfx/genericConstBuffer.h"
|
||||
#include "materials/materialParameters.h"
|
||||
#include "lighting/lightInfo.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "math/util/matrixSet.h"
|
||||
|
||||
class FFMaterialParameterHandle : public MaterialParameterHandle
|
||||
{
|
||||
public:
|
||||
virtual ~FFMaterialParameterHandle() {}
|
||||
virtual const String& getName() const { return mName; }
|
||||
virtual bool isValid() const { return false; }
|
||||
virtual S32 getSamplerRegister( U32 pass ) const { return -1; }
|
||||
private:
|
||||
String mName;
|
||||
};
|
||||
|
||||
ProcessedFFMaterial::ProcessedFFMaterial()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mParamDesc );
|
||||
|
||||
_construct();
|
||||
}
|
||||
|
||||
ProcessedFFMaterial::ProcessedFFMaterial(Material &mat, const bool isLightingMaterial)
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mParamDesc );
|
||||
|
||||
_construct();
|
||||
mMaterial = &mat;
|
||||
mIsLightingMaterial = isLightingMaterial;
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::_construct()
|
||||
{
|
||||
mHasSetStageData = false;
|
||||
mHasGlow = false;
|
||||
mIsLightingMaterial = false;
|
||||
mDefaultHandle = new FFMaterialParameterHandle();
|
||||
mDefaultParameters = new MaterialParameters();
|
||||
mCurrentParams = mDefaultParameters;
|
||||
}
|
||||
|
||||
ProcessedFFMaterial::~ProcessedFFMaterial()
|
||||
{
|
||||
SAFE_DELETE(mDefaultParameters);
|
||||
SAFE_DELETE( mDefaultHandle );
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::_createPasses( U32 stageNum, const FeatureSet &features )
|
||||
{
|
||||
FixedFuncFeatureData featData;
|
||||
_determineFeatures(stageNum, featData, features);
|
||||
// Just create a simple pass!
|
||||
_addPass(0, featData);
|
||||
|
||||
mFeatures.clear();
|
||||
if ( featData.features[FixedFuncFeatureData::DiffuseMap] )
|
||||
mFeatures.addFeature( MFT_DiffuseMap );
|
||||
if ( featData.features[FixedFuncFeatureData::LightMap] )
|
||||
mFeatures.addFeature( MFT_LightMap );
|
||||
if ( featData.features[FixedFuncFeatureData::ToneMap] )
|
||||
mFeatures.addFeature( MFT_ToneMap );
|
||||
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::_determineFeatures( U32 stageNum,
|
||||
FixedFuncFeatureData& featData,
|
||||
const FeatureSet &features )
|
||||
{
|
||||
if ( mStages[stageNum].getTex( MFT_DiffuseMap ) )
|
||||
featData.features[FixedFuncFeatureData::DiffuseMap] = true;
|
||||
|
||||
if ( features.hasFeature( MFT_LightMap ) )
|
||||
featData.features[FixedFuncFeatureData::LightMap] = true;
|
||||
if ( features.hasFeature( MFT_ToneMap ))
|
||||
featData.features[FixedFuncFeatureData::ToneMap] = true;
|
||||
}
|
||||
|
||||
U32 ProcessedFFMaterial::getNumStages()
|
||||
{
|
||||
// Loops through all stages to determine how many stages we actually use
|
||||
U32 numStages = 0;
|
||||
|
||||
U32 i;
|
||||
for( i=0; i<Material::MAX_STAGES; i++ )
|
||||
{
|
||||
// Assume stage is inactive
|
||||
bool stageActive = false;
|
||||
|
||||
// Cubemaps only on first stage
|
||||
if( i == 0 )
|
||||
{
|
||||
// If we have a cubemap the stage is active
|
||||
if( mMaterial->mCubemapData || mMaterial->mDynamicCubemap )
|
||||
{
|
||||
numStages++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a texture for the a feature the
|
||||
// stage is active.
|
||||
if ( mStages[i].hasValidTex() )
|
||||
stageActive = true;
|
||||
|
||||
// If this stage has specular lighting, it's active
|
||||
if ( mMaterial->mPixelSpecular[i] )
|
||||
stageActive = true;
|
||||
|
||||
// If we have a Material that is vertex lit
|
||||
// then it may not have a texture
|
||||
if( mMaterial->mVertLit[i] )
|
||||
{
|
||||
stageActive = true;
|
||||
}
|
||||
|
||||
// Increment the number of active stages
|
||||
numStages += stageActive;
|
||||
}
|
||||
|
||||
|
||||
return numStages;
|
||||
}
|
||||
|
||||
bool ProcessedFFMaterial::setupPass( SceneRenderState *state, const SceneData &sgData, U32 pass )
|
||||
{
|
||||
PROFILE_SCOPE( ProcessedFFMaterial_SetupPass );
|
||||
|
||||
// Make sure we have a pass
|
||||
if(pass >= mPasses.size())
|
||||
return false;
|
||||
|
||||
_setRenderState( state, sgData, pass );
|
||||
|
||||
// Bind our textures
|
||||
setTextureStages( state, sgData, pass );
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::setTextureStages(SceneRenderState * state, const SceneData& sgData, U32 pass)
|
||||
{
|
||||
// We may need to do some trickery in here for fixed function, this is just copy/paste from MatInstance
|
||||
#ifdef TORQUE_DEBUG
|
||||
AssertFatal( pass<mPasses.size(), "Pass out of bounds" );
|
||||
#endif
|
||||
RenderPassData *rpd = mPasses[pass];
|
||||
for( U32 i=0; i<rpd->mNumTex; i++ )
|
||||
{
|
||||
U32 currTexFlag = rpd->mTexType[i];
|
||||
if (!LIGHTMGR || !LIGHTMGR->setTextureStage(sgData, currTexFlag, i, NULL, NULL))
|
||||
{
|
||||
switch( currTexFlag )
|
||||
{
|
||||
case Material::NoTexture:
|
||||
if (rpd->mTexSlot[i].texObject)
|
||||
GFX->setTexture( i, rpd->mTexSlot[i].texObject );
|
||||
break;
|
||||
|
||||
case Material::NormalizeCube:
|
||||
GFX->setCubeTexture(i, Material::GetNormalizeCube());
|
||||
break;
|
||||
|
||||
case Material::Lightmap:
|
||||
GFX->setTexture( i, sgData.lightmap );
|
||||
break;
|
||||
|
||||
case Material::Cube:
|
||||
// TODO: Is this right?
|
||||
GFX->setTexture( i, rpd->mTexSlot[0].texObject );
|
||||
break;
|
||||
|
||||
case Material::SGCube:
|
||||
// No cubemap support just yet
|
||||
//GFX->setCubeTexture( i, sgData.cubemap );
|
||||
GFX->setTexture( i, rpd->mTexSlot[0].texObject );
|
||||
break;
|
||||
|
||||
case Material::BackBuff:
|
||||
GFX->setTexture( i, sgData.backBuffTex );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MaterialParameters* ProcessedFFMaterial::allocMaterialParameters()
|
||||
{
|
||||
return new MaterialParameters();
|
||||
}
|
||||
|
||||
MaterialParameters* ProcessedFFMaterial::getDefaultMaterialParameters()
|
||||
{
|
||||
return mDefaultParameters;
|
||||
}
|
||||
|
||||
MaterialParameterHandle* ProcessedFFMaterial::getMaterialParameterHandle(const String& name)
|
||||
{
|
||||
return mDefaultHandle;
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::setTransforms(const MatrixSet &matrixSet, SceneRenderState *state, const U32 pass)
|
||||
{
|
||||
GFX->setWorldMatrix(matrixSet.getObjectToWorld());
|
||||
GFX->setViewMatrix(matrixSet.getWorldToCamera());
|
||||
GFX->setProjectionMatrix(matrixSet.getCameraToScreen());
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::setSceneInfo(SceneRenderState * state, const SceneData& sgData, U32 pass)
|
||||
{
|
||||
_setPrimaryLightInfo(*sgData.objTrans, sgData.lights[0], pass);
|
||||
_setSecondaryLightInfo(*sgData.objTrans, sgData.lights[1]);
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::_setPrimaryLightInfo(const MatrixF &_objTrans, LightInfo* light, U32 pass)
|
||||
{
|
||||
// Just in case
|
||||
GFX->setGlobalAmbientColor(ColorF(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
if ( light->getType() == LightInfo::Ambient )
|
||||
{
|
||||
// Ambient light
|
||||
GFX->setGlobalAmbientColor( light->getAmbient() );
|
||||
return;
|
||||
}
|
||||
|
||||
GFX->setLight(0, NULL);
|
||||
GFX->setLight(1, NULL);
|
||||
// This is a quick hack that lets us use FF lights
|
||||
GFXLightMaterial lightMat;
|
||||
lightMat.ambient = ColorF(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
lightMat.diffuse = ColorF(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
lightMat.emissive = ColorF(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
lightMat.specular = ColorF(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
lightMat.shininess = 128.0f;
|
||||
GFX->setLightMaterial(lightMat);
|
||||
|
||||
// set object transform
|
||||
MatrixF objTrans = _objTrans;
|
||||
objTrans.inverse();
|
||||
|
||||
// fill in primary light
|
||||
//-------------------------
|
||||
GFXLightInfo xlatedLight;
|
||||
light->setGFXLight(&xlatedLight);
|
||||
Point3F lightPos = light->getPosition();
|
||||
Point3F lightDir = light->getDirection();
|
||||
objTrans.mulP(lightPos);
|
||||
objTrans.mulV(lightDir);
|
||||
|
||||
xlatedLight.mPos = lightPos;
|
||||
xlatedLight.mDirection = lightDir;
|
||||
|
||||
GFX->setLight(0, &xlatedLight);
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::_setSecondaryLightInfo(const MatrixF &_objTrans, LightInfo* light)
|
||||
{
|
||||
// set object transform
|
||||
MatrixF objTrans = _objTrans;
|
||||
objTrans.inverse();
|
||||
|
||||
// fill in secondary light
|
||||
//-------------------------
|
||||
GFXLightInfo xlatedLight;
|
||||
light->setGFXLight(&xlatedLight);
|
||||
|
||||
Point3F lightPos = light->getPosition();
|
||||
Point3F lightDir = light->getDirection();
|
||||
objTrans.mulP(lightPos);
|
||||
objTrans.mulV(lightDir);
|
||||
|
||||
xlatedLight.mPos = lightPos;
|
||||
xlatedLight.mDirection = lightDir;
|
||||
|
||||
GFX->setLight(1, &xlatedLight);
|
||||
}
|
||||
|
||||
bool ProcessedFFMaterial::init( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
const MatFeaturesDelegate &featuresDelegate )
|
||||
{
|
||||
TORQUE_UNUSED( vertexFormat );
|
||||
TORQUE_UNUSED( featuresDelegate );
|
||||
|
||||
_setStageData();
|
||||
|
||||
// Just create a simple pass
|
||||
_createPasses(0, features);
|
||||
_initRenderPassDataStateBlocks();
|
||||
mStateHint.init( this );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::_addPass(U32 stageNum, FixedFuncFeatureData& featData)
|
||||
{
|
||||
U32 numTex = 0;
|
||||
|
||||
// Just creates a simple pass, but it can still glow!
|
||||
RenderPassData rpd;
|
||||
|
||||
// Base texture, texunit 0
|
||||
if(featData.features[FixedFuncFeatureData::DiffuseMap])
|
||||
{
|
||||
rpd.mTexSlot[0].texObject = mStages[stageNum].getTex( MFT_DiffuseMap );
|
||||
rpd.mTexType[0] = Material::NoTexture;
|
||||
numTex++;
|
||||
}
|
||||
|
||||
// lightmap, texunit 1
|
||||
if(featData.features[FixedFuncFeatureData::LightMap])
|
||||
{
|
||||
rpd.mTexType[1] = Material::Lightmap;
|
||||
numTex++;
|
||||
}
|
||||
|
||||
rpd.mNumTex = numTex;
|
||||
rpd.mStageNum = stageNum;
|
||||
rpd.mGlow = false;
|
||||
|
||||
mPasses.push_back( new RenderPassData(rpd) );
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::_setPassBlendOp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ProcessedFFMaterial::_initPassStateBlock( RenderPassData *rpd, GFXStateBlockDesc &result )
|
||||
{
|
||||
Parent::_initPassStateBlock( rpd, result );
|
||||
|
||||
if ( mIsLightingMaterial )
|
||||
{
|
||||
result.ffLighting = true;
|
||||
result.blendDefined = true;
|
||||
result.blendEnable = true;
|
||||
result.blendSrc = GFXBlendOne;
|
||||
result.blendSrc = GFXBlendOne;
|
||||
}
|
||||
|
||||
// This is here for generic FF shader fallbacks.
|
||||
CustomMaterial* custmat = dynamic_cast<CustomMaterial*>(mMaterial);
|
||||
if (custmat && custmat->getStateBlockData() )
|
||||
result.addDesc(custmat->getStateBlockData()->getState());
|
||||
}
|
||||
125
Engine/source/materials/processedFFMaterial.h
Normal file
125
Engine/source/materials/processedFFMaterial.h
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _MATERIALS_PROCESSEDFFMATERIAL_H_
|
||||
#define _MATERIALS_PROCESSEDFFMATERIAL_H_
|
||||
|
||||
#ifndef _MATERIALS_PROCESSEDMATERIAL_H_
|
||||
#include "materials/processedMaterial.h"
|
||||
#endif
|
||||
|
||||
class LightInfo;
|
||||
struct GFXShaderConstDesc;
|
||||
|
||||
|
||||
/// Fixed function rendering. Does not load or use shaders. Does not rely on GFXMaterialFeatureData.
|
||||
/// Tries very hard to not rely on anything possibly related to shaders.
|
||||
///
|
||||
/// @note Does not always succeed.
|
||||
class ProcessedFFMaterial : public ProcessedMaterial
|
||||
{
|
||||
typedef ProcessedMaterial Parent;
|
||||
public:
|
||||
ProcessedFFMaterial();
|
||||
ProcessedFFMaterial(Material &mat, const bool isLightingMaterial = false);
|
||||
~ProcessedFFMaterial();
|
||||
/// @name Render state setting
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Sets necessary textures and texture ops for rendering
|
||||
virtual void setTextureStages(SceneRenderState *, const SceneData &sgData, U32 pass );
|
||||
|
||||
virtual MaterialParameters* allocMaterialParameters();
|
||||
virtual MaterialParameterHandle* getMaterialParameterHandle(const String& name);
|
||||
virtual MaterialParameters* getDefaultMaterialParameters();
|
||||
|
||||
virtual void setTransforms(const MatrixSet &matrixSet, SceneRenderState *state, const U32 pass);
|
||||
|
||||
virtual void setSceneInfo(SceneRenderState *, const SceneData& sgData, U32 pass);
|
||||
|
||||
/// @}
|
||||
|
||||
virtual bool init( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
const MatFeaturesDelegate &featuresDelegate );
|
||||
|
||||
/// Sets up the given pass
|
||||
///
|
||||
/// @returns false if the pass could not be set up
|
||||
virtual bool setupPass(SceneRenderState *, const SceneData& sgData, U32 pass);
|
||||
|
||||
/// Returns the number of stages we're using (not to be confused with the number of passes)
|
||||
virtual U32 getNumStages();
|
||||
|
||||
protected:
|
||||
|
||||
MaterialParameterHandle* mDefaultHandle;
|
||||
MaterialParameters* mDefaultParameters;
|
||||
|
||||
struct FixedFuncFeatureData
|
||||
{
|
||||
enum
|
||||
{
|
||||
DiffuseMap,
|
||||
LightMap,
|
||||
ToneMap,
|
||||
NumFeatures
|
||||
};
|
||||
bool features[NumFeatures];
|
||||
};
|
||||
|
||||
bool mIsLightingMaterial;
|
||||
|
||||
Vector<GFXShaderConstDesc> mParamDesc;
|
||||
|
||||
/// @name Internal functions
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Adds a pass for the given stage
|
||||
virtual void _addPass(U32 stageNum, FixedFuncFeatureData& featData);
|
||||
|
||||
/// Chooses a blend op for the pass during pass creation
|
||||
virtual void _setPassBlendOp();
|
||||
|
||||
/// Creates all necessary passes for the given stage
|
||||
void _createPasses( U32 stageNum, const FeatureSet &features );
|
||||
|
||||
/// Determine what features we need
|
||||
void _determineFeatures( U32 stageNum,
|
||||
FixedFuncFeatureData &featData,
|
||||
const FeatureSet &features);
|
||||
|
||||
/// Sets light info for the first light
|
||||
virtual void _setPrimaryLightInfo(const MatrixF &objTrans, LightInfo* light, U32 pass);
|
||||
|
||||
/// Sets light info for the second light
|
||||
virtual void _setSecondaryLightInfo(const MatrixF &objTrans, LightInfo* light);
|
||||
|
||||
/// Does the base render state block setting, normally per pass
|
||||
virtual void _initPassStateBlock( RenderPassData *rpd, GFXStateBlockDesc &result );
|
||||
/// @}
|
||||
|
||||
void _construct();
|
||||
};
|
||||
|
||||
#endif
|
||||
480
Engine/source/materials/processedMaterial.cpp
Normal file
480
Engine/source/materials/processedMaterial.cpp
Normal file
|
|
@ -0,0 +1,480 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/processedMaterial.h"
|
||||
|
||||
#include "materials/sceneData.h"
|
||||
#include "materials/materialParameters.h"
|
||||
#include "materials/matTextureTarget.h"
|
||||
#include "materials/materialFeatureTypes.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "scene/sceneRenderState.h"
|
||||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#include "gfx/sim/cubemapData.h"
|
||||
|
||||
|
||||
RenderPassData::RenderPassData()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void RenderPassData::reset()
|
||||
{
|
||||
for( U32 i = 0; i < Material::MAX_TEX_PER_PASS; ++ i )
|
||||
destructInPlace( &mTexSlot[ i ] );
|
||||
|
||||
dMemset( &mTexSlot, 0, sizeof(mTexSlot) );
|
||||
dMemset( &mTexType, 0, sizeof(mTexType) );
|
||||
|
||||
mCubeMap = NULL;
|
||||
mNumTex = mNumTexReg = mStageNum = 0;
|
||||
mGlow = false;
|
||||
mBlendOp = Material::None;
|
||||
|
||||
mFeatureData.clear();
|
||||
|
||||
for (U32 i = 0; i < STATE_MAX; i++)
|
||||
mRenderStates[i] = NULL;
|
||||
}
|
||||
|
||||
String RenderPassData::describeSelf() const
|
||||
{
|
||||
String desc;
|
||||
|
||||
// Now write all the textures.
|
||||
String texName;
|
||||
for ( U32 i=0; i < Material::MAX_TEX_PER_PASS; i++ )
|
||||
{
|
||||
if ( mTexType[i] == Material::TexTarget )
|
||||
texName = ( mTexSlot[i].texTarget ) ? mTexSlot[i].texTarget->getName() : "null_texTarget";
|
||||
else if ( mTexType[i] == Material::Cube && mCubeMap )
|
||||
texName = mCubeMap->getPath();
|
||||
else if ( mTexSlot[i].texObject )
|
||||
texName = mTexSlot[i].texObject->getPath();
|
||||
else
|
||||
continue;
|
||||
|
||||
desc += String::ToString( "TexSlot %d: %d, %s\n", i, mTexType[i], texName.c_str() );
|
||||
}
|
||||
|
||||
// Write out the first render state which is the
|
||||
// basis for all the other states and shoud be
|
||||
// enough to define the pass uniquely.
|
||||
desc += mRenderStates[0]->getDesc().describeSelf();
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
ProcessedMaterial::ProcessedMaterial()
|
||||
: mMaterial( NULL ),
|
||||
mCurrentParams( NULL ),
|
||||
mHasSetStageData( false ),
|
||||
mHasGlow( false ),
|
||||
mMaxStages( 0 ),
|
||||
mVertexFormat( NULL ),
|
||||
mUserObject( NULL )
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mPasses );
|
||||
}
|
||||
|
||||
ProcessedMaterial::~ProcessedMaterial()
|
||||
{
|
||||
for_each( mPasses.begin(), mPasses.end(), delete_pointer() );
|
||||
}
|
||||
|
||||
void ProcessedMaterial::_setBlendState(Material::BlendOp blendOp, GFXStateBlockDesc& desc )
|
||||
{
|
||||
switch( blendOp )
|
||||
{
|
||||
case Material::Add:
|
||||
{
|
||||
desc.blendSrc = GFXBlendOne;
|
||||
desc.blendDest = GFXBlendOne;
|
||||
break;
|
||||
}
|
||||
case Material::AddAlpha:
|
||||
{
|
||||
desc.blendSrc = GFXBlendSrcAlpha;
|
||||
desc.blendDest = GFXBlendOne;
|
||||
break;
|
||||
}
|
||||
case Material::Mul:
|
||||
{
|
||||
desc.blendSrc = GFXBlendDestColor;
|
||||
desc.blendDest = GFXBlendZero;
|
||||
break;
|
||||
}
|
||||
case Material::LerpAlpha:
|
||||
{
|
||||
desc.blendSrc = GFXBlendSrcAlpha;
|
||||
desc.blendDest = GFXBlendInvSrcAlpha;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// default to LerpAlpha
|
||||
desc.blendSrc = GFXBlendSrcAlpha;
|
||||
desc.blendDest = GFXBlendInvSrcAlpha;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessedMaterial::setBuffers(GFXVertexBufferHandleBase* vertBuffer, GFXPrimitiveBufferHandle* primBuffer)
|
||||
{
|
||||
GFX->setVertexBuffer( *vertBuffer );
|
||||
GFX->setPrimitiveBuffer( *primBuffer );
|
||||
}
|
||||
|
||||
bool ProcessedMaterial::stepInstance()
|
||||
{
|
||||
AssertFatal( false, "ProcessedMaterial::stepInstance() - This type of material doesn't support instancing!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
String ProcessedMaterial::_getTexturePath(const String& filename)
|
||||
{
|
||||
// if '/', then path is specified, use it.
|
||||
if( filename.find('/') != String::NPos )
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
// otherwise, construct path
|
||||
return mMaterial->getPath() + filename;
|
||||
}
|
||||
|
||||
GFXTexHandle ProcessedMaterial::_createTexture( const char* filename, GFXTextureProfile *profile)
|
||||
{
|
||||
return GFXTexHandle( _getTexturePath(filename), profile, avar("%s() - NA (line %d)", __FUNCTION__, __LINE__) );
|
||||
}
|
||||
|
||||
void ProcessedMaterial::addStateBlockDesc(const GFXStateBlockDesc& sb)
|
||||
{
|
||||
mUserDefined = sb;
|
||||
}
|
||||
|
||||
void ProcessedMaterial::_initStateBlockTemplates(GFXStateBlockDesc& stateTranslucent, GFXStateBlockDesc& stateGlow, GFXStateBlockDesc& stateReflect)
|
||||
{
|
||||
// Translucency
|
||||
stateTranslucent.blendDefined = true;
|
||||
stateTranslucent.blendEnable = mMaterial->mTranslucentBlendOp != Material::None;
|
||||
_setBlendState(mMaterial->mTranslucentBlendOp, stateTranslucent);
|
||||
stateTranslucent.zDefined = true;
|
||||
stateTranslucent.zWriteEnable = mMaterial->mTranslucentZWrite;
|
||||
stateTranslucent.alphaDefined = true;
|
||||
stateTranslucent.alphaTestEnable = mMaterial->mAlphaTest;
|
||||
stateTranslucent.alphaTestRef = mMaterial->mAlphaRef;
|
||||
stateTranslucent.alphaTestFunc = GFXCmpGreaterEqual;
|
||||
stateTranslucent.samplersDefined = true;
|
||||
stateTranslucent.samplers[0].textureColorOp = GFXTOPModulate;
|
||||
stateTranslucent.samplers[0].alphaOp = GFXTOPModulate;
|
||||
stateTranslucent.samplers[0].alphaArg1 = GFXTATexture;
|
||||
stateTranslucent.samplers[0].alphaArg2 = GFXTADiffuse;
|
||||
|
||||
// Glow
|
||||
stateGlow.zDefined = true;
|
||||
stateGlow.zWriteEnable = false;
|
||||
|
||||
// Reflect
|
||||
stateReflect.cullDefined = true;
|
||||
stateReflect.cullMode = mMaterial->mDoubleSided ? GFXCullNone : GFXCullCW;
|
||||
}
|
||||
|
||||
void ProcessedMaterial::_initRenderPassDataStateBlocks()
|
||||
{
|
||||
for (U32 pass = 0; pass < mPasses.size(); pass++)
|
||||
_initRenderStateStateBlocks( mPasses[pass] );
|
||||
}
|
||||
|
||||
void ProcessedMaterial::_initPassStateBlock( RenderPassData *rpd, GFXStateBlockDesc &result )
|
||||
{
|
||||
if ( rpd->mBlendOp != Material::None )
|
||||
{
|
||||
result.blendDefined = true;
|
||||
result.blendEnable = true;
|
||||
_setBlendState( rpd->mBlendOp, result );
|
||||
}
|
||||
|
||||
if (mMaterial->isDoubleSided())
|
||||
{
|
||||
result.cullDefined = true;
|
||||
result.cullMode = GFXCullNone;
|
||||
}
|
||||
|
||||
if(mMaterial->mAlphaTest)
|
||||
{
|
||||
result.alphaDefined = true;
|
||||
result.alphaTestEnable = mMaterial->mAlphaTest;
|
||||
result.alphaTestRef = mMaterial->mAlphaRef;
|
||||
result.alphaTestFunc = GFXCmpGreaterEqual;
|
||||
}
|
||||
|
||||
result.samplersDefined = true;
|
||||
NamedTexTarget *texTarget;
|
||||
|
||||
U32 maxAnisotropy = 1;
|
||||
if ( mMaterial->mUseAnisotropic[ rpd->mStageNum ] )
|
||||
maxAnisotropy = MATMGR->getDefaultAnisotropy();
|
||||
|
||||
for( U32 i=0; i < rpd->mNumTex; i++ )
|
||||
{
|
||||
U32 currTexFlag = rpd->mTexType[i];
|
||||
|
||||
switch( currTexFlag )
|
||||
{
|
||||
default:
|
||||
{
|
||||
result.samplers[i].textureColorOp = GFXTOPModulate;
|
||||
result.samplers[i].addressModeU = GFXAddressWrap;
|
||||
result.samplers[i].addressModeV = GFXAddressWrap;
|
||||
|
||||
if ( maxAnisotropy > 1 )
|
||||
{
|
||||
result.samplers[i].minFilter = GFXTextureFilterAnisotropic;
|
||||
result.samplers[i].magFilter = GFXTextureFilterAnisotropic;
|
||||
result.samplers[i].maxAnisotropy = maxAnisotropy;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.samplers[i].minFilter = GFXTextureFilterLinear;
|
||||
result.samplers[i].magFilter = GFXTextureFilterLinear;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Material::Cube:
|
||||
case Material::SGCube:
|
||||
case Material::NormalizeCube:
|
||||
{
|
||||
result.samplers[i].addressModeU = GFXAddressClamp;
|
||||
result.samplers[i].addressModeV = GFXAddressClamp;
|
||||
result.samplers[i].addressModeW = GFXAddressClamp;
|
||||
break;
|
||||
}
|
||||
|
||||
case Material::TexTarget:
|
||||
{
|
||||
texTarget = mPasses[0]->mTexSlot[i].texTarget;
|
||||
if ( texTarget )
|
||||
texTarget->setupSamplerState( &result.samplers[i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The prepass will take care of writing to the
|
||||
// zbuffer, so we don't have to by default.
|
||||
// The prepass can't write to the backbuffer's zbuffer in OpenGL.
|
||||
if ( MATMGR->getPrePassEnabled() &&
|
||||
!GFX->getAdapterType() == OpenGL &&
|
||||
!mFeatures.hasFeature(MFT_ForwardShading))
|
||||
result.setZReadWrite( result.zEnable, false );
|
||||
|
||||
result.addDesc(mUserDefined);
|
||||
}
|
||||
|
||||
/// Creates the default state blocks for a list of render states
|
||||
void ProcessedMaterial::_initRenderStateStateBlocks( RenderPassData *rpd )
|
||||
{
|
||||
GFXStateBlockDesc stateTranslucent;
|
||||
GFXStateBlockDesc stateGlow;
|
||||
GFXStateBlockDesc stateReflect;
|
||||
GFXStateBlockDesc statePass;
|
||||
|
||||
_initStateBlockTemplates( stateTranslucent, stateGlow, stateReflect );
|
||||
_initPassStateBlock( rpd, statePass );
|
||||
|
||||
// Ok, we've got our templates set up, let's combine them together based on state and
|
||||
// create our state blocks.
|
||||
for (U32 i = 0; i < RenderPassData::STATE_MAX; i++)
|
||||
{
|
||||
GFXStateBlockDesc stateFinal;
|
||||
|
||||
if (i & RenderPassData::STATE_REFLECT)
|
||||
stateFinal.addDesc(stateReflect);
|
||||
if (i & RenderPassData::STATE_TRANSLUCENT)
|
||||
stateFinal.addDesc(stateTranslucent);
|
||||
if (i & RenderPassData::STATE_GLOW)
|
||||
stateFinal.addDesc(stateGlow);
|
||||
|
||||
stateFinal.addDesc(statePass);
|
||||
|
||||
if (i & RenderPassData::STATE_WIREFRAME)
|
||||
stateFinal.fillMode = GFXFillWireframe;
|
||||
|
||||
GFXStateBlockRef sb = GFX->createStateBlock(stateFinal);
|
||||
rpd->mRenderStates[i] = sb;
|
||||
}
|
||||
}
|
||||
|
||||
U32 ProcessedMaterial::_getRenderStateIndex( const SceneRenderState *sceneState,
|
||||
const SceneData &sgData )
|
||||
{
|
||||
// Based on what the state of the world is, get our render state block
|
||||
U32 currState = 0;
|
||||
|
||||
// NOTE: We should only use per-material or per-pass hints to
|
||||
// change the render state. This is importaint because we
|
||||
// only change the state blocks between material passes.
|
||||
//
|
||||
// For example sgData.visibility would be bad to use
|
||||
// in here without changing how RenderMeshMgr works.
|
||||
|
||||
if ( sgData.binType == SceneData::GlowBin )
|
||||
currState |= RenderPassData::STATE_GLOW;
|
||||
|
||||
if ( sceneState && sceneState->isReflectPass() )
|
||||
currState |= RenderPassData::STATE_REFLECT;
|
||||
|
||||
if ( sgData.binType != SceneData::PrePassBin &&
|
||||
mMaterial->isTranslucent() )
|
||||
currState |= RenderPassData::STATE_TRANSLUCENT;
|
||||
|
||||
if ( sgData.wireframe )
|
||||
currState |= RenderPassData::STATE_WIREFRAME;
|
||||
|
||||
return currState;
|
||||
}
|
||||
|
||||
void ProcessedMaterial::_setRenderState( const SceneRenderState *state,
|
||||
const SceneData& sgData,
|
||||
U32 pass )
|
||||
{
|
||||
// Make sure we have the pass
|
||||
if ( pass >= mPasses.size() )
|
||||
return;
|
||||
|
||||
U32 currState = _getRenderStateIndex( state, sgData );
|
||||
|
||||
GFX->setStateBlock(mPasses[pass]->mRenderStates[currState]);
|
||||
}
|
||||
|
||||
|
||||
void ProcessedMaterial::_setStageData()
|
||||
{
|
||||
// Only do this once
|
||||
if ( mHasSetStageData )
|
||||
return;
|
||||
mHasSetStageData = true;
|
||||
|
||||
U32 i;
|
||||
|
||||
// Load up all the textures for every possible stage
|
||||
for( i=0; i<Material::MAX_STAGES; i++ )
|
||||
{
|
||||
// DiffuseMap
|
||||
if( mMaterial->mDiffuseMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_DiffuseMap, _createTexture( mMaterial->mDiffuseMapFilename[i], &GFXDefaultStaticDiffuseProfile ) );
|
||||
if (!mStages[i].getTex( MFT_DiffuseMap ))
|
||||
{
|
||||
mMaterial->logError("Failed to load diffuse map %s for stage %i", _getTexturePath(mMaterial->mDiffuseMapFilename[i]).c_str(), i);
|
||||
|
||||
// Load a debug texture to make it clear to the user
|
||||
// that the texture for this stage was missing.
|
||||
mStages[i].setTex( MFT_DiffuseMap, _createTexture( "core/art/missingTexture", &GFXDefaultStaticDiffuseProfile ) );
|
||||
}
|
||||
}
|
||||
|
||||
// OverlayMap
|
||||
if( mMaterial->mOverlayMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_OverlayMap, _createTexture( mMaterial->mOverlayMapFilename[i], &GFXDefaultStaticDiffuseProfile ) );
|
||||
if(!mStages[i].getTex( MFT_OverlayMap ))
|
||||
mMaterial->logError("Failed to load overlay map %s for stage %i", _getTexturePath(mMaterial->mOverlayMapFilename[i]).c_str(), i);
|
||||
}
|
||||
|
||||
// LightMap
|
||||
if( mMaterial->mLightMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_LightMap, _createTexture( mMaterial->mLightMapFilename[i], &GFXDefaultStaticDiffuseProfile ) );
|
||||
if(!mStages[i].getTex( MFT_LightMap ))
|
||||
mMaterial->logError("Failed to load light map %s for stage %i", _getTexturePath(mMaterial->mLightMapFilename[i]).c_str(), i);
|
||||
}
|
||||
|
||||
// ToneMap
|
||||
if( mMaterial->mToneMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_ToneMap, _createTexture( mMaterial->mToneMapFilename[i], &GFXDefaultStaticDiffuseProfile ) );
|
||||
if(!mStages[i].getTex( MFT_ToneMap ))
|
||||
mMaterial->logError("Failed to load tone map %s for stage %i", _getTexturePath(mMaterial->mToneMapFilename[i]).c_str(), i);
|
||||
}
|
||||
|
||||
// DetailMap
|
||||
if( mMaterial->mDetailMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_DetailMap, _createTexture( mMaterial->mDetailMapFilename[i], &GFXDefaultStaticDiffuseProfile ) );
|
||||
if(!mStages[i].getTex( MFT_DetailMap ))
|
||||
mMaterial->logError("Failed to load detail map %s for stage %i", _getTexturePath(mMaterial->mDetailMapFilename[i]).c_str(), i);
|
||||
}
|
||||
|
||||
// NormalMap
|
||||
if( mMaterial->mNormalMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_NormalMap, _createTexture( mMaterial->mNormalMapFilename[i], &GFXDefaultStaticNormalMapProfile ) );
|
||||
if(!mStages[i].getTex( MFT_NormalMap ))
|
||||
mMaterial->logError("Failed to load normal map %s for stage %i", _getTexturePath(mMaterial->mNormalMapFilename[i]).c_str(), i);
|
||||
}
|
||||
|
||||
// Detail Normal Map
|
||||
if( mMaterial->mDetailNormalMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_DetailNormalMap, _createTexture( mMaterial->mDetailNormalMapFilename[i], &GFXDefaultStaticNormalMapProfile ) );
|
||||
if(!mStages[i].getTex( MFT_DetailNormalMap ))
|
||||
mMaterial->logError("Failed to load normal map %s for stage %i", _getTexturePath(mMaterial->mDetailNormalMapFilename[i]).c_str(), i);
|
||||
}
|
||||
|
||||
// SpecularMap
|
||||
if( mMaterial->mSpecularMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_SpecularMap, _createTexture( mMaterial->mSpecularMapFilename[i], &GFXDefaultStaticDiffuseProfile ) );
|
||||
if(!mStages[i].getTex( MFT_SpecularMap ))
|
||||
mMaterial->logError("Failed to load specular map %s for stage %i", _getTexturePath(mMaterial->mSpecularMapFilename[i]).c_str(), i);
|
||||
}
|
||||
|
||||
// EnironmentMap
|
||||
if( mMaterial->mEnvMapFilename[i].isNotEmpty() )
|
||||
{
|
||||
mStages[i].setTex( MFT_EnvMap, _createTexture( mMaterial->mEnvMapFilename[i], &GFXDefaultStaticDiffuseProfile ) );
|
||||
if(!mStages[i].getTex( MFT_EnvMap ))
|
||||
mMaterial->logError("Failed to load environment map %s for stage %i", _getTexturePath(mMaterial->mEnvMapFilename[i]).c_str(), i);
|
||||
}
|
||||
}
|
||||
|
||||
mMaterial->mCubemapData = dynamic_cast<CubemapData*>(Sim::findObject( mMaterial->mCubemapName ));
|
||||
if( !mMaterial->mCubemapData )
|
||||
mMaterial->mCubemapData = NULL;
|
||||
|
||||
|
||||
// If we have a cubemap put it on stage 0 (cubemaps only supported on stage 0)
|
||||
if( mMaterial->mCubemapData )
|
||||
{
|
||||
mMaterial->mCubemapData->createMap();
|
||||
mStages[0].setCubemap( mMaterial->mCubemapData->mCubemap );
|
||||
if ( !mStages[0].getCubemap() )
|
||||
mMaterial->logError("Failed to load cubemap");
|
||||
}
|
||||
}
|
||||
|
||||
306
Engine/source/materials/processedMaterial.h
Normal file
306
Engine/source/materials/processedMaterial.h
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATERIALS_PROCESSEDMATERIAL_H_
|
||||
#define _MATERIALS_PROCESSEDMATERIAL_H_
|
||||
|
||||
#ifndef _MATERIALDEFINITION_H_
|
||||
#include "materials/materialDefinition.h"
|
||||
#endif
|
||||
#ifndef _MATERIALFEATUREDATA_H_
|
||||
#include "materials/materialFeatureData.h"
|
||||
#endif
|
||||
#ifndef _GFXSTATEBLOCK_H_
|
||||
#include "gfx/gfxStateBlock.h"
|
||||
#endif
|
||||
#ifndef _MATTEXTURETARGET_H_
|
||||
#include "materials/matTextureTarget.h"
|
||||
#endif
|
||||
#ifndef _MATSTATEHINT_H_
|
||||
#include "materials/matStateHint.h"
|
||||
#endif
|
||||
|
||||
class ShaderFeature;
|
||||
class MaterialParameters;
|
||||
class MaterialParameterHandle;
|
||||
class SceneRenderState;
|
||||
class GFXVertexBufferHandleBase;
|
||||
class GFXPrimitiveBufferHandle;
|
||||
class MatrixSet;
|
||||
|
||||
|
||||
/// This contains the common data needed to render a pass.
|
||||
struct RenderPassData
|
||||
{
|
||||
public:
|
||||
|
||||
struct TexSlotT
|
||||
{
|
||||
/// This is the default type of texture which
|
||||
/// is valid with most texture types.
|
||||
/// @see mTexType
|
||||
GFXTexHandle texObject;
|
||||
|
||||
/// Only valid when the texture type is set
|
||||
/// to Material::TexTarget.
|
||||
/// @see mTexType
|
||||
NamedTexTargetRef texTarget;
|
||||
|
||||
} mTexSlot[Material::MAX_TEX_PER_PASS];
|
||||
|
||||
U32 mTexType[Material::MAX_TEX_PER_PASS];
|
||||
|
||||
/// The cubemap to use when the texture type is
|
||||
/// set to Material::Cube.
|
||||
/// @see mTexType
|
||||
GFXCubemap *mCubeMap;
|
||||
|
||||
U32 mNumTex;
|
||||
|
||||
U32 mNumTexReg;
|
||||
|
||||
MaterialFeatureData mFeatureData;
|
||||
|
||||
bool mGlow;
|
||||
|
||||
Material::BlendOp mBlendOp;
|
||||
|
||||
U32 mStageNum;
|
||||
|
||||
/// State permutations, used to index into
|
||||
/// the render states array.
|
||||
/// @see mRenderStates
|
||||
enum
|
||||
{
|
||||
STATE_REFLECT = 1,
|
||||
STATE_TRANSLUCENT = 2,
|
||||
STATE_GLOW = 4,
|
||||
STATE_WIREFRAME = 8,
|
||||
STATE_MAX = 16
|
||||
};
|
||||
|
||||
///
|
||||
GFXStateBlockRef mRenderStates[STATE_MAX];
|
||||
|
||||
RenderPassData();
|
||||
|
||||
virtual ~RenderPassData() { reset(); }
|
||||
|
||||
virtual void reset();
|
||||
|
||||
/// Creates and returns a unique description string.
|
||||
virtual String describeSelf() const;
|
||||
};
|
||||
|
||||
/// This is an abstract base class which provides the external
|
||||
/// interface all subclasses must implement. This interface
|
||||
/// primarily consists of setting state. Pass creation
|
||||
/// is implementation specific, and internal, thus it is
|
||||
/// not in this base class.
|
||||
class ProcessedMaterial
|
||||
{
|
||||
public:
|
||||
ProcessedMaterial();
|
||||
virtual ~ProcessedMaterial();
|
||||
|
||||
/// @name State setting functions
|
||||
///
|
||||
/// @{
|
||||
|
||||
///
|
||||
virtual void addStateBlockDesc(const GFXStateBlockDesc& sb);
|
||||
|
||||
///
|
||||
virtual void updateStateBlocks() { _initRenderPassDataStateBlocks(); }
|
||||
|
||||
/// Set the user defined shader macros.
|
||||
virtual void setShaderMacros( const Vector<GFXShaderMacro> ¯os ) { mUserMacros = macros; }
|
||||
|
||||
/// Sets the textures needed for rendering the current pass
|
||||
virtual void setTextureStages(SceneRenderState *, const SceneData &sgData, U32 pass ) = 0;
|
||||
|
||||
/// Sets the transformation matrix, i.e. Model * View * Projection
|
||||
virtual void setTransforms(const MatrixSet &matrixSet, SceneRenderState *state, const U32 pass) = 0;
|
||||
|
||||
/// Sets the scene info like lights for the given pass.
|
||||
virtual void setSceneInfo(SceneRenderState *, const SceneData& sgData, U32 pass) = 0;
|
||||
|
||||
/// Sets the given vertex and primitive buffers so we can render geometry
|
||||
virtual void setBuffers(GFXVertexBufferHandleBase* vertBuffer, GFXPrimitiveBufferHandle* primBuffer);
|
||||
|
||||
/// @see BaseMatInstance::setUserObject
|
||||
virtual void setUserObject( SimObject *userObject ) { mUserObject = userObject; }
|
||||
|
||||
///
|
||||
virtual bool stepInstance();
|
||||
|
||||
/// @}
|
||||
|
||||
/// Initializes us (eg. loads textures, creates passes, generates shaders)
|
||||
virtual bool init( const FeatureSet& features,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
const MatFeaturesDelegate &featuresDelegate ) = 0;
|
||||
|
||||
/// Returns the state hint which can be used for
|
||||
/// sorting and fast comparisions of the equality
|
||||
/// of a material instance.
|
||||
virtual const MatStateHint& getStateHint() const { return mStateHint; }
|
||||
|
||||
/// Sets up the given pass. Returns true if the pass was set up, false if there was an error or if
|
||||
/// the specified pass is out of bounds.
|
||||
virtual bool setupPass(SceneRenderState *, const SceneData& sgData, U32 pass) = 0;
|
||||
|
||||
// Material parameter methods
|
||||
virtual MaterialParameters* allocMaterialParameters() = 0;
|
||||
virtual MaterialParameters* getDefaultMaterialParameters() = 0;
|
||||
virtual void setMaterialParameters(MaterialParameters* param, S32 pass) { mCurrentParams = param; };
|
||||
virtual MaterialParameters* getMaterialParameters() { return mCurrentParams; }
|
||||
virtual MaterialParameterHandle* getMaterialParameterHandle(const String& name) = 0;
|
||||
|
||||
/// Returns the pass data for the given pass.
|
||||
RenderPassData* getPass(U32 pass)
|
||||
{
|
||||
if(pass >= mPasses.size())
|
||||
return NULL;
|
||||
return mPasses[pass];
|
||||
}
|
||||
|
||||
/// Returns the pass data for the given pass.
|
||||
const RenderPassData* getPass( U32 pass ) const { return mPasses[pass]; }
|
||||
|
||||
/// Returns the number of stages we're rendering (not to be confused with the number of passes).
|
||||
virtual U32 getNumStages() = 0;
|
||||
|
||||
/// Returns the number of passes we are rendering (not to be confused with the number of stages).
|
||||
U32 getNumPasses() const { return mPasses.size(); }
|
||||
|
||||
/// Returns true if any pass glows
|
||||
bool hasGlow() const { return mHasGlow; }
|
||||
|
||||
/// Gets the stage number for a pass
|
||||
U32 getStageFromPass(U32 pass) const
|
||||
{
|
||||
if(pass >= mPasses.size())
|
||||
return 0;
|
||||
return mPasses[pass]->mStageNum;
|
||||
}
|
||||
|
||||
/// Returns the active features in use by this material.
|
||||
/// @see BaseMatInstance::getFeatures
|
||||
const FeatureSet& getFeatures() const { return mFeatures; }
|
||||
|
||||
/// Dump shader info, or FF texture info?
|
||||
virtual void dumpMaterialInfo() { }
|
||||
|
||||
/// Returns the source material.
|
||||
Material* getMaterial() const { return mMaterial; }
|
||||
|
||||
/// Returns the texture used by a stage
|
||||
GFXTexHandle getStageTexture(U32 stage, const FeatureType &type)
|
||||
{
|
||||
return (stage < Material::MAX_STAGES) ? mStages[stage].getTex(type) : NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// Our passes.
|
||||
Vector<RenderPassData*> mPasses;
|
||||
|
||||
/// The active features in use by this material.
|
||||
FeatureSet mFeatures;
|
||||
|
||||
/// The material which we are processing.
|
||||
Material* mMaterial;
|
||||
|
||||
MaterialParameters* mCurrentParams;
|
||||
|
||||
/// Material::StageData is used here because the shader
|
||||
/// generator throws a fit if it's passed anything else.
|
||||
Material::StageData mStages[Material::MAX_STAGES];
|
||||
|
||||
/// If we've already loaded the stage data
|
||||
bool mHasSetStageData;
|
||||
|
||||
/// If we glow
|
||||
bool mHasGlow;
|
||||
|
||||
/// Number of stages (not to be confused with number of passes)
|
||||
U32 mMaxStages;
|
||||
|
||||
/// The vertex format on which this material will render.
|
||||
const GFXVertexFormat *mVertexFormat;
|
||||
|
||||
/// Set by addStateBlockDesc, should be considered
|
||||
/// when initPassStateBlock is called.
|
||||
GFXStateBlockDesc mUserDefined;
|
||||
|
||||
/// The user defined macros to pass to the
|
||||
/// shader initialization.
|
||||
Vector<GFXShaderMacro> mUserMacros;
|
||||
|
||||
/// The user defined object to pass to ShaderFeature::createConstHandles.
|
||||
SimObject *mUserObject;
|
||||
|
||||
/// The state hint used for material sorting
|
||||
/// and quick equality comparision.
|
||||
MatStateHint mStateHint;
|
||||
|
||||
/// Loads all the textures for all of the stages in the Material
|
||||
virtual void _setStageData();
|
||||
|
||||
/// Sets the blend state for rendering
|
||||
void _setBlendState(Material::BlendOp blendOp, GFXStateBlockDesc& desc );
|
||||
|
||||
/// Returns the path the material will attempt to load for a given texture filename.
|
||||
String _getTexturePath(const String& filename);
|
||||
|
||||
/// Loads the texture located at _getTexturePath(filename) and gives it the specified profile
|
||||
GFXTexHandle _createTexture( const char *filename, GFXTextureProfile *profile );
|
||||
|
||||
/// @name State blocks
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Creates the default state block templates, used by initStateBlocks.
|
||||
virtual void _initStateBlockTemplates(GFXStateBlockDesc& stateTranslucent, GFXStateBlockDesc& stateGlow, GFXStateBlockDesc& stateReflect);
|
||||
|
||||
/// Does the base render state block setting, normally per pass.
|
||||
virtual void _initPassStateBlock( RenderPassData *rpd, GFXStateBlockDesc& result);
|
||||
|
||||
/// Creates the default state blocks for a list of render states.
|
||||
virtual void _initRenderStateStateBlocks( RenderPassData *rpd );
|
||||
|
||||
/// Creates the default state blocks for each RenderPassData item.
|
||||
virtual void _initRenderPassDataStateBlocks();
|
||||
|
||||
/// This returns the index into the renderState array based on the sgData passed in.
|
||||
virtual U32 _getRenderStateIndex( const SceneRenderState *state,
|
||||
const SceneData &sgData );
|
||||
|
||||
/// Activates the correct mPasses[currPass].renderState based on scene graph info
|
||||
virtual void _setRenderState( const SceneRenderState *state,
|
||||
const SceneData &sgData,
|
||||
U32 pass );
|
||||
/// @
|
||||
};
|
||||
|
||||
#endif // _MATERIALS_PROCESSEDMATERIAL_H_
|
||||
1291
Engine/source/materials/processedShaderMaterial.cpp
Normal file
1291
Engine/source/materials/processedShaderMaterial.cpp
Normal file
File diff suppressed because it is too large
Load diff
262
Engine/source/materials/processedShaderMaterial.h
Normal file
262
Engine/source/materials/processedShaderMaterial.h
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MATERIALS_PROCESSEDSHADERMATERIAL_H_
|
||||
#define _MATERIALS_PROCESSEDSHADERMATERIAL_H_
|
||||
|
||||
#ifndef _MATERIALS_PROCESSEDMATERIAL_H_
|
||||
#include "processedMaterial.h"
|
||||
#endif
|
||||
#ifndef _GFXSHADER_H_
|
||||
#include "gfx/gfxShader.h"
|
||||
#endif
|
||||
|
||||
class GenericConstBufferLayout;
|
||||
class ShaderData;
|
||||
class LightInfo;
|
||||
class ShaderMaterialParameterHandle;
|
||||
class ShaderFeatureConstHandles;
|
||||
class CustomMaterial;
|
||||
|
||||
|
||||
class ShaderConstHandles
|
||||
{
|
||||
public:
|
||||
GFXShaderConstHandle* mDiffuseColorSC;
|
||||
GFXShaderConstHandle* mToneMapTexSC;
|
||||
GFXShaderConstHandle* mTexMatSC;
|
||||
GFXShaderConstHandle* mSpecularColorSC;
|
||||
GFXShaderConstHandle* mSpecularPowerSC;
|
||||
GFXShaderConstHandle* mParallaxInfoSC;
|
||||
GFXShaderConstHandle* mFogDataSC;
|
||||
GFXShaderConstHandle* mFogColorSC;
|
||||
GFXShaderConstHandle* mDetailScaleSC;
|
||||
GFXShaderConstHandle* mVisiblitySC;
|
||||
GFXShaderConstHandle* mColorMultiplySC;
|
||||
GFXShaderConstHandle* mAlphaTestValueSC;
|
||||
GFXShaderConstHandle* mModelViewProjSC;
|
||||
GFXShaderConstHandle* mWorldViewOnlySC;
|
||||
GFXShaderConstHandle* mWorldToCameraSC;
|
||||
GFXShaderConstHandle* mWorldToObjSC;
|
||||
GFXShaderConstHandle* mViewToObjSC;
|
||||
GFXShaderConstHandle* mCubeTransSC;
|
||||
GFXShaderConstHandle* mObjTransSC;
|
||||
GFXShaderConstHandle* mCubeEyePosSC;
|
||||
GFXShaderConstHandle* mEyePosSC;
|
||||
GFXShaderConstHandle* mEyePosWorldSC;
|
||||
GFXShaderConstHandle* m_vEyeSC;
|
||||
GFXShaderConstHandle* mEyeMatSC;
|
||||
GFXShaderConstHandle* mOneOverFarplane;
|
||||
GFXShaderConstHandle* mAccumTimeSC;
|
||||
GFXShaderConstHandle* mMinnaertConstantSC;
|
||||
GFXShaderConstHandle* mSubSurfaceParamsSC;
|
||||
GFXShaderConstHandle* mDiffuseAtlasParamsSC;
|
||||
GFXShaderConstHandle* mBumpAtlasParamsSC;
|
||||
GFXShaderConstHandle* mDiffuseAtlasTileSC;
|
||||
GFXShaderConstHandle* mBumpAtlasTileSC;
|
||||
GFXShaderConstHandle *mRTSizeSC;
|
||||
GFXShaderConstHandle *mOneOverRTSizeSC;
|
||||
GFXShaderConstHandle* mDetailBumpStrength;
|
||||
GFXShaderConstHandle* mViewProjSC;
|
||||
|
||||
GFXShaderConstHandle *mImposterUVs;
|
||||
GFXShaderConstHandle *mImposterLimits;
|
||||
|
||||
GFXShaderConstHandle* mTexHandlesSC[Material::MAX_TEX_PER_PASS];
|
||||
GFXShaderConstHandle* mRTParamsSC[TEXTURE_STAGE_COUNT];
|
||||
|
||||
void init( GFXShader* shader, CustomMaterial* mat = NULL );
|
||||
};
|
||||
|
||||
class ShaderRenderPassData : public RenderPassData
|
||||
{
|
||||
typedef RenderPassData Parent;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~ShaderRenderPassData() { reset(); }
|
||||
|
||||
GFXShaderRef shader;
|
||||
ShaderConstHandles shaderHandles;
|
||||
Vector<ShaderFeatureConstHandles*> featureShaderHandles;
|
||||
|
||||
virtual void reset();
|
||||
virtual String describeSelf() const;
|
||||
};
|
||||
|
||||
class ProcessedShaderMaterial : public ProcessedMaterial
|
||||
{
|
||||
typedef ProcessedMaterial Parent;
|
||||
public:
|
||||
|
||||
ProcessedShaderMaterial();
|
||||
ProcessedShaderMaterial(Material &mat);
|
||||
~ProcessedShaderMaterial();
|
||||
|
||||
// ProcessedMaterial
|
||||
virtual bool init( const FeatureSet &features,
|
||||
const GFXVertexFormat *vertexFormat,
|
||||
const MatFeaturesDelegate &featuresDelegate );
|
||||
virtual bool setupPass(SceneRenderState *, const SceneData& sgData, U32 pass);
|
||||
virtual void setTextureStages(SceneRenderState *, const SceneData &sgData, U32 pass );
|
||||
virtual void setTransforms(const MatrixSet &matrixSet, SceneRenderState *state, const U32 pass);
|
||||
virtual void setSceneInfo(SceneRenderState *, const SceneData& sgData, U32 pass);
|
||||
virtual void setBuffers(GFXVertexBufferHandleBase* vertBuffer, GFXPrimitiveBufferHandle* primBuffer);
|
||||
virtual bool stepInstance();
|
||||
virtual void dumpMaterialInfo();
|
||||
virtual MaterialParameters* allocMaterialParameters();
|
||||
virtual MaterialParameters* getDefaultMaterialParameters() { return mDefaultParameters; }
|
||||
virtual MaterialParameterHandle* getMaterialParameterHandle(const String& name);
|
||||
virtual U32 getNumStages();
|
||||
|
||||
protected:
|
||||
|
||||
Vector<GFXShaderConstDesc> mShaderConstDesc;
|
||||
MaterialParameters* mDefaultParameters;
|
||||
Vector<ShaderMaterialParameterHandle*> mParameterHandles;
|
||||
|
||||
/// Hold the instancing state data for the material.
|
||||
class InstancingState
|
||||
{
|
||||
const static U32 COUNT = 200;
|
||||
|
||||
public:
|
||||
|
||||
InstancingState()
|
||||
: mInstFormat( NULL ),
|
||||
mBuffer( NULL ),
|
||||
mCount( -1 )
|
||||
{
|
||||
}
|
||||
|
||||
~InstancingState()
|
||||
{
|
||||
delete [] mBuffer;
|
||||
}
|
||||
|
||||
void setFormat( const GFXVertexFormat *instFormat, const GFXVertexFormat *vertexFormat )
|
||||
{
|
||||
mInstFormat = instFormat;
|
||||
mDeclFormat.copy( *vertexFormat );
|
||||
mDeclFormat.append( *mInstFormat, 1 );
|
||||
mDeclFormat.getDecl();
|
||||
|
||||
delete [] mBuffer;
|
||||
mBuffer = new U8[ mInstFormat->getSizeInBytes() * COUNT ];
|
||||
mCount = -1;
|
||||
}
|
||||
|
||||
bool step( U8 **outPtr )
|
||||
{
|
||||
// Are we starting a new draw call?
|
||||
if ( mCount < 0 )
|
||||
{
|
||||
*outPtr = mBuffer;
|
||||
mCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Increment to the next instance.
|
||||
*outPtr += mInstFormat->getSizeInBytes();
|
||||
mCount++;
|
||||
}
|
||||
|
||||
return mCount < COUNT;
|
||||
}
|
||||
|
||||
void resetStep() { mCount = -1; }
|
||||
|
||||
U8* getBuffer() const { return mBuffer; }
|
||||
|
||||
S32 getCount() const { return mCount; }
|
||||
|
||||
const GFXVertexFormat* getFormat() const { return mInstFormat; }
|
||||
|
||||
const GFXVertexFormat* getDeclFormat() const { return &mDeclFormat; }
|
||||
|
||||
protected:
|
||||
|
||||
GFXVertexFormat mDeclFormat;
|
||||
const GFXVertexFormat *mInstFormat;
|
||||
U8 *mBuffer;
|
||||
S32 mCount;
|
||||
|
||||
};
|
||||
|
||||
/// The instancing state if this material
|
||||
/// supports instancing.
|
||||
InstancingState *mInstancingState;
|
||||
|
||||
/// @name Internal functions
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Adds a pass for the given stage.
|
||||
virtual bool _addPass( ShaderRenderPassData &rpd,
|
||||
U32 &texIndex,
|
||||
MaterialFeatureData &fd,
|
||||
U32 stageNum,
|
||||
const FeatureSet &features);
|
||||
|
||||
/// Chooses a blend op for the given pass
|
||||
virtual void _setPassBlendOp( ShaderFeature *sf,
|
||||
ShaderRenderPassData &passData,
|
||||
U32 &texIndex,
|
||||
MaterialFeatureData &stageFeatures,
|
||||
U32 stageNum,
|
||||
const FeatureSet &features);
|
||||
|
||||
/// Creates passes for the given stage
|
||||
virtual bool _createPasses( MaterialFeatureData &fd, U32 stageNum, const FeatureSet &features );
|
||||
|
||||
/// Fills in the MaterialFeatureData for the given stage
|
||||
virtual void _determineFeatures( U32 stageNum,
|
||||
MaterialFeatureData &fd,
|
||||
const FeatureSet &features );
|
||||
|
||||
/// Do we have a cubemap on pass?
|
||||
virtual bool _hasCubemap(U32 pass);
|
||||
|
||||
/// Used by setTextureTransforms
|
||||
F32 _getWaveOffset( U32 stage );
|
||||
|
||||
/// Sets texture transformation matrices for texture animations such as scale and wave
|
||||
virtual void _setTextureTransforms(const U32 pass);
|
||||
|
||||
/// Sets all of the necessary shader constants for the given pass
|
||||
virtual void _setShaderConstants(SceneRenderState *, const SceneData &sgData, U32 pass);
|
||||
|
||||
/// @}
|
||||
|
||||
void _setPrimaryLightConst(const LightInfo* light, const MatrixF& objTrans, const U32 stageNum);
|
||||
|
||||
/// This is here to deal with the differences between ProcessedCustomMaterials and ProcessedShaderMaterials.
|
||||
virtual GFXShaderConstBuffer* _getShaderConstBuffer(const U32 pass);
|
||||
virtual ShaderConstHandles* _getShaderConstHandles(const U32 pass);
|
||||
|
||||
///
|
||||
virtual void _initMaterialParameters();
|
||||
|
||||
ShaderRenderPassData* _getRPD(const U32 pass) { return static_cast<ShaderRenderPassData*>(mPasses[pass]); }
|
||||
};
|
||||
|
||||
#endif // _MATERIALS_PROCESSEDSHADERMATERIAL_H_
|
||||
128
Engine/source/materials/sceneData.h
Normal file
128
Engine/source/materials/sceneData.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _SCENEDATA_H_
|
||||
#define _SCENEDATA_H_
|
||||
|
||||
#ifndef _SCENERENDERSTATE_H_
|
||||
#include "scene/sceneRenderState.h"
|
||||
#endif
|
||||
#ifndef _LIGHTMANAGER_H_
|
||||
#include "lighting/lightManager.h"
|
||||
#endif
|
||||
#ifndef _GFXDEVICE_H_
|
||||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
|
||||
class GFXTexHandle;
|
||||
class GFXCubemap;
|
||||
|
||||
|
||||
struct SceneData
|
||||
{
|
||||
/// The special bin types.
|
||||
enum BinType
|
||||
{
|
||||
/// A normal render bin that isn't one of
|
||||
/// the special bins we care about.
|
||||
RegularBin = 0,
|
||||
|
||||
/// The glow render bin.
|
||||
/// @see RenderGlowMgr
|
||||
GlowBin,
|
||||
|
||||
/// The prepass render bin.
|
||||
/// @RenderPrePassMgr
|
||||
PrePassBin,
|
||||
};
|
||||
|
||||
/// This defines when we're rendering a special bin
|
||||
/// type that the material or lighting system needs
|
||||
/// to know about.
|
||||
BinType binType;
|
||||
|
||||
// textures
|
||||
GFXTextureObject *lightmap;
|
||||
GFXTextureObject *backBuffTex;
|
||||
GFXTextureObject *reflectTex;
|
||||
GFXTextureObject *miscTex;
|
||||
|
||||
/// The current lights to use in rendering
|
||||
/// in order of the light importance.
|
||||
LightInfo* lights[8];
|
||||
|
||||
///
|
||||
ColorF ambientLightColor;
|
||||
|
||||
// fog
|
||||
F32 fogDensity;
|
||||
F32 fogDensityOffset;
|
||||
F32 fogHeightFalloff;
|
||||
ColorF fogColor;
|
||||
|
||||
// misc
|
||||
const MatrixF *objTrans;
|
||||
GFXCubemap *cubemap;
|
||||
F32 visibility;
|
||||
|
||||
/// Enables wireframe rendering for the object.
|
||||
bool wireframe;
|
||||
|
||||
/// A generic hint value passed from the game
|
||||
/// code down to the material for use by shader
|
||||
/// features.
|
||||
void *materialHint;
|
||||
|
||||
/// Constructor.
|
||||
SceneData()
|
||||
{
|
||||
dMemset( this, 0, sizeof( SceneData ) );
|
||||
objTrans = &MatrixF::Identity;
|
||||
visibility = 1.0f;
|
||||
}
|
||||
|
||||
/// Initializes the data with the scene state setting
|
||||
/// common scene wide parameters.
|
||||
inline void init( const SceneRenderState *state, BinType type = RegularBin )
|
||||
{
|
||||
dMemset( this, 0, sizeof( SceneData ) );
|
||||
setFogParams( state->getSceneManager()->getFogData() );
|
||||
wireframe = GFXDevice::getWireframe();
|
||||
binType = type;
|
||||
objTrans = &MatrixF::Identity;
|
||||
visibility = 1.0f;
|
||||
ambientLightColor = state->getAmbientLightColor();
|
||||
}
|
||||
|
||||
inline void setFogParams( const FogData &data )
|
||||
{
|
||||
fogDensity = data.density;
|
||||
fogDensityOffset = data.densityOffset;
|
||||
if ( !mIsZero( data.atmosphereHeight ) )
|
||||
fogHeightFalloff = 1.0f / data.atmosphereHeight;
|
||||
else
|
||||
fogHeightFalloff = 0.0f;
|
||||
|
||||
fogColor = data.color;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _SCENEDATA_H_
|
||||
282
Engine/source/materials/shaderData.cpp
Normal file
282
Engine/source/materials/shaderData.cpp
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/shaderData.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "core/strings/stringUnit.h"
|
||||
#include "lighting/lightManager.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
using namespace Torque;
|
||||
|
||||
|
||||
Vector<ShaderData*> ShaderData::smAllShaderData;
|
||||
|
||||
|
||||
IMPLEMENT_CONOBJECT( ShaderData );
|
||||
|
||||
ConsoleDocClass( ShaderData,
|
||||
"@brief Special type of data block that stores information about a handwritten shader.\n\n"
|
||||
|
||||
"To use hand written shaders, a ShaderData datablock must be used. This datablock "
|
||||
"refers only to the vertex and pixel shader filenames and a hardware target level. "
|
||||
"Shaders are API specific, so DirectX and OpenGL shaders must be explicitly identified.\n\n "
|
||||
|
||||
"@tsexample\n"
|
||||
"// Used for the procedural clould system\n"
|
||||
"singleton ShaderData( CloudLayerShader )\n"
|
||||
"{\n"
|
||||
" DXVertexShaderFile = \"shaders/common/cloudLayerV.hlsl\";\n"
|
||||
" DXPixelShaderFile = \"shaders/common/cloudLayerP.hlsl\";\n"
|
||||
" OGLVertexShaderFile = \"shaders/common/gl/cloudLayerV.glsl\";\n"
|
||||
" OGLPixelShaderFile = \"shaders/common/gl/cloudLayerP.glsl\";\n"
|
||||
" pixVersion = 2.0;\n"
|
||||
"};\n"
|
||||
"@endtsexample\n\n"
|
||||
|
||||
"@ingroup Shaders\n");
|
||||
|
||||
ShaderData::ShaderData()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mShaderMacros );
|
||||
|
||||
mUseDevicePixVersion = false;
|
||||
mPixVersion = 1.0;
|
||||
}
|
||||
|
||||
void ShaderData::initPersistFields()
|
||||
{
|
||||
addField("DXVertexShaderFile", TypeStringFilename, Offset(mDXVertexShaderName, ShaderData),
|
||||
"@brief %Path to the DirectX vertex shader file to use for this ShaderData.\n\n"
|
||||
"It must contain only one program and no pixel shader, just the vertex shader."
|
||||
"It can be either an HLSL or assembly level shader. HLSL's must have a "
|
||||
"filename extension of .hlsl, otherwise its assumed to be an assembly file.");
|
||||
|
||||
addField("DXPixelShaderFile", TypeStringFilename, Offset(mDXPixelShaderName, ShaderData),
|
||||
"@brief %Path to the DirectX pixel shader file to use for this ShaderData.\n\n"
|
||||
"It must contain only one program and no vertex shader, just the pixel "
|
||||
"shader. It can be either an HLSL or assembly level shader. HLSL's "
|
||||
"must have a filename extension of .hlsl, otherwise its assumed to be an assembly file.");
|
||||
|
||||
addField("OGLVertexShaderFile", TypeStringFilename, Offset(mOGLVertexShaderName, ShaderData),
|
||||
"@brief %Path to an OpenGL vertex shader file to use for this ShaderData.\n\n"
|
||||
"It must contain only one program and no pixel shader, just the vertex shader.");
|
||||
|
||||
addField("OGLPixelShaderFile", TypeStringFilename, Offset(mOGLPixelShaderName, ShaderData),
|
||||
"@brief %Path to an OpenGL pixel shader file to use for this ShaderData.\n\n"
|
||||
"It must contain only one program and no vertex shader, just the pixel "
|
||||
"shader.");
|
||||
|
||||
addField("useDevicePixVersion", TypeBool, Offset(mUseDevicePixVersion, ShaderData),
|
||||
"@brief If true, the maximum pixel shader version offered by the graphics card will be used.\n\n"
|
||||
"Otherwise, the script-defined pixel shader version will be used.\n\n");
|
||||
|
||||
addField("pixVersion", TypeF32, Offset(mPixVersion, ShaderData),
|
||||
"@brief Indicates target level the shader should be compiled.\n\n"
|
||||
"Valid numbers at the time of this writing are 1.1, 1.4, 2.0, and 3.0. "
|
||||
"The shader will not run properly if the hardware does not support the "
|
||||
"level of shader compiled.");
|
||||
|
||||
addField("defines", TypeRealString, Offset(mDefines, ShaderData),
|
||||
"@brief String of case-sensitive defines passed to the shader compiler.\n\n"
|
||||
"The string should be delimited by a semicolon, tab, or newline character."
|
||||
|
||||
"@tsexample\n"
|
||||
"singleton ShaderData( FlashShader )\n"
|
||||
"{\n"
|
||||
"DXVertexShaderFile = \"shaders/common/postFx/flashV.hlsl\";\n"
|
||||
"DXPixelShaderFile = \"shaders/common/postFx/flashP.hlsl\";\n\n"
|
||||
" //Define setting the color of WHITE_COLOR.\n"
|
||||
"defines = \"WHITE_COLOR=float4(1.0,1.0,1.0,0.0)\";\n\n"
|
||||
"pixVersion = 2.0\n"
|
||||
"}\n"
|
||||
"@endtsexample\n\n"
|
||||
);
|
||||
|
||||
Parent::initPersistFields();
|
||||
|
||||
// Make sure we get activation signals.
|
||||
LightManager::smActivateSignal.notify( &ShaderData::_onLMActivate );
|
||||
}
|
||||
|
||||
bool ShaderData::onAdd()
|
||||
{
|
||||
if( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
mShaderMacros.clear();
|
||||
|
||||
// Keep track of it.
|
||||
smAllShaderData.push_back( this );
|
||||
|
||||
// NOTE: We initialize the shader on request.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShaderData::onRemove()
|
||||
{
|
||||
// Remove it from the all shaders list.
|
||||
smAllShaderData.remove( this );
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
const Vector<GFXShaderMacro>& ShaderData::_getMacros()
|
||||
{
|
||||
// If they have already been processed then
|
||||
// return the cached result.
|
||||
if ( mShaderMacros.size() != 0 || mDefines.isEmpty() )
|
||||
return mShaderMacros;
|
||||
|
||||
mShaderMacros.clear();
|
||||
GFXShaderMacro macro;
|
||||
const U32 defineCount = StringUnit::getUnitCount( mDefines, ";\n\t" );
|
||||
for ( U32 i=0; i < defineCount; i++ )
|
||||
{
|
||||
String define = StringUnit::getUnit( mDefines, i, ";\n\t" );
|
||||
|
||||
macro.name = StringUnit::getUnit( define, 0, "=" );
|
||||
macro.value = StringUnit::getUnit( define, 1, "=" );
|
||||
mShaderMacros.push_back( macro );
|
||||
}
|
||||
|
||||
return mShaderMacros;
|
||||
}
|
||||
|
||||
GFXShader* ShaderData::getShader( const Vector<GFXShaderMacro> ¯os )
|
||||
{
|
||||
PROFILE_SCOPE( ShaderData_GetShader );
|
||||
|
||||
// Combine the dynamic macros with our script defined macros.
|
||||
Vector<GFXShaderMacro> finalMacros;
|
||||
finalMacros.merge( _getMacros() );
|
||||
finalMacros.merge( macros );
|
||||
|
||||
// Convert the final macro list to a string.
|
||||
String cacheKey;
|
||||
GFXShaderMacro::stringize( macros, &cacheKey );
|
||||
|
||||
// Lookup the shader for this instance.
|
||||
ShaderCache::Iterator iter = mShaders.find( cacheKey );
|
||||
if ( iter != mShaders.end() )
|
||||
return iter->value;
|
||||
|
||||
// Create the shader instance... if it fails then
|
||||
// bail out and return nothing to the caller.
|
||||
GFXShader *shader = _createShader( finalMacros );
|
||||
if ( !shader )
|
||||
return NULL;
|
||||
|
||||
// Store the shader in the cache and return it.
|
||||
mShaders.insertUnique( cacheKey, shader );
|
||||
return shader;
|
||||
}
|
||||
|
||||
GFXShader* ShaderData::_createShader( const Vector<GFXShaderMacro> ¯os )
|
||||
{
|
||||
F32 pixver = mPixVersion;
|
||||
if ( mUseDevicePixVersion )
|
||||
pixver = getMax( pixver, GFX->getPixelShaderVersion() );
|
||||
|
||||
// Enable shader error logging.
|
||||
GFXShader::setLogging( true, true );
|
||||
|
||||
GFXShader *shader = GFX->createShader();
|
||||
bool success = false;
|
||||
|
||||
// Initialize the right shader type.
|
||||
switch( GFX->getAdapterType() )
|
||||
{
|
||||
case Direct3D9_360:
|
||||
case Direct3D9:
|
||||
{
|
||||
success = shader->init( mDXVertexShaderName,
|
||||
mDXPixelShaderName,
|
||||
pixver,
|
||||
macros );
|
||||
break;
|
||||
}
|
||||
|
||||
case OpenGL:
|
||||
{
|
||||
success = shader->init( mOGLVertexShaderName,
|
||||
mOGLPixelShaderName,
|
||||
pixver,
|
||||
macros );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Other device types are assumed to not support shaders.
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we failed to load the shader then
|
||||
// cleanup and return NULL.
|
||||
if ( !success )
|
||||
SAFE_DELETE( shader );
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void ShaderData::reloadShaders()
|
||||
{
|
||||
ShaderCache::Iterator iter = mShaders.begin();
|
||||
for ( ; iter != mShaders.end(); iter++ )
|
||||
iter->value->reload();
|
||||
}
|
||||
|
||||
void ShaderData::reloadAllShaders()
|
||||
{
|
||||
Vector<ShaderData*>::iterator iter = smAllShaderData.begin();
|
||||
for ( ; iter != smAllShaderData.end(); iter++ )
|
||||
(*iter)->reloadShaders();
|
||||
}
|
||||
|
||||
void ShaderData::_onLMActivate( const char *lm, bool activate )
|
||||
{
|
||||
// Only on activations do we do anything.
|
||||
if ( !activate )
|
||||
return;
|
||||
|
||||
// Since the light manager usually swaps shadergen features
|
||||
// and changes system wide shader defines we need to completely
|
||||
// flush and rebuild all shaders.
|
||||
|
||||
reloadAllShaders();
|
||||
}
|
||||
|
||||
DefineEngineMethod( ShaderData, reload, void, (),,
|
||||
"@brief Rebuilds all the vertex and pixel shader instances created from this ShaderData.\n\n"
|
||||
|
||||
"@tsexample\n"
|
||||
"// Rebuild the shader instances from ShaderData CloudLayerShader\n"
|
||||
"CloudLayerShader.reload();\n"
|
||||
"@endtsexample\n\n")
|
||||
{
|
||||
object->reloadShaders();
|
||||
}
|
||||
122
Engine/source/materials/shaderData.h
Normal file
122
Engine/source/materials/shaderData.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef _SHADERTDATA_H_
|
||||
#define _SHADERTDATA_H_
|
||||
|
||||
#ifndef _SIMOBJECT_H_
|
||||
#include "console/simObject.h"
|
||||
#endif
|
||||
#ifndef _GFXSHADER_H_
|
||||
#include "gfx/gfxShader.h"
|
||||
#endif
|
||||
#ifndef _TDICTIONARY_H_
|
||||
#include "core/util/tDictionary.h"
|
||||
#endif
|
||||
|
||||
class GFXShader;
|
||||
class ShaderData;
|
||||
struct GFXShaderMacro;
|
||||
|
||||
|
||||
///
|
||||
class ShaderData : public SimObject
|
||||
{
|
||||
typedef SimObject Parent;
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
static Vector<ShaderData*> smAllShaderData;
|
||||
|
||||
typedef HashTable<String,GFXShaderRef> ShaderCache;
|
||||
|
||||
ShaderCache mShaders;
|
||||
|
||||
bool mUseDevicePixVersion;
|
||||
|
||||
F32 mPixVersion;
|
||||
|
||||
FileName mDXVertexShaderName;
|
||||
|
||||
FileName mDXPixelShaderName;
|
||||
|
||||
FileName mOGLVertexShaderName;
|
||||
|
||||
FileName mOGLPixelShaderName;
|
||||
|
||||
/// A semicolon, tab, or newline delimited string of case
|
||||
/// sensitive defines that are passed to the shader compiler.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// SAMPLE_TAPS=10;USE_TEXKILL;USE_TORQUE_FOG=1
|
||||
///
|
||||
String mDefines;
|
||||
|
||||
/// The shader macros built from mDefines.
|
||||
/// @see _getMacros()
|
||||
Vector<GFXShaderMacro> mShaderMacros;
|
||||
|
||||
/// Returns the shader macros taking care to rebuild
|
||||
/// them if the content has changed.
|
||||
const Vector<GFXShaderMacro>& _getMacros();
|
||||
|
||||
/// Helper for converting an array of macros
|
||||
/// into a formatted string.
|
||||
void _stringizeMacros( const Vector<GFXShaderMacro> ¯os,
|
||||
String *outString );
|
||||
|
||||
/// Creates a new shader returning NULL on error.
|
||||
GFXShader* _createShader( const Vector<GFXShaderMacro> ¯os );
|
||||
|
||||
/// @see LightManager::smActivateSignal
|
||||
static void _onLMActivate( const char *lm, bool activate );
|
||||
|
||||
public:
|
||||
|
||||
|
||||
ShaderData();
|
||||
|
||||
/// Returns an initialized shader instance or NULL
|
||||
/// if the shader failed to be created.
|
||||
GFXShader* getShader( const Vector<GFXShaderMacro> ¯os = Vector<GFXShaderMacro>() );
|
||||
|
||||
/// Forces a reinitialization of all the instanced shaders.
|
||||
void reloadShaders();
|
||||
|
||||
/// Forces a reinitialization of the instanced shaders for
|
||||
/// all loaded ShaderData objects in the system.
|
||||
static void reloadAllShaders();
|
||||
|
||||
/// Returns the required pixel shader version for this shader.
|
||||
F32 getPixVersion() const { return mPixVersion; }
|
||||
|
||||
// SimObject
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
|
||||
// ConsoleObject
|
||||
static void initPersistFields();
|
||||
DECLARE_CONOBJECT(ShaderData);
|
||||
};
|
||||
|
||||
#endif // _SHADERTDATA_H_
|
||||
229
Engine/source/materials/shaderMaterialParameters.cpp
Normal file
229
Engine/source/materials/shaderMaterialParameters.cpp
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "materials/shaderMaterialParameters.h"
|
||||
|
||||
#include "console/console.h"
|
||||
|
||||
//
|
||||
// ShaderMaterialParameters
|
||||
//
|
||||
ShaderMaterialParameterHandle::ShaderMaterialParameterHandle(const String& name)
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mHandles );
|
||||
|
||||
mName = name;
|
||||
}
|
||||
|
||||
ShaderMaterialParameterHandle::ShaderMaterialParameterHandle(const String& name, Vector<GFXShader*>& shaders)
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mHandles );
|
||||
|
||||
mName = name;
|
||||
mHandles.setSize(shaders.size());
|
||||
|
||||
for (U32 i = 0; i < shaders.size(); i++)
|
||||
mHandles[i] = shaders[i]->getShaderConstHandle(name);
|
||||
}
|
||||
|
||||
ShaderMaterialParameterHandle::~ShaderMaterialParameterHandle()
|
||||
{
|
||||
}
|
||||
|
||||
S32 ShaderMaterialParameterHandle::getSamplerRegister( U32 pass ) const
|
||||
{
|
||||
AssertFatal( mHandles.size() > pass, "ShaderMaterialParameterHandle::getSamplerRegister - out of bounds" );
|
||||
return mHandles[pass]->getSamplerRegister();
|
||||
}
|
||||
|
||||
//
|
||||
// ShaderMaterialParameters
|
||||
//
|
||||
ShaderMaterialParameters::ShaderMaterialParameters()
|
||||
: MaterialParameters()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mBuffers );
|
||||
}
|
||||
|
||||
ShaderMaterialParameters::~ShaderMaterialParameters()
|
||||
{
|
||||
releaseBuffers();
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::setBuffers(Vector<GFXShaderConstDesc>& constDesc, Vector<GFXShaderConstBufferRef>& buffers)
|
||||
{
|
||||
mShaderConstDesc = constDesc;
|
||||
mBuffers = buffers;
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::releaseBuffers()
|
||||
{
|
||||
for (U32 i = 0; i < mBuffers.size(); i++)
|
||||
{
|
||||
mBuffers[i] = NULL;
|
||||
}
|
||||
mBuffers.setSize(0);
|
||||
}
|
||||
|
||||
U32 ShaderMaterialParameters::getAlignmentValue(const GFXShaderConstType constType)
|
||||
{
|
||||
if (mBuffers.size() > 0)
|
||||
return mBuffers[0]->getShader()->getAlignmentValue(constType);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define SHADERMATPARAM_SET(handle, f) \
|
||||
AssertFatal(handle, "Handle is NULL!" ); \
|
||||
AssertFatal(handle->isValid(), "Handle is not valid!" ); \
|
||||
AssertFatal(dynamic_cast<ShaderMaterialParameterHandle*>(handle), "Invalid handle type!"); \
|
||||
ShaderMaterialParameterHandle* h = static_cast<ShaderMaterialParameterHandle*>(handle); \
|
||||
AssertFatal(h->mHandles.size() == mBuffers.size(), "Handle length differs from buffer length!"); \
|
||||
for (U32 i = 0; i < h->mHandles.size(); i++) \
|
||||
{ \
|
||||
GFXShaderConstHandle* shaderHandle = h->mHandles[i]; \
|
||||
if (shaderHandle->isValid()) \
|
||||
mBuffers[i]->set(shaderHandle, f); \
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const F32 f)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, f);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const Point2F& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const Point3F& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const Point4F& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const PlaneF& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const ColorF& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const S32 f)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, f);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const Point2I& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const Point3I& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const Point4I& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const AlignedArray<F32>& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point2F>& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point3F>& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point4F>& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const AlignedArray<S32>& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point2I>& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point3I>& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const AlignedArray<Point4I>& fv)
|
||||
{
|
||||
SHADERMATPARAM_SET(handle, fv);
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType)
|
||||
{
|
||||
if ((!handle) || !handle->isValid())
|
||||
return;
|
||||
AssertFatal(dynamic_cast<ShaderMaterialParameterHandle*>(handle), "Invalid handle type!");
|
||||
ShaderMaterialParameterHandle* h = static_cast<ShaderMaterialParameterHandle*>(handle);
|
||||
AssertFatal(h->mHandles.size() == mBuffers.size(), "Handle length differs from buffer length!");
|
||||
for (U32 i = 0; i < h->mHandles.size(); i++)
|
||||
{
|
||||
GFXShaderConstHandle* shaderHandle = h->mHandles[i];
|
||||
if (shaderHandle && shaderHandle->isValid())
|
||||
mBuffers[i]->set(shaderHandle, mat, matrixType);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderMaterialParameters::set(MaterialParameterHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType)
|
||||
{
|
||||
if ((!handle) || !handle->isValid())
|
||||
return;
|
||||
AssertFatal(dynamic_cast<ShaderMaterialParameterHandle*>(handle), "Invalid handle type!");
|
||||
ShaderMaterialParameterHandle* h = static_cast<ShaderMaterialParameterHandle*>(handle);
|
||||
AssertFatal(h->mHandles.size() == mBuffers.size(), "Handle length differs from buffer length!");
|
||||
for (U32 i = 0; i < h->mHandles.size(); i++)
|
||||
{
|
||||
GFXShaderConstHandle* shaderHandle = h->mHandles[i];
|
||||
if (shaderHandle && shaderHandle->isValid())
|
||||
mBuffers[i]->set(shaderHandle, mat, arraySize, matrixType);
|
||||
}
|
||||
}
|
||||
|
||||
#undef SHADERMATPARAM_SET
|
||||
100
Engine/source/materials/shaderMaterialParameters.h
Normal file
100
Engine/source/materials/shaderMaterialParameters.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SHADERMATERIALPARAMETERS_H_
|
||||
#define _SHADERMATERIALPARAMETERS_H_
|
||||
|
||||
#ifndef _MATERIALPARAMETERS_H_
|
||||
#include "materials/materialParameters.h"
|
||||
#endif
|
||||
#ifndef _GFXSHADER_H_
|
||||
#include "gfx/gfxShader.h"
|
||||
#endif
|
||||
|
||||
|
||||
class ShaderMaterialParameterHandle : public MaterialParameterHandle
|
||||
{
|
||||
friend class ShaderMaterialParameters;
|
||||
public:
|
||||
virtual ~ShaderMaterialParameterHandle();
|
||||
|
||||
ShaderMaterialParameterHandle(const String& name);
|
||||
ShaderMaterialParameterHandle(const String& name, Vector<GFXShader*>& shaders);
|
||||
|
||||
virtual const String& getName() const { return mName; }
|
||||
virtual S32 getSamplerRegister( U32 pass ) const;
|
||||
|
||||
// NOTE: We always return true here instead of querying the
|
||||
// children... often there is only one element, so lets just
|
||||
// hit the loop once on the set.
|
||||
virtual bool isValid() const { return true; };
|
||||
|
||||
protected:
|
||||
Vector< GFXShaderConstHandle* > mHandles;
|
||||
String mName;
|
||||
};
|
||||
|
||||
// This is the union of all of the shaders contained in a material
|
||||
class ShaderMaterialParameters : public MaterialParameters
|
||||
{
|
||||
public:
|
||||
ShaderMaterialParameters();
|
||||
virtual ~ShaderMaterialParameters();
|
||||
|
||||
void setBuffers(Vector<GFXShaderConstDesc>& constDesc, Vector<GFXShaderConstBufferRef>& buffers);
|
||||
GFXShaderConstBuffer* getBuffer(U32 i) { return mBuffers[i]; }
|
||||
|
||||
///
|
||||
/// MaterialParameter interface
|
||||
///
|
||||
|
||||
/// Returns the material parameter handle for name.
|
||||
virtual void set(MaterialParameterHandle* handle, const F32 f);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point2F& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point3F& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point4F& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const PlaneF& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const ColorF& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const S32 f);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point2I& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point3I& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const Point4I& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<F32>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point2F>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point3F>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point4F>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<S32>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point2I>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point3I>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const AlignedArray<Point4I>& fv);
|
||||
virtual void set(MaterialParameterHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
|
||||
virtual void set(MaterialParameterHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
|
||||
|
||||
virtual U32 getAlignmentValue(const GFXShaderConstType constType);
|
||||
|
||||
private:
|
||||
Vector<GFXShaderConstBufferRef> mBuffers;
|
||||
|
||||
void releaseBuffers();
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue