Сколько mipmaps имеет текстура в OpenGL
неважно, что я тот, кто создал текстуру в первую очередь, и я должен прекрасно знать, сколько mipmaps я загрузил/сгенерировал для него. Я делаю это для модульного теста. Кажется, нет чтобы выяснить это. Ближе всего я подошел к чему-то вроде этого:
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 width для несуществующего mipmap, если я использую графический процессор NVidia, но с Mesa он возвращает GL_INVALID_VALUE
, что заставляет меня думать, что это очень многое Неправильно.
как узнать, какие уровни mipmap я заселил текстурой?
3 ответов
спецификация немного нечеткая на этом. Он говорит, что вы получите GL_INVALID_VALUE
если параметр level "больше максимально допустимого уровня детализации". Как именно это определяется, не указано.
на документация для функции очищает его немного, говоря, что это максимально возможное количество ЛПДС для максимально возможной текстуры (GL_MAX_TEXTURE_SIZE
). Другие подобные функции, такие как glFramebufferTexture
семья явно указывает это как предел для GL_INVALID_VALUE
. Так что я ожидал этого.
таким образом, Mesa имеет ошибку. Однако вы можете обойти это, предположив, что либо 0, либо a GL_INVALID_VALUE
ошибка означает, что вы отошли от конца массива mipmap.
тем не менее, я бы предложил использовать glTexStorage
и никогда не нужно даже задавать вопрос снова. Это принудительно помешает кому-то установить MAX_LEVEL на слишком большое значение. Это довольно новый, от GL 4.2, но он реализован (или будет очень скоро) на всем оборудовании, отличном от Intel, которое все еще поддерживается.
похоже, что в настоящее время нет способа запросить, сколько уровней mipmap имеет текстура, за исключением проб/ошибок OPs с недопустимой проверкой значения @NicolBolas. В большинстве случаев я думаю, что его производительность не имеет значения, если размер уровня 0 не меняется часто.
однако, предполагая, что текстура не имеет ограниченное количество уровней, спецификации дают предпочтительный расчет (обратите внимание на использование floor
и не ceiling
как некоторые примеры дай):
numLevels = 1 + floor(log2(max(w, h, d)))
каково правило уменьшения размера для каждого последовательно меньшего уровня mipmap?
каждый последовательно меньший уровень mipmap равен половине размера предыдущего уровня, но если это Половинное значение является дробным, вы должны округлить до следующего по величине целого числа.
...
Обратите внимание, что это расширение совместимо с поддержкой других правил, поскольку оно просто ослабляет ошибку и полноту условия для MIP-карт. В то же время имеет смысл предоставить разработчикам одно согласованное правило, поскольку разработчики вряд ли захотят создавать mipmaps для разных правил без необходимости. Одно разумное правило является достаточным и предпочтительным, и наилучшим выбором является Конвенция о "нижнем" уровне.
Это, конечно, можно проверить с помощью метода OPs или в моем случае, когда я получил GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
С glFramebufferTexture2D(..., numLevels)
.
предполагая, что вы создаете mipmaps стандартным способом,количество уникальных изображений будет чем-то вроде ceil(log_2(max(width, height)))+1. Это можно легко получить, заметив, что mipmaps уменьшает размер изображения в два раза каждый раз, пока не будет одного пикселя.