DirectX 11 : Matrix Array for animation

Started by
3 comments, last by DieterVW 13 years, 1 month ago
Hi All,
iam trying to send a matrix array to the GPU but its not working >.<

This is what iam doing

Create a constant buffer to put the matrix array ( a XMMATRIX*)

#define MAX_BONE_MATRICES 100
...


// Create the constant buffers
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.ByteWidth = sizeof(XMMATRIX) * MAX_BONE_MATRICES;
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
hr = EngineStuff::EGraphicsDevice->CreateBuffer( &bd, NULL, &boneMatrixBuffer);
CheckError(hr);



Iam Updating the buffer using
(&obj.IOBJECT->GetMesh()->AbsoluteBone is the XMMATRIX*)

EngineStuff::EImediateDeviceContext->UpdateSubresource( boneMatrixBuffer, 0, NULL, &obj.IOBJECT->GetMesh()->AbsoluteBone, 0, 0 );


To send the buffer iam using

EngineStuff::EImediateDeviceContext->VSSetConstantBuffers( 1, 1, &boneMatrixBuffer); (in the hlsl, the buffer is binded to the b1 register)




The HLSL declaration of the buffer is


#define MAX_BONE_MATRICES 100
cbuffer cbChangeOnResize : register( b1 )
{
matrix BonesMatrix[MAX_BONE_MATRICES];
};



Iam the code that access the buffer is
(ibone is declared as a float, but constains a integer (like 1.00 ))


matrix m = BonesMatrix[ibone];
output.Pos += fweight * mul( pos, m );




The matrix that iam sending is declared as

AbsoluteBone = (XMMATRIX*) _aligned_malloc(sizeof(XMMATRIX) * 100,16);


(not all of the reserved space is used)


I tryed using pix, but its says that the buffer has only 48 float elements (and when i "cast" it to a matrix array it fails ... -> maybe i dont know how to use pix to debug constant buffers !!! >.<)

Is there a obvious mistake in this code ?
Thanks for every kind of help.
Advertisement
You're not creating a constant buffer, you're creating a regular buffer that can be bound as a shader resource. You need to create it with D3D11_BIND_CONSTANT_BUFFER, not D3D11_BIND_SHADER_RESOURCE.

You're not creating a constant buffer, you're creating a regular buffer that can be bound as a shader resource. You need to create it with D3D11_BIND_CONSTANT_BUFFER, not D3D11_BIND_SHADER_RESOURCE.


thanks for the answer
i correct that but still no working >.<

i simplified the example at most,
filling an array with identity matrix, sending them to the gpu and just multiply the position by him
but i still got nothing on the screen

in the directx10 with the effect api, u used the setmatrixarray() function, in dx 11, i dont know how to do it without the effect (i cant use it in this project ....)
is the a sample where i can look how to do it !!!


the new code that still not working is:



D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.ByteWidth = sizeof(XMMATRIX) * 10;
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
hr = EngineStuff::EGraphicsDevice->CreateBuffer( &bd, NULL, &boneMatrixBuffer);
CheckError(hr);





XMMATRIX mat[10];
for(int i = 0; i < 10 ; i++)
{
mat = XMMatrixIdentity();
}

EngineStuff::EImediateDeviceContext->UpdateSubresource( boneMatrixBuffer, 0, NULL, mat, 0, 0 ); ///tried &mat also (desperate measures ....)
EngineStuff::EImediateDeviceContext->VSSetConstantBuffers( 1, 1, &boneMatrixBuffer);






#define MAX_BONE_MATRICES 10
cbuffer cbChangeOnResize : register( b1 )
{
matrix BonesMatrix[MAX_BONE_MATRICES];
};

...


matrix mat = BonesMatrix[1];
output.Pos = mul( input.Pos, mat);
output.Pos = mul( output.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );



if i remove the line output.Pos = mul( input.Pos, mat); and change output.Pos = mul( output.Pos, World ); to output.Pos = mul( input.Pos, World ); it works (of course, im not using the matrix array)

any help ?









I thing i got it working
insted of using the UpdateSubResource i tryied the Map, Unmap way of updating buffers




D3D11_MAPPED_SUBRESOURCE subr;
ZeroMemory(&subr,sizeof(subr));
EngineStuff::EImediateDeviceContext->Map(boneMatrixBuffer,0,D3D11_MAP_WRITE_DISCARD ,0,&subr);

for(int i = 0; i < 10 ; i++)
{
( (XMMATRIX*) subr.pData) = XMMatrixIdentity();
}

EngineStuff::EImediateDeviceContext->Unmap(boneMatrixBuffer,0);




The UpdateSubResource function should work for matrix array ?
When i use it or the map unmap ? (what is the diference ? )
You have to use Map/Unmap with a dynamic or staging surface. UpdateSubresource will only work with a default usage.

This topic is closed to new replies.

Advertisement