Search in sources :

Example 11 with Technique

use of com.jme3.material.Technique in project jmonkeyengine by jMonkeyEngine.

the class Material method getSortId.

/**
     * Returns the sorting ID or sorting index for this material.
     *
     * <p>The sorting ID is used internally by the system to sort rendering
     * of geometries. It sorted to reduce shader switches, if the shaders
     * are equal, then it is sorted by textures.
     *
     * @return The sorting ID used for sorting geometries for rendering.
     */
public int getSortId() {
    if (sortingId == -1 && technique != null) {
        sortingId = technique.getSortId() << 16;
        int texturesSortId = 17;
        for (int i = 0; i < paramValues.size(); i++) {
            MatParam param = paramValues.getValue(i);
            if (!param.getVarType().isTextureType()) {
                continue;
            }
            Texture texture = (Texture) param.getValue();
            if (texture == null) {
                continue;
            }
            Image image = texture.getImage();
            if (image == null) {
                continue;
            }
            int textureId = image.getId();
            if (textureId == -1) {
                textureId = 0;
            }
            texturesSortId = texturesSortId * 23 + textureId;
        }
        sortingId |= texturesSortId & 0xFFFF;
    }
    return sortingId;
}
Also used : Image(com.jme3.texture.Image) Texture(com.jme3.texture.Texture)

Example 12 with Technique

use of com.jme3.material.Technique 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)

Example 13 with Technique

use of com.jme3.material.Technique in project jmonkeyengine by jMonkeyEngine.

the class Technique method render.

/**
     * Render the technique according to its {@link TechniqueDefLogic}.
     * 
     * @param renderManager The render manager to perform the rendering against.
     * @param shader The shader that was selected in 
     * {@link #makeCurrent(com.jme3.renderer.RenderManager, java.util.EnumSet)}.
     * @param geometry The geometry to render
     * @param lights Lights which influence the geometry.
     */
void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
    TechniqueDefLogic logic = def.getLogic();
    logic.render(renderManager, shader, geometry, lights, lastTexUnit);
}
Also used : TechniqueDefLogic(com.jme3.material.logic.TechniqueDefLogic)

Example 14 with Technique

use of com.jme3.material.Technique 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 15 with Technique

use of com.jme3.material.Technique in project jmonkeyengine by jMonkeyEngine.

the class RenderManager method renderGeometry.

/**
     * Renders the given geometry.
     * <p>
     * First the proper world matrix is set, if 
     * the geometry's {@link Geometry#setIgnoreTransform(boolean) ignore transform}
     * feature is enabled, the identity world matrix is used, otherwise, the 
     * geometry's {@link Geometry#getWorldMatrix() world transform matrix} is used. 
     * <p>
     * Once the world matrix is applied, the proper material is chosen for rendering.
     * If a {@link #setForcedMaterial(com.jme3.material.Material) forced material} is
     * set on this RenderManager, then it is used for rendering the geometry,
     * otherwise, the {@link Geometry#getMaterial() geometry's material} is used.
     * <p>
     * If a {@link #setForcedTechnique(java.lang.String) forced technique} is
     * set on this RenderManager, then it is selected automatically
     * on the geometry's material and is used for rendering. Otherwise, one
     * of the {@link MaterialDef#getDefaultTechniques() default techniques} is
     * used.
     * <p>
     * If a {@link #setForcedRenderState(com.jme3.material.RenderState) forced
     * render state} is set on this RenderManager, then it is used
     * for rendering the material, and the material's own render state is ignored.
     * Otherwise, the material's render state is used as intended.
     * 
     * @param geom The geometry to render
       * 
     * @see Technique
     * @see RenderState
     * @see Material#selectTechnique(java.lang.String, com.jme3.renderer.RenderManager) 
     * @see Material#render(com.jme3.scene.Geometry, com.jme3.renderer.RenderManager) 
     */
public void renderGeometry(Geometry geom) {
    if (geom.isIgnoreTransform()) {
        setWorldMatrix(Matrix4f.IDENTITY);
    } else {
        setWorldMatrix(geom.getWorldMatrix());
    }
    // Perform light filtering if we have a light filter.
    LightList lightList = geom.getWorldLightList();
    if (lightFilter != null) {
        filteredLightList.clear();
        lightFilter.filterLights(geom, filteredLightList);
        lightList = filteredLightList;
    }
    Material material = geom.getMaterial();
    //else the geom is not rendered
    if (forcedTechnique != null) {
        MaterialDef matDef = material.getMaterialDef();
        if (matDef.getTechniqueDefs(forcedTechnique) != null) {
            Technique activeTechnique = material.getActiveTechnique();
            String previousTechniqueName = activeTechnique != null ? activeTechnique.getDef().getName() : TechniqueDef.DEFAULT_TECHNIQUE_NAME;
            geom.getMaterial().selectTechnique(forcedTechnique, this);
            //saving forcedRenderState for future calls
            RenderState tmpRs = forcedRenderState;
            if (geom.getMaterial().getActiveTechnique().getDef().getForcedRenderState() != null) {
                //forcing forced technique renderState
                forcedRenderState = geom.getMaterial().getActiveTechnique().getDef().getForcedRenderState();
            }
            // use geometry's material
            material.render(geom, lightList, this);
            material.selectTechnique(previousTechniqueName, this);
            //restoring forcedRenderState
            forcedRenderState = tmpRs;
        //Reverted this part from revision 6197
        //If forcedTechnique does not exists, and forcedMaterial is not set, the geom MUST NOT be rendered
        } else if (forcedMaterial != null) {
            // use forced material
            forcedMaterial.render(geom, lightList, this);
        }
    } else if (forcedMaterial != null) {
        // use forced material
        forcedMaterial.render(geom, lightList, this);
    } else {
        material.render(geom, lightList, this);
    }
}
Also used : RenderState(com.jme3.material.RenderState) LightList(com.jme3.light.LightList) Material(com.jme3.material.Material) Technique(com.jme3.material.Technique) MaterialDef(com.jme3.material.MaterialDef)

Aggregations

Caps (com.jme3.renderer.Caps)4 Material (com.jme3.material.Material)3 Camera (com.jme3.renderer.Camera)3 Technique (com.jme3.material.Technique)2 Renderer (com.jme3.renderer.Renderer)2 Shader (com.jme3.shader.Shader)2 ShaderType (com.jme3.shader.Shader.ShaderType)2 Texture (com.jme3.texture.Texture)2 Statement (com.jme3.util.blockparser.Statement)2 IOException (java.io.IOException)2 LightList (com.jme3.light.LightList)1 MaterialDef (com.jme3.material.MaterialDef)1 RenderState (com.jme3.material.RenderState)1 ShaderGenerationInfo (com.jme3.material.ShaderGenerationInfo)1 StaticPassLightingLogic (com.jme3.material.logic.StaticPassLightingLogic)1 TechniqueDefLogic (com.jme3.material.logic.TechniqueDefLogic)1 GeometryList (com.jme3.renderer.queue.GeometryList)1 Geometry (com.jme3.scene.Geometry)1 Box (com.jme3.scene.shape.Box)1 DefineList (com.jme3.shader.DefineList)1