我一直在尝试使用“顶点缓冲对象”将顶点数据保存在GPU上并减少开销,但我无法使其正常工作。代码如下。
据我了解,您使用生成了缓冲区glGenBuffers
,然后将其绑定到缓冲区,glBindBuffer
以便可以使用它,然后使用将数据写入缓冲区glBufferData
并完成操作,可以将其解除绑定并准备使用,只需再次绑定即可。
但是最后一部分是我遇到的麻烦,当我在创建并加载数据并将其加载并尝试使用它进行绘制后将其绑定时,它给了我很多 GL Error: Out of Memory.
我怀疑我的简单网格内存不足,因此我必须做错了什么。
谢谢。
编辑1:我每帧之后调用glGetError,但是由于这是我在整个程序中所做的唯一的OpenGL,这应该不是问题
//when loading the mesh we create the VBO
void createBuffer()
{
GLuint buf;
glGenBuffers(1, &buf);
glBindBuffer(GL_ARRAY_BUFFER, buf);
glBufferData(GL_ARRAY_BUFFER, vertNormalBuffer->size() * sizeof(GLfloat), (GLvoid*) bufferData, GL_STATIC_DRAW);
//EDIT 1: forgot to show how I handle the buffer
model->vertexNormalBuffer = &buf;
//Unbinds it
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Fighter::doRedraw(GLuint shaderProgram)
{
glm::mat4 transformationMatrix = getTransform();
GLuint loc = glGetUniformLocation(shaderProgram,"modelviewMatrix");
glUniformMatrix4fv(loc, 1, GL_FALSE, (GLfloat*) &transformationMatrix);
glBindBuffer(GL_ARRAY_BUFFER, *model->vertexNormalBuffer);
//If I uncomment this line below all works wonderfully, but isnt the purpose of VBO of not uploading the same data again and again?
//glBufferData(GL_ARRAY_BUFFER, model->vertAndNormalArraySize * sizeof(GLfloat), model->vertAndNormalArray, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
renderChild(model, model);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Fighter::renderChild(ModelObject* model, ModelObject* parent)
{
//Recursively render the mesh children
for(int i = 0; i < model->nChildren; i++)
{
renderChild( dynamic_cast<ModelObject*>(model->children[i]), parent);
}
//Vertex and normal data are interlieved
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat),(void*)(model- >vertexDataPosition*sizeof(GLfloat)));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)((model->vertexDataPosition + 4)*sizeof(GLfloat)));
//Draws using two sets of indices
glDrawElements(GL_QUADS, model->nQuads * 4, GL_UNSIGNED_INT,(void*) model->quadsIndices);
glDrawElements(GL_TRIANGLES, model->nTriangles * 3, GL_UNSIGNED_INT, (void*) model->trisIndices);
}
这是你的问题:
model->vertexNormalBuffer = &buf;
/* ... */
glBindBuffer(GL_ARRAY_BUFFER, *model->vertexNormalBuffer);
您存储的是buf变量的地址,而不是其内容,然后在createBuffer
返回时它超出范围,并且很可能被其他数据覆盖,因此当您稍后渲染时,您将使用未初始化的缓冲区。只需将存储内容的buf
在你的vertexNormalBuffer
领域代替。
我承认我不知道为什么OpenGL仅仅因为这个原因就认为它是“内存不足”是恰当的,但是也许您只是在调用未定义的行为。但是,它的确说明了为什么在重新绑定后用数据重新填充缓冲区时,为什么它开始工作,因为您然后隐式初始化了刚绑定的缓冲区。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句