mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 07:34:45 +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
|
|
@ -629,6 +629,8 @@ void GFXD3D9Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
|
|||
mVolatileVB = NULL;
|
||||
}
|
||||
|
||||
U32 offset = d3dBuffer && stream != 0 ? d3dBuffer->mVolatileStart * d3dBuffer->mVertexSize : 0;
|
||||
|
||||
// NOTE: We do not use the stream offset here for stream 0
|
||||
// as that feature is *supposedly* not as well supported as
|
||||
// using the start index in drawPrimitive.
|
||||
|
|
@ -638,7 +640,7 @@ void GFXD3D9Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
|
|||
|
||||
D3D9Assert( mD3DDevice->SetStreamSource( stream,
|
||||
d3dBuffer ? d3dBuffer->vb : NULL,
|
||||
d3dBuffer && stream != 0 ? d3dBuffer->mVolatileStart * d3dBuffer->mVertexSize : 0,
|
||||
offset,
|
||||
d3dBuffer ? d3dBuffer->mVertexSize : 0 ),
|
||||
"GFXD3D9Device::setVertexStream - Failed to set stream source." );
|
||||
}
|
||||
|
|
@ -929,10 +931,12 @@ GFXVertexDecl* GFXD3D9Device::allocVertexDecl( const GFXVertexFormat *vertexForm
|
|||
U32 elemCount = vertexFormat->getElementCount();
|
||||
U32 offsets[4] = { 0 };
|
||||
U32 stream;
|
||||
S32 i = 0;
|
||||
S32 elemIdx = 0;
|
||||
D3DVERTEXELEMENT9 *vd = new D3DVERTEXELEMENT9[ elemCount + 1 ];
|
||||
for ( U32 i=0; i < elemCount; i++ )
|
||||
for ( i=0; elemIdx < elemCount; i++, elemIdx++ )
|
||||
{
|
||||
const GFXVertexElement &element = vertexFormat->getElement( i );
|
||||
const GFXVertexElement &element = vertexFormat->getElement( elemIdx );
|
||||
|
||||
stream = element.getStreamIndex();
|
||||
|
||||
|
|
@ -955,6 +959,18 @@ GFXVertexDecl* GFXD3D9Device::allocVertexDecl( const GFXVertexFormat *vertexForm
|
|||
vd[i].Usage = D3DDECLUSAGE_TANGENT;
|
||||
else if ( element.isSemantic( GFXSemantic::BINORMAL ) )
|
||||
vd[i].Usage = D3DDECLUSAGE_BINORMAL;
|
||||
else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
|
||||
{
|
||||
vd[i].Usage = D3DDECLUSAGE_BLENDINDICES;
|
||||
vd[i].UsageIndex = element.getSemanticIndex();
|
||||
}
|
||||
else if ( element.isSemantic( GFXSemantic::BLENDWEIGHT ) )
|
||||
{
|
||||
vd[i].Usage = D3DDECLUSAGE_BLENDWEIGHT;
|
||||
vd[i].UsageIndex = element.getSemanticIndex();
|
||||
}
|
||||
else if ( element.isSemantic( GFXSemantic::PADDING ) )
|
||||
i--;
|
||||
else
|
||||
{
|
||||
// Anything that falls thru to here will be a texture coord.
|
||||
|
|
@ -966,7 +982,7 @@ GFXVertexDecl* GFXD3D9Device::allocVertexDecl( const GFXVertexFormat *vertexForm
|
|||
}
|
||||
|
||||
D3DVERTEXELEMENT9 declEnd = D3DDECL_END();
|
||||
vd[elemCount] = declEnd;
|
||||
vd[i] = declEnd;
|
||||
|
||||
decl = new D3D9VertexDecl();
|
||||
D3D9Assert( mD3DDevice->CreateVertexDeclaration( vd, &decl->decl ),
|
||||
|
|
|
|||
|
|
@ -112,3 +112,4 @@ void GFXD3D9PrimitiveBuffer::resurrect()
|
|||
usage , GFXD3D9IndexFormat[GFXIndexFormat16], pool, &ib, 0),
|
||||
"GFXD3D9PrimitiveBuffer::resurrect - Failed to allocate an index buffer.");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ class GFXD3D9PrimitiveBuffer : public GFXPrimitiveBuffer
|
|||
public:
|
||||
IDirect3DIndexBuffer9 *ib;
|
||||
StrongRefPtr<GFXD3D9PrimitiveBuffer> mVolatileBuffer;
|
||||
U32 mVolatileStart;
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
#define _PBGuardString "GFX_PRIMTIVE_BUFFER_GUARD_STRING"
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "core/stream/fileStream.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "console/console.h"
|
||||
#include "math/mMathFn.h"
|
||||
|
||||
|
||||
using namespace Torque;
|
||||
|
||||
|
|
@ -172,6 +174,40 @@ bool GFXD3D9ShaderBufferLayout::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(GFXD3D9ShaderBufferLayout_setMatrix_not4x4);
|
||||
|
|
@ -186,6 +222,9 @@ bool GFXD3D9ShaderBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
|
|||
case GFXSCT_Float3x3 :
|
||||
csize = 48;
|
||||
break;
|
||||
case GFXSCT_Float3x4 :
|
||||
csize = 64;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Unhandled case!");
|
||||
return false;
|
||||
|
|
@ -204,6 +243,10 @@ bool GFXD3D9ShaderBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
|
|||
dMemcpy(currDestPointer, currSourcePointer, csize);
|
||||
ret = true;
|
||||
}
|
||||
else if (pd.constType == GFXSCT_Float4x3)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
|
||||
currDestPointer += csize;
|
||||
currSourcePointer += sizeof(MatrixF);
|
||||
|
|
@ -390,8 +433,15 @@ void GFXD3D9ShaderConstBuffer::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)
|
||||
{
|
||||
|
|
@ -420,9 +470,17 @@ void GFXD3D9ShaderConstBuffer::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)
|
||||
|
|
@ -1069,13 +1127,13 @@ void GFXD3D9Shader::_getShaderConstants( ID3DXConstantTable *table,
|
|||
case D3DXPC_MATRIX_ROWS :
|
||||
case D3DXPC_MATRIX_COLUMNS :
|
||||
{
|
||||
switch (constantDesc.RegisterCount)
|
||||
switch (constantDesc.Rows)
|
||||
{
|
||||
case 3 :
|
||||
desc.constType = GFXSCT_Float3x3;
|
||||
desc.constType = constantDesc.Columns == 4 ? GFXSCT_Float3x4 : GFXSCT_Float3x3;
|
||||
break;
|
||||
case 4 :
|
||||
desc.constType = GFXSCT_Float4x4;
|
||||
desc.constType = constantDesc.Columns == 3 ? GFXSCT_Float4x3 : GFXSCT_Float4x4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1436,9 +1494,15 @@ U32 GFXD3D9Shader::getAlignmentValue(const GFXShaderConstType constType) const
|
|||
case GFXSCT_Float3x3 :
|
||||
return mRowSizeF * 3;
|
||||
break;
|
||||
case GFXSCT_Float3x4 :
|
||||
return mRowSizeF * 4;
|
||||
break;
|
||||
case GFXSCT_Float4x4 :
|
||||
return mRowSizeF * 4;
|
||||
break;
|
||||
case GFXSCT_Float4x3 :
|
||||
return mRowSizeF * 3;
|
||||
break;
|
||||
//// Scalar
|
||||
case GFXSCT_Int :
|
||||
case GFXSCT_Int2 :
|
||||
|
|
|
|||
|
|
@ -228,4 +228,3 @@ void GFXD3D9VertexBuffer::resurrect()
|
|||
"GFXD3D9VertexBuffer::resurrect - Failed to allocate VB" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -372,6 +372,7 @@ void GFXD3D9EnumTranslate::init()
|
|||
GFXD3D9DeclType[GFXDeclType_Float3] = D3DDECLTYPE_FLOAT3;
|
||||
GFXD3D9DeclType[GFXDeclType_Float4] = D3DDECLTYPE_FLOAT4;
|
||||
GFXD3D9DeclType[GFXDeclType_Color] = D3DDECLTYPE_D3DCOLOR;
|
||||
GFXD3D9DeclType[GFXDeclType_UByte4] = D3DDECLTYPE_UBYTE4;
|
||||
VALIDATE_LOOKUPTABLE( GFXD3D9DeclType, GFXDeclType );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
void GFXD3D9PrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
|
||||
{
|
||||
AssertFatal(!mLocked, "GFXD3D9PrimitiveBuffer::lock - Can't lock a primitive buffer more than once!");
|
||||
|
||||
mLocked = true;
|
||||
U32 flags=0;
|
||||
switch(mBufferType)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue