2011-07-25 4 views
6

В настоящее время я пытаюсь реализовать «загрузочную нить» для очень основного игрового движка, который заботится о загрузке, например. текстуры или аудио, в то время как основной поток продолжает отображать правильное сообщение/экран, пока операция не закончится или даже не будет отображать обычные игровые сцены, в то время как загрузка меньших объектов происходит в фоновом режиме.SDL/OpenGL: Реализация «Погрузочной нити»

Теперь я, безусловно, не специалист по OpenGL, но когда я реализовал такой механизм «Загрузка», я быстро обнаружил, что OGL не любит доступ к контексту визуализации из потока, отличного от того, который был создан на очень. Я гугле вокруг и решение кажется:

«Создать второй контекст рендеринга на резьбе и поделиться им с контекстом главного потока»

Проблема в том, что я использую SDL для позаботьтесь о моем управлении окнами и создании контекста, и насколько я могу судить по проверке API, нет возможности рассказать SDL об обмене контекстами между собой :(

Я пришел к выводу, что лучшие решения для мой случай:

подход A) Изменяйте SDL библиотеку для поддержки совместного контекста с конкретными функциями платформы (wglShareLists() и glXCreateContext() Я предполагаю)

подход B) Пусть «Loading Thread» только загрузить данные в память и обработайте его в формате OpenGL и передайте его в основной поток, который, например, позаботится о загрузке текстуры в графический адаптер. Это, конечно, относится только к данным, для которых необходим действительный контекст OpenGL.

Первое решение является наименее эффективным, я думаю. Я действительно не хочу калечить SDL, и кроме того, я читал, что совместное использование контекста не является высокопроизводительной операцией. Итак, мой следующий подход будет на втором подходе.

EDIT: Что касается «высокопроизводительной операции»: я прочитал статью неправильно, на самом деле это не так сильно. В статье предлагается перевести интенсивные операции ЦП на второй поток со вторым контекстом. Извините за что

После всего этого введения я был бы очень признателен, если кто-нибудь может дать мне несколько советов и комментарии на следующие вопросы:

1) Есть ли способ поделиться контексты с СВД и было бы любой хороший способ сделать это?

2) Есть ли еще более «элегантный» способ загрузить мои данные в фоновом режиме, о которых я, возможно, пропустил или не думал?

3) Могу ли я намерен пойти с подходом В, который считается хорошим выбором? По-прежнему будут незначительные накладные расходы на операции OpenGL на моем основном потоке, которые блокируют рендеринг, или он настолько мал, что его можно игнорировать?

+2

Я бы пошел с решением B. Позвольте фоновому потоку загружать все необходимые данные, а основной поток обрабатывает чертеж. –

+0

Спасибо, я рефакторинг моего кода на данный момент, чтобы загрузить мои данные таким образом. Но, возможно, у кого-то еще есть некоторые комментарии, чтобы этот вопрос дал больше информации, если кто-то столкнулся с одной проблемой :) – PuerNoctis

+0

Имейте в виду, что это решение проще сказать, чем сделать: в зависимости от деталей вашего приложения, ваши потоки, скорее всего, должны быть синхронизированы должным образом, и это не всегда простая задача. Я предположил, что вы изучили однопоточные альтернативы и не нашли подходящего вам. –

ответ

6

Есть ли способ поделиться контексты с SDL

No.

Да!

Вы должны получить текущий контекст, используя вызовы, специфичные для платформы. Оттуда вы можете создать новый контекст и сделать его общим, а также с вызовами для конкретной платформы.

Есть ли еще более «элегантный» способ загрузить мои данные в фоновом режиме, о которых я, возможно, пропустил или не думал?

Не совсем. Вы достаточно хорошо перечислили параметры: взломать SDL, чтобы получить нужные данные, или загрузить данные неэффективно.

Однако вы можете загрузить данные в отображаемые объекты буфера и transfer the data to OpenGL. Вы можете делать только отображение/развязку в потоке OpenGL, но указатель, который вы получаете при сопоставлении, можно использовать в любом потоке. Поэтому сопоставьте буфер, передайте его рабочему потоку. Он загружает данные в сопоставленную память и переворачивает переключатель. Поток GL разворачивает указатель (рабочий поток должен забыть о указателе сейчас) и загружает данные текстуры.

Могу ли я собираться идти с подходом В, который считается хорошим выбором?

Определить «хорошо»? На это невозможно ответить, не зная больше о вашей проблемной области.

+0

С «хорошим» я на самом деле имел в виду, если бы это была лучшая или профессиональная идея, чтобы получить совместное использование контекста, несмотря ни на что. Но спасибо за ваше предложение, я определенно буду заглядывать в него завтра. – PuerNoctis

+3

@Nicol Bolas: На самом деле вы можете обмениваться контекстами с SDL, если вы не боитесь писать код, зависящий от формы: wglGetCurrent {DC, Context}, glXGetCurrent {Display, Drawable, Context}, вы считаете остальное. Я использовал их в своей библиотеке удобного доступа. – datenwolf

+0

@ datenworlf: Я совсем забыл, что вы можете просто получить текущий контекст. –

Смежные вопросы