Когда я изучал Borland C++ версии 3.0 (работал он только под DOS-ом, о Windows еще никто ничего не знал) меня потянуло в графику. После некоторого изучения я понял, что без русского шрифта не обойтись. С ним были проблемы, когда переходил в графический режим вместо русского выходили иероглифы. Но потом нашел выход, сделал двумерный массив под каждую букву с шириной 8х8 точек и заполнил их. И позже в своей программе их использовал. Был один недостаток у шрифта, нельзя было менять размер. Но меня тогда это не расстраивало, т.к. на то время, шрифт был стандартным и использовали во всех программах один тип и один размер. Сейчас, все по другому, ничего не нужно самому изобретать все уже есть :) Вы можете использовать любой тип шрифта с любым цветом, с любыми размерами :) и с кириллицей теперь нет проблем :)
Как Вы уже знаете из раздела MFC, прежде чем отображать шрифт, его нужно создать. Поэтому добавьте в конструктор главного окна после инициализации указателей следующее:
HFONT hFont = CreateFont( 24, // высота шрифта 0, // ширина 0, // угол по часовой стрелке 0, // угол против часовой стрелки FW_NORMAL, // насыщенность шрифта FALSE, // курсив FALSE, // подчеркивание 0, // зачеркнуть ANSI_CHARSET, // использование кодировки OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // качество DEFAULT_PITCH | FF_SWISS, // семейство и гарнитура "Arial"); // тип шрифта
Дальше мы создадим свой класс Font, чтобы позже нам было проще работать с шрифтом. Для этого закроем свой исходник, зайдем в окно Class View, нажмем правую кнопку на имени проекта, из меню выберем Add->Add Class (Добавить->Добавить Класс). В появившемся окне выбираем в правой части Generic C++ Class (Генерировать Класс C++), нажимаем кнопку Open (Открыть). Появится новое окно Generic C++ Class Wizard Имя проекта в поле Class Name (Имя Класса) вводим Font и нажимаем кнопку Finish (Финиш). Скелет класса готов. Начнем постепенно его заполнять.
Щелкните правой кнопкой на классе Font и выберите из меню Add->Add Function (Добавить->Добавить Функцию).
В появившемся диалоговом окне в поле Return Type (Возвращаемый Тип) выберите из выпадающего списка void (пустой). В поле Function Name (Имя Функции) введите Init. В поле Parameter Type (Тип Параметра) введите LPDIRECT3DDEVICE8 и в поле Parameter Name (Имя Параметра) введите Device. Затем щелкните на кнопку Add (Добавить). Тип и имя параметра попадут в поле Parameter List (Список Параметров), см. ниже рисунок:
Не закрывая диалоговое окно, добавьте тип и имя параметра HFONT Font. Должно получиться:
И теперь нажмите кнопку Finish (Финиш).
Добавим к данному классу несколько переменных. Щелкаем правой кнопкой мышки на классе Font и из меню выбираем Add->Add Variable (Добавить->Добавить Переменную):
В появившемся диалоговом окне заполняем:
И нажимаем кнопку Finish (Финиш). Таким же способом добавьте:
LPD3DXFONT pFont; // Используемый шрифт RECT Rect; // Координаты текста
Более подробно о структуре LPD3DXFONT см. раздел Справка по DirectX: "Шаг 83 - Описание интерфейса ID3DXFont". В конструкторе класса указатель pFont присвойте NULL.
Font::Font(void) { pFont = NULL; }
Перейдем к заполнению функции Init():
void Font::Init(LPDIRECT3DDEVICE8 Device, HFONT Font) { d3d_Device = Device; // Запоминаем используемое устройство D3DXCreateFont (Device, Font, &pFont); // Создаем шрифт }
Наше устройство должно знать, какой шрифт нужно использовать. Т.к. здесь мы используем функцию D3DXCreateFont, то нам нужно указать соответствующие библиотеки. Более подробно об этой функции см. раздел Справка по DirectX: "Шаг 84 - Функция D3DXCreateFont".
Откройте файл Font.h и добавьте:
#pragma once #include <D3dx8core.h> #pragma comment (lib, "d3dx8.lib")
Вывод на экран. Добавим новую функцию Print к классу Font и заполним его:
void Font::Print(char* text, int x, int y, D3DCOLOR Color) { Rect.left = x; // Заносим координаты текста Rect.top = y; // в структуру Rect, как Rect.bottom = 0; // левый верхний угол Rect.right = 0; pFont->Begin(); // Начинаем вывод текста // Рисуем текст в определенном месте, с заданным цветом pFont->DrawTextA (text, -1, &Rect, 0, Color); pFont->End(); // Закончили вывод текста }
Более подробно об этих функциях см. раздел Справка по DirectX:
Все, с классом Font покончено :) Теперь возьмемся за его реализацию в нашей программе. Так как мы собираемся использовать этот класс, то и подключим его:
#include "font.h"
Произведем MyFont от класса Font:
class CMainWnd : public CFrameWnd { private: . . . Font MyFont; // Наш текст . . .
Перейдем в конструктор главного окна рамки, перед закрывающей скобкой инициализируем шрифт:
MyFont.Init(p_d3d_Device, (HFONT)hFont);
Перейдем в функцию OnPaint() и перед EndScene() добавим:
MyFont.Print ("Привет, всем разработчикам DirectX !!!", 300, 400, D3DCOLOR_XRGB (0,255,0));
Осталось только удалить указатели, которые потом станут ненужными, вставьте ниже следующий код после подключения библиотек в файле Font.h:
#define _RELEASE_(p) { if(p) { (p)->Release(); (p)=NULL; };}; #define _DELETE_(p) { if(p) { delete (p); (p)=NULL; };};
И деструктор должен выглядеть:
Font::~Font(void) { _RELEASE_ (pFont); _DELETE_ (pFont); }
Компилируем, запускаем и получаем:
Чтобы восстановить шрифт, нам нужно сделать следующее:
void Font::Restore(void) { pFont->OnLostDevice (); // Освобождаем шрифт (если устройство потеряно) pFont->OnResetDevice (); // Восстанавливаем шрифт }
Добавьте выше показанную функцию самостоятельно :) Более подробно об этих функциях см. раздел Справка по DirectX:
И вызовите эту функцию в OnPaint():
if (hr==D3DERR_DEVICENOTRESET) { p_d3d_Device->Reset(&d3dpp); Transform3D(); MyFont.Restore(); }
Тестируйте и проверяйте :)