Подтвердить что ты не робот

Сколько mipmaps имеет текстуру в OpenGL

Никогда не думайте, что я тот, кто создал текстуру в первую очередь, и я должен прекрасно знать, сколько mipmaps я загрузил/сгенерировал для нее. Я делаю это для unit test. Кажется, что параметр glGetTexParameter не найден. Самое близкое, что я пришел, это примерно так:

int max_level;
glGetTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, &max_level );
int max_mipmap = -1;
for ( int i = 0; i < max_level; ++i )
{
    int width;
    glGetTexLevelParameter( GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &width );
    if ( 0 == width )
    {
        max_mipmap = i-1;
        break;
    }
)

Во всяком случае, glGetTexLevelParameter() вернет 0 ширину для несуществующего mipmap, если я использую NVidia GPU, но с Mesa, он возвращает GL_INVALID_VALUE, что заставляет меня поверить, что это очень неправильная вещь.

Как узнать, какие уровни mipmap я заполнил текстурой?

4b9b3361

Ответ 1

Спектр выглядит нечетким на этом. В нем говорится, что вы получите GL_INVALID_VALUE, если параметр уровня "больше максимально допустимого уровня детализации". Точно, как это определено, не указано.

Документация для для функции немного ускоряет ее, заявив, что это максимально возможное количество LOD для максимально возможной текстуры (GL_MAX_TEXTURE_SIZE). Другие подобные функции, такие как glFramebufferTexture, явно указывают это как ограничение для GL_INVALID_VALUE. Поэтому я ожидал бы этого.

Поэтому у Mesa есть ошибка. Однако вы можете обойти это, предположив, что ошибка 0 или GL_INVALID_VALUE означает, что вы ушли с конца массива mipmap.

Говоря, я предлагаю использовать glTexStorage и никогда не буду снова задавать вопрос. Это принудительно помешает кому-либо установить MAX_LEVEL на слишком большое значение. Это довольно новое, от GL 4.2, но оно реализовано (или будет очень скоро) на всех не-Intel-аппаратных средствах, которые все еще поддерживаются.

Ответ 2

Похоже, что в настоящее время нет способа запросить, сколько уровней mipmap имеет текстура, за исключением проб/ошибок OPs с проверкой недопустимого значения @NicolBolas. В большинстве случаев я думаю, что его производительность не имеет значения, если размер уровня 0 не меняется часто.

Однако, предполагая, что текстура не имеет ограниченного количества уровней, спецификации дают предпочтительный расчет (обратите внимание на использование floor, а не ceiling, как показывают некоторые примеры):

numLevels = 1 + floor(log2(max(w, h, d)))
  1. Какое правило уменьшения размера для каждого уровня ниже mipmap?

    Каждый последующий меньший уровень mipmap равен половине размера предыдущего уровня, но если это значение половины является дробным значением, вы должны округлить до следующего наибольшего целого числа.
    ...
    Обратите внимание, что это расширение совместимо с поддержкой других правил, поскольку оно просто ослабляет условия ошибки и полноты для мипмапов. В то же время имеет смысл предоставить разработчикам единое согласованное правило, поскольку разработчики вряд ли захотят генерировать mipmaps для разных правил без необходимости. Одно разумное правило является достаточным и предпочтительным, и наилучшим вариантом является "этажное" соглашение.

    [ARB_texture_non_power_of_two]

Это можно, конечно, проверить с помощью метода OPs или в моем случае, когда я получил GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT с glFramebufferTexture2D(..., numLevels).

Ответ 3

Предполагая, что вы строите mipmaps стандартным образом, количество уникальных изображений будет чем-то вроде ceil (log_2 (max (ширина, высота))) + 1. Это можно легко получить, заметив, что mipmaps уменьшают размер изображения в два раза каждый раз, пока не будет один пиксель.