OpenGL学习——glut/ glMatrixMode()、旋转、平移

因为可能要做太阳系,所以通过此程序先了解一下,顺便学习以下知识。没有列出来的,代码里如果有注释的话,也要看一下。

学习要点

理解glMatrixMode()设置的几种变换。

了解gluPerspective()和gluLookAt()的参数,清楚他们该如何使用的。理解OpenGL下的三维座标的展示,观察一个物体的角度。

理解深度缓冲区。

了解怎么用glutSolidSphere()画一个圆。

关于旋转和平移的用法,glRotatef(),glTranslatef()。

相关学习资料

glMatrixMode()

gluPerspective()和gluLookAt()

要点简单解析

其实就是注释里写的,解释的比较简单,主要是函数参数解释,详细解释和深入理解还得看其他的文章。

投影变换

glMatrixMode(GL_PROJECTION);

gluPerspective(75, 1, 1, 2000);

在投影变换下才能设置。透视投影空间, 近大远小的那种感觉。

参数:
眼睛睁开的角度,实际窗口的纵横比,眼睛距离近处的距离,远处的裁面(即后面两个参数表示眼睛能看的多远)。

函数设置投视角设为75度, 在y轴方向上以角度为单位的视野, 度数越大离的越远看的越小。

模型变换

在模型变换下可以对矩阵进行变换,移动旋转缩放等。

glMatrixMode(GL_MODELVIEW);

gluLookAt(0, -200, 200, 0, 0, 0, 0, 0, 1)

参数:每三个参数表示一个座标
eye眼睛在世界座标系的位置,center眼睛看的那个点的座标,up观察者本身的方向,比如正立还是倒立异或某一个角度在看。

函数表示在(0, -200, -200)的位置正着向(0, 0, 0)点看去。

深度缓冲区

opengl默认是没有开启深度检测的,也就是说, 后绘制的物体覆盖先绘制的物体。

当开启更新深度缓冲区的功能,也就是,如果通过比较后,深度值发生变化了,会进行更新深度缓冲区的操作。启动后,OpenGL就可以跟踪在Z轴上的像素,这样,它只会再那个像素前方没有东西时,才会绘制这个像素。

#include<Windows.h>
#include<GL\glut.h>
//太阳、地球和月亮
//假设每个月都是30天
//一年12个月,共是360天
static int day = 200; // day的变化:从0到359
void myDisplay(void)
{
    /*用来开启更新深度缓冲区的功能,也就是,如果通过比较后深度值发生变化了,
    会进行更新深度缓冲区的操作。启动它,OpenGL就可以跟踪再Z轴上的像素,
    这样,它只会再那个像素前方没有东西时,才会绘画这个像素。*/
    glEnable(GL_DEPTH_TEST);

    /*opengl默认是没有开启深度检测的,也就是说,
    后绘制的物体覆盖先绘制的物体(颜色缓冲区中,先绘制的物体 被 后绘制的物体 覆盖)。*/
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);    //投影变换
    glLoadIdentity();   //调用单位矩阵
    //投视角设为75度, 在y轴方向上以角度为单位的视野, 度数越大离的越远看的越小
    //参数 眼睛睁开的角度  实际窗口的纵横比  眼睛距离近处的距离  远处的裁面(即眼睛能看的多远)
    gluPerspective(75, 1, 1, 2000); //透视投影空间, 近大远小

    glMatrixMode(GL_MODELVIEW); //模型变换
    glLoadIdentity();
    //eye眼睛在世界座标系的位置,
    //center眼睛看的那个点的座标,
    //up观察者本身的方向,比如正立还是倒立异或某一个角度在看
    gluLookAt(0, -200, 200, 0, 0, 0, 0, 0, 1);

//绘制红色的“太阳”
    glColor3f(1.0f, 0.0f, 0.0f);
    glutSolidSphere(69.6, 100, 100);

//绘制蓝色的“地球”
    glColor3f(0.0f, 0.0f, 1.0f);
    glRotatef(day / 360.0*360.0, 0.0f, 0.0f, -1.0f);
    //相对当前所在屏幕位置移动
    glTranslatef(150, 0.0f, 0.0f);
    glutSolidSphere(15.945, 100, 100);

//绘制黄色的“月亮”
    glColor3f(1.0f, 1.0f, 0.0f);
    glRotatef(day / 30.0*360.0 - day / 360.0*360.0, 0.0f, 0.0f, -1.0f);
    glRotatef(day / 30.0*360.0, 0.0f, 0.0f, -1.0f);
    glTranslatef(38, 0.0f, 0.0f);
    glutSolidSphere(4.345, 100, 100);

    //glFlush();  //这句加不加好像都行,因为用的是双缓冲区
    glutSwapBuffers();
}
void myIdle(void)
{
    Sleep(50);
    ++day;
    if (day >= 360)
        day = 0;
    myDisplay();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutInitWindowPosition(200, 100);
    glutInitWindowSize(600, 600);
    glutCreateWindow("平移旋转");
    glutDisplayFunc(&myDisplay);
    //如果不存在其他尚未完成的,就执行这个函数(当没有窗口事件到达时,就执行这个回调函数
    glutIdleFunc(&myIdle);
    glutMainLoop();
    return 0;
}

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章