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)
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];