Почему при использовании массивов текстур не нужно привязывать семплер к шейдеру?

Я создаю массив текстур, используя GL_TEXTURE_2D_ARRAY в своем коде:

// Load all images ito opengl
unsigned int width, height;
std::vector<unsigned char> textures;
int num = 0;
for ( auto each : image_list )
{
    // Load PNG
    std::vector<unsigned char> buffer, this_texture;

    lodepng::load_file(buffer, each.string().c_str());
    auto lode_error = lodepng::decode(this_texture, width, height, buffer);
    if (lode_error)
    {
        LOG_ERROR("lodepng has reported this error: " + std::string(lodepng_error_text(lode_error)));
        return false;
    }
    m_indexes.insert(std::make_pair(each.filename().string(), num));
    textures.insert(textures.end(), this_texture.begin(), this_texture.end());
    num++;
}

// Active texture
glActiveTexture(GL_TEXTURE0);

// Generate texture
glGenTextures(1, &m_texture_id);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_id);

// Send pixels
glTexImage3D(GL_TEXTURE_2D_ARRAY,
             0,
             GL_RGBA,
             width, height,
             image_list.size(),
             0,
             GL_RGBA,
             GL_UNSIGNED_BYTE,
             textures.data());

// Set options
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Вот шейдеры, которые я использую:

Вершинный шейдер

#version 430 core

/* layouts */
layout (location = 0) in vec3 in_vertex;
layout (location = 1) in vec2 in_uv;
layout (location = 2) in vec4 in_tint;
layout (location = 3) in mat4 in_model;
layout (location = 7) in vec3 in_scale;
layout (location = 8) in float in_textured_index;

/* uniforms */
uniform mat4 ortho;
uniform mat4 view;

/* outputs */
out vec4 tint;
out vec2 uv;
out float textured_index;

void main()
{
    mat4 mvp = ortho * view * in_model;
    gl_Position = mvp * vec4(in_vertex * in_scale, 1.0);
    tint = in_tint;
    uv = in_uv;
    textured_index = in_textured_index;
}

Фрагментный шейдер

#version 430 core

/* inputs from vertex shader */
in vec4 tint;
in vec2 uv;
in float textured_index;

/* output to GPU */
out vec4 fragment;

/* texture sampler */
uniform sampler2DArray sampler_unit;


void main()
{
    fragment = texture(sampler_unit, vec3(uv.xy, textured_index)).rgba;
    fragment = fragment * tint;
}

Код для привязки массива текстур:

void ArrayTextures::attach()
{
    if (glIsTexture(m_texture_id)){
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_id);
    }
}

Я заметил, что мне не нужно прикреплять блок текстуры или идентификатор текстуры к моему шейдеру, если текстура связана с указанной выше функцией. Просто работает. Хотелось бы понять почему. В OpenGL 3.X вы должны привязать семплер к своему шейдеру, прежде чем вы сможете его использовать. Есть ли за кулисами какой-то автоматизм, о котором я не подозреваю? Поскольку у меня 5700XT, может быть, это специфическая странность AMD? Какой здесь правильный способ, чтобы я мог быть уверен, что он также работает на NVIDIA?

См. также:  Гарантируется ли, что левый операнд в операторе запятой не будет фактически выполнен, если он не имеет побочных эффектов?
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 1
  1. TuxStash.de

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

    В GLSL по умолчанию почти все инициализируется 0 и 0,0. Поэтому по умолчанию Точка привязки равна 0. Если текстура привязана к блоку текстуры 0 (GL_Texture0), нет необходимости устанавливать униформу сэмплера текстуры, так как по умолчанию он равен 0.

    Я изменил его на GL_TEXTURE1, и он перестал работать. При привязке 1 к шейдеру текстуры снова отображались. Спасибо за ответ. Я просто не смотрел на инициализацию. person TuxStash.de; 03.04.2021

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: