netlib.narod.ru< Назад | Оглавление | Далее >

Использование шрифтов

Один из недостатков DirectX 9 — слабая поддержка шрифтов. Старые версии DirectX (до версии 8) могли использовать функции вывода текста из Windows. В версии 9 вы должны вручную рисовать шрифт в поверхность текстуры и рисовать каждый символ шрифта как небольшой текстурированный полигон.

Работа с содержащей шрифт текстурой слишком сложна, чтобы использовать ее только для рисования текста, но, благодаря библиотеке D3DX, у нас есть специальный объект ID3DXFont, который работает с картами текстур шрифтов за вас. Объект ID3DXFont предоставляет семь функций, из которых нас сейчас интересуют только три.

Вот эти функции:

 

ПРИМЕЧАНИЕ
Четвертая функция, которая может оказаться полезной — это ID3DXFont::OnResetDevice. Всякий раз, когда вы теряете контроль над устройством отображения (например, в тех случаях когда пользователь переключается на другое приложение) вы теряете ресурсы, такие как объект шрифта. Всякий раз, когда вы теряете ресурсы (это можно определить по коду ошибки — за дополнительной информации обращайтесь к документации DX SDK), вам необходимо вызвать функцию OnResetDevice для восстановления этих ресурсов.

Перед тем, как двигаться дальше, давайте посмотрим как создать шрифт.

Создание шрифта

Чтобы использовать объект ID3DXFont вы должны сперва инициализировать его с помощью функции D3DXCreateFontIndirect:

HRESULT D3DXCreateFontIndirect(
    IDirect3DDevice9 *pDevice,  // Устройство, связанное со шрифтом
    CONST LOGFONT    *pLogFont, // Структура, описывающая шрифт
    ID3DXFont        **ppFont); // Указатель на созданный объект шрифта

 

ВНИМАНИЕ!
Поскольку ID3DXFont — это COM-объект, не забывайте освобождать его по завершении работы.

Вы передаете этой функции ранее созданный объект устройства и указатель на объект ID3DXFont, который хотите инициализировать, но что за параметр pLogFont?

Как видите, pLogFont — это указатель на структуру LOGFONT (ее имя означает логический шрифт), которая выглядит так:

typedef struct tagLOGFONT {
    LONG  lfHeight;
    LONG  lfWidth;
    LONG  lfEscapement;
    LONG  lfOrientation;
    LONG  lfWeight;
    BYTE  lfItalic;
    BYTE  lfUnderline;
    BYTE  lfStrikeOut;
    BYTE  lfCharSet;
    BYTE  lfOutPrecision;
    BYTE  lfClipPrecision;
    BYTE  lfQuality;
    BYTE  lfPitchAndFamily;
    TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;

Как много информации! Вы можете спокойно пропустить инициализацию большинства полей в структуре LOGFONT и оставить для них значения по умолчанию, которые я покажу. Единственные поля, с которыми вы обязаны работать: lfHeight, lfWeight, lfItalic, lfUnderline и lfFaceName.

Начнем с самого простого — вы присваиваете переменным lfItalic и lfUnderline значения 0 или 1, чтобы отключить или включить использование курсива и подчеркнутого шрифта, соответственно. В переменной lfWeight вы задаете уровень насыщенности шрифта; 0 соответствует обычному шрифту, а 700 — полужирному. Переменная lfHeight представляет размер шрифта в точках. Значение lfHeight несколько необычно, поскольку в нем не указывается непосредственно размер. Вместо этого вы должны предоставить отрицательное число, представляющее примерную высоту шрифта в пикселях. Например, для шрифта высотой 16 пикселей вы должны указать значение –16.

И, наконец, в поле lfFaceName вы указываете имя шрифта, который хотите использовать. Это может быть Times New Roman, Courier New или любой другой шрифт, установленный в вашей системе. Вы просто копируете имя в поле lfFaceName. Вот пример в котором используется шрифт Times New Roman высотой 16 точек:

// g_pD3DDevice = ранее созданный объект устройства
// hWnd         = дескриптор родительского окна
ID3DXFont *pD3DFont;
LOGFONT   lf;

// Очищаем структуру данных шрифта
ZeroMemory(&lf, sizeof(LOGFONT));

// Устанавливаем имя шрифта и высоту
strcpy(lf.lfFaceName, "Times New Roman");
lfHeight = -16;

// Создаем объект шрифта
if(FAILED(D3DXCreateFontIndirect(g_pD3DDevice,
                                 &lf, &pD3DFont))) {
    // Произошла ошибка
}

Рисование текста

Как только ваш объект ID3DXFont инициализирован, вы можете начинать рисовать текст с помощью функции ID3DXFont::DrawText:

HRESULT ID3DXFont::DrawText(
    LPCSTR   pString, // Выводимая строка
    INT      Count,   // -1
    LPRECT   pRect,   // Область, в которой будет выведен текст
    DWORD    Format,  // 0
    D3DCOLOR Color);  // Цвет для рисования

Единственная вещь, о которой надо помнить используя функцию DrawText, — это параметр pRect, являющийся указателем на структуру RECT, определяющую область в которой будет нарисован текст. Вы можете установить эту область равной размерам экрана, или, если хотите, чтобы текст был только в заданной области, используйте ее экранные координаты. Вот как выглядит структура RECT:

typedef struct tagRECT {
    LONG left;   // Левая координата
    LONG top;    // Верхняя координата
    LONG right;  // Правая координата
    LONG bottom; // Нижняя координата
} RECT;

Последний параметр функции DrawText — Color, определяет цвет, используемый для рисования текста. Для определения цвета рисуемого текста воспользуйтесь удобными макросами D3DCOLOR_RGBA или D3DCOLOR_COLORVALUE.

Ах да, еще один момент. Вы должны поместить ваши вызовы DrawText между парой вызовов ID3DXFont::Begin и ID3DXFont::End. Эти две функции информируют Direct3D о том, что вы готовитесь к визуализации текста.

В приведенном ниже примере подразумевается, что вы уже инициализировали объект шрифта и готовы выводить текст:

// g_pD3DDevice = ранее созданный объект устройства
// pD3DXFont    = ранее созданный объект шрифта

// Устанавливаем структуру RECT для области рисования
RECT rect = { 0, 0, 200, 100 };

// Начало блока кода рисования
if(SUCCEEDED(g_pD3DDevice->BeginScene())) {

    // Начинаем визуализацию шрифта
    pD3DXFont->Begin();

    // Рисуем какой-нибудь текст
    pD3DXFont->DrawText("I can draw with text!", -1,
                        &rect, 0, D3DCOLOR_RGBA(255,255,255,255));

    // Завершаем визуализацию шрифта
    pD3DXFont->End();

    // Завершаем сцену
    g_pD3DDevice->EndScene();
}

netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz