跳转至

05 索引缓冲区(元素缓冲区)

绘制一个长方形

在上一个课程中,绘制的是一个三角形。本节课来绘制一个长方形。 有一个背景知识是,在计算机世界里绘制的基础图元都是三角形,因此我们需要将长方形拆成两个三角形来进行绘制。

只需修改三个地方,即可完成长方形的绘制。

//定义两个三角形的顶点
float positions[] = 
{
    -0.5f, -0.5f,
     0.5f, -0.5f,
     0.5f,  0.5f,

     0.5f,  0.5f,
    -0.5f,  0.5f,
    -0.5f, -0.5f
};

//调整顶点缓冲区的大小
glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), positions, GL_STATIC_DRAW);

//绘制时,绘制6个顶点
glDrawArrays(GL_TRAINGLES, 0, 6);

使用索引缓冲区以重用顶点

上节绘制使用了6个顶点,但长方形只有4个顶点,多用了2个顶点。其实能发现2个顶点是重复的。 此时,我们就可以使用索引缓冲区来重用我们的顶点,减少数据量。

索引缓冲区(又名,元素缓冲区):允许我们重用顶点

float positions[] = 
{                  //索引号
    -0.5f, -0.5f,  //0,从0开始
     0.5f, -0.5f,  //1
     0.5f,  0.5f,  //2
    -0.5f,  0.5f   //3
};

unsigned int indices[] = 
{
    0, 1, 2, //第1个三角形
    2, 3, 0  //第2个三角形
};

unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 4 * 2 * sizeof(float), positions, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

//将索引缓冲区发送到显卡上
unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW);

//...

while(...)
{
    //...

    glDrawElements(GL_TRANGLES, 6, GL_UNSIGNED_INT, nullptr);
    //绘制6个索引
    //指向索引缓冲区的一个指针:前面已经glBindBuffer(ibo)了,可以用nullptr

    //...
}