您的位置:首页 > 运维架构

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中绘制的顺序和逻辑考察,参考了网上的一些好的代码,感觉学到了好多东西
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: