Some progress, using ellipse window, AWTGLCanvas and JPanel panel components, rotating rectangles. Here is a screenshot.
http://koti.mbnet.fi/akini/lwjgl/
But it is unusable at the moment, runs very slow eating CPU 100%. Lower part jpanel is transparent but lwjgl upper part is always opaque. I guess it was not that simple to use java 3d libraries as was hoping for. Working DirectX 3d demos I’ve seen might do some heavy tricks, although they run super smooth and low cpu%.
/**
* http://koti.mbnet.fi/akini/
* @author Aki Nieminen
* @version $Id$
*/
package fi.mbnet.akini.lwjgl;
import java.nio.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import org.lwjgl.opengl.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.util.glu.*;
import com.sun.awt.AWTUtilities;
/**
* Test translucent Java window
* http://www.java-gaming.org/index.php/topic,23127.0.html
*/
public class AWTTest extends Frame {
private Thread renderThread;
private GameCanvas canvas;
private FooPanel panel;
public void initialize() throws LWJGLException {
setUndecorated(true);
setBackground(new Color(0,0,0,0));
setTitle("AWTTest");
setSize(640, 480);
setLocation(40,40);
setLayout(new GridLayout(2,1));
canvas = new GameCanvas();
add(canvas);
panel = new FooPanel();
add(panel);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
try {
renderThread.interrupt();
renderThread.join(5*1000);
// set to opaque or window area may show garbage
Shape shape = new Rectangle(0, 0, getWidth(), getHeight());
AWTUtilities.setWindowShape(AWTTest.this, shape);
AWTUtilities.setWindowOpaque(AWTTest.this, true);
} catch (Exception ex) { }
renderThread = null;
dispose();
}
});
addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent evt) {
if (!AWTUtilities.isWindowOpaque(AWTTest.this))
return;
AWTUtilities.setWindowOpaque(AWTTest.this, false);
System.out.println("setWindowOpaque=false");
}
public void componentMoved(ComponentEvent evt) {
canvas.isInitialized = false;
System.out.println( String.format("moved to %d,%d"
, getX(), getY()
));
}
public void componentResized(ComponentEvent evt) {
//Shape shape = new Rectangle(0, 0, getWidth(), getHeight());
Shape shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
AWTUtilities.setWindowShape(AWTTest.this, shape);
canvas.isInitialized = false;
System.out.println( String.format("resized to %d,%d"
, getWidth(), getHeight()
));
}
});
// add same listeners to frame and canvas objects
addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent evt) {
switch(evt.getKeyCode()) {
case KeyEvent.VK_ESCAPE:
Frame frm = AWTTest.this;
frm.dispatchEvent(new WindowEvent(frm, WindowEvent.WINDOW_CLOSING));
break;
}
}
});
for(KeyListener listener : getKeyListeners()) {
canvas.addKeyListener(listener);
}
renderThread = new Thread(new Runnable() {
public void run() {
while(true) {
try {
Thread.sleep( (long)1000/15 );
panel.update();
canvas.update();
//panel.repaint();
//canvas.repaint();
AWTTest.this.repaint();
} catch (InterruptedException ex) {
break;
} catch (Exception ex) {
ex.printStackTrace();
//break;
}
}
}
});
renderThread.start();
}
//************************************************************
//************************************************************
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
AWTTest test = new AWTTest();
try {
test.initialize();
test.setResizable(true);
test.setVisible(true);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
//************************************************************
//************************************************************
private class GameCanvas extends AWTGLCanvas {
private int curHeight = -1;
private int curWidth = -1;
private volatile float angle;
private volatile boolean isInitialized;
private GameCanvas() throws LWJGLException {
super();
}
private void initialize() {
System.out.println("initialize");
curWidth = getWidth();
curHeight = getHeight();
GL11.glViewport(0, 0, curWidth, curHeight);
GL11.glLoadIdentity();
GLU.gluOrtho2D(0.0f, (float)curWidth, 0.0f, (float)curHeight);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
public void update() {
angle += 2.0f;
}
public void paintGL() {
try {
//if (getWidth() != curWidth || getHeight() != curHeight) {
if (!isInitialized) {
initialize();
isInitialized = true;
}
// clear background
GL11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
// rotate box at a center
GL11.glPushMatrix();
GL11.glColor3f(1f, 1f, 0f);
GL11.glTranslatef((float)curWidth / 2.0f, (float)curHeight / 2.0f, 0.0f);
GL11.glRotatef(angle, 0f, 0f, 1.0f);
GL11.glRectf(-50.0f, -50.0f, 50.0f, 50.0f);
GL11.glPopMatrix();
swapBuffers();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
//************************************************************
//************************************************************
private class FooPanel extends JPanel {
double angle = 0;
private void update() {
angle += 2;
if (angle >= 360) angle = 0;
}
protected void paintComponent(Graphics g) {
final int R = 040;
final int G = 140;
final int B = 240;
Paint p = new GradientPaint(0.0f, 0.0f,
new Color(R, G, B, 0),
getWidth(), getHeight(),
new Color(R, G, B, 255),
false
);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(new Color(150,60,170,127));
g2d.rotate(Math.toRadians(angle), getWidth()/2, getHeight()/2);
g2d.translate(getWidth()/2-100, getHeight()/4-40);
g2d.fillRect(50, 50, 100, 100);
}
}
}