Here's a solution that works on XP. I'll try to update it. Sorry about the logger, I'm using another library for that. Basically call start()/stop() rather than begin()/end()
-Jeff
/**
* Xith3D on another thread for windows (and hopefully everything else).
*
* @author Jeff Hoye
*
*/
public abstract class DisplayThread extends RenderLoop {
public Canvas3DPanel canvas3D;
public Xith3DEnvironment xithEnv;
Thread thread;
Logger logger;
private Object lock;
boolean initialized = false;
boolean running = false;
/**
* Runs init() on own thread, but blocks unitl done.
*
* @param name
* @param logger
*/
public DisplayThread(String name, Logger logger) {
this.logger = logger;
logger.log("DisplayThread.ctor()");
lock = new Object();
thread = new Thread(new Runnable() {
@Override
public void run() {
runMe();
}
}, name);
thread.start();
synchronized(lock) {
if (initialized) return;
try {
lock.wait(); // block the ctor until done with init() ... can take a while
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
}
}
public void runMe() {
init();
synchronized(lock) {
initialized = true;
lock.notify(); // this lets the ctor continue
}
while(true) {
try {
synchronized(lock) {
if (!running) {
lock.wait(); // if not running block
}
}
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
logger.log(this+".beginning()");
begin();
}
}
Runnable task;
public void init() {
xithEnv = new Xith3DEnvironment();
setXith3DEnvironment(xithEnv);
canvas3D = new Canvas3DPanel();
xithEnv.addCanvas( canvas3D.getCanvas() );
try {
InputSystem.getInstance().registerNewKeyboardAndMouse( canvas3D.getCanvas().getPeer() );
} catch (Exception e) {
logger.logException("Error in "+toString()+".init()", e);
}
}
public String toString() {
return thread.toString();
}
public void start() {
logger.log(this+".start()");
synchronized(lock) {
running = true;
lock.notify();
}
}
public void stop() {
logger.log("stopping");
synchronized(lock) {
running = false;
}
end();
}
}
Then to use it:
renderLoop = new DisplayThread("Render",logger) {
@Override
protected void prepareNextFrame( long gameTime, long frameTime, TimingMode tm ) {
super.prepareNextFrame(gameTime, frameTime, tm);
render();
}
};
// set up geometry etc
renderLoop.start();