¿Hay una biblioteca decente de dibujo de texto OpenGL para el iPhone SDK?

Estoy tratando de encontrar un simple para dibujar texto en OpenGL. Mi investigación ha demostrado que es una tarea bastante compleja. Implica crear (o generar en tiempo de ejecución) una textura de atlas de fuente y luego crear un cuadrángulo para cada letra con las coordenadas de colocación y textura correctas.

He escuchado algunas cosas buenas acerca de freetype, pero he descubierto muy poco sobre cómo ejecutarlo en el iPhone, y parece ser bastante complejo.

Entonces, ¿hay alguna biblioteca de texto OpenGL envuelta en Objective-C que funcione con el SDK de iPhone que las personas han estado usando? ¿O estoy por encima de pensar esto y hay un enfoque más fácil que me estoy perdiendo?

Tu descripción de usar freetype para crear un atlas de texturas junto con toda la información de glifos es exactamente lo que estoy haciendo en mi proyecto actual de iPhone.

Hago todo el análisis de la fuente en un paso previo al proceso (Todo en C # en Windows, como sucede). El atlas en sí mismo se genera y contiene solo los caracteres necesarios: para reducir el espacio, también a veces termino generando más de un atlas para mantener las texturas en tamaños pow2 y de una resolución sensata.

Puede extraer fácilmente la información de glifos de freetype. Transfiere eso a tu aplicación junto con las texturas en tiempo de ejecución y luego es bastante trivial simplemente alterar los coords UV de la textura según sea necesario.

Por lo que vale, así es como defino un carácter de glifo dentro de mi pequeño motor:

struct FontGlyph { u32 char_code; u32 m_x; // base x position on tpage u32 m_y; // base y position on tpage u32 m_width; // glyph width u32 m_height; // glyph height i32 m_horiBearingX; // Distance to X shift i32 m_horiBearingY; // Distance to Y shift u32 m_horiAdvance; // Total Horizontal advance this character requires u32 m__tpage_index; // Which tpage does this glyph use? }; 

Luego tengo un objeto ‘SpriteString’, que se comporta como cualquier otra cadena, aparte de que puedo dibujar usando sprites ….

Estoy de acuerdo en que todo esto puede parecer un gran trabajo para un problema bastante trivial, pero he descubierto que me ha dado mucha flexibilidad y realmente no tardé tanto en implementarlo cuando llegué a eso.

No dude en responder o comentar si necesita más detalles. (Y buena suerte 🙂


Responda a su comentario cuando me quede sin espacio en la sección de comentarios …

Echa un vistazo a la documentación de Freetype, básicamente te da los datos del glifo sin problemas, simplemente lo saca de la fuente. En cuanto a las texturas en sí, obtienes el tipo de freet para representar cada glifo, y luego lo administras para construir la textura. Esto lo hago como un proceso previo completamente separado de mi aplicación principal.

Aquí hay un extracto de mi código de herramienta que hace esto: http://pastebin.com/md1c6354

Sin embargo, tenga en cuenta que esto solo fue pensado para mis ojos y no para el consumo público, así que disculpe el hecho de que está desordenado como el infierno 🙂

Una forma de hacerlo es configurando un UILabel y luego renderizando su capa en una textura. Una ruta indirecta a esto sería configurar primero UILabel con texto, fuente, etc. y luego usar el siguiente código

 UIGraphicsBeginImageContext(yourLabel.frame.size); [yourLabel.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *layerImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

para capturar el UILabel a un UIImage. Luego puede usar el constructor initWithImage: de la clase Texture2D en el proyecto CrashLanding para transformarlo en una textura.

Parece que initWithImage: en ese ejemplo vuelve a mostrar el UIImage en un contexto de bitmap y lo usa para crear la textura. Con un poco de trabajo, puede extraer el código relevante de ese método y modificar el código anterior para convertir su capa directamente en la textura.

De esta forma, obtienes la agradable compatibilidad con Unicode y fonts de UILabel al crear el texto para tu textura.

Encontré una solución simple para esto. Aquí hay una función rápida que escribí para ella. (Necesitarás la clase Texture2D.)

 - (void) drawText:(NSString*)theString AtX:(float)XY:(float)Y { // Use black glColor4f(0, 0, 0, 1.0); // Set up texture Texture2D* statusTexture = [[Texture2D alloc] initWithString:theString dimensions:CGSizeMake(150, 150) alignment:UITextAlignmentLeft fontName:@"Helvetica" fontSize:11]; // Bind texture glBindTexture(GL_TEXTURE_2D, [statusTexture name]); // Enable modes needed for drawing glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // Draw [statusTexture drawInRect:CGRectMake(X,Y-1,1,1)]; // Disable modes so they don't interfere with other parts of the program glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); } 

Creo que las coordenadas de entrada deben estar en las coordenadas de tu mundo, pero no estoy seguro de si eso es cierto en general o si funciona de esa manera para mí. Es posible que necesite jugar con las compensaciones para hacerlo bien.

Gracias por ese método. Me salvó un tiempo.

Sin embargo, hubo un par de cosas que tuve que cambiar. La llamada glBlendFunc necesitaba ser:

 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA) 

Y en segundo lugar, el texto parecía estar dibujando en un solo punto. La llamada CGRectMake crea un rectángulo de 1×1, a menos que lo lea incorrectamente.

Use la biblioteca de fonts “meditaciones”:

http://www.themusingsofalostprogrammer.com/2010/01/how-to-do-font-rendering-in-opengl-on.html

 Font font("Verdena"); font.print("Hello World!", x, y, z); 

Fácil 🙂

Viene con soporte unicode, carga glifos “a pedido” e incluso tiene una forma de generar variables

 font.print(x, y, z) << "fps: " << fps; 

Creé una clase de fuente similar a la biblioteca de fonts “meditaciones”, menos las pérdidas de memoria y menos la creación de texturas para cada personaje, cada fotogtwig. Todavía usa una glTexture diferente para cada personaje. Nota: Texture2D se ha cambiado para comentar su eliminación de textura.

init en constructor: _font = new Font("Helvetica", 40);

usar en el método _font->draw("Hello, World!", 50, 100, ALIGN_LEFT); (): _font->draw("Hello, World!", 50, 100, ALIGN_LEFT);

Enlace de GitHub:

https://github.com/chandl34/public/tree/master/personal/c%2B%2B/Font

Verifique la demo de aterrizaje forzoso. La clase Texture2D que se proporciona permite la creación de texturas con texto y una fuente. (Afortunadamente habrá una mejor respuesta, me encantaría una forma más simple de dibujar en una vista de apertura)

Sí, hay 2 que yo sé . El truco es que debes renderizar la textura usando Quartz (funciones CGContext *) y luego renderizar esa textura para que el usuario la vea.

Si le preocupa el rendimiento, también puede usar Quartz para generar su atlas de textura.

Es bastante fácil actualizar una herramienta de generación de texturas (en xCode) una vez que conozca los conceptos básicos de renderizar una fuente .

Todo lo que tienes que hacer es tener un CGContext válido. Puede encontrar un código de muestra muy bueno en este cargador de texturas .

Básicamente el código dice:

 // Create the cgcontext as shown by links above // Now to render text into the cg context, // the drop the raw data behind the cgcontext // to opengl. 2 ways to do this: // 1) CG* way: (advantage: easy to use color) CGContextSelectFont(cgContext, "Arial", 24, kCGEncodingMacRoman); // set color to yellow text CGContextSetRGBFillColor(cgContext, 1, 1, 0, 1) ; // Be sure to use FILL not stroke! // draw it in there CGContextShowTextAtPoint(cgContext, 20, 20, "HI THERE", strlen("HI THERE") ) ; /* // WAY #2: this way it's always black and white // DRAW SOME TEXT IN IT // that works ok but let's try cg to control color UIGraphicsPushContext(cgContext); UIFont *helv = [UIFont fontWithName:@"Helvetica" size:[UIFont systemFontSize]]; NSString* msg = @"Hi hello" ; [msg drawInRect:CGRectMake(0,0,pow2Width,pow2Height) withFont:helv] ; UIGraphicsPopContext(); */ // put imData into OpenGL's memory glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pow2Width, pow2Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imData); CHECK_GL ; 

Sale luciendo bastante bien y antialias,

tex atlas

Una lista de fonts ios está disponible aquí , y con prerrededores aquí