Search in sources :

Example 1 with Bucket

use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.

the class BinaryExporter method save.

public void save(Savable object, OutputStream os) throws IOException {
    // reset some vars
    aliasCount = 1;
    idCount = 1;
    classes.clear();
    contentTable.clear();
    locationTable.clear();
    contentKeys.clear();
    // write signature and version
    os.write(ByteUtils.convertToBytes(FormatVersion.SIGNATURE));
    os.write(ByteUtils.convertToBytes(FormatVersion.VERSION));
    int id = processBinarySavable(object);
    // write out tag table
    int classTableSize = 0;
    int classNum = classes.keySet().size();
    // make all
    int aliasSize = ((int) FastMath.log(classNum, 256) + 1);
    // aliases a
    // fixed width
    os.write(ByteUtils.convertToBytes(classNum));
    for (String key : classes.keySet()) {
        BinaryClassObject bco = classes.get(key);
        // write alias
        byte[] aliasBytes = fixClassAlias(bco.alias, aliasSize);
        os.write(aliasBytes);
        classTableSize += aliasSize;
        // jME3 NEW: Write class hierarchy version numbers
        os.write(bco.classHierarchyVersions.length);
        for (int version : bco.classHierarchyVersions) {
            os.write(ByteUtils.convertToBytes(version));
        }
        classTableSize += 1 + bco.classHierarchyVersions.length * 4;
        // write classname size & classname
        byte[] classBytes = key.getBytes();
        os.write(ByteUtils.convertToBytes(classBytes.length));
        os.write(classBytes);
        classTableSize += 4 + classBytes.length;
        // for each field, write alias, type, and name
        os.write(ByteUtils.convertToBytes(bco.nameFields.size()));
        for (String fieldName : bco.nameFields.keySet()) {
            BinaryClassField bcf = bco.nameFields.get(fieldName);
            os.write(bcf.alias);
            os.write(bcf.type);
            // write classname size & classname
            byte[] fNameBytes = fieldName.getBytes();
            os.write(ByteUtils.convertToBytes(fNameBytes.length));
            os.write(fNameBytes);
            classTableSize += 2 + 4 + fNameBytes.length;
        }
    }
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    // write out data to a seperate stream
    int location = 0;
    // keep track of location for each piece
    HashMap<String, ArrayList<BinaryIdContentPair>> alreadySaved = new HashMap<String, ArrayList<BinaryIdContentPair>>(contentTable.size());
    for (Savable savable : contentKeys) {
        // look back at previous written data for matches
        String savableName = savable.getClass().getName();
        BinaryIdContentPair pair = contentTable.get(savable);
        ArrayList<BinaryIdContentPair> bucket = alreadySaved.get(savableName + getChunk(pair));
        int prevLoc = findPrevMatch(pair, bucket);
        if (prevLoc != -1) {
            locationTable.put(pair.getId(), prevLoc);
            continue;
        }
        locationTable.put(pair.getId(), location);
        if (bucket == null) {
            bucket = new ArrayList<BinaryIdContentPair>();
            alreadySaved.put(savableName + getChunk(pair), bucket);
        }
        bucket.add(pair);
        byte[] aliasBytes = fixClassAlias(classes.get(savableName).alias, aliasSize);
        out.write(aliasBytes);
        location += aliasSize;
        BinaryOutputCapsule cap = contentTable.get(savable).getContent();
        out.write(ByteUtils.convertToBytes(cap.bytes.length));
        // length of bytes
        location += 4;
        out.write(cap.bytes);
        location += cap.bytes.length;
    }
    // write out location table
    // tag/location
    int numLocations = locationTable.keySet().size();
    os.write(ByteUtils.convertToBytes(numLocations));
    int locationTableSize = 0;
    for (Integer key : locationTable.keySet()) {
        os.write(ByteUtils.convertToBytes(key));
        os.write(ByteUtils.convertToBytes(locationTable.get(key)));
        locationTableSize += 8;
    }
    // write out number of root ids - hardcoded 1 for now
    os.write(ByteUtils.convertToBytes(1));
    // write out root id
    os.write(ByteUtils.convertToBytes(id));
    // append stream to the output stream
    out.writeTo(os);
    out = null;
    os = null;
    if (debug) {
        logger.fine("Stats:");
        logger.log(Level.FINE, "classes: {0}", classNum);
        logger.log(Level.FINE, "class table: {0} bytes", classTableSize);
        logger.log(Level.FINE, "objects: {0}", numLocations);
        logger.log(Level.FINE, "location table: {0} bytes", locationTableSize);
        logger.log(Level.FINE, "data: {0} bytes", location);
    }
}
Also used : IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Savable(com.jme3.export.Savable)

Example 2 with Bucket

use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.

the class TestDepthFuncChange method simpleInitApp.

