sampler2DArray - настройка и использование
Я изучаю OpenGL, и мне пришлось использовать sampler2DArray. Я весь день мучаюсь - все безрезультатно. У меня есть два вопроса:
- Как создать список текстур?
- Как использовать sampler2DArray в шейдере?
Вот результат моих попыток создать список текстур:
// textures - ids loaded textures
private int createTextureArray(GL2 gl, int[] textures, int width, int height) {
int layerCount = textures.length;
int mipLevelCount = 1;
IntBuffer texture = IntBuffer.allocate(1);
gl.glGenTextures(1, texture);
gl.glActiveTexture(GL.GL_TEXTURE0);
gl.glBindTexture(GL2.GL_TEXTURE_2D_ARRAY, texture.get(0));
gl.glTexStorage3D(GL2.GL_TEXTURE_2D_ARRAY, mipLevelCount, GL2.GL_RGBA8, width, height, layerCount);
for (int i = 0; i<textures.length; i++) {
gl.glTexSubImage3D(GL2.GL_TEXTURE_2D_ARRAY, i, // error here
0, 0, 0,
width, height, layerCount,
GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE,
textures[i]);
}
// Always set reasonable texture parameters
gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);
return texture.get(0);
}
Пример шейдера:
#version 130
uniform sampler2DArray textures;
varying vec2 UV;
...
void main() {
...
int layer = 0;
gl_FragColor = texture2DArray(textures, vec3(UV, layer));
}
Буду благодарен за помощь.
2 ответа
Текстура массива не является "списком текстур". Текстура массива - это отдельная текстура OpenGL, в которой по отдельности имеется несколько квазинезависимых слоев. Хотя вы можете концептуально рассматривать каждый слой текстуры массива как отдельную концептуальную текстуру, в OpenGL (и GLSL) это отдельный объект.
Учитывая это, интерфейс в вашей функции неверен. Он должен возвращать один объект текстуры, и он должен принимать в качестве параметра, а не массив int
(примечание: объекты OpenGL представляют собой целые числа без знака), но одно целое число: количество слоев массива, создаваемых в этой текстуре.
Как вы используете текстуру массива в GLSL просто. Ваш uniform
для сэмплера используется тип сэмплера массива-текстуры (например sampler2DArray
для 2D массивов текстур). Вы привязываете текстуру массива к той же единице изображения текстуры, которую вы указали в качестве привязки для униформы сэмплера (так же, как и для 2D-текстуры без массива).
Ваш GLSL пропускает одну вещь. Здесь нет texture2DArray
функция. Правильная функция для использования просто texture
, Тип текстуры в Post-GL 3.0 определяется исключительно параметром, а не именем функции.
В дополнение к тому, что @NicolBolas уже сказал: существует множество проблем с кодом шейдера, в основном из-за функциональности, которая устарела в версии 130:
- Нет способа
texture2DArray
в любой стандартной версии glsl. Был один в расширении EXT_texture_array, но он никогда не был интегрирован, так как в glsl 130 все функции поиска текстуры (texture2D, texture3D, ...) были заменены перегруженнымиtexture
команда. Если вы нацелены на 130 без расширений, вы должны использоватьtexture(textures, vec3(UV, layer))
varying
Ключевое слово устарело в GLSL 130 и должно быть замененоin
/out
gl_FragColor
устарел и пользовательский вывод (out
) переменная должна быть использована.
Возможно, вы захотите взглянуть на Раздел 1.2.1 Спецификации GLSL 130, в котором описаны амортизации и способы их обработки. В целом, я бы посоветовал всем не использовать 130 вообще сегодня, если только для этого нет особой причины. Лучше перейти на OpenGL 3.3+ Core Profile и GLSL 330+.