在计算机图形学中生成计算机动画的技术有很多,我们现在不想过多地涉猎其中,只简单使用双缓存技术来实现动画效果。
在光栅系统中使用两个刷新缓存生成实时动画的技术称为双缓存。初始状态时,在第一个缓存中创建动画的一帧;然后,当用该缓存中的帧刷新屏幕时,在第二个缓存中创建下一帧;下一帧创建完成后,互换两个缓存的角色;因而刷新进程开始用第二个缓存中的帧来刷新屏幕,同时在第一个缓存创建下一帧。
下列代码给出一个动画程序的例子,该例子在xy平面绕z轴连续旋转一个正六边形。
#include <gl/glut.h>
#include <math.h>
#include <stdlib.h>
const double TWO_PI = 6.2831853;
GLsizei winWidth = 500, winHeight = 500;
GLuint regHex;
static GLfloat rotTheta = 0.0;
class scrPt{
public:
GLint x, y;
};
static void init(void)
{
scrPt hexVertex;
GLdouble hexTheta;
GLint k;
glClearColor(1.0, 1.0, 1.0, 0.0);
regHex = glGenLists(1);
glNewList(regHex, GL_COMPILE);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
for (k = 0; k < 6;k++)
{
hexTheta = TWO_PI*k / 6;
hexVertex.x = 150 + 100 * cos(hexTheta);
hexVertex.y = 150 + 100 * sin(hexTheta);
glVertex2i(hexVertex.x, hexVertex.y);
}
glEnd();
glEndList();
}
void displayHex(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(rotTheta, 0.0, 0.0, 1.0);
glCallList(regHex);
glPopMatrix();
glutSwapBuffers();//互换两个帧缓存
glFlush();
}
void rotateHex(void)//随时间旋转
{
rotTheta += 3.0;
if (rotTheta>360.0)
{
rotTheta -= 360.0;
}
glutPostRedisplay();//显示窗口重新绘制
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glViewport(0, 0, (GLsizei)newWidth, (GLsizei)newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-320.0, 320.0, -320.0, 320.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
}
void mouseFcn(GLint button, GLint action, GLint x, GLint y)
{
switch (button)
{
case GLUT_MIDDLE_BUTTON://如果中键响应
if (action == GLUT_DOWN)//按下动作
glutIdleFunc(rotateHex);//开始旋转
break;
case GLUT_RIGHT_BUTTON://如果右键响应
if (action == GLUT_DOWN)//按下动作
glutIdleFunc(NULL);//停止旋转
break;
default:
break;
}
}
void main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);//使用双缓存模式
glutInitWindowPosition(150, 150);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("Animation Example");
init();
glutDisplayFunc(displayHex);
glutReshapeFunc(winReshapeFcn);
glutMouseFunc(mouseFcn);//鼠标响应函数
glutMainLoop();
}
相信以大家现在的知识,在有注释的情况下很容易就能看懂这段代码,我们重点来看下几个函数。
启用双缓存模式:
glutInitDisplayMode(GLUT_DOUBLE);
双缓存激活后产生两个交替刷新屏幕的缓存,分别称为前缓存和后缓存。
互换两个缓存的角色:
glutSwapBuffers();
激活动画:
glutIdleFunc(rotateHex);
只要没有窗口处理时间就会一直调用回调函数rotateHex,从而真正实现动画效果。