Search in sources :

Example 1 with SafeArrayList

use of com.jme3.util.SafeArrayList in project jmonkeyengine by jMonkeyEngine.

the class RenderManager method renderViewPort.

/**
     * Renders the {@link ViewPort}.
     * <p>
     * If the ViewPort is {@link ViewPort#isEnabled() disabled}, this method
     * returns immediately. Otherwise, the ViewPort is rendered by 
     * the following process:<br>
     * <ul>
     * <li>All {@link SceneProcessor scene processors} that are attached
     * to the ViewPort are {@link SceneProcessor#initialize(com.jme3.renderer.RenderManager, com.jme3.renderer.ViewPort) initialized}.
     * </li>
     * <li>The SceneProcessors' {@link SceneProcessor#preFrame(float) } method 
     * is called.</li>
     * <li>The ViewPort's {@link ViewPort#getOutputFrameBuffer() output framebuffer}
     * is set on the Renderer</li>
     * <li>The camera is set on the renderer, including its view port parameters.
     * (see {@link #setCamera(com.jme3.renderer.Camera, boolean) })</li>
     * <li>Any buffers that the ViewPort requests to be cleared are cleared
     * and the {@link ViewPort#getBackgroundColor() background color} is set</li>
     * <li>Every scene that is attached to the ViewPort is flattened into 
     * the ViewPort's render queue 
     * (see {@link #renderViewPortQueues(com.jme3.renderer.ViewPort, boolean) })
     * </li>
     * <li>The SceneProcessors' {@link SceneProcessor#postQueue(com.jme3.renderer.queue.RenderQueue) }
     * method is called.</li>
     * <li>The render queue is sorted and then flushed, sending
     * rendering commands to the underlying Renderer implementation. 
     * (see {@link #flushQueue(com.jme3.renderer.ViewPort) })</li>
     * <li>The SceneProcessors' {@link SceneProcessor#postFrame(com.jme3.texture.FrameBuffer) }
     * method is called.</li>
     * <li>The translucent queue of the ViewPort is sorted and then flushed
     * (see {@link #renderTranslucentQueue(com.jme3.renderer.ViewPort) })</li>
     * <li>If any objects remained in the render queue, they are removed
     * from the queue. This is generally objects added to the 
     * {@link RenderQueue#renderShadowQueue(com.jme3.renderer.queue.RenderQueue.ShadowMode, com.jme3.renderer.RenderManager, com.jme3.renderer.Camera, boolean) 
     * shadow queue}
     * which were not rendered because of a missing shadow renderer.</li>
     * </ul>
     * 
     * @param vp View port to render
     * @param tpf Time per frame value
     */
