以下为一些对数据存储原理的自我推断,如有错误,还请指正。
数据原理
数据定义
命名一个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
暂无评论内容