在Directx10和11中更新顶点缓冲区

时间:2018-01-23 16:59:45

标签: c++ directx directx-10

我在程序中使用Directx10。当我尝试更改顶点的位置时,我得到一个错误:

  

在0x558CA083(d3d10core.dll)中抛出异常   NBodyProblemDebug.exe:0xC0000005:访问冲突读取位置   00000000

在运行时执行下一个代码期间发生:

    D3D10_MAPPED_TEXTURE3D resourse;        
    ZeroMemory(&resourse, sizeof(D3D10_MAPPED_TEXTURE3D));
    g_pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &resourse.pData); //exception is thrown here
    memcpy(resourse.pData, positions, 4 * n_bodies * sizeof(float));
    g_pVertexBuffer->Unmap();

其中veкtex缓冲区初始化如下:

    float * positions;
    ID3D10Buffer*  g_pVertexBuffer = nullptr;
    D3D10_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D10_USAGE_DYNAMIC;
    bd.ByteWidth = sizeof( SimpleVertex ) * bodies;
    bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
    D3D10_SUBRESOURCE_DATA InitData;
    ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = positions;
    result = m_device->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );

应该做些什么来解决它?这段代码是否与Directx11中使用的代码相当:

 D3D11_MAPPED_SUBRESOURCE resourse;
 ZeroMemory(&resourse, sizeof(D3D11_MAPPED_SUBRESOURCE));
 g_pImmediateContext->Map(g_pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resourse);
 memcpy(resourse.pData, positions, 4 * bodies * sizeof(float));     
 g_pImmediateContext->Unmap(g_pVertexBuffer, 0);

1 个答案:

答案 0 :(得分:2)

您的代码没有进行任何错误检查。每当COM API返回HRESULT时,您必须检查它是否失败。如果忽略返回值是安全的,那么它将返回void。您应该使用SUCCEEDEDFAILED宏来检查结果,或采用类似ThrowIfFailed的内容。

D3D11_MAPPED_SUBRESOURCE resource = {};
if ( SUCCEEDED(
    g_pImmediateContext->Map(g_pVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD,
       0, &resource) )
{
    memcpy(resourse.pData, positions, 4 * bodies * sizeof(float));     
    g_pImmediateContext->Unmap(g_pVertexBuffer, 0);
}

如果您注意到在Map的行上抛出了异常,那么可能您错过了程序中较早的HRESULT导致g_pImmediateContext仍然是nullptr。< / p>

  

请注意,ZeroMemory非常老派。如果您在VS 2013之前使用的是Visual C ++版本,则只需要它。使用VS 2013或更高版本,C ++ 11统一初始化规则意味着D3D11_MAPPED_SUBRESOURCE resource = {};保证用零填充结构。

如果您在适当的时候检查了所有HRESULTs,则调试DirectX应用程序的第二步是启用DEBUG设备。然后,这将提供有关调试输出窗口中任何故障的其他详细信息,这将有助于您查明程序中的故障情况。请参阅Anatomy of Direct3D 11 Create DeviceDirect3D SDK Debug Layer Tricks

顺便说一句,根据你的风格,你使用的是COM接口的原始指针。您应该考虑采用像ComPtr这样的智能指针。

  

完全没有理由继续使用DirectX 10.所有支持运行DirectX 10的平台都可以运行DirectX 11. DirectX 11支持更多硬件,具有更好的实用程序库支持,更好的工具支持,是目前的主流'版本的DirectX。不要使用DirectX 10.从DirectX 10到DirectX 11的移植非常简单。请参阅MSDNLiving without D3DXDirect3D 11 Deployment for Game Developers