   OTTER, a simple lib for texture mapped TTF opengl text
  Since I could find nothing that supports this readily, I decided to write my own. Since I'm sure others will find this useful, I've made it public. I won't assert that there are no errors in the code, and I would love to have feedback on anything that needs corrected. That said, here is the header file for the C lib and links to get the source files/distribution files./*OpenGl Truetype Text Enhanced Renderer (OTTER)VERSION: 1.0Jason A. Petrasko (C) 2007LICENSE: Creative Commons Share-Alike: http://creativecommons.org/licenses/by-sa/3.0/us/DESCRIPTION:Creates sized font faces from truetype files (freetype2) with integer handles, and renderers them in OpenGL.FEATURES:Supports caching render streams for fast text redraw at the cost of memory (64 bytes per character in a render stream)Very high-quality freetype to texture map code. (As compared to other available source code)Fonts are threadsafe, using Critical Sections under Win32 and pthread mutexes otherwise- RENDERING IS NOT THREAD SAFE. WHY WOULD IT BE? *ROLLS EYES**/#ifdef _cplusplusextern "C" {#endif// some configuration#define FONT_MAX_INSTALLED1024#define FONT_TEX_MAXDIM1024// some basic definitions#define FONT_FREED-2#define FONT_INVALID    -1#define FONT_ASCII0#define FONT_UNICODE1// font install errors#define FONT_ERR_FT2_INIT"failed to initialize freetype 2"#define FONT_ERR_FT2_FACE"failed to create font face"#define FONT_ERR_FT2_LOAD"(internal) failed on FT_Load_Glyph"#define FONT_ERR_FT2_GET"(internal) failed on FT_Get_Glyph"#define FONT_ERR_TEX_LIMIT"could not fit font into a texture"#define FONT_ERR_TEX_GUESS"image dimensions guess routine failed to provide large enough surface"#define FONT_ERR_FNT_MAX"beyond maximum limit of installed fonts"/* returns the version as a string (eg. "1.0") */const char *font_versions();/* returns the version as a float (eg. 1.0f) */float font_versionf();/* return the last error as a string */const char *font_error();/* install a font file with a given pixel height, return a font handle on success or FONT_INVALID on failurefont_error() will return a human readable error string. */int font_install_ascii(const char *fname, int pixel_height);/* redefines an installed font to a new file/pixel heightn can be NULL for the same file, ph can be -1 for the same height */int font_redefine(int f, const char *n, int ph);/* frees the texture for the selected font.we never actually allow a font to be deleted, but this frees up mostof the memory it hogs, and if its used again it can be rebuilt*/void font_free(int f);/* returns the state of the font (state less than 0 = non-functional) */int font_state(int f);/* rebuilds a font that has been freed with font_free() */int font_rebuild(int f);/* // return the height of a font */int font_height(int f);/* return the width of a string in a given font, don't use this inside rendering code,use font_string_width() instead */int font_widths(int f, const char *s);/* select font 'f' for drawing */void font_select(int f);/* set the current string for rendering, builds a render stream NOTE: the string passed to this shouldn't be more than 512 characters */void font_string(const char *s);/* return a new copy of the current render stream */unsigned char* font_export(int *len);/* render an exported render stream, and uh, if you change/alter a font,you'll likely break the render stream such that you'll get garbage from this */void font_outx(int x, int y, unsigned char *rs, int len);/* render the current string/render stream */void font_out(int x, int y);/* width of a given string in the current selected font */int font_string_width(const char *s);/* configure the screen dimensions, only matters if you force witha call such as: font_begin(1); */void font_screen(int scr_w, int scr_h); /* if you set force to 1, then the OTTER creates a proper Ortho modeotherwise it doesn't bother, assuming its already set.call this before font_out for a given frame/scene/whatever*/void font_begin(int force);/* call when font drawing is done for this frame/scene/whatever*/void font_end();/* invalidate all font textures, so they will be reloaded */void font_invalidate();  /* *******************************************************************************low level drawing here (not as fast as the string handling)*//* set the font cursor for char output */void font_set_cursor(int x, int y);/* output a char 'c' and adjust the cursor accordingly */void font_char_out(int c);/* return the width of char 'c' */int font_char_width(int c);/* set the font cursor for char output */void font_get_cursor(int *x, int *y);#ifdef _cplusplus}#endifFiles and sourceThe header explains everything pretty well, though you'll need to have a functioning FreeType 2 library to build the source / link the library though that isn't mentioned.Any questions, problems, etc. Fire Away!   
  Ok, since I was dumb enough to post this without even a test compile... I updated and fixed some of the .c source (stupid syntax errors).Also, though the code hints at it, the current version does not yet support unicode fonts and UTF-8 strings. That will come in version 1.1   ;  (Ok, some more testing and fixes - Fully debugged and tested OK as of 17:54, 09/08/07)Also, a simple example of use:glfwInit();ScreenDims.x = 768;ScreenDims.y = 512;if (glfwOpenWindow(ScreenDims.x,ScreenDims.y,0,0,0,8,0,0,GLFW_WINDOW) == GL_FALSE) die("Could not open window! (GLFW)");test_fnt = font_install_ascii("dat/fnt/BN Deep Blue.ttf",16);if (test_fnt == FONT_INVALID) die("Font loading failed! (%s)",font_error());font_screen(ScreenDims.x,ScreenDims.y);glfwSetKeyCallback(testkeycall);glfwSwapInterval(1);while (glfwGetWindowParam(GLFW_OPENED) == GL_TRUE){glClear(GL_COLOR_BUFFER_BIT);glColor4f(1.0f,1.0f,1.0f,1.0f);font_begin(FONT_FORCE_ORTHO);font_select(test_fnt);font_string("This is text!");font_out(10,10);font_end();glfwSwapBuffers();}glfwTerminate();This example (which I'm using to debug the functions) is wrapped by GLFW, but you could use whatever opengl base you'd like.[Edited by - Jason Petrasko on September 8, 2007 4:08:01 PM];  Upgraded to version 1.1. (download)Several new features, but the major change is the move to DLL format.All you need is the header, the DLL, and then do like so:otterInterface *font;int r;int main(){font = otterOpen("./otter11.dll");if (!font){printf("Could not open otter11.dll!\n");return -1;}if (!otterOk(font)) {printf("Could not open otter11.dll!\n");return -1;} glfwInit();glfwOpenWindow(512,256,0,0,0,8,0,0,GLFW_WINDOW);glfwSwapInterval(1);r = font->install_ascii("./rabbit.ttf",18);if (r == FONT_INVALID){printf("Failed to load font: %s\n",font->errors());return -2;}font->screen(512,256);while (1){glClear(GL_COLOR_BUFFER_BIT);glColor4f(1.0f,1.0f,1.0f,1.0f);font->begin(FONT_FORCE_ORTHO);font->select(r);font->string("Testing the OTTER dll...");font->out(5,5);font->end();glfwSwapBuffers();if (glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS) break;}glfwTerminate();otterClose(font);return 0;NOTES: The .dll is stripped and packed with UPX. Shouldn't be a problem usually. Also, PNG is compiled with MMX extensions.;  i had a quick browse// configure GL properlyglEnable(GL_TEXTURE_2D);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);etc*/ now u prolly want to let the user choose what they want material they want enabled etc, eg glsl doesnt use glEnable( GL_TEXTURE_2D ), blending etc*/ ild sure most ppl would prefer to see everything in a single header, as its quite small (ie no lib to worry about)*also performance aint ideal, with the immediate mode calls, though the problem with adding VA/VBOs is ideally OTTER needs to communicate with the app wrt rendering states set etc (which complicates it heaps)im not to sure what would be ideal for the user perhaps someit likefont->init_font( "verdana", 16 );font->add_string( X,Y, vec4(1,1,1,1), text );font->add_string_with_word_wrap( X,Y,W,H, vec4(1,1,1,1), text );font->flush_all(); or font->simple_flush_all(); // set 2d ortho window + states   ;  Well the whole thing is geared for simple usage This means I traded off a lot of neat things that could have been done.Also, really, just how much text is your game going to render in the 2d UI? Does it even matter?Now lets talk turkey. Baste the bird so to speak.If you want to support your own way or doing things, OTTER need never make any GL calls sans setting up its textures. Simply do something like this:r = font->install_ascii("myfont.ttf",18);font->select(r);font->string("I love turkey!");int rlen = 0;font_sovts *rdat = font_stream(&rlen);Now, in rdat is all the coords (texture and vertex) for all the quads needed to render the text. Since none of these calls draw, you never need to call font-begin() and font->end();Of course, making OTTER support rendering into your own vertex array (with user format) is something for 1.2.   