Как вызвать 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);