OpenGL缓冲对象:glBufferStorage、glNamedBufferStorage、glBufferData、glNamedBufferData简介

  1. OpenGL缓冲对象概念
  2. 缓冲区对象 Buffer Objects API列表

  1. 缓冲区对象 Buffer Objects
  2. 创建和绑定缓冲区对象 Creating and Binding Buffer Objects
  3. 创建缓冲对象数据存储 Creating Buffer Object Data Stores
  4. 修改缓冲对象数据存储 Modifying Buffer Object Data Stores
  5. Clear缓冲对象数据存储 Clear Buffer Object Data Stores
  6. 映射映射缓冲数据 Mapping Buffer Data
  7. 刷新映射缓冲数据 Flush Buffer Data
  8. 取消映射缓冲数据 Unmapping Buffer Data
  9. 使缓冲区数据无效 Invalidating Buffer Data
  10. 缓冲区间复制 Copying Between Buffers
  11. 缓冲对象查询 Buffer Object Queries

void glBufferStorage( enum target, sizeiptr size, const void *data, bitfield flags );
void glNamedBufferStorage( uint buffer, sizeiptr size,const void *data, bitfield flags );
void glBufferData( enum target, sizeiptr size, const void *data, enum usage );
void glNamedBufferData( uint buffer, sizeiptr size, const void *data, enum usage );
  • glBufferStorage 和 glNamedBufferStorage

glBufferStorageglNamedBufferStorage是OpenGL中的函数,用于创建或重新分配缓冲对象的数据存储区。这两个函数的主要区别在于如何指定目标缓冲对象:glBufferStorage通过绑定到指定的缓冲目标(如GL_ARRAY_BUFFER)来操作当前绑定的缓冲对象;而glNamedBufferStorage则直接通过传递缓冲对象的名字来操作。

  1. size参数指定了数据存储区的大小,以基本机器单位为计数单位。

  2. data参数是一个指向客户端内存中初始数据的指针,用以初始化缓冲对象的数据存储区。如果设置为NULL,则会创建一个未初始化的、具有指定大小的存储区。

  3. flags参数是描述应用程序对数据存储区使用意图的位标志组合。这些标志包括:

    • DYNAMIC_STORAGE_BIT:允许在创建后通过调用BufferSubData更新缓冲内容。若不设置此标志,则客户端不能直接更新缓冲内容,但仍然可以通过服务器端命令(例如CopyBufferSubData和ClearBufferSubData)进行更新。
    • MAP_READ_BIT:允许客户端将数据存储区映射到其地址空间以供读取访问。
    • MAP_WRITE_BIT:允许客户端将数据存储区映射到其地址空间以供写入访问。
    • MAP_PERSISTENT_BIT:当数据存储区被映射时,允许服务器端在客户端映射期间读取或写入缓冲,并且客户端的指针保持有效。
    • MAP_COHERENT_BIT:当与MAP_PERSISTENT_BIT一起使用时,保证同时映射给客户端并由服务器使用的共享缓冲的访问一致性,即客户端或服务器的写入操作会被后续的GL命令自动看到。
    • CLIENT_STORAGE_BIT:指示实现选择是否使用本地于服务器或客户端的存储作为缓冲的后端存储。
  4. 如果设置了MAP_PERSISTENT_BIT,则必须至少同时设置MAP_READ_BITMAP_WRITE_BIT之一。

  5. 不能单独指定MAP_COHERENT_BIT而不同时指定MAP_PERSISTENT_BIT,否则会导致错误。

执行glBufferStorageglNamedBufferStorage时,它会删除任何现有的数据存储区,并根据表6.3设置缓冲对象的状态变量。如果缓冲对象在当前上下文或其他线程的当前上下文中已被映射,则在删除现有数据存储区之前,效果相当于在每个这样的上下文中先调用了UnmapBuffer。此外,一旦通过这两个函数分配了数据存储区,除非删除整个缓冲对象,否则该存储区无法重新分配或释放。

  • glBufferData 和 glNamedBufferData

