CFA LogoCFA Logo Computer
Новости Статьи Магазин Драйвера Контакты
Новости
RSS канал новостей
В конце марта компания ASRock анонсировала фирменную линейку графических ускорителей Phantom Gaming. ...
Компания Huawei продолжает заниматься расширением фирменной линейки смартфонов Y Series. Очередное ...
Компания Antec в своем очередном пресс-релизе анонсировала поставки фирменной серии блоков питания ...
Компания Thermalright отчиталась о готовности нового высокопроизводительного процессорного кулера ...
Компания Biostar сообщает в официальном пресс-релизе о готовности флагманской материнской платы ...
Самое интересное
Программаторы 25 SPI FLASH Адаптеры Optibay HDD Caddy Драйвера nVidia GeForce Драйвера AMD Radeon HD Игры на DVD Сравнение видеокарт Сравнение процессоров

АРХИВ СТАТЕЙ ЖУРНАЛА «МОЙ КОМПЬЮТЕР» ЗА 2002 ГОД

OpenGL и Delphi-2

Руслан РИЗВАНОВ rizvanov_ruslan@mail.ru

(Продолжение, начало см. в МК № 36 (207)).
Главным средством передачи информации приложением пользователю, конечно же, является текст. Разве только суперталантливые дизайнеры смогут нагромождением геометрических примитивов, дивной сменой текстур и прочими профессиональными жестами передать пользователю, например, информацию о создателях игры, подсказки и пр. :-) Поэтому создатели OpenGL благоразумно снабдили свое детище функциями вывода текста. И не только простого, а еще и объемного. Так поговорим же сегодня о видах графического текста в OpenGL и способах его вывода! :-)

Объемный текст

Вполне возможно, что один из примеров вывода такого текста уже есть на вашем компьютере — стандартный для Windows хранитель экрана под названием «Объемный текст». Выглядит довольно эффектно, но мало информативно. Однако создается просто. Для этого в OpenGL есть специальная функция wglUseFontOutlines, которая преобразует символы любого TTF-шрифта в объемные графические объекты. К ним применимы практически все манипуляции OpenGL (поворот, сдвиг, масштабирование, наложение текстуры и прочие). Давайте рассмотрим работу с таким текстом на небольшом примере с анимацией (в этот раз я привожу текст процедуры установки пиксела, в следующих примерах, дабы лишний раз не повторяться, будет присутствовать только ссылка на него). Для начала установите шрифт формы Arial и в разделе private объявите необходимые переменные:

Массив mc (material color) — для установки цвета материала объектов; массив lp (light position) — для задания координат положения источника света на сцене. Так как для вывода текста требуется несколько команд, то для упрощения создаем процедуру:

Далее идет установка формата пиксела:

А теперь — текст, который размещается в обработчиках событий OnCreate и OnDestroy формы:

И последний кусочек текста — обработчик события OnTimer (разместите на форме таймер). Так как здесь используется не мультимедийный, а стандартный таймер, подберите его интервал самостоятельно.

Итак, как все это работает. Вызовом функции wglUseFontOutlines создаются так называемые дисплейные списки — аналоги паскалевских процедур, только в OpenGL-реализации. Функция заполняет их операторами рисования объемных символов текста. Вы в состоянии создавать и свои дисплейные списки, где будут размещаться, например, последовательности команд рисования чего-либо, которые должны многократно вызываться в программе. В отличие от паскалевских процедур, к дисплейным спискам обращение осуществляется по числовому имени. В параметрах функции wglUseFontOutlines указывается, откуда брать ссылку на шрифт (в данном случае используется шрифт, установленный в свойствах формы). Далее идет указание первого номера символа (из таблицы символов) и количества символов, для которых будут созданы дисплейные списки. Так как неизвестно, какие символы и с какими номерами содержатся в выводимом тексте, создаем списки для всех символов шрифта с номерами в диапазоне от 0 до 255. Следующим параметром задается смещение 1000 (берется произвольно) для числовых имен списков, т.е. первый список для первого символа будет иметь имя 1000, последний —1255. Далее указывается погрешность построения объемных букв (0 — наиболее точное повторение контуров используемого шрифта), а также глубина выдавливания контуров букв по оси z и WGL_FONT_POLYGONS — использование полигонов (можно использовать и линии) для построения объемного текста. После того как списки созданы, можно их вызывать. Это делается командой glCallLists — она позволяет обращаться к набору списков. В ее параметрах указывается их количество (в данном случае равно количеству букв в тексте), тип, а также текст (переменная типа Pchar), с точки зрения OpenGL представляющий собой смещения в именах списков, определяющиеся кодами символов текста. Перед этим командой glListBase задается стартовое (базовое) смещение в списках. В приведенном примере эти команды размещены в отдельной процедуре — так удобнее работать с выводом текста из основной программы. Кстати, обратите внимание на команды glPushAttrib и glPopAttrib в этой же процедуре. Так как при выводе текста сбиваются настройки сцены, то в дальнейшем может возникнуть путаница с выводом других объектов. Чтобы этого не было, следует перед выводом текста сохранять текущие настройки (glPushAttrib(GL_ALL_ATTRIB_BITS)), а после — восстанавливать (glPopAttrib).

