SWT and JPCT?

Started by Tobias, December 11, 2005, 05:49:21 PM

Previous topic - Next topic

Tobias

Quite self-explanatory subject line. JPCT is designed to work with AWT. how about SWT? I read somewhere that that would be possible, don't remember where. The library looks really good to me, don't have to learn OpenGL to use it, and has been around for a number of years.

EgonOlsen

For OpenGL support, jPCT uses LWJGL, which can either render into a native window of its own or into an awt canvas. There is no support for SWT in LWJGL as far as i know. And i do know nothing about SWT, so i don't know if it's possible to use that awt canvas inside of SWT by using a kind of hack or whatever.

The Librarian

Hi there,

I've been working on an MMORPG project for some time now and I've recently decided to switch to 3D/OpenGL. Who is going to be suprised if I say that seeing the Technopolies screenshots greatly influenced my decision ? ;) (great work rolz !)

Anyway, I'm using the Eclipse RCP framework for the client software (the server being in Erlang), which means SWT/JFace everywhere. Since Eclipse 3.2, the LWJGL can be perfectly integrated with SWT, so I assume it won't be too much of a problem to use jPCT.

Has anyone tried that yet ? I'll try to get it to work tonight when I get home from work, and since I'm new to jPCT it may involve quite a few trials...

Thanks !

The Librarian

Okay, spent some time poking around, yielding nothing...

The SWT way to use LWGJL, as described in Snippet195, is using a GLCanvas :

Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new FillLayout());
GLData data = new GLData();
data.doubleBuffer = true;
GLCanvas canvas = new GLCanvas(composite, SWT.NONE, data);
canvas.setCurrent();
try {
GLContext.useContext(canvas);
} catch(LWJGLException e) { e.printStackTrace(); }

//
// OpenGL stuff using the LWJGL bindings
//

canvas.swapBuffers();


Et voila, the scene is rendered in your canvas...

I tried to do basically the same stuff with jPCT : create the GLCanvas and init the GLContext. But when I call buffer.displayGLOnly(), a new window is created by jPCT.

Any idea on how to tell it to draw to the GLCanvas ? Or is a new version of buffer.display() necessary ?

Thanks !

EgonOlsen

You *may* try to put that part into the startPainting()-method of a IPaintListener and excute it once, but i somehow doubt that this will work. If it doesn't, i have to think about another solution...

The Librarian

Tried something like this :

buffer = new FrameBuffer(640, 480, FrameBuffer.SAMPLINGMODE_NORMAL);
   
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);
   
IPaintListener listener = new IPaintListener() {
private static final long serialVersionUID = 4586527128365364279L;
public void startPainting() {
    Global.logger.debug("Start painting");
    canvas.setCurrent();
           try {
        GLContext.useContext(canvas);
           } catch(LWJGLException e) { e.printStackTrace(); }
    }
public void finishedPainting() {
       }
};
buffer.setPaintListener(listener);

buffer.clear();
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();



Simply enabling the OpenGL renderer opens the jpct window, is this normal ? A side effect of the RCP framework, or something I did wrong ? Nothing is drawn in my GLCanvas...

In any case, it'll be great to have this engine available in SWT :)

EgonOlsen

Well, that's caused by the normal LWJGL initialization code. Judging from the snippet you've posted, i assume that none of this is needed when using SWT. Sadly, i don't have the time to bother with SWT right now, but i've uploaded a modified jar, that allows to skip LWJGL init here: http://www.jpct.net/download/beta/jpct.jar
Just set Config.glSkipInitialization=true before enabling the renderer and make sure that you did the SWT specific initialization before too. Using this hack, display() will no longer swap the buffers, so you have to do this yourself (like it's done in the snippet). I'm not sure if this will work...it's worth a try though.

The Librarian

Thanks a lot, I'll try that and keep you posted !

The Librarian

OK it works, thank you very much ! And in an RCP ViewPart too :)
If anyone is interested, here is the init() function I use :


private void init() {
canvas.setCurrent();
try {
GLContext.useContext(canvas);
} catch(LWJGLException e) { e.printStackTrace(); }

buffer = new FrameBuffer(640, 480, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);


}


And the render() function :

private void render() {
buffer.clear();
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.displayGLOnly();
canvas.swapBuffers();
}


Finally the createPartControl() function (since this is an RCP ViewPart) :

public void createPartControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new FillLayout());
GLData data = new GLData();
data.doubleBuffer = true;
canvas = new GLCanvas(composite, SWT.NONE, data);

canvas.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
render();
}
});
canvas.addListener(SWT.Paint, new Listener() {
public void handleEvent(Event event) {
render();
}
});

               init();
       }


Don't forget the paint listener or it won't work :) (LWJGL related)

Oh and an extra question : is it possible to dynamically resize the framebuffer ? Or should I just make it as large as the screen and let the GLCanvas crop it when it is resized ?

Thanks !

EgonOlsen

:D  Great to see this working (well, actually i don't really see it, but i trust you... :wink: ). You can't resize the FrameBuffer as this would usually require a new initialization of the renderers. Just discard the former and create a new one on resize (with some delay added, so that not every resize event triggers  this...just a few times a second).

The Librarian

OK I'll do that :)

Actually the resize events are handled by the RCP framework and are sent only once per resize operation. Since I won't be using a render loop (the scene will be updated only after specific events such as player actions, network activity, etc.) it is really straightforward : add listeners, trigger the rendering at will. Frame rate is nearly constant : 0 :D (well, except during animations obviously).

And don't worry, I'll post some screenshots soon. And who knows, if I decide to stick with jPCT, you should see more of Sanctuaire on this forum :)

raft

in the last few months i was writing an eclipse plugin as a freelancer. here is what i think about swt: avoid it when possible ! swing and awt are far more superior..

r a f t