OpenGl L19高级数据

一、高级数据

下面,我们将使用纹理对象来存储大量的数据。OpenGL中的缓冲只是一个管理特定内存块的对象,在我们将它绑定到一个缓冲目标时,便赋予了意义。
当绑定到GL_ARRAY_BUFFER时,就是一个顶点数组缓冲(或者GL_ELEMENT_ARRAY_BUFFER)。
到目前为止,我们一直调用glBufferData函数填充缓存对象管理的内存,这个函数会分配一块内存,然后将数据添加到这块内存中去(如果参数data设置为NULL,也就是说这个函数只会分配内存,不进行填充)。
除了调用一次函数填充整个缓冲外,也可以使用glBufferSubData,填充缓冲的特定区域。其参数列表为一个缓冲目标,一个偏移量,数据大小,和数据本身。与上面的填充函数不同的是,我们可以指定是从哪一个位置开始填充内存。

glBufferSubData(GL_ARRAY_BUFFER, 24, sizeof(data), &data); // 范围: [24, 24 + sizeof(data)]

将数据导入缓冲的另外一种方法是,请求缓冲内存的指针,直接将数据复制到缓冲当中。
通过调用glMapBuffer函数,OpenGL会返回当前绑定缓冲的内存指针。

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);

二、分批顶点属性

使用glVertexAttribPointer,可以指定顶点数组缓冲内容的属性布局。在顶点属性中,对属性进行了交错处理,也就是将每一个顶点的位置,或纹理坐标紧密放置在一起。
能做的是将每一个属性类型的向量数据打包为一个大的区块,而不是进行交错存储。与交错布局123123123不同,将采用分批的方式111222333。
当从文件中加载顶点数据时,获取到的是一个顶点坐标,一个纹理坐标,需要将这些数组结合为一个大的交错坐标数据数组,使用分批glBufferSubData可以很容易实现:

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);

这样我们可以直接将属性数组作为一个整体传递给缓冲,不需要事先进行处理。
可以先合并为一个大的数组,然后使用glBufferData来填充。

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);

readtargetwritetarget参数需要填入复制源和复制目标的缓冲目标。

接下来glCopyBufferSubData会从readtarget中读取size大小的数据,并将其写入writetarget缓冲的writeoffset偏移量处。

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));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值