OpenGL编程(三)让矩形动起来
来源:互联网 发布:销售团队励志视频知乎 编辑:程序博客网 时间:2024/05/01 01:29
上次实现了在窗口中添加一个了一个矩形。这次的任务是在上次代码的基础上,让那个矩形动起来。
1、思路
要看到动态的效果,首先添加一个定时器,规定的时间刷新一次窗口;不断修改矩形的位置,使其在时间轴上达到动态的效果。
2、注册定时器
glutTimerFunc(33, timerFunction, 1); 33表示33毫秒后调用,timerFunction为回调函数,1为区别值(用以区分不同的定时器)。然后我们在timerFunction函数里修改矩形的坐标。因为注册一次定时器(glutTimerFunc)才会回调一次,所以要达到持续的效果,在timerFunction函数体内的末尾再是注册定时器回调自己glutTimerFunc(33, timerFunction, 1);
3、在定时器回调函数体内修改矩形的位置
假设矩形的左下角的位置为(x1, y1),每次回调我们修改x1,y1的值,让x1,y1加上或减去一个步长(向左运动是加,向右运动是减;向上运动是加,向下运动是减)。当x1的值大于等于窗口的宽度减去矩形的长(x1 > windowWidth - size)时x1开始改方向为减去步长x1 -= xstep;;当x1的值小于0时x1再次改为反方向为加步长(x1 += xstep;);同理y1也使用同样的方法处理。
4、重绘窗口
glutPostRedisplay();每次修改矩形的位置时要调用该函数重绘窗口。该函数的调用不是马上让GULT马上重绘窗口,而是先告诉GULT窗口已经改变,需要重新绘画,等GULT再次调用glutMainLoop()函数时会重回窗口,以达到窗口改变的效果。
完整代码如下:
#include <windows.h>#include <gl/glut.h>//animation.cppGLfloat x1 = 100.0f;GLfloat y1 = 150.0f;GLsizei size = 50;GLfloat xstep = 5.0f;GLfloat ystep = 5.0f;GLfloat windowWidth = 300.0f;GLfloat windowHeight = 300.0f;void renderScene(void){ glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池 glColor3f(1.0f, 0.0f, 0.0f); //设置绘图颜色 glRectf(x1, y1, x1 + size, y1 + size); //绘制矩形 glFlush(); //执行OpenGL指令列表中的指令}void timerFunction(int value){ if(x1 > windowWidth - size || x1 < 0) xstep = -xstep; if(y1 > windowWidth - size || y1 < 0) ystep = -ystep; if(x1 > windowWidth - size) x1 = windowWidth - size - 1; if(y1 > windowHeight - size) y1 = windowHeight - size - 1; x1 += xstep; y1 += ystep; glutPostRedisplay(); glutTimerFunc(33, timerFunction, 1);}void main(void){ glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //设置显示模式 glutInitWindowSize(windowWidth, windowHeight); //设置窗口大小 glutInitWindowPosition(200, 200); //设置窗口在屏幕上的位置 glutCreateWindow("动画"); //创建窗口并给出标题 glutDisplayFunc(renderScene); //注册显示窗口时回调函数renderScene glOrtho(0.0f, windowWidth, 0.0f, windowHeight, 1.0, -1.0); //修改修剪空间的范围 glutTimerFunc(33, timerFunction, 1); //注册定时器 glClearColor(0.0f, 0.0f, 1.0f, 1.0f); //使用蓝色清空背景底 glutMainLoop(); //消息循环(处理操作系统等的消息,例如键盘、鼠标事件等)}
5、让动画看起来更顺畅
上面能看到了动画的效果,但是有时候看起来不是很顺畅,主要原因是上面使用的是单缓冲的技术(前面文章提到过),即在显示窗口执行绘图过程。应该把单缓冲改为双缓冲,即现在显示窗口外完成了绘图,然后再把已经渲染完成的绘图切换到显示窗口。要修改的地方有:glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 把GLUT_SINGLE改成GLUT_DOUBLE。同时把glFlush();改成glutSwapBuffers();
完整代码如下:
#include <windows.h>#include <gl/glut.h>//animation.cppGLfloat x1 = 100.0f;GLfloat y1 = 150.0f;GLsizei size = 50;GLfloat xstep = 5.0f;GLfloat ystep = 5.0f;GLfloat windowWidth = 300.0f;GLfloat windowHeight = 300.0f;void renderScene(void){ glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池 glColor3f(1.0f, 0.0f, 0.0f); //设置绘图颜色 glRectf(x1, y1, x1 + size, y1 + size); //绘制矩形 glutSwapBuffers();}void timerFunction(int value){ if(x1 > windowWidth - size || x1 < 0) xstep = -xstep; if(y1 > windowWidth - size || y1 < 0) ystep = -ystep; if(x1 > windowWidth - size) x1 = windowWidth - size - 1; if(y1 > windowHeight - size) y1 = windowHeight - size - 1; x1 += xstep; y1 += ystep; glutPostRedisplay(); glutTimerFunc(33, timerFunction, 1);}void main(void){ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //设置显示模式 glutInitWindowSize(windowWidth, windowHeight); //设置窗口大小 glutInitWindowPosition(200, 200); //设置窗口在屏幕上的位置 glutCreateWindow("动画"); //创建窗口并给出标题 glutDisplayFunc(renderScene); //注册显示窗口时回调函数renderScene glOrtho(0.0f, windowWidth, 0.0f, windowHeight, 1.0, -1.0); //修改修剪空间的范围 glutTimerFunc(33, timerFunction, 1); //注册定时器 glClearColor(0.0f, 0.0f, 1.0f, 1.0f); //使用蓝色清空背景底 glutMainLoop(); //消息循环(处理操作系统等的消息,例如键盘、鼠标事件等)}
6、效果
- OpenGL编程(三)让矩形动起来
- 计算机图形学OpenGL(2)——让图形动起来,跳动的喜悦
- 4 让战机动起来(一)
- 初学unity(让场景动起来)
- opengles(四)让图像动起来
- 让下划线动起来
- 让位图动起来!
- 让精灵动起来
- 让大脑动起来
- 让动画动起来
- 让cube动起来
- 让图片动起来
- DEM:让ERP动起来
- 让照片真正动起来
- 让google map 动起来
- 线程------让画面动起来
- Flex 让组件动起来
- 让 Angular 应用动起来!
- 表单美化css
- ExpandableListView的首次加载全部展开,并且点击Group不收缩
- 将android的adb命令工具作用于mac全局
- [leetcode 255] Verify Preorder Sequence in Binary Search Tree ---先序遍历验证二叉搜索树
- Fragment之底层关键操作函数moveToState
- OpenGL编程(三)让矩形动起来
- 最大子数组
- 开博小记
- 多如牛毛,乱迷人眼
- 研究推荐系统心得
- 高斯日记
- IOS-UITableViewStyle设置Group、Plain问题
- ***LeetCode 95. Unique Binary Search Trees II
- 排它平方数