Краткий ответ - texStorage2D
и texStorage3D
выделить всю текстурную память заранее. Где texImage2D
и texImage3D
выделяют по одному уровню MIP за раз.
texSubImage2D
и texSubImage3D
ничего не выделяют. Они просто копируют данные на mip-уровень текстуры, который ранее был назначен одной из вышеперечисленных функций.
Что касается того, почему то или другое. texStorage2D
и texStorage3D
могут немедленно выделять память на GPU. texImage2D
и texImage3D
не могут, поскольку они не знают полную текстуру (все mips), пока вы действительно не попытаетесь что-то нарисовать с помощью текстуры. Другими словами, texStorage2D/3D
может быть более эффективным, если texImage2D/3D
более гибким.
Для того, чтобы текстура могла быть визуализирована, все уровни mip, которые вы собираетесь использовать, должны иметь один и тот же внутренний формат и правильные размеры.
Когда вы вызываете texStorage2D/3D
, вы сообщаете размер уровня MIP 0 (самый большой уровень) и сколько всего уровней MIP нужно выделить. Допустим, вы указываете ему внутренний формат gl.RGBA8
, ширину и высоту 8 и 4 уровней MIP.
gl.texStorage2D(gl.TEXTURE_2D,
4, // 4 levels
gl.RGBA8, // internal format
8, // width
8); // height
Он будет выделять mip-уровни 8x8x4, 4x4x4, 2x2x4, 1x1x4, все 4 уровня mip. Он знает, что все они RGBA8. Он знает, что все они подходящего размера. Текстуры, выделенные с помощью texStorage2D
, не могут быть изменены по размеру или внутреннему формату. Если вы попытаетесь вызвать texImage2D
для текстуры, созданной с помощью texStorage2D
, вы получите сообщение об ошибке.
Если вы вместо этого сначала хорошо использовали texImage2D
, вы, вероятно, укажете первый mip
gl.texImage2D(gl.TEXTURE_2D,
0, // mip level
gl.RGBA8, // internal format
8, // width
8, // height
0, // border
gl.RGBA, // data format
gl.UNSIGNED_BYTE, // data type
data);
Итак, теперь у вас есть только 1 уровень mip, уровень # 0. Вы добавите еще 3 мипа? Они будут подходящего размера? Будут ли эти 3 MIP-формата иметь такой же внутренний формат? Вы измените уровень MIP # 0 на что-то другое, другой размер или другой внутренний формат? WebGL не знает, какой будет ваша следующая команда, ему нужно дождаться, пока вы действительно попытаетесь нарисовать текстуру, прежде чем он сможет проверить. С texStorage
вы заранее определяете размеры и форматы всех mips, поэтому вам нужно проверить только один раз. С texImage
вы не сообщаете ему все заранее, поэтому он должен снова проверить во время отрисовки, если что-то изменится.
person
gman
schedule
11.08.2020