Запуск Direct3D, простой треугольник не отображается

Я уже некоторое время занимаюсь созданием игр, сначала используя SDL, а затем SFML. Было приятно, что за меня сделали основы, но теперь я хотел бы сделать еще один шаг и научиться делать графику с нуля. Поэтому я пытаюсь изучить основы Direct3D и для начала прочитал пару руководств по D3D 11. Я просто пытаюсь понять основы, рисуя белый треугольник на темном фоне... но я не могу заставить его работать.

Я использую Visual Studio 2012 RC и Windows 8 SDK, так что здесь есть некоторый синтаксис C++11, плюс нет D3DX. Мне удалось настроить окно, и инициализация Direct3D, похоже, прошла нормально. Он запускает часть рендеринга основного цикла, так как очищает экран в указанном мной цвете. Однако мой причудливый белый треугольник просто не появится. Я просмотрел свой код несколько раз, и с моим отсутствием опыта я не могу сказать, что с ним не так. Я вырезал инициализацию окна/выключение d3d и другие нерелевантные части, но я боюсь отрезать слишком много на случай, если что-то из этого имеет отношение к моей проблеме, так что... big-wall-of-code-warning .

Я думаю, что у меня есть все необходимые шаги; Я создаю устройство, контекст устройства, цепочку обмена и цель рендеринга. Затем я создаю макет вершинного шейдера + ввода и пиксельный шейдер. После этого я создаю буфер вершин, добавляю вершины для моего треугольника и устанавливаю примитивную топологию в TRIANGLELIST, и все для инициализации. В моем основном цикле я указываю D3D на свои вершинные/пиксельные шейдеры и говорю ему отрисовать 3 вершины, которые я вставил в буфер. Но появляется только темно-синий фон от вызова ClearRenderTargetView; нет треугольника. Я пропустил какие-либо шаги или сделал что-то неправильно на этом пути?

Вот код, который у меня есть (я с позором признаю, что немного расслабился с соглашениями о коде в этом, поэтому нет p перед переменными-указателями и т. д.):

Основной цикл:

while ( msg.message != WM_QUIT )
{
    if ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    else
    {
        g_d3dContext->ClearRenderTargetView( g_renderTarget, clearColor );
        g_d3dContext->VSSetShader( g_vertexShader, nullptr, 0 );
        g_d3dContext->PSSetShader( g_pixelShader, nullptr, 0 );
        g_d3dContext->Draw( 3, 0 );
        g_swapChain->Present( 0, 0 );
    }
}

Инициализация Direct3D:

HRESULT hr = S_OK;

RECT rc;
GetClientRect( g_hWnd, &rc );
float width = static_cast<float>( rc.right - rc.left );
float height = static_cast<float>( rc.bottom - rc.top );

uint createDeviceFlags = 0;

const uint numDriverTypes = 3;
D3D_DRIVER_TYPE driverTypes[ numDriverTypes ] =
{
    D3D_DRIVER_TYPE_HARDWARE,
    D3D_DRIVER_TYPE_WARP,
    D3D_DRIVER_TYPE_REFERENCE
};

const uint numFeatureLevels = 3;
D3D_FEATURE_LEVEL featureLevels[ numFeatureLevels ] =
{
    D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1,
    D3D_FEATURE_LEVEL_10_0
};

DXGI_SWAP_CHAIN_DESC sd = { 0 };
sd.BufferCount                          = 1;
sd.BufferDesc.Width                     = static_cast<uint>( width );
sd.BufferDesc.Height                    = static_cast<uint>( height );
sd.BufferDesc.Format                    = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator     = 60;
sd.BufferDesc.RefreshRate.Denominator   = 1;
sd.BufferUsage                          = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow                         = g_hWnd;
sd.SampleDesc.Count                     = 1;
sd.SampleDesc.Quality                   = 0;
sd.Windowed                             = true;

for( uint driverTypeIndex : driverTypes )
{
    g_driverType = driverTypes[ driverTypeIndex ];
    hr = D3D11CreateDeviceAndSwapChain( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
                                        D3D11_SDK_VERSION, &sd, &g_swapChain, &g_d3d, &g_featureLevel, &g_d3dContext );
    if( SUCCEEDED( hr ))
        break;
}
if( FAILED( hr ))
    return hr;

