[openGL超级宝典][笔记][8.1缓冲区]

缓冲区

特性:缓冲区存储在GPU显存中,可提供高速高效的访问显存的方式。
作用:
- 可以将数据从一个渲染管线移动到另一个渲染管线(GPU显存中).
- 可以从一个对象绑定到另一个对象.
- 可以将GPU中数据移动到合适位置,不需CPU介入。如PBO移动数据到Texture中


缓冲区使用:

缓冲区的创建,Binding, 删除的示例代码如下:

    // Step1: 为新缓冲区创建名称
    gluint pixBufObject[1];
    glGenBuffer(1, pixBufObject); 

    // Step2: 根据不同的绑定点也就是目的,使用缓冲区
    // 下例中,是以像素包装缓冲区绑定点,使用GLReadPixels将像素数据复制到缓冲区中。
    glBindBuffer(GL_PIXEL_PACK_BUFFER, pixBufObject[0]);

    //Step3:对一个缓冲区解除绑定,则可调用以0为缓冲区名称
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

    //Step4: 用完缓冲区后,清除缓冲区, 则DeleteBuffers + 缓冲区名
    glDeleteBuffers(1, pixBufObject);

绑定点

缓冲区可以先分配,再设置绑定点。绑定点的不同,作用也不同。OpenGL通常有如下的绑定点。

绑定点 作用
GL_ARRAY_BUFFER 数据缓冲区存储颜色,位置,纹理坐标或其它自定义属性
GL_COPY_READ_BUFFER 指定 glCopyBufferSubData 复制的数据源
GL_COPY_WRITE_BUFFER 指定 glCopyBufferSubData 要复制到的地方(目标)
GL_ELEMENT_ARRAY_BUFFER 索引数据缓冲区用于保存glDrawElements, glDrawRangeElements, glDrawElementsInstanced 的索引。
GL_PIXEL_PACK_BUFFER 指定glReadPixels等将像素拷贝到的目标地方。
GL_PIXEL_UNPACK_BUFFER glTexImage**, glTexSubImage**,等纹理更新函数的源缓冲区
GL_TEXTURE_BUFFER 通过纹理单元拾取来访问的缓冲区。
GL_TRANSFORM_FEEDBACK_BUFFER 变换反馈顶点着色器写入的缓冲区
GL_UNIFORM_BUFFER 着色器能访问的Uniform值

上面的各个绑定点,代表不同的Buffer的用法。如PBO常绑定GL_PIXEL_PACK_BUFFER,TBO指绑定GL_TEXTURE_BUFFER,UBO指绑定GL_UNIFORM_BUFFER,VAO中常使用GL_ARRAY_BUFFER等。后续的很多缓冲区的用法,都是根据绑定点不同来使用的。


缓冲区的填充

填充缓冲区,也就是将数据传递到缓冲区中。通常是从CPU拷贝内存到GPU端。

  • 方法1:使用glBufferData,如下例子:
glBindBuffer(GL_PIXEL_PACK_BUFFER, pixBufObject[0]);
// 参数1 GL_PIXEL_PACK_BUFFER,需与BindPoint 一致
// 参数2 数据大小,以字节Byte为单位。
// 参数3:pixelData 将要被上传的数据本身。当为Null时,表示申请特定大小的缓冲区,而不是立即上传数据。
// 参数4 告诉GL如何使用缓冲区。GL_DYNAMIC_COPY表示应用程序经常更新
glBufferData(GL_PIXEL_PACK_BUFFER, pixelDataSize, pixelData, GL_DYNAMIC_COPY);    
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
  • 方法2:使用glBufferSubData(GLenum target, intptr offset, sizeiptr size, const void *data);更新缓冲区中的部分数据。有点类似于改变CPU端的部分数据。

总结:

缓冲区结束了传统很多操作需要GPU到CPU,CPU到GPU的效率低下的方式,带来OpenGL极大的提升。

你可能感兴趣的:([openGL超级宝典][笔记][8.1缓冲区])