zoukankan      html  css  js  c++  java
  • 第46月第17天 opengl vbo vao indices

    1.

    https://www.bilibili.com/video/BV1zt4y1C7dh?from=search&seid=9121448760250757989

    indices

    索引数组如下:

    static const GLushort vertex_indices[] =
    {
    0, 1, 2
    }
    索引缓冲区的创建,绑定,填充数据及删除如下:

    GLuint index_buffer;
    glGenBuffers(1, &index_buffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(vertex_indices),vertex_indices,GL_STATIC_DRAW);

    glDeleteBuffers(1, &index_buffer)

    https://blog.csdn.net/liyazhen2011/article/details/102580130

    https://www.cnblogs.com/xuqp/p/10387824.html
    ————————————————

    OpenGL渲染时涉及到的数据传输
    准备好需要绘制的顶点数据。(自己定义的或者是从某些模型文件中读取出来的)
    在GPU中开辟一块内存。
    将顶点数据传到上一步开辟的GPU的内存中。
    将着色器代码转化为着色器程序,并链接到当前的执行程序中。
    GPU根据着色器的逻辑将这块内存的数据进行计算。(指定该如何将数据发送给显卡)
    将这块已经计算完的数据一并发送给显卡进行渲染绘制。
    上述流程中涉及到的内存
    根据上面的流程,可知整个数据渲染的流程中,涉及到两个数据传输的流程,一个是将数据传输到GPU中的内存、另一个是将GPU中的数据传输给显卡。
    GPU的内存通过顶点缓冲对象(Vertex Buffer Objects),也就是VBO来管理这个内存,它会在GPU内存(通常被称为显存)中储存大量顶点。
    使用这VBO的好处是我们可以一次性的发送一大批数据到显卡上,而不是每个顶点发送一次。
    一、VBO的相关API调用
    生成一个VBO对象:
    int vboId = glGenBuffers();

    设置顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER,将创建的vbo对象绑定到当前的执行程序上,也可以理解为激活。
    glBindBuffer(GL_ARRAY_BUFFER, vboId);

    将准备好的顶点数据复制到缓冲的内存中,posBuffer为顶点数据,GL_STATIC_DRAW表示数据不会改变和几乎不会改变。第三个参数一共有三个选择:GL_STATIC_DRAW 表示数据不会或几乎不会改变、GL_DYNAMIC_DRAW表示数据会被改变很多、GL_STREAM_DRAW 表示数据每次绘制时都会改变。
    glBufferData(GL_ARRAY_BUFFER, posBuffer, GL_STATIC_DRAW);

    比如说一个缓冲中的数据将频繁被改变,那么使用的类型就是GL_DYNAMIC_DRAW或GL_STREAM_DRAW,这样就能确保显卡把数据放在能够高速写入的内存部分。

    指定输入数据的哪一个部分对应顶点着色器的哪一个顶点属性,也就是在渲染前指定OpenGL该如何解释VBO中的顶点数据。glVertexAttribPointer中的参数的意义分别是:

    第一个参数为顶点着色器中layout (location=0) in vec3 position;中的location的值。
    第二个参数为第二个参数指定顶点属性的维数,如果是vec3,它由3个值组成,所以大小是3。
    第三个参数为数据的类型。
    第四个参数为是否希望数据被标准化,如果我们设置为GL_TRUE,所有数据都会被映射到0(对于有符号型signed数据是-1)到1之间。
    第五个参数叫做步长(Stride),它告诉我们在连续的顶点属性组之间的间隔。设置为0的意思是让OpenGL自己去识别步长。
    最后一个参数表示位置数据在缓冲中起始位置的偏移量(Offset)。由于位置数据在数组的开头,所以这里是0。
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

    二、渲染vbo内存中的数据需要调用的API
    进行完上面的步骤,准备工作已经做完,接下来就是要准备渲染了。

    glEnableVertexAttribArray(0);//使vbo的内存变为可用状态。
    glUseProgram(shaderProgram);//调用着色器程序。
    glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);//绘制方法

    当一个vbo中的数据准备完成以后,绘制的过程是需要执行以上三步,如果程序中只有一种顶点类型的vbo,那倒还好;如果有很多种vbo(在激活vbo时,调用glBindBuffer时是可以选择很多种类型的),这样一来,在绘制这些vbo时,就需要重复调用很多次上面的三个步骤。为了简化这个流程,也减少GPU和显卡的交互次数。思考:有没有一些方法可以使我们把所有这些状态配置储存在一个对象中,并且可以通过绑定这个对象来恢复状态,此时就提出了VAO的概念。

    三、VAO的相关调用的API
    顶点数组对象(Vertex Array Object )VAO可以像VBO顶点缓冲对象那样被创建和绑定。当一个VAO被创建绑定之后,任何随后的顶点属性调用都会储存在这个VAO中。 这样一来如果有多个vbo对象,在渲染绘制时,就不用执行很多次前面提到的渲染程序,只需要执行一次绑定的VAO的渲染API即可。

    创建VAO的流程与VBO类似。
    int vaoId = glGenVertexArrays();//创建
    glBindVertexArray(vaoId);//绑定,激活

    VAO渲染
    glBindVertexArray(getVaoId());
    glEnableVertexAttribArray(0);
    glUseProgram(shaderProgram);
    glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);

    四、VBO和VAO的解绑
    VBO解绑
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    VAO解绑
    glDisableVertexAttribArray(0);
    glBindVertexArray(0);

    https://blog.csdn.net/xyh930929/article/details/83352645

  • 相关阅读:
    数据库性能优化之冗余字段的作用
    SQL里面的排序语句desc和ASC有什么区别
    Mybatis@options注解属性useGeneratedKeys,keyProperty,keyColumn的使用
    关于resultType与parameterType的基本使用和区别
    阿里云Centos7的部署springboot后mysql中文问号乱码
    LINUX下启动/停止/重启MYSQL
    CondenseNet:可学习分组卷积,原作对DenseNet的轻量化改造 | CVPR 2018
    MnasNet:经典轻量级神经网络搜索方法 | CVPR 2019
    MobileNetV1/V2/V3简述 | 轻量级网络
    ShuffleNetV1/V2简述 | 轻量级网络
  • 原文地址:https://www.cnblogs.com/javastart/p/13330962.html
Copyright © 2011-2022 走看看