public void renderViewPort(ViewPort vp, float tpf) {
    if (!vp.isEnabled()) {
        return;
    }
    if (prof != null)
        prof.vpStep(VpStep.BeginRender, vp, null);
    SafeArrayList<SceneProcessor> processors = vp.getProcessors();
    if (processors.isEmpty()) {
        processors = null;
    }
    if (processors != null) {
        if (prof != null)
            prof.vpStep(VpStep.PreFrame, vp, null);
        for (SceneProcessor proc : processors.getArray()) {
            if (!proc.isInitialized()) {
                proc.initialize(this, vp);
            }
            proc.setProfiler(this.prof);
            if (prof != null)
                prof.spStep(SpStep.ProcPreFrame, proc.getClass().getSimpleName());
            proc.preFrame(tpf);
        }
    }
    renderer.setFrameBuffer(vp.getOutputFrameBuffer());
    setCamera(vp.getCamera(), false);
    if (vp.isClearDepth() || vp.isClearColor() || vp.isClearStencil()) {
        if (vp.isClearColor()) {
            renderer.setBackgroundColor(vp.getBackgroundColor());
        }
        renderer.clearBuffers(vp.isClearColor(), vp.isClearDepth(), vp.isClearStencil());
    }
    if (prof != null)
        prof.vpStep(VpStep.RenderScene, vp, null);
    List<Spatial> scenes = vp.getScenes();
    for (int i = scenes.size() - 1; i >= 0; i--) {
        renderScene(scenes.get(i), vp);
    }
    if (processors != null) {
        if (prof != null)
            prof.vpStep(VpStep.PostQueue, vp, null);
        for (SceneProcessor proc : processors.getArray()) {
            if (prof != null)
                prof.spStep(SpStep.ProcPostQueue, proc.getClass().getSimpleName());
            proc.postQueue(vp.getQueue());
        }
    }
    if (prof != null)
        prof.vpStep(VpStep.FlushQueue, vp, null);
    flushQueue(vp);
    if (processors != null) {
        if (prof != null)
            prof.vpStep(VpStep.PostFrame, vp, null);
        for (SceneProcessor proc : processors.getArray()) {
            if (prof != null)
                prof.spStep(SpStep.ProcPostFrame, proc.getClass().getSimpleName());
            proc.postFrame(vp.getOutputFrameBuffer());
        }
        if (prof != null)
            prof.vpStep(VpStep.ProcEndRender, vp, null);
    }
    //renders the translucent objects queue after processors have been rendered
    renderTranslucentQueue(vp);
    // clear any remaining spatials that were not rendered.
    clearQueue(vp);
    if (prof != null)
        prof.vpStep(VpStep.EndRender, vp, null);
}
Also used : SceneProcessor(com.jme3.post.SceneProcessor)

Example 2 with SafeArrayList

use of com.jme3.util.SafeArrayList in project jmonkeyengine by jMonkeyEngine.

the class Spatial method oldClone.

/**
     *  The old clone() method that did not use the new Cloner utility.
     */
public Spatial oldClone(boolean cloneMaterial) {
    try {
        Spatial clone = (Spatial) super.clone();
        if (worldBound != null) {
            clone.worldBound = worldBound.clone();
        }
        clone.worldLights = worldLights.clone();
        clone.localLights = localLights.clone();
        // Set the new owner of the light lists
        clone.localLights.setOwner(clone);
        clone.worldLights.setOwner(clone);
        clone.worldOverrides = new SafeArrayList<>(MatParamOverride.class);
        clone.localOverrides = new SafeArrayList<>(MatParamOverride.class);
        for (MatParamOverride override : localOverrides) {
            clone.localOverrides.add((MatParamOverride) override.clone());
        }
        // No need to force cloned to update.
        // This node already has the refresh flags
        // set below so it will have to update anyway.
        clone.worldTransform = worldTransform.clone();
        clone.localTransform = localTransform.clone();
        if (clone instanceof Node) {
            Node node = (Node) this;
            Node nodeClone = (Node) clone;
            nodeClone.children = new SafeArrayList<Spatial>(Spatial.class);
            for (Spatial child : node.children) {
                Spatial childClone = child.clone(cloneMaterial);
                childClone.parent = nodeClone;
                nodeClone.children.add(childClone);
            }
        }
        clone.parent = null;
        clone.setBoundRefresh();
        clone.setTransformRefresh();
        clone.setLightListRefresh();
        clone.setMatParamOverrideRefresh();
        clone.controls = new SafeArrayList<Control>(Control.class);
        for (int i = 0; i < controls.size(); i++) {
            Control newControl = controls.get(i).cloneForSpatial(clone);
            newControl.setSpatial(clone);
            clone.controls.add(newControl);
        }
        if (userData != null) {
            clone.userData = (HashMap<String, Savable>) userData.clone();
        }
        return clone;
    } catch (CloneNotSupportedException ex) {
        throw new AssertionError();
    }
}
Also used : Control(com.jme3.scene.control.Control) MatParamOverride(com.jme3.material.MatParamOverride)

Example 3 with SafeArrayList

use of com.jme3.util.SafeArrayList in project jmonkeyengine by jMonkeyEngine.

the class Material method applyOverrides.

private int applyOverrides(Renderer renderer, Shader shader, SafeArrayList<MatParamOverride> overrides, int unit) {
    for (MatParamOverride override : overrides.getArray()) {
        VarType type = override.getVarType();
        MatParam paramDef = def.getMaterialParam(override.getName());
        if (paramDef == null || paramDef.getVarType() != type || !override.isEnabled()) {
            continue;
        }
        Uniform uniform = shader.getUniform(override.getPrefixedName());
        if (override.getValue() != null) {
            if (type.isTextureType()) {
                renderer.setTexture(unit, (Texture) override.getValue());
                uniform.setValue(VarType.Int, unit);
                unit++;
            } else {
                uniform.setValue(type, override.getValue());
            }
        } else {
            uniform.clearValue();
        }
    }
    return unit;
}
Also used : Uniform(com.jme3.shader.Uniform) VarType(com.jme3.shader.VarType)

Example 4 with SafeArrayList

use of com.jme3.util.SafeArrayList in project jmonkeyengine by jMonkeyEngine.

the class Material method updateShaderMaterialParameters.

private int updateShaderMaterialParameters(Renderer renderer, Shader shader, SafeArrayList<MatParamOverride> worldOverrides, SafeArrayList<MatParamOverride> forcedOverrides) {
    int unit = 0;
    if (worldOverrides != null) {
        unit = applyOverrides(renderer, shader, worldOverrides, unit);
    }
    if (forcedOverrides != null) {
        unit = applyOverrides(renderer, shader, forcedOverrides, unit);
    }
    for (int i = 0; i < paramValues.size(); i++) {
        MatParam param = paramValues.getValue(i);
        VarType type = param.getVarType();
        Uniform uniform = shader.getUniform(param.getPrefixedName());
        if (uniform.isSetByCurrentMaterial()) {
            continue;
        }
        if (type.isTextureType()) {
            renderer.setTexture(unit, (Texture) param.getValue());
            uniform.setValue(VarType.Int, unit);
            unit++;
        } else {
            uniform.setValue(type, param.getValue());
        }
    }
    //TODO HACKY HACK remove this when texture unit is handled by the uniform.
    return unit;
}
Also used : Uniform(com.jme3.shader.Uniform) VarType(com.jme3.shader.VarType)

Example 5 with SafeArrayList

use of com.jme3.util.SafeArrayList in project jmonkeyengine by jMonkeyEngine.

the class Material method render.

/**
     * Called by {@link RenderManager} to render the geometry by
     * using this material.
     * <p>
     * The material is rendered as follows:
     * <ul>
     * <li>Determine which technique to use to render the material -
     * either what the user selected via
     * {@link #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager)
     * Material.selectTechnique()},
     * or the first default technique that the renderer supports
     * (based on the technique's {@link TechniqueDef#getRequiredCaps() requested rendering capabilities})<ul>
     * <li>If the technique has been changed since the last frame, then it is notified via
     * {@link Technique#makeCurrent(com.jme3.asset.AssetManager, boolean, java.util.EnumSet)
     * Technique.makeCurrent()}.
     * If the technique wants to use a shader to render the model, it should load it at this part -
     * the shader should have all the proper defines as declared in the technique definition,
     * including those that are bound to material parameters.
     * The technique can re-use the shader from the last frame if
     * no changes to the defines occurred.</li></ul>
     * <li>Set the {@link RenderState} to use for rendering. The render states are
     * applied in this order (later RenderStates override earlier RenderStates):<ol>
     * <li>{@link TechniqueDef#getRenderState() Technique Definition's RenderState}
     * - i.e. specific renderstate that is required for the shader.</li>
     * <li>{@link #getAdditionalRenderState() Material Instance Additional RenderState}
     * - i.e. ad-hoc renderstate set per model</li>
     * <li>{@link RenderManager#getForcedRenderState() RenderManager's Forced RenderState}
     * - i.e. renderstate requested by a {@link com.jme3.post.SceneProcessor} or
     * post-processing filter.</li></ol>
     * <li>If the technique {@link TechniqueDef#isUsingShaders() uses a shader}, then the uniforms of the shader must be updated.<ul>
     * <li>Uniforms bound to material parameters are updated based on the current material parameter values.</li>
     * <li>Uniforms bound to world parameters are updated from the RenderManager.
     * Internally {@link UniformBindingManager} is used for this task.</li>
     * <li>Uniforms bound to textures will cause the texture to be uploaded as necessary.
     * The uniform is set to the texture unit where the texture is bound.</li></ul>
     * <li>If the technique uses a shader, the model is then rendered according
     * to the lighting mode specified on the technique definition.<ul>
     * <li>{@link LightMode#SinglePass single pass light mode} fills the shader's light uniform arrays
     * with the first 4 lights and renders the model once.</li>
     * <li>{@link LightMode#MultiPass multi pass light mode} light mode renders the model multiple times,
     * for the first light it is rendered opaque, on subsequent lights it is
     * rendered with {@link BlendMode#AlphaAdditive alpha-additive} blending and depth writing disabled.</li>
     * </ul>
     * <li>For techniques that do not use shaders,
     * fixed function OpenGL is used to render the model (see {@link GL1Renderer} interface):<ul>
     * <li>OpenGL state ({@link FixedFuncBinding}) that is bound to material parameters is updated. </li>
     * <li>The texture set on the material is uploaded and bound.
     * Currently only 1 texture is supported for fixed function techniques.</li>
     * <li>If the technique uses lighting, then OpenGL lighting state is updated
     * based on the light list on the geometry, otherwise OpenGL lighting is disabled.</li>
     * <li>The mesh is uploaded and rendered.</li>
     * </ul>
     * </ul>
     *
     * @param geometry The geometry to render
     * @param lights Presorted and filtered light list to use for rendering
     * @param renderManager The render manager requesting the rendering
     */
