Reputation: 795
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
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
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