glutbitmapcharacter performance opengl text-rendering

performance - glutbitmapcharacter - ¿Cómo hacer OpenGL live text-rendering para una GUI?



download freetype (7)

Estoy implementando una GUI construida sobre OpenGL. Llegué al problema que tendrá cada GUI: representación de texto. Sé de varios métodos para renderizar texto en OpenGL, sin embargo, me pregunto cuál de ellos sería el más adecuado para una GUI.

En general, en una GUI tenemos dos tipos de texto: estático y en vivo. La estática es bastante fácil: podemos convertir un TTF en una textura y olvidarnos de ella. Es el texto "en vivo" el que me molesta más: imagine una consola o un chat en vivo en un juego multijugador.

Pensé en varias opciones:

  • no hay casos especiales: renderice y cargue una textura cada vez que cambie el texto, teniendo en cuenta solo para volver a enviarlo cuando aparezca un texto nuevo, y tratando de dividir el texto más grande en partes pequeñas (como por línea de chat). Sin embargo, esto todavía nos dejaría pendientes en casos como una línea de puntuación que cambia todo el tiempo, o un texto de introducción que representa "por personaje" (estilo de máquina de escribir visto en algunos juegos de ciencia ficción)
  • quad-por carácter: esto también parece ser una solución popular, se prepara una textura con la tabla ASCII y se renderiza un carácter cuatricromático texturizado. Sin embargo, tengo serias dudas sobre la eficacia de tal solución. Consejos para hacer eso más rápido también serían bienvenidos.
  • soluciones híbridas, sin embargo, no tengo idea de cómo implementar eso limpiamente

La pregunta es, por lo tanto, cómo hacer un texto en OpenGL de manera eficiente.

Si esto ayuda, estoy codificando en C ++ STL / Boost-heavy y apuntando a las tarjetas gráficas GForce 6 y posteriores.


EDIT2: Sean Barrett acaba de lanzar fuentes Bitmap para programadores 3D C / C ++ .

EDITAR: otra joya de código que vale la pena ver es Font Stash, que aprovecha el stb_truetype.h Sean Barrett.

Puede crear una textura en la que represente todos los caracteres de su fuente. Luego, simplemente dibuja quads con textura con proyección ortográfica y coordenadas de textura apropiadas: este enfoque funciona cuando el texto está en un idioma que no contiene muchos símbolos: como inglés. La textura de la fuente se crea una vez al comienzo de la aplicación y luego la representación de los cuádriceps es realmente rápida.

Eso es lo que estoy usando y creo que es la forma más rápida de procesar texto en OpenGL. Al principio, utilicé la herramienta Generador de fuentes Bitmap de Angelcode y luego integé FreeType directamente y construí una gran textura que contenía todos los glifos al inicio de la aplicación. En cuanto a los consejos para mejorar la velocidad de renderizado de los cuádriceps, acabo de utilizar VBO como para el resto de la geometría en mi aplicación.

Me sorprende que tengas dudas sobre el renderizado cuádruple mientras que no pareces preocuparte por el rendimiento de generar una textura en la CPU, luego subirla, luego unirla para finalmente renderizar un rectángulo con ella, que para cada fotograma. Cambiar los estados de OpenGL es el cuello de botella, no los 500 - 1000 quads que usará para el texto.

Además, eche un vistazo a bibliotecas como la biblioteca FTGL que convierte toda la fuente en polígonos (fuentes geométricas).


Es complicado de hacer, especialmente si desea utilizar técnicas de representación de fuentes subpixel. Eche un vistazo al ClanLib SDK . Utiliza un procesador de proceso por lotes para representar una pantalla completa de texto en una sola llamada OpenGL. Como tiene una licencia basada en zlib, puede extraer su código si no desea usar el SDK en sí mismo.


Intente leer esto: http://dmedia.dprogramming.com/?n=Tutorials.TextRendering1 .

El enfoque descrito es el método típico para la representación de texto con API de gráficos. Un personaje por quad y todos los datos de imagen para texto en una sola textura. Si puede ajustar todo su conjunto de caracteres en una textura (de hecho, dependiendo del tamaño de la textura, puede ser que pueda caber en varias), la representación es extremadamente rápida.

La clave es que el enlace de textura es la operación que necesita minimizar. Si puede renderizar todo su texto con una sola textura, no importará la cantidad de texto que necesite poner en la pantalla. Incluso si tiene que cambiar texturas varias veces (fuentes diferentes, diferentes atributos de fuente [negrita, subrayado, etc.]), el rendimiento debería ser bueno. El rendimiento del texto puede ser más crítico para un HUD, pero es menos importante en la GUI.


Por cada personaje quad manejado, una lista de visualización (actualizada solo cuando el texto cambia) es suficiente para la mayoría de los casos.

Lo usé con las fuentes X11 usando XLoadQueryFont, glGenLists, glXUseXFont, glCallLists, tienes una matriz de listas de visualización que describen cada personaje.

la función glCallLists acepta un argumento char * para su texto y se puede incrustar dentro de una lista de visualización.

Entonces terminas con una sola llamada para mostrar el texto de bloques.

La textura de fuente sugerida por G. Pakosz es similar, pero usted calcula sus propias listas de visualización "por carácter".

Sus primeras opciones serán bastante más lentas, ya que requerirán un procesamiento basado en el procesador en cada cambio de texto.


Puede representar el texto como caras triangulares y evitar el uso de una textura. De esta forma evitará los bordes difusos cuando se amplía el texto. Escribí una fuente ASCII de baja poli que está abierta y disponible en mi github .

Otra forma de tener bordes afilados en el texto es la representación de fuentes SDF , pero esto adolece de algunos artefactos.


podría usar estas dos funciones:

void renderstring2d(char string[], float r, float g, float b, float x, float y) { glColor3f(r, g, b); glRasterPos2f(x, y); for(unsigned int i = 0; i &lt strlen(string); i++) glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]); } void renderstring3d(char string[], float r, float g, float b, float x, float y, float z) { glDisable(GL_LIGHTING); glColor3f(r, g, b); glRasterPos3f(x, y, z); for(unsigned int i = 0; i &lt strlen(string); i++) glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]); }

luego, cuando procesa texto en 2D, no olvide restablecer las matrices de proyección de modelos y de proyección.

glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // Render text and quads glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix();

No necesita renderizar en un quad usando estas funciones, porque estas funciones se procesan directamente en el framebuffer.

Y si eso no funciona para ti, mira esto. http://www.opengl.org/resources/faq/technical/fonts.htm

Habla de renderizar texto usando glBitmap, glDrawPixels y alfa blending.