public void simpleInitApp() {
    viewPort.setBackgroundColor(ColorRGBA.DarkGray);
    flyCam.setMoveSpeed(20);
    //top of the screen
    //default depth func (less or equal) rendering.
    //2 cubes, a blue and a red. the red cube is offset by 0.2 WU to the right   
    //the red cube is put in the transparent bucket to be sure it's rendered after the blue one (but there is no transparency involved).
    //You should see a small part of the blue cube on the left and the whole red cube
    Box boxshape1 = new Box(1f, 1f, 1f);
    Geometry cube1 = new Geometry("box", boxshape1);
    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setColor("Color", ColorRGBA.Blue);
    cube1.setMaterial(mat);
    rootNode.attachChild(cube1);
    cube1.move(0, 1.5f, 0);
    Geometry cube2 = cube1.clone(true);
    cube2.move(0.2f, 0, 0);
    cube2.setQueueBucket(RenderQueue.Bucket.Transparent);
    cube2.getMaterial().setColor("Color", ColorRGBA.Red);
    rootNode.attachChild(cube2);
    //Bottom of the screen
    //here the 2 cubes are clonned and the depthFunc for the red cube's material is set to Less
    //You should see the whole bleu cube and a small part of the red cube on the right
    Geometry cube3 = cube1.clone();
    Geometry cube4 = cube2.clone(true);
    cube4.getMaterial().getAdditionalRenderState().setDepthFunc(RenderState.TestFunction.Less);
    cube3.move(0, -3, 0);
    cube4.move(0, -3, 0);
    rootNode.attachChild(cube3);
    rootNode.attachChild(cube4);
//Note that if you move the camera z fighting will occur but that's expected.
}
Also used : Geometry(com.jme3.scene.Geometry) Box(com.jme3.scene.shape.Box) Material(com.jme3.material.Material)

Example 3 with Bucket

use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.

the class RenderManager method renderViewPortQueues.

/**
     * Render the given viewport queues.
     * <p>
     * Changes the {@link Renderer#setDepthRange(float, float) depth range}
     * appropriately as expected by each queue and then calls 
     * {@link RenderQueue#renderQueue(com.jme3.renderer.queue.RenderQueue.Bucket, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera, boolean) }
     * on the queue. Makes sure to restore the depth range to [0, 1] 
     * at the end of the call.
     * Note that the {@link Bucket#Translucent translucent bucket} is NOT
     * rendered by this method. Instead the user should call 
     * {@link #renderTranslucentQueue(com.jme3.renderer.ViewPort) }
     * after this call.
     * 
     * @param vp the viewport of which queue should be rendered
     * @param flush If true, the queues will be cleared after
     * rendering.
     * 
     * @see RenderQueue
     * @see #renderTranslucentQueue(com.jme3.renderer.ViewPort) 
     */
public void renderViewPortQueues(ViewPort vp, boolean flush) {
    RenderQueue rq = vp.getQueue();
    Camera cam = vp.getCamera();
    boolean depthRangeChanged = false;
    // opaque objects are sorted front-to-back, reducing overdraw
    if (prof != null)
        prof.vpStep(VpStep.RenderBucket, vp, Bucket.Opaque);
    rq.renderQueue(Bucket.Opaque, this, cam, flush);
    // render the sky, with depth range set to the farthest
    if (!rq.isQueueEmpty(Bucket.Sky)) {
        if (prof != null)
            prof.vpStep(VpStep.RenderBucket, vp, Bucket.Sky);
        renderer.setDepthRange(1, 1);
        rq.renderQueue(Bucket.Sky, this, cam, flush);
        depthRangeChanged = true;
    }
    // back-to-front.
    if (!rq.isQueueEmpty(Bucket.Transparent)) {
        if (prof != null)
            prof.vpStep(VpStep.RenderBucket, vp, Bucket.Transparent);
        if (depthRangeChanged) {
            renderer.setDepthRange(0, 1);
            depthRangeChanged = false;
        }
        rq.renderQueue(Bucket.Transparent, this, cam, flush);
    }
    if (!rq.isQueueEmpty(Bucket.Gui)) {
        if (prof != null)
            prof.vpStep(VpStep.RenderBucket, vp, Bucket.Gui);
        renderer.setDepthRange(0, 0);
        setCamera(cam, true);
        rq.renderQueue(Bucket.Gui, this, cam, flush);
        setCamera(cam, false);
        depthRangeChanged = true;
    }
    // restore range to default
    if (depthRangeChanged) {
        renderer.setDepthRange(0, 1);
    }
}
Also used : RenderQueue(com.jme3.renderer.queue.RenderQueue)

Example 4 with Bucket

use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.

the class Camera method setClipPlane.

