我一直在尝试使用顶点缓冲区对象来保存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);
}
Run Code Online (Sandbox Code Playgroud)
这是你的问题:
model->vertexNormalBuffer = &buf;
/* ... */
glBindBuffer(GL_ARRAY_BUFFER, *model->vertexNormalBuffer);
Run Code Online (Sandbox Code Playgroud)
你正在存储你的buf变量的地址,而不是它的内容,然后它在createBuffer返回时会超出范围,很可能被其他数据覆盖,所以当你以后渲染时,你正在使用一个未初始化的缓冲区.只需将存储内容的buf在你的vertexNormalBuffer领域代替.
我承认我不知道为什么OpenGL认为只是因为它而"缺乏内存"才适当,但也许你只是在调用未定义的行为.但是,它确实解释了为什么在重新绑定数据后用数据重新填充缓冲区时它开始工作,因为然后隐式初始化刚刚绑定的缓冲区.
| 归档时间: |
|
| 查看次数: |
1313 次 |
| 最近记录: |