Este código le permite representar texto de alto rendimiento en su propia aplicación OpenGL. La biblioteca de renderizado de fuentes fue diseñada con facilidad de uso y rendimiento de rendimiento. Lo escribí en ~ 2010 y lo actualicé de vez en cuando. Los archivos de fuentes leídos por esta biblioteca siguen el formato desarrollado para el generador de fuentes BM: http://angelcode.com/products/bmfont/. El archivo de fuentes se acompaña de un archivo de textura. La biblioteca admite texturas RGBA estándar, así como SDF de un solo canal, e incluso SDF de canales múltiples.

Manténganse al tanto.
La biblioteca de fuentes se divide en los siguientes archivos:
La llamada de función de cordón de dibujo hace lo siguiente: recibe cadena → cadena analiza → Crea una lista de quads → traduce eso en una matriz de búfer de vértice -> dibuja todos los triángulos texturizados. Durante el análisis, la cadena para dibujar se verifica para los caracteres que no se pueden dibujar por la fuente actual, esos caracteres se dibujarán como signos de interrogación. Para cada personaje de la cadena, se crea un quad y se agrega a la lista de quad final, este quad contiene información sobre la posición y el tamaño en la pantalla (¡2D, ortogonal!) Y la textura coordinada para ese personaje dentro de la fuente de mapa de bits. La posición de un quad depende de la posición inicial de la cadena y la posición del carácter anterior. La relación específica entre el espacio de un carácter y el siguiente se llama kerning. El archivo de configuración de fuentes contiene una tabla con toda la información de kerning para esa fuente específica. Por ejemplo, podría ser que si una "A" sigue a una "M", debe estar separada por un píxel, sin embargo, cuando una "O" sigue una "M", es menos un píxel o píxeles cero. Esta información se almacenan internamente en una matriz bidimensional para acceso rápido. Para hacer este dibujo lo suficientemente rápido, toda la información sobre los caracteres y las relaciones de los personajes (como Kerning), así como las texturas se cargan al inicio del programa. Los textos se pueden almacenar para que no tengan que crearse en cada iteración de bucle de renderizado.
La forma más fácil de verificar cómo funciona la biblioteca y cómo puede usarla en su proyecto es revisando la implementación de ejemplo suministrada con este repositorio. Sin embargo, en caso de que necesite más información, lea el resto de este capítulo.
Deberá copiar los 10 archivos mencionados en la vista excesiva en la carpeta de su proyecto.
En su código, cree un objeto de biblioteca de fuentes globales, antes de abrir un contexto de renderizado, como así:
// load openGL fonts
m_fontLibrary = new CFontLibrary(<PathToFontFolder>);
if (!m_fontLibrary-> ParseAllFontsInFolder ())
return; // no fonts found!Esto cargará todas las fuentes almacenadas en la carpeta que ha especificado como parámetro de entrada. Después de que se crea el contexto de renderizado, las texturas deben cargarse, así:
// init font library from the current rendering context!
theApp.m_fontLibrary-> InitGLFonts ();Esto se puede hacer en una función inicial única de ese contexto de renderizado, por ejemplo. Tenga en cuenta que no puede compartir texturas entre dos o más contextos con esta biblioteca (no la implementé porque en ese momento no había una forma eficiente de hacerlo, solo algunas tarjetas NVIDIA podían y solo). Por lo tanto, debe llamar a esto para cada nuevo contexto de renderizado. Una vez hecho esto, la biblioteca de fuentes está lista para usar, lo que significa que puede llamar al método DrawString () desde el objeto FontLibrary.
(Nota: este capítulo necesita una revisión, es solo más o menos correcto, faltan algunos parámetros de función, pero en su mayoría se explican por sí mismos) el encabezado de la llamada de dibujo lee:
void DrawString ( const std::string& textToDraw, int x, int y, float color[ 4 ], const std::string& font, float scale = 1 . 0f );Los parámetros se describen a continuación en la tabla.
| Parámetro | Descripción |
|---|---|
| const std :: string y texttodraw | La cadena para dibujar como std :: cadena, los caracteres no reconocidos se dibujan como '?'. Qué caracteres son válidos depende de la fuente utilizada y se pueden definir al crear Font-BitMap. |
| int x | Posición X del comienzo de la cadena en las coordenadas de la pantalla. 0 - ancho |
| int y | Posición y del comienzo de la cadena en las coordenadas de la pantalla. 0 - Altura |
| color flotante [4] | La matriz flotante que contiene la información de color que se utilizará para modular la textura. La información del color son valores de 0.0 a 1.0 (inclusive), en el siguiente orden estándar: {r, g, b, alfa} obviamente .. |
| const std :: string & font | Este parámetro define el tipo de fuente a usar. Solo se pueden usar tipos de fuentes que están en la carpeta y estaban allí en el momento de la carga. Puede pasar el nombre del archivo de esa fuente, sin la extensión o para obtener más lectura y seguridad de código, utilice la definición de archivo: fontLibrary.h. Nota: Si desea imprimir en negrita o en cursiva, entonces debe usar una fuente que esté configurada para hacerlo. |
| escala flotante | Para las texturas RGBA se recomienda usar el valor predeterminado: 1.0f. Puede escalar hacia arriba o hacia abajo, pero debe quedar claro que esto dará como resultado un desenfoque. Sin embargo, con SDF y MSDF, debería poder escalar más allá antes de ver artefactos. |
Tenga en cuenta que hay más funciones con características adicionales, como descansos automáticos de línea. Consulte el archivo de encabezado de la biblioteca de fuentes. También tenga en cuenta que la cadena para dibujar se cortará después de 10922 caracteres. Si necesita más carácter por cualquier razón extraña, simplemente use llamadas de dibujo adicionales y divida la cadena en partes.
Este capítulo se refiere a agregar sus propias fuentes a la biblioteca de fuentes.
Tenga en cuenta que me concentro en fuentes no SDF aquí. Los pasos para las fuentes SDF son bastante similares, sin embargo, BM-Font-Gen no es suficiente. Todavía puede usar esa herramienta, pero deberá realizar un paso de procesamiento posterior con herramientas como ImageMagick. Tutorial a continuación.
Solo se necesitan tres pasos para integrar una nueva fuente: 1. Cree la fuente-config y Font-bitmap usando BM-Font-Generator 2. Copie los dos archivos resultantes en la carpeta Fonts 3. (Opcional) Agregue la cadena de fuentes como Define a FontLibrary.h para que pueda usarlo más fácilmente en su aplicación
En la siguiente sección, el uso del generador de fuentes BM se describe en detalle, pero primero algunas notas. Cada archivo de fuente que produce contiene solo una fuente de un tamaño fijo, también ya está definido por el archivo, ya sea en negrita o en cursiva, etc. El mismo recuento de esquema, suavidad de la fuente, etc. Este asunto se volverá más claro con la siguiente sección.
Para producir el config de fuentes, así como el mapa de bits de fuentes, uso el "Generador de fuentes de mapa de bits" de AngelCode. Que se puede obtener de su sitio web: http://angelcode.com/products/bmfont/ Después de la instalación, abra el programa, debería parecer en la siguiente figura.

