androidopengl-esglslglsles

Problem with SSBO values in fragment shader


I'm writing a shader for android camera and I have an array of values that I would like to use to create an overlay. In reality it is a 2D array, but I'm setting it as 1D and just doint the math to find proper index. When I use the calculated index it looks like the shader crahes, so I either don't have any output at all or have "corrupted" output. On android opengl debugging capabilities are very limited and I'm not an expert in OpenGL.

#version 320 es
#extension GL_OES_EGL_image_external_essl3 : require
precision highp float;
uniform samplerExternalOES sTexture;
in vec2 vTextureCoord;
out vec4 fragColor;

layout(std430, binding=2) readonly buffer Overlay {
    int cols;
    int rows;
    float data[];
} overlay;

void main() {
    int x = int(gl_FragCoord.x);
    int y = int(gl_FragCoord.y);
    int index = y * overlay.cols + x;

    if (index > overlay.data.length()) {
        // use overlay.data to set the color
        float value = overlay.data[index];
        fragColor = vec4(...); // TODO: Use the value here
    } else {
        fragColor = texture(sTexture, vTextureCoord);
    }
}
private fun addOverlay(cols: Int, rows: Int, data: FloatArray) {
    val buffer = createByteBuffer(data.size * Float.SIZE_BYTES + 2 * Int.SIZE_BYTES)
    buffer.putInt(cols)
    buffer.putInt(rows)
    data.values.forEach(buffer::putFloat)
    buffer.position(0)

    val bo = intArrayOf(0)
    GLES32.glGenBuffers(1, bo, 0)
    GLES32.glBindBuffer(GLES32.GL_SHADER_STORAGE_BUFFER, bo[0])
    GLES32.glBufferData(
        GLES32.GL_SHADER_STORAGE_BUFFER,
        data.values.size * Float.SIZE_BYTES + 2 * Int.SIZE_BYTES,
        buffer,
        GLES32.GL_STATIC_READ
    )
    GLES32.glBindBufferBase(GLES32.GL_SHADER_STORAGE_BUFFER, 2, bo[0])
}

One weird thing that I have noticed is that if I directly compare cols * rows == overlay.data.length() I get false, but I'm 100% sure that it should be true. When I use extra variables it works as it should:

int size = cols * rows;
int length = overlay.data.length();

if (size == length) { // true
}

if (cols * rows == overlay.data.length()) { // false
}

What am I doing wrong? Apparently, the values I set in SSBO are correct, but something weird happens when I try to use them together.

(I would be grateful if you share debugging techniques you find useful)


Solution

  • Pretty sure you want to invert that if check ...

    if (index > overlay.data.length()) {
        // use overlay.data to set the color
        float value = overlay.data[index];