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

1 に答える 1

0

updateVertexGLFx 関数を以下のコードに変更しました。これとの主な違いは、頂点情報を GL に再供給した後、gl*AtribPointer を使用して OpenGL にポインター オフセットを通知したことです。update 関数を呼び出すと、プログラムが確実に更新されるようになりました。

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 に答える