我试图弄清楚在OpenGL中绘制一些文本的简单方法.我的研究表明它是一项相当复杂的任务.它涉及创建(或在运行时生成)字体图集纹理,然后为每个字母创建一个四边形,只有正确的位置和纹理坐标.
我听说过一些关于freetype的好东西,但是对于如何让它在iPhone上运行却发现很少,而且看起来相当复杂.
那么是否有任何Objective-C包装的OpenGL文本库可以与人们一直使用的iPhone SDK一起使用?或者我只是在思考这个问题而且我有一个更容易的方法,我错过了?
一种方法是设置UILabel,然后将其图层渲染为纹理.对此的间接途径是首先使用文本,字体等设置UILabel,然后使用以下代码
UIGraphicsBeginImageContext(yourLabel.frame.size); [yourLabel.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *layerImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
捕获UILabel到UIImage.然后,您可以在CrashLanding项目中使用Texture2D类的initWithImage:构造函数将其转换为纹理.
它看起来像initWithImage:在该示例中,将UIImage重新呈现为位图上下文并使用它来创建纹理.通过一些工作,您可以从该方法中提取相关代码并更改上面的代码,直接将图层渲染到纹理中.
这样,在为纹理创建文本时,您可以获得UILabel的Unicode和字体支持.
您使用freetype创建纹理图集以及所有字形信息的描述正是我在当前iPhone项目中所做的.
我在预处理步骤中完成了对字体的所有解析(在Windows上的所有C#中都是如此).地图集本身生成并且仅包含所需的字符 - 为了减少空间,我有时最终生成的不仅仅是单个图集以保持纹理尺寸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'对象,其行为与任何其他字符串非常相似,除了我可以使用精灵绘制它....
我同意这对于一个相当微不足道的问题看起来似乎是一件很重要的事情,但我发现它给了我足够的灵活性,并且在我开始实施时并没有花太多时间来实现它.
如果您需要任何其他详细信息,请随时回复或发表评论.(还有祝你好运 :)
当我在评论部分用完房间时回复你的评论...
查看freetype文档,它基本上为您提供了字形数据而没有搞乱,它只是将它从字体中拉出来.至于纹理本身,你得到freetype来渲染每个字形,然后管理它来构建纹理.这个我做的预处理完全独立于我的主应用程序.
以下是我的工具代码的摘录:http://pastebin.com/md1c6354
请注意,这只是为了我的眼睛,而不是为了公众消费,所以原谅它是凌乱的地狱:)
我找到了一个简单的解决方案.这是我为它写的一个快速功能.(您将需要Texture2D类.)
- (void) drawText:(NSString*)theString AtX:(float)X Y:(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); }
我相信输入坐标需要在你的世界坐标中,但我不确定这一般是否正确,或者它是否对我有效.您可能需要使用偏移才能使其正确.