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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -80,9 +80,13 @@ bool GenericConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstType
|
|||
(
|
||||
( pd.constType == GFXSCT_Float2x2 ||
|
||||
pd.constType == GFXSCT_Float3x3 ||
|
||||
pd.constType == GFXSCT_Float3x4 ||
|
||||
pd.constType == GFXSCT_Float4x3 ||
|
||||
pd.constType == GFXSCT_Float4x4 ) &&
|
||||
( constType == GFXSCT_Float2x2 ||
|
||||
constType == GFXSCT_Float3x3 ||
|
||||
constType == GFXSCT_Float3x3 ||
|
||||
constType == GFXSCT_Float3x4 ||
|
||||
constType == GFXSCT_Float4x3 ||
|
||||
constType == GFXSCT_Float4x4 )
|
||||
), "Mismatched const type!" );
|
||||
|
||||
|
|
@ -91,6 +95,7 @@ bool GenericConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstType
|
|||
{
|
||||
case GFXSCT_Float2x2 :
|
||||
case GFXSCT_Float3x3 :
|
||||
case GFXSCT_Float4x3 :
|
||||
case GFXSCT_Float4x4 :
|
||||
return setMatrix(pd, constType, size, data, basePointer);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -190,6 +190,8 @@ public:
|
|||
{
|
||||
AssertFatal( matrixType == GFXSCT_Float2x2 ||
|
||||
matrixType == GFXSCT_Float3x3 ||
|
||||
matrixType == GFXSCT_Float3x4 ||
|
||||
matrixType == GFXSCT_Float4x3 ||
|
||||
matrixType == GFXSCT_Float4x4,
|
||||
"GenericConstBuffer::set() - Invalid matrix type!" );
|
||||
|
||||
|
|
@ -200,6 +202,8 @@ public:
|
|||
{
|
||||
AssertFatal( matrixType == GFXSCT_Float2x2 ||
|
||||
matrixType == GFXSCT_Float3x3 ||
|
||||
matrixType == GFXSCT_Float3x4 ||
|
||||
matrixType == GFXSCT_Float4x3 ||
|
||||
matrixType == GFXSCT_Float4x4,
|
||||
"GenericConstBuffer::set() - Invalid matrix type!" );
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ enum GFXBufferType
|
|||
///< allowed.
|
||||
GFXBufferTypeVolatile, ///< Volatile vertex or index buffers are meant for vertices or indices that are essentially
|
||||
///< only used once. They can be resized without any performance penalty.
|
||||
|
||||
GFXBufferTypeImmutable, ///< Immutable buffers must specify the data when creating the buffer. Cannot be modified.
|
||||
|
||||
GFXBufferType_COUNT ///< Number of buffer types.
|
||||
|
|
@ -581,7 +582,9 @@ enum GFXShaderConstType
|
|||
GFXSCT_Float4,
|
||||
// Matrices
|
||||
GFXSCT_Float2x2,
|
||||
GFXSCT_Float3x3,
|
||||
GFXSCT_Float3x3,
|
||||
GFXSCT_Float3x4,
|
||||
GFXSCT_Float4x3,
|
||||
GFXSCT_Float4x4,
|
||||
// Scalar
|
||||
GFXSCT_Int,
|
||||
|
|
@ -621,6 +624,9 @@ enum GFXDeclType
|
|||
/// @see GFXVertexColor
|
||||
GFXDeclType_Color,
|
||||
|
||||
/// Four-component, packed, unsigned bytes ranged 0-255
|
||||
GFXDeclType_UByte4,
|
||||
|
||||
/// The count of total GFXDeclTypes.
|
||||
GFXDeclType_COUNT,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ public: //protected:
|
|||
U32 mPrimitiveCount;
|
||||
GFXBufferType mBufferType;
|
||||
GFXPrimitive *mPrimitiveArray;
|
||||
GFXDevice *mDevice;
|
||||
GFXDevice *mDevice;
|
||||
|
||||
U32 mVolatileStart;
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
// In debug builds we provide a TOC leak tracking system.
|
||||
|
|
@ -59,7 +61,8 @@ public: //protected:
|
|||
GFXPrimitiveBuffer( GFXDevice *device,
|
||||
U32 indexCount,
|
||||
U32 primitiveCount,
|
||||
GFXBufferType bufferType )
|
||||
GFXBufferType bufferType ) :
|
||||
mVolatileStart(0)
|
||||
{
|
||||
mDevice = device;
|
||||
mIndexCount = indexCount;
|
||||
|
|
@ -122,7 +125,7 @@ public: //protected:
|
|||
|
||||
// GFXResource interface
|
||||
/// The resource should put a description of itself (number of vertices, size/width of texture, etc.) in buffer
|
||||
virtual const String describeSelf() const;
|
||||
virtual const String describeSelf() const;
|
||||
};
|
||||
|
||||
class GFXPrimitiveBufferHandle : public StrongRefPtr<GFXPrimitiveBuffer>
|
||||
|
|
|
|||
|
|
@ -64,11 +64,11 @@ public:
|
|||
const GFXVertexFormat *vertexFormat,
|
||||
U32 vertexSize,
|
||||
GFXBufferType bufferType )
|
||||
: mNumVerts( numVerts ),
|
||||
: mDevice( device ),
|
||||
mVolatileStart( 0 ),
|
||||
mNumVerts( numVerts ),
|
||||
mVertexSize( vertexSize ),
|
||||
mBufferType( bufferType ),
|
||||
mDevice( device ),
|
||||
mVolatileStart( 0 )
|
||||
mBufferType( bufferType )
|
||||
{
|
||||
if ( vertexFormat )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ namespace GFXSemantic
|
|||
const String TANGENTW = String( "TANGENTW" ).intern();
|
||||
const String COLOR = String( "COLOR" ).intern();
|
||||
const String TEXCOORD = String( "TEXCOORD" ).intern();
|
||||
const String BLENDINDICES = String( "BLENDINDICES" ).intern();
|
||||
const String BLENDWEIGHT = String( "BLENDWEIGHT" ).intern();
|
||||
const String PADDING = String( "PADDING" ).intern();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -59,6 +62,9 @@ U32 GFXVertexElement::getSizeInBytes() const
|
|||
case GFXDeclType_Color:
|
||||
return 4;
|
||||
|
||||
case GFXDeclType_UByte4:
|
||||
return 4;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
|
|
@ -85,6 +91,7 @@ void GFXVertexFormat::copy( const GFXVertexFormat &format )
|
|||
mHasTangent = format.mHasTangent;
|
||||
mHasColor = format.mHasColor;
|
||||
mHasInstancing = format.mHasInstancing;
|
||||
mHasBlendIndices = format.mHasBlendIndices;
|
||||
mTexCoordCount = format.mTexCoordCount;
|
||||
mSizeInBytes = format.mSizeInBytes;
|
||||
mDescription = format.mDescription;
|
||||
|
|
@ -171,6 +178,35 @@ bool GFXVertexFormat::hasInstancing() const
|
|||
return mHasInstancing;
|
||||
}
|
||||
|
||||
bool GFXVertexFormat::hasBlendIndices() const
|
||||
{
|
||||
if ( mDirty )
|
||||
const_cast<GFXVertexFormat*>(this)->_updateDirty();
|
||||
|
||||
return mHasBlendIndices;
|
||||
}
|
||||
|
||||
U32 GFXVertexFormat::getNumBlendIndices() const
|
||||
{
|
||||
if ( mDirty )
|
||||
const_cast<GFXVertexFormat*>(this)->_updateDirty();
|
||||
|
||||
if ( !mHasBlendIndices )
|
||||
return 0;
|
||||
|
||||
U32 numIndices = 0;
|
||||
|
||||
for ( U32 i=0; i < mElements.size(); i++ )
|
||||
{
|
||||
const GFXVertexElement &element = mElements[i];
|
||||
|
||||
if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
|
||||
numIndices++;
|
||||
}
|
||||
|
||||
return numIndices;
|
||||
}
|
||||
|
||||
U32 GFXVertexFormat::getTexCoordCount() const
|
||||
{
|
||||
if ( mDirty )
|
||||
|
|
@ -199,6 +235,7 @@ void GFXVertexFormat::_updateDirty()
|
|||
mTexCoordCount = 0;
|
||||
|
||||
mHasColor = false;
|
||||
mHasBlendIndices = false;
|
||||
mHasNormal = false;
|
||||
mHasTangent = false;
|
||||
mSizeInBytes = 0;
|
||||
|
|
@ -222,6 +259,8 @@ void GFXVertexFormat::_updateDirty()
|
|||
mHasColor = true;
|
||||
else if ( element.isSemantic( GFXSemantic::TEXCOORD ) )
|
||||
++mTexCoordCount;
|
||||
else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
|
||||
mHasBlendIndices = true;
|
||||
|
||||
mSizeInBytes += element.getSizeInBytes();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ namespace GFXSemantic
|
|||
extern const String TANGENTW;
|
||||
extern const String COLOR;
|
||||
extern const String TEXCOORD;
|
||||
extern const String BLENDWEIGHT;
|
||||
extern const String BLENDINDICES;
|
||||
extern const String PADDING;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -184,10 +187,16 @@ public:
|
|||
|
||||
/// Returns true if there is a COLOR semantic in this vertex format.
|
||||
bool hasColor() const;
|
||||
|
||||
/// Returns true if there is a BLENDWEIGHT or BLENDINDICES semantic in this vertex format.
|
||||
bool hasBlendIndices() const;
|
||||
|
||||
/// Return true if instancing is used with this vertex format.
|
||||
bool hasInstancing() const;
|
||||
|
||||
/// Returns number of blend indices
|
||||
U32 getNumBlendIndices() const;
|
||||
|
||||
/// Returns the texture coordinate count by
|
||||
/// counting the number of TEXCOORD semantics.
|
||||
U32 getTexCoordCount() const;
|
||||
|
|
@ -230,6 +239,9 @@ protected:
|
|||
|
||||
/// Is true if there is a COLOR semantic in this vertex format.
|
||||
bool mHasColor;
|
||||
|
||||
/// Is true if there is a BLENDWEIGHT or BLENDINDICES semantic in this vertex format.
|
||||
bool mHasBlendIndices;
|
||||
|
||||
/// Is instaning used with this vertex format.
|
||||
bool mHasInstancing;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ GFXImplementVertexFormat( GFXVertexP )
|
|||
addElement( "POSITION", GFXDeclType_Float3 );
|
||||
}
|
||||
|
||||
GFXImplementVertexFormat( GFXVertexPad )
|
||||
{
|
||||
addElement("PADDING", GFXDeclType_UByte4);
|
||||
}
|
||||
|
||||
GFXImplementVertexFormat( GFXVertexPT )
|
||||
{
|
||||
addElement( "POSITION", GFXDeclType_Float3 );
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@
|
|||
#include "math/mPoint3.h"
|
||||
#endif
|
||||
|
||||
GFXDeclareVertexFormat( GFXVertexPad )
|
||||
{
|
||||
U32 data;
|
||||
};
|
||||
|
||||
GFXDeclareVertexFormat( GFXVertexP )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -608,13 +608,11 @@ void GFXGLDevice::drawIndexedPrimitive( GFXPrimitiveType primType,
|
|||
U32 startIndex,
|
||||
U32 primitiveCount )
|
||||
{
|
||||
AssertFatal( startVertex == 0, "GFXGLDevice::drawIndexedPrimitive() - Non-zero startVertex unsupported!" );
|
||||
|
||||
preDrawPrimitive();
|
||||
|
||||
U16* buf = (U16*)static_cast<GFXGLPrimitiveBuffer*>(mCurrentPrimitiveBuffer.getPointer())->getBuffer() + startIndex;
|
||||
U16* buf = (U16*)static_cast<GFXGLPrimitiveBuffer*>(mCurrentPrimitiveBuffer.getPointer())->getBuffer() + startIndex + mCurrentPrimitiveBuffer->mVolatileStart;
|
||||
|
||||
const U32 baseVertex = mCurrentVB[0]->mBufferVertexOffset;
|
||||
const U32 baseVertex = mCurrentVB[0]->mBufferVertexOffset + startVertex;
|
||||
|
||||
if(mDrawInstancesCount)
|
||||
glDrawElementsInstancedBaseVertex(GFXGLPrimType[primType], primCountToIndexCount(primType, primitiveCount), GL_UNSIGNED_SHORT, buf, mDrawInstancesCount, baseVertex);
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ static U32 shaderConstTypeSize(GFXShaderConstType type)
|
|||
return 16;
|
||||
case GFXSCT_Float3x3:
|
||||
return 36;
|
||||
case GFXSCT_Float4x3:
|
||||
return 48;
|
||||
case GFXSCT_Float4x4:
|
||||
return 64;
|
||||
default:
|
||||
|
|
@ -305,6 +307,9 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& ma
|
|||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[7] = mat[9];
|
||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[8] = mat[10];
|
||||
break;
|
||||
case GFXSCT_Float4x3:
|
||||
dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, (sizeof(F32) * 12));// matrix with end row chopped off
|
||||
break;
|
||||
case GFXSCT_Float4x4:
|
||||
{
|
||||
if(_glHandle->mInstancingConstant)
|
||||
|
|
@ -334,6 +339,13 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* ma
|
|||
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for matrix arrays");
|
||||
|
||||
switch (matrixType) {
|
||||
case GFXSCT_Float4x3:
|
||||
// Copy each item with the last row chopped off
|
||||
for (int i = 0; i<arraySize; i++)
|
||||
{
|
||||
dMemcpy(mBuffer + _glHandle->mOffset + (i*(sizeof(F32) * 12)), (F32*)(mat + i), sizeof(F32) * 12);
|
||||
}
|
||||
break;
|
||||
case GFXSCT_Float4x4:
|
||||
dMemcpy(mBuffer + _glHandle->mOffset, (F32*)mat, _glHandle->getSize());
|
||||
break;
|
||||
|
|
@ -443,6 +455,14 @@ bool GFXGLShader::_init()
|
|||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Tangent, "vTangent");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TangentW, "vTangentW");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Binormal, "vBinormal");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_BlendIndex0, "vBlendIndex0");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_BlendIndex1, "vBlendIndex1");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_BlendIndex2, "vBlendIndex2");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_BlendIndex3, "vBlendIndex3");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_BlendWeight0, "vBlendWeight0");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_BlendWeight1, "vBlendWeight1");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_BlendWeight2, "vBlendWeight2");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_BlendWeight3, "vBlendWeight3");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord0, "vTexCoord0");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord1, "vTexCoord1");
|
||||
glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord2, "vTexCoord2");
|
||||
|
|
@ -572,6 +592,9 @@ void GFXGLShader::initConstantDescs()
|
|||
case GL_FLOAT_MAT4:
|
||||
desc.constType = GFXSCT_Float4x4;
|
||||
break;
|
||||
case GL_FLOAT_MAT4x3: // jamesu - columns, rows
|
||||
desc.constType = GFXSCT_Float4x3;
|
||||
break;
|
||||
case GL_SAMPLER_1D:
|
||||
case GL_SAMPLER_2D:
|
||||
case GL_SAMPLER_3D:
|
||||
|
|
@ -805,6 +828,11 @@ void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
|
|||
case GFXSCT_Float3x3:
|
||||
glUniformMatrix3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
|
||||
break;
|
||||
case GFXSCT_Float4x3:
|
||||
// NOTE: To save a transpose here we could store the matrix transposed (i.e. column major) in the constant buffer.
|
||||
// See _mesa_uniform_matrix in the mesa source for the correct transpose algorithm for a 4x3 matrix.
|
||||
glUniformMatrix4x3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
|
||||
break;
|
||||
case GFXSCT_Float4x4:
|
||||
glUniformMatrix4fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,14 @@ namespace Torque
|
|||
GL_VertexAttrib_Tangent,
|
||||
GL_VertexAttrib_TangentW,
|
||||
GL_VertexAttrib_Binormal,
|
||||
GL_VertexAttrib_BlendIndex0,
|
||||
GL_VertexAttrib_BlendIndex1,
|
||||
GL_VertexAttrib_BlendIndex2,
|
||||
GL_VertexAttrib_BlendIndex3,
|
||||
GL_VertexAttrib_BlendWeight0,
|
||||
GL_VertexAttrib_BlendWeight1,
|
||||
GL_VertexAttrib_BlendWeight2,
|
||||
GL_VertexAttrib_BlendWeight3,
|
||||
GL_VertexAttrib_TexCoord0,
|
||||
GL_VertexAttrib_TexCoord1,
|
||||
GL_VertexAttrib_TexCoord2,
|
||||
|
|
|
|||
|
|
@ -187,6 +187,28 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
|
|||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
else if ( element.isSemantic( GFXSemantic::BLENDWEIGHT ) )
|
||||
{
|
||||
glElement.attrIndex = Torque::GL_VertexAttrib_BlendWeight0 + element.getSemanticIndex();
|
||||
glElement.elementCount = 4;
|
||||
glElement.normalized = false;
|
||||
glElement.type = GL_FLOAT;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
|
||||
{
|
||||
glElement.attrIndex = Torque::GL_VertexAttrib_BlendIndex0 + element.getSemanticIndex();
|
||||
glElement.elementCount = 4;
|
||||
glElement.normalized = false;
|
||||
glElement.type = GL_UNSIGNED_BYTE;
|
||||
glElement.stride = vertexSize;
|
||||
glElement.pointerFirst = (void*)buffer;
|
||||
|
||||
buffer += element.getSizeInBytes();
|
||||
}
|
||||
else // Everything else is a texture coordinate.
|
||||
{
|
||||
String name = element.getSemantic();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue