[solved] help to identify Splat blending problem

Hi.  I'd very much appreciate it if somebody could identify my problem.  I know that most of the code is right, because the multiPass transparency does work right if I just put a texture with transparency in one PassNodeState over top of a different PassNodeState.  What I can't get to work, is to combine an alpha texture ("alphaTexture" in the code) with an opaque texture ("dirtTexture" in the code) to make a single PassNode state that is transparent in some areas.  I have copied the BlendState and Combiner functions from demos that are doing similar things, but my result is always the unaffected, opaque dirt.



I don't care about the clamping and repeat settings at this point, as I can adjust them after I get transparency working.



… I'm starting to think that maybe I need to somehow duplicate the texture coord values from the first texture channel to the second, as is done when splattering terrain by the .setDatailTexture() methods.  I see no methods to accomplish the same thing without the terrain classes though.  Still studying all of the demo programs…


/*
 * @(#)$Id: PassedQuadNode.java 2192 2009-05-04 23:04:07Z blaine $
 */


package com.admc.play;

import java.net.URL;

import com.jme.scene.shape.Quad;
import com.jme.math.Vector3f;
import com.jme.util.TextureManager;
import com.jme.scene.state.TextureState;
import com.jme.image.Texture;
import com.jme.system.DisplaySystem;
import com.jme.scene.PassNode;
import com.jme.scene.PassNodeState;
import com.jme.scene.state.BlendState;
import com.jme.renderer.Renderer;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.ResourceLocator;

public class PassedQuadNode extends PassNode {
    public PassedQuadNode() {
        super("passedQuadNode");
        PassNodeState pnState;
        Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer();

        Quad quad = new Quad("passedQuad", 2, 2);
        attachChild(quad);
        quad.setLocalTranslation(new Vector3f(0, 2f, 0));

        BlendState blendState = renderer.createBlendState();
        blendState.setBlendEnabled(true);
        blendState.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
        blendState.setDestinationFunction(
                BlendState.DestinationFunction.OneMinusSourceAlpha);
        blendState.setTestEnabled(true);
        blendState.setTestFunction(BlendState.TestFunction.GreaterThan);
        blendState.setEnabled(true);

        /*
        URL labelUrl = ResourceLocatorTool.locateResource(
                ResourceLocatorTool.TYPE_TEXTURE,
                "/textures/labelled.png");
        if (labelUrl == null)
            throw new IllegalStateException(
                    "Missing resource:  /textures/labelled.png");
        */
        URL dirtUrl = ResourceLocatorTool.locateResource(
                ResourceLocatorTool.TYPE_TEXTURE, "/textures/dirt.jpg");
        if (dirtUrl == null)
            throw new IllegalStateException(
                    "Missing resource:  /textures/dirt.jpg");
        URL alphaUrl = ResourceLocatorTool.locateResource(
                ResourceLocatorTool.TYPE_TEXTURE, "/textures/alphamap01.png");
        if (alphaUrl == null)
            throw new IllegalStateException(
                    "Missing resource:  /textures/alphamap01.png");
        //Texture labelTexture = TextureManager.loadTexture(labelUrl);
        Texture dirtTexture = TextureManager.loadTexture(dirtUrl);
        Texture alphaTexture = TextureManager.loadTexture(alphaUrl);

        /*
        dirtTexture.setApply(Texture.ApplyMode.Modulate); // this is default
        dirtTexture.setWrap(Texture.WrapMode.Repeat);
        */

        alphaTexture.setApply(Texture.ApplyMode.Combine);
        alphaTexture.setCombineFuncRGB(Texture.CombinerFunctionRGB.Replace);
        alphaTexture.setCombineSrc0RGB(Texture.CombinerSource.Previous);
        alphaTexture.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor);
        alphaTexture.setCombineFuncAlpha(Texture.CombinerFunctionAlpha.Replace);

        /*
        TextureState labelTs = renderer.createTextureState();
        labelTs.setTexture(labelTexture, 0);
        */
        TextureState transpTs = renderer.createTextureState();
        transpTs.setTexture(dirtTexture, 0);
        transpTs.setTexture(alphaTexture, 1);

        /*
        PassNodeState labelPnState = new PassNodeState();
        labelPnState.setPassState(labelTs);
        */
        PassNodeState transpPnState = new PassNodeState();
        transpPnState.setPassState(transpTs);
        transpPnState.setPassState(blendState);

        //addPass(labelPnState);
        addPass(transpPnState);
    }
}

There's a method in Geometry, copyTextureCoordinates, should be just what you need. AFAIK all setDetailTexture does is call that.



quad.copyTextureCoordinates(0, 1, 1);

Alric said:

There's a method in Geometry, copyTextureCoordinates, should be just what you need. AFAIK all setDetailTexture does is call that.


quad.copyTextureCoordinates(0, 1, 1);




That's it!  Works great now.  What would I do without you?