Строить модель OpenGL параллельно? - PullRequest
3 голосов
/ 17 мая 2010

У меня есть программа, которая рисует некоторую местность и моделирует воду, протекающую по ней (дешевым и простым способом).

Обновление воды было легко распараллелить с помощью OpenMP, поэтому я могу делать ~ 50 обновлений в секунду. Проблема заключается в том, что даже при небольшом количестве воды количество обращений в секунду очень и очень низкое (начинается с 5 и падает до 2 после значительного количества воды).

Это не проблема с видеокартой, потому что ландшафт более сложный и прорисовывается настолько быстро, что boost::timer говорит мне, что я получаю бесконечное ничье в секунду, если отключаю воду. Это может быть связано с пропускной способностью памяти (так как я предполагаю, что модель остается на карте и не должна передаваться каждый раз).

Меня беспокоит то, что при каждом розыгрыше я звоню glVertex3f() примерно миллион раз (максимальный размер 450 * 600, 4 вершины в каждой), и это делается полностью последовательно, потому что Glut не позволяет я звоню что-нибудь параллельно.

Итак ... есть ли какой-то способ построить список параллельно, а затем сразу передать его OpenGL? Или какой-то другой способ заставить его рисовать это быстрее? Я использую неправильный метод (кроме очевидного «использовать меньше вершин»)?

Ответы [ 4 ]

8 голосов
/ 17 мая 2010

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

Как указал Георг: glVertexPointer() в сочетании с glDrawElements() или glDrawArrays() хорошо подходят для вашей ситуации, если этого недостаточно, вы должны подойти к объектам буфера вершин. Другой вариант - проводить вычисления непосредственно в графическом процессоре с помощью шейдеров. Во всех этих методах вы получаете паралич в GPU практически бесплатно.

7 голосов
/ 17 мая 2010

Меня беспокоит то, что при каждом розыгрыше я вызываю glVertex3f () примерно миллион раз

Взгляните на glVertexPointer().

4 голосов
/ 17 мая 2010

В дополнение к glVertexPointer вы также должны взглянуть на ARB_vertex_buffer_object, который поддерживается на большинстве современных аппаратных средств и в некоторых случаях может быть быстрее, чем массивы Vertex.

2 голосов
/ 17 мая 2010

glVertex () крайне неэффективен. Я даже не рисую один текстурированный квад (2D-изображение), используя glVertex ().
Вместо этого вот код, который должен сделать это проще:

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,vertCoords);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glTexCoordPointer(2,GL_FLOAT,0,texCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT,0,vertNorm);
glDrawElements(drawtype,tCount*3,GL_UNSIGNED_INT,tris);

Другой подход - использовать VBO, но это уже другая история.
Я надеюсь, что это поможет вам с вашим проектом. Если у вас есть еще вопросы, пожалуйста, задавайте. Я был бы рад ответить на вопрос об OpenGL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...