DirectX11更新动态实例缓冲区

Onemandan

通过在地形生成应用程序中使用实例化,我渲染了许多树木。我将实例列表与我的相机视锥表进行了比较,以测试它们是否可见。如果它们是可见的,则将它们推送到实例向量。每帧,如果有可见的树,我将更新树实例缓冲区。这项工作绝对正常,并且在每个帧上渲染树都没有任何问题,但是,我在每个帧上重新创建了实例缓冲区,而不是对其进行了更新。

我最近更改了更新功能,以为可以更新缓冲区:

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

问题是,树木没有正确渲染,因为有很多闪烁(我无法很好地捕捉到),我只能形容为树木无处不在:

在此处输入图片说明

使用“ 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));
}
Onemandan

正如@ 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));

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章