Добавляем мультипоточность

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

Еще в первых тестовых прототипах на Python я использовал раздельные потоки для загрузки информации из базы данных в GPU и для считывания ввода от пользователя и управления камерой. Пусть в Python многопоточность реализована в "софтовом" виде, но тем не менее, даже такая реализация позволяла плавно управлять камерой независимо от обращений к базе данных. В процессе перехода на С++ выяснилось, что OpenGL не поддерживает разделение по потокам работы с буфером, ввода пользователя и рендеринг изображения. Это было плохой новостью. Но я какое-то время обходил эту проблему при помощи системы самодельного "планировщика" процессов, аналогичного тому как это реализовано в Python. Идея состоит в том, чтобы затратные по времени процессы (например, обращения к базе данных) отправлять в кэш-очередь и выделять на их выполнение фиксированные отрезки времени в каждом кадре рендера. Не позволяя при этом FPS падать ниже определенного уровня. Но такая схема не очень удобна по той простой причине, что скорость линейного перемещения или поворота камеры должна изменяться в зависимости от времени рендера каждого кадра, но это время становится известным только после того, как первая, после очередного изменения FPS, картинка уже выведена на экран. Возникает нарушение плавности управления камерой. Конечно, потом все сглаживается и усредняется, но для устранения рывков "первого кадра" приходится усложнять схему работы движка.

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