码迷,mamicode.com
首页 > 其他好文 > 详细

VAO VBO EBO(3)

时间:2019-09-15 19:38:45      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:point   fse   blog   三角形   一个   类型   void   lan   csdn   

本篇写一下EBO(element buffer object, 又称index buffer object IBO,索引缓冲对象)。

在明白了VBO,VAO的相关概念之后,EBO理解起来就简单了很多。

假设现在我们需要绘制一个矩形,首先我们想到的是给出四个点,然后让OpenGL处理。但是限制出现了,OpenGL主要处理三角形,这个时候我们就会想着给出两个三角形来组成一个矩形(事实上OpenGL就是这么干的)。

那么我们怎么处理呢?给出两个三角形的点

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   // 左上角
};

上面我们可以看到,有几个点叠加了,本来只要四个点的矩形变成了6个点,也就是增加了50%的开销,这显然不合理(很糟糕)。

更好的解决方案是只储存不同的顶点,并设定绘制这些顶点的顺序。这样子我们只要储存4个顶点就能绘制矩形了,之后只要指定绘制的顺序就行了。于是,EBO应运而生。EBO存储的是顶点位置的索引,它和VBO类似,也是在显存中的一个缓冲对象(都是xBO嘛)。

于是就有了下面这个东东:

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开始! 
    0, 1, 3, // 第一个三角形
    1, 2, 3  // 第二个三角形
};

接下来是EBO的定义以及用法:

unsigned int eboID;
glGenBuffers(1, &eboID);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

需要注意的是要用glDrawElements()替换掉之前用VAO&VBO时候的glDrawArrays(),来指明我们从索引缓冲渲染(rendering)

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

//第一个参数指定我们绘制的模式
//第二个参数是打算绘制的顶点数目
//第三个参数是索引的数据类型
//第四个参数可以指定EBO的偏移量(offset)

同样,绑定VAO的同时也会绑定EBO。

整个代码就是这样:

// ..:: 初始化代码 :: ..
// 1. 绑定顶点数组对象
glBindVertexArray(VAO);
// 2. 把我们的顶点数组复制到一个顶点缓冲中,供OpenGL使用
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. 复制我们的索引数组到一个索引缓冲中,供OpenGL使用
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 4. 设定顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

[...]

// ..:: 绘制代码(渲染循环中) :: ..
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
glBindVertexArray(0);

 

PS:在解绑VAO之前先解绑EBO,否则它就没有这个EBO配置了。

 

给出一些我参考的博客,以及教程

[1] 你好,三角形

[2] OpenGL渲染管线、VAO、VBO、EBO概念及用例

VAO VBO EBO(3)

标签:point   fse   blog   三角形   一个   类型   void   lan   csdn   

原文地址:https://www.cnblogs.com/zhlabcd/p/11523463.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!