• 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概念及用例

    原来人类的悲欢并不相通, 我只觉得他们吵闹。
  • 相关阅读:
    hadoop脑裂
    磁盘动态扩容
    zookeeper快照清理
    hadoop rebalance
    redis
    斜率场--微分方程图形解
    simpson法计算arctan(1)-即pi/4
    反函数的导数
    动能公式推导
    schwarz( 施瓦兹)不等式证明
  • 原文地址:https://www.cnblogs.com/zhlabcd/p/11523463.html
Copyright © 2020-2023  润新知