Alpha texture to mesh

What is the proper way to render a nifty GUI containing transparent areas to a quad? When I attempt this the areas which should be transparent are simply black. I checked the repo and saw that the original test for rendering nifty to mesh was updated however it yields the same result.

erm this is more of a general question than a gui one -__-



anyway i found setting the blendmode to alpha works, however since i use a toonShader their is an outline around it is their a way to prevent post rendering on some mesh?



[java]mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);[/java]



EDIT:

actually the part thats suppose to be transparent looks more like its translucent and appears somewhat like stained glass, also while looking through it the outlines of other objects are not shown (the filters on other objects vanish weather fog, toon outline,overlay color or bloom) ,is their a way around this?

I need to create a new Nifty Display for each userPlayer. This doesn’t seem to be an issue performance wise, however I was wondering about the filter situation.

Should I apply all filters on the niftyViewport as well then?







[java]

/**

  • This is the method that should be called directly to set up the GUI portion of the EssenceControls
  • TODO: Fix odd translucency for GUI
  • @param spatial
  • @return GuiEssenceController this instance of the GUI essenceController

    */

    public GuiEssenceController start(final Spatial spatial){

    //Set Up The new NiftyViewPort

    int height = 1024;

    int width = 768;



    com.spectre.app.SpectreApplication app = Director.getApp();

    ViewPort niftyView = app.getRenderManager().createPreView("NiftyView", new Camera(height, width));

    niftyView.setClearEnabled(true);

    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(app.getAssetManager(),

    app.getInputManager(),

    app.getAudioRenderer(),

    niftyView);

    //Set Up Nifty

    nifty = niftyDisplay.getNifty();

    try {

    nifty.validateXml("Interface/EssenceInterface/EssenceInterface.xml");

    } catch (Exception ex) {

    Logger.getLogger(GuiEssenceController.class.getName()).log(Level.SEVERE, null, ex);

    }

    nifty.fromXml("Interface/EssenceInterface/EssenceInterface.xml", "start");

    niftyView.addProcessor(niftyDisplay);

    //Create a new FrameBuffer

    FrameBuffer fb = new FrameBuffer(height, width, 1);

    fb.setDepthBuffer(Format.Depth);

    //Create a basic Texture

    Texture2D tex = new Texture2D(height, width, Format.RGBA8);

    tex.setMinFilter(MinFilter.Trilinear);

    tex.setMagFilter(MagFilter.Bilinear);



    fb.setColorTexture(tex);

    niftyView.setClearEnabled(true);

    niftyView.setOutputFrameBuffer(fb);

    //Create a Quad to render Nifty To

    Geometry geom = new Geometry("EssenceGUI", new Quad(.5f,.5f));

    Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");

    mat.setTexture("ColorMap", tex);

    //Renders the alpha portion as translucent

    mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);

    //Render Both Sides

    mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);

    geom.setMaterial(mat);

    //Translate the Quad behind the Geom

    geom.rotate(0, com.jme3.math.FastMath.PI, 0);

    com.jme3.bounding.BoundingBox bb = ((com.jme3.bounding.BoundingBox)spatial.getWorldBound());

    geom.setLocalTranslation(.25f,-.25f+bb.getYExtent()/2, -bb.getZExtent()*3);

    ((com.jme3.scene.Node)spatial).attachChild(geom);



    return this;

    }

    [/java]

mhh sorry did not see that issue till now.



ok if i understand well, you have a gui that is displayed next to the player.

But this gui is not in the GUI viewport right?

So…i’m afraid there is no easy way to solve this.

you can try to set the depthWrite of the gui object to false, the border should vanish, but it may have some unexpected side effects.



As i can see you render the nifty display to a texture in a pre-viewport and then apply it to a quad that is attached to the 3d view to a spatial (I suppose it’s the character).

Why not just use Nifty directly in the GUI viewport?

You could use a nifty panel in absolute position (x and y specified).

If you want the ui to move with the player, you should create a custom control that would be attached to the player.

This control would calculate the position of the UI in world space and translate it in screen space (look at camera.getScreenSpacePosition) and reposition the ui in the nifty display according to the computed coordinates.

Putting the quad in the transparent queue should work, no?

Nope because it still write depth so the edgeFilter outlines it.

And btw there will still be the “no outline through the quad” issue

ahh thanx for the replies

Setting The DepthWrite of the material to False does not seem to remedy the problem and as you said it actually causes additional issues mainly when viewing the quad in the empty game space it disappears.



As for rendering nifty Directly in the GUI viewport I will have to play around a bit more with it because the game is planned to be multiplayer so i figured the multiple instances of nifty would be fine; however, when I attempted to use the guiVieport before hand it gave some weird sizing issues. I’ll investigate your solution though thnx.



thnx for the replies again

okay now that its the weekend I can try this solution out… was the method you referring to getCamera().getScreenCoordinates(Vector3f.ZERO);?



For your solution i understand I should encapsulate everything i have under screen into a nifty panel set to absolute and access it through my nifty screenController and then finally attaching a controller to the model that feeds the screenController the screenCoordinates that will somehow translate to the characters position. Is this correct even though a vector is returned and the constraints call for an internal class SizeValue?



I understand I will have to take advantage of the ConstraintX and ConstraintY methods however for height and width i guess i would have to figure out something with the camera’s relative distance to the character correct?

Bonechilla said:
okay now that its the weekend I can try this solution out.. was the method you referring to getCamera().getScreenCoordinates(Vector3f.ZERO);?

Yes, but feeding it with Vector3f.ZERO makes little sense, but i guess it was an example.

I'm not too good with Nifty, but yes you got the main idea,

well after messing around with nifty and jME for a day i couldn’t get the display to move at all on the screen let alone allow it to seem attached to my character. Could their be something i’m missing i changed all childLayout to absolute and instead of having many layers i only have one and changed the layers into panels however nothing works any suggestions?



hmm if i can get it working it would probably be a good jME testCase for an ubiquitous UI solution…

[java]

/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.

    */



    package test.guiPosition;



    import com.jme3.app.SimpleApplication;

    import com.jme3.light.AmbientLight;

    import com.jme3.math.Vector3f;

    import com.jme3.niftygui.NiftyJmeDisplay;

    import com.jme3.scene.Spatial;

    import de.lessvoid.nifty.Nifty;

    import de.lessvoid.nifty.elements.Element;

    import de.lessvoid.nifty.screen.Screen;

    import de.lessvoid.nifty.screen.ScreenController;

    import de.lessvoid.nifty.tools.SizeValue;



    /**
  • @author Kyle Williams

    */

    public class GUIPosition extends SimpleApplication implements ScreenController{

    private Nifty nifty;

    private Screen screen;

    private Spatial model;

    private AmbientLight al;

    private Element mainPanel;

    private Vector3f screenCoordinates = new Vector3f();



    @Override

    public void simpleInitApp() {

    setUpNifty();

    this.getFlyByCamera().setMoveSpeed(30f);

    al = new AmbientLight();

    getRootNode().addLight(al);

    model = getAssetManager().loadModel("Models/Alex/Alex.j3o");

    getRootNode().attachChild(model);

    }







    @Override

    public void simpleUpdate(float tpf) {

    if(screenCoordinates.length()!=0)screenCoordinates.zero();

    getCamera().getScreenCoordinates(model.getWorldTranslation(), screenCoordinates);

    SizeValue x = new SizeValue("2%");

    SizeValue y = new SizeValue("2%");

    SizeValue height = new SizeValue("1h");

    SizeValue width = new SizeValue("1w");

    System.out.println("BEGINn"+x+"n"+y+"n"+height+"n"+width+"n END");

    updatePosition(x, y, height, width);

    }



    public void updatePosition(SizeValue newX,SizeValue newY,SizeValue newHeight,SizeValue newWidth){

    //for(Element ele:screen.getLayerElements()){

    // ele.setConstraintHeight(newHeight);

    // ele.setConstraintWidth(newWidth);

    // ele.setConstraintX(newX);

    // ele.setConstraintY(newY);

    // ele.layoutElements();

    //}

    mainPanel.setConstraintHeight(newHeight);

    mainPanel.setConstraintWidth(newWidth);

    mainPanel.setConstraintX(newX);

    mainPanel.setConstraintY(newY);

    mainPanel.layoutElements();

    mainPanel.layoutElements();

    screen.layoutLayers();

    }



    protected void setUpNifty(){

    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,

    inputManager,

    audioRenderer,

    guiViewPort);

    this.nifty = niftyDisplay.getNifty();



    nifty.fromXml("test/guiPosition/EssenceInterface2.xml", "start");

    this.screen=nifty.getScreen("start");

    this.mainPanel=screen.findElementByName("mainPanel");



    // attach the nifty display to the gui view port as a processor

    guiViewPort.addProcessor(niftyDisplay);

    }



    @Override

    public void bind(Nifty nifty, Screen screen) { }

    @Override

    public void onStartScreen() {}

    @Override

    public void onEndScreen() {}



    public static void main(String[] args){GUIPosition app = new GUIPosition();app.start();}

    }



    [/java]

Until I mess with nifty a bit more this seems to be the only way i can get it kind of working…

The only problem however is its positioning, Wheater i use local or world translation the GUI appears out of place any suggestions



*Also I can’t seem to get the height and width coordinates to work for camera zooming using screenCoordinates.getZ()

**value must be casted to int to work with screenCoordinates “px”



[java]

@Override

public void simpleUpdate(float tpf) {

if(screenCoordinates.length()!=0)screenCoordinates.zero();

getCamera().getScreenCoordinates(model.getLocalTranslation(), screenCoordinates);

System.out.println(screenCoordinates);

SizeValue x = new SizeValue(screenCoordinates.getX()+"%");

SizeValue y = new SizeValue(screenCoordinates.getY()+"%");

SizeValue height = new SizeValue(“1h”);

SizeValue width = new SizeValue(“1w”);

for(Element layer:screen.getLayerElements()){

updatePosition(layer,x, y, height, width);

layer.layoutElements();

}

screen.layoutLayers();

}



public void updatePosition(Element ele, SizeValue newX,SizeValue newY,SizeValue newHeight,SizeValue newWidth){

//ele.setConstraintHeight(newHeight);

//ele.setConstraintWidth(newWidth);

ele.setConstraintX(newX);

ele.setConstraintY(newY);

if(!ele.getElements().isEmpty()){

for(Element elem:ele.getElements()){

updatePosition(elem,newX, newY, newHeight, newWidth);

}

}

ele.layoutElements();

}

[/java]

Why are you using percentages? The values are in screen coordinates so from 0x0 - WxH

Also I see you’re applying the position to the child elements as well. I thought nifty inherits location from the parent?

i attempted that for some odd reason it wasn’t workimg for me. setting all elements was the only way i i could get it to work. i will mess with it more a bit later though as i was havng difficulties



i attempted using both % and px i will try w & h i originally though it was nly for width and height