Question

I'm strageling with openGl and can't find a solution for the following problem. I'm using openGl with Ndk and trying to generate ByteBuffer of pixels from my texture and send it to the native c.

The texture image is black and white image, meaning byte-wise:

black: expected result - 0(R) 0(G) 0(B) 1(A) - 0001

white: expected result - 1(R) 1(G) 1(B) 1(A) - 1111

The sign is not relevant here sence both numbers are positive.

This is true because in Java the state of the primitive is always signed.

Complication: we are getting a buffer of unsigned bytes so the expectations are:

black: 0(R) 0(G) 0(B) 1(A) - 0001 stays the same because left bit of every byte is 0.

white: 1(R) 1(G) 1(B) 1(A) - bit sign is always on(meaning negative number), so -127,-127,-127,-127

BUT, the strange output I'm getting is: -10 -10 -10 -1(RGBA),-10 -10 -10 -1,-10 -10 -10 -1,-10 -10 -10 -1

why there is sign if I asked for unsigned bytes? Edit: Partial explanation is that java types are still signed, so on debugger/logs/prints the value will be null depending on the left most(big endian) bit. I still don't know why this bit is 1.

why the values are -10 and -1? at least alpha byte should always be 1.

I'm setting the ByteBuffer as following:

int[] frame = new int[1];
    GLES20.glGenFramebuffers(1, frame, 0);
    RendererUtils.checkGlError("glGenFramebuffers");
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frame[0]);
    RendererUtils.checkGlError("glBindFramebuffer");
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, texture, 0);
    RendererUtils.checkGlError("glFramebufferTexture2D");


    ByteBuffer buffer = ByteBuffer.allocate(width * height * 4);
    //GLES20.glPixelStorei(pname, param);
    GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, arrayNativeType, buffer); // todo take unsigned int

    RendererUtils.checkGlError("glReadPixels");

    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
    RendererUtils.checkGlError("glBindFramebuffer");
    GLES20.glDeleteFramebuffers(1, new int[]{0}, 0);
    RendererUtils.checkGlError("glDeleteFramebuffer");
Was it helpful?

Solution

Unbelivable answer, I checked everything memory and ndk wise and at the end the problem was in my black&white shader.

Explanation: the previous wrong shader took the highest rgb value and set the r g and b according to it, that way we got the black:

float greyValue = max(fragColor.r, max(fragColor.g, fragColor.b));
gl_FragColor = vec4(greyValue, greyValue, greyValue, 1.0);

The error is that I don't know the precise color and its byte representation.

The fix was instead of greyValue to put 1, and if its value is 0 than to put 0 for r g and b.

I hope it clear.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top