Linux下Modern OpenGL显示汉字
2017-08-24 14:48
671 查看
Linux下Modern OpenGL显示汉字
前一篇中解码出来的图像已经能够正常颜色格式转换和显示了,现在遇到了新的问题:显示文字本以为这是一个很简单的东西,因为之前使用SDL时直接应用sdl_ttf库很简单的就实现了文字渲染工作,结果万万没想到OpenGL中实现这个小功能竟然没有现成API,这对于CV码农来说简直是灾难。没办法,看了这么久的GL硬着头皮也要走下去,经过两天不断的查资料和编码调试终于大功告成!老版本的OpenGL直接使用glut加载字符就能完成显示,modern OpenGL则需要使用shader结合vaovbo完成渲染,下面介绍如何实现
FreeType2
freetype2是一个字体库,能够完成加载字体文件,提取字符,生成bitmap等工作FreeType is a software development library that is able to load fonts, render them to bitmaps and provide support for several font-related operations. It is a popular library used by Mac OS X, Java, PlayStation Consoles, Linux and Android to name a few. What makes FreeType particularly attractive is that it is able to load TrueType fonts.
关键代码
FT_Library ft; if (FT_Init_FreeType(&ft)) std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl; FT_Face face; if (FT_New_Face(ft, "fonts/arial.ttf", 0, &face)) std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;
这部分代码完成初始化工作
if (FT_Load_Char(face, 'X', FT_LOAD_RENDER)) std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
完成加载字符工作
glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width, face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer );
完成字符到GL纹理的存储
struct Character { GLuint TextureID; // ID handle of the glyph texture glm::ivec2 Size; // Size of glyph glm::ivec2 Bearing; // Offset from baseline to left/top of glyph GLuint Advance; // Horizontal offset to advance to next glyph };
这是存储字符纹理和大小、偏移等参数的结构体
要显示中文的话需要加载中文字体,可以去网上下载自己喜欢的或者去win里面拷
我使用的是谷歌出品的思源宋体,挺好看的
String转WString
英文字符占一字节,中文字符占两个,所以需要把String转成Wstring这里我使用C++11的codecvt类完成,话说C++做文字处理真是蛋疼,这活在Python里根本不算事
include <locale> include <codecvt> using convert_typeX = std::codecvt_utf8<wchar_t>; std::wstring_convert<convert_typeX, wchar_t> converterX; std::wstring wide = converterX.from_bytes(text);
还算简单,五行代码完活
纹理存储
每一个字符都是一张纹理,如果需要显示很多文字的话,那么每次刷新都为文字创建纹理会很耗费资源,所以使用map存储显示过的文字,就第一次使用这个字符时需要创建纹理分配存储,后面可以直接去map中找,节省计算资源。std::map<wchar_t, Character> Characters; if(Characters.find(c)==Characters.end()) { //生成纹理,绑定,存储等等 Characters.insert(std::pair<wchar_t, Character>(c, character)); } else {}
效果
代码
将文字显示功能整合了一下,实际使用只需要两步textRender tr(800,600,"/home/wnl/workspace/textRender/SourceHanSerifCN-Bold.otf");
参数是窗口大小和字体路径
渲染循环中
std::string s("WuNL的OpenGL文字显示测试"); tr.RenderText(s,(GLfloat)35.0f,(GLfloat)35.0f,1.0f, glm::vec3(0.5, 0.8f, 0.2f));
rendertext参数为需要渲染的文字,显示位置,大小比例,颜色
实现代码在我的github上,网址为https://github.com/WuNL/textRender
觉得我的代码有些帮助请打颗星,谢谢
相关文章推荐
- linux生成文字变成小框框,无法正常显示汉字
- OpenGL显示文字--显示汉字
- linux 下使用opengl的glut库显示和旋转BMP图片
- linux生成文字变成小框框,无法正常显示汉字
- 一个极好的OpenGL汉字显示类(转,作者Y_Y)
- 在VTK下/OpenGL环境下显示汉字
- OpenGL显示三维汉字
- 移植算法编译环境到linux【redhat9.0如何显示汉字】
- 在VTK下/OpenGL环境下显示汉字
- 基于Linux系统核心的汉字显示的尝试--zt
- 附录4 一个OpenGL下的汉字显示类
- OpenGL 显示汉字,别的地方摘录
- OpenGL显示文字--显示汉字
- 一个极好的OpenGL汉字显示类
- openGL学习笔记5 显示汉字
- activiti部署到linux后流程图不显示汉字的问题
- linux平台上通过jfreechart生成的PNG图像中显示的汉字为方框的问题的解决
- linux终端显示汉字问题
- OpenGL中的汉字显示
- 用PuTTY登录Linux后,汉字显示为乱码的两种解决办法