Direct3D 11 - Рисование треугольника

Я инициализировал все Direct3D 11, но когда я пришел нарисовать некоторую геометрию, геометрия не показывается.

Я создал Pipeline, Geometry и создал функцию рисования для геометрии, которую нужно нарисовать. Мой главный вопрос: может ли кто-нибудь помочь мне понять, почему в окне не нарисован треугольник?

void cSystem::Draw(UINT count)
{
    // draw stuff...    
    UINT stride = sizeof(Vertex);
    UINT offset = 0;
    p_D3D11DeviceContext->IASetVertexBuffers(0, 1, &p_VertextBuffer, &stride, &offset);

    p_D3D11DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    p_D3D11DeviceContext->Draw(3, 0);

    if (count == 0)
    {
        INFO(L"Draw() Complete");
    }   
}

void cSystem::InitGeometry() // initialise the geometry for the scene
{   
    Vertex vertices[] =
    {
        { D3DXVECTOR3(0.0f, 0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) },
        { D3DXVECTOR3(0.5f, -0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) },
        { D3DXVECTOR3(-0.5f, -0.5f, 0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) }
    };

    D3D11_BUFFER_DESC bdsc;
    ZeroMemory(&bdsc, sizeof(D3D11_BUFFER_DESC));
    bdsc.Usage = D3D11_USAGE_IMMUTABLE;
    bdsc.ByteWidth = sizeof(Vertex) * 3;
    bdsc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bdsc.CPUAccessFlags = 0;
    bdsc.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA vinitdata;
    ZeroMemory(&vinitdata, sizeof(D3D11_SUBRESOURCE_DATA));
    vinitdata.pSysMem = vertices;

    p_D3D11Device->CreateBuffer(&bdsc, &vinitdata, &p_VertextBuffer);   

    /*D3D11_MAPPED_SUBRESOURCE ms;
    p_D3D11DeviceContext->Map(p_VertextBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
    memcpy(ms.pData, vertices, sizeof(Vertex));
    p_D3D11DeviceContext->Unmap(p_VertextBuffer, NULL);*/

    INFO(L"InitGeometry() Complete");
}

void cSystem::InitPipeline(void)
{   
#if defined(DEBUG) || (_DEBUG)
    DWORD shaderflags = 0;
#endif
    //p_D3D11Device->GetFeatureLevel() == D3D_FEATURE_LEVEL_11_0;
    ID3D10Blob *VS_, *PS_ = NULL;
    D3DX11CompileFromFile(L"Shader.shader", 0, 0, "VS", "vs_5_0", 0, 0, 0, &VS_, 0, 0);
    D3DX11CompileFromFile(L"Shader.shader", 0, 0, "PS", "ps_5_0", 0, 0, 0, &PS_, 0, 0);

    p_D3D11Device->CreateVertexShader(VS_->GetBufferPointer(), VS_->GetBufferSize(), NULL, &p_VS);
    p_D3D11Device->CreatePixelShader(PS_->GetBufferPointer(), PS_->GetBufferSize(), NULL, &p_PS);

    p_D3D11DeviceContext->VSSetShader(p_VS, 0, 0);
    p_D3D11DeviceContext->PSSetShader(p_PS, 0, 0);

    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT NumElements = ARRAYSIZE(layout);

    p_D3D11Device->CreateInputLayout(layout, NumElements, VS_->GetBufferPointer(),
    VS_->GetBufferSize(), &p_InputLayout);

    p_D3D11DeviceContext->IASetInputLayout(p_InputLayout);

    VS_->Release();
    PS_->Release();

    INFO(L"InitPipeline() Complete");
}

void cSystem::D3D11RenderFrame_(void)
{
    // clear the back buffer
    p_D3D11DeviceContext->ClearRenderTargetView(p_D3D11RenderTargetView, m_BackBufferColour[0]);
    // clear the depth buffer
    p_D3D11DeviceContext->ClearDepthStencilView(p_D3D11DepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0.0f);  

    // draw 
    Draw(count++);

    // switch the back buffer and the front buffer
    p_D3D11SwapChain->Present(0, 0);
}

