OpenGL, Java, LWJGL - Рисование нескольких треугольников с использованием IBO, VBO и VAO - PullRequest
1 голос
/ 09 апреля 2020

Я пытаюсь визуализировать два треугольника на экране одновременно, используя два разных VBO, чтобы я мог добавить текстуры позже (насколько я понимаю, если вы хотите добавить разные текстуры, вы должны сделать два VBO?). Я попытался использовать комбинацию VAO (оба примера) и VAO и IBO (1-й пример).

Редактировать: так как Stackoverflow не распознает тег, я хотел бы уточнить, что IBO обозначает индексный буфер Объект

В обоих случаях я получаю пустой красный экран.

Ранее мне удавалось нарисовать четыре треугольника на экране, используя только одно VBO и одно IBO, но без VAO, помещая все вершины в одном VBO, однако я чувствую, что мне нужно научиться рисовать несколько VBO, так как все в одном VBO станет громоздким и неэффективным по мере добавления большего числа объектов.

Я уже консультировался с другими связанные вопросы, а также несколько учебных пособий, но не смогли найти в них нужную мне информацию (учебные пособия, предназначенные только для описания рисунка одного предмета)

https://learnopengl.com/Getting-started/OpenGL

https://www.lwjgl.org/guide

OpenGL - VAO, VBO, IBO, glDrawElements не отображаются

Какова роль glBind VertexArrays против glBindBuffer и каковы их отношения?

Текстурированные треугольники с OpenGL с использованием VBO / IBO

Вот мой исходный код:

Render l oop

private void setupLoop() {
        GL.createCapabilities();
        debugProc = GLUtil.setupDebugMessageCallback();

        // Set the clear color
        glClearColor(1.0f, 0.0f, 0.0f, 0.0f);

        while (!glfwWindowShouldClose(window)) {
            Engine.makeAndDrawBuffersForTwoTriangles();

            renderLoop();
        }
    }

    private void renderLoop() {
        // Run the rendering loop until the user has attempted to close
        // the window or has pressed the ESCAPE key.
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer

        glViewport(0, 0, width, height);
        glMatrixMode(GL_PROJECTION);
        float aspect = (float) width / height;
        glLoadIdentity();
        glOrtho(-aspect, aspect, -1, 1, -1, 1);

        glfwSwapBuffers(window); // swap the color buffers

        // Poll for window events.
        glfwPollEvents();
    }

Определение моих вершин и объявление моих идентификаторов

static int vbo_left;
static int vao_left;
static int ibo_left;
static float left_vertices[] = { -0.5f, 0f, -0.25f, 0.5f, 0f, 0f };
static int left_indices[] = { 0, 1, 2, 3, 4, 5 };

static int vbo_right;
static int vao_right;
static int ibo_right;
static float right_vertices[] = { 0f, 0f, 0.25f, -0.5f, 0.5f, 0f };
static int right_indices[] = { 0, 1, 2, 3, 4, 5 };

1-й класс двигателя

public static void makeAndDrawBuffersForTwoTriangles() {
    // VBO
    vbo_left = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
    glBufferData(GL_ARRAY_BUFFER, left_vertices, GL_STATIC_DRAW);
    // IBO
    ibo_left = glGenBuffers();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_left);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
            (IntBuffer) BufferUtils.createIntBuffer(left_indices.length).put(left_indices).flip(), GL_STATIC_DRAW);
    glVertexPointer(2, GL_FLOAT, 0, 0L);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    // VAO
    vao_left = glGenVertexArrays();
    glBindVertexArray(vao_left);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
    glBindVertexArray(0);

    // VBO
    vbo_right = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vbo_right);
    glBufferData(GL_ARRAY_BUFFER, right_vertices, GL_STATIC_DRAW);
    // IBO
    ibo_right = glGenBuffers();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_right);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
            (IntBuffer) BufferUtils.createIntBuffer(right_indices.length).put(right_indices).flip(),
            GL_STATIC_DRAW);
    glVertexPointer(2, GL_FLOAT, 0, 0L);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    // VAO
    vao_right = glGenVertexArrays();
    glBindVertexArray(vao_right);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_right);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
    glBindVertexArray(0);

    // Unbind all
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // Draw elements
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_left);
    glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
    glDrawElements(GL_TRIANGLES, left_indices.length, GL_UNSIGNED_INT, 0L);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_right);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_right);
    glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);
    glDrawElements(GL_TRIANGLES, right_indices.length, GL_UNSIGNED_INT, 0L);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    /*
    // Draw Arrays
    glBindVertexArray(vao_left);
    glDrawArrays(GL_TRIANGLES, 0, left_indices.length);
    glBindVertexArray(vao_right);
    glDrawArrays(GL_TRIANGLES, 0, right_indices.length);
    glBindVertexArray(0);
    */

2-й класс двигателя

    public static void makeAndDrawBuffersForTwoTriangles() {
        vbo_left = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
        glBufferData(GL_ARRAY_BUFFER, left_vertices, GL_STATIC_DRAW);

        vao_left = glGenVertexArrays();
        glBindVertexArray(vao_left);
        glBindBuffer(GL_ARRAY_BUFFER, vao_left);
        glVertexAttribPointer(vao_left, 2, GL_FLOAT, false, 2, 0);
        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        vbo_left = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
        glBufferData(GL_ARRAY_BUFFER, left_vertices, GL_STATIC_DRAW);

        vao_left = glGenVertexArrays();
        glBindVertexArray(vao_left);
        glBindBuffer(GL_ARRAY_BUFFER, vao_left);
        glVertexAttribPointer(vao_left, 2, GL_FLOAT, false, 2, 0);
        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(vao_left);
        glDrawArrays(GL_TRIANGLES, 0, left_vertices.length);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(vao_right);
        glDrawArrays(GL_TRIANGLES, 0, right_vertices.length);

    }

1 Ответ

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

Связывание индексных буферов указано в объекте Vertex Array . Вызов glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); нарушает привязку индексного буфера к VAO.
Вы должны удалить glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);. Кроме того, спецификация вершины сохраняется в VAO, поэтому VAO необходимо связать до того, как будет задан массив обобщенных данных атрибута вершины c и индексный буфер будет привязан:

// VBO
vbo_left = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glBufferData(GL_ARRAY_BUFFER, left_vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

// IBO
ibo_left = glGenBuffers();

// VAO
vao_left = glGenVertexArrays();
glBindVertexArray(vao_left);

// IBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_left);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
    (IntBuffer) BufferUtils.createIntBuffer(left_indices.length).put(left_indices).flip(), GL_STATIC_DRAW);

// vertex specification
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_left);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 2, 0);

Примечание. по сравнению с индексным буфером привязка буфера массива является глобальным состоянием.
Каждый атрибут, который указан в векторе состояния VAO, может относиться к другому ARRAY_BUFFER. Эта ссылка сохраняется при вызове glVertexAttribPointer (соответственно glVertexPointer). Затем буфер, который в настоящее время привязан к цели ARRAY_BUFFER, ассоциируется с атрибутом, а имя (значение) объекта сохраняется в векторе состояний VAO.
Но буфер индекса является состоянием VAO , Когда буфер связан с целью ELEMENT_ARRAY_BUFFER, тогда этот буфер ассоциируется с объектом массива вершин, который в данный момент связан.

...