有没有一个像样的OpenGL文本绘图库的iPhone SDK?
我试图找出一个简单的在OpenGL中绘制一些文字。 我的研究表明它是一个相当复杂的任务。 它包括创build(或在运行时生成)字体图集纹理,然后创build每个字母只有正确的位置和纹理坐标四元组。
我听说过关于freetype的一些好消息,但是却没有发现如何让它在iPhone上运行,而且看起来相当复杂。
那么是否有任何Objective-C包装的OpenGL文本库与人们一直在使用的iPhone SDK一起工作? 还是我只是在想这个,有一个更简单的方法,我失踪了?
你使用freetype来创build纹理地图集以及所有字形信息的描述正是我在当前的iPhone项目中所做的。
我在前处理步骤中完成所有字体的parsing(所有在Windows上的C#都是这样)。 地图本身生成,只包含需要的字符 – 为了减less空间,有时我最终还是生成了不止一个地图集,以保持纹理大小pow2和合理的分辨率。
您可以轻松地从freetype中提取字形信息。 在运行时将它们与纹理一起传递给应用程序,然后根据需要更改纹理的UV坐标,这相当简单。
对于它的价值,这是我如何在我的小引擎中定义一个字形字符:
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? };
然后,我有一个“SpriteString”对象,其行为几乎像任何其他string,除了我可以使用精灵绘制….
我同意这一切似乎是一个相当小的问题的大工作,但我发现它给了我很大的灵活性,真的没有花很长时间来实现,当我一口气。
如果您需要任何其他细节,请随时回复或评论。 (还有祝你好运 :)
当我在评论部分跑出房间时回复您的评论…
查看freetype文档,它基本上给你的字形数据没有搞砸,它只是把它从字体中拉出来。 至于纹理本身,您可以使用freetype来渲染每个字形,然后pipe理它来构build纹理。 这是我作为一个完全独立于我的主要应用程序的预过程。
以下是我的工具代码的摘录: http : //pastebin.com/md1c6354
请注意,虽然这只是有意为我的眼睛,而不是公共消费,所以请原谅这是凌乱的事实:)
一种方法是设置UILabel,然后将其图层渲染为纹理。 间接的路线是首先用文本,字体等设置UILabel,然后使用下面的代码
UIGraphicsBeginImageContext(yourLabel.frame.size); [yourLabel.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *layerImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
将UILabel捕获到UIImage。 然后,您可以使用CrashLanding项目中的Texture2D类的initWithImage:构造函数将其转换为纹理。
它看起来像initWithImage:在这个例子中,将UIImage重新渲染到位图上下文,并使用它来创build纹理。 通过一些工作,您可以从该方法中提取相关代码,并更改上面的代码以将图层直接渲染到纹理中。
这样,在为纹理创build文本时,您将获得UILabel的Unicode和字体支持。
我find了一个简单的解决scheme。 这是我为它写的一个快速function。 (您将需要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); }
我相信input坐标需要在你的世界坐标上,但是我不确定这是否是真的,或者它对我来说是正确的。 您可能需要使用偏移量才能正确使用。
感谢那个方法。 这节省了我一些时间。
有几件事我不得不改变。 glBlendFunc调用需要是:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_ALPHA)
其次,文本似乎正在绘制成一个单一的点。 CGRectMake调用正在创build一个1×1矩形,除非我正在读取不正确。
使用“沉思”字体库:
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);
简单 :)
它带有Unicode支持,“按需”加载字形,甚至有输出variables的方法
font.print(x, y, z) << "fps: " << fps;
我创build了一个类似于“沉思”字体库的Font类,减去内存泄漏,减去每个字符,每个帧的纹理创build。 它仍然为每个字符使用不同的glTexture。 注意:Texture2D已被更改为注释掉其纹理删除。
初始化在构造函数中: _font = new Font("Helvetica", 40);
在redraw()方法中使用: _font->draw("Hello, World!", 50, 100, ALIGN_LEFT);
GitHub链接:
https://github.com/chandl34/public/tree/master/personal/c%2B%2B/Font
检查崩溃登陆演示。 所提供的Texture2D类允许创build带有文本和字体的纹理。 (希望会有更好的答案,我会爱一个更简单的方式绘制到opengles视图)
是的,我知道有2个 。 诀窍是,您必须使用Quartz(CGContext *函数)渲染纹理,然后渲染该纹理以供用户查看。
如果您关心性能,还可以使用Quartz来生成纹理图集。
一旦你知道渲染字体的基础知识,就可以很容易地创build纹理生成工具(在xCode中)。
所有你需要做的是有一个有效的CGContext。 你可以在这个纹理加载器中find一些非常好的示例代码。
基本上这个代码是这样的:
// 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 ;
它出来看起来不错,antialiased,
在这里可以find ios字体的列表, 在这里还有prerenders