JavaFX embedded in jme3

Using prism renderer instead of sw I get this exception

java.lang.RuntimeException: Requested texture dimensions (0x0) require dimensions (0x0) that exceed maximum texture size (16384)
	at com.sun.prism.es2.ES2RTTexture.create(ES2RTTexture.java:220)
	at com.sun.prism.es2.ES2ResourceFactory.createRTTexture(ES2ResourceFactory.java:158)
	at com.sun.javafx.tk.quantum.UploadingPainter.run(UploadingPainter.java:117)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
	at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
	at java.lang.Thread.run(Thread.java:745)

Now I kinda wonder a) wtf is requesting a 0x0 texture, and why is this exceed 16k …

BTW, i would strongly suggest to bundle your game with a jre anyway, as jme-jfx uses sun internal classes this is just more stable

Hm just tested with jdk 1.9_b72 same errors.

Well I found the cause for the exeption, but not the solution yet:

In the class UploadingPainter at line 114 a RTTexture object is created
before u60 it got the parameters: 1914x1048 on my windowd machine,
after u60 it got 0x0.

The variable comes from ine 97 where
int bufWidth = Math.round(viewWidth * scale); is done

after u60 the varaible comes from @92
int bufWidth = sceneState.getRenderWidth();
the renderwidth is 0.

it comes from PresentableState , wich contains a renderScale.
Apparently in u60 the ability to scale the render output is added for the swing jfxpanel (whyever)
Now since we dont set this for our embedded scne all calcualtions go to 0 (if they had a default of 1 instead of 0 all would work hrmpf)

I added a reflection hack for this, so that it also does work with the older jdk versions

// 8_u60 and later fix
try {
	Method scaler = embeddedScene.getClass().getMethod("setPixelScaleFactor", float.class);
	scaler.setAccessible(true);
	scaler.invoke(embeddedScene, 1f);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
	e.printStackTrace();
}

It works with jdk 1_8_60 now and with 1.9 as well :slight_smile:
Should be fixed in 1.159.2015-07-12_153501-ddfdf01 please test.

3 Likes

Yes, @Empire_Phoenix I can confirm that this fixes it for my situation. Thanks a lot!

JavaFX is supporting Windows DPI scaling from update 60, so that seems to be the problem. Anyway, this solves it for now.

And yeah, setting it by default to 1, seems more logical then 0.

Hy there !
First i wanna thank you guys as i appreciate your work and doing all the responses here.
While crawling through this thread i did not get an idea of a solution of my problem.
I have an existing JME Stuff which i wanna reuse in a new JavaFX8 Application.
I could it get running by creating a simpleApplication run it and add FXML HUDs to it.
Could you guys also see that the performance of the javaFX Hud is a bit sluggish ?
The hover of buttons or the drag of a SliderThumb for example are very slow.
Can i do any performance tweaks on this ?

I wanna do all my application into a simple application and are afraid of the performance of my
existing JavaFX application, which will then be all in FXML HUDs …
Thanks for any hints.
BR
Harry

The bridge has mostly one static performance penalty. copying the javafx framebuffer to jme3.
If you are using a multicore, jme3 and javafx are most likly running on different cores.
The guimanager has some experimental optimal determined settings in them.
Check if the improve your performance by enabling/diabling them.

The bridge uses a pure software javafx renderer with theses settings, as the time to grab the javafx framebuffer from the gpu is longer than to do all work on cpu usually. Also this keeps the gpu free for jme3 work.

Hy Empire_Phoenix,

thanks for the hint. I gave it a try to do the following:
called the consturctor of GUIMANAGER with the boolean of the recommendedFXsettings (false)
boolean fullScreen = false;
boolean useRecommendedFXSettings = false;
final Material guiMaterial = new Material();
testguiManager = new GuiManager(app.getGuiNode(),
app.getAssetManager(), app, fullScreen,
new ProtonCursorProvider(app, app.getAssetManager(), app
.getInputManager()), guiMaterial,
useRecommendedFXSettings);

Got that exception:

FATAL: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NoSuchMethodError: com.jme3x.jfx.GuiManager.(Lcom/jme3/scene/Node;Lcom/jme3/asset/AssetManager;Lcom/jme3/app/Application;ZLcom/jme3x/jfx/cursor/ICursorDisplayProvider;Lcom/jme3/material/Material;Z)V