public void render(Geometry geometry, LightList lights, RenderManager renderManager) {
    if (technique == null) {
        selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
    }
    TechniqueDef techniqueDef = technique.getDef();
    Renderer renderer = renderManager.getRenderer();
    EnumSet<Caps> rendererCaps = renderer.getCaps();
    if (techniqueDef.isNoRender()) {
        return;
    }
    // Apply render state
    updateRenderState(renderManager, renderer, techniqueDef);
    // Get world overrides
    SafeArrayList<MatParamOverride> overrides = geometry.getWorldMatParamOverrides();
    // Select shader to use
    Shader shader = technique.makeCurrent(renderManager, overrides, renderManager.getForcedMatParams(), lights, rendererCaps);
    // Begin tracking which uniforms were changed by material.
    clearUniformsSetByCurrent(shader);
    // Set uniform bindings
    renderManager.updateUniformBindings(shader);
    // Set material parameters
    int unit = updateShaderMaterialParameters(renderer, shader, overrides, renderManager.getForcedMatParams());
    // Clear any uniforms not changed by material.
    resetUniformsNotSetByCurrent(shader);
    // Delegate rendering to the technique
    technique.render(renderManager, shader, geometry, lights, unit);
}
Also used : Renderer(com.jme3.renderer.Renderer) Shader(com.jme3.shader.Shader) Caps(com.jme3.renderer.Caps)

Aggregations

MatParamOverride (com.jme3.material.MatParamOverride)2 Uniform (com.jme3.shader.Uniform)2 VarType (com.jme3.shader.VarType)2 SafeArrayList (com.jme3.util.SafeArrayList)2 AssetManager (com.jme3.asset.AssetManager)1 OutputCapsule (com.jme3.export.OutputCapsule)1 TechniqueDefLogic (com.jme3.material.logic.TechniqueDefLogic)1 SceneProcessor (com.jme3.post.SceneProcessor)1 Caps (com.jme3.renderer.Caps)1 Renderer (com.jme3.renderer.Renderer)1 Bucket (com.jme3.renderer.queue.RenderQueue.Bucket)1 ShadowMode (com.jme3.renderer.queue.RenderQueue.ShadowMode)1 Control (com.jme3.scene.control.Control)1 Shader (com.jme3.shader.Shader)1