2012-11-20 2 views
0

Я изучаю DirectX, используя книгу «Sherrod A., Jones W. - Начало DirectX 11 Game Programming - 2011» Теперь я изучаю четвертую главу о рисовании текст.DirectX 11: вывод текста с использованием собственной текстуры шрифта

Пожалуйста, помогите нам исправить мою функцию, которую я использую, чтобы нарисовать строку на экране. Я уже загрузил текстуру шрифта, и в функции я создаю несколько спрайтов с буквами и определяю для них координаты текстуры. Это правильно компилируется, но ничего не рисует. Что не так?

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; 
} 

ответ

0

Хотя часть кода построения массива Vertex кажется правильным мне на первый взгляд, кажется, что вы пытаетесь рисовать свои вершины с Shader, который не был установлен еще! трудно точно ответить вам, не смотря на весь код, но я могу предположить, что вам нужно будет сделать что-то вроде этого:

1) Создать вершинные и пиксельные шейдеры путем составления их первого из соответствующих буферов

2) Создайте описание Input Layout, в котором описываются входные буферы, которые будут считываться на этапе ввода ассемблера. Он должен будет соответствовать вашей структуре VertexPos и структуре вашего шейдера.

3) Задайте параметры шейдера.

4) Только теперь вы можете установить параметры рендеринга Shader: Установите 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, чтобы сделать ваши треугольники по соображениям производительности: Это позволит видеоадаптер для хранения вершин в кэше вершин, позволяющий в последнее время ed, которую нужно извлечь из кеша, вместо того, чтобы читать его из буфера вершин. Подробнее об этой проблеме можно найти на MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/bb147325(v=vs.85).aspx

Надеюсь, это поможет!

P.S: Кроме того, не забудьте освободить ресурсы после их использования, позвонив по телефону Release().

Смежные вопросы