Простой текст

Такой текст уже более пригоден для вывода информации, чем предыдущий. Так как для его отображения тоже используются TrueType-шрифты, можно сделать выводимую информацию на вид более привлекательной и эффектной или же более строгой — все зависит от используемого шрифта. Принципы работы с таким текстом аналогичны тому, что было описано выше. Различия состоят в том, что вместо команды wglUseFontOutlines используется команда wglUseFontBitmaps. Как нетрудно догадаться из ее названия, она работает не с контурами символов шрифта, а с их растровыми изображениями. При ее вызове также создаются дисплейные списки, в каждом из которых располагаются команды рисования растровой картинки каждого символа. Именно поэтому команды масштабирования, поворота и т.п. для работы с таким текстом не годятся. Для задания координат вывода текста используется команда glRasterPos. Ее можно использовать как с двумя —x,y, так и тремя координатами —x,y,z. С помощью z-координаты задается расположение растра в пространстве. Хотя в данном случае лучше подходит понятие «слой», потому как изменение z не влияет на видимый размер текста. Кроме того, команда glRasterPos влияет на цвет. Если ее не использовать, изменения цвета текста в программе игнорируются — он в любом случае остается белым. Что касается примера по данной теме, то его можно опустить. Вы можете немного модифицировать приведенный выше пример, заменив команду wglUseFontOutlines на wglUseFontBitmaps и задав с помощью glRasterPos координаты вывода перед вызовом процедуры OutText.

Вот, пожалуй, и все, что касается текста в OpenGL. На рисунках — примеры текстов. Советую поэкспериментировать со шрифтами. Очень эффектно получается вывод объемного текста с использованием шрифтов с рукописным начертанием. Однако может возникнуть проблема, когда приложение без особых на то причин начинает некорректно работать. Лично у меня причиной этому был стандартный шрифт MS Sans Serif, используемый по умолчанию формой. После замены его все стало работать нормально.

Подробнее о примере

В примере есть части кода, не относящиеся непосредственно к выводу текста. Вполне возможно, что они вам не совсем понятны. Поэтому уделим им немного внимания. Во-первых, в процедуре-обработчике события OnCreate формы есть строки, задающие цвет материала и положение источника цвета. Они схожи принципом работы: вторым параметром указывается константа, определяющая какую-либо характеристику, а затем следует указатель на массив, элементы которого — значения, устанавливаемые для этой характеристики. Подробный перечень констант, используемых в команде выбора материала (glMaterialfv) и команде настройки источника света (glLightfv) имеется в хелпе. Цвет материала определяет цвет выводимых далее примитивов. Если бы в примере присутствовала строчка glEnable (GL_COLOR_MATERIAL), то можно было бы для установки цвета использовать glColor. Что касается источника света — при задании координат размещения используются 4 значения: x,y,z — собственно координаты, w — направленность. Если w=1 — источник направленный, иначе свет распространяется во все стороны (лампочка :-)). Во-вторых, часто возникает вопрос о повороте одного объекта относительно другого (как в примере). В OpenGL есть только команда поворота сцены glRotate. Но также есть команды glPushMatrix, glPopMatrix, glLoadIdentity. При повороте происходит изменение настроек сцены (точнее, изменение так называемой текущей матрицы). Поворот объекта относительно другого может происходить так: командой glPushMatrix сохраняется текущая матрица, затем происходит поворот сцены, вывод объекта, glPopMatrix восстанавливает матрицу, рисуется новый объект. Первый объект будет повернут относительно второго. Или же можно так: командой glLoadIdentity загружается текущая (единичная) матрица, затем происходит поворот, вывод объекта, опять загрузка матрицы, опять поворот и вывод. В примере это делается сразу двумя приведенными способами.

На сегодня все. Если возникнут какие-либо проблемы — смотрите хелп, а если не помогает — пишите на мой e-mail. Только не злоупотребляйте. Отвечу по возможности.

Рекомендуем ещё прочитать:






Данную страницу никто не комментировал. Вы можете стать первым.

Ваше имя:
Ваша почта:

RSS
Комментарий:
Введите символы или вычислите пример: *
captcha
Обновить





Хостинг на серверах в Украине, США и Германии. © sector.biz.ua 2006-2015 design by Vadim Popov