OPengl实现小球围绕大球旋转的效果
2016-03-27 00:58
387 查看
一些特殊函数的介绍
glutWireSphere(r,s1,s2)该函数用于渲染一个球体(由线条构成球体)。球体球心位于原点。在OpenGL中默认的原点就是窗口客户区的中心;
r 是球的半径,s1是以Z轴上线段为直径分布的圆周线的条数,s2是围绕在Z轴周围的线的条数
glRotatef(-80.0f,10.0f,1.0f,0.0f)表示将当前图形沿方向向量(-10,1,0)顺时针旋转80度
glTranslatef(0.0f,-20.0f,-40.0f)表示将当前图形向x轴平移0,向y轴平移-20,向z轴平移-40
注意如果先旋转在绘制,则是表现为自转;而先绘制在旋转,再移动一定距离,是为了到达绘公转的地方
我们在变换坐标的时候,使用的是glTranslatef(),glRotaef()等函数来操作,操作的是什么呢?操作的是当前矩阵,我们也知道,这些坐标变换(翻转,旋转也好)都是通过操作矩阵来实现的,而矩阵相乘是会叠加的,当你用完一个变换函数后,当前操作的矩阵就被改变了,当你还停留在变换以前的思维,我在这个地方绘制恰好是我想要的时候,你会发现再绘制出来的不是在你想要的位置,因为你在操作变换的时候,当前矩阵被改变了。
当你做了一些移动或旋转等变换后,使用
glPushMatrix();OpenGL 会把这个变换后的位置和角度保存起来。然后你再随便做第二次移动或旋转变换,再用
glPopMatrix();OpenGL 就把刚刚保存的那个位置和角度恢复。
实验截图
代码如下
#include "GL\glut.h" static int year = 0, day = 0; void display(void) { glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲区 glColor3f(1, 1, 1); //重置颜色,白色 glPushMatrix(); //压栈 glutWireSphere(1, 20, 16); //绘制太阳 glRotatef((GLfloat)year, 0, 1, 0); //沿y轴旋转 glTranslatef(3, 0, 0); //将场景中的物体沿x轴正方向移动2个单位长 glRotatef((GLfloat)day, 0, 1, 0); //沿y轴旋转 glutWireSphere(0.2, 10, 8); //绘制行星 glPopMatrix(); //出栈 glutSwapBuffers(); glFlush(); //刷新窗口以显示当前绘制图形 } void init(void) { glClearColor(0, 0, 0, 0); glShadeModel(GL_FLAT); //选择平面明暗模式或光滑明暗模式 } void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); //设置机口 glMatrixMode(GL_PROJECTION); //指定哪一个矩阵是当前矩阵 glLoadIdentity(); gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 20); //创建透视投影矩阵(fovy,aspect,zNear,zFar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 5, 5, 0, 0, 0, 0, 1, 0); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 'd': day = (day + 10) % 360; glutPostRedisplay(); break; case 'D': day = (day - 10) % 360; // 大写情况下是逆向的 glutPostRedisplay(); break; case 'y': year = (year + 5) % 360; glutPostRedisplay(); break; case 'Y': year = (year - 5) % 360; // 大写情况下是逆向的 glutPostRedisplay(); break; default: break; } } int main(int argc, char *argv[]) { glutInit(&argc, argv); //固定格式 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //缓存模式 glutInitWindowSize(600, 600); //显示框的大小 glutInitWindowPosition(100, 100); //确定显示框左上角的位置 glutCreateWindow("第三次作业"); init(); // 初始化 glutDisplayFunc(display); // 执行显示 glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); //进人GLUT事件处理循环 return 0; }
总结
本次任务是对opengl中绘制的顺序和逻辑考察,参考了网上的一些好的代码,感觉学到了好多东西相关文章推荐
- [提权禁区] SQL语句利用xp_cmdshell获取权限
- 分析system_call中断处理过程(Linux)
- LINUX的SOCKET 编程详解
- Mac搭建web后端开发环境:jdk +Eclipse EE + SVN + Tomcat + MySql + mysqlWorkbench
- Linux配置lampp重定向
- nginx日志切割
- Linux下创建并执行python脚本
- Hadoop如何计算map数和reduce数
- ubuntu为程序创建启动器(如程序快捷方式)
- Linux学习笔记:Linux软件安装管理【图】
- Linux搭建Java开发环境
- Apache Hadoop 2.7.1 文档翻译(1)独立模式、伪分布式建立
- Apache Hadoop 2.7.1文档翻译(2)集群安装
- 用shell脚本写ftp服务器
- 反射
- 分布式架构浅谈
- vim编辑器命令小记(一)
- 二代旅游网站管理程序V1使用手册(四):旅游出发地的管理
- linux内核分析 第五周
- 网站被黑检测-网页挂马及暗链检测