• 作者:老汪软件技巧
  • 发表时间:2024-09-07 00:05
  • 浏览量:

最新大型开源项目-云游戏,云桌面系统,欢迎关注

GammaRay源码地址

本项目代码仓库

点击这里

1.如何绘制一个矩形?

上一章我们成功绘制了一个三角形,很容易的想到,一个矩形就是两个三角形构成的。那么我们就定义它:

    float vertices[] = {
            0.5f, 0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
            -0.5f, 0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            -0.5f, 0.5f, 0.0f,
    };

然后将我们的绘制代码参数修改一下,将上一章的3改成6,因为我们的顶点变成了6个:

glDrawArrays(GL_TRIANGLES, 0, 6);

运行效果:

2.索引绘制

首先我们成功的绘制了矩形,值得先高兴一下。但也很容易发现一个问题,一个矩形只有四个顶点,这里为何用了6个?参看下面的这张图:

从图上可以看出,有两个点(A、C)是共用的,重复使用了,导致多了两个顶点。仅仅是一个矩形就多了2个顶点,当一个模型几十万,几百万顶点时,那么重复将是巨大的,所以就有了索引缓冲的出现。所谓索引缓冲,就是用另一个缓冲区的数据,存储顶点的顺序,哪些3个顶点组成一个三角形。

    float vertices[] = {
            0.5f, 0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            -0.5f, 0.5f, 0.0f
    };

    unsigned int indices[] = {
            0, 1, 3,
            1, 2, 3
    };

这个数组表示第一个三角形,由vertices的第0,1,3的数据组成,第二个同理。现在看来去掉了重复的顶点,又增加了另一个缓冲,好像并没有节省什么内存?其实不然,只是这个是简单的矩形。可以简单推算一下,每个三角形都有三条边,都有相邻的三角形,在一个曲面中都是公用顶点的,而索引则是和三角形个数一一对应的,数量要少的多,看一下这个模型就可以理解了,一个点是要被多个三角形公用的(5个6个甚至更多):

GLuint EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

主要变在绘制函数上,由glDrawArrays,变成glDrawElements:

参数说明:
glDrawElements(GL_TRIANGLES,  // 绘制三角形
			   6, //一共有6个索引
			   GL_UNSIGNED_INT, //索引的类型是 unsigned int
			   0); // 在该缓冲区的offset,我们的数据从0开始的,一般情况下indices数组干一件事,就是0

最后得到的绘制图形与上图的矩形是一样的。

3.看一下矩形的组成

在OpenGL库被加载后,即glew执行完后,或者while死循环执行前,添加一句代码:

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

可以看到执行结果,因为它要求OpenGL以LINE绘制。当然还有POINT绘制,自己可以尝试。