1

私は現在 DirectX 11 を学んでおり、本「Beginning DirectX 11 programming」のデモの 1 つを試していました。本のガイドラインに従って、ウィンドウの作成と破棄 (d3d11 セットアップを含む) を処理する基本クラスを作成しました。他のすべてのデモは、このクラスに基づいています。そこで、2D 三角形を描くことを目的とした Triangle デモを作成しました。Triangle クラスの実装は次のとおりです。

#include "Triangle.h"


Triangle::Triangle(void): mVertexShader(0), mPixelShader(0), mInputLayout(0), mVertexBuffer(0)
{
}


Triangle::~Triangle(void)
{
}

void Triangle::Update(float deltaTime){

}

void Triangle::UnloadContent(){
    if(mVertexShader)
        mVertexShader->Release();

    if(mPixelShader)
        mPixelShader->Release();

    if(mInputLayout)
        mInputLayout->Release();

    if(mVertexBuffer)
        mVertexBuffer->Release();

    mVertexBuffer = 0;
    mPixelShader = 0;
    mVertexShader = 0;
    mInputLayout = 0;
}

bool Triangle::LoadContent(){
    //Load Vertex Shader and make it active
    ID3DBlob* vsBlob = 0;

    if(!CompileShader(L"shaders.fx", "VS_Main", "vs_4_0", &vsBlob)){
        MessageBox(0, L"Error Loading Vertex Shader", L"Compile Error", MB_OK);
        return false;
    }
    HRESULT hr;
    if(FAILED(hr = mDevice->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), 0, &mVertexShader))){
        if(vsBlob)
            vsBlob->Release();

        return false;
    }

    D3D11_INPUT_ELEMENT_DESC vertexLayout[] = {
        {
            "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
        }
    };

    unsigned int layoutSize = ARRAYSIZE(vertexLayout);

    if(FAILED(mDevice->CreateInputLayout(
            vertexLayout,
            layoutSize,
            vsBlob->GetBufferPointer(),
            vsBlob->GetBufferSize(),
            &mInputLayout
        ))){
            vsBlob->Release();
            return false;
    }

    vsBlob->Release();

    ID3DBlob* psBlob = 0;

    if(!CompileShader(L"shaders.fx", "PS_Main", "ps_4_0", &psBlob)){
        MessageBox(0, L"Error Loading Pixel Shader", L"Compile Error", MB_OK);

        if(psBlob)
            psBlob->Release();

        return false;
    }

    if(FAILED(mDevice->CreatePixelShader(
            psBlob->GetBufferPointer(),
            psBlob->GetBufferSize(),
            0,
            &mPixelShader
        ))){
            psBlob->Release();
            return false;
    }

    psBlob->Release();


    //vertex buffer creation
    VertexPos vertices[] =
    {
        XMFLOAT3( 0.5f, 0.5f, 0.5f ),
        XMFLOAT3( 0.5f, -0.5f, 0.5f ),
        XMFLOAT3( -0.5f, -0.5f, 0.5f )
    };

    D3D11_BUFFER_DESC vertexDesc;
    ZeroMemory(&vertexDesc, sizeof(vertexDesc));

    vertexDesc.Usage = D3D11_USAGE_DEFAULT;
    vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vertexDesc.ByteWidth = sizeof(VertexPos) * 3;

    D3D11_SUBRESOURCE_DATA subresourceData;
    ZeroMemory(&subresourceData, sizeof(subresourceData));
    subresourceData.pSysMem = vertices;

    if(FAILED(mDevice->CreateBuffer(
            &vertexDesc,
            &subresourceData,
            &mVertexBuffer
        ))){
            return false;
    }

    return true;
}

bool Triangle::CompileShader(wchar_t* filePath, char* entry, char* shaderModel, ID3DBlob** buffer){
    DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

#if defined(DEBUG) || defined(_DEBUG)
    shaderFlags |= D3DCOMPILE_DEBUG;
#endif

    ID3DBlob* errorBuffer = 0;
    HRESULT result;

    result = D3DX11CompileFromFileW(
            filePath,
            0,0,
            entry,
            shaderModel,
            shaderFlags,
            0,0,
            buffer,
            &errorBuffer,
            0
        );

    if(FAILED(result)){
        if(errorBuffer != 0){
            OutputDebugStringA((char*) errorBuffer->GetBufferPointer());
            errorBuffer->Release();
        }
        return false;
    }
    if(errorBuffer)
        errorBuffer->Release();

    return true;
}


void Triangle::Render(){
    float clearColor[4] = { 1.0f, 0.0f, 1.25f, 1.0f };
    mDeviceContext->ClearRenderTargetView(mRenderTarget, clearColor);

    unsigned int stride = sizeof(VertexPos);
    unsigned int offset = 0;

    mDeviceContext->IASetInputLayout(mInputLayout);
    mDeviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &offset);
    mDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    mDeviceContext->VSSetShader(mVertexShader, 0, 0);
    mDeviceContext->PSSetShader(mPixelShader, 0, 0);
    mDeviceContext->Draw(3, 0);

    mSwapChain->Present(0, 0);

}

これを実行すると、画面がクリアされ、指定した色になりますが、画面には何も描画されません。本で提供されているソースコードをコンパイルしただけで、問題なく動作することを確認してください. 使用するシェーダーも同じです。私のコンピューターは directx 11 をサポートしています。ほとんどの名前は一目瞭然だと思いますが、わかりにくい場合は私に尋ねてください。フレームワークを他のデモでテストしましたが、正常に動作します。コードでエラーが見つからないようです。

4

1 に答える 1

4

位置は、標準のユークリッド空間座標、3 タプル、または - 4 番目のコンポーネントが 1 に設定された 4D 同次座標 (4 タプル) で渡される (ポイントであるため) でエンコードする必要があります。入力要素の説明、頂点データのレイアウトを渡すときは、次のように設定DXGI_FORMAT_R32G32B32A32_FLOATします。

    D3D11_INPUT_ELEMENT_DESC vertexLayout[] = 
{
    {
         "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
    }
};

ただし、3D 頂点のみを渡します。

VertexPos vertices[] =
    {
        XMFLOAT3( 0.5f, 0.5f, 0.5f ),
        XMFLOAT3( 0.5f, -0.5f, 0.5f ),
        XMFLOAT3( -0.5f, -0.5f, 0.5f )
    };

最初は、w 座標が 0 に初期化され、頂点シェーダーで何らかの形で変換が台無しになると推測するかもしれませんが、何が起こるかは、線形メモリ レイアウトと、GPU がそのデータを取得することを約束した方法に固有のものです。あなたはそれが32ビットの4タプルを取得していて、32ビットの3タプルしか取得していないと言いました。現在、それらは隣接しているため、一見すると間違ったスロットにポンピングされているように見えます. ただし、境界で型を壊すことは HLSL で厳密に禁止されているため、死ぬだけです。

修正方法は?

シンプルに、DXGI_FORMAT_R32G32B32_FLOATHLSL コードを変更して調整し、ポイントの 4 番目のコンポーネントを追加して、float4(pos, 1.0) のように 1.0 に設定し、CPU で構築したワールド、ビュー、プロジェクション マトリックスで乗算します。 HLSL は列優先であり、C++ は行優先であることを覚えておいてください。つまり、計算を意味のあるものにするためには、すべてを HLSL に転置する必要があります。

ハッピーコーディング。

于 2012-06-27T16:47:58.587 に答える