Как вызвать glDrawElements со статическими TexCoords и динамическими вершинами - PullRequest
1 голос
/ 13 апреля 2011

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

В моей сцене вершины являются динамическими, что означает, что мне нужно записывать в VBO каждый кадр.Большая часть моей обработки выполняется на GPU с использованием CUDA, поэтому я постоянно отображаю память процессора в память 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 Ответ

3 голосов
/ 13 апреля 2011

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

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

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

Кстати, похоже, у вас небольшая ошибка: вам нужно связать правильный VBO до gl*Pointercall (также ваши смещения и шаги не верны, если вы используете один 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);
...