上次实现了在窗口中添加一个了一个矩形。这次的任务是在上次代码的基础上,让那个矩形动起来。

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()函数时会重回窗口,以达到窗口改变的效果。

完整代码如下:

  1. #include <windows.h>
  2. #include <gl/glut.h>
  3. //animation.cpp
  4. GLfloat x1 = 100.0f;
  5. GLfloat y1 = 150.0f;
  6. GLsizei size = 50;
  7. GLfloat xstep = 5.0f;
  8. GLfloat ystep = 5.0f;
  9. GLfloat windowWidth = 300.0f;
  10. GLfloat windowHeight = 300.0f;
  11. void renderScene(void)
  12. {
  13. glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池
  14. glColor3f(1.0f, 0.0f, 0.0f); //设置绘图颜色
  15. glRectf(x1, y1, x1 + size, y1 + size); //绘制矩形
  16. glFlush(); //执行OpenGL指令列表中的指令
  17. }
  18. void timerFunction(int value)
  19. {
  20. if(x1 > windowWidth - size || x1 < 0)
  21. xstep = -xstep;
  22. if(y1 > windowWidth - size || y1 < 0)
  23. ystep = -ystep;
  24. if(x1 > windowWidth - size)
  25. x1 = windowWidth - size - 1;
  26. if(y1 > windowHeight - size)
  27. y1 = windowHeight - size - 1;
  28. x1 += xstep;
  29. y1 += ystep;
  30. glutPostRedisplay();
  31. glutTimerFunc(33, timerFunction, 1);
  32. }
  33. void main(void)
  34. {
  35. glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //设置显示模式
  36. glutInitWindowSize(windowWidth, windowHeight); //设置窗口大小
  37. glutInitWindowPosition(200, 200); //设置窗口在屏幕上的位置
  38. glutCreateWindow("动画"); //创建窗口并给出标题
  39. glutDisplayFunc(renderScene); //注册显示窗口时回调函数renderScene
  40. glOrtho(0.0f, windowWidth, 0.0f, windowHeight, 1.0, -1.0); //修改修剪空间的范围
  41. glutTimerFunc(33, timerFunction, 1); //注册定时器
  42. glClearColor(0.0f, 0.0f, 1.0f, 1.0f); //使用蓝色清空背景底
  43. glutMainLoop(); //消息循环(处理操作系统等的消息,例如键盘、鼠标事件等)
  44. }

5、让动画看起来更顺畅

上面能看到了动画的效果,但是有时候看起来不是很顺畅,主要原因是上面使用的是单缓冲的技术(前面文章提到过),即在显示窗口执行绘图过程。应该把单缓冲改为双缓冲,即现在显示窗口外完成了绘图,然后再把已经渲染完成的绘图切换到显示窗口。要修改的地方有:glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 把GLUT_SINGLE改成GLUT_DOUBLE。同时把glFlush();改成glutSwapBuffers();

完整代码如下:

  1. #include <windows.h>
  2. #include <gl/glut.h>
  3. //animation.cpp
  4. GLfloat x1 = 100.0f;
  5. GLfloat y1 = 150.0f;
  6. GLsizei size = 50;
  7. GLfloat xstep = 5.0f;
  8. GLfloat ystep = 5.0f;
  9. GLfloat windowWidth = 300.0f;
  10. GLfloat windowHeight = 300.0f;
  11. void renderScene(void)
  12. {
  13. glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池
  14. glColor3f(1.0f, 0.0f, 0.0f); //设置绘图颜色
  15. glRectf(x1, y1, x1 + size, y1 + size); //绘制矩形
  16. glutSwapBuffers();
  17. }
  18. void timerFunction(int value)
  19. {
  20. if(x1 > windowWidth - size || x1 < 0)
  21. xstep = -xstep;
  22. if(y1 > windowWidth - size || y1 < 0)
  23. ystep = -ystep;
  24. if(x1 > windowWidth - size)
  25. x1 = windowWidth - size - 1;
  26. if(y1 > windowHeight - size)
  27. y1 = windowHeight - size - 1;
  28. x1 += xstep;
  29. y1 += ystep;
  30. glutPostRedisplay();
  31. glutTimerFunc(33, timerFunction, 1);
  32. }
  33. void main(void)
  34. {
  35. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //设置显示模式
  36. glutInitWindowSize(windowWidth, windowHeight); //设置窗口大小
  37. glutInitWindowPosition(200, 200); //设置窗口在屏幕上的位置
  38. glutCreateWindow("动画"); //创建窗口并给出标题
  39. glutDisplayFunc(renderScene); //注册显示窗口时回调函数renderScene
  40. glOrtho(0.0f, windowWidth, 0.0f, windowHeight, 1.0, -1.0); //修改修剪空间的范围
  41. glutTimerFunc(33, timerFunction, 1); //注册定时器
  42. glClearColor(0.0f, 0.0f, 1.0f, 1.0f); //使用蓝色清空背景底
  43. glutMainLoop(); //消息循环(处理操作系统等的消息,例如键盘、鼠标事件等)
  44. }

