我通过在我的地形生成应用程序中使用实例化来渲染大量树。我将实例列表与我的相机视锥体进行比较,以测试它们是否可见。如果它们可见,则会将它们推送到实例向量。每个帧,如果有树可见,我更新树实例缓冲区。这非常正常,并且每个帧都呈现树而没有任何问题,但是,我每帧重新创建实例缓冲区,而不是更新它。
我最近更改了更新功能,我认为它会更新缓冲区:
void CModel::UpdateInstances(const std::vector<SInstance>& instances, ID3D11DeviceContext* context)
{
D3D11_MAPPED_SUBRESOURCE resource;
ZeroMemory(&resource, sizeof(resource));
mInstanceCount = instances.size();
size_t copySize = sizeof(SInstance) * mInstanceCount;
context->Map(mIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
memcpy(resource.pData, &instances[0], copySize);
context->Unmap(mIB, 0);
}
问题是,树木没有正确渲染,因为有很多闪烁(我无法捕捉得非常好),我只能将其描述为传送到各处的树木:
使用&#39; D3D11_USAGE_DYNAMIC&#39;正确设置缓冲区。使用标志和&#39; D3D11_CPU_ACCESS_WRITE&#39;访问标志。
我做错了吗?作为参考,这是如何重新创建缓冲区之前:
void CModel::UpdateInstances(const std::vector<SInstance>& instances, ID3D11Device* device)
{
mInstanceCount = instances.size();
if (mIB)
SafeRelease(mIB);
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_DYNAMIC;
ibd.ByteWidth = sizeof(SInstance) * mInstanceCount;
ibd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
ibd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA isr;
isr.pSysMem = &instances[0];
isr.SysMemPitch = 0;
isr.SysMemSlicePitch = 0;
DXHRes(device->CreateBuffer(&ibd, &isr, &mIB));
}
答案 0 :(得分:0)
正如@ galop1n指出的那样,问题是由于我没有使用可能的最大实例数创建实例缓冲区。
为了解决这个问题,我只是简单地创建了缓冲区。
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_DYNAMIC;
ibd.ByteWidth = sizeof(SInstance) * maxInstances;
ibd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
ibd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA isr;
isr.pSysMem = &instances[0];
isr.SysMemPitch = 0;
isr.SysMemSlicePitch = 0;
DXHRes(device->CreateBuffer(&ibd, &isr, &mIB));