为什么我不能单独创建和初始化 OpenGl VAO?
Why can't I create and initialize an OpenGl VAO separately?
我目前正在开发一个OpenGl 3.3应用程序,该应用程序使用VAOs(每个网格一个)。当我分别创建和初始化我的vao时,对glDrawElements
的任何调用都会导致程序立即退出,而不会出现任何错误消息。然而,当我同时创建和初始化它们时,完全相同的glDrawElements
调用成功了。
独立初始化代码:
Chunk::Chunk(){
glGenVertexArrays(1, &m_vaoId);
glBindVertexArray(m_vaoId);
glGenBuffers(1, &m_vboId);
glGenBuffers(1, &m_eboId);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)(0));
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)(1*sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
}
void Chunk::refreshMesh(){
/*build data into vector<GLfloat> verticies and vector<GLuint> indices...*/
//send data to GPU
glBindVertexArray(m_vaoId);
glBindBuffer(GL_ARRAY_BUFFER, m_vboId);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_eboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLfloat), indices.data(), GL_STATIC_DRAW);
}
编译初始化代码:
void Chunk::refreshMesh(){
/*build data into vector<GLfloat> verticies and vector<GLuint> indices...*/
//send data to GPU
glGenVertexArrays(1, &m_vaoId);
glBindVertexArray(m_vaoId);
glGenBuffers(1, &m_vboId);
glBindBuffer(GL_ARRAY_BUFFER, m_vboId);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);
glGenBuffers(1, &m_eboId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_eboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(GLfloat), indices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)(0));
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)(1*sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
}
注意:我使用Ubuntu 16.04 LTS来编译g++ 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2), glow 1.13和SDL2 2.0.0。我想做单独的初始化,以允许网格数据定期更新,而无需创建新的VAO等,因为我想象有限数量的网格数据可以在任何真正的GPU上处理。
在VAO被发明之前,(几乎)所有东西都保存在全局OpenGL状态。这与VAO略有不同,因为它们有自己的状态。
您正在使用glVertexAttribPointer
来设置缓冲区中属性的指针,然而,VAO状态不仅包含您传递给函数的值,还包含它们指向的缓冲区,这是当您调用函数时绑定到GL_ARRAY_BUFFER
的缓冲区。这允许这样做(伪代码):
glBindBuffer(GL_ARRAY_BUFFER, a);
glVertexAttribPointer(...);
glBindBuffer(GL_ARRAY_BUFFER, b);
glVertexAttribPointer(...);
在中,您将使用来自两个不同缓冲区的属性。然后你可以取消绑定缓冲区,忘记它们,你不需要绑定它们来绘制。
TLDR:为了解决这个问题,你需要在调用glVertexAttribPointer
之前将你打算使用的缓冲区绑定到GL_ARRAY_BUFFER
。您不需要每次绘制时都绑定缓冲区,因为VAO 不使用当前绑定的缓冲区数组buffer 进行绘制,而是在设置属性指针时绑定的缓冲区。
*:要更改或删除它们,显然您仍然需要它们的名称,因此不要在严格意义上"忘记"它们。
- OpenGL GLM 矩阵/向量未正确初始化
- 在没有库的情况下初始化 OpenGL
- GTKmm Opengl 上下文未初始化
- 在上下文初始化之前查询支持的最高 OpenGL 版本?
- OpenGL C++:VBO 的结构包装器不会初始化成员
- 初始化多个纹理 OpenGL、SDL C++ 时出现问题
- openGL如何处理发送给它的空/未初始化数据?
- 您应该如何在OpenGL 4.5中初始化立方体地图阵列
- 为什么要使用'glad'库进行 opengl 初始化?
- OpenGL + SDL + glew 在成功初始化后不会绘制任何内容
- 无法初始化 OpenGL
- 使用visual studio 2012初始化openGL时出现问题
- 正确初始化 OpenGL 的结构数组
- 如何在 ActiveX 控件中正确初始化 OpenGL
- MFC和OpenGL CView,C ,Glew之后初始化OpenGL
- 在渲染以外的另一个线程中初始化 OpenGL 上下文
- QGLWidget paintEvent:在哪里初始化openGL
- OpenGL 着色器语言初始化错误无法从 GLChar 转换为 const
- iOS 下的 OpenGL ES 2.0 初始化
- 为什么我不能单独创建和初始化 OpenGl VAO?