glBufferData函数
填充整个缓冲对象,会分配一块内存,并将数据添加到这块内存中。如果data
为NULL
则只分配内存不进行填充。当需要预留(Reserve)特定大小的内存,之后回到这个缓冲填充的时候会很有用。
glBufferSubData
填充缓冲的特定区域。参数为缓冲目标、偏移量、数据大小和数据本身。
偏移量用于指定从何处开始填充这个缓冲,使得可以插入或更新部分缓冲内存。
缓冲要有足够的已分配内存,所以对一个缓冲调用 glBufferSubData
前必须要先调用glBufferData
。
glBufferSubData(GL_ARRAY_BUFFER, 24, sizeof(data), &data); // 范围: [24, 24 + sizeof(data)]
glMapBuffer
请求缓冲内存的指针,直接将数据复制到缓冲当中。
float data[] = {
0.5f, 1.0f, -0.35f
...
};
glBindBuffer(GL_ARRAY_BUFFER, buffer);
// 获取指针
void *ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
// 复制数据到内存
memcpy(ptr, data, sizeof(data));
// 记得告诉OpenGL我们不再需要这个指针了
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer
用于指针操作完成后解除映射,指针将不再可用,并且如果数据成功映射到缓冲中则返回GL_TRUE
。
分批顶点属性
float positions[] = { ... };
float normals[] = { ... };
float tex[] = { ... };
// 填充缓冲
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(positions), &positions);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(positions), sizeof(normals), &normals);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(positions) + sizeof(normals), sizeof(tex), &tex);
//更新顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(sizeof(positions)));
glVertexAttribPointer(
2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)(sizeof(positions) + sizeof(normals)));
复制缓冲
glCopyBufferSubData
能从一个缓冲中复制数据到另一个缓冲中。
void glCopyBufferSubData(GLenum readtarget, GLenum writetarget, GLintptr readoffset,
GLintptr writeoffset, GLsizeiptr size);
readtarget
: 填入复制源
writetarget
: 复制目标的缓冲目标。
如果读写数据的两个不同缓冲都为顶点数组缓冲可以使用GL_COPY_READ_BUFFER
和GL_COPY_WRITE_BUFFER
作为readtarget
和writetarget
参数。
float vertexData[] = { ... };
glBindBuffer(GL_COPY_READ_BUFFER, vbo1);
glBindBuffer(GL_COPY_WRITE_BUFFER, vbo2);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(vertexData));
也可以只将writetarget
缓冲绑定为新的缓冲目标类型之一:
float vertexData[] = { ... };
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glBindBuffer(GL_COPY_WRITE_BUFFER, vbo2);
glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(vertexData));