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

1 回答 1

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);
}
于 2013-07-18T18:18:02.450 回答