简体   繁体   English

DirectX11更新动态实例缓冲区

[英]DirectX11 Update Dynamic Instance Buffer

I have a multitude of trees being rendered through the use of instancing within my terrain generation app. 我通过在我的地形生成应用程序中使用实例化来渲染大量树。 I compare an instance list with my cameras frustum, to test whether they are visible. 我将实例列表与我的相机视锥体进行比较,以测试它们是否可见。 If they are visible, they get pushed to an instance vector. 如果它们可见,则会将它们推送到实例向量。 Each frame, if there are trees visible, I update the tree instance buffer. 每个帧,如果有树可见,我更新树实例缓冲区。 This works absolutely fine and the trees were rendered each frame without any problems, however, I recreated the instance buffer each frame, rather than updated it. 这非常正常,并且每个帧都呈现树而没有任何问题,但是,我每帧重新创建实例缓冲区,而不是更新它。

I recently changed the update function, which I thought would instead update the buffer: 我最近更改了更新功能,我认为它会更新缓冲区:

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

The problem is, the trees arent rendered correctly, as there is a lot of flickering (which I couldn't really capture very well), which I can only describe as the trees teleporting everywhere: 问题是,树木没有正确渲染,因为有很多闪烁(我无法真正捕捉到它),我只能将其描述为传送到各处的树木:

在此输入图像描述

The buffer is properly set up with 'D3D11_USAGE_DYNAMIC' usage flag and 'D3D11_CPU_ACCESS_WRITE' access flag. 使用'D3D11_USAGE_DYNAMIC'使用标志和'D3D11_CPU_ACCESS_WRITE'访问标志正确设置缓冲区。

Is it immediately obvious what I'm doing wrong? 我的错误立即显而易见吗? For reference this is how the buffer was recreated previously : 作为参考,这是先前重建缓冲区的方式:

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

As @galop1n pointed out, the issue was due to the fact that I wasn't creating the instance buffer with the maximum amount of instances that were possible. 正如@ galop1n指出的那样,问题是由于我没有使用可能的最大实例数创建实例缓冲区。

To solve the issue, I simply created the buffer with this in mind. 为了解决这个问题,我简单地创建了缓冲区。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM