directx11中的可选vertexbufferobjects

时间:2017-03-22 16:35:10

标签: directx-11 vertex-attributes

我有一些具有一些顶点信息的模型(几何)。例如,position,normal,color,texcoord这些信息中的每一个都有自己的顶点缓冲区。但其中一些模型的纹理坐标有些不... 为了管理这些差异,我写了一个顶点着色器,它正在检查,如果常量缓冲区内的标志是'#TextureCoordinates"是== 1.如果是这样,它是否使用texcoord参数。 但Directx并不真正喜欢这种解决方法并打印出来:

  

D3D11 INFO:ID3D11DeviceContext :: Draw:当前Input Layout的声明引用输入槽3中的Element [3],但没有绑定到此槽的Buffer。这是可以的,因为从空槽读取被定义为返回0.开发人员也可能知道无论如何都不会使用数据。如果开发人员实际上打算在这里绑定输入缓冲区,这只是一个问题。 [执行信息#348:DEVICE_DRAW_VERTEX_BUFFER_NOT_SET]

我不确定每个硬件是否都能正确处理这个问题,而且在输出内部看到这个"警告"并不好。每一帧...... 我知道我可以写两个着色器,一个有一个没有texcoods,但问题是这不是唯一可能缺少的参数......有些颜色不是其他颜色,有些颜色和纹理坐标等等。为每个顶点缓冲输入组合写一个着色器是极其冗余的。这是非常糟糕的,因为如果我们改变一个着色器,我们也必须改变所有其他着色器。还可以将着色器的一部分放到不同的文件中并包含它们,但这会让人感到困惑。

有没有办法说directx特定的顶点缓冲区是可选的? 或者有人知道这个问题的更好解决方案吗?

1 个答案:

答案 0 :(得分:1)

您可以通过编程方式禁止显示此特定邮件。由于它是 INFO 而不是 ERROR CORRUPTION 消息,因此可以安全地忽略。

#include <wrl/client.h>

using Microsoft::WRL::ComPtr;

ComPtr<ID3D11Debug> d3dDebug;
if ( SUCCEEDED( device.As(&d3dDebug) ) )
{
    ComPtr<ID3D11InfoQueue> d3dInfoQueue;
    if ( SUCCEEDED( d3dDebug.As(&d3dInfoQueue) ) )
    {
#ifdef _DEBUG
        d3dInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_CORRUPTION, true );
        d3dInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_ERROR, true );
#endif
        D3D11_MESSAGE_ID hide[] =
        {
            D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
            D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_NOT_SET, // <--- Your message here!
            // Add more message IDs here as needed 
        };
        D3D11_INFO_QUEUE_FILTER filter = {};
        filter.DenyList.NumIDs = _countof(hide);
        filter.DenyList.pIDList = hide;
        d3dInfoQueue->AddStorageFilterEntries( &filter );
    }
}

除了抑制“噪音”消息之外,在调试版本中,如果您点击 ERROR CORRUPTION 消息,这也会导致调试层生成断点因为那些确实需要修复。

请参阅Direct3D SDK Debug Layer Tricks

  

注意我在这里使用ComPtr来简化QueryInterface链,我假设您将设备保持为ComPtr<ID3D11Device> device,而不是Anatomy of Direct3D 11 Create Device < / p>      

我还假设您使用的是VS 2013或更高版本,因此D3D11_INFO_QUEUE_FILTER filter = {};足以对结构进行零填充。