Многопоточный рендеринг на OpenGL
У меня многопоточное приложение, в котором я пытаюсь выполнить рендеринг с разными потоками. Сначала я попытался использовать один и тот же контекст визуализации между всеми потоками, но я получал текущие контексты NULL для других потоков. Я читал в Интернете, что один контекст может быть только в одном потоке за раз.
Поэтому я решил сделать что-то другое. Я создаю окно, я получаю HDC от него и создаю первый RC. Скорее всего, я разделяю этот HDC между потоками, и в каждом новом потоке, который я создаю, я получаю новый RC от того же HDC, и я делаю его актуальным для этого потока. Каждый раз, когда я это делаю, возвращаемый RC всегда отличается (обычно предыдущее значение + 1). Я делаю утверждение, чтобы проверить, возвращает ли wglGetCurrentContext()
RC, и похоже, что он возвращает тот, который был только что создан. Но после выполнения рендеринга я не получаю рендеринга, и если я вызываю GetLastError()
, я получаю ошибку 6 (неверный дескриптор??)
Итак, означает ли это, что, несмотря на то, что каждый новый вызов wglCreateContext()
дает мне новое значение, почему-то это означает, что все эти разные значения являются одним и тем же "Каналом связи" с вызовами OpenGL?
Означает ли это, что мне всегда придется недействить предыдущий контекст визуализации в потоке и активировать его на новом? Мне действительно нужно постоянно выполнять эту синхронизацию или есть ли другой способ решить эту проблему?
Ответы
Ответ 1
У меня многопоточное приложение, в котором я пытаюсь отображать разные потоки.
<я > DO NOT!!!
Вы не получите ничего от попытки многопоточности вашего рендеринга. В основном вы работаете в одном большом состоянии гонки, и драйвер будет просто занят синхронизацией потоков, чтобы как-то понять это.
Чтобы получить лучшую производительность рендеринга, все операции OpenGL сохраняются только в одном потоке. Все распараллеливание происходит бесплатно на графическом процессоре.
Ответ 2
Я предлагаю прочитать следующую статью в вики из Консорциума OpenGL.
http://www.opengl.org/wiki/OpenGL_and_multithreading
В простых словах это сильно зависит от того, что вы подразумеваете для многопоточности в отношении OpenGl, если у вас есть один поток, выполняющий часть рендеринга, и один (или более) выполняющий другие задания (например, AI, физика, логика игры и т.д. ) это совершенно правильно.
Если вы хотите, чтобы несколько потоков взаимодействовали с OpenGL, вы не можете или, лучше, могли бы, но это действительно даст вам больше проблем, чем преимуществ.
Попробуйте прочитать следующие часто задаваемые вопросы о параллельном использовании OpenGL, чтобы лучше понять эту концепцию:
http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html
Ответ 3
В некоторых случаях может иметь смысл использовать несколько контекстов рендеринга в разных потоках. Я использовал такую конструкцию для загрузки данных изображения из файловой системы и перевода этих данных в текстуру.
Ответ 4
OpenGL на Mac OS X является однопоточным; для его включения:
#include <OpenGL/OpenGL.h>
CGLError err = 0;
CGLContextObj ctx = CGLGetCurrentContext();
// Enable the multi-threading
err = CGLEnable( ctx, kCGLCEMPEngine);
if (err != kCGLNoError ) {
// Multi-threaded execution is possibly not available
// Insert your code to take appropriate action
}
См:
Concurrency и OpenGL - разработчик Apple
А:
Техническое Q & A QA1612: многопоточность OpenGL ES и...