Russian Qt Forum
Ноябрь 24, 2024, 01:53
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
2D и 3D графика
>
Асинхронная загрузка текстур (OpenGL)
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Асинхронная загрузка текстур (OpenGL) (Прочитано 9871 раз)
UnSeen
Гость
Асинхронная загрузка текстур (OpenGL)
«
:
Октябрь 05, 2011, 13:49 »
Задача в следующем - в приложении требуется подгружать текстуры в отдельном потоке, чтобы не затормаживать рисование в основном потоке (программа - аналог Google Earth, т.е. огромное количество текстур, но одновременно показывается только небольшая часть)
Нашёл такой же вопрос тут, но без ответа
http://www.prog.org.ru/topic_1564_0.html
Как это делать в теории - понятно, но будет здорово, если кто-нибудь скинет рабочий пример.
Обычно это делается так: во втором потоке создаётся отдельный контекст рендеринга (т.к. нельзя использовать один в двух потоках одновременно) и они объединяются функцией wglShareLists. После чего текстуры, созданные во втором потоке, становятся доступны и в первом.
Вот именно с wglShareLists и проблема - контексты почему-то не хотят объединяться, функиция возвращает false
Текстуры во втором потоке создаются, но в первом они, само собой, не доступны.
В первом потоке используется QGLWidget, поставленный в качестве viewport-а на QGraphicsScene
Во втором для создания контекста используется QGLPixelBuffer (так как, насколько я понимаю, создать окно вне основного потока нельзя? если что, с Qt работаю впервые)). При создании QGLPixelBuffer в качестве формата указываю GLWidget->format(), чтобы форматы были одинаковые у обоих контекстов. Но wglShareLists не срабатывает
Что я делаю не так? ©
Наверняка кто-то такое уже делал, ткните в пример, плиз
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #1 :
Октябрь 05, 2011, 18:24 »
Сейчас занимаюсь тоже OpenGL текстурами, но "с др. стороны", поэтому пример не скину. Возможно полезно будет такое соображение:
Сама "загрузка текстуры для OpenGL" производится ф-цией glTexImage2D или аналогичной - в той обертке что Вы пользуете это выглядит как bindTexture метод. После выполнения этой операции исходный имедж не нужен, OpenGL скопировал его куда надо. Поэтому есть смысл все дела OpenGL делать в одной нитке, а "узкое место" (подгрузка имеджей с диска) вынести в отдельную нитку.
Записан
UnSeen
Гость
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #2 :
Октябрь 05, 2011, 18:45 »
Цитата: Igors от Октябрь 05, 2011, 18:24
Сейчас занимаюсь тоже OpenGL текстурами, но "с др. стороны", поэтому пример не скину. Возможно полезно будет такое соображение:
Сама "загрузка текстуры для OpenGL" производится ф-цией glTexImage2D или аналогичной - в той обертке что Вы пользуете это выглядит как bindTexture метод. После выполнения этой операции исходный имедж не нужен, OpenGL скопировал его куда надо. Поэтому есть смысл все дела OpenGL делать в одной нитке, а "узкое место" (подгрузка имеджей с диска) вынести в отдельную нитку.
Я сначала тоже собирался этим ограничиться, но оказалось, что время загрузки и раскодирования с диска jpg текстуры сравнимо со временем закачки текстуры в видеопамять (даже если без создания мипмапов). Как-никак текстурка 1024х1024 - это 4 метра данных. Так что этот способ не идеальный, часть глюков останется, и это будет заметно из-за специфики программы: при перемещении карты приходится одновременно подгружать большое количество текстур, которые раньше были не видны.
Так что хотелось бы полностью вынести загрузку во второй поток. Чтобы всё честно, красиво и без извращений
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #3 :
Октябрь 05, 2011, 19:23 »
Цитата: UnSeen от Октябрь 05, 2011, 18:45
Я сначала тоже собирался этим ограничиться, но оказалось, что время загрузки и раскодирования с диска jpg текстуры сравнимо со временем закачки текстуры в видеопамять (даже если без создания мипмапов). Как-никак текстурка 1024х1024 - это 4 метра данных. Так что этот способ не идеальный, часть глюков останется, и это будет заметно из-за специфики программы: при перемещении карты приходится одновременно подгружать большое количество текстур, которые раньше были не видны.
У меня немного похожая задача, текстуры побольше (часто 8x8k), зато легче с drag'ом - я могу (и должен) загрузить все до того как началась интерактивщина. Зачем зачем Вы связались с разделяемым контекстом и.т..п ? Ну делайте glTextImage (затратную работу) во вспомогательной нитке (нужно синхронизировать только создание нового ID текстуры), не вижу почему это должно не работать.
Записан
UnSeen
Гость
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #4 :
Октябрь 05, 2011, 19:45 »
Цитата: Igors от Октябрь 05, 2011, 19:23
У меня немного похожая задача, текстуры побольше (часто 8x8k), зато легче с drag'ом - я могу (и должен) загрузить все до того как началась интерактивщина. Зачем зачем Вы связались с разделяемым контекстом и.т..п ? Ну делайте glTextImage (затратную работу) во вспомогательной нитке (нужно синхронизировать только создание нового ID текстуры), не вижу почему это должно не работать.
Тем не менее, не работает
Нельзя одновременно использовать один и тот же контекст в двух потоках (что вполне объяснимо. как вы себе представляете, например, параллельное выполнение блоков glBegin-glEnd в разных потоках с одним контекстом?))))
wglShareLists, похоже, самое удобное и простое решение
http://www.gamedev.ru/code/forum/?id=72099
«
Последнее редактирование: Октябрь 05, 2011, 19:47 от UnSeen
»
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #5 :
Октябрь 05, 2011, 20:28 »
Цитата: UnSeen от Октябрь 05, 2011, 19:45
Тем не менее, не работает
Нельзя одновременно использовать один и тот же контекст в двух потоках (что вполне объяснимо. как вы себе представляете, например, параллельное выполнение блоков glBegin-glEnd в разных потоках с одним контекстом?))))
wglShareLists, похоже, самое удобное и простое решение
http://www.gamedev.ru/code/forum/?id=72099
Ссылка интересная. Но я бы проверился прежде чем лезть в дебри с контекстами, тем более это несложно. Создаю текстуру с новым ID в главной нитке, glGenTextures быстрая операция. Заряжаю созданную текстуру в др. нитке - с какого перепугу это не должно работать? Конечно придется ответить/обеспечить что новое ID еще нигде не используется - ну это нормально. Др. словами: нигде ясно не звучит что, мол, все действия в одной нитке игнорируются контекстом созданным в другой.
Записан
UnSeen
Гость
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #6 :
Октябрь 05, 2011, 21:47 »
Цитата: Igors от Октябрь 05, 2011, 20:28
Заряжаю созданную текстуру в др. нитке - с какого перепугу это не должно работать? Конечно придется ответить/обеспечить что новое ID еще нигде не используется - ну это нормально. Др. словами: нигде ясно не звучит что, мол, все действия в одной нитке игнорируются контекстом созданным в другой.
Проблема уже в "заряжаю"
glBindTexture, вызванное из другого потока с тем же контекстом, выдаёт GL_INVALID_OPERATION . Так что увы, всё не так просто
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #7 :
Октябрь 05, 2011, 22:28 »
Цитата: UnSeen от Октябрь 05, 2011, 21:47
Проблема уже в "заряжаю"
glBindTexture, вызванное из другого потока с тем же контекстом, выдаёт GL_INVALID_OPERATION . Так что увы, всё не так просто
Ну привет, делать glBindTexture, (текущей) Вас в др. нитке никто не заставлял, речь шла о glTextImage.
Записан
UnSeen
Гость
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #8 :
Октябрь 05, 2011, 22:59 »
И куда же вы будете загружать текстуру, если она не выбрана?
Нашёл, что я делал не так
Оказывается, создавать и связывать два контекста нужно в одном потоке. А потом уже можно использовать один из контекстов в другом потоке. А я пытался создавать контексты в разных потоках и это не срабатывало. Почему так - хз...
Теперь всё работает
Записан
xop
Гость
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #9 :
Октябрь 10, 2011, 08:23 »
Делаю примерно так:
1) контекст только один, в основном потоке
2) выделяю заранее буфер для загрузки типа GL_PIXEL_UNPACK_BUFFER, с usage GL_STREAM_DRAW
3) когда надо грузить текстуру в основном потоке делаю glMapBuffer, полученный указатель на область памяти передаю в параллельный поток
4) в параллельном потоке загружаю текстуру в полученную область памяти и кидаю сообщение основному потоку
5) в основном потоке делаю glUnmapBuffer, и потом с этим буфером привязанным к target GL_PIXEL_UNPACK_BUFFER выполняю нужные glTexImage2D, при этом вместо указателя на данные там передается смещение относительно начала буфера
Если нужно подробнее - могу кусочки кода накидать.
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #10 :
Октябрь 10, 2011, 11:18 »
xop
, рад Вас видеть т.к. привалило много работы с OpenGL и нужны советы знатока.
Общая задача поддерживать 2 и более текстур на 1 объекте со всеми типами и наворотами маппинга. (изначально приложение обходилось 1 текстурой). Сделал так: создаю UV координаты для каждой текстуры и затем использую glTextImage2D и glTetCoordPointer. Это работает, но возникает капитальнейший геморрой: UV seam (шов). Приходится "распиливать" полигоны по шву, с 2 и более текстурами это особенно неприятно.
Есть ли лучшее ("модерновое") решение?
Примечание: если лучше вынести это в отдельный топик - нет проблем
Спасибо
Записан
xop
Гость
Re: Асинхронная загрузка текстур (OpenGL)
«
Ответ #11 :
Октябрь 15, 2011, 17:18 »
Думаю лучше все-таки новую тему открыть. И заодно более подробно описать задачу, в которой понадобились разные текстурные координаты для разных текстур
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...