JME in JavaFX: anti-aliasing not work

Hello, I clone the code from jfx-11-jme-embedded-jayfella-github and run the demo. Everything is fine except anti-aliasing doesn’t work. Is there anybody who knows why? Thanks!

What I do:

AppSettings appSettings = myJmeGame.getSettings();
// enable anti-aliasing
appSettings.setSamples(16);

Result:

Not sure what is breaking, except that setting things like vsync, and anti-aliasing will probably not work anymore as the opengl canvas is not directly being rendered. It is being rendered to an ‘off-screen’ canvas, which is turned into an image and displayed in JavaFX. If you need javafx functionality then it is recommended to use javafx inside of jme, not jme inside of javafx. If you absolutely must run jme inside of javafx, then keep in mind you will run into these issues.

The original creator of the library is no longer maintaining it, nor the javafx inside jme. Currently I am putting together a repo with fixes for jfx in jme, and I have done several major changes to jme in jfx to allow for a much simpler implementation of jfx in jme in jfx. When I get some time I will post the fixes, but I do not believe that AA will be fixed by the changes I have made. If I get some time after I have made the changes public, then I may be able to track down what is needed to do AA in jfx.

1 Like

I believe you will need to set up the offscreen framebuffer as a multisampled buffer and then resolve it when you do the buffer copy to the JFX surface.

1 Like

Is this the only code you have?

If so, you also need to add this line before calling app.start() for the changes to take effect

app.setSettings(settings);
app.start(JmeContext.Type.Display);
1 Like

In order to use the jme in jfx binding, the start function gets called internally by the wrapper if implemented correctly.

1 Like

thanks, I have set samples correctly but it still doesn’t work

I tried to use a multi samples framebuffer, but it turns out to be white screen. Maybe the way to read pixel should change, but I have no idea how to do it. BTW I use opengl3.2.

// the original codes
// this.frameBuffer = new FrameBuffer(width, height, 1);
// this.frameBuffer.setDepthBuffer(Image.Format.Depth);
// this.frameBuffer.setColorBuffer(imageFormat);
// I try to use a multi samples framebuffer
this.frameBuffer = new FrameBuffer(width, height, numSamples);
Texture2D msColor = new Texture2D(width, height, numSamples, format);
this.frameBuffer.setColorTexture(msColor);
Texture2D msDepth = new Texture2D(width, height,numSamples,Image.Format.Depth);
this.frameBuffer.setDepthTexture(msDepth);

Result:

Framebuffers can be subtle - there are lots of things that can look right but won’t work at all. One thing that comes to mind is that with OpenGL 3 you definitely need to “resolve” a multisampled FBO before you do the copy, and that takes a specific call when you copy it (I don’t remember off the top of my head what it is, but a search should easily turn it up). You may also need to back the FBO with renderbuffers instead of textures, and blit those buffers to a texture instead of directly copying the textures.

The last time I dealt with this was in a renderer I was building from scratch, not in jME. You’ll want to log OpenGL errors as they happen - not sure how jME handles that, but worst comes to worst you can drop directly to LWJGL to do that.

1 Like

Following your suggestion, I referred to how to do it in LWJGL/OpenGL, and finally find a way to resolve multisampling FBO correctly in JME.

Thank you all.

How I do

FrameBuffer normalFrameBuffer = new FrameBuffer(width, height, 1);
normalFrameBuffer.setColorBuffer(format);
normalFrameBuffer.setDepthBuffer(Image.Format.Depth);
renderer.setFrameBuffer(normalFrameBuffer);
renderer.copyFrameBuffer(frameBuffer, normalFrameBuffer, false);
renderer.readFrameBufferWithFormat(normalFrameBuffer, frameByteBuffer, format);
renderer.setFrameBuffer(null);

Result

4 Likes