6、效果

OpenGL编程(三)让矩形动起来的更多相关文章

  1. 用MFC实现OpenGL编程

    一.OpenGL简介 众所周知,OpenGL原先是Silicon Graphics Incorporated(SGI公司)在他们的图形工作站上开发高质量图像的接口.但最近几年它成为一个非常优秀的开放式 ...

  2. Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤

    http://blog.csdn.net/vagrxie/article/details/4602961 Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤 wri ...

  3. OpenGL编程指南(第七版)

    OpenGL编程指南(第七版) 转自:http://blog.csdn.net/w540982016044/article/details/21287645 在接触OpenGL中,配置显得相当麻烦,特 ...

  4. OpenGL编程(一)渲染一个指定颜色的背景窗口

    上次已经搭好了OpenGL编程的环境.已经成功运行了第一个程序.可只是照搬书上的代码,并没弄懂其中的原理.这次通过一个小程序来解释使用GLUT库编写OpenGL程序的过程. 程序的入口 与其他程序一样 ...

  5. [转]OpenGL编程指南(第9版)环境搭建--使用VS2017

    1.使用CMake Configure中选择VS2017 Win64 , Finish: 点击Generate. 2.进入build目录 打开GLFW.sln , 生成解决方案. 打开vermilio ...

  6. 编译opengl编程指南第八版示例代码通过

    最近在编译opengl编程指南第八版的示例代码,如下 #include <iostream> #include "vgl.h" #include "LoadS ...

  7. 在 Mac OS X Yosemite 10.10.5 上配置 OpenGL 编程环境

    这个教程主要参考了youtube上的视频 Getting Started in OpenGL with GLFW/GLEW in Xcode 6 ,这个视频有点问题,不能照搬.本人通过自己摸(瞎)索( ...

  8. 用AE如何制作如下三个loading动效,

    在本期象牙绘UED团队分享当中,我们将详细演示用AE如何制作如下三个loading动效, 其中涉及到AE表达式的应用.值曲线调整.速度曲线编辑等知识. 对于初学者来说可能信息量略大,希望通过是视频教程 ...

  9. Linux网络编程(三)

    Linux网络编程(三) wait()还是waitpid() Linux网络编程(二)存在客户端断开连接后,服务器端存在大量僵尸进程.这是由于服务器子进程终止后,发送SIGCHLD信号给父进程,而父进 ...

随机推荐

  1. 基于One-Class的矩阵分解方法

    在矩阵分解中. 有类问题比較常见,即矩阵的元素仅仅有0和1. 相应实际应用中的场景是:用户对新闻的点击情况,对某些物品的购买情况等. 基于graphchi里面的矩阵分解结果不太理想.调研了下相关的文献 ...

  2. FireEye APT检测——APT业务占比过重,缺乏其他安全系统的查杀和修复功能

    摘自:https://zhidao.baidu.com/question/1694626564301467468.html火眼,APT威胁下快速成长 FireEye的兴起开始于2012年,这时段正好迎 ...

  3. hdoj--2180--时钟(数学)

    时钟 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  4. springMVC接受对象实体并且对象实体里面又有对象集合方式

    springMVC接受对象实体并且对象实体里面又有对象集合方式: Ajax: function add(){ var orders = [ { orderNo : "H222255" ...

  5. Swift学习笔记(7):函数

    目录: 函数参数与返回值 参数标签和参数名称 可变参数 传入传出参数 函数类型 嵌套函数 函数是一段完成特定任务的独立代码片段,使用func标示函数名,使用->标示返回类型. ・可以为函数参数设 ...

  6. Swift学习笔记(6):控制流

    目录: For-In While If-Else, Guard-Else Switch 控制转移 For-In 可以使用for-in语句循环遍历集合.区间.元组.字符串. // 遍历区间,返回元素值 ...

  7. Android官方培训课程中文版(v0.9.7)

    Android官方培训课程中文版(v0.9.7) Google Android团队在2012年的时候开设了Android Training板块 - http://developer.android.c ...

  8. 《剑指offer》二叉搜索树与双向链表

    一.题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向 二.输入描述 输入一棵二叉搜索树 三.输出描述 将该二叉搜索树转换成一个 ...

  9. Git常见问题 资料汇总

    来源https://blog.csdn.net/albb_/article/details/80420468

  10. java中的json使用

    import org.json.simple.JSONArray;import org.json.simple.JSONObject; /** * 使用的是json-lib-2.4.jar * @au ...