/**
     * Sets a clipPlane for this camera.
     * The clipPlane is used to recompute the
     * projectionMatrix using the plane as the near plane     
     * This technique is known as the oblique near-plane clipping method introduced by Eric Lengyel
     * more info here
     * <ul>
     * <li><a href="http://www.terathon.com/code/oblique.html">http://www.terathon.com/code/oblique.html</a>
     * <li><a href="http://aras-p.info/texts/obliqueortho.html">http://aras-p.info/texts/obliqueortho.html</a>
     * <li><a href="http://hacksoflife.blogspot.com/2008/12/every-now-and-then-i-come-across.html">http://hacksoflife.blogspot.com/2008/12/every-now-and-then-i-come-across.html</a>
     * </ul>
     *
     * Note that this will work properly only if it's called on each update, and be aware that it won't work properly with the sky bucket.
     * if you want to handle the sky bucket, look at how it's done in SimpleWaterProcessor.java
     * @param clipPlane the plane
     * @param side the side the camera stands from the plane
     */
public void setClipPlane(Plane clipPlane, Plane.Side side) {
    float sideFactor = 1;
    if (side == Plane.Side.Negative) {
        sideFactor = -1;
    }
    //we are on the other side of the plane no need to clip anymore.
    if (clipPlane.whichSide(location) == side) {
        return;
    }
    TempVars vars = TempVars.get();
    try {
        Matrix4f p = projectionMatrixOverride.set(projectionMatrix);
        Matrix4f ivm = viewMatrix;
        Vector3f point = clipPlane.getNormal().mult(clipPlane.getConstant(), vars.vect1);
        Vector3f pp = ivm.mult(point, vars.vect2);
        Vector3f pn = ivm.multNormal(clipPlane.getNormal(), vars.vect3);
        Vector4f clipPlaneV = vars.vect4f1.set(pn.x * sideFactor, pn.y * sideFactor, pn.z * sideFactor, -(pp.dot(pn)) * sideFactor);
        Vector4f v = vars.vect4f2.set(0, 0, 0, 0);
        v.x = (Math.signum(clipPlaneV.x) + p.m02) / p.m00;
        v.y = (Math.signum(clipPlaneV.y) + p.m12) / p.m11;
        v.z = -1.0f;
        v.w = (1.0f + p.m22) / p.m23;
        //clipPlaneV.x * v.x + clipPlaneV.y * v.y + clipPlaneV.z * v.z + clipPlaneV.w * v.w;
        float dot = clipPlaneV.dot(v);
        Vector4f c = clipPlaneV.multLocal(2.0f / dot);
        p.m20 = c.x - p.m30;
        p.m21 = c.y - p.m31;
        p.m22 = c.z - p.m32;
        p.m23 = c.w - p.m33;
        setProjectionMatrix(p);
    } finally {
        vars.release();
    }
}
Also used : TempVars(com.jme3.util.TempVars)

Example 5 with Bucket

use of com.jme3.renderer.queue.RenderQueue.Bucket in project jmonkeyengine by jMonkeyEngine.

the class TestShaderNodesStress method simpleInitApp.

@Override
public void simpleInitApp() {
    Quad q = new Quad(1, 1);
    Geometry g = new Geometry("quad", q);
    g.setLocalTranslation(-500, -500, 0);
    g.setLocalScale(1000);
    rootNode.attachChild(g);
    cam.setLocation(new Vector3f(0.0f, 0.0f, 0.40647888f));
    cam.setRotation(new Quaternion(0.0f, 1.0f, 0.0f, 0.0f));
    Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
    Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md");
    //Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setColor("Color", ColorRGBA.Yellow);
    mat.setTexture("ColorMap", tex);
    g.setMaterial(mat);
    //place the geoms in the transparent bucket so that they are rendered back to front for maximum overdraw
    g.setQueueBucket(RenderQueue.Bucket.Transparent);
    for (int i = 0; i < 1000; i++) {
        Geometry cl = g.clone(false);
        cl.move(0, 0, -(i + 1));
        rootNode.attachChild(cl);
    }
    flyCam.setMoveSpeed(20);
    Logger.getLogger("com.jme3").setLevel(Level.WARNING);
    this.setAppProfiler(new Profiler());
}
Also used : Geometry(com.jme3.scene.Geometry) Quad(com.jme3.scene.shape.Quad) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f) Material(com.jme3.material.Material) Texture(com.jme3.texture.Texture)

Aggregations

Material (com.jme3.material.Material)2 Geometry (com.jme3.scene.Geometry)2 Savable (com.jme3.export.Savable)1 Quaternion (com.jme3.math.Quaternion)1 Vector3f (com.jme3.math.Vector3f)1 RenderQueue (com.jme3.renderer.queue.RenderQueue)1 Box (com.jme3.scene.shape.Box)1 Quad (com.jme3.scene.shape.Quad)1 Texture (com.jme3.texture.Texture)1 TempVars (com.jme3.util.TempVars)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 IdentityHashMap (java.util.IdentityHashMap)1