C++ direct x 11智能创建顶点缓冲区

C++ direct x 11智能创建顶点缓冲区,c++,directx-11,C++,Directx 11,我有一个难题,完全难住了我。假设我有两个具有不同顶点类型的着色器,如下所示: // light shader struct vertexInputType { float4 position : POSITION; float2 tex : TEXCOORD0; float3 normal : NORMAL; }; // color shader struct vertexInputType { float4 position : POSITION; f

我有一个难题,完全难住了我。假设我有两个具有不同顶点类型的着色器,如下所示:

// light shader
struct vertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
};

// color shader
struct vertexInputType
{
    float4 position : POSITION;
    float4 color : COLOR;
};

// bump mapping shader
struct vertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 binormal : BINORMAL;
    float3 tangent : TANGENT;
};
现在让我们假设我有一个包含所有这些数据的模型。我不能完全让它们都在同一个缓冲区中,并按照我的选择使用所有3个进行渲染,因为它们的数据布局都不正确。我认为只有两种选择可以让这成为可能,这两种选择都同样痛苦

1) 我可以在ram中有一个大的缓冲区来保存所有的数据,然后每次绘制调用,我从着色器对象中获取顶点类型,并使用正确的信息创建一个新的顶点缓冲区。正如你所看到的,这将是非常缓慢的

或者

2) 在初始化模型时,我可以创建多个ID3D11缓冲区,其中一个缓冲区具有位置和颜色,一个缓冲区具有位置、texcoord和法线,一个缓冲区具有位置、texcoord、法线、副法线和切线,以及模型具有信息的任何其他顶点类型所需的缓冲区。相比之下,这会删除可用的vram,使其成为nogo


我看不出有任何其他方法可以做到这一点。其他d3d人员是如何做到这一点的?

诀窍是将数据分成流:p、T、A

流p包含位置和法线。使用照明渲染顶点时需要此数据。还可以包括副法线和顶点颜色数据

流T包含纹理信息,因此最多可以有8个TU通道。应注意存储此流中编码的通道数量,以确保内存带宽不会浪费在通过GPU总线复制空通道上

流A包含动画信息、骨骼权重等


根据渲染管道的体系结构,可以有更多或更少的通道。这里的技巧是使用FVF动态定义数据布局。这种体系结构的一个优点是最佳内存带宽利用率。当需要多个渲染过程,但不是每个过程都需要所有数据时,这一点尤其重要。

在DX11上下文中,您可以询问这一点,这是一件好事-与以前的版本相比,这一概念简化了很多。您可以使用创建顶点数据的多个布局(一个用于上面提供的每个结构),并在希望对同一顶点缓冲区进行不同解释的点处使用正确的布局调用

编辑:查找创建输入布局对象的示例


希望这有帮助

是的,到目前为止,我在为着色器创建输入布局时使用了教程,但现在我很好奇输入布局是如何设置的。例如,你是说我可以有一个ID3D11缓冲区,它保存所有数据,如位置、颜色、法线、纹理等,然后可以设置布局以拾取该着色器的各个元素?我该怎么做?现在我只将第一个input desc元素及其alignedbyteoffset成员定义为0,然后将其余元素定义为D3D11_input_PER_VERTEX_DATA。我希望这样做的背后的方法是什么?woops意味着其余的被设置为D3D11\u APPEND\u ALIGNED\u元素。复制粘贴了它下面的一个:Pwow,现在我知道它与输入布局有关,我只是设法用谷歌搜索了这篇文章。有点解释了我需要知道的一切:\。谢谢你让我走上正轨!只是做了一个很长的编辑来解释一切,但是你的链接效果更好。我将把它作为编辑添加到我的答案中,这样以后来的人就不必在评论中翻来翻去了。不过,谢谢你的帮助。嗯,我想FVF和streams是d3d9。我真的不知道你在说什么:\据我所知-FVF被丢弃在D3D11中: