DirectX 11の使用と学習を簡単にするために、独自の「Engine」クラスを作成しています。その「エンジン」には、レンダリングするオブジェクトのリストがあります。それらのいくつかは「プリミティブ」(独自のBoxクラス)です。
問題は、Box :: render()が関数呼び出しごとにバッファーを作成することです。
関数呼び出しごとに計算しないように何かを変更できますか?
たぶん、コンストラクターでg_pIndexBufferを1回だけ計算し、ボックスごとに保持する必要がありますか?しかし、g_pVertexBufferとg_pConstantBufferはどうでしょうか?
私は箱を求めているだけでなく、もっと一般的です-他のプリミティブやメッシュを描きたいときに状況は変わりますか?(Boxの場合、g_pVertexBufferを1回計算でき、マトリックスを使用してオブジェクトをスケーリングするだけではないと思います)。
コードは次のようになります(ここではコードの一部をスキップしました。コードはDirectX SDKのチュートリアルに基づいています)。
Box::render(
XMFLOAT4X4 &viewM,
XMFLOAT4X4 &projectionM,
ID3D11Buffer* g_pConstantBuffer, ID3D11DeviceContext* g_pImmediateContext,
ID3D11VertexShader* g_pVertexShader,
ID3D11PixelShader* g_pPixelShader,
ID3D11Device * g_pd3dDevice,
ID3D11Buffer* g_pIndexBuffer){
...
// Create vertex buffer
SimpleVertex vertices[] =
{
{ XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 0.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) },
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 8;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
ID3D11Buffer* g_pVertexBuffer;
HRESULT hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset);
WORD indices[] =
{
3,1,0, 2,1,3,
0,5,4, 1,5,0,
3,4,7, 0,4,3,
1,6,5, 2,6,1,
2,7,6, 3,7,2,
6,4,5, 7,4,6,
};
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( WORD ) * 36; // 36 vertices needed for 12 triangles in a triangle list
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
InitData.pSysMem = indices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
// Set index buffer
g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );
// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Create the constant buffer
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBuffer2);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pConstantBuffer );
...
XMMATRIX mSpin = XMMatrixRotationZ( a );
XMMATRIX mOrbit = XMMatrixRotationY( b );
XMMATRIX mTranslate = XMMatrixTranslation( c, d, e );
XMMATRIX mScale = XMMatrixScaling( f, g, h );
XMMATRIX g_World = mScale * mSpin * mTranslate * mOrbit;
ConstantBuffer2 cb1;
cb1.mWorld = XMMatrixTranspose( g_World );
XMMATRIX g_View = XMLoadFloat4x4(&viewM);
XMMATRIX g_Projection = XMLoadFloat4x4(&projectionM);
cb1.mView = XMMatrixTranspose( g_View );
cb1.mProjection = XMMatrixTranspose( g_Projection );
g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb1, 0, 0 );
g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer );
g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
g_pImmediateContext->DrawIndexed( 36, 0, 0 );
}