VAO VBO EBO(3)

本篇写一下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概念及用例

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

时间: 2024-10-12 20:49:39

VAO VBO EBO(3)的相关文章

VAO VBO EBO(2)

本篇blog讲的是VAO,想看VBO参照上一篇blog. VAO(vertex array object,顶点数组对象),不得不说......这个名字起得真是鬼畜,名字和功能八竿子打不着. 吐槽归吐槽,该写还是要写的. 我们知道,VBO保存了一个模型的顶点属性信息,每次绘制模型之前我们需要绑定所有的这些信息,对于单个模型来说,这个操作本身无可厚非,但是,当绘制量很大且有大量重复的时候,这样的操作就会变得很麻烦.为了解决这个问题,引入了VAO.VAO可以把所有的配置以及绘制操作都存储在一个对象中,

基于Cocos2d-x学习OpenGL ES 2.0系列——使用VBO索引(4)

在上一篇文章中,我们介绍了uniform和模型-视图-投影变换,相信大家对于OpenGL ES 2.0应该有一点感觉了.在这篇文章中,我们不再画三角形了,改为画四边形.下篇教程,我们就可以画立方体了,到时候就是真3D了. 为什么三角形在OpenGL教程里面这么受欢迎呢?因为在OpenGL的世界里面,所有的几何体都可以用三角形组合出来.我们的四边形也一样,它可以用两个三角形组合出来. 你的第一个四边形 首先,因为OpenGL里面没有直接绘制四边形的命令的,所以我们需要画两个三角形来拼成一个四边形.

Assimp里的一些知识(1)

OpenGL 学习到模型加载的时候,介绍了一个模型导入库(Open Asset Import Library,Assimp)的用法.初学的时候觉得稍微有些复杂,故借由这篇blog来简单地捋一下其中的细节. 首先,当我们使用Assimp导入模型的时候,它通常会将整个模型加载到一个场景(Scene)对象,这个对象包含了导入模型的所有数据.具体结构如下图所示(这个图结构十分重要,需要充分理解): Scene 场景.Scene场景有3个成员,分别是mRootNode(场景根节点),mMeshes(场景中

[原]OpenGL基础教程(四)VBO+纹理绘制四边形

工程下载地址:http://pan.baidu.com/s/1ntr7NHv 提取码:yf1h 一.本文牵扯知识点梳理: (1)VBO (2)纹理 (3)libpng(加载png) (4)shader 1.VBO(Vertex Buffer Objec) //顶点坐标   glEnableVertexAttribArray(0);//激活顶点属性数组 glGenBuffers(1, &VertexID);创建句柄   glBindBuffer(GL_ARRAY_BUFFER, VertexID)

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

直接给出原文链接吧 1.OpenGL图形渲染管线.VBO.VAO.EBO概念及用例 2.OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 3.OpenGL中常用函数详解和VBO VAO详解以及VAO的使用 原文地址:https://www.cnblogs.com/rainbow70626/p/11781336.html

计算机图形学学习(3)—— 基础篇:可编程渲染管线

3.1 渲染管线的发展历程 图形编程的发展 早期的图形编程:调用硬件供货商提供的函数库(用来绘制图元及其属性的函数库不存在) 图形标准的产生:硬件供货商提供标准图形数据库,使得能够在设备无关的方式下生成图像 GKS(Graphical Kernel System, 图形核心系统) PHISS(Programmer's Hierarchical Interactive Graphics System, 程序员层次式交互图形系统) OpenGL 固定管线 图形API提供了一个对硬件进行操作的标准接口

cocos2D-X源码分析之从cocos2D-X学习OpenGL(3)----BATCH_COMMAND

个人原创,欢迎转载,转载请注明原文地址http://blog.csdn.net/bill_man 上一篇介绍了QUAD_COMMAND渲染命令,顺带介绍了VAO和VBO,这一篇介绍批处理渲染命令BatchCommand,批处理命令的处理在Render中比较简单 else if(commandType == RenderCommand::Type:: BATCH_COMMAND) { //将之前缓存的绘制 flush(); auto cmd = static_cast<BatchCommand*>

随便聊聊水面效果的2D实现(二)

0. 引子 之前提到想要随便聊一聊RippleEffect的2D实现方法,近来又总算有了些许空余时间,于是便有了这篇东西~ 1. 概述 RippleEffect我个人的理解是波纹或者说涟漪效果,与之前所讲的WaterEffect有所不同的是,RippleEffect表现的是水波产生与消散的一个过程,而WaterEffect更注重的则是持续的水波"荡漾"效果. 其实游戏中的Ripple效果也很常见,譬如在之前提到过的<Crysis>中,波纹效果就被应用到了很多地方(射击水面等

OpenGL(二)加载模型

在OpenGL(一) OpenGL管线 与 可编程管线流程中,提到加载VBO.IBO的相关技术,本篇详细说一下.实际应用时,我们是不可能手写顶点和索引点.通常模型是使用3dMax或Maya制作,然后在OpenGL程序中 加载模型 .本文着重分析这些文件的格式以及 加载模型 的流程和方法. 大体流程 加载模型 的主要流程是: 读取模型文件内容 解析 vbo(vertex buffer object) 和 ibo(index buffer object) 信息.其中vbo包括顶点的位置.纹理坐标.法