// Create a render target view
ID3D11Texture2D* backBuffer = nullptr;
hr = g_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &backBuffer ));
if( FAILED( hr ))
    return hr;

hr = g_d3d->CreateRenderTargetView( backBuffer, nullptr, &g_renderTarget );
backBuffer->Release();
if( FAILED( hr ))
    return hr;

g_d3dContext->OMSetRenderTargets( 1, &g_renderTarget, nullptr );

// Setup the viewport
D3D11_VIEWPORT vp = { 0 };
vp.Width    = width;
vp.Height   = height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_d3dContext->RSSetViewports( 1, &vp );

// Create vertex shader and input layout
ID3DBlob* vsBlob = nullptr;
ID3DBlob* errorBlob = nullptr;
hr = D3DCompileFromFile( L"VertexShader.hlsl", nullptr, nullptr, "main", "vs
float4 main( float4 pos : POSITION ) : SV_POSITION
{
    return pos;
}
0", 0, 0, &vsBlob, &errorBlob ); if ( FAILED( hr )) return hr; hr = g_d3d->CreateVertexShader( vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &g_vertexShader ); if ( FAILED( hr )) { vsBlob->Release(); return hr; } D3D11_INPUT_ELEMENT_DESC ied = { 0 }; ied.AlignedByteOffset = 0; ied.Format = DXGI_FORMAT_R32G32B32_FLOAT; ied.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; ied.InputSlot = 0; ied.InstanceDataStepRate = 0; ied.SemanticIndex = 0; ied.SemanticName = "POSITION"; hr = g_d3d->CreateInputLayout( &ied, 1, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &g_inputLayout ); vsBlob->Release(); if ( FAILED ( hr )) return hr; g_d3dContext->IASetInputLayout( g_inputLayout ); // Create pixel shader ID3DBlob* psBlob = nullptr; errorBlob = nullptr; hr = D3DCompileFromFile( L"PixelShader.hlsl", nullptr, nullptr, "main", "ps
float4 main( float4 pos : POSITION ) : SV_POSITION
{
    return pos;
}
0", 0, 0, &psBlob, &errorBlob ); if ( FAILED( hr )) return hr; hr = g_d3d->CreatePixelShader( psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &g_pixelShader ); psBlob->Release(); if ( FAILED( hr )) return hr; // Put some vertices up in this bitch Vector3f vertices[] = { Vector3f( 0.5f, -0.5f, 0.5f ), Vector3f( 0.5f, -0.5f, 0.5f ), Vector3f( -0.5f, -0.5f, 0.5f ) }; D3D11_BUFFER_DESC bd = { 0 }; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.ByteWidth = sizeof( Vector3f ) * 3; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; bd.StructureByteStride = 0; bd.Usage = D3D11_USAGE_DEFAULT; D3D11_SUBRESOURCE_DATA initData = { 0 }; initData.pSysMem = vertices; initData.SysMemPitch = 0; initData.SysMemSlicePitch = 0; hr = g_d3d->CreateBuffer( &bd, &initData, &g_vertexBuffer ); if ( FAILED( hr )) return hr; uint stride = sizeof( Vector3f ); uint offset = 0; g_d3dContext->IASetVertexBuffers( 0, 1, &g_vertexBuffer, &stride, &offset ); g_d3dContext->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); return S_OK;

Мой тип вершины:

struct Vector3f
{
    Vector3f( float ix, float iy, float iz )
        : x( ix ), y( iy ), z( iz ) {}

    float x;
    float y;
    float z;
};

Мой вершинный шейдер:

float4 main( float4 pos : POSITION ) : SV_POSITION
{
    return pos;
}

Мой пиксельный шейдер:

float4 main() : SV_TARGET
{
    return float4( 1.0f, 1.0f, 1.0f, 1.0f );
}

person Martin Wedvich    schedule 11.06.2012    source источник


Ответы (1)


Конечно, это была невероятно глупая оплошность. Я просто ввел неправильные данные вершины — все вершины были в одном и том же измерении Y; два первых были даже идентичны.

Изменено на это:

Vector3f( -0.5f, 0.5f, 0.5f ),
Vector3f( 0.5f, 0.5f, 0.5f ),
Vector3f( -0.5f, -0.5f, 0.5f )

И было много песен, танцев и счастья.

person Martin Wedvich    schedule 11.06.2012