0

我有一些模型(几何)有一些顶点信息。例如位置、法线、颜色、纹理坐标,这些信息中的每一个都有自己的顶点缓冲区。但是其中一些模型有纹理坐标有些没有......为了管理这些差异,我编写了一个顶点着色器,它正在检查常量缓冲区“hasTextureCoordinates”中的标志是否 == 1。如果是这样,它是否使用 texcoord 参数。但是 Directx 并不真正喜欢这种解决方法并打印出:

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

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

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

4

1 回答 1

1

您可以通过编程方式隐藏此特定消息。因为它是一个INFO而不是ERRORCORRUPTION消息,所以可以安全地忽略它。

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

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

请参阅Direct3D SDK 调试层技巧

注意我在这里使用ComPtr来简化QueryInterface链,我假设您将您的设备保持ComPtr<ID3D11Device> device为我在Direct3D 11 创建设备的解剖中所做的那样

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

于 2017-03-22T17:49:42.890 回答