All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jme3.renderer.queue.RenderQueue Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2009-2021 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 com.jme3.renderer.queue;

import com.jme3.post.SceneProcessor;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;

/**
 * RenderQueue is used to queue up and sort 
 * {@link Geometry geometries} for rendering.
 * 
 * @author Kirill Vainer
 */
public class RenderQueue {

    private GeometryList opaqueList;
    private GeometryList guiList;
    private GeometryList transparentList;
    private GeometryList translucentList;
    private GeometryList skyList;

    /**
     * Creates a new RenderQueue, the default {@link GeometryComparator comparators}
     * are used for all {@link GeometryList geometry lists}.
     */
    public RenderQueue() {
        this.opaqueList = new GeometryList(new OpaqueComparator());
        this.guiList = new GeometryList(new GuiComparator());
        this.transparentList = new GeometryList(new TransparentComparator());
        this.translucentList = new GeometryList(new TransparentComparator());
        this.skyList = new GeometryList(new NullComparator());
    }

    /**
     * The render queue Bucket specifies the bucket
     * to which the spatial will be placed when rendered. 
     * 

* The behavior of the rendering will differ depending on which * bucket the spatial is placed. A spatial's queue bucket can be set * via {@link Spatial#setQueueBucket(com.jme3.renderer.queue.RenderQueue.Bucket) }. */ public enum Bucket { /** * The renderer will try to find the optimal order for rendering all * objects using this mode. * You should use this mode for most normal objects, except transparent * ones, as it could give a nice performance boost to your application. */ Opaque, /** * This is the mode you should use for object with * transparency in them. It will ensure the objects furthest away are * rendered first. That ensures when another transparent object is drawn on * top of previously drawn objects, you can see those (and the object drawn * using Opaque) through the transparent parts of the newly drawn * object. */ Transparent, /** * A special mode used for rendering really far away, flat objects - * e.g. skies. In this mode, the depth is set to infinity so * spatials in this bucket will appear behind everything, the downside * to this bucket is that 3D objects will not be rendered correctly * due to lack of depth testing. */ Sky, /** * A special mode used for rendering transparent objects that * should not be affected by {@link SceneProcessor}. * Generally this would contain translucent objects, and * also objects that do not write to the depth buffer such as * particle emitters. */ Translucent, /** * This is a special mode, for drawing 2D object * without perspective (such as GUI or HUD parts). * The spatial's world coordinate system has the range * of [0, 0, -1] to [Width, Height, 1] where Width/Height is * the resolution of the screen rendered to. Any spatials * outside of that range are culled. */ Gui, /** * A special mode, that will ensure that this spatial uses the same * mode as the parent Node does. */ Inherit, } /** * ShadowMode is a marker used to specify how shadow * effects should treat the spatial. */ public enum ShadowMode { /** * Disable both shadow casting and shadow receiving for this spatial. * Generally used for special effects like particle emitters. */ Off, /** * Enable casting of shadows but not receiving them. */ Cast, /** * Enable receiving of shadows but not casting them. */ Receive, /** * Enable both receiving and casting of shadows. */ CastAndReceive, /** * Inherit the ShadowMode from the parent node. */ Inherit } /** * Sets a different geometry comparator for the specified bucket, one * of Gui, Opaque, Sky, Transparent, or Translucent. The GeometryComparators are * used to sort the accumulated list of geometries before actual rendering * occurs. * *

The most significant comparator is the one for the transparent * bucket since there is no correct way to sort the transparent bucket * that will handle all geometries all the time. In certain cases, the * application may know the best way to sort and now has the option of * configuring a specific implementation.

* *

The default comparators are:

*
    *
  • Bucket.Opaque: {@link com.jme3.renderer.queue.OpaqueComparator} which sorts * by material first and front to back within the same material. *
  • Bucket.Transparent: {@link com.jme3.renderer.queue.TransparentComparator} which * sorts purely back to front by leading bounding edge with no material sort. *
  • Bucket.Translucent: {@link com.jme3.renderer.queue.TransparentComparator} which * sorts purely back to front by leading bounding edge with no material sort. this bucket is rendered after post processors. *
  • Bucket.Sky: {@link com.jme3.renderer.queue.NullComparator} which does no sorting * at all. *
  • Bucket.Gui: {@link com.jme3.renderer.queue.GuiComparator} sorts geometries back to * front based on their Z values. *
* * @param bucket which Bucket to modify (not null) * @param c the comparator to use (alias created) */ public void setGeometryComparator(Bucket bucket, GeometryComparator c) { switch (bucket) { case Gui: guiList = new GeometryList(c); break; case Opaque: opaqueList = new GeometryList(c); break; case Sky: skyList = new GeometryList(c); break; case Transparent: transparentList = new GeometryList(c); break; case Translucent: translucentList = new GeometryList(c); break; default: throw new UnsupportedOperationException("Unknown bucket type: " + bucket); } } /** * Returns the current GeometryComparator used by the specified bucket, * one of Gui, Opaque, Sky, Transparent, or Translucent. * * @param bucket which Bucket to access (not null) * @return the pre-existing instance */ public GeometryComparator getGeometryComparator(Bucket bucket) { switch (bucket) { case Gui: return guiList.getComparator(); case Opaque: return opaqueList.getComparator(); case Sky: return skyList.getComparator(); case Transparent: return transparentList.getComparator(); case Translucent: return translucentList.getComparator(); default: throw new UnsupportedOperationException("Unknown bucket type: " + bucket); } } /** * Adds a geometry to the given bucket. * The {@link RenderManager} automatically handles this task * when flattening the scene graph. The bucket to add * the geometry is determined by {@link Geometry#getQueueBucket() }. * * @param g The geometry to add * @param bucket The bucket to add to, usually * {@link Geometry#getQueueBucket() }. */ public void addToQueue(Geometry g, Bucket bucket) { switch (bucket) { case Gui: guiList.add(g); break; case Opaque: opaqueList.add(g); break; case Sky: skyList.add(g); break; case Transparent: transparentList.add(g); break; case Translucent: translucentList.add(g); break; default: throw new UnsupportedOperationException("Unknown bucket type: " + bucket); } } private void renderGeometryList(GeometryList list, RenderManager rm, Camera cam, boolean clear) { list.setCamera(cam); // select camera for sorting list.sort(); for (int i = 0; i < list.size(); i++) { Geometry obj = list.get(i); assert obj != null; rm.renderGeometry(obj); obj.queueDistance = Float.NEGATIVE_INFINITY; } if (clear) { list.clear(); } } public void renderShadowQueue(GeometryList list, RenderManager rm, Camera cam, boolean clear) { rm.getRenderer().pushDebugGroup("ShadowQueue"); renderGeometryList(list, rm, cam, clear); rm.getRenderer().popDebugGroup(); } public boolean isQueueEmpty(Bucket bucket) { switch (bucket) { case Gui: return guiList.size() == 0; case Opaque: return opaqueList.size() == 0; case Sky: return skyList.size() == 0; case Transparent: return transparentList.size() == 0; case Translucent: return translucentList.size() == 0; default: throw new UnsupportedOperationException("Unsupported bucket type: " + bucket); } } public void renderQueue(Bucket bucket, RenderManager rm, Camera cam) { renderQueue(bucket, rm, cam, true); } public void renderQueue(Bucket bucket, RenderManager rm, Camera cam, boolean clear) { rm.getRenderer().pushDebugGroup(bucket.name()); switch (bucket) { case Gui: renderGeometryList(guiList, rm, cam, clear); break; case Opaque: renderGeometryList(opaqueList, rm, cam, clear); break; case Sky: renderGeometryList(skyList, rm, cam, clear); break; case Transparent: renderGeometryList(transparentList, rm, cam, clear); break; case Translucent: renderGeometryList(translucentList, rm, cam, clear); break; default: throw new UnsupportedOperationException("Unsupported bucket type: " + bucket); } rm.getRenderer().popDebugGroup(); } public void clear() { opaqueList.clear(); guiList.clear(); transparentList.clear(); translucentList.clear(); skyList.clear(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy