2013-07-18 4 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); 

} 

Обновить информацию Mesh Vertex почему это не в состоянии

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, я сообщил OpenGL о смещении указателя, используя gl * AtribPointer. Теперь программа надежно обновляется при вызове моей функции обновления.

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); 
}