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

OpenGL(三)图形变换之矩阵堆栈

2016-07-08 11:53 127 查看
通过原子核动画 示例学习知识点:

<span style="font-size:18px;">#include<windows.h>
#include<gl/gl.h>
#include<gl/glut.h>

//还是以俯视理解

void SetupRC(void)
{

glEnable(GL_DEPTH_TEST);//启动深度测试
glFrontFace(GL_CCW); //指定逆时针绕法表示多边形正面
//设置窗口背景颜色为白色
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

void ChangeSize(int w, int h)
{
if (h == 0)
h = 1;
//设置视区尺寸
glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

//设置修剪空间
GLfloat fAspect = (float)w / (float)h;

gluPerspective(45.0,fAspect,1.0,500.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void RenderScene(void)
{

//绕原子核旋转的角度
static float fElect1 = 0.0f;

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

//设置当前操作矩阵为模型视图矩阵,并复位为单位矩阵

//重置模型视图矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//将图形沿z轴负方向移动
//越往z轴负方向,视图越小
glTranslatef(0.0f, 0.0f, -250.0f);

//绘制红色的原子核
glColor3f(1.0f,0.0f,0.0f);
//该函数用于渲染一个球体。球体球心位于原点。
//在OpenGL中默认的原点就是窗口客户区的中心
glutSolidSphere(10.0f,15,15);

//当前绘制颜色为黑色
glColor3f(0.0f,0.0f,0.0f);

//保存当前的模型
glPushMatrix();
//绘制第一个电子
//绕y轴旋转一定的角度
glRotatef(fElect1,0.0f,1.0f,0.0f);
//平移一段距离
glTranslated(90.0f,0.0,0.0f);//向x轴正方向平移
glColor3f(1.0f, 1.0f, 0.0f);//黄
glutSolidSphere(6.0f,15,15);//画出电子
//恢复矩阵
glPopMatrix();

//绘制第二个电子
glPushMatrix();
glRotatef(45.0f,0.0f,0.0f,1.0);
glRotatef(fElect1, 0.0f, 1.0f, 0.0);
glTranslatef(-70.0f,0.0f,0.0f);//向y轴负方向平移
glColor3f(0.0f, 1.0f, 0.0f); //绿
glutSolidSphere(6.0f,15,15);
glPopMatrix();

//绘制第三个电子
glPushMatrix();
glRotatef(-45.0f,0.0f,0.0f,1.0f);
glRotatef(fElect1,0.0f,1.0f,0.0f);
glTranslatef(0.0f,0.0f,60.0f); //向z轴正方向平移
glColor3f(0.0f, 0.0f, 1.0f);//蓝色
glutSolidSphere(6.0f,15,15);
glPopMatrix();

//增加旋转步长
fElect1 += 10.0f;

if (fElect1 > 360.0f)
fElect1 = 10.0f;
//交换两个缓冲区的指针
//功能:防止复杂绘制时屏幕闪烁
glutSwapBuffers();

}

void TimerFunc(int value)
{
glutPostRedisplay();
glutTimerFunc(100,TimerFunc,1);
}
int main(int argc, char *argv[])
{
//glutInit is used to initialize the GLUT library
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH);
glutCreateWindow("原子示例");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);

glutTimerFunc(500,TimerFunc,1);

SetupRC();
glutMainLoop();
return 0;
}
</span>

本程序使用了透视投影,可以清楚地看到电子在旋转到远处时,体积逐渐变小,而旋转到近处时,体积有渐渐变大。

运行结果:



学习知识点:

1.矩阵堆栈(其实前面已经接触过了)

OpenGL 为模型视图矩阵和投影矩阵各维护这一个“”矩阵堆栈“”,工作方式跟我们普通堆栈一样。

我们可以吧当前矩阵压到堆栈中保存它,然后对当前矩阵进行修改,把矩阵弹出堆栈即可恢复。

使用函数如下:

void glPushMatrix(void );

void glPopMatrix(void );

函数glPushMatrix(void )用户将当前矩阵压人矩阵堆栈,常用于保存当前矩阵。

glPopMatrix常用于将最后一个矩阵弹出当前矩阵堆栈,常用于恢复当前变换矩阵原先的状态。

2:、OpenGL 维护两个栈:投影变换栈,几何变换栈。

投影: glOrtho,gluPerspective--------------------glMatrixMode(GL_PROJECTION); 
几何变 换:glTranslatef,glRotatef,glScalef--------glMatrixMode(GL_MODELVIEW); 
在调用glMatrixMode(GL_MODELVIEW)时,系统会自动将几何变换桟清空并压入单位矩阵,因此不必再调用glLoadIdentity()函数。
glMatrixMode(GL_MODELVIEWING或GL_PROJECTION);本命令执行后参数所指矩阵栈就成为当前矩阵栈,以后的矩阵栈操纵命令将作用于它。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: