imageLoad glsl всегда возвращает 0 в вычислительном шейдере OpenGL 4.3

Я знаю, что есть еще один вопрос с точно таким же названием здесь, однако предложенное там решение не работает для моего случая.

Я пытаюсь получить значение пикселя из своего вычислительного шейдера. Но функция imageLoad всегда возвращает 0.

Вот как я загружаю изображение:

void setTexture(GLuint texture_input, const char *fname)
{
    // set texture related

    int width, height, nbChannels;
    unsigned char *data = stbi_load(fname, &width, &height, &nbChannels, 0);
    if (data)
    {
        GLenum format;
        if (nbChannels == 1)
        {
            format = GL_RED;
        }
        else if (nbChannels == 3)
        {
            format = GL_RGB;
        }
        else if (nbChannels == 4)
        {
            format = GL_RGBA;
        }
        glActiveTexture(GL_TEXTURE0 + 1);
        gerr();
        glBindTexture(GL_TEXTURE_2D, texture_input);
        gerr();
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        gerr();
        glTexImage2D(GL_TEXTURE_2D, // target
                     0,             // level, 0 means base level
                     format,        // internal format of image specifies color  components
                     width, height, // what it says
                     0,             // border, should be 0 at all times
                     format, GL_UNSIGNED_BYTE, // data type of pixel data
                     data);
        gerr();
        glBindImageTexture(1,             // unit
                           texture_input, // texture id
                           0,             // level
                           GL_FALSE,      // is layered
                           0,             // layer no
                           GL_READ_ONLY,  // access type
                           GL_RGBA32F);

        // end texture handling
        gerr();
        glBindTexture(GL_TEXTURE_2D, 0); // unbind
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);
}

А вот соответствующее объявление и код вызова в шейдере:


layout(rgba32f, location = 1, binding = 1) readonly uniform image2D in_image;

struct ImageTexture
{
    int width;
    int height;
};

vec3 imageValue(ImageTexture im, float u, float v, in vec3 p)
{
    u = clamp(u, 0.0, 1.0);
    v = 1 - clamp(v, 0.0, 1.0);
    int i = int(u * im.width);
    int j = int(v * im.height);

    if (i >= im.width)
        i = im.width - 1;

    if (j >= im.height)
        j = im.height - 1;

    vec3 color = imageLoad(in_image, ivec2(i, j)).xyz;

    if (color == vec3(0))
        color = vec3(0, u, v); // debug 

    return color;
}

Я вижу зеленый градиент вместо содержимого изображения, что означает, что мой код отладки действует.


person Kaan E.    schedule 29.05.2020    source источник
comment
Почему вы привязываете текстуру неизвестного формата (внутренний формат для glTexImage не жестко закодирован) как изображение очень определенного формата (формат для glBindImageTexture жестко закодирован)? Вы уверены, что ваши данные соответствуют указанному формату?   -  person Nicol Bolas    schedule 29.05.2020


Ответы (1)


Либо внутренний формат текстуры не соответствует формату, указанному в glBindImageTexture или аргумент формата не является допустимой константой перечислителя, когда указано двумерное изображение текстуры, потому что format используется дважды, для внутреннего формата и формат (см. glTexImage2D):

glTexImage2D(GL_TEXTURE_2D, // target
                0,             // level, 0 means base level
                format,        // internal format of image specifies color
                // components
                width, height, // what it says
                0,             // border, should be 0 at all times
                format, GL_UNSIGNED_BYTE, // data type of pixel data
                data);

Аргумент format для glBindImageTexture равен GL_RGBA32F:

glBindImageTexture(1,             // unit
                    texture_input, // texture id
                    0,             // level
                    GL_FALSE,      // is layered
                    0,             // layer no
                    GL_READ_ONLY,  // access type
                    GL_RGBA32F);

Следовательно, внутренний формат должен быть GL_RGBA32F. Возможный формат: GL_RGBA:

glTexImage2D(GL_TEXTURE_2D, // target
                0,             // level, 0 means base level
                GL_RGBA32F,        // internal format of image specifies color
                // components
                width, height, // what it says
                0,             // border, should be 0 at all times
                GL_RGBA, GL_UNSIGNED_BYTE, // data type of pixel data
                data);
person Rabbid76    schedule 29.05.2020
comment
Изменение внутреннего формата на GL_RGBA32F сделало это - person Kaan E.; 29.05.2020