Vertex Alpha

how would i go about setting the alpha for each vertex? i tried something like this:



  ColorRGBA[] colors={
   new ColorRGBA(1,0,0,7f),
   new ColorRGBA(1,0,0,0.2f),
   new ColorRGBA(0,1,0,1),
   new ColorRGBA(0,1,0,1)
  };

Note: untested, syntax may be a bit off…



Quad quad = new Quad("Da_quad");
FloatBuffer colorBuffer = quad.getColorBuffer(0);
colorBuffer.put(r).put(g).put(b).put(alpha);  // vertex 0
colorBuffer.put(r).put(g).put(b).put(alpha);  // vertex 1
colorBuffer.put(r).put(g).put(b).put(alpha);  // vertex 2
colorBuffer.put(r).put(g).put(b).put(alpha);  // vertex 3



You will also need to set up and assign an AlphaState to the quad. http://www.jmonkeyengine.com/doc/
And then call the proper update methods. ( updateRenderState() and updateGeometricState() ? )

hello. i tried that code on a terrainblock and it didn't work. i tried to just get the color buffer and toString it but i got a null pointer exception

ok, what is it that you want to accomplish? Semi-transparent terrain?

im trying to modify the alpha of each vertex on an TerrainBlock

Well, if you got a nullpointerexception then there is no colorbuffer. You must create one with BufferUtils.createColorBuffer() and then set it to the mesh with setColorBuffer(0)



And also remember that vertex colors does nothing unless you turn off lighting.

how would i go about getting vertex alpha and lighting?

Tobias said:

Well, if you got a nullpointerexception then there is no colorbuffer. You must create one with BufferUtils.createColorBuffer() and then set it to the mesh with setColorBuffer(0)

And also remember that vertex colors does nothing unless you turn off lighting.


Or if you use a material state that makes use of color materials.

is it possible to have a textured terrainblock with vertex's with different alphas and lighting?

Is there a broken record in here? :wink:



Yes, it is possible as stated above.  Set the per-vertex colors in the color buffers of your terrainblocks and use a material state with a color material setting targetting diffuse.  If your wanting different alphas to make it possible to see through the terrain, you'll also need to apply an alphastate.

heres what all my effort got me :smiley:





code if anyone is interested.


package VertexTerrain;

import com.jme.scene.Node;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.MaterialState;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.util.TextureManager;
import com.jme.util.geom.BufferUtils;
import com.jmex.terrain.TerrainBlock;
import com.jme.system.DisplaySystem;

import java.util.ArrayList;
import java.net.URL;
import java.nio.FloatBuffer;

import org.lwjgl.opengl.Display;

/**
 * Created by IntelliJ IDEA.
 * User: bglib
 * Date: Feb 20, 2007
 * Time: 3:47:16 AM
 * Desc: A Terrain that uses layers to harness the power of vertex alphas.
 */
public class VertexTerrainBlock extends Node
{
    ArrayList<TextureState> textureStates = new ArrayList<TextureState>();
    public ArrayList<TerrainBlock> terrainBlocks = new ArrayList<TerrainBlock>();
    private int terrainSize;
    private boolean terrainClod;
    private int numLayers=0;
    private AlphaState as;
    private FloatBuffer vertexBuffer;
    private MaterialState ms;
    private int[] heights;


    public VertexTerrainBlock(int size, boolean clod, DisplaySystem display)
    {
        terrainSize=size;
        terrainClod=clod;
        as = display.getRenderer().createAlphaState();
                as.setBlendEnabled(true);
                as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
                as.setDstFunction(AlphaState.SB_ONE_MINUS_SRC_ALPHA);
                as.setTestFunction(AlphaState.TF_GREATER);

        ms = display.getRenderer().createMaterialState();
            ms.setColorMaterial(MaterialState.CM_DIFFUSE);
        this.setRenderState(ms);
        this.setRenderState(as);
        randomNoise();
    }
    public void randomNoise()
    {
        int[] noiseRandom = new int[(terrainSize*terrainSize)];
        for(int x = 0;x<((terrainSize)*(terrainSize));x++)
        {
            noiseRandom[x]=(int)(Math.random()*5);
        }
        heights=noiseRandom;
    }
    public float[] getColorBuffer(float alpha)
    {
        float[] tempFloat = new float[(terrainSize*terrainSize)*4];
        for(int x = 0;x<((terrainSize)*(terrainSize))*4;x+=4)
        {
            tempFloat[x]=1f;
            tempFloat[x+1]=1f;
            tempFloat[x+2]=1f;
            tempFloat[x+3]=alpha;
        }
        return tempFloat;
    }
    public void addLayer(URL texture, DisplaySystem display, float startAlpha)
    {
        TerrainBlock tb=new TerrainBlock("block: "+numLayers,terrainSize,
        new Vector3f(16,8,16),
        heights,
        new Vector3f(0,0,0),
        false);

        tb.setModelBound(new BoundingBox());
        tb.updateModelBound();
        tb.updateRenderState();

        Texture t =
            TextureManager.loadTexture(texture,
            Texture.MM_LINEAR,
            Texture.FM_LINEAR);
            t.setScale(new Vector3f(terrainSize,terrainSize,terrainSize));
            t.setWrap(Texture.WM_WRAP_S_WRAP_T);
      // Assign the texture to the TextureState
            TextureState ts=display.getRenderer().createTextureState();
                ts.setTexture(t);
                textureStates.add(ts);
        //float[] tempFloat = new float[4000];

        FloatBuffer colorBuffer = BufferUtils.createFloatBuffer(getColorBuffer(startAlpha));
        tb.setColorBuffer(0,colorBuffer);

        tb.setRenderState(ts);
        terrainBlocks.add(tb);

        this.attachChild(tb);
        numLayers++;
    }
    public void setHeight(int x, int y, int amount)
    {
        for(int n = 0; n<terrainBlocks.size();n++)
        {
            TerrainBlock tb = terrainBlocks.get(n);
            vertexBuffer = tb.getVertexBuffer(0);
            vertexBuffer.put(1+(x+(terrainSize*y))*3, amount);

            tb.setVertexBuffer(0,vertexBuffer);
            tb.setModelBound(new BoundingBox());
            tb.updateModelBound();
            tb.updateRenderState();
            tb.updateGeometricState(0,true);
        }
    }
    public void setAlpha(int x, int y, int layer, float amount)
    {
        TerrainBlock tb = terrainBlocks.get(layer);
        FloatBuffer colorBuffer = tb.getColorBuffer(0);//reuse same buffer for speed
        colorBuffer.put(3+(x+(terrainSize*y))*4, amount);
        //colorBuffer.put(4, amount);
        tb.setColorBuffer(0,colorBuffer);

        tb.setModelBound(new BoundingBox());
        tb.updateModelBound();
        tb.updateRenderState();
        tb.updateGeometricState(0,true);
    }


}

I tried to make some better looking terrain:





once i optimize some things and clean up the code im probably going make a terrain editor for it



also question… whats the easiest way to tell jme not to render certain polygons. maybe tell it based on the vertices?

The best way is to tell it not to render certain batches, not polygons.  You can use setCullMode for that.