OpenGL超级宝典第七版学习笔记-缓冲区(buffers)(2)

2017-3-28缓冲区(buffers)
1、对缓冲区赋值的三种方法:一是指定数据仓库时指定默认初始化值,二是使用gl?BufferSubData()系列函数;三是使用glMapNamedBufferData();
2、使用以下两个函数进行对缓冲区进行赋值(写入数据)
voidglBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
voidglNamedBufferSubData(GLuint buffer ,GLintptr offset, GLsizeiptr size, const void data);
前者为所有绑定在target上的缓冲区写入数据,后者为buffer缓冲区写入数据。
使用方法举例:
// This is the data that we will place into the buffer object
staticconst float data[] =
{
0.25, -0.25, 0.5, 1.0,
-0.25, -0.25, 0.5, 1.0,
0.25, 0.25, 0.5, 1.0
};
// Put the data into the buffer at offset zero
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(data), data);
3、使用glMapNamedBufferData()或使用glMapBufferData()函数会向系统索要一个指向某缓冲区的数据仓库的指针,从而自行进行数据写入操作。二者原型如下:
Void * glMapNamedBufferData(GLenumtarget,GLenum usage);
Void * glMapNamedBufferData(GLuintbuffer,GLenum usage);
使用方法如下:
// This is the data that we will place into the buffer object
staticconst float data[] =
{
0.25, -0.25, 0.5, 1.0,
-0.25, -0.25, 0.5, 1.0,
0.25, 0.25, 0.5, 1.0
};
// Get a pointer to the buffer's data store
void * ptr = glMapNamedBuffer(buffer, GL_WRITE_ONLY);
// Copy our data into it...
memcpy(ptr, data, sizeof(data));
// Tell OpenGL that we're done with the pointer
glUnmapNamedBuffer(GL_ARRAY_BUFFER);
4、取消缓冲区映射:
glUnmapNamedBuffer();
glUnmapBuffer();
5、当你想往缓冲区写入数据但是又没有得到所有的数据时,映射缓冲区是很有用的,比如当你从一个文件中生成或者读取数据的时候。如果你使用glBufferSubData()或者glBufferData()中的初始数据的指针时,必须先把数据生成或者读取到临时的内存中,然后让OpenGL生成另外一份数据拷贝并保存到缓冲区对象中,如果你使用映射缓冲区操作,那么OpenGL会直接从文件中读取数据并写入到缓冲区中。当解除映射时,OpenGL能避免复制就避免复制一份数据拷贝。
6、glMapBuffer()或者glMapNamedBuffer有时候处理起来可能比较繁重,它映射整个缓冲区,除了usage参数,它而不提供任何关于要处理的映射操作的类型的信息。改进的方法是:
void *glMapBufferRange(GLenum target,
GLintptr offset, 
GLsizeiptr length,
GLbitfieldaccsess);
void *glMapNamedBufferRange(GLuint buffer,
GLintptr offset,
GLsizeptr length,
GLbitfield access);
这两个函数不是映射整个缓冲区对象,而是而是映射指定的范围。这个范围有offset和length来决定。Access参数同样有GL_MAP_READ_BIT,GL_MAP_WRITE_BIT,GL_MAP_PERSISTENT_BIT,GL_MAT_COHERENT_BIT这几个flag标志位,且意思与glBufferStorage()中的用法一样。不同的是glBufferStorage()中的标志位只是一种用法提示,而glMapBufferRange()和glMapNamedBufferRange是强制要求用途正确的,如果你想使用缓冲区映射来读写数据,那么在调用glBufferStorage()时,它的用途标志位必须有GL_MAP_READ_BIT……
7、一般会优先使用glMapBufferRange()和glMapNamedBufferRange函数,即使你不需要使用它们的一些高级特性,也要养成使用它们的习惯。

你可能感兴趣的:(OpenGL)