views:

363

answers:

5

This is a C++ SDL OpenGL question.

Hello,

I have a game that requires me to allow players to chat with each other via network. All is well, except the part where players can type in Unicode input.

So, the question can be split into two parts:

  • When players type, how do I capture input? I have done this before via the game input handling (polling), however, it is not as responsive as something like Windows Forms.

  • After I capture input into a string, how do I output it using TrueType Fonts? The reason I ask this is because usually, I would build bitmap fonts at the start of the game from the all the text used in the game. But with unicode input, there are nearly 10k characters that are needed, which is quite impossible to build at the start of the game.

Thank you so much in advance.

P.S. My target input languages are more specific to Chinese, Korean and Japanese.

A: 

When players type, how do I capture input?

That depends on what you use I guess. I'm not familiar with SDL. On Linux you can use standard X functions and event loop, it works well (used in Quake for example; so it should be reactive enough).

After I capture input into a string, how do I output it using TrueType Fonts?

You should have a look at FreeType2 library. It lets you load TrueType fonts, and retrieve the glyph (the image) of any character.

But with unicode input, there are nearly 10k characters that are needed, which is quite impossible to build at the start of the game.

I have the same problem. I guess a cache manager with MRU (most recently used) characters would do the trick. I bit more complicated than simple static bitmap though.

A: 

Here is some code showing how to capture keyboard input with SDL.

First of all you need to query key input from SDL by calling EventPoll. You can do that whenever you are ready to process input, or regularly in a fixed interval and store keys and keyboard status in internal tables.

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 
}

Here is a link to a document describing methods to render text with OpenGL: http://www.opengl.org/resources/features/fontsurvey/

What you may want to do is to capture keyboard input and render it on the fly using the proper font(s) you have preloaded.

karx11erx
A: 

I've done no game development myself, so I have just a vague idea of how things work there, but here are my 2 cents:

Don't cache all the glyphs at the start of the program. Instead, when you have to display a chat string, render the whole string on-the-fly to some new texture. Keep this texture in memory until a time when it is unlikely that it will be needed again (say, after the chat window is closed). Perhaps you can re-render the whole chat window when it gets updated - then you would only have one texture to worry about.

Vilx-
+3  A: 

For Input

  1. Use SDL_EnableUNICODE to enable unicode input handling
  2. Receive the SDL_KeyboardEvent as usual
  3. Use the unicode member of SDL_keysym to get the unicode

For Rendering

If the needed font size is reasonably small, say 16px, you actually could just render it all to a single texture, you can fit a minimum of 4096 glyphs on 1024x1024 texture at that size, a bit more when you pack them tightly (see fontgen for example code). That should be enough for common chat, but not enough to fit all the glyphs of a TTF file.

If you don't want to use a larger texture size you have to generate the fonts on demand, to do that just create the Texture's as usual and then use glTexSubImage2D to upload new glyphs to the texture.

Another alternative is to not use textures for glyphs, but for the text itself. That way you bypass all the trouble that glyph generation produces. But its probably not such a good idea for non-static editable text.

Grumbel
Thank you sooo much! I've been pondering about this for ages. Cheers!
Roy
A: 

As far as display goes, I've had very good luck with the caching system described in this tutorial, transliterated to C++.

For fonts, GNU Unifont has full BMP glyph coverage, available in convenient TTF form.

genpfault