Existe uma biblioteca decente de desenho de texto OpenGL para o iPhone SDK?

Eu estou tentando descobrir um simples para desenhar algum texto no OpenGL. Minha pesquisa mostrou que é uma tarefa bastante complexa. Ele envolve a criação (ou geração em tempo de execução) de uma textura de atlas de fonts e a criação de um quadrilátero para cada letra com as coordenadas corretas de posicionamento e textura.

Já ouvi algumas coisas boas sobre o freetype, mas descobri muito pouco sobre como executá-lo no iPhone, e parece ser bastante complexo.

Então, existe alguma biblioteca de texto em OpenGL com Objective-C que funcione com o iPhone SDK que as pessoas estão usando? Ou estou apenas pensando nisso e há uma abordagem mais fácil que estou perdendo?

Sua descrição de usar o freetype para criar um atlas de textura junto com todas as informações de glifo é exatamente o que eu estou fazendo no meu projeto atual do iPhone.

Eu faço toda a análise da fonte em uma etapa de pré-processo (tudo em C # no Windows, como acontece). O próprio atlas é gerado e contém apenas os caracteres necessários – para reduzir o espaço, às vezes também acabo gerando mais de um único atlas para manter tamanhos de texturas em pow2 e uma resolução sensível.

Você pode facilmente extrair as informações de glifo do freetype. Passe isso junto ao seu aplicativo junto com as texturas em tempo de execução e, em seguida, é bastante trivial apenas alterar as coordenadas de UV da textura conforme necessário.

Por que vale a pena, é assim que eu defino um caractere de glifo dentro do meu pequeno mecanismo:

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? }; 

Eu então tenho um object ‘SpriteString’, que se comporta como qualquer outra string, além de poder desenhar usando sprites ….

Eu concordo que tudo isso pode parecer um grande trabalho para um problema bastante trivial, mas eu descobri que me deu bastante flexibilidade e realmente não demorei tanto para implementar quando cheguei a isso.

Sinta-se à vontade para responder ou comentar se precisar de outros detalhes. (E boa sorte 🙂


Responda ao seu comentário enquanto eu fiquei sem espaço na seção de comentários …

Confira a documentação do freetype, ela basicamente fornece os dados do glifo sem mexer, apenas puxa para fora da fonte. Quanto às próprias texturas, você obtém um freetype para renderizar cada glifo e, em seguida, gerencia isso para criar a textura. Isso eu faço como um pré-processo totalmente separado do meu aplicativo principal.

Aqui está um trecho do meu código de ferramenta que faz isso: http://pastebin.com/md1c6354

Por favor note, porém, isso só foi destinado a meus olhos e não para consumo público, então desculpe o fato de que é confuso como o inferno 🙂

Uma maneira de fazer isso é configurar um UILabel e renderizar sua camada em uma textura. Uma rota indireta para isso seria primeiro configurar o UILabel com texto, fonte, etc. e, em seguida, usar o seguinte código

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

para capturar o UILabel para um UIImage. Você poderia então usar o construtor initWithImage: da class Texture2D no projeto CrashLanding para transformar isso em uma textura.

Parece initWithImage: nesse exemplo re-renderiza o UIImage para um contexto de bitmap e usa isso para criar a textura. Com um pouco de trabalho, você pode extrair o código relevante desse método e alterar o código acima para renderizar sua camada diretamente na textura.

Dessa forma, você obtém o bom suporte Unicode e fonte do UILabel ao criar o texto para sua textura.

Eu encontrei uma solução simples para isso. Aqui está uma function rápida que escrevi para isso. (Você precisará da class 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); } 

Acredito que as coordenadas de input precisam estar em suas coordenadas mundiais, mas não tenho certeza se isso é verdade em geral ou se funciona dessa maneira para mim. Você pode precisar jogar com os offsets para acertar.

Obrigado por esse método. Isso me salvou algum tempo.

Havia algumas coisas que eu tinha que mudar embora. A chamada glBlendFunc precisava ser:

 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA) 

E em segundo lugar, o texto parecia estar desenhando em um único ponto. A chamada CGRectMake está criando um retângulo 1×1, a menos que eu esteja lendo isso incorretamente.

Use a biblioteca de fonts “musings”:

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 🙂

Ele vem com suporte a unicode, carrega glifos “on-demand” e até tem uma maneira de gerar variables

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

Eu criei uma class de fonte semelhante à biblioteca de fonts “musings”, menos os vazamentos de memory e menos a criação de textura para cada caractere, cada quadro. Ele ainda usa um glTexture diferente para cada personagem. Nota: Texture2D foi alterado para comentar sua exclusão de textura.

init no construtor: _font = new Font("Helvetica", 40);

use no método redraw (): _font->draw("Hello, World!", 50, 100, ALIGN_LEFT);

Link do GitHub:

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

Verifique a demonstração de pouso forçado. A class Texture2D que é fornecida permite a criação de texturas com texto e uma fonte. (Espero que haja uma resposta melhor Eu adoraria uma maneira mais simples de desenhar para uma visão opengles)

Sim, existem 2 que eu conheço . O truque é que você tem que renderizar a textura usando o Quartz (funções CGContext *), então renderizar essa textura para o usuário ver.

Se você está preocupado com o desempenho, também pode usar o Quartz para gerar seu atlas de textura.

É bastante fácil criar uma ferramenta de geração de texturas (no xCode) uma vez que você conheça os fundamentos da renderização de uma fonte .

Tudo o que você precisa fazer é ter um CGContext válido. Você pode encontrar um código de exemplo muito bom neste carregador de textura .

Basicamente o código vai:

 // 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 ; 

Ele sai muito bonito e antialiased,

atlas de tex

Uma lista de fonts ios está disponível aqui e com pré – remetentes aqui