glBufferDataglNamedBufferData是OpenGL中的函数,用于分配和初始化(或重置)缓冲对象的数据存储区。在这些函数中:

  • glBufferData作用于当前绑定到指定目标(如GL_ARRAY_BUFFERGL_ELEMENT_ARRAY_BUFFER等)的缓冲对象。
  • glNamedBufferData直接作用于指定名称的缓冲对象。

对于这两个函数,参数包括:

  • size:数据存储区的大小(以基本机器单位为单位)。
  • data:指向客户端内存中源数据的指针。如果为NULL,则不填充数据,缓冲区内容将变为未定义状态。
  • usage:指示应用程序预期的数据使用模式,共有九种可能值:
    • STREAM_DRAW, STATIC_DRAW, DYNAMIC_DRAW: 应用程序写入数据,并且可能多次作为图像来源或由着色器访问。
    • STREAM_READ, STATIC_READ, DYNAMIC_READ: 从OpenGL读取数据并被应用程序查询多次。
    • STREAM_COPY, STATIC_COPY, DYNAMIC_COPY: 从OpenGL读取数据并可能多次作为图像来源。

usage 参数提供的是性能提示,实际使用模式并不受其限制。当调用 glBufferDataglNamedBufferData 时,会删除任何已存在的数据存储,并根据表6.3设置缓冲对象的状态变量。

如果有其他上下文正在映射缓冲对象的部分内容,则会在删除现有数据存储之前模拟执行 UnmapBuffer 操作。

数据元素必须按照客户端平台的要求进行对齐,并满足基础级别的要求,即指向由N个基本机器单元组成的数据项的偏移量应是N的倍数。

  • 区别

glBufferStorage, glNamedBufferStorage, glBufferData, 和 glNamedBufferData 都是OpenGL中用于管理缓冲对象(例如顶点缓冲、索引缓冲或通用目的缓冲)的函数,但它们在功能和行为上有一定的区别:

  1. glBufferData 和 glNamedBufferData

    • glBufferData 函数分配一个新的可变大小的数据存储区域给当前绑定到指定目标的缓冲对象,并且可以将客户端内存中的数据复制到该缓冲区。这个函数创建的数据存储是可变的,意味着应用程序可以在任何时候重新定义或更新其内容。
    • glNamedBufferData 直接作用于通过名称指定的缓冲对象,而不是依赖于当前绑定的对象。其功能与 glBufferData 类似,也是分配可变大小的存储空间并可选择性地填充数据。
  2. glBufferStorage 和 glNamedBufferStorage

    • glBufferStorage 是一个更高级的函数,它分配的是不可变(immutable)或者持久化(persistent)的数据存储空间。一旦使用此函数创建了缓冲区,就不能改变其大小,而且根据所传入标志的不同,可能无法重写整个数据存储的内容。这对于GPU能够进行优化,比如预读取和缓存数据,提供了更强的保证。
    • glNamedBufferStorage 同样直接作用于指定名称的缓冲对象,提供与 glBufferStorage 相同的功能,即分配不可变或持久化的存储空间。

具体来说:

  • 可变性(Mutability)glBufferData 系列函数允许创建可变存储,而 glBufferStorage 系列函数则默认创建不可变存储,除非指定了特定的标志允许部分修改。
  • 映射模式(Mapping Modes)glBufferStorage 可以设置额外的标志来控制如何映射缓冲区到客户端内存,如是否支持读写映射等。
  • 性能提示(Usage Hints):虽然 glBufferData 接受一个 usage 参数作为性能提示,但 glBufferStorage 并没有这样的参数,因为它通常暗示着对缓冲内容的长期持久利用。

总之,glBufferData / glNamedBufferData 更适合需要频繁修改或一次性上传数据的应用场景;而 glBufferStorage / glNamedBufferStorage 则更适合那些希望优化存储管理和访问性能,尤其是当数据在程序运行过程中基本不变的情况下。

你可能感兴趣的:(OpenGL,图形渲染)