mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 08:15:44 +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
|
|
@ -1426,6 +1426,8 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
|
|||
StringBuilder mainBodyData;
|
||||
//make shader
|
||||
mainBodyData.append("VertOut main(VertIn IN){VertOut OUT;");
|
||||
|
||||
bool addedPadding = false;
|
||||
for (U32 i = 0; i < elemCount; i++)
|
||||
{
|
||||
const GFXVertexElement &element = vertexFormat->getElement(i);
|
||||
|
|
@ -1433,6 +1435,8 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
|
|||
String semanticOut = semantic;
|
||||
String type;
|
||||
|
||||
AssertFatal(!(addedPadding && !element.isSemantic(GFXSemantic::PADDING)), "Padding added before data");
|
||||
|
||||
if (element.isSemantic(GFXSemantic::POSITION))
|
||||
{
|
||||
semantic = "POSITION";
|
||||
|
|
@ -1458,6 +1462,21 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
|
|||
semantic = "BINORMAL";
|
||||
semanticOut = semantic;
|
||||
}
|
||||
else if (element.isSemantic(GFXSemantic::BLENDINDICES))
|
||||
{
|
||||
semantic = String::ToString("BLENDINDICES%d", element.getSemanticIndex());
|
||||
semanticOut = semantic;
|
||||
}
|
||||
else if (element.isSemantic(GFXSemantic::BLENDWEIGHT))
|
||||
{
|
||||
semantic = String::ToString("BLENDWEIGHT%d", element.getSemanticIndex());
|
||||
semanticOut = semantic;
|
||||
}
|
||||
else if (element.isSemantic(GFXSemantic::PADDING))
|
||||
{
|
||||
addedPadding = true;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Anything that falls thru to here will be a texture coord.
|
||||
|
|
@ -1481,6 +1500,9 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
|
|||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
type = "float4";
|
||||
break;
|
||||
case DXGI_FORMAT_R8G8B8A8_UINT:
|
||||
type = "uint4";
|
||||
break;
|
||||
}
|
||||
|
||||
StringBuilder in;
|
||||
|
|
@ -1570,16 +1592,17 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
|
|||
U32 stream;
|
||||
D3D11_INPUT_ELEMENT_DESC *vd = new D3D11_INPUT_ELEMENT_DESC[ elemCount];
|
||||
|
||||
for ( U32 i=0; i < elemCount; i++ )
|
||||
S32 elemIndex = 0;
|
||||
for (S32 i = 0; i < elemCount; i++, elemIndex++)
|
||||
{
|
||||
|
||||
const GFXVertexElement &element = vertexFormat->getElement( i );
|
||||
|
||||
|
||||
const GFXVertexElement &element = vertexFormat->getElement(elemIndex);
|
||||
|
||||
stream = element.getStreamIndex();
|
||||
|
||||
vd[i].InputSlot = stream;
|
||||
|
||||
vd[i].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
|
||||
|
||||
vd[i].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
|
||||
vd[i].Format = GFXD3D11DeclType[element.getType()];
|
||||
// If instancing is enabled, the per instance data is only used on stream 1.
|
||||
if (vertexFormat->hasInstancing() && stream == 1)
|
||||
|
|
@ -1596,16 +1619,32 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
|
|||
// texture coords for now... this may change later.
|
||||
vd[i].SemanticIndex = 0;
|
||||
|
||||
if ( element.isSemantic( GFXSemantic::POSITION ) )
|
||||
if (element.isSemantic(GFXSemantic::POSITION))
|
||||
vd[i].SemanticName = "POSITION";
|
||||
else if ( element.isSemantic( GFXSemantic::NORMAL ) )
|
||||
else if (element.isSemantic(GFXSemantic::NORMAL))
|
||||
vd[i].SemanticName = "NORMAL";
|
||||
else if ( element.isSemantic( GFXSemantic::COLOR ) )
|
||||
else if (element.isSemantic(GFXSemantic::COLOR))
|
||||
vd[i].SemanticName = "COLOR";
|
||||
else if ( element.isSemantic( GFXSemantic::TANGENT ) )
|
||||
else if (element.isSemantic(GFXSemantic::TANGENT))
|
||||
vd[i].SemanticName = "TANGENT";
|
||||
else if ( element.isSemantic( GFXSemantic::BINORMAL ) )
|
||||
else if (element.isSemantic(GFXSemantic::BINORMAL))
|
||||
vd[i].SemanticName = "BINORMAL";
|
||||
else if (element.isSemantic(GFXSemantic::BLENDWEIGHT))
|
||||
{
|
||||
vd[i].SemanticName = "BLENDWEIGHT";
|
||||
vd[i].SemanticIndex = element.getSemanticIndex();
|
||||
}
|
||||
else if (element.isSemantic(GFXSemantic::BLENDINDICES))
|
||||
{
|
||||
vd[i].SemanticName = "BLENDINDICES";
|
||||
vd[i].SemanticIndex = element.getSemanticIndex();
|
||||
}
|
||||
else if (element.isSemantic(GFXSemantic::PADDING))
|
||||
{
|
||||
i--;
|
||||
elemCount--;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Anything that falls thru to here will be a texture coord.
|
||||
|
|
|
|||
|
|
@ -152,5 +152,6 @@ void GFXD3D11EnumTranslate::init()
|
|||
GFXD3D11DeclType[GFXDeclType_Float3] = DXGI_FORMAT_R32G32B32_FLOAT;
|
||||
GFXD3D11DeclType[GFXDeclType_Float4] = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
GFXD3D11DeclType[GFXDeclType_Color] = DXGI_FORMAT_B8G8R8A8_UNORM; // DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
GFXD3D11DeclType[GFXDeclType_UByte4] = DXGI_FORMAT_R8G8B8A8_UINT;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,9 +150,11 @@ bool GFXD3D11ConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstTyp
|
|||
(
|
||||
(pd.constType == GFXSCT_Float2x2 ||
|
||||
pd.constType == GFXSCT_Float3x3 ||
|
||||
pd.constType == GFXSCT_Float4x3 ||
|
||||
pd.constType == GFXSCT_Float4x4) &&
|
||||
(constType == GFXSCT_Float2x2 ||
|
||||
constType == GFXSCT_Float3x3 ||
|
||||
constType == GFXSCT_Float4x3 ||
|
||||
constType == GFXSCT_Float4x4)
|
||||
), "Mismatched const type!");
|
||||
|
||||
|
|
@ -161,6 +163,7 @@ bool GFXD3D11ConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstTyp
|
|||
{
|
||||
case GFXSCT_Float2x2:
|
||||
case GFXSCT_Float3x3:
|
||||
case GFXSCT_Float4x3:
|
||||
case GFXSCT_Float4x4:
|
||||
return setMatrix(pd, constType, size, data, basePointer);
|
||||
break;
|
||||
|
|
@ -201,6 +204,40 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
|
|||
|
||||
return false;
|
||||
}
|
||||
else if (pd.constType == GFXSCT_Float4x3)
|
||||
{
|
||||
F32 buffer[4 * 4];
|
||||
const U32 csize = 48;
|
||||
|
||||
// Loop through and copy
|
||||
bool ret = false;
|
||||
U8* currDestPointer = basePointer + pd.offset;
|
||||
const U8* currSourcePointer = static_cast<const U8*>(data);
|
||||
const U8* endData = currSourcePointer + size;
|
||||
while (currSourcePointer < endData)
|
||||
{
|
||||
#ifdef TORQUE_DOUBLE_CHECK_43MATS
|
||||
Point4F col;
|
||||
((MatrixF*)currSourcePointer)->getRow(3, &col);
|
||||
AssertFatal(col.x == 0.0f && col.y == 0.0f && col.z == 0.0f && col.w == 1.0f, "3rd row used");
|
||||
#endif
|
||||
|
||||
if (dMemcmp(currDestPointer, currSourcePointer, csize) != 0)
|
||||
{
|
||||
dMemcpy(currDestPointer, currSourcePointer, csize);
|
||||
ret = true;
|
||||
}
|
||||
else if (pd.constType == GFXSCT_Float4x3)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
|
||||
currDestPointer += csize;
|
||||
currSourcePointer += sizeof(MatrixF);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
PROFILE_SCOPE(GFXD3D11ConstBufferLayout_setMatrix_not4x4);
|
||||
|
|
@ -480,8 +517,15 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF&
|
|||
AssertFatal(!h->isSampler(), "Handle is sampler constant!" );
|
||||
AssertFatal(h->mShader == mShader, "Mismatched shaders!");
|
||||
|
||||
MatrixF transposed;
|
||||
mat.transposeTo(transposed);
|
||||
MatrixF transposed;
|
||||
if (matrixType == GFXSCT_Float4x3)
|
||||
{
|
||||
transposed = mat;
|
||||
}
|
||||
else
|
||||
{
|
||||
mat.transposeTo(transposed);
|
||||
}
|
||||
|
||||
if (h->mInstancingConstant)
|
||||
{
|
||||
|
|
@ -510,9 +554,17 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF*
|
|||
|
||||
static Vector<MatrixF> transposed;
|
||||
if (arraySize > transposed.size())
|
||||
transposed.setSize(arraySize);
|
||||
for (U32 i = 0; i < arraySize; i++)
|
||||
mat[i].transposeTo(transposed[i]);
|
||||
transposed.setSize(arraySize);
|
||||
|
||||
if (matrixType == GFXSCT_Float4x3)
|
||||
{
|
||||
dMemcpy(transposed.address(), mat, arraySize * sizeof(MatrixF));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (U32 i = 0; i < arraySize; i++)
|
||||
mat[i].transposeTo(transposed[i]);
|
||||
}
|
||||
|
||||
// TODO: Maybe support this in the future?
|
||||
if (h->mInstancingConstant)
|
||||
|
|
@ -1190,19 +1242,13 @@ bool GFXD3D11Shader::_convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDe
|
|||
case D3D_SVC_MATRIX_ROWS:
|
||||
case D3D_SVC_MATRIX_COLUMNS:
|
||||
{
|
||||
switch (typeDesc.Columns)
|
||||
switch (typeDesc.Rows)
|
||||
{
|
||||
case 3:
|
||||
if (typeDesc.Rows == 3)
|
||||
{
|
||||
desc.constType = GFXSCT_Float3x3;
|
||||
}
|
||||
desc.constType = typeDesc.Columns == 4 ? GFXSCT_Float3x4 : GFXSCT_Float3x3;
|
||||
break;
|
||||
case 4:
|
||||
if (typeDesc.Rows == 4)
|
||||
{
|
||||
desc.constType = GFXSCT_Float4x4;
|
||||
}
|
||||
desc.constType = typeDesc.Columns == 3 ? GFXSCT_Float4x3 : GFXSCT_Float4x4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1513,6 +1559,9 @@ U32 GFXD3D11Shader::getAlignmentValue(const GFXShaderConstType constType) const
|
|||
case GFXSCT_Float3x3 :
|
||||
return mRowSizeF * 3;
|
||||
break;
|
||||
case GFXSCT_Float4x3:
|
||||
return mRowSizeF * 3;
|
||||
break;
|
||||
case GFXSCT_Float4x4 :
|
||||
return mRowSizeF * 4;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue