Теория
Почему это сложно
Популярные форматы шрифтов, такие как TrueType и OpenType , представляют собой форматы векторных контуров:они используют кривые Безье для определения границы буквы.
Источник изображения .
Преобразование этих форматов в массивы пикселей (растеризация)слишком специфичен и выходит за рамки OpenGL, особенно потому, что OpenGl не имеет непрямых примитивов (например, см. Почему в OpenGL нет круговых или эллиптических примитивов? )
Самый простой подход заключается всначала растровые шрифты сами на процессоре, а затем передаем массив пикселей OpenGL в качестве текстуры.
Затем OpenGL знает, как очень хорошо справляться с массивами пикселей с помощью текстур.
Атлас текстуры
Мы могли бы растровых символов для каждого кадра и воссоздать текстуры, но это не очень эффективно, особенно если символы имеют фиксированный размер.
Чем эффективнееподход это растр всех символов, которые вы планируете использовать, и втиснуть их в одну текстуру.
А затем перенести это в графический процессор и использовать текстуру с пользовательскими координатами uv для выбора правильного символа.
Этот подход называется текстурным атласом , и его можно использовать не только для текстур, но и для других многократно используемых текстур, таких как плитки в 2D-играх или значки веб-интерфейса.
Википедиякартина полной текстуры, которая взята из freetype-gl, хорошо иллюстрирует это:
Я подозреваю, что оптимизация размещения персонажа для наименьшей проблемы с текстурой - сложная задача для NPсм.: Какой алгоритм можно использовать для упаковки прямоугольников разных размеров в наименьший из возможных прямоугольников довольно оптимальным способом?
Этот же метод используется в веб-разработке для передачи нескольких маленькихизображения (например, значки) сразу, но там это называется «CSS Sprites»: https://css -tricks.com / css-sprites / и используетсяd чтобы скрыть задержку в сети, а не задержку связи CPU / GPU.
Растровые методы без использования ЦП
Существуют также методы, которые не используют растр ЦП для текстур.
Растрирование ЦП является простым, поскольку оноиспользует GPU как можно меньше, но мы также начинаем думать, можно ли будет использовать эффективность GPU в дальнейшем.
Это видео FOSDEM 2014 объясняет другие существующие методы:
- тесселяция: преобразование шрифта в крошечные треугольники.Графический процессор тогда действительно хорош в рисовании треугольников.Недостатки:
- генерирует набор треугольников
- O (n log n) Процессор вычисляет треугольники
- вычисляет кривые на шейдерах.В статье 2005 года Блинн-Лупа этот метод обозначен на карте.Недостаток: сложный.См .: Рисование независимого кубического Безье с разрешением на графическом процессоре (Blinn / Loop)
- Прямые аппаратные реализации, такие как OpenVG .Недостаток: не очень широко реализован по некоторым причинам.См .:
Шрифты внутри трехмерной геометрии с перспективой
Рендеринг шрифтов внутри трехмерной геометрии с перспективой (по сравнению с ортогональным HUD) намного сложнее, потому что перспектива может сделать одну часть символа намного ближе к экрану и больше, чем другая, делая униформуДискретизация процессора (например, растр, тесселяция) на закрытой части выглядит плохо.На самом деле это активная тема исследования:
Поля расстояний в настоящее время являются одним из популярных методов.
Реализации
Следующие примеры были протестированы на Ubuntu 15.10.
Поскольку это сложная проблема, как обсуждалось ранее, большинство примеров являются большими, и они взорвали бы предел в 30 КБ этого ответа, поэтому просто клонируйте соответствующие репозитории Git для компиляции.
Однако все они полностью с открытым исходным кодом, так что вы можете просто использовать RTFS.
Решения FreeType
FreeType выглядит как доминирующая библиотека растеризации шрифтов с открытым исходным кодом, поэтому она позволит нам использовать шрифты TrueType и OpenType, что делает ее наиболее элегантным решением.
Примеры / учебные пособия:
Другие растеризаторы шрифтов
Они кажутся менее хорошими, чем FreeType, но могут быть более легкими:
Пример учебника Антона по OpenGL 4 26 "Растровые шрифты"
Шрифт был создан автором вручную и сохранен в одном файле .png
. Письма хранятся в виде массива внутри изображения.
Этот метод, конечно, не очень общий, и у вас возникнут трудности с интернационализацией.
Сборка с:
make -f Makefile.linux64
Предварительный просмотр:
Руководство по opengl, глава 11 "2D-шрифты"
Текстуры создаются из файлов DDS .
В учебном пособии объясняется, как создавались файлы DDS с использованием CBFG и Paint.Net .
.
Предварительный просмотр вывода:
По какой-то причине мне не хватает Сюзанны, но счетчик времени работает нормально: https://github.com/opengl-tutorials/ogl/issues/15
FreeGLUT
GLUT имеет glutStrokeCharacter
и FreeGLUT с открытым исходным кодом ...
https://github.com/dcnieho/FreeGLUT/blob/FG_3_0_0/src/fg_font.c#L255
OpenGLText
https://github.com/tlorach/OpenGLText
Растр TrueType. Сотрудник NVIDIA. Цели для повторного использования. Еще не пробовал.
Образец ARM Mali GLES SDK
http://malideveloper.arm.com/resources/sample-code/simple-text-rendering/, кажется, кодирует все символы в PNG и вырезает их оттуда.
SDL_ttf
Источник: https://github.com/cirosantilli/cpp-cheat/blob/d36527fe4977bb9ef4b885b1ec92bd0cd3444a98/sdl/ttf.c
Живет в отдельном дереве для SDL и легко интегрируется.
Однако не предусмотрена реализация атласа текстуры, поэтому производительность будет ограничена: Как эффективно визуализировать шрифты и текст с помощью SDL2?
Похожие темы