游戏中的 Unicode 输入处理

问题描述 投票:0回答:5

我有一款游戏,要求我允许玩家通过网络互相聊天。一切都很好,除了玩家可以输入 Unicode 输入的部分。

所以,问题可以分为两部分:

  • 当玩家打字时,如何捕获输入?我之前通过游戏输入处理(轮询)完成过此操作,但是,它不像 Windows 窗体那样响应灵敏。

  • 在将输入捕获到字符串中后,如何使用 TrueType 字体输出它? 我问这个的原因是因为通常,我会在游戏开始时根据游戏中使用的所有文本构建位图字体。但如果使用 unicode 输入,则需要近 10k 个字符,这在游戏开始时是不可能构建的。

附注我的目标输入语言更具体为中文、韩语和日语。

c++ opengl unicode sdl
5个回答
8
投票

用于输入

  1. 使用 SDL_EnableUNICODE 启用 unicode 输入处理
  2. 照常接收SDL_KeyboardEvent
  3. 使用
    SDL_keysym
    unicode成员来获取unicode

用于渲染

如果所需的字体大小相当小,例如 16px,您实际上可以将其全部渲染为单个纹理,您可以在该大小的 1024x1024 纹理上容纳至少 4096 个字形,当您紧密打包它们时可以容纳更多字形(请参阅fontgen 示例代码)。这对于普通聊天来说应该足够了,但不足以容纳 TTF 文件的所有字形。

如果您不想使用更大的纹理尺寸,则必须根据需要生成字体,为此只需像往常一样创建纹理,然后使用 glTexSubImage2D 将新字形上传到纹理。

另一种选择是不将纹理用于字形,而是用于文本本身。这样你就可以绕过字形生成产生的所有麻烦。但对于非静态可编辑文本来说,这可能不是一个好主意。


0
投票

当玩家打字时,我如何捕获 输入?

我想这取决于你使用什么。我对 SDL 不熟悉。在 Linux 上,您可以使用标准 X 函数和事件循环,它运行良好(例如在 Quake 中使用;因此它应该具有足够的反应性)。

将输入捕获到字符串中后,如何使用 TrueType 字体输出它?

您应该看看 FreeType2 库。它允许您加载 TrueType 字体,并检索任何字符的字形(图像)。

但是使用unicode输入,需要近10k个字符,这在游戏开始时是不可能构建的。

我也有同样的问题。我想带有 MRU(最近使用的)字符的缓存管理器可以解决这个问题。不过,我比简单的静态位图更复杂一些。


0
投票

这里有一些代码展示了如何使用 SDL 捕获键盘输入。

首先需要通过调用EventPoll从SDL查询按键输入。 您可以在准备好处理输入时执行此操作,或者定期执行此操作 固定间隔并将按键和键盘状态存储在内部表中。

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/

您可能想要做的是捕获键盘输入并使用您预加载的正确字体即时渲染它。


0
投票

我自己没有做过游戏开发,所以我对那里的工作原理只有一个模糊的想法,但这里是我的 2 美分:

不要在程序开始时缓存所有字形。相反,当您必须显示聊天字符串时,请将整个字符串即时渲染为某个新纹理。将此纹理保留在内存中,直到不太可能再次需要它为止(例如,在聊天窗口关闭之后)。也许您可以在更新时重新渲染整个聊天窗口 - 那么您只需担心一个纹理。


0
投票

就显示而言,我对本教程(音译为 C++)中描述的缓存系统非常幸运。

对于字体,GNU Unifont 具有完整的 BMP 字形覆盖,以方便的 TTF 形式提供。

© www.soinside.com 2019 - 2024. All rights reserved.