第十九课,高级数据(数据存储)

以下为一些对数据存储原理的自我推断,如有错误,还请指正。

数据原理

数据定义

命名一个unsigned int类型变量

GLuint VBO,EBO,VAO;

将EBO定义为gpu内存中的数据区块地址。

glGenBuffers(1, &EBO);

将VAO定义为GPU中的属性块地址

glGenVertexArrays(1, &VAO);

在这里插入图片描述
以上这些都将存储在GPU内存块,而运行时需要将缓冲绑定为当前运行缓冲。

缓冲绑定为当前运行缓冲

glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

运行时仅能使用一个VertexArray,GL_ELEMENT_ARRAY_BUFFER,GL_ARRAY_BUFFER。(运存中能绑定的缓冲不止这些)
即只能绑定一个VAO,VBO,EBO为当前运行缓冲。

对当前运行缓冲的数据写入

计算机必须将要修改的缓冲绑定为当前运行缓冲时,才能对数据进行读取和写入。

分配特定大小的内存
glBufferData(GL_ARRAY_BUFFER, 分配内存大小, 数据, GL_STATIC_DRAW);

如果将数据设为null,则只会分配特定大小的内存而不会填充数据

之后我们可以使用glBufferSubData,填充缓冲的特定区域。
glBufferSubData(GL_ARRAY_BUFFER, 偏移量(字节), sizeof(data), &data);
将数据导入缓冲的另外一种方法是,请求缓冲内存的指针
// 获取指针
void *ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);//只写指针,对运存中GL_ARRAY_BUFFER操作
// 复制数据到内存
memcpy(ptr, data, sizeof(data));//从指针位置开始写入data。
// 记得告诉OpenGL我们不再需要这个指针了
glUnmapBuffer(GL_ARRAY_BUFFER);

如果要直接映射数据到缓冲,而不事先将其存储到临时内存中,glMapBuffer这个函数会很有用。比如说,你可以从文件中读取数据,并直接将它们复制到缓冲内存中。

分批顶点属性

与交错布局123123123123不同,我们将采用分批(Batched)的方式111122223333。

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

这与QT对OpenGL封装的vbo类中的allocate有相同作用。

VBO.allocate(vertices1,sizeof (vertices1));

复制缓冲

void glCopyBufferSubData(GLenum readtarget, GLenum writetarget, GLintptr readoffset,
                         GLintptr writeoffset, GLsizeiptr size);

readtarget,writetarget接受一个缓冲类型,有
已知的:
VERTEX_ARRAY_BUFFER
VERTEX_ELEMENT_ARRAY_BUFFER
未知的:
GL_COPY_READ_BUFFER
GL_COPY_WRITE_BUFFER
通过

glBindBuffer(GL_COPY_READ_BUFFER, vbo1);
glBindBuffer(GL_COPY_WRITE_BUFFER, vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo3);
glBindBuffer(VERTEX_ELEMENT_ARRAY_BUFFER, vbo4);

再使用函数

glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(vertexData));
//将vbo1中的数据从0(偏移量)开始复制sizeof(vertexData)个字节到vbo2从0开始的位置上。

可以将GPU内存中的数据直接进行复制。

学习该节的作用

使用哪种方法都不会对OpenGL有什么立刻的好处,它只是设置顶点属性的一种更整洁的方式。
具体使用的方法将完全取决于你的喜好与程序类型。
这节就是让你知道还有不同的数据存储处理方法,下一节将继续让你了解更多的GLSL语法和使用。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片