问题描述
在使用OpenGl时,我通常会创建一个VBO并使用
将顶点数据传递给它glBufferData();
我最近一直在阅读this的资料,请让我引用其中的一部分:
在创建新存储时,将删除所有先前存在的数据存储。将使用指定的大小(以字节为单位)和使用情况创建新的数据存储。如果data不为NULL,则使用该指针中的数据初始化数据存储。在初始状态下,新数据存储区未映射,它具有NULL映射指针,其映射访问权限为GL_READ_WRITE。
由此我得出结论,当设置了缓冲区数据功能时,缓冲区中的数据将被复制到VBO。
现在,当调用glVertexAttribPointer()
时,我必须再次传递一个指向数据的指针。
我了解attrib指针的用途-它们告诉OpenGL状态机如何在VBO中组织数据。
但是,将指针既传递给VBO又传递给glVertexAttribPointer
函数似乎是多余的,因为VAO始终会保存attrib指针配置,并且调用glVertexAttribPointer
必须将顶点数据存储在程序存储器中无论如何-内存会重复(一个原始副本和glBufferData()
制作的副本)。
为什么存在这种明显的冗余?也许我以错误的方式理解了某些东西? 也许我误解了文档,并且数据没有复制到VBO,但是VBO的目的是什么?
解决方法
您不必。如果将命名缓冲区对象绑定到 ARRAY_BUFFER 目标,则glVertexAttribPointer
的最后一个参数( pointer )被视为缓冲区对象数据存储区中的字节偏移量
两者之一(仅兼容性配置文件):
float *data;
glBindBuffer(GL_ARRAY_BUFFER,0); // 0 is default
glVertexAttribPointer(...,data);
或
float *data;
GLuint vbo;
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferData(GL_ARRAY_BUFFER,...,data,...);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glVertexAttribPointer(...,(void*)0);