Обработка ввода Unicode в играх

У меня есть игра, которая требует, чтобы я разрешил игрокам общаться друг с другом по сети. Все хорошо, кроме той части, где игроки могут вводить Unicode.

Итак, вопрос можно разделить на две части:

  • Когда игроки вводят, как я могу захватить ввод? Я делал это раньше с помощью обработки ввода в игре (опроса), однако он не такой отзывчивый, как что-то вроде Windows Forms.

  • После ввода в строку, как мне вывести его с помощью шрифтов TrueType? Причина, по которой я спрашиваю об этом, заключается в том, что обычно я создаю растровые шрифты в начале игры из всего используемого текста. в игре. Но при вводе в юникоде требуется около 10 тысяч символов, что совершенно невозможно построить в начале игры.

P.S. Мои целевые языки ввода более специфичны для китайского, корейского и японского языков.


person Roy    schedule 10.09.2009    source источник


Ответы (5)


Для ввода

  1. Используйте SDL_EnableUNICODE, чтобы включить обработку ввода Unicode.
  2. Получите SDL_KeyboardEvent как обычно.
  3. Используйте член unicode SDL_keysym, чтобы получить юникод

Для рендеринга

Если необходимый размер шрифта достаточно мал, скажем, 16 пикселей, вы можете просто отрендерить все это в одну текстуру, вы можете уместить как минимум 4096 глифов на текстуре 1024x1024 такого размера, немного больше, если вы упаковываете их плотно (см. < href="http://svn.berlios.de/svnroot/repos/pingus/trunk/fontgen/" rel="noreferrer">fontgen, например код). Этого должно быть достаточно для обычного чата, но недостаточно для размещения всех глифов TTF-файла.

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

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

person Grumbel    schedule 10.09.2009
comment
Большое спасибо! Я размышлял об этом целую вечность. Ваше здоровье! - person Roy; 10.09.2009

Когда игроки печатают, как мне захватить ввод?

Это зависит от того, что вы используете, я думаю. Я не знаком с SDL. В Linux вы можете использовать стандартные функции X и цикл обработки событий, они хорошо работают (используются, например, в Quake, поэтому они должны быть достаточно реактивными).

После ввода ввода в строку, как мне вывести его с помощью шрифтов TrueType?

Вы должны взглянуть на библиотеку FreeType2. Он позволяет загружать шрифты TrueType и извлекать глиф (изображение) любого символа.

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

У меня такая же проблема. Я предполагаю, что диспетчер кеша с символами MRU (последние использованные) справится с задачей. Я немного сложнее, чем простое статическое растровое изображение.

person Community    schedule 10.09.2009

Вот код, показывающий, как захватывать ввод с клавиатуры с помощью SDL.

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

void EventPoll (ulong mask)
{
SDL_Event event;
while (SDL_PollEvent (&event)) {
   switch(event.type) {
      case SDL_KEYDOWN:
         KeyHandler (reinterpret_cast<SDL_KeyboardEvent*> (&event));
         break;
      case SDL_KEYUP:
         KeyHandler (reinterpret_cast<SDL_KeyboardEvent*> (&event));
         break;
      // handle other events
      }
   }
}

void KeyHandler (SDL_KeyboardEvent *event)
{
   SDLKey      keySym = event->keysym.sym;
   wchar_t     unicode = event->keysym.unicode;
   int         keyState = (event->state == SDL_PRESSED);

// process key info, e.g. put key into a buffer and 
// store keyboard state 
}

Вот ссылка на документ, описывающий методы визуализации текста с помощью OpenGL: http://www.opengl.org/resources/features/fontsurvey/

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

person Razzupaltuff    schedule 10.09.2009

Сам я не занимался разработкой игр, поэтому имею лишь смутное представление о том, как там все работает, но вот мои 2 цента:

Не кэшируйте все глифы в начале программы. Вместо этого, когда вам нужно отобразить строку чата, визуализируйте всю строку на лету в какую-нибудь новую текстуру. Держите эту текстуру в памяти до момента, когда она вряд ли понадобится снова (скажем, после закрытия окна чата). Возможно, вы сможете перерендерить все окно чата, когда оно обновится — тогда вам придется беспокоиться только об одной текстуре.

person Vilx-    schedule 10.09.2009

Что касается отображения, мне очень повезло с системой кэширования, описанной в это руководство, транслитерированное на C++.

Для шрифтов GNU Unifont есть полный BMP покрытие глифов, доступное в удобной форме TTF.

person genpfault    schedule 10.09.2009