我用DirectXToolKit做一些基本的渲染,我希望能够获得每个模型的顶点坐标,以便计算模型之间的碰撞。
目前,我有一些测试代码可以加载模型,但ID3D11Buffer
在内部使用CreateFromSDKMESH
加载
void Model3D::LoadSDKMESH(ID3D11Device* p_device, ID3D11DeviceContext* device_context, const wchar_t* file_mesh)
{
mAlpha = 1.0f;
mTint = DirectX::Colors::White.v;
mStates.reset(new DirectX::CommonStates(p_device));
auto fx = new DirectX::EffectFactory(p_device);
fx->SetDirectory(L"media");
mFxFactory.reset(fx);
mBatch.reset(new DirectX::PrimitiveBatch<DirectX::VertexPositionColor>(device_context));
mBatchEffect.reset(new DirectX::BasicEffect(p_device));
mBatchEffect->SetVertexColorEnabled(true);
{
void const* shaderByteCode;
size_t byteCodeLength;
mBatchEffect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);
HR(p_device->CreateInputLayout(DirectX::VertexPositionColor::InputElements,
DirectX::VertexPositionColor::InputElementCount,
shaderByteCode, byteCodeLength,
mBatchInputLayout.ReleaseAndGetAddressOf()));
}
mModel = DirectX::Model::CreateFromSDKMESH(p_device, file_mesh, *mFxFactory);
}
我知道有一种方法可以从ID3D11Buffer
获取顶点,在这里回答:
How to read vertices from vertex buffer in Direct3d11
但他们建议不要从GPU内存加载。所以我假设将顶点提前加载到一个单独的容器中会更好。
答案 0 :(得分:0)
我查看了CreateFromSDKMESH
,并且有一些可公开访问的功能,而无需更改XTK
要在加载模型时获取顶点,请将以上问题中的行mModel = DirectX::Model::CreateFromSDKMESH(p_device, file_mesh, *mFxFactory);
替换为:
size_t data_size = 0;
std::unique_ptr<uint8_t[]> v_data;
HRESULT hr = DirectX::BinaryReader::ReadEntireFile(file_mesh, v_data, &data_size);
if (FAILED(hr))
{
DirectX::DebugTrace("CreateFromSDKMESH failed (%08X) loading '%ls'\n", hr, file_mesh);
throw std::exception("CreateFromSDKMESH");
}
uint8_t* mesh_data = v_data.get();
mModel = DirectX::Model::CreateFromSDKMESH(p_device, v_data.get(), data_size, *mFxFactory, false, false);
mModel->name = file_mesh;
auto v_header = reinterpret_cast<const DXUT::SDKMESH_HEADER*>(mesh_data);
auto vb_array = reinterpret_cast<const DXUT::SDKMESH_VERTEX_BUFFER_HEADER*>(mesh_data + v_header->VertexStreamHeadersOffset);
if(v_header->NumVertexBuffers < 1)
throw std::exception("Vertex Buffers less than 1");
auto& vertex_header = vb_array[0];
uint64_t buffer_data_offset = v_header->HeaderSize + v_header->NonBufferDataSize;
uint8_t* buffer_data = mesh_data + buffer_data_offset;
auto verts_pairs = reinterpret_cast<std::pair<Vector3,Vector3>*>(buffer_data + (vertex_header.DataOffset - buffer_data_offset));
在那里,访问坐标应该像
一样简单 float x = verts_pairs[0].first.x;
并且顶点总数存储在
vertex_header.NumVertices
不要忘记加载顶点缓冲区后会被删除,所以你可能想要做类似的事情:
memcpy(vertexBuffer, reinterpret_cast<std::pair<Vector3,Vector3>*>(buffer_data + (vertex_header.DataOffset - buffer_data_offset)), vertexCnt);
此外,顶点缓冲区不会被绘制函数转换,所以你需要自己进行转换
谢谢,