ПрограммированиеФорумГрафика

Не выходит подружить OpenMP и OpenGL.

#0
10:09, 10 фев 2013

Здравствуйте.
Поиск не дал результата, надеюсь на подсказку.
Суть проблемы: рисую большой массив кубиков (15миллионов).
Каждый кубик рисует функция

Box() 
{
 glBegin(GL_QUADS); 
 ...
 glVertex3f(...);
 ...
 glEnd()
}
Массив кубов русует функция
Array()
{
  for (int i=0; i<Nx; i++)
     for (int j=0; j<Ny; j++)
        for (int k=0; k<Nz; k++)
          box();      
}

В таком виде все работает как надо.
Теперь хочу распараллелить с помощью OpenMP, array() модифицируется (хотябы цикл по i...)

Array()
{
  #pragma omp parallel for 
  for (int i=0; i<Nx; i++)
     for (int j=0; j<Ny; j++)
        for (int k=0; k<Nz; k++)
          box();      
}

в итоге рисуется только 1/4 часть (только один из потоков).
Пробовал выносить glBegin, glEnd в array() - та же ситуация
чувствую что где-то концептуально ошибка и не пойму где :(
спасибо за советы

#1
10:16, 10 фев 2013

OpenGL. Он не многопоточен, он потоко-безопасный.

#2
10:18, 10 фев 2013

Значит плохо дело :(
Задача носит для меня прикладной характер, поэтому сильно углубляться не хотелось бы.
Есть несложный способ ускорить отрисовку?

#3
10:34, 10 фев 2013

отрисовка с помощью
glBegin(...);
glVertex3f(...);
glEnd();
- очень неэффективный способ
лучше использовать glDrawArrays/glDrawElements, а еще лучше расширение ARB_vertex_buffer_object

#4
10:35, 10 фев 2013

VBO, instancing.

#5
13:45, 10 фев 2013

notnA
что glGetError выдает  ?
OpenMP создает потоки, и твои вызовы OpenGL с разных потоков идут, а контекст один.

#6
13:55, 10 фев 2013

для кубов которые не отрисовываются glGetError возвращает 1282 (invalid operation, подсказал гугл).
не компетентен в Opengl, "вызовы OpenGL с разных потоков идут, а контекст один" -  это значит что должно работать, как я планировал сделать?

#7
15:06, 10 фев 2013

notnA
> для кубов которые не отрисовываются glGetError возвращает 1282 (invalid
> operation, подсказал гугл).
Ну вообще я так и думал что будет эта ошибка.
Используй gluErrorString для получения строки с ошибкой.
>это значит что должно работать, как я планировал сделать?
Контекст OpenGL должен быть текущим в том потоке где он работает. У тебя это не так. Ты не делал текущим контекст в другом потоке отсюда и ошибка.
читай основы. Сделай тестовое приложение, пробуй шарить/не шарить контексты может синхронизацию придумаешь и без этого, и только потом пытайся это все реализовать через OpenMP.

#8
15:17, 10 фев 2013

Всем спасибо за  информацию. буду копать :)

#9
16:42, 10 фев 2013

notnA
> Есть несложный способ ускорить отрисовку?

Ну во первых - рисование из нескольких потоков ЦПУ никак вообще не может увеличить скорость отрисовки, а только ухудшить. Сколько ядер и потоков у ЦПУ видеокарте абсолютно наплевать, это отдельное устройство со своими собственными ядрами, а вот путаться друг у друга под ногами такие потоки будут.
Если задача именно ускорить вывод графики - то выше уже советовали - выкинуть на свалку подход с glBegin/glEnd и перейти на VBO - это как минимум.

#10
20:00, 10 фев 2013

=A=L=X=
> выкинуть на свалку подход с glBegin/glEnd и перейти на VBO - это как минимум.
А еще можно кубы строить в геометрическом шейдере, что радикально снизит нагрузку на шину.

P. S. Если эти кубы -- что-то по типу майнкрафта, то стоит для начала выкинуть невидимые кубы/грани.

ПрограммированиеФорумГрафика

Тема в архиве.