为什么这个顶点缓冲区对象无法更新?

时间:2013-07-18 02:12:36

标签: c++ opengl jquery-animate vertex-buffer

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

1 个答案:

答案 0 :(得分: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);
}