Como primer paso, abra los ajustes de fuentes, haciendo clic en Opciones → Configuración de fuentes o presionando [F], que abrirá una nueva ventana, como se muestra en la siguiente figura.

Después de hacer estas configuraciones, cierre la ventana de configuración de fuente y continúe con el siguiente paso.
De vuelta en la ventana principal del programa, ahora puede seleccionar los conjuntos de caracteres que desea incluir. Puede seleccionar conjuntos completos o seleccionar solo caracteres específicos de un conjunto. Como ejemplo, ver la siguiente figura.

Como regla básica, solo seleccione los caracteres que es probable que use, esto ahorra tiempo de procesamiento y, sobre todo, memoria, no solo un carácter, sino mucho más (kerning, tamaño de mapa de bits, tamaños de matriz en nuestro código, etc.). Después de seleccionar todos los caracteres que su fuente incluirá, proceda a la siguiente sección.
Ahora es el momento de exportar la fuente como un mapa de bits y crear un archivo de configuración para ella. Abra las opciones de exportación mi presionamiento, ya sea [t], o haga clic en Opciones → Opciones de exportación. Debe aparecer una nueva ventana, como en la siguiente figura.

Una vez que se realicen estas configuraciones, cierre la ventana y continúe al siguiente paso.
Para asegurarse de que su textura no sea ni demasiado grande o demasiado pequeña, presione [v] mientras esté en la ventana principal o haga clic en Opciones → Visualizar. Si el título de la ventana dice algo más que "vista previa 1/1", su textura es demasiado pequeña para todos sus personajes y el programa produciría más de un mapa de bits. En ese caso, abra las opciones de exportación y aumente el tamaño de la textura. Nota: ya no necesita ser cuadrado o una potencia de dos, esto solo estaba en OpenGL versión 1, el caso. Sin embargo, todavía lo recomendaría que lo haga como tal, ya que algunas funciones relacionadas con la textura aún pueden estar optimizadas para ello. La fontlibrary intencionalmente no maneja más de una "página" o textura, ya que esto significaría unir/desgastar la textura durante una llamada de cordón, lo cual es lento! Así que hazlo exactamente una página. Si, por otro lado, ves que los caracteres solo llenan una parte del mapa de bits, reduzca el tamaño de la textura, si es posible, pero esto no es tan importante como al revés. Una vez que esté satisfecho con el uso del espacio de textura, continúe con el siguiente paso.
Ahora que se realizan todas las configuraciones, es hora de exportar la fuente. Haga clic en Opciones → Guardar mapa de bits como ... El nombre de archivo que especifique aquí afectará el nombre de la fuente en la biblioteca de fuentes, así que elija sabiamente. Por razones de conveniencia y legibilidad, sugiero la siguiente convención de nombres:
< Entenshic? > <Ald> <_ ¿Size?>
Aquí hay algunos ejemplos:
Presione Guardar para completar el proceso. Todo lo que hay que hacer ahora es copiar los dos archivos para esa fuente en la carpeta de fuentes de su software. Puede convertir el TGA en PNG con otra herramienta, solo recuerde cambiar la extensión del archivo en el archivo FNT correctamente.
Este es un proceso de 3 pasos.
Primero, use el generador BMFONT como se describió anteriormente. Sin embargo, luego use la siguiente configuración que puede diferir en forma de lo que ha usado antes.
Por último, debe usar ImageMagick (https://imagemagick.org/index.php) o una herramienta similar para convertir el archivo de textura en un SDF. Una vez que tenga instalado ImageMagick, ejecute lo siguiente desde la línea de comando (el ejemplo es para Windows Power Shell, pero es muy similar para Unix):
magick convert --% Arial400_0.tga -filter Jinc ( +clone -negate -morphology Distance Euclidean -level 50%,-50% ) -morphology Distance Euclidean -compose Plus -composite -level 45%,55% -resize 25% Arial400_0.png
A continuación, necesitamos editar el archivo FNT. Agregue lo siguiente al encabezado FNT mi mano antes de la definición de chars:
fieldType=sdf
Esto le dirá a la fuente lib a la usa del sombreador SDF de un solo canal cuando se use esta fuente.
Para los SDF de múltiples channel, no puede usar el generador de fuentes BM, en su lugar, use: https://soimy.github.io/msdf-bmfont-xml/ Con esta herramienta, debe comenzar desde un archivo TTF, pero recibirá el archivo FNT habitual más un archivo PNG. Una vez instalado, ejecute lo siguiente desde la línea de comando:
msdf-bmfont -o multisdf.png cour.ttf
Tenga en cuenta que también puede suministrar el tamaño de fuente y otros parámetros a través de la línea de comandos.
Esto es opcional: haga una definición para cada fuente nueva que agregue a la FontLibrary.h, ¡sin embargo, esto debería facilitar la codificación!
// font type defines, string must match the filename without extension in your fonts folder!
# define GLFONT_COURIER42_MSDF " Courier42_msdf "
# define GLFONT_ARIAL20 " Arial20 "
# define GLFONT_DINNEXTLTPROMED_SDF " DINNextLTProMED_SDF ".. Agregue su propia define aquí!