Hello discourse,
I'm trying to use image() to draw a movie that contains transparency and it does not work when using opengl. I'm doing this:
Code:
movie = new Movie(this, "mymovie.mov");
(...)
image(movie, 0, 0, 100, 100);
And when the movie is drawn, its background is set to black, as if the alpha channel was always set to 1.
Here's a few clues:
1. Using JAVA2D works, and the movie IS transparent where it should
2. Using set() or copy() produce the same result, with the movie transparent areas being opaque instead
3. Using image() with an image with transparency (PNG) works as intended
Here's where it gets weird though: if I try to copy the movie (as if it was an image) to another image, and then draw this new image, it works. Similarly, using alpha(get(x,y)) properly reads the transparenty of transparent pixels as being 0. So it's not a problem with the movie but apparently something with how image() accesses the image of a movie under OpenGL; alpha is ignored. So I'm doing this now:
Code:
movie = new Movie(this, "mymovie.mov");
(...)
imageBuffer = createImage(movie.width, movie.height, ARGB);
imageBuffer.copy(movie, 0, 0, movie.width, movie.height, 0, 0, movie.width, movie.height);
image(imageBuffer, 0, 0, 100, 100);
And it works fine. The problem, however, is that the additional copy() puts some additional strain in my execution - I already have a good number of videos I'm processing this way, and it's starting to make it slower than I'd like it to be. It works if I just shrink the video then draw it at the same screen size as before, but it loses quality as a result. And it's not something *too* crazy, it just has a number of small videos with transparency.
*Other* solution I'm looking into is using OpenGL to directly draw the image content, using the solution proposed
here. I've modified the javaToNativeRGB function to preserve alpha so it also works and keeps alpha intact, and is pretty fast:
Code:
PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;
GL gl = pgl.beginGL();
IntBuffer buf = BufferUtil.newIntBuffer(movie.width * movie.height);
javaToNativeRGB(movie);
buf.put(movie.pixels);
buf.rewind();
//gl.glPixelZoom(1, 1);
gl.glRasterPos2i(__x, __y);
gl.glDrawPixels(movie.width, movie.height, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buf);
pgl.endGL();
However, it introduces new problems, as it uses glDrawPixels() and that doesn't take interpolation into account (if I actually use glPixelZoom), *and* won't let me rotate the content, something I need for a few specific movies.
So my question is, is there anyway to use image() with a movie on OpenGL preserving alpha channel, *or* to have some way to write it fast to the screen? This is just 2D, no depth or anything needed... I'm really at a loss here, because anything I try is either too slow or just doesn't work as intended.
Any help is appreciated. Thanks.