Шейдер (или.fx файл)

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut VS(float4 position : POSITION, float4 color : COLOR)
{
    VOut output;

    output.position = position;
    output.color = color;

    return output;
}


float4 PS(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

Ссылка на картинку программы находится здесь: http://i.imgur.com/JyNkPqQ.png

Вызовы выполняются правильно при выполнении программы, но не отображаются. На всякий случай, если мой вопрос забыт сверху, почему не отображается треугольник?

Я надеюсь, что кто-то может помочь..:)

3 ответа

Я не гуру в DirectX11 (на самом деле я только недавно начал), но кажется, что даже если ваш вершинный шейдер получит D3DXVECTOR3 для положения вершины, вы говорите, что POSITION является

Четырехкомпонентный 32-битный формат unsigned-normalized-integer, поддерживающий 8 бит на канал, включая альфа-канал.

в вашей структуре ввода. Теперь это сбивает с толку!

Вы должны использовать DXGI_FORMAT_R32G32B32_FLOAT,

Спасибо за чтение.

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

Обычно, когда я сталкиваюсь с этой проблемой, я загружаю графический отладчик, подобный тому, который включен в Visual Studio, и просматриваю каждый фрагмент состояния, отправляемый в графический процессор, чтобы выяснить, что пошло не так. Однако вначале это может быть сложно, если вы не знаете точно, что делает каждый кусочек государства и каким он должен быть. Но, в конце концов, вы учитесь, и вам нужно угадать догадки, выясняя, что пошло не так.

Еще одна полезная вещь - включить режим отладки на вашем компьютере. ID3D11Device, Для этого установите Flags параметр D3D11CreateDevice или же D3D11CreateDeviceAndSwapChain (что вы используете), чтобы D3D11_CREATE_DEVICE_DEBUG, Это выдаст предупреждения, если что-то идет не так.

В конце концов вам захочется научиться пользоваться графическим отладчиком, но прежде чем вы подойдете к этому вопросу, я бы рекомендовал сначала попытаться точно следовать учебному руководству, а затем вернуться и изменить его по своему вкусу. С каждым значительным изменением запускайте программу, чтобы убедиться, что она все еще работает. Когда это не так, вы знаете, что пошло не так.

К вашей проблеме. Одна проблема, которую я вижу, заключается в том, что вы не объявили свой элемент цвета в макете ввода. Вам нужно будет добавить это после элемента позиции:

{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }

В противном случае ваш шейдер не знает, где найти цвет в потоке вершин. Обратите внимание, что позиция также должна быть DXGI_FORMAT_R32G32B32_FLOAT как упоминалось в ответе Нарда. Без этих двух вещей, CreateInputLayout вернет нулевой входной макет, потому что он не соответствует входной сигнатуре вершинного шейдера.

Также убедитесь, что вы настраиваете область просмотра.

Могут быть и другие проблемы, но это трудно понять, не видя каждый сделанный вызов API.

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

 cbuffer Transform
 {
     matrix mWorld;
     matrix mView;
     matrix mProjection;
 }

затем в вершинном шейдере, сделайте это

output.position= mul(position, mWorld);
output.position= mul(output.position, mView);
output.position= mul(output.position, mProjection);

вам нужно создать для него буфер D3D11_BIND_CONSTANT_BUFFER и использовать ID3D11DeviceContext::VSSetConstantBuffers связать это.

ты можешь использовать #include <DirectXMath.h> для управления матрицей, например, используйте XMMatrixTranslation а также XMMatrixRotation чтобы изменить mWorld, используйте XMMatrixLookAtLH чтобы изменить mView, используйте XMMatrixPerspective изменить mProjection.

после того, как вы получите матрицу в памяти процессора, вам нужно использовать ID3D11DeviceContext::UpdateSubresource обновить данные в памяти gpu (постоянные буферы, которые вы создали выше). не забудьте сделать XMMatrixTranspose прежде чем пройти матрицу.

Другие вопросы по тегам