Ох ... Нет, нет, нет. Темы не то, что вы должны использовать здесь. Серьезно. Нить не ваше решение в данном конкретном случае. Давайте немного откатимся ...
В данный момент вы используете GLUT и говорите, что вам нужны потоки, чтобы «избежать блокировки на glutMainLoop()
». И вам не нужна блокировка, потому что вы хотите сделать некоторые вычисления в то же время.
Остановитесь сейчас и спросите себя - Вы уверены, что эти операции должны выполняться асинхронно (в целом) при рендеринге OpenGL? Если это так, вы можете перестать читать этот пост и посмотреть другие , но я искренне верю, что это не может иметь место для + - типичного приложения OpenGL реального времени.
Итак ... Типичное приложение OpenGL выглядит так:
- обработка событий
- тиковые расчеты
- перерисовать экран
Большинство оконных библиотек GL позволяют вам реализовать это как свой собственный главный цикл, GLUT как бы скрывает это своими «обратными вызовами», но идея та же.
Вы все еще можете ввести параллелизм в своем приложении, но он должен начинаться и останавливаться на шаге 2, поэтому он все еще последовательн на уровне основного цикла: «вычислить кадр вычислений, ТОТ отрендерить этот кадр». Такой подход, скорее всего, избавит вас от многих неприятностей .
Подсказка: измени свою библиотеку. GLUT устарел и больше не поддерживается. Переключение на GLFW (или SDL) для создания окна не потребует больших усилий с точки зрения кода, и - в отличие от GLUT - вы сами определяете свой основной цикл, что, по-видимому, и является тем, чего вы хотите достичь. (Плюс они, как правило, более удобны для обработки событий ввода и окна и т. Д.)
Несколько типичных псевдокодов с физикой реального времени с постоянным временным шагом без вмешательства в рендеринг (при условии, что вы хотите запускать физику чаще, чем рендеринг, в общем):
var accum = 0
const PHYSICS_TIMESTEP = 20
while (runMainLoop) {
var dt = getTimeFromLastFrame
accum += dt
while (accum > PHYSICS_TIMESTEP) {
accum -= PHYSICS_TIMESTEP
tickPhysicsSimulation(PHYSICS_TIMESTEP)
}
tickAnyOtherLogic(dt)
render()
}
Возможным расширением этого является использование значения accum
в качестве дополнительного значения «экстраполяции» только для рендеринга, что позволило бы визуально сгладить графическое представление при более редком моделировании физики (с большим DT), возможно, более редко, чем один раз за кадр рендеринга.