LINUX.ORG.RU

Нубские вопросы по текстурам OpenGL (+ немного Qt)


0

1

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

* Какой тип текстуры для кадра выбрать, чтобы не заморачиваться с ограничениями типа «размеры текстуры должны быть степенью двойки» и при этом код работал на большинстве платформ с разными версиями OpenGL?

* Какие проблемы с GT_TEXTURE_RECTANGLE, который вроде бы работает «везде» и не имеет указанного выше ограничения?

* QGLContext::bindTexture(), судя по коду, проверяет в рантайме версию OpenGL и поддерживаемые расширения и берет на себя проблему с размерами текстур, но при этом кэширует текстуры на основе QImage::cacheKey(), что бесполезно для видеокадров, а также, судя по всему, не предоставляет возможности обновить уже созданную текстуру. Нормально ли удалять предыдущую текстуру (QGLContext::deleteTexture()) и создавать новую для каждого следующего кадра?

* Когда используются QPainter::begin/endNativePainting()?

Если это имеет значение, то поток видео приходит покадровым образом в 32-битном RGB-формате.

Спасибо.


Не знаю, как в современных стандартах OGL, но лет 5 назад текстуры с произвольными размерами были железо-специфичны. Т.е. с драйвером одного железа работает, с другим нет. Я для нвидии GL_TEXTURE_RECTANGLE_ARB использовал.

Но ведь никто не мешает создавать текстуру по размеру видео и нехай её железо масштабирует?

mv ★★★★★
()

На размер со степенью 2 - можешь забить. Уже давно поддерживаются текстуры любых размеров (до определённого максимального).

Создавать новую текстуру для каждого кадра - это очень и очень плохо. Если есть возможность получить идентификатор текстуры - то можно воспользоваться родными опенЖЛ-евскими функциями. С другой стороны - даже обновление содержимого текстуры каждый кадр родным способом (glTexSubImage2D) - это прошлой век и дурной тон, т.к. это большой тормозистор.

rip86oz
()
Ответ на: комментарий от mv

> Не знаю, как в современных стандартах OGL

Гугл подсказывает, что начиная с OpenGL 2.0 NPOT-текстуры поддерживаются в т.ч. для типа GL_TEXTURE_2D

Но ведь никто не мешает создавать текстуру по размеру видео и нехай её железо масштабирует?

Ммм, не совсем понял.

Только что залез в исходники gl-рендерера VLC, там используется следующий подход: создается «правильная» текстура с размером большим, чем кадр, затем каждый кадр просто копируется в ее левый-верхний угол с помощью glTexSubImage2D(). Пока кажется наиболее оптимальным вариантом для моей задачи. Или ты это и имел ввиду?

mannaz
() автор топика
Ответ на: комментарий от rip86oz

Да, я эту же хрень нашел в VLC. А начиная с какого уровня карточек прошлых лет поддерживается OpenGL 2.0?

mannaz
() автор топика
Ответ на: комментарий от rip86oz

> Создавать новую текстуру для каждого кадра - это очень и очень плохо.

обновление содержимого текстуры каждый кадр родным способом (glTexSubImage2D) - это прошлой век и дурной тон, т.к. это большой тормозистор.

А как тогда реализуются динамические текстуры по-современному?

mannaz
() автор топика
Ответ на: комментарий от mannaz

Или ты это и имел ввиду?

Да. Только я создавал текстуру по размеру кадра.

mv ★★★★★
()
Ответ на: комментарий от rip86oz

это прошлой век и дурной тон, т.к. это большой тормозистор.

Гонять графику по шине тормозно, но другого способа передачи данных между хост-системой и девайсом не изобретено :)

mv ★★★★★
()
Ответ на: комментарий от mannaz

> А как тогда реализуются динамические текстуры по-современному? Смотря какая цель.

- Рендер в текстуру

- Процедурные текстуры (в шейдере генерются)

Но тебе это навятли-поможет.

Однако можно попробовать использовать текстурный буфер. Т.е. это буфер, в который ты можешь записывать данные каждого кадра, а потом в шейдере уже отрисовывать. Буфер поддерживает размер до 128 Мб, кадр при HD - около 6 Мб. К тому-же можно попробовать использовать glMapBuffer для получение указателя на этот буфер (и указать GL_WRITE_ONLY - т.е. будет оптимизирована работа для записи). В итоге тебе надо будет просто по указателю писать данные видеокадра (или передавать указатель в какую-то там функцию декодирования видео - я не знаю) - а в шейдере уже использовть этот буфер.

Я-бы попробовал сделать таким образом, но подобных задач у меня ещё не встречалось. Думаю что всё должно работать, и значительно быстрей, чем при копировании данных в обычную текстуру.

ЗЫ. Если для тебя тут много нового, то скажу что на самом деле это всё просто - и сложностей при реализации быть не должно.

rip86oz
()
16 июня 2012 г.
Ответ на: комментарий от rip86oz

Однако можно попробовать использовать текстурный буфер. Т.е.
это буфер, в который ты можешь записывать данные каждого
кадра, а потом в шейдере уже отрисовывать. Буфер поддерживает
размер до 128 Мб, кадр при HD - около 6 Мб.

Можешь дать ссылку на хороший HOWTO по использованию текстурного буфера?

pacify ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.