During my latest Android OpenGL ES 2 experimentation I found the need to create a small texture using pixel values which I manually filled. I used glTexImage2D to create my texture of width 3 and height 1. Note that OpenGL ES 2 is a somewhat cut-down version of OpenGL and does not support 1D textures.
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, 3, 1, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(pixels));
An RGB triple consists of a red byte, a green byte and a blue byte. Each is an unsigned byte, so it can range from 0 to 255, or in binary from 0000 0000 to 1111 1111.
A white pixel would be 255 255 255, or in binary 1111 1111 1111 1111 1111 1111
and a red pixel 255 0 0, or 1111 1111 0000 0000 0000 0000
So, how do I put these values into my pixel array. Let's try to make some bright red pixels:
byte[] pixels = new byte[3*3];
for (int x = 0; x < 3; x++) }
pixels[x*3] = 255;
pixels[(x*3)+1] = 0;
pixels[(x*3)+2] = 0;
}
The compiler doesn't like that, because bytes only go up to 127. pixels[x*3] = 127;
What if I try 127? Well, that compiles, but it only produces a dull red, half the intensity of what I wanted. How do I get above 127? Pretty easily, actually!
pixels[x*3] = (byte)255;
Casting to a byte does the trick. But why?
Going back to the bit level, what OpenGL wants is the bits in that pixel to be 1111 1111. How that is interpreted by Java is not relevant, as long as it passes those bits along correctly. In fact, Java stores its signed bytes using the Two's complement method. You can read the Wikipedia page for the full details of how that works, but for now just check out the 8-bit two's complement integers table. It shows that 1111 1111 = 255 unsigned = -1 signed. Sure enough, if we test out
pixels[x*3] = -1;
you'll find the bright red colour we're after. When we cast 255 to a byte Java is storing it as 1111 1111, which it considers to be -1. So, I could range my pixel colours from 0 to 127, then -128 to -1, but simply casting the values 0 to 255 makes it easier for me, and lets Java do the conversion. I told you it was easy.