Filling and Copying Data in Buffers

周一到周五,每天一篇,北京时间早上7点准时更新~

After allocating storage space for your buffer object using glBufferStorage(), one possible next step is to fill the buffer with known data. Whether you use the initial data parameter of glBufferStorage(), use glBufferSubData() to put the initial data in the buffer, or use glMapBufferRange() to obtain a pointer to the buffer’s data store and fill it with your application, you will need to get the buffer into a known state before you can use it productively. If the data you want to put into a buffer is a constant value, it is probably much more efficient to call glClearBufferSubData() or glClearNamedBufferSubData(), whose prototypes are

在缓冲区对象分配好了内存后,下一步可能就轮到给给内存填充数据了。你可以在分配内存的同时为缓冲区填充数据,也可以使用glBufferSubData或者glMapBufferRange在缓冲区内存分配好之后 为缓冲区填充数据。在你使用buffer之前,你需要把buffer置于一个已知的状态。如果你想往缓冲区里刷入常数,那么你可以使用glClearBufferSubData或者glClearNamedBufferSubData来高效的做这事。

void glClearBufferSubData(GLenum target,
GLenum internalformat,
GLintptr offset,
GLsizeiptr size,
GLenum format,
GLenum type,
const void data);
void glClearNamedBuffeSubData(GLuint buffer,
GLenum internalformat,
GLintptr offset,
GLsizeiptr size,
GLenum format,
GLenum type,
const void
data);
These functions take a pointer to a variable containing the values that you want to clear the buffer object to and, after converting it to the format specified in internalformat, replicate the data across the range of the buffer’s data store specified by offset and size, both of which are measured in bytes. format and type tell OpenGL about the data pointed to by data. The format can be one of GL_RED, GL_RG, GL_RGB, or GL_RGBA to specify one-, two-, three-, or four-channel data, for example. Meanwhile, type should represent the data type of the components. For instance, it could be GL_UNSIGNED_BYTE or GL_FLOAT to specify unsigned bytes or floating-point data, respectively. The most common types supported by OpenGL and their corresponding C data types are listed in Table 5.3.

这些函数使用data指针指向位置的数据去刷新缓冲区的内存,数据会被转化成internalformat的格式,数据刷新的多少由offset和size指定,数据大小的单位为字节。 format和type告诉OpenGL,data指针指向的数据的格式,format的值可以是GGL_RED, GL_RG, GL_RGB,或者 GL_RGBA,用来标记数据是1、2、3、4通道的数据。type这里指定的是每个通道是什么格式。 比如,它可能是GL_UNSIGNED_BYTE或者GL_FLOAT。比较常见的类型在表5.3里展示出来了
Filling and Copying Data in Buffers
Once your data has been sent to the GPU, it’s entirely possible you may want to share that data between buffers or copy the results from one buffer into another. OpenGL provides an easy-to-use way of doing that. glCopyBufferSubData() and glCopyNamedBufferSubData() let you specify which buffers are involved as well as the size and offsets to use.

当你把数据发送给GPU后,你可能希望与其他buffer共享数据或者是从一个buffer拷贝数据到另一个buffer。OpenGL提供的对应的API是 glCopyBufferSubData和glCopyNamedBufferSubData,他们的定义如下

void glCopyBufferSubData(GLenum readtarget,
GLenum writetarget,
GLintptr readoffset,
GLintptr writeoffset,
GLsizeiptr size);
void glCopyNamedBufferSubData(GLuint readBuffer,
GLuint writeBuffer,
GLintptr readOffset,
GLintptr writeOffset,
GLsizeiptr size);
For glCopyBufferSubData(), the readtarget and writetarget are the targets where the two buffers you want to copy data between are bound. They can be buffers bound to any of the available buffer binding points. However, since buffer binding points can have only one buffer bound at a time, you couldn’t copy between two buffers that are both bound to the GL_ARRAY_BUFFER target, for example. Thus, when you perform the copy, you need to pick two targets to bind the buffers to, which will disturb the OpenGL state.

glCopyBufferSubData的数据读取地址和数据写入地址只某个绑定的节点而不是buffer对象本身的标记。然而每个特定的绑定节点只能绑定一个buffer,所以你无法将两个都绑定在GL_ARRAY_BUFFER 上的buffer进行数据拷贝。所以,在你要拷贝的时候,你需要将buffer绑定到两个绑定节点上去,然后执行拷贝操作,这实际上会扰乱OpenGL状态机

To resolve this, OpenGL provides the GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER targets. These targets were added specifically to allow you to copy data from one buffer to another without any unintended side effects. Because they are not used for anything else in OpenGL, you can bind your read and write buffers to these binding points without affecting any other buffer target.

为了实现这一目标,OpenGL提供两个专门的绑定节点,GL_COPY_READ_BUFFER和GL_COPY_WRITE_BUFFER,这俩节点能执行buffer间的数据拷贝,并且没有什么副作用。 因为这俩货除了具备拷贝功能以外不会有其他功能,所以你执行buffer间拷贝的时候,改变这俩个节点的状态不会影响到其他的OpenGL的逻辑。

Alternatively, you can use the glCopyNamedBufferSubData() form, which takes the names of the two buffers directly. Of course, you can specify the same buffer for both readBuffer and writeBuffer to copy a region of data between two offsets in the same buffer object. Be careful that the regions to be copied don’t overlap, though, as in this case the results of the copy are undefined. You can consider glCopyNamedBufferSubData() as a form of the C function memcpy for buffer objects.

同样的,你可以使用第二个glCopyNamedBufferSubData,直接传入写数据的地址和读数据的地址。你同样可以指定写入和读取的是同一个buffer,并在buffer内的不同区域内进行数据的拷贝。你可以把这个函数想象成为memcpy

The readoffset and writeoffset parameters tell OpenGL where in the source and destination buffers to read or write the data, and the size parameter tells it how big the copy should be. Be sure that the ranges you are reading from and writing to remain within the bounds of the buffers; otherwise, your copy will fail. You may notice the types of readoffset, writeoffset, and size, which are GLintptr and GLsizeiptr. These types are special definitions of integer types that are at least wide enough to hold a pointer variable

readoffset和writeoffset告诉OpenGL读地址和写地址的数据偏移位置。size告诉OpenGL拷贝数据的大小。你必须保证别越界了,否则你的拷贝会失败。 你可能注意到了GLintptr和GLsizeiptr,这些数据都是整型的数据,它们对于标记指针的地址来说已经足够大了。

本日的翻译就到这里,明天见,拜拜~~

第一时间获取最新桥段,请关注东汉书院以及图形之心公众号

东汉书院,等你来玩哦

上一篇:linux系列之常用运维命令整理笔录


下一篇:this is prerequisite condition to test whether sufficient total swap space is avalible on the system