Some1Else
Some1Else

Reputation: 795

Passing array of single precision floats to GLSL shader using glBindImageTexture

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.

Upvotes: 0

Views: 103

Answers (2)

Some1Else
Some1Else

Reputation: 795

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

Upvotes: 1

Nicol Bolas
Nicol Bolas

Reputation: 474406

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.

Upvotes: 0

Related Questions