2

最初はSDLを使用し、次にSFMLを使用して、しばらくの間ゲームを作成して遊んでいます。基本ができて良かったのですが、今度はもう一歩踏み込んで、グラフィックを一から作る方法を学びたいと思います。だから私はDirect3Dのロープを学ぼうとしていて、始めるためにD3D11に関するいくつかのチュートリアルを読んでいます。暗い背景に白い三角形を描いて、絶対的な基本を理解しようとしています...しかし、それを機能させることはできません。

Visual Studio2012RCとWindows8SDKを使用しているので、ここにはC ++ 11構文がいくつかあり、さらにD3DXはありません。ウィンドウを設定できましたが、Direct3Dの初期化はうまくいくようです。私が指定した色で画面をクリアするので、メインループのレンダリング部分を実行します。しかし、私の派手な白い三角形は表示されません。私は自分のコードを数回調べましたが、経験が不足しているため、コードの何が問題になっているのかわかりません。ウィンドウの初期化/d3dのシャットダウンやその他の無関係な部分を切り取りましたが、問題に関連する部分がある場合に備えて、切りすぎてしまうのではないかと心配しています。 。

必要な手順はすべて整っていると思います。デバイス、デバイスコンテキスト、スワップチェーン、およびレンダリングターゲットを作成します。次に、頂点シェーダー+入力レイアウトとピクセルシェーダーを作成します。その後、頂点バッファーを作成し、三角形の頂点を追加し、プリミティブトポロジを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 init:

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_4_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_4_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 );
}
4

1 に答える 1

2

もちろん、それは信じられないほど愚かな見落としでした。入力した頂点データが間違っているだけです。すべての頂点が同じ Y 次元にありました。最初の 2 つはまったく同じでした。

これに変更:

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

そして、たくさんの歌と踊りと幸せがありました。

于 2012-06-11T18:08:56.783 に答える