Image Texture Binding Solution

Hi,

Trying to move along on this project of mine, but there is a really nasty problem when using textures. Currently using opengl es 3.1 for access to compute shaders, and inverse accessibility to the project.

Before compute shaders, I am trying to test the image textures with the vertex fragment pipeline, but there is a minor bug somewhere.

I can easily gen and store data in a texture, and read it in a fragment shader using a sampler, as in the following code:

:: Vertex Shader (0) ::

#version 310 es
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 iiPoint;
out vec2 point;
void main(){
      gl_Position = vec4(pos, 1.0);
      point = iiPoint;
}

:: Fragment Shader (0) ::

#version 310 es
precision highp float;
uniform sampler2D tex;
in vec2 point;
out vec4 color;
void main() {
      color = texture(tex, point);
}

:: Texture (0) ::

 float[] pixels = new *Randomized Float Array*;
 int[] texture = new int[1];
 GLES31.glGenTextures(1, texture, 0);];
 GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, texture[0]);
 GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_RGBA32F, width, height, 0, GLES31.GL_RGBA, GLES31.GL_FLOAT, FloatBuffer.wrap(pixels));

: Parameters :

GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_LINEAR);
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_LINEAR);
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_CLAMP_TO_EDGE);
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_CLAMP_TO_EDGE);

:: Vertex Array (0) ::

 int[] buffer = new int[1];
                     FloatBuffer floatBuffer = FloatBuffer.wrap(new float[]{
                             -1.0f,-1.0f,0.0f, 0.0f,0.0f,
                             -1.0f,1.0f,0.0f, 0.0f,1.0f,
                             1.0f,1.0f,0.0f, 1.0f,1.0f,
                             -1.0f,-1.0f,0.0f, 0.0f,0.0f,
                             1.0f,-1.0f,0.0f, 1.0f,0.0f,
                             1.0f,1.0f,0.0f, 1.0f,1.0f
                     });
int[] buffer = new int[1];
GLES31.glGenBuffers(buffer.length, buffer, 0);
int verticesBuffer= buffer[0];
GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, verticesBuffer);
GLES31.glBufferData(GLES31.GL_ARRAY_BUFFER, 30*Float.SIZE / Byte.SIZE, floatBuffer, GLES31.GL_STATIC_DRAW);
GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
GLES31.glGenVertexArrays(1, buffer, 0);
vao = buffer[0];
GLES31.glBindVertexArray(vao);
GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, verticesBuffer);
GLES31.glVertexAttribPointer(0, 3, GLES31.GL_FLOAT, false, 5 * Float.SIZE / Byte.SIZE, 0);
GLES31.glEnableVertexAttribArray(0);
GLES31.glVertexAttribPointer(1, 2, GLES31.GL_FLOAT, false, 5 * Float.SIZE / Byte.SIZE, 3 * Float.SIZE / Byte.SIZE);
GLES31.glEnableVertexAttribArray(1);
GLES31.glBindVertexArray(0);

:: Loop (0) ::

GLES31.glUseProgram(program);
GLES31.glBindVertexArray(vao);
GLES31.glDrawArrays(GLES31.GL_TRIANGLES, 0, 6);
GLES31.glBindVertexArray(0);
GLES31.glFinish();

If you see any problems at this point, please feel free to share. I can confirm that the above code successfully produced the randomized pixels on the display, without any corruption.

The problem is when I introduce ImageTexture bindings, and try reading from one. The code for this approach is as follows:

:: Vertex Shader (1) ::

Same as :: Vertex Shader (0) ::

:: Fragment Shader (1) ::

#version 310 es
precision highp float;
layout (rgba32f, binding =0) highp uniform readonly image2D pixels;
in vec2 point;
out vec4 color;
void main() {
      color = imageLoad(pixels, ivec2(int(point.x*width), int (point.y*height)));
} // Assume width & height are both initialized floats, and screen dimensions

:: Texture (1) ::

 float[] pixels = new *Randomized Float Array*;
 int[] texture = new int[1];
 GLES31.glGenTextures(1, texture, 0);];
 GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, texture[0]);
 GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_RGBA32F, width, height, 0, GLES31.GL_RGBA, GLES31.GL_FLOAT, FloatBuffer.wrap(pixels));
 GLES31.glTexStorage2D(GLES31.GL_TEXTURE_2D, 1, GLES31.GL_RGBA32F, width, height);

: Parameters :

GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_LINEAR);
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_LINEAR);
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_CLAMP_TO_EDGE);
GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_CLAMP_TO_EDGE);

:: Vertex Array (1) ::

Same as :: Vertex Array (0) ::

:: Loop (0) ::

GLES31.glUseProgram(program);
GLES31.glBindImageTexture(0, texture[0], 0, true, 0, GLES31.GL_READ_ONLY, GLES31.GL_RGBA32F);
GLES31.glBindVertexArray(vao);
GLES31.glDrawArrays(GLES31.GL_TRIANGLES, 0, 6);
GLES31.glBindVertexArray(0);
GLES31.glFinish();

Each time I run the image texture approach (i.e. the (1)'s), the randomized pixels lose unpredictable bits in the form of the black checkerboard band on the side of the image shown above. i.e. using the texture sampler approach (the (0)'s), there was no black band, only random bits.

I chopped the code in various places to detect the break point, and its only a problem when calling glTexStorage(), (and therefore glBindImageTexture(); because of its dependence on glTexStorage()).

Any ideas?

Calling both glTexImage2D and glTexStorage2D doesn’t make sense. It’s not an error, but the first call is redundant; the data uploaded in the first call is discarded by the second. If you use glTexStorage2D to allocate storage, you then need to use glTexSubImage2D to upload the pixel data.

Also: please use triple quotes (``` … ```) around code to preserve formatting.

Sweet. Thanks; on behalf of all future newcomers ! :slight_smile: aha