Как использовать glDrawArrays с массивом текстур без шейдеров
Я пытаюсь оптимизировать свой код, комбинируя мои текстуры в текстуры массива (я понял, что не могу использовать атласы текстур, потому что большинство текстур повторяются (над землей и т. Д.)). Я работаю в PyGame и PyOpenGL и никогда раньше не использовал шейдеры. Можно ли связать текстуру одного массива с glBindTexture(GL_TEXTURE_2D_ARRAY, texname)
и использовать координаты 3D-текстуры или что-то для доступа к различным слоям? Это вообще возможно без шейдеров?
На данный момент у меня есть вызов glDrawArrays для каждой текстуры с этой функцией:
def DRAW(im, array):
glBindTexture(GL_TEXTURE_2D,im)
glTexCoordPointer(2, GL_FLOAT, 32, array)
glNormalPointer(GL_FLOAT, 32, array[2:])
glVertexPointer(3, GL_FLOAT, 32, array[5:])
glDrawArrays(GL_QUADS,0,len(array)/8)
2 ответа
Как видно из спецификации в ответе @derhass, текстуры массива не поддерживаются без шейдеров.
Тем не менее, вы можете использовать 3D текстуры, чтобы сделать почти то же самое. Вы сохраняете каждую текстуру в слое 3D-текстуры. Затем вы используете первые 2 текстурные координаты, как обычно, чтобы определить положение в текстурном изображении. Третья координата текстуры используется для выбора слоя в 3D-текстуре.
Чтобы загрузить изображение в 3D текстуру, вы используете glTexSubImage3D()
, Например, скажем, ваши текстуры имеют размер 512x512, и вы хотите загрузить индекс текстуры 20:
glTexSubImage3D(GL_TEXTURE_3D, 0,
0, 0, 20, 512, 512, 1,
GL_RGBA, GL_UNSIGNED_BYTE, data);
Единственная сложная часть - правильно рассчитать 3-ю координату текстуры, поскольку координаты текстуры - это нормализованные числа с плавающей точкой. В частности, если вы используете линейную выборку, вам нужно точно попасть в центр слоя, иначе вы получите смесь изображений.
Если у вас есть n
слои в вашей 3D текстуре, координаты текстуры для слоя k
является:
(k + 0.5f) / n
Например, с n = 4
результирующие текстурные координаты для 4 слоев будут:
0.125f
0.375f
0.625f
0.875f
Обратите внимание, как значения расположены на 0,25f, как и следовало ожидать, и расположены симметрично в пределах интервала [0.0f, 1.0f]
Недостатком использования 3D-текстур является то, что они имеют меньшие ограничения по размеру. При таком подходе убедитесь, что вы не превышаете MAX_3D_TEXTURE_SIZE
,
Я бы посоветовал вам научиться использовать шейдеры. Поначалу это может показаться немного пугающим, потому что это, безусловно, больше работы для очень простых случаев использования. Но вы поймете, что как только вы освоитесь с этим, они действительно упростят ситуацию, когда ваша функциональность станет более сложной. Часто гораздо проще написать код GLSL, который будет выполнять именно то, что вы хотите, вместо того, чтобы пытаться выяснить, как правильно установить несколько десятков значений состояния для получения желаемых результатов. И, конечно, шейдеры позволяют реализовать функциональность, которая просто невозможна в фиксированном конвейере.
Массивы текстур нельзя использовать без шейдеров. Они никогда не были частью конвейера с фиксированной функцией. Здесь нет GL_TEXTURE_2D_ARRAY
включить бит в GL.
Фиксированная обработка фрагмента функции указана в разделе 16 в спецификации профиля совместимости OpenGL 4.5., Раздел 16.2 гласит:
Текстуры массивов и мультисэмплов поддерживаются только шейдерами и могут быть недоступны для текстурирования с фиксированными функциями.
В исходном расширении GL_EXT_texture_array вы найдете следующие операторы:
(2) Должны ли текстурные массивы поддерживаться для обработки фрагментов с фиксированной функцией?
РЕШЕНО: Нет; Считается, что оно того не стоит. Обработка фрагментов с фиксированной функцией может быть легко поддержана, позволяя приложениям включать или отключать
TEXTURE_1D_ARRAY_EXT
или жеTEXTURE_2D_ARRAY_EXT
,Обратите внимание, что при обработке фрагментов с фиксированными функциями могут возникнуть проблемы с поиском текстур двумерных массивов текстур с отображением теней. Учитывая, что все текстуры поиска являются проективными, в общей сложности потребуется пять координатных компонентов (s, t, layer, глубина, q).
(3) Если поддерживается фиксированная функция, следует ли делить номер слоя (T или R) на Q в поисках проективной текстуры?
РАЗРЕШЕНО: Это не нужно решать в этом расширении, но это будет проблемой. Вероятно, есть случаи, когда приложение хотело бы разделить (обрабатывать R более или менее как S/T); возможно, есть и другие случаи, когда разделение было бы нежелательным. Многим разработчикам все равно, и они могут даже не знать, для чего используется координата Q! Значение по умолчанию 1.0 позволяет приложениям, которые не заботятся о проективных поисках, просто игнорировать этот факт.
Для программируемого затенения фрагмента приложение может кодировать его любым способом и использовать непроективный поиск. Поскольку деление на Q для проективного поиска является "бесплатным" или "дешевым" на оборудовании OpenGL, компиляторы могут распознавать проективный шаблон в вычисленных координатах и генерировать код соответствующим образом.
Когда текстуры массива были расширены как основная функция OpenGL, это не изменилось.