简体   繁体   English

DirectX 11:使用多个顶点缓冲区时,如何定义输入布局?

[英]DirectX 11: how to define input layout when using more than one vertex buffer?

Using Direct3D 11, I would like to be able to use separate vertex buffers for positions and color. 使用Direct3D 11,我希望能够对位置和颜色使用单独的顶点缓冲区。 I want do do that when positions rarely change at runtime, whereas colors may change quite often. 当位置在运行时很少改变而颜色可能经常改变时,我想这样做。 The subject is not new but I could not find a comprehensive answer to correctlty handle many vertex buffers/shaders. 这个主题不是新话题,但是我无法找到正确的答案来正确处理许多顶点缓冲区/着色器。 If I'm quite confident on how to create and set the vertex buffers, I'm not sure how to define the layout. 如果我对如何创建和设置顶点缓冲区很有信心,则不确定如何定义布局。 To experiment, I started from a MSDN tutorial that just draw a single triangle with just one vertex shader. 为了进行实验,我从MSDN教程开始,该教程只用一个顶点着色器绘制了一个三角形。 I splitted the shader into 2 parts, position and color. 我将着色器分为位置和颜色两部分。

Hereafter are the main lines of my HLSL and C++ code. 以下是我的HLSL和C ++代码的主要内容。

// ****** Shaders file ***** // ******着色器文件*****

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR0;
};

// Position shader
VS_OUTPUT VPS( float4 Pos : POSITION )
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    output.Pos = Pos;
    return output;
}

// Color shader
VS_OUTPUT VCS( float4 Color : COLOR )
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    output.Color = Color;
    return output;
}

// Pixel shader
float4 PS( VS_OUTPUT input ) : SV_Target
{
    return input.Color;
}

// ********** C++ file abstract ********** // ********** C ++文件摘要**********

// Position shader
ID3DBlob* pVPSBlob
ID3D11VertexShader* g_pVertexShader

// Color shader
ID3DBlob* pVCSBlob
ID3D11VertexShader* g_pVertexColorShader

// Pixel shader
ID3DBlob* pPSBlob
ID3D11InputLayout* g_pVertexLayout

// Vertex buffers
ID3D11Buffer* g_pVertexBuffer = nullptr;
ID3D11Buffer* g_pVertexColorBuffer = nullptr;

// I compile and create the shaders with:
D3DCompileFromFile(), CreateVertexShader()



// I define the input vertex position layout in slot 0
D3D11_INPUT_ELEMENT_DESC positionLayout[] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE( positionLayout );

// Create the input vertex layout
hr = g_pd3dDevice->CreateInputLayout( positionLayout, numElements, pVPSBlob->GetBufferPointer(),
                                      pVPSBlob->GetBufferSize(), &g_pVertexLayout );

// Set the input vertex layout
g_pImmediateContext->IASetInputLayout( g_pVertexLayout );


 // I define the input color layout in slot 1
D3D11_INPUT_ELEMENT_DESC colorsLayout[] =
{
    { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
numElements = ARRAYSIZE( colorsLayout );

// Create the input colors layout
hr = g_pd3dDevice->CreateInputLayout( colorsLayout, numElements, pVCSBlob->GetBufferPointer(),
                                      pVCSBlob->GetBufferSize(), &g_pVertexColorLayout );

// Set the input color layout
g_pImmediateContext->IASetInputLayout( g_pVertexColorLayout );

// I set the 3 shaders:
g_pImmediateContext->VSSetShader( g_pVertexShader, nullptr, 0 );
g_pImmediateContext->VSSetShader( g_pVertexColorShader, nullptr, 0 );
g_pImmediateContext->PSSetShader( g_pPixelShader, nullptr, 0 );


// I create 2 vertex buffers for positions and colors and set them

// Set the positions & colors vertex buffers
ID3D11Buffer *vertexBuffers[] = { g_pVertexBuffer, g_pVertexColorBuffer };
UINT strides[] = { sizeof( SimpleVertex ), sizeof( ColorVertex ) };
UINT offsets[] = { 0, 0};
g_pImmediateContext->IASetVertexBuffers( 0, 2, vertexBuffers, strides, offsets );

I also tried to define the layout element into a single array, in two different slots, but it didn't work either. 我还尝试将layout元素定义为一个数组,在两个不同的插槽中,但是它也不起作用。 In that case, what shader should I use? 在那种情况下,我应该使用什么着色器?

All I could get was an empty screen, and I'm getting stuck... Thanks in advance if someone could help. 我所能得到的只是一个空白的屏幕,而且我陷入了困境……如果有人可以帮助,请先谢谢。

You can only have one input layout and one vertex shader set on the device context at one time. 一次只能在设备上下文上设置一个输入布局和一个顶点着色器。 Each time you call IASetInputLayout and VSSetShader the previous layout/shader is replaced with the new one. 每次调用IASetInputLayoutVSSetShader ,以前的布局/着色器都会被新的替换。 Merge your two input layout structures into one structure, and your HLSL vertex shaders into one shader. 将两个输入布局结构合并为一个结构,并将HLSL顶点着色器合并为一个着色器。 The InputSlot field member of D3D11_INPUT_ELEMENT_DESC will determine which vertex buffer is used for that element. 所述InputSlot的场构件D3D11_INPUT_ELEMENT_DESC将决定哪些顶点缓冲器用于该元素。

Something like: 就像是:

VS_OUTPUT VS( float4 Pos : POSITION, float4 Color : COLOR)
{
    VS_OUTPUT output = (VS_OUTPUT)0;
    output.Pos = Pos;
    output.Color = Color;
    return output;
}
D3D11_INPUT_ELEMENT_DESC positionLayout[] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

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

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