繁体   English   中英

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

[英]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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM