You’re rigth, it’s not what I want to do… 
What I want to do is to Have 2 windows (maybe 2 SimpleApps). In the first one the Nifty GUI Overlay will be displayed so I can interact with it with the mouse.
In the second one a geometry using the Nifty GUI as texture (using projection) will be displayed.
The purpose is to interact with the GUI in the first window and to see the interactions replicated in the second window. I want to use this system because we can’t directly interact with a projected NiftyGUI (at least with the mouse) because it’s just a texture.
I made this implementation and it’s working (at least I think ^^) and I post it if somebody is interested. In fact if you see something terrible wrong or weird do not esitate to comment!
Remember that I’m new to Jmonkey engine and maybe I don’t understand all the “implementation details” so to make this example work I just modified/combinedTestNiftyToMesh.java and TestNiftyGui.java.
import render_3d.MyChaseCamera;
import com.jme3.app.SimpleApplication;
import com.jme3.input.ChaseCamera;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture2D;
import de.lessvoid.nifty.Nifty;
public class TestNiftyToMesh extends SimpleApplication{
Nifty nifty;
ViewPort niftyViewPort;
MyChaseCamera chaseCam;
Camera cam2;
Texture2D depthTex;
Texture2D tex;
public static void main(String[] args){
TestNiftyToMesh app = new TestNiftyToMesh();
app.setShowSettings(false);
app.start();
}
public void initChaseCamera(){
// camera initialization
// Disable the default first-person cam
flyCam.setEnabled(false);
// Enable a chase cam
chaseCam = new MyChaseCamera(cam, inputManager);
chaseCam.setMinVerticalRotation(-FastMath.PI/2);
chaseCam.setMaxVerticalRotation(FastMath.PI/2);
chaseCam.setInvertVerticalAxis(true);
chaseCam.setRotationSpeed(4f);
chaseCam.setMinDistance(2f);
chaseCam.setMaxDistance(30f);
chaseCam.setDefaultHorizontalRotation(FastMath.PI/2);
chaseCam.setDefaultVerticalRotation(0f);
chaseCam.setDefaultDistance(9f);
chaseCam.setDragToRotate(true);
cam.setViewPort(0.0f, 1.0f, 0.0f, 1.0f);
//Create overlaping viewport for nifty
cam2 = cam.clone();
cam2.setViewPort(0.0f, 1.0f, 0.0f, 1.0f);
niftyViewPort = renderManager.createMainView("View of camera #2", cam2);
niftyViewPort.setClearFlags(true, true, true);
niftyViewPort.attachScene(rootNode);
niftyViewPort.setBackgroundColor(ColorRGBA.Gray);
}
public void simpleInitApp() {
initChaseCamera();
NiftyJmeDisplay niftyDisplayGui = new NiftyJmeDisplay(assetManager,
inputManager,
audioRenderer,
guiViewPort);
NiftyJmeDisplay niftyDisplayOff = new NiftyJmeDisplay(assetManager,
inputManager,
audioRenderer,
niftyViewPort);
Nifty nifty = niftyDisplayGui.getNifty();
nifty.fromXml("Interfaces/HellowJmePerso.xml", "start");
niftyViewPort.addProcessor(niftyDisplayGui);
guiViewPort.addProcessor(niftyDisplayGui);
//Texture init
depthTex = new Texture2D(1024, 768, Format.Depth);
FrameBuffer fb = new FrameBuffer(1024, 768, 1);
fb.setDepthTexture(depthTex);
tex = new Texture2D(1024, 768, Format.RGBA8);
tex.setMinFilter(MinFilter.Trilinear);
tex.setMagFilter(MagFilter.Bilinear);
fb.setColorTexture(tex);
niftyViewPort.setClearFlags(true, true, true);
niftyViewPort.setOutputFrameBuffer(fb);
//Geometry that uses the texture (will be in another SimpleApp)
Box b = new Box(Vector3f.ZERO, 2, 2, 2);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", tex);
geom.setMaterial(mat);
//scale the texture because it does not fit the shape (dont know why..?)
geom.getMesh().scaleTextureCoordinates(new Vector2f(0.6f,0.6f));
rootNode.attachChild(geom);
}
}
Here’s the ChaseCamera I’(m using :
import com.jme3.input.ChaseCamera;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
public class MyChaseCamera extends ChaseCamera{
private boolean shiftDown = false;
private boolean controlDown = false;
private float moveSpeed = 3f;
private static Spatial centerTarget = new Geometry("rotationCenter", new Box(Vector3f.ZERO, 0.1f,0.1f,0.1f));
public MyChaseCamera(Camera cam, InputManager inputManager) {
super(cam, centerTarget, inputManager);
registerKeys(inputManager);
}
public void setRotationSpeed(float speed){
this.rotationSpeed = speed;
}
public void onAction(String name, boolean keyPressed, float tpf) {
if (dragToRotate) {
if (name.equals(ChaseCamToggleRotate) && enabled && shiftDown) {
if (keyPressed) {
canRotate = true;
if (hideCursorOnRotate) {
inputManager.setCursorVisible(false);
}
} else {
canRotate = false;
if (hideCursorOnRotate) {
inputManager.setCursorVisible(true);
}
}
}
}
if (name.equals("shiftDown")){
shiftDown = (shiftDown) ? false : true;
}
if (name.equals("controlDown")){
controlDown = (controlDown) ? false : true;
}
}
public void onAnalog(String name, float value, float tpf){
super.onAnalog(name, value, tpf);
if (name.equals("CAM_UP")){
System.out.println("up");
riseCamera(value);
}
else if (name.equals("CAM_DOWN")){
riseCamera(-value);
}
else if(name.equals("CAM_LEFT")){
moveCamera(-value, true);
}
else if(name.equals("CAM_RIGHT")){
moveCamera(value, true);
}
updateCamera(tpf);
}
public void registerKeys(InputManager inputManager) {
inputManager.addMapping("shiftDown", new KeyTrigger(KeyInput.KEY_LSHIFT));
inputManager.addMapping("controlDown", new KeyTrigger(KeyInput.KEY_LCONTROL));
inputManager.addMapping("CAM_UP", new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("CAM_DOWN", new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("CAM_LEFT", new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("CAM_RIGHT", new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addListener(this, "shiftDown", "controlDown", "CAM_UP", "CAM_DOWN", "CAM_LEFT","CAM_RIGHT");
}
public boolean isShiftDown(){
return shiftDown;
}
protected void riseCamera(float value){
centerTarget.move(0f, value*moveSpeed, 0f);
}
protected void moveCamera(float value, boolean sideways){
centerTarget.move(value*moveSpeed, 0f,0f);
}
}
And there is my XML file defining the Nifty GUI:
<?xml version="1.0" encoding="UTF-8"?>
<nifty>
<screen id="start" controller="jme3test.niftygui.TestNiftyGui">
<layer id="layer" backgroundColor="#0000" childLayout="center">
<panel id="panel" height="30%" width="30%" align="center" valign="center" backgroundColor="#f60f" childLayout="center" visibleToMouse="true">
<interact onClick="quit()"/>
<effect>
<onStartScreen name="move" mode="in" direction="top" length="300" startDelay="0" inherit="true"/>
<onEndScreen name="move" mode="out" direction="bottom" length="300" startDelay="0" inherit="true"/>
<onHover name="pulsate" scaleFactor="0.008" startColor="#f600" endColor="#ffff" post="true"/>
</effect>
<text id="text" font="aurulent-sans-16.fnt" color="#000f" text="Hello from jME3 perso" align="center" valign="center" />
</panel>
</layer>
</screen>
<screen id="end">
</screen>
</nifty>
Fell free to comment if someting is wrong or what… 