That’s a tough challenge. You might be
able to fake it using 2 methods:
System.setProperty(“sun.awt.noerasebackground”, “true”);
This will turn off automatic background clearing
of AWT components, which GLCanvas is based on.
Use the Robot class to capture an image of
your desktop and turn it into a JOGL texture
which you use to fill the background of your
window.
I would recommend using the GLJPanel. This is a pure-Java Swing component with which you should be able to enable transparency. It has hardware acceleration so it’s faster than a pure software rendering component and supports the latest OpenGL features. If it doesn’t work for you then take a look at its internals (the hardware acceleration path is built with pbuffers, which are exposed in JOGL’s public API) and take out what you need, which would include the offscreen rendering and texture readback.
This seems to only not redraw it during resizing.
I’ve set up a JFrame with no other components.
The window shows the default light blue color (I think) . If I don’t set the property, then it resizes and retains it’s color. If I set the property to true, then it shows through during resize, but leaves rubbish behind at intervals where the border was as it resized, and it also fills out with colour when i finish the resize. unfortunately not transparent.
Perhaps i’m missing something.
This smells very CPU intensive. Especially when I will have at least one canvas the size of the screen ALWAYS as the bottom-most window. if I have to grab a texture for every window that’s open over the canvas 23 times per second (if thats my refresh rate), this is going to hurt performance hugely.
Hmmmm.
Ken, I’ll have to read your response again, perhaps a few times, to see what I have to do on that idea.
I just realized I probably misunderstood your question. The AWT unfortunately does not currently support transparent top-level windows. However, if you’re doing an MDI application with JInternalFrames, then using the GLJPanel should solve your problem as Swing components do support transparency.
To do a Transparent window you’re going to have to grab the pixel information that lies beneath the window and draw that to the “transparent” window. There is no simple way around this. Transparency is an illusion, as are most things in the hacky world of graphics programming - there is no magic “please make my window seethru” method.
I had a similar problem where I needed to build a “magnifying glass” for one of my scrolling visuals. I used glCopyPixels to draw to a GLCanvas that was placed in a Window with no decorations and I used JDK1.5’s useful setAlwaysOnTop method to keep the “magnifying glass” on top of the other windows.
TO get the pixel information underneath your window is going to be tricky if you’re spanning multiple windows that aren’t necessarily processes of your own. For that you may have to resort to some JNI to query the OS for the pixel info on desktop at a certain screen coordinate.
This smells very CPU intensive. Especially when I will have at least one canvas the size of the screen ALWAYS as the bottom-most window. if I have to grab a texture for every window that’s open over the canvas 23 times per second (if thats my refresh rate), this is going to hurt performance hugely.
[/quote]
You can write a vertex shader to lookup the pixel info on a texture.
texture lookup is the fastest thing a GPU can do, equivalent (faster even) to a CPU looking up something in memory.
[quote]I just realized I probably misunderstood your question. The AWT unfortunately does not currently support transparent top-level windows. However, if you’re doing an MDI application with JInternalFrames, then using the GLJPanel should solve your problem as Swing components do support transparency.
[/quote]
Thanks for the suggestion Ken. With a little more targeted dogpiling (the meta-search-engine, not some wierd Australian game) I was able to track down a few other sources.
As a result, I have developed a simple sample (sorry) using a JDesktopPane and JInternalPane(s) where the internal panes are either transparent or translucent. No robot, no grabbing pixels, etc.
Now I just have to incorporate a GLJPanel, and away we go.
Download the source code for the jogl-demos project from the latest JOGL distribution. The jgears and jrefract demos contain examples of drawing OpenGL graphics with a transparent background over Java2D rendering.
The speed isn’t all that great but the Java2D team and I are working on a prototype of integration of this with the Java2D OpenGL pipeline and so far the results look fantastic. There are some issues to fix but hopefully we’ll see the capability for this show up in later Mustang and JOGL builds.
Ken, can you elaborate on this integration.
Is it the same thing as what I asked about
before: sharing of context between Java2D
and JOGL so they can both render to the
same canvas?
It turns out that sharing the actual OpenGL context is a bad idea for various reasons but it seems feasible to create another OpenGL context on the Java2D OpenGL drawable (HDC, GLXDrawable, etc.) from within JOGL’s code. This work is still in the prototype phase and there are several issues still to fix but it’s looking pretty good so far. Basically if your code works with a GLJPanel then it should work unmodified when integrating with the Java2D OpenGL pipeline. The only minor difference is that if you’re using a transparent GLJPanel then you need to optionally skip clearing the color buffer if you want Java2D rendering to show through the alpha=0 portions of your OpenGL rendering.
P.S. This integration will only be accessible via JOGL’s GLEventListener callback model. There are tricky threading and other issues which we are not going to expose in the public API.