0

「Sherrod A.、Jones W. - Beginning DirectX 11 Game Programming - 2011」という本を使用して、DirectX を学習しています。現在、テキストの描画に関する第 4 章を調べています。

画面に文字列を描画するために使用している関数を修正するのを手伝ってください。既にフォント テクスチャを読み込んでおり、関数内で文字を含むスプライトを作成し、それらのテクスチャ座標を定義しています。これは正しくコンパイルされますが、何も描画されません。どうしたの?

bool DirectXSpriteGame :: DrawString(char* StringToDraw, float StartX, float StartY)
{
//VAR
    HRESULT D3DResult;                                                                              //The result of D3D functions

    int i;                                                                                          //Counters
    const int IndexA = static_cast<char>('A');                                                      //ASCII index of letter A
    const int IndexZ = static_cast<char>('Z');                                                      //ASCII index of letter Z
    int StringLenth = strlen(StringToDraw);                                                         //Lenth of drawing string
    float ScreenCharWidth = static_cast<float>(LETTER_WIDTH) / static_cast<float>(SCREEN_WIDTH);    //Width of the single char on the screen(in %)
    float ScreenCharHeight = static_cast<float>(LETTER_HEIGHT) / static_cast<float>(SCREEN_HEIGHT); //Height of the single char on the screen(in %)
    float TexelCharWidth = 1.0f / static_cast<float>(LETTERS_NUM);                                  //Width of the char texel(in the texture %)
    float ThisStartX;                                                                               //The start x of the current letter, drawingh
    float ThisStartY;                                                                               //The start y of the current letter, drawingh
    float ThisEndX;                                                                                 //The end x of the current letter, drawing
    float ThisEndY;                                                                                 //The end y of the current letter, drawing
    int LetterNum;                                                                                  //Letter number in the loaded font
    int ThisLetter;                                                                                 //The current letter

    D3D11_MAPPED_SUBRESOURCE MapResource;                                                           //Map resource
    VertexPos* ThisSprite;                                                                          //Vertecies of the current sprite, drawing
//VAR

//Clamping string, if too long
if(StringLenth > LETTERS_NUM)
{
    StringLenth = LETTERS_NUM;
}

//Mapping resource
D3DResult = _DeviceContext -> Map(_vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MapResource);
if(FAILED(D3DResult))
{
    throw("Failed to map resource");
}
ThisSprite = (VertexPos*)MapResource.pData;

for(i = 0; i < StringLenth; i++)
{
    //Creating geometry for the letter sprite
    ThisStartX = StartX + ScreenCharWidth * static_cast<float>(i);
    ThisStartY = StartY;
    ThisEndX = ThisStartX + ScreenCharWidth;
    ThisEndY = StartY + ScreenCharHeight;

    ThisSprite[0].Position = XMFLOAT3(ThisEndX, ThisEndY, 1.0f);
    ThisSprite[1].Position = XMFLOAT3(ThisEndX, ThisStartY, 1.0f);
    ThisSprite[2].Position = XMFLOAT3(ThisStartX, ThisStartY, 1.0f);

    ThisSprite[3].Position = XMFLOAT3(ThisStartX, ThisStartY, 1.0f);
    ThisSprite[4].Position = XMFLOAT3(ThisStartX, ThisEndY, 1.0f);
    ThisSprite[5].Position = XMFLOAT3(ThisEndX, ThisEndY, 1.0f);

    ThisLetter = static_cast<char>(StringToDraw[i]);

    //Defining the letter place(number) in the font
    if(ThisLetter < IndexA || ThisLetter > IndexZ)
    {
        //Invalid character, the last character in the font, loaded
        LetterNum = IndexZ - IndexA + 1;
    }
    else
    {
        LetterNum = ThisLetter - IndexA;
    }

    //Unwraping texture on the geometry
    ThisStartX = TexelCharWidth * static_cast<float>(LetterNum);
    ThisStartY = 0.0f;
    ThisEndY = 1.0f;
    ThisEndX = ThisStartX + TexelCharWidth;

    ThisSprite[0].TextureCoords = XMFLOAT2(ThisEndX, ThisEndY);
    ThisSprite[1].TextureCoords = XMFLOAT2(ThisEndX, ThisStartY);
    ThisSprite[2].TextureCoords = XMFLOAT2(ThisStartX, ThisStartY);

    ThisSprite[3].TextureCoords = XMFLOAT2(ThisStartX, ThisStartY); 
    ThisSprite[4].TextureCoords = XMFLOAT2(ThisStartX, ThisEndY);   
    ThisSprite[5].TextureCoords = XMFLOAT2(ThisEndX, ThisEndY);

    ThisSprite += VERTEX_IN_RECT_NUM;
}

for(i = 0; i < StringLenth; i++, ThisSprite -= VERTEX_IN_RECT_NUM);

_DeviceContext -> Unmap(_vertexBuffer, 0);
_DeviceContext -> Draw(VERTEX_IN_RECT_NUM * StringLenth, 0);

return true;
}
4

1 に答える 1

0

頂点配列を構築するコードは一見正しいように見えますが、まだ設定されていないシェーダーで頂点を描画しようとしているようです! コード全体を見ずに正確に答えるのは難しいですが、次のようなことをする必要があると推測できます。

1) 頂点シェーダーとピクセル シェーダーをそれぞれのバッファーから最初にコンパイルして作成します。

2)Input Layout入力アセンブラー ステージによって読み取られる入力バッファーを記述する記述を作成します。VertexPos構造とシェーダー構造に一致する必要があります。

3) シェーダーのパラメーターを設定します。

4) シェーダー レンダリング パラメーターを設定できるようになったのは今だけです。次のInputLayoutような方法で、三角形のレンダリングに使用される頂点シェーダーとピクセル シェーダーを設定します。

_DeviceContext -> Unmap(_vertexBuffer, 0);

_DeviceContext->IASetInputLayout(myInputLayout);
_DeviceContext->VSSetShader(myVertexShader, NULL, 0); // Set Vertex shader
_DeviceContext->PSSetShader(myPixelShader, NULL, 0); // Set Pixel shader

_DeviceContext -> Draw(VERTEX_IN_RECT_NUM * StringLenth, 0);

このリンクは、やりたいことを達成するのに役立ちます: http://www.rastertek.com/dx11tut12.html

また、パフォーマンス上の理由からIndexBuffer、メソッドを設定して三角形をレンダリングすることをお勧めします。これにより、グラフィックス アダプターが頂点キャッシュに頂点を格納できるようになり、最近使用した頂点を読み取る代わりにキャッシュからフェッチできるようになります。DrawIndexed頂点バッファから。この問題の詳細については、MSDN を参照してください: http://msdn.microsoft.com/en-us/library/windows/desktop/bb147325(v=vs.85).aspx

お役に立てれば!

PS : また、リソースを使用した後は、 を呼び出してリソースを解放することを忘れないでくださいRelease()

于 2012-11-23T23:05:59.937 に答える