Может ли OpenGL ES отображать текстуры не базовых размеров 2? - PullRequest
14 голосов
/ 18 сентября 2010

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

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

Ответы [ 4 ]

10 голосов
/ 18 сентября 2010

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

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

6 голосов
/ 02 декабря 2010

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

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

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

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

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

3 голосов
/ 24 сентября 2010

Нет, это должно быть 2base.Тем не менее, вы можете обойти это, добавив черные полосы в верхней и / или нижней части вашего изображения, а затем с помощью массива координат текстуры, чтобы ограничить, где текстура будет отображаться из вашего изображения.Например, предположим, у вас есть текстура 13 х 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
    };

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

1 голос
/ 11 декабря 2012

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

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

Проверьте эти расширения, позвонив по номеру glGetString(GL_EXTENSIONS) и выполнив поиск нужного расширения.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...