Что делает glTexStorage?

Документация указывает, что это "распределяет" хранилище для текстуры и ее уровней. Предложенный псевдокод указывает, что это для уровней mipmap.

Как использование glTexStorage относится к glGenerateMipmap? glTexStorage кажется, "блокирует" размер хранилища текстур. Мне кажется, это будет только для того, чтобы сделать вещи менее гибкими. Должны ли быть выгоды от производительности, которые должны быть здесь?

Это довольно новый и доступный только в 4.2, поэтому я попытаюсь избежать его использования, но я смущен, потому что его описание делает его очень важным.

Как хранилище для текстур управляется в более ранних версиях GL? Когда я звоню glTexImage2D, я эффективно удаляю и освобождаю хранилище, ранее связанное с дескриптором текстуры, да? и создание mipmaps также автоматически обрабатывает хранилище для меня.

Я помню, используя метод старой школы glTexSubImage2D для реализации рендеринга в OpenGL 2-стиле для выполнения некоторых эффектов после обработки в предыдущем эксперименте с двигателем. Имеет смысл, что glTexStorage приведет к более разумному способу управления ресурсами, связанными с текстурой, теперь, когда у нас есть лучшие способы сделать RTT.

Ответ 1

Чтобы понять, что делает glTexStorage, вам нужно понять, что делают функции glTexImage*.

glTexImage2D выполняет три функции:

  • Он выделяет хранилище OpenGL для определенного уровня mipmap с определенным размером. Например, вы можете выделить 2D-изображение размером 64x64 как mipmap level 2.
  • Он устанавливает внутренний формат для уровня mipmap.
  • Он загружает пиксельные данные в текстуру. Последний шаг необязателен; если вы передаете значение NULL в качестве значения указателя (а объект буфера не привязан к GL_PIXEL_UNPACK_BUFFER), то передача пикселов не происходит.

Создание mipmapped текстуры вручную требует последовательности вызовов glTexImage, по одному для каждого уровня mipmap. Каждый из размеров уровней mipmap должен быть правильного размера, основываясь на предыдущем размере уровня.

Теперь, если вы посмотрите на раздел 3.9.14 спецификации GL 4.2, вы увидите две страницы правил, которые должны следовать текстурному объекту, чтобы они были "полными". Доступ к объекту текстуры, который является неполным, не может быть доступен.

Среди этих правил такие вещи, как "mipmaps должны иметь соответствующий размер". Возьмем пример, который я привел выше: 2D-изображение размером 64x64, которое является уровнем mipmap 2. Было бы совершенно правильно использовать OpenGL-код для распределения уровня mipmap 1, который использовал текстуру 256x256. Или 16x16. Или 10x345. Все они были бы совершенно функциональными в отношении исходного кода. Очевидно, они создавали бы бессмыслицу как текстуру, так как текстура была бы неполной.

Снова рассмотрим mipmap 64x64 2. Я создаю это как свое первое изображение. Теперь я мог бы создать mipmap 128x128 1. Но я мог бы также создать mipmap с размером 128x12 9 1. Оба они полностью согласуются с уровнем mipmap 64x64 2 (размеры mipmap всегда округляются вниз). Хотя они оба последовательны, они также имеют разные размеры. Если драйвер должен распределить всю цепочку mipmap сразу (что вполне возможно), какой размер он выделяет? Он не знает. Он не может знать, пока вы явно не выделите остальных.

Вот еще одна проблема. Скажем, у меня есть текстура с полной цепью mipmap. Это, по правилам, полная текстура. И затем я снова назову glTexImage2D. Что теперь? Я мог бы случайно изменить внутренний формат. Каждый уровень mipmap имеет отдельный внутренний формат; если они не все согласны, то текстура не завершена. Я мог бы случайно изменить размер текстуры, снова сделав текстуру незавершенной.

glTexStorage предотвращает все эти возможные ошибки. Он создает все мипмапы, которые вы хотите передними, учитывая размер базового уровня. Он выделяет все эти mipmaps с одним и тем же форматом изображения, поэтому вы не можете его испортить. Это делает текстуру неизменной, поэтому вы не можете прийти и попытаться сломать текстуру с плохим вызовом glTexImage2D. И это предотвращает другие ошибки, которые я даже не удосужился покрыть.

Вопрос не в том, что делает glTexStorage? Вопрос в том, "почему мы так долго прошли без него".

glTexStorage не имеет отношения к glGenerateMipmap; они являются ортогональными функциями. glTexStorage выполняет именно то, что он говорит: он выделяет пространство для хранения текстур. Он не заполняет это пространство чем-либо. Таким образом, он создает текстуру с заданным размером, заполненным неинициализированными данными. Подобно glRenderbufferStorage выделяет рендерингбуфер с заданным размером, заполненным неинициализированными данными. Если вы используете glTexStorage, вам нужно загрузить данные с помощью glTexSubImage (так как glTexImage запрещено на неизменяемой текстуре).

glTexStorage создает пространство для mipmaps. glGenerateMipmap создает сами данные mipmap (меньшие версии базового слоя). Он также может создавать пространство для mipmaps, если это пространство еще не существует. Они используются для двух разных вещей.

Ответ 2

Перед вызовом glGenerateMipmap необходимо установить базовый уровень mipmap. (либо с изменяемым, либо с неизменным хранением).so..., вы можете использовать glTexImage2D+glGenerateMipmap только, более просто!