1

I know that there is another question with exactly the same title here however the solution provided over there does not work for my case.

I am trying to access pixel value from my compute shader. But the imageLoad function always returns 0.

Here is how I load the image:

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);
}

And here is the relevant declaration and calling code in the shader:


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;
}

I am seeing a green gradient instead of the contents of the image, which means my debugging code is in effect.

Kaan E.
  • 515
  • 4
  • 16
  • Why are you binding a texture of unknown format (the internalformat for `glTexImage` isn't hardcoded) as an image of a very specific format (the format for `glBindImageTexture` is hardcoded)? Are you sure your data matches the given format? – Nicol Bolas May 29 '20 at 14:37

1 Answers1

0

Either the internal format of the texture does not match the format which is specified at glBindImageTexture or the format argument is not a valid enumerator constant, when the two-dimensional texture image is specified, because format is used twice, for the internal format and the format (see 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);

The format argument to glBindImageTexture is 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);

Hence, internal format has to be GL_RGBA32F. A possible fomrat is 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);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174