0

私は小さなプロジェクトを開発しており、VBO、IBO、VAO を使用しています。頂点の配列とそれぞれの配列インデックスがあります。マテリアルについても同じことを行います (同じ頂点が反対側に異なるマテリアルを持つことができるため)。 ) しかし、同じ VAO のこのリンクには何も表示されません。すべての VAO は IBO でなければならないのですか?

添付されているのは、gpu とレンダリングにそれぞれデータを送信する私のコードです!

私はあなたの助けに感謝します、挨拶:)

void Upload(){
    GLuint ibo[2], vbo[3];

    glGenBuffers(3, vbo);
    glGenBuffers(2, ibo);
    glGenVertexArrays(1, vao);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); //Vertices
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec3), vertices.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); //Normales
    glBufferData(GL_ARRAY_BUFFER, vertex_normal.size()*sizeof(vec3), vertex_normal.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, v_indices.size()*sizeof(GLuint), v_indices.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); //Material
    glBufferData(GL_ARRAY_BUFFER, materials.size()*sizeof(Material), materials.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size()*sizeof(GLuint), m_indices.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glBindVertexArray(vao[0]);
    //Vertices:
    glEnableVertexAttribArray(attrib_vertex);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glVertexAttribPointer(attrib_vertex, 3, GL_FLOAT, GL_FALSE, 0, 0);
    //Normales:
    glEnableVertexAttribArray(attrib_normal);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, 0, 0);
    //IBO:
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]);

    //Materiales:
    for(int i=0; i<5; ++i)
        glEnableVertexAttribArray(attrib_material+i);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
    glVertexAttribPointer(attrib_material, 4, GL_FLOAT, GL_FALSE, sizeof(Material), NULL);
    glVertexAttribPointer(attrib_material+1, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, diffuse));
    glVertexAttribPointer(attrib_material+2, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, specular));
    glVertexAttribPointer(attrib_material+3, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, emission));
    glVertexAttribPointer(attrib_material+4, 1, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, shininess));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]);

    //Desactivando todo:
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(attrib_vertex);
    glDisableVertexAttribArray(attrib_normal);
    for(int i=0; i<5; ++i)
        glDisableVertexAttribArray(attrib_material+i);
}
void Draw(){
    glBindVertexArray(vao[0]);
    glDrawElements(GL_TRIANGLES, v_indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}
4

1 に答える 1

1

各 VAO は、現在の の値を格納しますGL_ELEMENT_ARRAY_BUFFER_BINDING

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0])その保存された値は、 およびを呼び出したときに設定されますglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1])

コードの問題は、 への 2 回目の呼び出しがglBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...)、最初の呼び出しで格納された値を上書きしていることです。これは、各 VAO が に対して 1 つの値しか格納できないために発生しGL_ELEMENT_ARRAY_BUFFER_BINDINGます。つまり、VAO ごとに許可される IBO は 1 つだけです。

私が提案するいくつかの解決策:

  • メッシュ内のインデックスと一致するように、マテリアル データを別の方法で保存できます。これは、材料データを複製する必要があることを意味する場合があります。
  • マテリアル データをユニフォーム バッファに格納してから、マテリアル データのインデックスを各頂点の頂点属性としてユニフォーム バッファ内に格納できます。
  • マテリアルが照明情報を定義しているようです。レンダリングを複数のパスに分割できるかもしれません。(つまり、アンビエント パス、ディフューズ パス、スペキュラー パス...) ディファード ライティングのようなレンダリング方法では、これは問題になりません。
  • 頂点のインデックスとマテリアルを 1 つの大きな IBO に結合できます。(私が言及した他の方法と組み合わせて動作する可能性があります。)
  • glVertexAttribDivisorデータがパターンに適合する場合は、使用できる可能性があります。

いずれにせよ、中心的な問題は、VAO ごとに 1 つの IBO しか持てないことです。用途に合ったソリューションを見つけるには、創造性を発揮する必要があります。幸運を!

于 2014-08-05T09:54:52.107 に答える