Подтвердить что ты не робот

Monogame рендеринга текста с использованием Graphics.DrawString(вместо SpriteBatch.DrawString)

Есть ли недостаток в использовании Graphics.DrawString для рендеринга (довольно статического) куча текста в off-screen растровое изображение, конвертировать его в Texture2D один раз, а затем просто вызывать SpriteBatch.Draw вместо использования конвейера контента и рендеринг текста с помощью SpriteFont? Это, в основном, страница текста, нарисованная на "листе бумаги", но пользователь также может изменить размер шрифтов, поэтому это означает, что мне нужно будет включать spritefonts разных размеров.

Поскольку это приложение только для Windows (не планируя его переносить), у меня будет доступ ко всем шрифтам, как в обычном старом приложении WinForms, и я считаю, что качество рендеринга будет намного лучше при использовании Graphics.DrawString (или даже TextRenderer), чем использование шрифтов спрайтов.

Кроме того, кажется, что производительность может быть лучше, так как SpriteBatch.DrawString должен "визуализировать" весь текст на каждой итерации (т.е. отправлять вершины для каждой буквы отдельно), а при использовании растрового изображения я делаю это только один раз, поэтому он должен немного меньше работать на стороне процессора.

  • Есть ли какие-либо проблемы или недостатки, которые я не вижу здесь?
  • Можно ли получить альфа-смешанный текст с помощью spritefonts? Я видел, что Nuclex Framework упоминается вокруг, но он не был перенесен в Monogame AFAIK.

[Обновление]

С технической стороны кажется, что он работает отлично, гораздо лучше, чем через шрифты спрайтов. Если они отображаются горизонтально, я даже получаю ClearType. Одна из проблем, которая может существовать, заключается в том, что spritesheets для шрифтов (может быть?) Более эффективен с точки зрения памяти текстур, чем создание отдельной текстуры для страницы текста.

4b9b3361

Ответ 1

Нет

Похоже, что нет недостатка
На самом деле вы, похоже, следуете стандартным подходам к текстовому рендерингу.

Рендеринг текста "правильно" сравнительно медленный, по сравнению с рендерингом текстурированного квадрата, даже если SpriteFonts вырезает все сплайсирующие глифы, если вы создаете страницу с текстом, тогда вы все равно можете разбивать большое количество треугольников.

Всякий раз, когда я рассматриваю различные решения для визуализации текста для GL/XNA, люди склонны рекомендовать ваш подход. Нарисуйте свою стену текста один раз на многократно используемую текстуру, затем отрисуйте эту текстуру.

Вы также можете рассмотреть RenderTarget2D как возможное решение, которое переносится.
В качестве примера:

// Render the new text on the texture
LoadPageText(int pageNum) {
    string[] text = this.book[pageNum];
    GraphicsDevice.SetRenderTarget(pageTarget);
    // TODO: draw page background

    this.spriteBatchCache.Begin();
    for (int i = 0; i < text.Length; i++) {
         this.spriteBatchCache.DrawText(this.font, 
             new Vector2(10, 10 + this.fontHeight * i), 
             text[i], 
             this.color);
    }
    this.spriteBatchCache.End();
    GraphicsDevice.SetRenderTarget(null);
}

Затем в рендеринг сцены вы можете spriteBatch.Draw(..., pageTarget, ...) визуализировать текст. Таким образом вам понадобится только 1 текстура для всех ваших страниц, просто запомните также перерисовать, если ваш шрифт изменится.

Другими вещами, которые следует учитывать, является режим сортировки SpriteBatches, иногда это может повлиять на производительность при рендеринге многих треугольников.

В пункте 2, как я уже упоминал выше, SpriteFonts представляют собой предварительно обработанные текстуры, это означает, что прозрачность выпекается на их спрайте. По существу, библиотека по умолчанию не использует прозрачность/сглаживание.

Если вы сделали их в два раза большими и белыми на черном и использовали SourceColor в качестве альфа-канала, тогда они отображали их уменьшенное смещение с помощью Color.Black, вы могли бы вернуть его.

Ответ 2

Попробуйте смешивать цвета с указателем:

MixedColor = ((Alpha1 * Channel1) + (Alpha2 * Channel2))/(Alpha1 + Alpha2)