4

この「モデル」クラスを作成して、.obj ファイルをロードし、それらのデータを VBO に割り当てました。そのコードは次のようなものです: (VAO を使用していないことに注意してください)

class Model {...}

void Model::LoadOBJ(const char *file)
{
    //load vertices, normals, UVs, and put them all in _vec, which is a private data member of std::vector<glm::vec3>
    ...

    //if an .obj file is loaded for the first time, generate a buffer object and bind it
    if(glIsBuffer(_vbo) == GL_FALSE)
    {
        glGenBuffers(1, &_vbo);//_vbo is a private data member
        glBindBuffer(GL_ARRAY_BUFFER, _vbo);
    }
    
    //load the data in the array buffer object
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * _vec.size(), &_vec[0][0], GL_STATIC_DRAW);
}

void Model::Draw()
{
    glBindBuffer(GL_ARRAY_BUFFER, _vbo);
    glDrawArrays(GL_TRIANGLES, 0, _numVertices);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

私は、次のコードが 2 つの異なるオブジェクトをレンダリングするのにうまく機能すると考えていました。

void init()
{
    //vao dummy (?)
    GLuint VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    //load 3d models
    Model cube = load("cube.obj");
    Model cow = load("cow.obj");

    //the next two lines should be valid for both objects?
    glVertexAttribPointer(prog.GetAttribLocation("vertex"), 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(prog.GetAttribLocation("vertex"));
}

void render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    //draw cube:
    //some matrix transformations
    ...
    cube.Draw();

    //draw cow:
    //some matrix transformations
    ...
    cow.Draw()

    glutSwapBuffers();
}

しかし、OpenGL は 2 つの牛または 2 つの立方体を描画するだけであることがわかりました。(init() で最後にロードしたモデルによって異なります) 二頭の牛 2 つの立方体

ところで、最初の画像では、opengl が 2 頭の牛を描画しようとしたことは確かですが、glDrawArrays() 関数は立方体に必要な量の頂点で呼び出されました。

それで、私は何が欠けていますか?バッファ オブジェクトごとに異なる VAO が必要ですか?

4

2 に答える 2

2

バッファーをバインドした後、頂点属性コード (設定および有効化) を描画関数に移動する必要があります。これらの呼び出しは、現在バインドされているバッファーに作用します。

モデルごとに異なる vaos を使用する場合、属性データは vao に保存され、新しいオブジェクトを描画するたびに属性を再バインドする必要はありません (vao を変更するだけです)。

于 2014-12-14T21:21:56.270 に答える