Экземпляры кубов рядом друг с другом OpenGL - PullRequest
1 голос
/ 05 апреля 2020

Я попытался собрать множество кубиков рядом друг с другом.

Насколько я понимаю, мне нужно создать MVP матрицу для каждого куба и связать ее, а затем каким-то образом изменить положение. затем запустите это в a для l oop, сколько кубиков вы хотите.

Это то, что я пробовал:

while (!glfwWindowShouldClose(window)) {
    glClearColor(0.0f / 255.0f, 170.0f / 255.0f, 204.0f / 255.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(programID);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
        0,
        3, GL_FLOAT, GL_FALSE,
        0,
        (void*)0
    );

    computeMatricesFromInputs();
    glm::mat4 ProjectionMatrix = getProjectionMatrix();
    glm::mat4 ViewMatrix = getViewMatrix();
    glm::mat4 ModelMatrix = glm::mat4(1.0);
    glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

    for (int i = 0; i == cubes; i++) {
        GLuint MatrixID = glGetUniformLocation(programID, "MVP");
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
        glDrawArraysInstanced(GL_TRIANGLES, 0, 1, i);
    }

    //GLuint MatrixID = glGetUniformLocation(programID, "MVP");
    //glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
    //glDrawArrays(GL_TRIANGLES, 0, 12*3);
    glDisableVertexAttribArray(0);

    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, texturebuffer);
    glVertexAttribPointer(
        1,
        2,
        GL_FLOAT,
        GL_FALSE,
        0,
        (void*)0
    );
    glfwSwapBuffers(window);
    glfwPollEvents();
}

Это не рисует никаких кубов в все, и я не могу понять, как я изменил бы положение для каждого куба, чтобы быть рядом друг с другом. Итак, почему этот код не рисует экземпляры кубов и как я могу изменить положение каждого куба, чтобы он располагался рядом друг с другом?

1 Ответ

1 голос
/ 05 апреля 2020

3-й параметр glDrawArraysInstanced - это количество вершин, которые вы хотите нарисовать, соответственно, куба (точно так же, как glDrawArrays), 4-й - это число экземпляры должны быть нарисованы одним вызовом отрисовки, а не индексом экземпляра.

В любом случае Вам вообще не нужно glDrawArraysInstanced, потому что вы рисуете каждый куб в отдельности. Используйте glDrawArrays вместо:

for (int i = 0; i < cubes; i++) {
    GLuint MatrixID = glGetUniformLocation(programID, "MVP");
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
    glDrawArrays(GL_TRIANGLES, 0, noOfVertices);
}

Это может быть заменено на glDrawArraysInstanced:

glDrawArraysInstanced(GL_TRIANGLES, 0, noOfVertices, cubes); 

Это будет рисовать все кубы cubes одновременно , Чтобы это работало, вам нужно найти способ использовать разные матрицы моделей для каждого экземпляра.
Одна из возможностей - использовать объект буфера хранилища шейдеров (SSBO) , чтобы хранить все матрицы моделей. в массиве. В вершинном шейдере индекс экземпляра (индекс куба) можно получить с помощью встроенного ввода gl_InstanceID. Эту переменную можно использовать для получения правильной модели матрицы для экземпляра массива.

Например:

layout(std430) buffer Matrices
{
    mat4 mvpArray[];
};

void main()
{
    mat4 mvp = mvpArray[gl_InstanceID];

    // [...]
}
...