SDL / OpenGL: реализация "загрузки потока"
В настоящее время я пытаюсь реализовать "Загрузка потока" для очень простого игрового движка, который заботится о загрузке, например, текстур или аудио, пока основной поток продолжает отображать правильное сообщение / экран до завершения операции или даже воспроизводить обычные игровые сцены во время загрузки. из более мелких объектов происходит в фоновом режиме.
Сейчас я не эксперт по OpenGL, но, реализовав такой механизм "загрузки", я быстро обнаружил, что OGL не очень нравится доступ к контексту рендеринга из потока, отличного от того, в котором он был создан. Я гуглил вокруг, и решение, кажется, было:
"Создать второй контекст рендеринга в потоке и поделиться им с контекстом основного потока"
Проблема в том, что я использую SDL, чтобы позаботиться о своем управлении окнами и создании контекста, и, насколько я могу судить из проверки API, нет способа сказать SDL об обмене контекстами между собой:(
Я пришел к выводу, что лучшие решения для моего случая:
Подход A) Измените библиотеку SDL для поддержки совместного использования контекста с помощью функций, специфичных для платформы (я предполагаю, что wglShareLists() и glXCreateContext())
Подход Б) Пусть "Загрузка потока" только загружает данные в память и обрабатывает их в формате, удобном для OpenGL, и передает их основному потоку, который, например, заботится о загрузке текстуры в графический адаптер. Это, конечно, относится только к данным, для которых требуется действительный контекст OpenGL
Первое решение является наименее эффективным, я думаю. Я не очень хочу работать с SDL, и кроме того, я прочитал, что совместное использование контекста не является высокопроизводительной операцией. Так что мой следующий шаг будет на втором подходе до сих пор.
РЕДАКТИРОВАТЬ: Относительно "высокопроизводительной операции": я прочитал статью неправильно, это на самом деле не так уж много производительности. В статье предлагалось перенести интенсивные операции с ЦП на второй поток со вторым контекстом. Простите за это
После всего этого вступления я был бы очень признателен, если бы кто-нибудь дал мне несколько советов и комментариев к следующим вопросам:
1) Есть ли какой-нибудь способ поделиться контекстами с SDL, и будет ли это полезно в любом случае?
2) Есть ли другой, более "элегантный" способ загрузки моих данных в фоновом режиме, который я мог пропустить или не подумать?
3) Может ли мое намерение использовать подход B считаться хорошим выбором? Операции OpenGL в главном потоке, которые блокируют рендеринг, все равно будут иметь незначительные накладные расходы, или это настолько мало, что их можно игнорировать?
1 ответ
Есть ли способ поделиться контекстами с SDL
Нет.
Да!
Вы должны получить текущий контекст, используя вызовы для конкретной платформы. Оттуда вы можете создать новый контекст и сделать его доступным, в том числе для вызовов, специфичных для платформы.
Есть ли другой, более "элегантный" способ загрузки моих данных в фоновом режиме, который я мог пропустить или не подумать?
На самом деле, нет. Вы довольно хорошо перечислили параметры: взломайте SDL, чтобы получить необходимые данные, или загрузите данные неэффективно.
Однако вы можете загрузить данные в сопоставленные буферные объекты и перенести данные в OpenGL. Вы можете выполнять сопоставление / отмену сопоставления только в потоке OpenGL, но указатель, который вы получаете при отображении, можно использовать в любом потоке. Итак, сопоставьте буфер, передайте его рабочему потоку. Он загружает данные в отображенную память и переключает переключатель. Поток GL отображает указатель (рабочий поток должен забыть об указателе сейчас) и загружает данные текстуры.
Может ли мое намерение перейти с подхода B считаться хорошим выбором?
Определить "хорошо"? Там нет никакого способа ответить на это, не зная больше о вашей проблемной области.