mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 07:04:36 +00:00
Hardware Skinning Support
- Supports GL, D3D9 & D3D11 - Extends vertex formats & shadergen to support blend indices and weights - Adds basic support for using 4x3 matrices for shader constants - Supports software fallback
This commit is contained in:
parent
507c239a87
commit
3496c549b5
72 changed files with 2533 additions and 1327 deletions
|
|
@ -101,6 +101,30 @@ Var * AppVertConnectorGLSL::getElement( RegisterType type,
|
|||
return newVar;
|
||||
}
|
||||
|
||||
case RT_BLENDINDICES:
|
||||
{
|
||||
Var *newVar = new Var;
|
||||
newVar->constNum = mCurBlendIndicesElem;
|
||||
mElementList.push_back(newVar);
|
||||
char out[32];
|
||||
dSprintf((char*)out, sizeof(out), "vBlendIndex%d", mCurBlendIndicesElem);
|
||||
mCurBlendIndicesElem += 1;
|
||||
newVar->setConnectName(out);
|
||||
return newVar;
|
||||
}
|
||||
|
||||
case RT_BLENDWEIGHT:
|
||||
{
|
||||
Var *newVar = new Var;
|
||||
newVar->constNum = mCurBlendWeightsElem;
|
||||
mElementList.push_back(newVar);
|
||||
char out[32];
|
||||
dSprintf((char*)out, sizeof(out), "vBlendWeight%d", mCurBlendWeightsElem);
|
||||
mCurBlendWeightsElem += 1;
|
||||
newVar->setConnectName(out);
|
||||
return newVar;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "core/util/autoPtr.h"
|
||||
|
||||
#include "lighting/advanced/advancedLightBinManager.h"
|
||||
#include "ts/tsShape.h"
|
||||
|
||||
LangElement * ShaderFeatureGLSL::setupTexSpaceMat( Vector<ShaderComponent*> &, // componentList
|
||||
Var **texSpaceMat )
|
||||
|
|
@ -2795,4 +2796,68 @@ void ImposterVertFeatureGLSL::determineFeature( Material *material,
|
|||
{
|
||||
if ( features.hasFeature( MFT_ImposterVert ) )
|
||||
outFeatureData->features.addFeature( MFT_ImposterVert );
|
||||
}
|
||||
}
|
||||
|
||||
//****************************************************************************
|
||||
// HardwareSkinningFeatureGLSL
|
||||
//****************************************************************************
|
||||
|
||||
void HardwareSkinningFeatureGLSL::processVert(Vector<ShaderComponent*> &componentList,
|
||||
const MaterialFeatureData &fd)
|
||||
{
|
||||
MultiLine *meta = new MultiLine;
|
||||
|
||||
Var *inPosition = (Var*)LangElement::find("inPosition");
|
||||
Var *inNormal = (Var*)LangElement::find("inNormal");
|
||||
|
||||
if (!inPosition)
|
||||
inPosition = (Var*)LangElement::find("position");
|
||||
|
||||
if (!inNormal)
|
||||
inNormal = (Var*)LangElement::find("normal");
|
||||
|
||||
Var* posePos = new Var("posePos", "vec3");
|
||||
Var* poseNormal = new Var("poseNormal", "vec3");
|
||||
Var* poseMat = new Var("poseMat", "mat4x3");
|
||||
Var* poseRotMat = new Var("poseRotMat", "mat3x3");
|
||||
Var* nodeTransforms = (Var*)LangElement::find("nodeTransforms");
|
||||
|
||||
if (!nodeTransforms)
|
||||
{
|
||||
nodeTransforms = new Var("nodeTransforms", "mat4x3");
|
||||
nodeTransforms->uniform = true;
|
||||
nodeTransforms->arraySize = TSShape::smMaxSkinBones;
|
||||
nodeTransforms->constSortPos = cspPrimitive;
|
||||
}
|
||||
|
||||
U32 numIndices = mVertexFormat->getNumBlendIndices();
|
||||
meta->addStatement(new GenOp(" @ = vec3(0.0);\r\n", new DecOp(posePos)));
|
||||
meta->addStatement(new GenOp(" @ = vec3(0.0);\r\n", new DecOp(poseNormal)));
|
||||
meta->addStatement(new GenOp(" @;\r\n", new DecOp(poseMat)));
|
||||
meta->addStatement(new GenOp(" @;\r\n int i;\r\n", new DecOp(poseRotMat)));
|
||||
|
||||
for (U32 i = 0; i<numIndices; i++)
|
||||
{
|
||||
// NOTE: To keep things simple, we assume all 4 bone indices are used in each element chunk.
|
||||
LangElement* inIndices = (Var*)LangElement::find(String::ToString("vBlendIndex%d", i));
|
||||
LangElement* inWeights = (Var*)LangElement::find(String::ToString("vBlendWeight%d", i));
|
||||
|
||||
AssertFatal(inIndices && inWeights, "Something went wrong here");
|
||||
AssertFatal(poseMat && nodeTransforms && posePos && inPosition && inWeights && poseNormal && inNormal && poseRotMat, "Something went REALLY wrong here");
|
||||
|
||||
meta->addStatement(new GenOp(" for (i=0; i<4; i++) {\r\n"));
|
||||
meta->addStatement(new GenOp(" int poseIdx = int(@[i]);\r\n", inIndices));
|
||||
meta->addStatement(new GenOp(" float poseWeight = @[i];\r\n", inWeights));
|
||||
meta->addStatement(new GenOp(" @ = @[poseIdx];\r\n", poseMat, nodeTransforms));
|
||||
meta->addStatement(new GenOp(" @ = mat3x3(@);\r\n", poseRotMat, poseMat));
|
||||
meta->addStatement(new GenOp(" @ += (@ * vec4(@, 1)).xyz * poseWeight;\r\n", posePos, poseMat, inPosition));
|
||||
meta->addStatement(new GenOp(" @ += ((@ * @) * poseWeight);\r\n", poseNormal, poseRotMat, inNormal));
|
||||
meta->addStatement(new GenOp(" }\r\n"));
|
||||
}
|
||||
|
||||
// Assign new position and normal
|
||||
meta->addStatement(new GenOp(" @ = @;\r\n", inPosition, posePos));
|
||||
meta->addStatement(new GenOp(" @ = normalize(@);\r\n", inNormal, poseNormal));
|
||||
|
||||
output = meta;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -659,4 +659,17 @@ public:
|
|||
MaterialFeatureData *outFeatureData );
|
||||
};
|
||||
|
||||
/// Hardware Skinning
|
||||
class HardwareSkinningFeatureGLSL : public ShaderFeatureGLSL
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
|
||||
virtual void processVert(Vector<ShaderComponent*> &componentList,
|
||||
const MaterialFeatureData &fd);
|
||||
|
||||
virtual String getName() { return "Hardware Skinning"; }
|
||||
};
|
||||
|
||||
#endif // _SHADERGEN_GLSL_SHADERFEATUREGLSL_H_
|
||||
|
|
|
|||
|
|
@ -113,6 +113,9 @@ const char* ShaderGenComponentFactoryGLSL::typeToString( GFXDeclType type )
|
|||
case GFXDeclType_Float3:
|
||||
return "vec3";
|
||||
|
||||
case GFXDeclType_UByte4:
|
||||
return "vec4";
|
||||
|
||||
case GFXDeclType_Float4:
|
||||
case GFXDeclType_Color:
|
||||
return "vec4";
|
||||
|
|
@ -160,6 +163,16 @@ ShaderComponent* ShaderGenComponentFactoryGLSL::createVertexInputConnector( cons
|
|||
var = vertComp->getElement( RT_COLOR );
|
||||
var->setName( "diffuse" );
|
||||
}
|
||||
else if (element.isSemantic(GFXSemantic::BLENDINDICES))
|
||||
{
|
||||
var = vertComp->getElement(RT_BLENDINDICES);
|
||||
var->setName(String::ToString("vBlendIndex%d", element.getSemanticIndex()));
|
||||
}
|
||||
else if (element.isSemantic(GFXSemantic::BLENDWEIGHT))
|
||||
{
|
||||
var = vertComp->getElement(RT_BLENDWEIGHT);
|
||||
var->setName(String::ToString("vBlendWeight%d", element.getSemanticIndex()));
|
||||
}
|
||||
else if ( element.isSemantic( GFXSemantic::TEXCOORD ) )
|
||||
{
|
||||
var = vertComp->getElement( RT_TEXCOORD );
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ void _initShaderGenGLSL( ShaderGen *shaderGen )
|
|||
FEATUREMGR->registerFeature( MFT_DeferredMatInfoFlags, new DeferredMatInfoFlagsGLSL );
|
||||
FEATUREMGR->registerFeature( MFT_DeferredEmptySpec, new DeferredEmptySpecGLSL );
|
||||
FEATUREMGR->registerFeature( MFT_SkyBox, new NamedFeatureGLSL( "skybox" ) );
|
||||
FEATUREMGR->registerFeature( MFT_HardwareSkinning, new HardwareSkinningFeatureGLSL );
|
||||
}
|
||||
|
||||
MODULE_BEGIN( ShaderGenGLSL )
|
||||
|
|
|
|||
|
|
@ -32,7 +32,20 @@ Var * ShaderConnectorHLSL::getElement( RegisterType type,
|
|||
U32 numElements,
|
||||
U32 numRegisters )
|
||||
{
|
||||
Var *ret = getIndexedElement( mCurTexElem, type, numElements, numRegisters );
|
||||
Var *ret = NULL;
|
||||
|
||||
if ( type == RT_BLENDINDICES )
|
||||
{
|
||||
ret = getIndexedElement( mCurBlendIndicesElem, type, numElements, numRegisters );
|
||||
}
|
||||
else if ( type == RT_BLENDWEIGHT )
|
||||
{
|
||||
ret = getIndexedElement( mCurBlendWeightsElem, type, numElements, numRegisters );
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = getIndexedElement( mCurTexElem, type, numElements, numRegisters );
|
||||
}
|
||||
|
||||
// Adjust texture offset if this is a texcoord type
|
||||
if( type == RT_TEXCOORD )
|
||||
|
|
@ -42,6 +55,20 @@ Var * ShaderConnectorHLSL::getElement( RegisterType type,
|
|||
else
|
||||
mCurTexElem += numElements;
|
||||
}
|
||||
else if ( type == RT_BLENDINDICES )
|
||||
{
|
||||
if ( numRegisters != -1 )
|
||||
mCurBlendIndicesElem += numRegisters;
|
||||
else
|
||||
mCurBlendIndicesElem += numElements;
|
||||
}
|
||||
else if ( type == RT_BLENDWEIGHT )
|
||||
{
|
||||
if ( numRegisters != -1 )
|
||||
mCurBlendWeightsElem += numRegisters;
|
||||
else
|
||||
mCurBlendWeightsElem += numElements;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -133,6 +160,46 @@ Var * ShaderConnectorHLSL::getIndexedElement( U32 index, RegisterType type, U32
|
|||
return newVar;
|
||||
}
|
||||
|
||||
case RT_BLENDINDICES:
|
||||
{
|
||||
Var *newVar = new Var;
|
||||
mElementList.push_back( newVar );
|
||||
|
||||
// This was needed for hardware instancing, but
|
||||
// i don't really remember why right now.
|
||||
if ( index > mCurBlendIndicesElem )
|
||||
mCurBlendIndicesElem = index + 1;
|
||||
|
||||
char out[32];
|
||||
dSprintf( (char*)out, sizeof(out), "BLENDINDICES%d", index );
|
||||
newVar->setConnectName( out );
|
||||
newVar->constNum = index;
|
||||
newVar->arraySize = numElements;
|
||||
|
||||
return newVar;
|
||||
}
|
||||
|
||||
case RT_BLENDWEIGHT:
|
||||
{
|
||||
Var *newVar = new Var;
|
||||
mElementList.push_back( newVar );
|
||||
|
||||
// This was needed for hardware instancing, but
|
||||
// i don't really remember why right now.
|
||||
if ( index > mCurBlendWeightsElem )
|
||||
mCurBlendWeightsElem = index + 1;
|
||||
|
||||
char out[32];
|
||||
dSprintf( (char*)out, sizeof(out), "BLENDWEIGHT%d", index );
|
||||
newVar->setConnectName( out );
|
||||
newVar->constNum = index;
|
||||
newVar->arraySize = numElements;
|
||||
|
||||
return newVar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -177,6 +244,8 @@ void ShaderConnectorHLSL::reset()
|
|||
|
||||
mElementList.setSize( 0 );
|
||||
mCurTexElem = 0;
|
||||
mCurBlendIndicesElem = 0;
|
||||
mCurBlendWeightsElem = 0;
|
||||
}
|
||||
|
||||
void ShaderConnectorHLSL::print( Stream &stream, bool isVertexShader )
|
||||
|
|
@ -231,12 +300,23 @@ void ParamsDefHLSL::assignConstantNumbers()
|
|||
if (dStrcmp((const char*)var->type, "float4x4") == 0)
|
||||
{
|
||||
mCurrConst += (4 * var->arraySize);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dStrcmp((const char*)var->type, "float3x3") == 0)
|
||||
{
|
||||
mCurrConst += (3 * var->arraySize);
|
||||
} else {
|
||||
mCurrConst += var->arraySize;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dStrcmp((const char*)var->type, "float4x3") == 0)
|
||||
{
|
||||
mCurrConst += (3 * var->arraySize);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrConst += var->arraySize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "core/util/autoPtr.h"
|
||||
|
||||
#include "lighting/advanced/advancedLightBinManager.h"
|
||||
#include "ts/tsShape.h"
|
||||
|
||||
LangElement * ShaderFeatureHLSL::setupTexSpaceMat( Vector<ShaderComponent*> &, // componentList
|
||||
Var **texSpaceMat )
|
||||
|
|
@ -2991,3 +2992,66 @@ void ImposterVertFeatureHLSL::determineFeature( Material *material,
|
|||
outFeatureData->features.addFeature( MFT_ImposterVert );
|
||||
}
|
||||
|
||||
//****************************************************************************
|
||||
// HardwareSkinningFeatureHLSL
|
||||
//****************************************************************************
|
||||
|
||||
void HardwareSkinningFeatureHLSL::processVert( Vector<ShaderComponent*> &componentList,
|
||||
const MaterialFeatureData &fd )
|
||||
{
|
||||
MultiLine *meta = new MultiLine;
|
||||
|
||||
Var *inPosition = (Var*)LangElement::find( "inPosition" );
|
||||
Var *inNormal = (Var*)LangElement::find( "inNormal" );
|
||||
|
||||
if ( !inPosition )
|
||||
inPosition = (Var*)LangElement::find( "position" );
|
||||
|
||||
if ( !inNormal )
|
||||
inNormal = (Var*)LangElement::find( "normal" );
|
||||
|
||||
Var* posePos = new Var("posePos", "float3");
|
||||
Var* poseNormal = new Var("poseNormal", "float3");
|
||||
Var* poseMat = new Var("poseMat", "float4x3");
|
||||
Var* poseRotMat = new Var("poseRotMat", "float3x3");
|
||||
Var* nodeTransforms = (Var*)LangElement::find("nodeTransforms");
|
||||
|
||||
if (!nodeTransforms)
|
||||
{
|
||||
nodeTransforms = new Var("nodeTransforms", "float4x3");
|
||||
nodeTransforms->uniform = true;
|
||||
nodeTransforms->arraySize = TSShape::smMaxSkinBones;
|
||||
nodeTransforms->constSortPos = cspPotentialPrimitive;
|
||||
}
|
||||
|
||||
U32 numIndices = mVertexFormat->getNumBlendIndices();
|
||||
meta->addStatement( new GenOp( " @ = 0.0;\r\n", new DecOp( posePos ) ) );
|
||||
meta->addStatement( new GenOp( " @ = 0.0;\r\n", new DecOp( poseNormal ) ) );
|
||||
meta->addStatement( new GenOp( " @;\r\n", new DecOp( poseMat ) ) );
|
||||
meta->addStatement(new GenOp(" @;\r\n int i;\r\n", new DecOp(poseRotMat)));
|
||||
|
||||
for (U32 i=0; i<numIndices; i++)
|
||||
{
|
||||
// NOTE: To keep things simple, we assume all 4 bone indices are used in each element chunk.
|
||||
LangElement* inIndices = (Var*)LangElement::find(String::ToString( "blendIndices%d", i ));
|
||||
LangElement* inWeights = (Var*)LangElement::find(String::ToString( "blendWeight%d", i ));
|
||||
|
||||
AssertFatal(inIndices && inWeights, "Something went wrong here");
|
||||
AssertFatal(poseMat && nodeTransforms && posePos && inPosition && inWeights && poseNormal && inNormal && poseRotMat, "Something went REALLY wrong here");
|
||||
|
||||
meta->addStatement( new GenOp( " for (i=0; i<4; i++) {\r\n" ) );
|
||||
meta->addStatement( new GenOp( " int poseIdx = int(@[i]);\r\n", inIndices ) );
|
||||
meta->addStatement( new GenOp( " float poseWeight = @[i];\r\n", inWeights) );
|
||||
meta->addStatement( new GenOp( " @ = @[poseIdx];\r\n", poseMat, nodeTransforms) );
|
||||
meta->addStatement( new GenOp( " @ = (float3x3)@;\r\n", poseRotMat, poseMat) );
|
||||
meta->addStatement( new GenOp( " @ += (mul(float4(@, 1), @)).xyz * poseWeight;\r\n", posePos, inPosition, poseMat) );
|
||||
meta->addStatement( new GenOp( " @ += (mul(@,@) * poseWeight);\r\n", poseNormal, inNormal, poseRotMat) );
|
||||
meta->addStatement( new GenOp( " }\r\n" ) );
|
||||
}
|
||||
|
||||
// Assign new position and normal
|
||||
meta->addStatement( new GenOp( " @ = @;\r\n", inPosition, posePos ) );
|
||||
meta->addStatement( new GenOp( " @ = normalize(@);\r\n", inNormal, poseNormal ) );
|
||||
|
||||
output = meta;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -663,4 +663,17 @@ public:
|
|||
MaterialFeatureData *outFeatureData );
|
||||
};
|
||||
|
||||
/// Hardware Skinning
|
||||
class HardwareSkinningFeatureHLSL : public ShaderFeatureHLSL
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
|
||||
virtual void processVert( Vector<ShaderComponent*> &componentList,
|
||||
const MaterialFeatureData &fd );
|
||||
|
||||
virtual String getName() { return "Hardware Skinning"; }
|
||||
};
|
||||
|
||||
#endif // _SHADERGEN_HLSL_SHADERFEATUREHLSL_H_
|
||||
|
|
|
|||
|
|
@ -121,6 +121,9 @@ const char* ShaderGenComponentFactoryHLSL::typeToString( GFXDeclType type )
|
|||
case GFXDeclType_Float4:
|
||||
case GFXDeclType_Color:
|
||||
return "float4";
|
||||
|
||||
case GFXDeclType_UByte4:
|
||||
return "uint4";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,6 +177,22 @@ ShaderComponent* ShaderGenComponentFactoryHLSL::createVertexInputConnector( cons
|
|||
else
|
||||
var->setName( String::ToString( "texCoord%d", element.getSemanticIndex() + 1 ) );
|
||||
}
|
||||
else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
|
||||
{
|
||||
var = vertComp->getIndexedElement( element.getSemanticIndex(), RT_BLENDINDICES );
|
||||
var->setName( String::ToString( "blendIndices%d", element.getSemanticIndex() ) );
|
||||
}
|
||||
else if ( element.isSemantic( GFXSemantic::BLENDWEIGHT ) )
|
||||
{
|
||||
var = vertComp->getIndexedElement( element.getSemanticIndex(), RT_BLENDWEIGHT );
|
||||
var->setName( String::ToString( "blendWeight%d", element.getSemanticIndex() ) );
|
||||
}
|
||||
else if ( element.isSemantic( GFXSemantic::PADDING ) )
|
||||
{
|
||||
var = NULL;
|
||||
//var = vertComp->getIndexedElement( vertComp->getCurTexElem() + element.getSemanticIndex(), RT_TEXCOORD );
|
||||
//var->setName( String::ToString( "pad%d", element.getSemanticIndex() + 1 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Everything else is a texcoord!
|
||||
|
|
|
|||
|
|
@ -100,13 +100,13 @@ void _initShaderGenHLSL( ShaderGen *shaderGen )
|
|||
|
||||
FEATUREMGR->registerFeature( MFT_ImposterVert, new ImposterVertFeatureHLSL );
|
||||
|
||||
// Deferred Shading
|
||||
FEATUREMGR->registerFeature( MFT_isDeferred, new NamedFeatureHLSL( "Deferred Material" ) );
|
||||
FEATUREMGR->registerFeature( MFT_DeferredSpecMap, new DeferredSpecMapHLSL );
|
||||
FEATUREMGR->registerFeature( MFT_DeferredSpecVars, new DeferredSpecVarsHLSL );
|
||||
FEATUREMGR->registerFeature( MFT_DeferredMatInfoFlags, new DeferredMatInfoFlagsHLSL );
|
||||
FEATUREMGR->registerFeature( MFT_DeferredEmptySpec, new DeferredEmptySpecHLSL );
|
||||
FEATUREMGR->registerFeature( MFT_SkyBox, new NamedFeatureHLSL( "skybox" ) );
|
||||
FEATUREMGR->registerFeature( MFT_HardwareSkinning, new HardwareSkinningFeatureHLSL );
|
||||
}
|
||||
|
||||
MODULE_BEGIN( ShaderGenHLSL )
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ ShaderConnector::ShaderConnector()
|
|||
{
|
||||
mCurTexElem = 0;
|
||||
mName[0] = '\0';
|
||||
mCurBlendIndicesElem = 0;
|
||||
mCurBlendWeightsElem = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ protected:
|
|||
Vector <Var*> mElementList;
|
||||
|
||||
U32 mCurTexElem;
|
||||
U32 mCurBlendIndicesElem;
|
||||
U32 mCurBlendWeightsElem;
|
||||
U8 mName[32];
|
||||
|
||||
public:
|
||||
|
|
@ -78,6 +80,8 @@ public:
|
|||
ShaderConnector();
|
||||
virtual ~ShaderConnector();
|
||||
|
||||
U32 getCurTexElem() { return mCurTexElem; }
|
||||
|
||||
///
|
||||
virtual Var* getElement( RegisterType type,
|
||||
U32 numElements = 1,
|
||||
|
|
|
|||
|
|
@ -99,6 +99,12 @@ protected:
|
|||
///
|
||||
S32 mProcessIndex;
|
||||
|
||||
public:
|
||||
|
||||
// TODO: Make this protected and give it a proper API.
|
||||
const GFXVertexFormat *mVertexFormat;
|
||||
|
||||
// TODO: Make this protected and give it a proper API.
|
||||
GFXVertexFormat *mInstancingFormat;
|
||||
|
||||
public:
|
||||
|
|
@ -139,7 +145,8 @@ public:
|
|||
ShaderFeature()
|
||||
: output( NULL ),
|
||||
mProcessIndex( 0 ),
|
||||
mInstancingFormat( NULL )
|
||||
mInstancingFormat( NULL ),
|
||||
mVertexFormat( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +292,7 @@ public:
|
|||
|
||||
/// Called after processing the vertex and processing the pixel
|
||||
/// to cleanup any temporary structures stored in the feature.
|
||||
virtual void reset() { output = NULL; mProcessIndex = 0; mInstancingFormat = NULL; }
|
||||
virtual void reset() { output = NULL; mProcessIndex = 0; mInstancingFormat = NULL; mVertexFormat = NULL; }
|
||||
|
||||
/// A simpler helper function which either finds
|
||||
/// the existing local var or creates one.
|
||||
|
|
|
|||
|
|
@ -265,6 +265,9 @@ void ShaderGen::_processVertFeatures( Vector<GFXShaderMacro> ¯os, bool macro
|
|||
continue;
|
||||
|
||||
feature->setInstancingFormat( &mInstancingFormat );
|
||||
|
||||
feature->mVertexFormat = mVertexFormat;
|
||||
|
||||
feature->processVert( mComponents, mFeatureData );
|
||||
|
||||
String line;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue