0

I want to pass a 2D array of single precision floats to a GLSL shader. I am trying to use glBindImageTexture for this purpose.

Before the main OpenGL render loop I define the texture and fill it with random values using

glGenTextures(1,@imagetexture);
glBindTexture(GL_TEXTURE_2D,imagetexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
setlength(arrayvalues,imwidth*imheight);
for loop:=0 to imwidth*imheight-1 do arrayvalues[loop]:=random;
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, imwidth, imheight, 0, GL_R32F, GL_FLOAT, arrayvalues);
setlength(arrayvalues,0);
glBindImageTexture( 0,                  //unit
                    imagetexture,       //texture
                    0,                  //level
                    false,              //layered
                    0,                  //layer
                    GL_READ_WRITE,      //access
                    GL_R32F);           //format

The shader code is the bare minimum for testing

#version 430

layout (binding=0,r32f) uniform image2D my_image;

void main()
{
    float f = imageLoad( my_image, ivec2(gl_FragCoord.xy) ).r;
    //f = 0.5;
    gl_FragColor=vec4(f,f,f,1.0);
}

The code all runs, but the output is always black? Any ideas what I have missed here?

The same surrounding code works fine for other shaders that do not rely on glBindImageTexture so I am assuming it is all OK.

If I unremark the f = 0.5 then I get a grey image, so it all seems OK otherwise.

2 Answers 2

1

Working code. The issue was me not originally calling glBindTexture before glBIndImageTexture and also using GL_R32F rather than GL_RED.

glGenTextures(1,@imagetexture);
glBindTexture(GL_TEXTURE_2D,imagetexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
setlength(arrayvalues,imwidth*imheight);
for loop:=0 to imwidth*imheight-1 do arrayvalues[loop]:=random;
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, imwidth, imheight, 0, GL_RED, GL_FLOAT, arrayvalues);
setlength(arrayvalues,0);
glBindImageTexture( 0,                  //unit
                    imagetexture,       //texture
                    0,                  //level
                    false,              //layered
                    0,                  //layer
                    GL_READ_WRITE,      //access
                    GL_R32F);           //format
Sign up to request clarification or add additional context in comments.

Comments

0

If you use glGenTextures to create a texture name, that texture is considered unused until you first bind it. And I don't mean glBindImageTexture; I mean glBindTexture.

glBindImageTexture does not bind the texture to a texture unit; it binds the texture to an image unit for use as an image. It does not bind it to the context for manipulation purposes. So calls to functions like glTexParameter don't care about what you've bound to image units.

You have to bind the texture with glBindTexture, then establish its information like the size and so forth, and after that, bind it for use as an image.

2 Comments

Thanks for the tip. It was an issue with needing glBindTexture. Also I have a GL_R32F rather than a GL_RED. I have updated the code to the working version in the original post as it may help someone else in the future.
OK, I answered my own question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.