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 считаться хорошим выбором?

Определить "хорошо"? Там нет никакого способа ответить на это, не зная больше о вашей проблемной области.

Другие вопросы по тегам