Как вызвать glDrawElements со статическими TexCoords и динамическими вершинами

Я использую вызов glDrawElements с VBO для визуализации моей сцены. Сцена - это ткань с вершинами и текстурными координатами - в этом примере я рисую флаг.

В моей сцене вершины динамические, что означает, что мне нужно записывать в VBO каждый кадр. Большая часть моей обработки выполняется на GPU с использованием CUDA, поэтому я постоянно сопоставляю память CPU с памятью GPU. Координаты текстуры, с другой стороны, являются статическими. Чтобы выполнить рендеринг с помощью glDrawElements (насколько я понимаю), я должен чередовать координаты текстуры в вершинах VBO, а затем просто вызывать glTexCoordPointer() и glEnableClientState(). Это не оптимально, потому что тогда мне нужно будет нарисовать все координаты текстуры при себе, когда я выполняю отображение памяти CPU<->GPU.

Есть ли способ организовать мое VBO таким образом, чтобы я мог обновить данные вершин в VBO, не касаясь данных текстуры в VBO? Ниже приведен мой код для рендеринга - у меня есть три массива: массив индекса, массив вершин и массив текстур.

В приведенном ниже коде indexVbo сопоставлен с массивом индекса, а vbo сопоставлен с массивом вершин. Теперь мне нужно включить текстуры. Любое понимание или предложения будут высоко оценены.

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, flagTexId);

glPushMatrix();
    glColor3f(1.0, 1.0, 1.0);

    glVertexPointer(4, GL_FLOAT, 0, 0);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // Render flag mesh
    glDrawElements(GL_TRIANGLES, numTriangles * 3, GL_UNSIGNED_INT, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix(); 

glDisable(GL_TEXTURE_2D);

1 ответ

Вы можете хранить отдельные VBO для обоих атрибутов вершины. Таким образом, вы можете даже пометить текс-координату как статическую, а другую как динамическую.

То, будет ли это на самом деле быстрее, зависит от многих факторов: драйвера, настройки памяти и т. Д. Преимущества наличия некоторой части данных в статической памяти могут перевесить преимущества наличия всей вершины в строке кэша (при перемежении). Но опять же, это не может быть. Тест на вашей целевой системе (ах), чтобы быть уверенным.

IMO, хороший аргумент для разделения атрибутов на разные VBO заключается в том, что это наиболее "естественное" представление ваших данных. Но я думаю, это зависит от личного вкуса и от того, позволите ли вы этому влиять на ваши программы:-)

Кстати, похоже, у вас есть небольшая ошибка: вам нужно связать правильный VBO перед gl*Pointer call (также ваши смещения и шаги не верны, если вы используете один VBO для своих вершин). Это также, как вы связываете отдельные VBO: просто выберите правильный перед gl*Pointer вызов:

glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex);
glVertexPointer(4, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_texcoord);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
Другие вопросы по тегам