DirectX 11: как определить структуру ввода при использовании более одного буфера вершин?

0

Используя Direct3D 11, я хотел бы иметь возможность использовать отдельные буферы вершин для позиций и цвета. Я хочу делать это, когда позиции редко меняются во время выполнения, тогда как цвета могут часто меняться. Тема не нова, но я не смог найти исчерпывающий ответ на правильность обработки многих буферов/шейдеров вершин. Если я достаточно уверен в том, как создавать и устанавливать буферы вершин, я не уверен, как определить макет. Чтобы поэкспериментировать, я начал с учебника MSDN, который просто рисует один треугольник только с одним вершинным шейдером. Я разделил шейдер на 2 части, положение и цвет.

В дальнейшем это основные строки моего кода 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++ аннотация файла **********

// 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 );

Я также попытался определить элемент макета в один массив в двух разных слотах, но он тоже не работал. В таком случае, какой шейдер следует использовать?

Все, что я мог получить, было пустым экраном, и я застреваю... Спасибо заранее, если кто-то может помочь.

Теги:
directx

1 ответ

4

Вы можете иметь только один макет ввода и один вершинный шейдер, установленные в контекст устройства за один раз. Каждый раз, когда вы вызываете IASetInputLayout и VSSetShader предыдущий макет/шейдер заменяется новым. Объедините две структуры ввода в одну структуру, а ваша вершина HLSL вернется в один шейдер. InputSlot поля D3D11_INPUT_ELEMENT_DESC определит, какой буфер вершин используется для этого элемента.

Что-то вроде:

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 },
};
  • 0
    Я попробовал ваше решение, оно отлично работает ... Спасибо за вашу помощь и объяснения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню