2010-06-21 3 views
0

Позвольте мне описать «поле боя» моей задачи:Advanced Text Rendering с Direct3D

  • Multi-комнатной аудио/видео-чат с более чем 1 млн пользователей;
  • Custom Direct3D renderer;

Что мне нужно реализовать, это функция TextOverVideo. Сам текст идет по сети и должен быть отображен на стороне получателя с помощью средства визуализации Direct3D. AFAIK, он обычно используется в разработке игр, чтобы создать свою собственную текстуру с буквами/цифрами и нарисовать эти предметы. Поскольку наше приложение должно поддерживать многие языки, мы должны использовать стандарт. Вот почему я работал с интерфейсом ID3DXFont, но обнаружил некоторые неудовлетворенные ограничения.

То, с чем я столкнулся, - это отсутствие масштабируемости. Например. если пользователь изменяет размер окна видео, я должен RE-создать D3DXFont с новым D3DXFONT_DESC, пока он это делает. Я думаю, что это неприемлемо. Именно поэтому единственное решение, которое я вижу (из-за моих навыков), как-то визуализирует текст текстуры и поэтому рисует спрайт с масштабированием, переводом и т. Д.

Итак, я не уверен, если я пойду в правильное направление. Пожалуйста, помогите с советами, опытом, литературой, источниками ...

ответ

3

Ваш вопрос немного неясен. Насколько я понимаю, вы хотите легко масштабируемый шрифт.

Я думаю, что это неприемлемо

Насколько я знаю, это стандартное поведение для шрифтов - даже для системных шрифтов. Они не должны быть легко масштабируемыми.

Возможные решения:

  1. Использование ID3DXRenderTarget для рендеринга текста на текстуру. Шрифт будет отфильтрован, если вы слишком сильно его масштабируете. Некоторые люди подумают, что это выглядит уродливо.
  2. Напишите пользовательскую библиотеку, которая поддерживает векторные шрифты. То есть - он должен иметь возможность извлекать шрифт из шрифта и строить из него текст. Он будет МНОГО медленнее, чем ID3DXFont (который уже медленнее, чем традиционные шрифты «текстуры»). Текст будет легко масштабироваться. Используя этот способ, вы, скорее всего, получите видимые артефакты («шум») для небольшого текста. Я бы не использовал этот подход, если вам не нужны огромные буквы (40+ пикселей). Библиотека Freetype может иметь функции для обработки контуров шрифтов.
  3. Или вы можете попробовать использовать D3DXCreateText. Это создаст 3D-текст для ОДНОЙ строки. Не будет быстро.

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

--EDIT--

О ID3DXRenderTarget.
Если вы используете ID3DXRenderTarget, вам понадобится ID3DXFont. То есть вы используете ID3DXFont для рендеринга текста на текстуре, а затем используйте текстуру для заливки текста на экран.
Поскольку вы сказали, что производительность имеет решающее значение, вы можете отложить создание нового ID3DXFont, пока пользователь не перестанет изменять размер видео. То есть Когда пользователь начинает изменять размер видео, вы используете старый шрифт, но увеличиваете его с помощью текстуры.Конечно, будет фильтрация. Когда пользователь перестает изменять размер, вы создаете новый шрифт, когда у вас есть время. вы, вероятно, можете сделать это в отдельном потоке, но я не уверен в этом. ИЛИ вы можете просто всегда отображать текст в том же разрешении, что и видео. Таким образом, вам не придется беспокоиться о его изменении (оно все равно будет отфильтровано - вместе с видео). Некоторые видеоплееры работают таким образом.
Немного больше о ID3DXFont. Есть одна проблема с ID3DXFont - она ​​медленная в ситуациях, когда вам нужно много текста (но вы все еще нуждаетесь в ней, потому что она поддерживает unicode, а писать texturefont с поддержкой unicode - боль). В прошлый раз, когда я работал с ним, я оптимизировал вещи, кэшируя обычно используемые строки в текстурах. То есть любая строка, нарисованная более 3 кадров в строке, была отображена на D3DFMT_A8R8G8B8 текстуру/рендер, а затем я копировал эту строку из текстуры вместо использования ID3DXFont. Строки, которые не отображались некоторое время, были удалены из текстуры. Это вызвало серьезный импульс. Это решение, однако, сложно: отслеживание пустого пространства в текстуре, удаление неиспользуемых строк, а дефрагментация текстуры не совсем тривиальна (нет ничего сложного, но легко сделать ошибку). Вам не понадобится такая сложная система, если ваш экран буквально не покрыт текстом.

+0

Большое спасибо за ваш ответ! «Неприемлемо» - я имел в виду, что создание D3DXFont требует больших ресурсов, и производительность имеет решающее значение для нашего программного обеспечения. Но если я правильно понял, то возможные решения № 2 и 3 еще хуже. ID3DXRenderTarget-да, я подумал о чем-то вроде этого. Но я не мог найти достаточно примеров того, как его использовать. Что я боялся - это то, что кто-нибудь скажет мне: «Эй, НЕ используйте D3DXFont! Его производительность хуже всех! ID3DXRenderTarget - это решение!» Итак, скажите, пожалуйста, должен ли я двигаться с помощью подхода D3DXFont или углубляться в технику ID3DXRenderTarget? – Dalamber

+0

@ Антон: Я обновил свой ответ. – SigTerm

+0

Еще раз спасибо! Буду признателен, если вы можете дать мне пример того, как визуализировать ID3DXFont текстуре. * SCRATCH * Слишком мало информации о ID3DXRenderTarget. Заранее спасибо! Btw, я пробовал динамически обновлять шрифт во время изменения размера и да - использование ЦП при изменении размера сравнительно. – Dalamber

0

ID3DXFont Шрифты плоские, всегда параллельные экрану. D3DXCreateText - это сетки, которые можно масштабировать и поворачивать.

Текстурные шрифты нечеткие и не выглядят очень четкими. Не подходит для приложения, которое использует большое количество небольшого текста.

Я пишу приложение, которое может создавать 500 текстовых сеток, каждый из которых имеет в среднем 3000-5000 вершин. Текстовые сетки создаются один раз, а затем статичны. Я получаю 700 кадров в секунду на GeForce 8800.