Понимание кода, используемого для рисования четырехугольников в ядре OpenGL 3.3+ с использованием треугольников

Я пытаюсь нарисовать квад для фона (2D), используя OpenGL 3.x+. Четверки устарели, поэтому цель состоит в том, чтобы использовать два треугольника, чтобы создать прямоугольник, который заполняет экран. Это работает, но я не уверен на все 100% здесь.

  1. Настроить

    GLuint positionBufferObject;
    GLfloat vertexPositions[] =
    {
        -1.0f, -1.0f, 0.0f, 1.0f,
        -1.0f,  1.0f, 0.0f, 1.0f,
         1.0f,  1.0f, 0.0f, 1.0f,
         1.0f, -1.0f, 0.0f, 1.0f,
        -1.0f, -1.0f, 0.0f, 1.0f,
    };
    glGenBuffers(1, &positionBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
    
    • Я понимаю vertexPositionsэто массив вершин.
    • glGenBuffers() говорит, я хочу 1 буфер и назначить идентификатор для &positionBufferObject?
    • glBufferData() загружает vertexPositions в память графического процессора; но как он узнал, что нужно было загрузить его, так как я не дал ему удостоверение личности?
  2. Рисовать

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);
    glDisableVertexAttribArray(0);
    
    • glEnableVertexAttribArray() просто говорит, что я буду рисовать с массивом 0?
    • glDrawArrays() - что если я хочу нарисовать два массива вершин? Как он узнает, какие из них визуализировать? Он знает, что из приведенной выше команды?
    • Не уверен что glVertexAttribPointer() делает?
    • glDrawArrays() ясно.
  3. Очистить, я думаю, что это правильно?

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDeleteBuffers(1, &positionBufferObject);
    

    Я делаю настройку / очистку только один раз.

Бонусные очки:

  • Это самый эффективный способ сделать это? Я читал, что я предполагаю, что отправляю и выполняю рендеринг в "пакетах" [?], Так как 3.x + больше не выполняет немедленный режим. Существует также только один массив, поэтому пакеты не будут влиять на производительность в этом случае, но если бы я сказал "очень большое количество" vertxArrays для рисования, это был бы тот же процесс?
  • В настройках они хранят идентификатор массива как positionBufferObject, но жестко кодируют его в цикле рендеринга. Кажется, что после дюжины массивов может возникнуть путаница, почему не стоит использовать переменную вместо ее жесткого кодирования?

2 ответа

Решение

glGenBuffers(1, &positionBufferObject); говорит "сделать объект буфера вершин, и positionBufferObject это его идентификатор. "

glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); говорит "positionBufferObject сейчас текущий GL_ARRAY_BUFFER".

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); говорит "загрузить vertexPositions к идентификатору в настоящее время связан с GL_ARRAY_BUFFER (который positionBufferObject) ".

glEnableVertexAttribArray(0); говорит "массив атрибутов вершины 0 теперь доступен для использования."

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); говорит "массив атрибутов вершины 0 должен интерпретироваться как состоящий из групп из 4-х чисел".

glDrawArrays(GL_TRIANGLE_STRIP, 0, 5); говорит "нарисуйте треугольную полосу с пятью индексами из каждого включенного массива".

glDisableVertexAttribArray(0); говорит: "Мы закончили с массивом атрибутов вершины 0".

В ответ на вопрос user697111 о нескольких массивах, это довольно просто.

Каждый атрибут вершины должен быть связан с буферным объектом. Вместо того, чтобы указывать объект буфера с помощью glVertexAttribPointer, связь выполняется через GL_ARRAY_BUFFER. Когда вы вызываете glVertexAttribPointer (или любой вызов gl*Pointer), буфер, который в настоящее время привязан к GL_ARRAY_BUFFER, будет использоваться в качестве источника для этого атрибута. Итак, рассмотрим следующее:

glBindBuffer(GL_ARRAY_BUFFER, myPositionData);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, ..., 0);
glBindBuffer(GL_ARRAY_BUFFER, myColorData);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, ..., 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(...);

Атрибут 0 будет получен из объекта буфера myPositionDataи атрибут 1 будет получен из объекта буфера myColorData, Тот факт, что я отменил привязку к GL_ARRAY_BUFFER перед вызовом glDrawArrays не изменяется, откуда берутся данные для этих атрибутов.

Другие вопросы по тегам