Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

OpenGL

Мне нужно выделить работу с OpenGL в отдельный поток (thread). Как мне это сделать ?

Основные положения многопоточности OpenGL таковы:

Каждый поток в OpenGL может иметь свой, активный контекст устройства (RC), но только один.

Именно туда поступают все gl-команды из потока. Контекст не может быть активным одновременно у нескольких потоков. Для этого существует функция wglMakeCurrent. Однако, поскольку периодические активизация/деактивизация контекста могут серьёзно замедлить программу, лучше всего будет "захватывать" контекст при запуске потока, и "отпускать" при его завершении. Например:

DWORD WINAPI ThreadFunc(LPVOID lpData)
{
// Получение входных параметров из блока, передаваемого по адресу lpData
hDC=....
hRC=....

// Получить контекст в своё распоряжение
wglMakeCurrent(hDC,hRC);

// Код потока
.....
....
//

// "Отпустить" контекст
wglMakeCurrent(hDC,NULL);
return 0;
}

Разумеется, нужно самому предусмотреть синхронизацию этого и основного потоков, а также механизм передачи "задания".

Есть ещё один важный момент. Если все текстуры загружены и дисплейные списки (display lists - DL) созданы ещё ДО запуска такого потока - прекрасно; если же их нужно подгружать и удалять в процессе работы, нужно ещё кое-что.

Можно создать ВТОРОЙ контекст устройства (в невидимом окне размером 1x1 пиксел), который будет активным у основного потока программы. Для объединения адресных пространств двух контекстов используется wglShareLists(dest,source).

Начиная с OpenGL версии 1.1, эта функция импортирует не только адресное пространство дисплейных списков (glGenLists,glDeleteLists), но и текстурных объектов (glGenTextures,glDeleteTextures). Все изменения, сделанные в одном контексте, будут автоматически отображаться в другой.

wglShareLists нужно вызывать сразу же после создания контекстов, пока ещё не определено никаких текстур и DL. Желательно также, но совсем не обязательно, чтобы оба контекста имели одинаковый формат (SetPixelFormat).

Примечание: многопоточность OpenGL невозможна на враперах вроде 3Dfx GL / miniGL из-за ограничений их нижнего этажа, GLide. В этих случаях контексты будут успешно создаваться, и каждый поток получит контекст в своё распоряжение, однако только один из них будет реально подключен к устройству (последний созданный, или тот, который сделали текущим для какого-либо потока с помощью функции wglMakeCurrent в последнюю очередь).

Попытка выводить что-то из других контекстов вызовет ошибку защиты памяти в коде враппера.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
7.6K
04 июня 2004 года
Dyach
1 / / 04.06.2004
Мне нравитсяМне не нравится
25 июня 2008, 06:28:19
[quote=bave]Не нужно создавать невидимого окна. Используя
девайс контекст (hDC) можно создать и второй контекст рендеринга (hRC2)[/quote]

без невидимого окна никак! оно обязаетльно! нельзя создавать два контекста рендеринга на один девайс-контекст...
2.
279
07 марта 2004 года
bave
456 / / 07.03.2004
Мне нравитсяМне не нравится
12 декабря 2006, 03:48:45
я бы даже сказал вот так:
Код:
HDC g_hDC;



//Main Thread:

//...

hRC1 = wglCreateContext(g_hDC);

hRC2 = wglCreateContext(g_hDC);

wglShareLists(hRC2, hRC1);



wglMakeCurrent(g_hDC, hRC1);



//Secondary Thread:

//...

wglMakeCurrent(g_hDC, hRC2);
3.
279
07 марта 2004 года
bave
456 / / 07.03.2004
Мне нравитсяМне не нравится
12 декабря 2006, 03:40:26

Цитата:
Можно создать ВТОРОЙ контекст устройства (в невидимом окне размером 1x1 пиксел), который будет активным у основного потока программы.


Не нужно создавать невидимого окна. Используя
девайс контекст (hDC) можно создать и второй контекст рендеринга (hRC2) и расшарить его для
контекста потока рендера(hRC1), тогда установив контексты hRC1 и hRC2 каждый как текущий в своём потоке, можно будет рендерить OpenGL-ом из двух потоков без проблем.

Код:
//Main Thread:

//...

hRC1 = wglCreateContext(hDC);

hRC2 = wglCreateContext(hDC);

wglShareLists(hRC2, hRC1);



wglMakeCurrent(hRC1);



//Secondary Thread:

//...

wglMakeCurrent(hRC2);
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог