JavaFX embedded in jme3

Everything works as it should, you are just positioning your camera wrong. Replace brain.move with (10,10,10) and you will see his legs. You can go on from there.

Comment before searching the issue:

I did the following change :

  • I remove code copied from jfx, and use the .jar
    repositories {
        //...
        maven { url "http://dl.bintray.com/jmonkeyengine/contrib" }
    }
    dependencies {
    	//...
    	compile "com.jme3x:jfx:1.+"
    }
    
  • I include src/assets as resources
    sourceSets {
    	main {
    		resources {
    			srcDirs = ["$projectDir/src/main/resources", "$projectDir/src/assets", "$projectDir/assets"]
    			exclude "**/*.blend*"
    		}
    	}
    }
    
  • with java 8, you can create Runnable simpler (no longer need to new Runnable(){...})
        	this.mp.setOnEndOfMedia(()-> {
    	    	NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
    	                inputManager,
    	                audioRenderer,
    	                guiViewPort);
    	    	nifty = niftyDisplay.getNifty();    	    	
    	    	nifty.fromXml("Interface/dummy.xml", "start", Test.this);    	    
    
        	// attach the nifty display to the gui view port as a processor
        	guiViewPort.addProcessor(niftyDisplay);   	    	
    	});
    

About the Arthur comment, my suggestion is to wrap scene modification (attach, detach, modify geometry, material,…) into SimpleApplication.enqueue when you’re not the jme’thread, eg when you process/react to event from jfx, nifty, eventbus, swing,…

  public void test() {
	this.enqueue(() -> {
		this.loadBrain();       // <-- modify the scene
		nifty.gotoScreen("end");
		return null;
	});
  }

Yes your camera doesn’t look at the brain.
alternatives to Arthur solution :

  private void loadBrain() {

      brain = (Node) assetManager.loadModel("Models/Bullock.j3o");

      //brain.setLocalScale(10f);
      brain.move(0f,-1.5f,0f);

      rootNode.detachAllChildren(); //<-- detachAll before setup the scene (geometry + lights)
      this.setupLights();
      rootNode.attachChild(brain);
      cam.lookAt(brain.getWorldTranslation(), Vector3f.UNIT_Y); // <-- loot the target
  }

Whoa it was right there, staring at me! :frowning: Well I’ve learned a lot today. David and Artur, thanks a lot for your time (…and patience :P) you guys rock! :slight_smile:

I ran the modifications successfully and…I built the code as a runnable JAR and ran it. The intro video plays fine but stalls afterwards with the last frame of the video still showing. No exceptions or error messages shown. I proceeded to drop in a few print statements and figured the code never reaches this.mp.setOnEndOfMedia() :

	this.mp.setOnEndOfMedia(()-> {
	    	NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
	                inputManager,
	                audioRenderer,
	                guiViewPort);
	    	nifty = niftyDisplay.getNifty();    	    	
	    	nifty.fromXml("Interface/dummy.xml", "start", Test.this);    	    
	
	    	// attach the nifty display to the gui view port as a processor
	    	guiViewPort.addProcessor(niftyDisplay);   	    	
    	});

Disabling the video playback results in the HUD being loaded as expected. I am clueless as to what is happening (as usual). I’m using Java 8 SE update 25 & Eclipse Luna. Any thoughts on the matter?

So it works when you run it from within eclipse, but fails when deployed as standalone jar?

Yes that is exactly what is happening.

it seems there are some issue to read video from jar. Maybe end is not detected. google about the issue. quick workaround, extract the video from the jar into local fs, and read the video from local fs.

Okay I’ll try that then. Just to clarify though this is an issue with JavaFX and not JME3-JFX, right?

It seems it’s a bug with javafx (I google without jme). You can create a 100% javafx simple app with only video player to confirm (no need to create a project a single class should be enough).

It is indeed a bug with JavaFX. Verified it this morning. I am using the workaround to play it from the local filesystem. If the bug has been reported there is a chance it’ll be fixed sooner than later. Anyways, as usual thanks for all the help David :slight_smile:

I have done a bit of refactoring, so please check if none of your code got broken (I had to do non-trivial merge, so I might have broken something accidentally).

It is start of support for scene-in-texture. Currently, we can put jfx scenes on screen-aligned pictures, with 1:1 pixel mapping. With new feature, you can put jfx scene as any texture for jme3. This will for example allow in-game computer screens with interactive content.

