многопоточность — C ++ OpenGL сбои в многопоточной среде

введите описание изображения здесь

Какова цель:

Я относительно новичок в потоках. Я пытался сделать Quad-Tree рендерингом ландшафта, который будет рендериться быстро и эффективно. Объем рендеринга, который в данный момент отображается, значительно отстает от пользователя, если он будет максимально детализирован. Вот почему я использовал QuadTree для его рендеринга. Движок также поддерживает ввод и физику, поэтому я решил использовать поток рендеринга. Это вызвало много проблем.

Проблемы):
Когда я не работал с потоками, было небольшое отставание из-за других систем в Engine. Основной причиной, вызвавшей задержку, является загрузка и удаление ландшафта в QuadTree (я даже не уверен, является ли это оптимальным способом сделать это.) Теперь рендеринг происходит очень быстро, и кажется, что он не задерживается. Когда камера стоит на месте, игра работает нормально. Я оставил игру запущенной в течение часа, и никаких сбоев обнаружено не было.

Когда ландшафт загружен, он использует несколько переменных, которые использует код рендеринга. А именно, связывание буферов —

    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);

Я полагаю, что эта переменная доступна одновременно с другим потоком. Что вызывает сбой. Как это исправить? Я пытался использовать мьютексы, но это не похоже на работу. Где бы я заблокировал и разблокировал мьютекс, чтобы это исправить?

Другая переменная, которая, кажется, вызывает ту же ошибку, является «IsLeaf».

Еще один сбой (std :: badAlloc) возникает после загрузки большого количества местности. Даже если это убирается. Я предполагаю, что это связано с моим кодом удаления, но я не знаю, что случилось.

В настоящее время я добавляю и удаляю плитки, проверяя диапазон с камеры и удаляя / создавая плитку. Я хочу сделать плитку, на которой я нахожусь, и те, что на ней. Однако это не работает при переходе с одной из 4 основных плиток. Создание с использованием диапазона не работает, так как это диапазон к центру большой плитки, а не меньших. Я также пытался удалять всю карту каждые несколько секунд, и это, кажется, тоже работает, но с большей задержкой. Есть ли лучший способ сделать создание и уничтожение?

Между разными разрешениями есть пробелы. Есть ли способ уменьшить это? В настоящее время я визуализирую плитки немного больше, чем нужно, но это не помогает при серьезных изменениях разрешения.

Если у вас есть идеи, как исправить одну из этих ошибок, это будет высоко ценится.

Код (слишком много, чтобы загрузить здесь)

http://pastebin.com/MwXaymG0

http://pastebin.com/2tRbqtEB

1

Решение

Контекст OpenGL может быть привязан только к одному потоку за раз (через wglMakeCurrent () в Windows).

Поэтому вам не следует использовать функции gl * в разных потоках, даже если вы используете мьютексы для обеспечения доступа к определенным переменным в памяти, вызовы не будут выполнены.

Я бы посоветовал перенести ваши вызовы gl * в ваш поток рендеринга, однако в другом потоке есть такие вещи, как загрузка ландшафта, расчеты усеченного контура, отсечение и т. Д. Поток рендеринга просто должен проверить, есть ли у объекта новые данные, а затем выполнить соответствующие вызовы GL как часть его обновления / рендеринга.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]