一、提要
今天的学习内容是在OpenGL的窗口中显示文字,实现FPS的显示,还有
OpenGL中动画的实现。
 
 
二、HelloWorld
关于位图文字的显示,nehe的教程只在windows下实现了,而相关了Linux下的实现
也需要借用其他的库,编程指南看了之后头更加大,于是我翻开了Qt帮助......
在QGLWidget的说明文档里,很幸运地找到了这个函数:
void QGLWidget::renderText ( int x, int y, const QString & str, const QFont & font = QFont(), int listBase = 2000 );
它的作用就是在渲染窗口显示文字了,前两个参数是位置坐标str是想要显示的字符串,font是希望使用的字体,最后
一个不用管.
最后一个不用管,后面版本的Qt会把它删掉。
还有比这更简单的方法吗!?
赶快来实践一下。
 
还是原来的框架,修改pantGL():
void NeHeWidget::paintGL()
{
 
// 清除屏幕和深度缓存
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
//移到屏幕的左半部分,并且将视图推入屏幕背后足够的距离以便我们可以看见全部的场景
glTranslatef(0.0f,0.0f,zoom);
glBegin(GL_TRIANGLES);							// 绘制三角形
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);					// 上顶点
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);					// 左下
glColor3f(0.0f,0.0f,1.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);					// 右下
glEnd();
renderText(100,100,"HelloWorld!  ",fpsFont);
}
 
 
 
 
 
三、Fps
frames per second(FPS, 帧率),作为渲染效率的一种衡量,反映的是整个程序在当前的一个渲染状态下平均每秒所能容纳的“渲染循环”执行次数,也表征了平均每个“渲染循环”(帧)所用的时间。就表面来看,很多人觉得只要在一个每帧运行一次的函数内设置一个计数器,这样计算出一秒内的记数,便可作为该1s瞬间的FPS了;同样也很容易能求出平均FPS。
为实现FPS的计算,我们在nehewidget类中添加 void calFrequency(),实现如下:
void NeHeWidget::calFrequency()
{
static  QString tmp="";
static float framesPerSecond=0.0f;//fps的数值
static float frames    = 0.0f;       // 用于存储渲染的帧数
static float lastTime   = 0.0f;       // 前一秒的时刻
float currentTime =  glutGet(GLUT_ELAPSED_TIME)* 0.001f;//程序运行的时间
++frames;
if( currentTime - lastTime > 1.0f )//,每秒刷新一次
{
framesPerSecond=frames;
tmp.setNum(framesPerSecond);
lastTime = currentTime;
frames= 0;
}
renderText(100,100,"FPS: "+tmp,fpsFont);//最终结果在窗口中渲染
}
 
将这个函数加载paintGL()里,那么每次渲染的时候,这个函数都会被调用一次,FPS的值会在窗口的左上角显示。
 
 
四、动画
为了实现动画,我们需要在添加一个计时器。
//计时器,实现动画
 
QTimer *timer;
 
 
然后在构造函数中将它初始化
 
timer = new QTimer(this);
timer->start(30);
connect(timer,SIGNAL(timeout()),this,SLOT(updateGL()));
 
 
这样,计时器每30毫秒就会发出一个信号,updateGL()会被触发。
 
下面的例子是一个不断变色的三角形,主要代码如下:
 
void NeHeWidget::paintGL()
{
 
// 清除屏幕和深度缓存
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
//移到屏幕的左半部分,并且将视图推入屏幕背后足够的距离以便我们可以看见全部的场景
glTranslatef(0.0f,0.0f,zoom);
 
glBegin(GL_TRIANGLES);							// 绘制三角形
glColor3f(1.0f,0.0f+colorSpan,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);					// 上顶点
glColor3f(0.0f,1.0f-colorSpan,0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);					// 左下
glColor3f(0.0f+colorSpan,0.0f,1.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);					// 右下
glEnd();
if(colorSpan<1&&colorSpan>=0) colorSpan+=0.01;
else colorSpan=0;
 
//fps的字体颜色
glColor3f(0.0f,0.0f,1.0f);
glFinish();
//计算FPS
calFrequency();
}
 
最终效果如下:
 
 
 
 
 
 

四.参考资料

1.      《 》, OpenGL 参考手册

2.      《 OpenGL 编程指南》(《 OpenGL Programming Guide 》), Dave Shreiner , Mason Woo , Jackie Neider , Tom Davis 著,徐波译,机械工业出版社

3.         《win32 OpenGL编程 》   一个大牛的博客     
4.             《OpenGL函数思考 》   里面有很多OpenGL函数的通俗解释