As i can see that the following constructor exists:
GuiManager(final Node guiParent, final AssetManager assetManager, final Application application, final boolean fullscreen, final ICursorDisplayProvider cursorDisplayProvider, final Material customMaterial, boolean useRecommendedJFXSettings) {

}
i am without any plans for now ;(
Thanks for any hints in advance,
best regards
Harry

Are you sure that your jfx jar is uptodate, could it be that you have multiple different versions in your classpath somehow?

Cause either it should already fail at compiletime in your ide, or it should work :smile:

Take a look at the class’s sourcecode, cause your guiMaterial is not valid as well.

aaaaah what a mess,
eclipse did not take care about my changes of the jar in my user lib :wink:
I now will take care about the material as it has to be valid …
Can you tell me whats that material for ?
Which texture should it contain ?

Thanks
Harry

Hy Empire_Phoenix,

as it tells me in the sourceCode Docu:
material → “allows to specify a own Material for the gui, requires the MaterialParamter Texture with type Texture, wich will contain the RenderTarget of jfx”

I do not get the point for this.
I attached my fxml (JFX) to the guiManager and the guiManager Constructor needs a material which is the
RenderTarget of jfx ?
So whats that, RenderTarget ?

I cannot imagine what material to create an give the guiManager.
Please give me a hint for that.

Thank you.

Hi,

basically you can use a own Material for rendering onto jme.
The texture is where the jfx bridge will output its content to.

For a simple material you can look at the other constructors, they just use one of the stock jme materials.

What this can be used for is, like a material that your gui distorts on hit or similar effects.

Hy,
now i am playing around with attaching and detaching FXMLHuds.
Its working fine on attaching. But when i detach a fxml HUD, the jme behind is reacting but
the ui of the FXMLHud still stays visible.
I tried to remove all children of the FXMLHUDs mainPane and tried to set it visible(false)
with no success on it.
Has there any update or so on to be triggered in the jme stuff ?

Thanks for any hints

You should just have to call guiManager.detachHudAsync(fxmlHud) in order for it to detach it.

Is this what you are doing?

Hy iam calling

guiManager.detachHudAsync(fxmlHud);

A simple HUD containing just a colored VBox detaches correctly but if its filled with more buttons …
i am doing some more tests right now. Will post later on, thanks

Hmm strange
When the Hud is on a different Layout position it detaches correctly, code is the same but XY is different …
I reduzed the viewPort of the jme on all 4 sides.
Just on Top it stays visible …
Even the simple pane stays visible in that region where the viewport is cut (On Top side) …
My viewport is also cut on the bottom side but there its working fine …

Ahh, thats it.
As on top there is no FXMLHud overlay anyway the HUD stays visible when detached, as ther is no viewport behind either.
On bottom there is another HUD over the same position an it stays when the other one is detached.

So if there is no viewport area and no other HUD if a HUD is detached, that one stays visible but events go to jme at all.

Therfore i have to be sure that at anytime anyone HUD is attached on areas where no viewport is located of jme

Hy, got a new problem.
I am attaching a FXMLHud as Full AppSize so there is no jme stuff visible at all.
I want to make some parts of jme visible at some time ,
so i would have to “cut a hole” into that fxmlHud to be able to navigate in jme “behind”
The clipping functionality of FX doesnt allow me to “cut a hole” just to cut around the node …
I did not get any idea for a solution right now.
Thanks in advance !

Well basically you need transparent parts trough your gui.

The hud itself is invisible, so it is likely that your hudcomponents itself have a background.

You may want to work without background and use a different aproach fo it, like moving a few white panels behind all other components around.

Hy, japp you are right. Could not believe that the jme would get events even if there is a transparent FXMLHud stuff overlayed over it.It works out for me as i set transparent backgrounds. Wow this is amazing you guys even thought about the eventhandling when there is a transparent Hud “over” jme. Thanks for that guys ! Makes things really easy like a charm.

I use the JavaFX for main UI and the tonegodGUI for indicator of targets and I have the problem with tonegodGUI. The tonegodGUI drawn above the JavaFX :frowning: How do it resolve?

I cannot speak for tonegod,
but the Javafx is basically just a fullscreenquad on jme side in the gui bucket.
So if you modify it’s draw order it shold be drawn over tonegod.

take a look at the guimanager to see how it is attached.