我正在创建两个不同的顶点缓冲区,使用两个不同的着色器来渲染它们。一旦绑定第二个顶点缓冲区,我停放在第一个顶点缓冲区中的数据就会被破坏或丢失。
如果我只生成并绘制一个顶点缓冲区,如下所示:
glGenBuffers( 1, &vb1 ) ;
glBindBuffer( GL_ARRAY_BUFFER, vb1 ) ;
// fill it..
glBufferData( .. )
然后,在draw()循环中,
glUseProgram( shader1 ) ;
glBindBuffer( vb1 ) ; // make sure it is bound
glDrawArrays( ... ) // draw it
然后它工作正常,没有问题,没有错误(我在每个 gl *调用之后是glGettingLastError(),所以看起来这个代码完全没问题)
现在如果我生成并绑定第二个顶点缓冲区,那么在生成和绑定第一个顶点缓冲区之后的任何时间,
// ran in init() -- then previously working code in draw() is broken
glGenBuffers( 1, &vb2 ) ; // ok.. no problems with this line
glBindBuffer( GL_ARRAY_BUFFER, vb2 ) ; // spoils data in vb1?
只要我使用这个新生成的glBindBuffer
缓冲区调用vb2
,vb1
中的数据就会被完全转储或丢失。在尝试绘制vb1
(而不是vb2
!)时,我遇到了这次崩溃:
我甚至用GL_STATIC_DRAW
填充了数组。
我不明白,我认为这些顶点缓冲区应该保留数据,即使创建并初始化了另一个顶点缓冲区?我做错了什么?
答案 0 :(得分:4)
我发现这个问题的答案非常微妙,很难找到。
我以为我不需要the vertex array declarations that the standard example uses,你可以看到我在问题中遗漏了它们。但事实证明,使用vertex array objects对于正确绑定索引至关重要。
例如,
// Make vertex array OBJECT, _this does not store any data!_
// A "vertex array object" is a bit like a display list in
// that it will just remember and repeat the function calls you make,
// with the values you make them with.
glGenVertexArraysOES( 1, &va ) ; // make vertex array OBJECT. NOT used
// to store data..
// Bind the vertex array
glBindVertexArrayOES( va ) ; // "start recording the calls I make.."
// Make a buffer for the vertex array (place to store the data)
glGenBuffers( 1, &vb ) ; // make the vertex BUFFER (used to
// store the actual data)
// Make the vertex array buffer active
glBindBuffer( GL_ARRAY_BUFFER, vb ) ;
glEnableVertexAttribArray( ... ) ; // REMEMBERED IN VAO (vertex array object)
glVertexAttribPointer( ... ) ; // REMEMBERED IN VAO
glBufferData( .. ) ; // send data down to gpu, not remembered by vao
// "Stop remembering" calls to glBindBuffer( .. ) and glEnableVertexAttribArray( .. )
glBindVertexArrayOES( 0 ) ; // "stop recording"
在抽奖时,简单地说:
glBindVertexArrayOES( va ) ; // runs ALL your glEnableVertexAttribArray() calls,
// as well as your glBindBuffer( .. ) call,
// now all that's left to do is draw
glDrawArrays( glDrawingStyle, 0, vertexCount );