How To Limit draw of Node to chosen Limit(Solve)

Hello, ( I am not using Nifty Gui)
I’m not sure how I should write this. Is there a way to prevent the pixel draw of certain element if they are out of a define region. An example would be a Chat where the text area wouldn’t need to be draw once it gone out of the text area. If i change the transparency it would hide the whole text of a player.

So my question, Is there a way to mask or prevent the pixel draw of certain node element (cutting it in half)

Below you can see the top text is cut out of the box (i know this is CSS in web but i would like to get the same result and I have no clue how I could achieve this with the BitMapText and a GuiNode) Actually i don’t know how to do this with anything.

http://cdn.digital.guide/dgarabble-chatbox.jpg

take a look at viewports http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:multiple_camera_views

otherwise you can use stencil buffer to set which pixels to draw

1 Like

I did try the ViewPort but i get an exception (it say i modified the thread while i wasn’t suppose… and this is really annoying me) But thx to certify i could do this like that.

In that case do use the render thread to initialize the viewports. If you get an exception saying your scene graph is not properly updated, make sure you do call updateLogicalState & updateGeometric state on the node that you attached to your viewport.

As The_Leo suggests, when you create your own viewports then you have to manage them yourself. You don’t get the magic management that rootNode and guiNode automatically get.

…best way is with an app state. Call yourRoot.updateLogicalState() on AppState.update() and updateGeometricState() on AppState.render().

I did this and it still making an error.

Is there a specific location where I need to put these 2 line?
From the TestRenderToTextutre test it was place at the very end of the code.

Am I supposed to call it every time i modify the actual node? (at best at the very last time)?

   Mar 13, 2016 10:29:34 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.IllegalStateException: Scene graph is not properly updated for rendering.
State was changed after rootNode.updateGeometricState() call. 
Make sure you do not modify the scene from another thread!
Problem spatial name: ChatText
    at com.jme3.scene.Spatial.checkCulling(Spatial.java:354)
    at com.jme3.renderer.RenderManager.renderSubScene(RenderManager.java:669)
    at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:662)
    at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1019)
    at com.jme3.renderer.RenderManager.render(RenderManager.java:1070)
    at com.jme3.app.SimpleApplication.update(SimpleApplication.java:260)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:152)
    at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:192)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:233)
    at java.lang.Thread.run(Thread.java:745)

Ok I got it to work properly. I tested to set the update at the very end and it worked out :smile:
I have to do some work on my game logic now :stuck_out_tongue: So it can support my whole code, my only final question would be can i make the viewport background transparent?

I told you exactly where to put them. I’m glad you got it working… but if you put updateGeometricState() in an AppState.render() then it is guaranteed to always work.

Everything else is luck.

OK ok I will change this part to prevent any possible bug, but is there a way to set the viewport background transparent? I only want the node inside to show.

You mean like some kind of flags to say how the viewport is cleared?

http://javadoc.jmonkeyengine.org/com/jme3/renderer/ViewPort.html#setClearFlags(boolean,%20boolean,%20boolean)

I mean to make the viewport windows transparent but not the node inside of it. so i can still see a nice edge without a windows delimitation(applying transparency to Windows too), An exemple would be to show the cube by it self with out the black back ground. Else there must be an other way to partly mask Models or Texture(I know about diffuse shader but it apply on Material and not Node)? See below

This black background?

Is because your viewport is setup to clear color. Set it up to not clear color… with the method I already gave you.

It does not work with the background from the Main viewport, it only work on the viewport it self, so if the cube was turning around it self it would let white pixel all over the place. Like this exemple.
But i get that the color Clear remove the color pixel under the view port.

How did you create your viewport? pre, main, post?

It should not behave this way. Set the clear flags to all false.

(Note: if it behaved this way then the gui viewport would also clear the screen… so something on your setup is wrong.)

this is comming from the Test file provided with jmonkey, so maybe the test is outdated (i m using the 3.1 alpha 1) and i did a copy of the test file to make sure the code would work.

When you clear all the flags

This is the code i ve been using.

/*
 * Copyright (c) 2009-2012 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package jme3test.post;

import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture2D;

/**
 * This test renders a scene to a texture, then displays the texture on a cube.
 */
public class TestRenderToTexture extends SimpleApplication implements ActionListener {

    private static final String TOGGLE_UPDATE = "Toggle Update";
    private Geometry offBox;
    private float angle = 0;
    private ViewPort offView;

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

    public Texture setupOffscreenView(){
        Camera offCamera = new Camera(512, 512);

        offView = renderManager.createPreView("Offscreen View", offCamera);
        offView.setClearFlags(false, false, false);
//        offView.setBackgroundColor(ColorRGBA.DarkGray);

        // create offscreen framebuffer
        FrameBuffer offBuffer = new FrameBuffer(512, 512, 1);

        //setup framebuffer's cam
        offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f);
        offCamera.setLocation(new Vector3f(0f, 0f, -5f));
        offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);

        //setup framebuffer's texture
        Texture2D offTex = new Texture2D(512, 512, Format.RGBA8);
        offTex.setMinFilter(Texture.MinFilter.Trilinear);
        offTex.setMagFilter(Texture.MagFilter.Bilinear);

        //setup framebuffer to use texture
        offBuffer.setDepthBuffer(Format.Depth);
        offBuffer.setColorTexture(offTex);
        
        //set viewport to render to offscreen framebuffer
        offView.setOutputFrameBuffer(offBuffer);

        // setup framebuffer's scene
        Box boxMesh = new Box(Vector3f.ZERO, 1,1,1);
        Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m");
        offBox = new Geometry("box", boxMesh);
        offBox.setMaterial(material);

        // attach the scene to the viewport to be rendered
        offView.attachScene(offBox);
        
        return offTex;
    }

    @Override
    public void simpleInitApp() {
        cam.setLocation(new Vector3f(3, 3, 3));
        cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
        
        viewPort.setBackgroundColor(ColorRGBA.Cyan);

        //setup main scene
        Quad quad = new Quad(400, 400);
        Geometry geo = new Geometry("test", quad);
        Texture offTex = setupOffscreenView();

        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setTexture("ColorMap", offTex);
        geo.setMaterial(mat);
        guiNode.attachChild(geo);
        inputManager.addMapping(TOGGLE_UPDATE, new KeyTrigger(KeyInput.KEY_SPACE));
        inputManager.addListener(this, TOGGLE_UPDATE);
    }

    @Override
    public void simpleUpdate(float tpf){
        Quaternion q = new Quaternion();
        
        if (offView.isEnabled()) {
            angle += tpf;
            angle %= FastMath.TWO_PI;
            q.fromAngles(angle, 0, angle);
            
            offBox.setLocalRotation(q);
            offBox.updateLogicalState(tpf);
            offBox.updateGeometricState();
        }
    }

    @Override
    public void onAction(String name, boolean isPressed, float tpf) {
        if (name.equals(TOGGLE_UPDATE) && isPressed) {
            offView.setEnabled(!offView.isEnabled());
        }
    }


}

Why are you rendering to a texture? I thought you just wanted a viewport?

These two things are pretty much completely different.

I mean there is a way to get render to texture to do what you want but it’s way way way less efficient than simply setting up a screen viewport.

If you have your heart set on doing the offscreen texture render stuff for some reason then you have to remember that you are ultimately drawing a quad. It will need to be in the transparent bucket, set blend mode, etc…

Then you DO want to clear your viewport and you want to set the color to something with alpha.

…but really there is no need to render to texture just to isolate rendering to a portion of the screen.

oh… alright, i did this because i thought it was the only way to do what i wanted. Then I only need to creat a new view port and to set it?

Was this intend for video player in game? Like a tv screen or something similar?