Hi, first just one clarification about the nativeToJavaARGB() method because I don't think the documentation of it was very clear: it does copy the alpha component from the native input pixel values to the ARGB output, while nativeToJavaRGB() sets the alpha of the output to 255.
The nativeToJavaARGB() function has an corresponding version that operates on a single input color, and I just added the equivalent nativeToJavaRGB(int color) to the PGL class, so the following code won't run on 2.0a6 (it will in the next release):
- size(100, 100, P2D);
- int natColor;
- if (PGL.BIG_ENDIAN) {
- // Native is R G B A
- natColor = 0x01020304;
- } else {
- // Native is A B G R
- natColor = 0x04030201;
- }
- int argb = PGL.nativeToJavaARGB(natColor);
- int rgb = PGL.nativeToJavaRGB(natColor);
- println(red(argb) + " " + green(argb) + " " + blue(argb) + " " + alpha(argb));
- println(red(rgb) + " " + green(rgb) + " " + blue(rgb) + " " + alpha(rgb));
but the output should be:
1.0 2.0 3.0 4.0
1.0 2.0 3.0 255.0
Going back to the background issues. I think these are the result of just how OpenGL works. Take a look at this updated version of the test sketch I posted earlier:
- import javax.media.opengl.GL;
- import java.nio.ByteOrder;
- import java.nio.ByteBuffer;
- import java.nio.IntBuffer;
- int alphaValue = 100;
- boolean copyAlpha = true;
- int SIZEOF_INT = Integer.SIZE / 8;
- IntBuffer buffer;
- void setup() {
- size(300, 100, P2D);
- noStroke();
- loadPixels();
-
- //buffer = IntBuffer.allocate(width * height);
- buffer = ByteBuffer.allocateDirect(width * height * SIZEOF_INT).order(ByteOrder.nativeOrder()).asIntBuffer();
- }
- void draw() {
- background(255, 0);
-
- fill(255, 0, 0, alphaValue);
- rect(0, 0, 100, 100);
-
- fill(0, 255, 0, alphaValue);
- rect(100, 0, 100, 100);
- fill(0, 0, 255, alphaValue);
- rect(200, 0, 100, 100);
-
- flush(); // Need flush to actually send the geometry to the video card.
-
- PGraphicsOpenGL pg = (PGraphicsOpenGL)g;
- GL gl = pg.beginPGL().gl;
-
- buffer.rewind();
- gl.getGL2().glReadBuffer(GL.GL_BACK);
- gl.glReadPixels(0, 0, width, height, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buffer);
- buffer.get(pixels);
- pg.endPGL();
-
- background(100, 100, 255);
-
- if (copyAlpha) {
- PGL.nativeToJavaARGB(pixels, width, height);
- } else {
- PGL.nativeToJavaRGB(pixels, width, height);
- }
- updatePixels();
- }
where now I'm using a direct ByteBuffer (note how the proper native order is set). Anyways, if you set the fill color to be semitransparent (alphaValue = 100), you can actually see the underlying color (100, 100, 255) from the last fill. But this is only because copyAlpha = true so that the pixels retain the alpha value from previous drawing on the screen. If you change copyAlpha to false, then nativeToJavaRGB is used instead and the alpha of all the pixels gets set to 255. Does this make sense?