Может ли OpenGL ES визуализировать текстуры без базовых размеров?

Это просто быстрый вопрос, прежде чем я погружу глубже в преобразование моей текущей системы рендеринга в openGL. Я слышал, что текстуры должны быть в размерах базы 2, чтобы их можно было сохранить для рендеринга. Это правда?

Мое приложение очень тесно связано с памятью, но большинство растровых изображений не являются двумя. Сохраняет ли память не-базовых 2 больше памяти?

Ответы

Ответ 1

Истинно, в зависимости от версии OpenGL ES, OpenGL ES 1.0/1.1 обладает двумя ограничениями. OpenGL ES 2.0 не имеет ограничений, но ограничивает режимы обертывания для немощности двух текстур.

Создание больших текстур в соответствии с размерами POT отбрасывает текстуру памяти.

Ответ 2

Суреш, сила 2 ограничения была встроена в OpenGL в самые ранние дни компьютерной графики (до доступного аппаратного ускорения), и это было сделано по соображениям производительности. Низкоуровневый код рендеринга получает достойный прирост производительности, когда он может быть жестко закодирован для текстур с двумя текстурами. Даже в современных графических процессорах текстуры POT быстрее, чем текстуры NPOT, но разница в скорости намного меньше, чем раньше (хотя она может быть заметна на многих устройствах ES).

GuyNoir, что вам нужно сделать, это построить атлас текстуры. Я просто решил эту проблему сам в минувшие выходные для своей собственной игры на Android. Я создал класс TextureAtlas, и его конструктор вызывает glTexImage2D() для создания большой текстуры любого размера, который я выбираю (передача значения null для значений пикселей). Затем я могу вызвать add (id, bitmap), который вызывает glTexSubImage2D(), несколько раз, чтобы упаковать изображения меньшего размера. Класс TextureAtlas отслеживает используемое и свободное пространство внутри большей текстуры, а прямоугольники сохраняют каждый битмап. Затем код рендеринга может вызвать get (id), чтобы получить прямоугольник для изображения внутри атласа (который он затем может преобразовать в текстуру координаты).

Боковое примечание # 1: Выбор наилучшего способа упаковки в различные размеры текстур НЕ является тривиальной задачей. Я решил начать с простой логики в классе TextureAtlas (думаю, пишущая машинка + возврат каретки + линия) и убедитесь, что я загружаю изображения в лучшем порядке, чтобы воспользоваться этой логикой. В моем случае это должно было начаться с наименьших квадратичных изображений и работать до средних квадратичных изображений. Затем я загружаю любые короткие + широкие изображения, заставляю CR + LF, а затем загружаю любые высокие + тощие изображения. Я загружаю наибольшие квадратные изображения в последний раз.

Боковое примечание # 2: Если вам нужно несколько атласов текстур, попробуйте сгруппировать изображения внутри каждого из них, которые будут отображаться вместе, чтобы свести к минимуму количество раз, когда вам нужно переключать текстуры (что может привести к гибели производительности). Например, в моей игре Android я поставил все элементы статической игровой панели в один атлас и все кадры различных анимационных эффектов во втором атласе. Таким образом, я могу привязать атлас №1 и нарисовать все на игровом поле, затем я смогу привязать атлас №2 и нарисую все специальные эффекты поверх него. Два варианта текстур для каждого кадра очень эффективны.

Боковое примечание # 3: Если вам нужно повторить/зеркалировать текстуры, им нужно перейти в свои собственные текстуры, и вам нужно масштабировать их (не добавлять черные пиксели для заполнения краев).

Ответ 3

Нет, это должно быть 2base. Однако вы можете обойти это, добавив черные полосы вверху и/или нижней части изображения, а затем используя массив текстурных координат, чтобы ограничить, где текстура будет отображаться из вашего изображения. Например, скажем, у вас есть текстура размером 13 x 16 пикселей. Вы можете добавить 3 пикселя черного в правую сторону, а затем сделать следующее:

static const GLfloat texCoords[] = {
        0.0, 0.0,
        0.0, 13.0/16.0,
        1.0, 0.0,
        1.0, 13.0/16.0
    };

Теперь у вас есть файл изображения 2base, но текстура не-2base. Просто убедитесь, что вы используете линейное масштабирование:)

Ответ 4

Это немного поздно, но поддержка 2 текстур поддерживается в OpenGL ES 1/2 через расширения.

Основной GL_OES_texture_npot. Существует также GL_IMG_texture_npot и GL_APPLE_texture_2D_limited_npot для устройств iOS.

Проверьте эти расширения, вызвав glGetString(GL_EXTENSIONS) и найдите требуемое расширение.

Я бы также посоветовал хранить текстуры до размеров, кратных 4, поскольку какое-то оборудование растягивает текстуры, если нет.