1

私は OpenGL を学んでいて、「障害」に遭遇しました。インデックスバッファを使用していくつかの家 (ブロックとピラミッド) を描きました。これは、(すべての家からの) すべての頂点を頂点バッファーにロードし、1 つの大きなインデックスバッファーを使用する場合にうまく機能します。ここで、オブジェクトを 1 つずつアニメートし、頂点バッファに 1 つずつロードして、オブジェクトを 1 つずつ変換できるようにします。コードは 1 つの大きなバッファーと大差ありませんが、これを実行すると、ランダムな形状が画面上で動き回るのが見えます。私のコードは次のとおりです。

3D オブジェクトのリストを保持するワールド クラスがあり、すべての頂点の 1 つの大きなリスト (試行用)、インデックスの 1 つの大きなリスト (これも試行用)、および Object3D オブジェクトをワールドに追加するメソッドがあります。

class World
{
public:
World();
~World();

vector<Object3D> objects;
vector<glm::vec3> Vertices;
vector<GLushort> Indices;

void AddObject(Object3D &object);

};

Object3D クラス:

class Object3D
{
public:
Object3D();
~Object3D();

glm::vec3 Position;
vector<glm::vec3> Vertices;
vector<unsigned int> Indices;
};

World AddObject メソッドは、単にオブジェクトを「オブジェクト」リストに追加し、頂点とインデックスを「頂点」リストと「インデックス」リストに追加して、1 つの大きなバッファーを作成します。

void World::AddObject(Object3D &object) {

int oldVerticesSize = Vertices.size();
objects.push_back(object);
Vertices.insert(Vertices.end(), object.Vertices.begin(), object.Vertices.end());

for each (GLushort index in object.Indices)
{
    Indices.push_back(index + oldVerticesSize);
}
}

すべての頂点とインデックス (以下に示すように) を含む大きなバッファーをレンダリングすると、正常に動作します。

void WorldRenderer::Render()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBindVertexArray(Vao); //use vao
glDrawElements(GL_TRIANGLES, World.Indices.size(), GL_UNSIGNED_SHORT, 0);
//glDrawArrays(GL_TRIANGLES, 0, World.Vertices.size());
glBindVertexArray(0); //release vao

//Model = glm::rotate(Model, 0.01f, glm::vec3(0.0f, 1.0f, 0.0f));
Mvp = Projection * View * Model;

glUniformMatrix4fv(UniformMvp, 1, GL_FALSE, glm::value_ptr(Mvp));
glutSwapBuffers();

//glutPostRedisplay();

}

オブジェクトをループして、オブジェクトの頂点を一度に 1 つのオブジェクトずつバッファにロードすると (以下に示すように)、ランダムな「形状」が表示されます。ここで何が間違っていますか?アドバイスをよろしくお願いします。

void WorldRenderer::Render()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

int index = 0;
for each (Object3D mesh in World.objects)
{
    Mvp = Projection * View * Model;

    UpdateBuffer(mesh.Vertices, mesh.Indices);

    glBindVertexArray(Vao); //use vao
    glDrawElements(GL_TRIANGLES, mesh.Indices.size() , GL_UNSIGNED_SHORT, 0);
    glBindVertexArray(0); //release vao
    glUniformMatrix4fv(UniformMvp, 1, GL_FALSE, glm::value_ptr(Mvp));
    index++;
}

glutSwapBuffers();
}

UpdateBuffers メソッド:

void WorldRenderer::UpdateBuffer(vector<glm::vec3> vertices, vector<unsigned int> indices) {

//fill Vbo
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

//fill ibo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

glBindVertexArray(Vao);
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ibo);
}

最初の Render メソッド (ループなし) では、バッファーは次のように init メソッドで 1 回作成されます。

void WorldRenderer::Init(int argc, char ** argv) {
InitGlutGlew(argc, argv);
InitMatrices();

glDisable(GL_CULL_FACE);
//-------------- init buffers --------------
// vbo vertices
glGenBuffers(1, &Vbo);
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
glBufferData(GL_ARRAY_BUFFER, World.Vertices.size() * sizeof(glm::vec3),
    &World.Vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//ibo
glGenBuffers(1, &Ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, World.Indices.size() * sizeof(unsigned int),
    &World.Indices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

// VAO setup
glGenVertexArrays(1, &Vao);
glBindVertexArray(Vao);
// Bind vertices to vao
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
//Bind elements
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Ibo);

//------ init shaders -----------
InitShader();
}
4

1 に答える 1