前言简介
FTGL
在使用QopenGLWidget中,由于需要绘制三维空间中的文本标注。而由于Qt的新版本中并没有引入QGLWidget中的绘制函数:
void renderText(double x, double y, double z, const QString & str, const QFont & font = QFont())
所以在我找到了第三方字体引擎库FTGL,通过阅读简介明确了他对OpenGL有很好的支持。简单灵活、跨平台,基于FreeType库,采用标准的字体库格式,可以直接读取字体文件,支持位图、抗锯齿、贴图映射、轮廓线、多边形格网、突出(挤压)多边形格网。
运行环境
- OS:Windows 7 旗舰版 64位
- VS:Visual Studio 2013
出现问题
在下面的代码测试中出现如图所示的问题:
操作步骤
- 下载FreeType与FTGL:在FreeType官方网站的下载页面以及FTGL库下载需要的文件,这里我选用FreeType和FTGL分别是图中解压的两个文件。
编译FreeType: 在目录
.\freetype-2.3.4\builds\win32\visualc
下,双击打开freetype.sln。在配置管理器中我选择的是Debug Multithreaded,在项目属性页中选择配置管理器,并注意查看下输出文件目录在objs文件夹下。
点击菜单项中的“生成解决方案”,在目录\freetype-2.3.4\objs
下找到静态链接库freetype234_D.lib。
拷贝包含文件: 将生成的freetype234_D.lib拷贝到
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib
下,再将\freetype-2.3.4\include
下的freetype文件夹以及ft2build.h拷贝到VC目录C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include
下
编译FTGL: 在目录
\ftgl-2.1.3~rc5\msvc\vc8
中点击ftgl.sln,由于我是要生成lib文件,所以右键点击ftgl_static的属性,设置附加包含目录与附加库目录、依赖项。
设置好属性后生成解决方案。拷贝包含文件:将生成的ftgl_static_D.lib拷贝到
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib
下,再将\ftgl-2.1.3~rc5\src
下的FTGL文件夹拷贝到VC目录C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include
下
解决方案
在排查原因后,发现是由于在设置项目“属性”页的时候没有加入FreeType的lib库导致的。主要是由于自己的马虎大意,而且认为FTGL与FreeType之间有依赖关系。事实上,在运行程序时,需要同时引入FreeType与FTGL的lib库,同时还要注意不要忘了添加include目录下的文件。
测试代码
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <iostream>
#include <FTGL/FTGLPixmapFont.h>
using namespace std;
FTGLPixmapFont *freeTypeFont = NULL;
void init(void)
{
glShadeModel(GL_SMOOTH); // 启用阴影平滑
glClearDepth(1.0f); // 设置深度缓存
glEnable(GL_DEPTH_TEST); // 启用深度测试
glDepthFunc(GL_LEQUAL); // 所作深度测试的类型
//FTGL初始化
char filePath[256] = { 0 };
sprintf_s(filePath, "C:\\WINDOWS\\Fonts\\simhei.ttf");
freeTypeFont = new FTGLPixmapFont(filePath);
if (freeTypeFont == NULL)
{
char buf[] = "Font C:\\WINDOWS\\Fonts\\simhei.ttf can not be fond.\r\n";
printf("%s", buf);
exit(0);
}
else
{
freeTypeFont->FaceSize(24); // 必须
}
}
wchar_t str[128] = L"FTGL 中文输出测试";
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glMatrixMode(GL_PROJECTION); // 切换到投影矩阵
glLoadIdentity(); // 重置投影矩阵
glOrtho(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 10.0f);
glMatrixMode(GL_MODELVIEW); // 切换到模型视图矩阵
glLoadIdentity(); // 重置模型视图矩阵
//FTGL 输出测试,
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glRasterPos2f(0.2, 0.5);
freeTypeFont->Render(str);
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLdouble)w / (GLdouble)h, 1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("FTGL 中文输出测试");
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}