为什么此顶点缓冲区对象无法更新
Why does this vertex buffer object fails to Update?
我有以下几段代码,其中我成功地创建了一个顶点缓冲区对象,用数据初始化它,并使用GLSL 4.0渲染它。但是,当我在动画后更新存储在顶点中的数据时,OpenGL会给我错误代码0x502,并且不接受我更新的顶点信息。
有人能告诉我为什么这些代码不允许我的顶点信息成功更新吗?我还应该提到,有时,成功更新的数据并不总是一致/可预测的。
使用的数据结构
struct Vertex3{
glm::vec3 vtx; //0
glm::vec3 norm; //3
glm::vec3 tex; //6 Use for texturing or color
};
vector<Vertex3> geometry.vertices3;
初始化代码
void solidus::Mesh::initVBO(){
geometry.totalVertexCount = geometry.getVertexCount();
// Allocate an OpenGL vertex array object.
glGenVertexArrays(1, &vertexArrayId);
glGenBuffers(2,geometry.vboObjects);
// Bind the vertex array object to store all the buffers and vertex attributes we create here.
glBindVertexArray(vertexArrayId);
glBindBuffer(GL_ARRAY_BUFFER, geometry.vboObjects[VERTEX_DATA]);
//size the size of the total vtx
GLuint byte_size = getTotalSize();
//Reserve the inital space for the vertex data
glBufferData(GL_ARRAY_BUFFER, byte_size, NULL, GL_STREAM_DRAW);
if(geometry.isStructVertex4())
initVBO4( );
else if(geometry.isStructVertex3())
initVBO3( );
else
initVBO2( );
//release
glBindVertexArray(0);
geometry.vertices4.clear();
//geometry.vertices3.clear();
geometry.vertices2.clear();
}
void solidus::Mesh::initVBO3( ){
//getTotalSize() == getVtxCount() * sizeof(Vertex3);
glBufferSubData(GL_ARRAY_BUFFER, 0, getTotalSize(), &geometry.vertices3[0]);
//Note: offsetof -- c++ standard library
//Note: glVertexAttribPointer- first parameter is location of GLSL variable
glEnableVertexAttribArray(0); // Vertex4 position
glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3), (GLvoid*)offsetof(Vertex3,vtx) );
// Vertex4 normal
glEnableVertexAttribArray(1);
glVertexAttribPointer( (GLuint)1, 3, GL_FLOAT, GL_TRUE, sizeof(Vertex3), (GLvoid*)offsetof(Vertex3,norm) );
// Texture coords
glEnableVertexAttribArray(2);
glVertexAttribPointer( (GLuint)2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3),(GLvoid*)offsetof(Vertex3,tex) );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry.vboObjects[INDEX_DATA]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*geometry.indices.size(), &geometry.indices[0], GL_STATIC_DRAW);
}
更新网格顶点信息为什么失败
void solidus::Mesh::uploadVertexGLFx(){
glBindBuffer(GL_ARRAY_BUFFER, geometry.vboObjects[VERTEX_DATA]);
string e0="";
if(geometry.isStructVertex2()){
solidus::GLVBO::setVBOSubData(getTotalSize (), &geometry.vertices2[0]);
e0="Vertex2";
}else if(geometry.isStructVertex3()){
//THIS IS THE POINT OF INTEREST: at least suspected!!!!!
// getVtxCount() * sizeof(Vertex3) = getTotalSize
glBufferSubData(GL_ARRAY_BUFFER, 0, getTotalSize (), &geometry.vertices3[0]);
e0="Vertex3";
}else {
solidus::GLVBO::setVBOSubData(getTotalSize (), &geometry.vertices4[0]);
e0="Vertex4";
}
//report error is glGetError is not equal to 0
postMsg("failed to upload vertex for struct " + e0 , "uploadVertexGLFx",30);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
我将updateVertexGLFx函数修改为下面列出的代码。与这种好的主要区别在于,在我将顶点信息重新提供给GL后,我使用GL*AtribPointer通知OpenGL指针偏移。现在,当我调用更新函数时,程序会可靠地更新。
void solidus::Mesh::uploadVertexGLFx(){
glBindBuffer(GL_ARRAY_BUFFER, geometry.vboObjects[VERTEX_DATA]);
string e0="";
if(geometry.isStructVertex2()){
solidus::GLVBO::setVBOSubData(getTotalSize (), &geometry.vertices2[0]);
e0="Vertex2";
}else if(geometry.isStructVertex3()){
//glBufferData(GL_ARRAY_BUFFER, getTotalSize (), NULL, GL_STREAM_DRAW);
//THIS IS THE POINT OF INTEREST: at least suspected!!!!!
// getVtxCount() * sizeof(Vertex3) = getTotalSize
cout << "Total Size = " << getTotalSize() <<endl;
cout << "Vtx Count = " << getVtxCount() << endl;
cout << "Sizeof(Vertex3)=" <<sizeof(Vertex3)<<endl;
Vertex3 *f = new Vertex3[getVtxCount()];
for(int i=0; i<getVtxCount();i++){
f[i] = geometry.vertices3[i];
}
glBufferData(GL_ARRAY_BUFFER, getTotalSize(), NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, getTotalSize (), f);
//Note: glVertexAttribPointer- first parameter is location of GLSL variable
glEnableVertexAttribArray(0); // Vertex4 position
glVertexAttribPointer( (GLuint)0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3), (GLvoid*)offsetof(Vertex3,vtx) );
// Vertex4 normal
glEnableVertexAttribArray(1);
glVertexAttribPointer( (GLuint)1, 3, GL_FLOAT, GL_TRUE, sizeof(Vertex3), (GLvoid*)offsetof(Vertex3,norm) );
// Texture coords
glEnableVertexAttribArray(2);
glVertexAttribPointer( (GLuint)2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3),(GLvoid*)offsetof(Vertex3,tex) );
delete f;
f = nullptr;
e0="Vertex3";
}else {
solidus::GLVBO::setVBOSubData(getTotalSize (), &geometry.vertices4[0]);
e0="Vertex4";
}
//report error is glGetError is not equal to 0
postMsg("failed to upload vertex for struct " + e0 , "uploadVertexGLFx",30);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
相关文章:
- 传递 std::vector of std::shared_ptr,而不是更新对象
- 我可以更新数组中的对象吗?
- Box2D World.GetBodyList() 返回 NULL,但 World 显然正在更新对象
- 无法更新属于列表中节点的对象中的值
- 如何确保我的"ifstream"文件对象指向的文件内容已更新?
- 当对象在屏幕空间中较小时,OpenGL 更新缓慢
- 如何更新对象的属性
- 有没有办法在更改与 HDC 关联的位图大小后更新图形对象?
- 更新对象中的值不起作用
- C++ 列表中的对象变量在迭代过程中不会更新
- OpenGL-缓冲区更新下一个渲染对象
- C++:使用父类运算符函数更新子类对象的继承变量
- 更新对象的属性时遇到问题?
- C++(煤渣):无法在 keyDown 函数中更新对象的属性
- 当我在C++中字符串更新对象记录时,用垃圾值更新了文件
- 获取和设置不更新对象
- 如何使用Boost序列化更新对象
- 四叉树更新对象失败
- C++使用set函数更新对象属性
- 返回新分配的指针或通过参数更新对象