そのため、頂点構造体が頂点の位置、テクスチャ座標、法線、およびインスタンスのモデル マトリックスを取得する単純なシェーダーを使用して、DirectX10 でハードウェア インスタンス化を実行しようとしています。問題は、シェーダーのモデル マトリックスにデータを送信する入力レイアウトを作成することです。PIX を使用してデバッグすると、行列が無意味な値しか得られないことがわかります。
関連コード:
入力レイアウト
m_Tech = m_Effect->GetTechniqueByName("SimpleTech");
//Position-normal-texture vertex
D3D10_INPUT_ELEMENT_DESC posNormalTexVertexDesc[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"mTransform", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_INSTANCE_DATA, 1},
{"mTransform", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_INSTANCE_DATA, 1}
};
D3D10_PASS_DESC PassDesc;
m_Effect->GetTechniqueByName("SimpleTech")->GetPassByIndex(0)->GetDesc(&PassDesc);
HR(mp_D3DDevice->CreateInputLayout(posNormalTexVertexDesc, 7, PassDesc.pIAInputSignature,
PassDesc.IAInputSignatureSize, &m_InputLayout));
シェーダー構造体
struct VS_IN
{
float4 Pos : POSITION;
float2 TexCoord : TEXCOORD0;
float4 Normal : NORMAL;
row_major float4x4 mTransform : mTransform;
};
バッファ
void Model::BuildVertexBuffer()
{
D3D10_BUFFER_DESC vbd;
vbd.Usage = D3D10_USAGE_DEFAULT;
vbd.ByteWidth = sizeof(MeshVertex) * (UINT)m_Mesh->VertexCount();
vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = m_Mesh->VertexData();
m_D3DDevice->CreateBuffer(&vbd, &vinitData, &m_VertexBuffer);
}
void Model::BuildInstanceBuffer()
{
D3D10_BUFFER_DESC ibd;
ibd.Usage = D3D10_USAGE_DEFAULT;
ibd.ByteWidth = sizeof(D3DXMATRIX) * (UINT)m_instanceData->size();
ibd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &m_instanceData[0];
m_D3DDevice->CreateBuffer(&ibd, &vinitData, &m_InstanceBuffer);
}
ドローコール
void Model::Draw(Camera& camera)
{
UINT strides[2];
UINT offsets[2];
ID3D10Buffer* bufferPointers[2];
//Set buffer strides
strides[0] = sizeof(MeshVertex);
strides[1] = sizeof(D3DXMATRIX);
//Set buffer offsets
offsets[0] = 0;
offsets[1] = 0;
//Set the array of pointers to the vertex and instance buffers
bufferPointers[0] = m_VertexBuffer;
bufferPointers[1] = m_InstanceBuffer;
//Set the vertex and instance buffers to active in the input assembler so it may be rendered
m_D3DDevice->IASetVertexBuffers(0,2,bufferPointers, strides, offsets);
m_D3DDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//Set input layout
m_D3DDevice->IASetInputLayout(m_Effect->GetLayout());
//Set
m_Effect->SetResources(camera, NULL);
D3D10_TECHNIQUE_DESC techDesc;
ID3D10EffectTechnique* tech = m_Effect->GetTech();
tech->GetDesc( &techDesc );
for(UINT i = 0; i < techDesc.Passes; ++i)
{
ID3D10EffectPass* pass = tech->GetPassByIndex(i);
pass->Apply(0);
m_D3DDevice->DrawInstanced(m_Mesh->VertexCount(), m_instanceData->size(),0,0);
}
}
m_instanceData は、各インスタンスの D3DXMATRIX を保持するベクトルです。SDK に付属の例を見てみましたが、入力レイアウトは同じように見えますが、マトリックスが正しく転送されていませんか?
現在、テスト目的で単位行列をモデル行列として送信しているだけですが、まったく別のものとして表示されます。インスタンスバッファを初期化したら、データが確実にベクトルにあることを確認しました。
Edit1: BuildInstanceBuffer() メソッドを
void Model::BuildInstanceBuffer()
{
D3D10_BUFFER_DESC ibd;
ibd.Usage = D3D10_USAGE_DYNAMIC;
ibd.ByteWidth = sizeof(D3DXMATRIX) * (UINT)m_instanceData->size();
ibd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
ibd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
ibd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &m_instanceData[0];
m_D3DDevice->CreateBuffer(&ibd, &vinitData, &m_InstanceBuffer);
D3DXMATRIX* pMatrices = NULL;
m_InstanceBuffer->Map( D3D10_MAP_WRITE_DISCARD, NULL, ( void** )&pMatrices );
memcpy( pMatrices, m_InstanceBuffer, m_instanceData->size() * sizeof( D3DXMATRIX ) );
m_InstanceBuffer->Unmap();
}
2番目の編集:それは少し時期尚早だったと思います. 各行が適切なポイントで値を取得するため、シェーダーのモデル マトリックスが「正しく」埋められているようです。しかし、その値はまだ私が渡しているものではありません。
これは正直なところ、分ごとに奇妙になります。Visual Studio でプログラムをデバッグすると、緑色のメッシュが表示されます。PIX では、黒で表示されます。私は本当にこれで助けを使うことができました、私は今何が起こっているのかわかりません.