2016-06-10 160 views
1

我有很多树通过在我的地形生成应用程序内使用实例呈现。我将一个实例列表与我的相机视锥体进行比较,以测试它们是否可见。如果它们可见,则将它们推送到实例向量。每一帧,如果有树可见,我更新树实例缓冲区。这工作非常好,每帧渲染树没有任何问题,但是,我重新创建实例缓冲区每帧,而不是更新它。DirectX11更新动态实例缓冲区

我最近改变了更新功能,我认为反而会更新缓冲区:

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); 
} 

的问题是,树木的arent正确呈现,因为有很多闪烁(其中我做不到真正捕捉得非常好),我只能形容为树木到处瞬移:

enter image description here

缓冲区是否正确设置了“D3D11_USAGE_DYNAMIC”使用标志和“D3D11_CPU_ACCESS_WRITE”访问佛罗里达州股份公司。

立即明白我做错了什么?作为参考,这是缓冲是如何重建以前

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

''Map''返回一个你没有检查的HRESULT。你需要用''SUCCEEDED'',''FAILED''或[ThrowIfFiled](https://github.com/Microsoft/DirectXTK/wiki/ThrowIfFiled)来检查所有的HRESULT失败。 –

+0

谢谢,没有看到。此外,它正在返回S_OK。 – Daniel

+0

您是否使用您现在具有的最大实例数创建实例缓冲区,您只更新它或使用第一次选择的大小结果? – galop1n

回答

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));