2013-07-18 171 views
1

我有以下几段代码,我成功地创建了一个顶点缓冲区对象,用数据初始化它,并使用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); 
} 
+0

您是否更改顶点数? 'glBufferSubData()'不能改变底层缓冲区存储的大小。 – derhass

+0

@derhass,我没有改变顶点的sie。顶点的数量和顶点的总大小保持不变,唯一改变的是顶点(x,y,z)值,我需要通知图形卡。 – ukaku

回答

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); 
} 
相关问题