绘制第一个三角形

初始化

初始化glut

当我们要新建一个窗口并开始绘制时,首先要使用glutInit函数对glut库进行初始化。glutInit原型:

1
void glutInitint * argcpchar ** argv;

接受两个参数,第一个是ragc的地址,注意这里是指针,所以要传地址进去。 第二个则是argv。(如果你不清楚命令行参数是什么,那你可能要再学习一下C)

glutInit函数会读取命令行参数,并进行解析与更改。 所以它必须被放在第一行,接受没有被修改过的参数。 因此我们只需要像这样

1
2
3
4
5
int main(int argc, char** argv){
    glutInit(&argc, argv);
    // Your code ......
    return 0;
}

使用glutInitDisplayMode来设置初始显示模式(initial display mode)。它的参数是一个枚举类型,可以在这里查看,一般来说使用GLUT_RGBA即可。

初始化窗口

使用glutInitWindowSize设置窗口大小,参数分别是宽度(width)和高度(height),单位是像素。

使用glutInitWindowPosition可以设置窗口的位置。屏幕坐标轴的原点在左上角,x轴方向从左向右,y轴方向从上到下。

我的屏幕分辨率是2560*1440,简单的计算一下可以计算出讲512*512的窗口放在中间所对应的参数。

1
2
    glutInitWindowSize(512, 512);
    glutInitWindowPosition(1024,464);

设置上下文

何为上下文(context)?
可以参考知乎上这个问题的回答。

设定版本,一般配置为3.3。

设定配置文件(Profile),分为以下两种:

1
2
GLUT_CORE_PROFILE: 核心配置文件,包括了当前OpenGL版本所有的API,可能会包含已经弃用的函数。
GLUT_COMPATIBILITY_PROFILE: 兼容配置文件,包括了核心配置文件,在此基础上还包含OpenGL规范或早期版本OpenGL规范中删除的大多数API,由GPU供应商提供哪些已删除的API包含在兼容配置文件内

用核心配置文件即可。

更多关于OpenGL上下文的解释:参考链接

1
2
    glutInitContextVersion(3, 3);
    glutInitContextProfile(GLUT_CORE_PROFILE);

创建窗口

使用glutCreateWindow创建窗口,参数为窗口的标题。

1
    glutCreateWindow("Red Triangle");

初始化图形渲染管线

参考图形渲染管线

事件与消息循环

使用形如glutXXXFunc函数来注册各种回调函数以相应各种消息,参数是对应的函数指针,即函数名。最简单的,使用glutDisplayFunc来注册一个用于显示的回调函数。

OpenGL的消息循环全部集成在一个glutMainLoop()函数中了,它负责处理所有的接受的消息,并调用相应的回调函数。比如我们改变了窗口的位置与大小,他就会调用被glutDisplayFunc注册的回调函数。

可以写一个简单的demo测试一下这个过程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static int counter = 0;

void init(){
    //...
}

void display()
{
    // 清理窗口
    glClear(GL_COLOR_BUFFER_BIT);
    std::cout << counter << std::endl;
    counter++;
    // 绘制所有点
    glDrawArrays(GL_TRIANGLES, 0, NUM_POINTS);
    glFlush();
}

int main(int argc, char** argv){
    //......
    init();
    glutDisplayFunc(display);
    glutMainLoop();
    //...
}

直接运行还是正常的三角形窗口。当我们拖动窗口位置、改变窗口大小的时候,可以看到控制台有1 2 3的输出。
仔细观察输出的模式,当我们鼠标拖住窗口不动的时候,counter不会改变,当松开时才会加一。而改变窗口大小的时候,每变化一个像素它才会加一。这应该能帮助我们理解他的消息响应机制。

评论