At this moment support is very preliminary - mostly render to texture. Tricky part is as always, event mapping back. In TestTextureContainer there is a start of support for mouse events. In final form, it would of course get moved to proper utility/manager class, but as it is broken, I left it in test class for now. You can click around and things will react, but:

  • keyboard input is not supported (should not be that hard to add)
  • popups are not getting events propagated to them (which might be a lot harder)

It seems that my previous full-screen support was working by accident - there were real popups appearing behind full screen and they were reacting to input on full screen jme3 properly. Now, there is no way to cheat like that, so I’ll have to rethink the approach. In any case, to avoid hard merges in future, I have committed work in progress.

I have tried to make API as compatible as possible, so hopefully there should be no noticeable difference.

BTW, while testing, I have noticed two issues (both of them happening without my changes as well):

  • cursor switching works in strange way around text fields (it seems that it doesn’t utilize cursor hotspot correctly, so it jumps on edges on text fields)
  • externalized windows sometimes gets broken - instead of nice window, I’m getting very long toolbar without any icons or content
1 Like

There have been new developments. I’ve noticed that 1080p videos (all that I’ve tried anyway -> in-house content, BigBuckBunny etc.) have a/v sync issues and a massive drop in the frame-rate. Videos that are 900p or lower play fine for some and for the rest play fine till the end of playback when there is an exception raised and the app crashes.

resize : 1600 x 1600
java.lang.NullPointerException
	at com.jme3x.jfx.media.TextureMovie$1.videoFrameUpdated(TextureMovie.java:147)
	at com.sun.media.jfxmediaimpl.NativeMediaPlayer$EventQueueThread.HandleRendererEvents(NativeMediaPlayer.java:464)
	at com.sun.media.jfxmediaimpl.NativeMediaPlayer$EventQueueThread.run(NativeMediaPlayer.java:396)
AL lib: (EE) alc_cleanup: 1 device not closed

Does this message make any sense to you guys? I haven’t tried another GPU (will be able to try that about 4-5 hours later) to know if anything is GPU specific.

Please go to TextureMovie line 174 and comment out ‘this.reorderData.apply(src);’

This will cause movie to display in wrong colors, but please check if it fixed a/v sync issues. If it does, then it is just cpu speed problem and there might be few solutions for that:

  • update to jme3 3.1 snapshot to get true ARGB8 support
  • we can try to opimize reordering of colors by either some smart java/native magic, or by preparing custom shader

As for the NPE, we probably try to mess around with disposed frames. It is not happening for any of my videos, but as a quick workaround, you can just add null check for argbFrame around line 120.

Commenting out line 174 fixes the a/v sync issue and just like you said the colours are displayed wrong. For the NPE, I added a null check for argbFrame around line 120 but it only lead to memory leakage. I then proceeded to add a null check + return right before line 147 in the default case of the parent switch and it seems to work. Is it acceptable for now?

Thanks Artur, for the support and evolution (I didn’t test the latest version).

FYI, the new render architecture of jme 3.1, should allow to use it as backend for javafx (prism). With this approach no more need to read Data from GPU to CPU.
I don’t have time to work on it currently, I’m focus on other.

1 Like

Please update to latest version.
I have added shader based swizzle. Use something like


final Material s1mat = new Material(this.assetManager, "com/jme3x/jfx/media/MovieShader.j3md");
s1mat.setTexture("ColorMap", this.textureMovie.getTexture());
s1mat.setInt("SwizzleMode", textureMovie.useShaderSwizzle());

and it should work a lot faster, hopefully avoiding a/v issues.

It should be fully backward compatible, so if you don’t call useShaderSwizzle, it will fall back to software conversion of formats - and then texture can be used with any of existing shaders.

I wonder if it will be possible to support YCBCR drectly in future - but it doesn’t look easy.

abies thanks for sharing :slight_smile:

Yeah i noticed the textfield stuff as well,
the externalized windows currently are really wip, you cannot even resize them properly.
I definitly will spend time there once I get back homw :slight_smile:

Also a happy new year everyone :slight_smile:

Tried the new code, this stuff is awesome! :slight_smile: Good one Artur!!

Could someone please post the latest working code? I’m having trouble getting something basic to work. I would be happy with a simple, basic example, e.g. just one button or label.

Thanks! And Happy New Year. :slight_smile: