glMultiDrawElementsIndirect

  
#include 
#include 
#include 

struct DrawCommand {
    uint32_t indexCount;
    uint32_t instanceCount;
    uint32_t baseIndex;
    uint32_t baseVertex;
    uint32_t baseInstance;
};

struct Mesh {
    uint32_t indexCount;
    uint32_t baseIndex;
    uint32_t baseVertex;
};

int main()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "glMultiDrawElementsIndirect", NULL, NULL);
    glfwMakeContextCurrent(window);

    gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
    glViewport(0, 0, 800, 600);

    GLuint VAO, VBO, EBO, IBO;

    GLfloat vertices[] = {
            -0.25f, -0.5f, 0.0f,  // Square 1
            0.25f, -0.5f, 0.0f,
            0.25f,  0.5f, 0.0f,
            -0.25f, 0.5f, 0.0f,

            -0.75f, -0.25f, 0.0f, // Triangle 2
            -0.25f, -0.25f, 0.0f,
            -0.5f,  0.25f, 0.0f,

            0.25f,  -0.25f, 0.0f, // Triangle 3
            0.75f,  -0.25f, 0.0f,
            0.5f,    0.25f, 0.0f
    };

    GLuint indices[] = {
        0, 1, 2, 2, 0, 3,  // Square 1
        0, 1, 2,  // Triangle 2
        0, 1, 2   // Triangle 3
    };

    std::vector meshes;
    meshes.push_back({ 6, 0, 0 });
    meshes.push_back({ 3, 6, 4 });
    meshes.push_back({ 3, 9, 7 });

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    glGenBuffers(1, &IBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);

    glBindVertexArray(0);

    while (!glfwWindowShouldClose(window)) {

        std::vector commands(meshes.size());
        for (int i = 0; i < meshes.size(); i++) {
            commands[i].indexCount = meshes[i].indexCount;
            commands[i].baseIndex= meshes[i].baseIndex;
            commands[i].baseVertex = meshes[i].baseVertex;
            commands[i].instanceCount = 1;
            commands[i].baseInstance = 0;
        }
        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, IBO);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand) * commands.size(), &commands[0], GL_STATIC_DRAW);

        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.2f, 0.2f, 0.2f, 1.0f);

        glBindVertexArray(VAO);
        glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (GLvoid*)0, commands.size(), 0);
        glBindVertexArray(0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();

    return 0;
}
  

edit this page