Need help textureing a complex mesh - minecraft type block engine

I have banged my head on this for the last 2 days and I’m missing something, btw I haven’t done much java programming so if you notice anything that can be tweaked please let me know.

I have a mesh being built from a 3d matrix of values to simulate the block world like mine craft (yes another one).

The mesh works except the texture I have assigned does not render I just get a solid color.

If someone could point out my mistakes I would be appreciative.



[java]package mygame;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.math.Vector2f;

import com.jme3.scene.Geometry;

import com.jme3.math.ColorRGBA;

import java.util.Random;

import com.jme3.util.SkyFactory;

import com.jme3.scene.Mesh;

import com.jme3.util.BufferUtils;

import com.jme3.scene.VertexBuffer.Type;

import java.util.ArrayList;

import com.jme3.texture.Texture;

import com.jme3.light.PointLight;





/**

  • test
  • @author normenhansen

    /

    public class Main extends SimpleApplication {



    byte themap[][][];

    Mesh mapmesh; // the mesh for the map

    ArrayList<Vector3f> vertices=new ArrayList<Vector3f>(); // points

    ArrayList<Vector2f> texCoord=new ArrayList<Vector2f>(); // tex cords

    float bsize=1; // block size

    int indexes[]=new int[100
    1001008]; // index list

    int ic=0;

    Texture envMap;





    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    @Override

    public void simpleInitApp() {



    flyCam.setMoveSpeed(25);



    mapmesh = new Mesh();



    themap=buildMap(100,100,100);



    rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky_horiz_6-2048.jpg", true));



    PointLight lamp_light = new PointLight();

    lamp_light.setColor(ColorRGBA.White);

    lamp_light.setRadius(200f);

    lamp_light.setPosition(new Vector3f(50,200,50));

    rootNode.addLight(lamp_light);



    Material mat;

    mat = new Material(assetManager, "Common/MatDefs/Misc/SimpleTextured.j3md");

    mat.setTexture("m_ColorMap", assetManager.loadTexture("Textures/dirt.jpg"));



    buildmesh(100,100,100);



    texCoord.add(new Vector2f(0,0));

    texCoord.add(new Vector2f(100,0));

    texCoord.add(new Vector2f(0,100));

    texCoord.add(new Vector2f(100,100));



    // move the index to correctly sized array

    // java is not my strong point

    int indx[]=new int[ic];

    for(int c=0;c<ic;c++) {

    indx[c]=indexes[c];

    }



    Vector3f[] v3=vertices.toArray(new Vector3f[vertices.size()]);

    Vector2f[] v2=texCoord.toArray(new Vector2f[texCoord.size()]);

    mapmesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(v3));

    mapmesh.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(v2));

    mapmesh.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indx));



    mapmesh.updateBound();

    Geometry map = new Geometry("Map", mapmesh);

    map.setMaterial(mat);

    rootNode.attachChild(map);







    }



    @Override

    public void simpleUpdate(float tpf) {

    //TODO: add update code

    }



    public void buildmesh(int sx,int sy,int sz) {

    for(int y=2;y<sy-2;y++) {

    for(int z=2;z<sz-2;z++) {

    for(int x=2;x<sx-2;x++) {

    if(themap[x][y][z]==0) {

    setboxside(x,y,z);

    }

    }

    }

    }

    }



    public void setboxside(int x,int y,int z) {

    int face=-1;

    if(themap[x][y][z+1]!=0) setface(x,y,z,5);

    if(themap[x][y][z-1]!=0) setface(x,y,z,2);

    if(themap[x][y+1][z]!=0) setface(x,y,z,4);

    if(themap[x][y-1][z]!=0) setface(x,y,z,1);

    if(themap[x+1][y][z]!=0) setface(x,y,z,3);

    if(themap[x-1][y][z]!=0) setface(x,y,z,0);

    }



    public void setface(int x,int y, int z,int face) {

    int vi=vertices.size();

    float bx,by,bz;

    int x2,y2,z2;

    float halfbsize=bsize/2;

    bx=xbsize;

    by=y
    bsize;

    bz=z*bsize;

    Vector3f pa=new Vector3f(bx-halfbsize,by-halfbsize,bz-halfbsize);

    Vector3f pb=new Vector3f(bx+halfbsize,by-halfbsize,bz-halfbsize);

    Vector3f pc=new Vector3f(bx-halfbsize,by+halfbsize,bz-halfbsize);

    Vector3f pd=new Vector3f(bx+halfbsize,by+halfbsize,bz-halfbsize);



    Vector3f pe=new Vector3f(bx-halfbsize,by-halfbsize,bz+halfbsize);

    Vector3f pf=new Vector3f(bx+halfbsize,by-halfbsize,bz+halfbsize);

    Vector3f pg=new Vector3f(bx-halfbsize,by+halfbsize,bz+halfbsize);

    Vector3f ph=new Vector3f(bx+halfbsize,by+halfbsize,bz+halfbsize);



    switch(face) {

    case 0: // x=-1

    vertices.add(pg);

    vertices.add(pe);

    vertices.add(pa);

    vertices.add(pc);





    break;

    case 1: // y=-1



    vertices.add(pa);

    vertices.add(pe);

    vertices.add(pf);

    vertices.add(pb);



    break;

    case 2: // z=-1

    vertices.add(pc);

    vertices.add(pa);

    vertices.add(pb);

    vertices.add(pd);



    break;

    case 3: // x=1

    vertices.add(pd);

    vertices.add(pb);

    vertices.add(pf);

    vertices.add(ph);



    break;

    case 4: // y=1

    vertices.add(pg);

    vertices.add(pc);

    vertices.add(pd);

    vertices.add(ph);



    break;

    case 5: // z=1

    vertices.add(ph);

    vertices.add(pf);

    vertices.add(pe);

    vertices.add(pg);



    break;



    default: break;

    }

    if((face>-1)&&(face<6)) {

    indexes[ic++]=vi+0;

    indexes[ic++]=vi+1;

    indexes[ic++]=vi+2;

    indexes[ic++]=vi+2;

    indexes[ic++]=vi+3;

    indexes[ic++]=vi+0;

    }

    }



    // load some random data

    public byte[][][] buildMap(int sx,int sy,int sz) {

    byte map[][][]=new byte[sx][sy][sz];

    byte blocktype;

    int x,y,z;

    Random r=new Random();

    for(y=0;y<sy;y++) {

    for(z=0;z<sz;z++) {

    for(x=0;x<sx;x++) {

    blocktype=0; // default

    if(y<3) blocktype=1; // base

    if(r.nextInt(200)==1) { // random splatter

    blocktype=1;

    }

    // set the new block type

    map[x][y][z]=blocktype;

    }

    }

    }

    return map;

    }



    }[/java]

Since the above may have been complicated, I’ll try to simplify it in the hope someone who knows how to do it may reply :wink:

My mesh comes out as a solid color how can i get the texture to cover the entire mesh?

From a quick look, it doesn’t seem like you are giving your vertexes their texture coordinates.



I’m actually not sure why your mesh isn’t blowing up but something under the covers must be being nice to you. The number of vertexes and the number of texture coordinates should be the same.



…at least in my experience.

Thanks pspeed,

I’ll dont supose anyone can point me to information about how texturing works with vertices, I think im missing some basic understanding of textures and stuff.

All that info should be available in the wiki if you look carefully.

I guess you should not use “m_ColorMap” any longer … use “ColorMap”.



Regards

Andreas



PS:

***craft rulez :wink:

http://code.google.com/p/bloxel/

Well thanks for the help guys the thing is rendering correctly now, and the frame rate for 100x100x100 block enviroment is not to bad either.



The working code:



[java]package mygame;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.math.Vector2f;

import com.jme3.scene.Geometry;

import com.jme3.math.ColorRGBA;

import java.util.Random;

import com.jme3.util.SkyFactory;

import com.jme3.scene.Mesh;

import com.jme3.util.BufferUtils;

import com.jme3.scene.VertexBuffer.Type;

import java.util.ArrayList;

import com.jme3.texture.Texture;

import com.jme3.light.PointLight;





/**

  • test
  • @author normenhansen

    /

    public class Main extends SimpleApplication {



    byte themap[][][];

    Mesh mapmesh; // the mesh for the map

    ArrayList<Vector3f> vertices=new ArrayList<Vector3f>(); // points

    ArrayList<Vector2f> texCoord=new ArrayList<Vector2f>(); // tex cords

    float bsize=1; // block size

    int indexes[]=new int[100
    1001008]; // index list

    int ic=0;

    Texture envMap;





    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    @Override

    public void simpleInitApp() {



    flyCam.setMoveSpeed(25);



    mapmesh = new Mesh();



    themap=buildMap(100,100,100);



    rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky_horiz_6-2048.jpg", true));



    PointLight lamp_light = new PointLight();

    lamp_light.setColor(ColorRGBA.White);

    lamp_light.setRadius(200f);

    lamp_light.setPosition(new Vector3f(50,200,50));

    rootNode.addLight(lamp_light);



    Material mat;

    mat = new Material(assetManager, "Common/MatDefs/Misc/SimpleTextured.j3md");

    mat.setTexture("m_ColorMap", assetManager.loadTexture("Textures/dirt.jpg"));



    buildmesh(100,100,100);







    // move the index to correctly sized array

    // java is not my strong point

    int indx[]=new int[ic];

    for(int c=0;c<ic;c++) {

    indx[c]=indexes[c];

    }



    Vector3f[] v3=vertices.toArray(new Vector3f[vertices.size()]);

    Vector2f[] v2=texCoord.toArray(new Vector2f[texCoord.size()]);

    mapmesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(v3));

    mapmesh.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(v2));

    mapmesh.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indx));



    mapmesh.updateBound();

    Geometry map = new Geometry("Map", mapmesh);

    map.setMaterial(mat);

    rootNode.attachChild(map);







    }



    @Override

    public void simpleUpdate(float tpf) {

    //TODO: add update code

    }



    public void buildmesh(int sx,int sy,int sz) {

    for(int y=2;y<sy-2;y++) {

    for(int z=2;z<sz-2;z++) {

    for(int x=2;x<sx-2;x++) {

    if(themap[x][y][z]==0) {

    setboxside(x,y,z);

    }

    }

    }

    }

    }



    public void setboxside(int x,int y,int z) {

    int face=-1;

    if(themap[x][y][z+1]!=0) setface(x,y,z,5);

    if(themap[x][y][z-1]!=0) setface(x,y,z,2);

    if(themap[x][y+1][z]!=0) setface(x,y,z,4);

    if(themap[x][y-1][z]!=0) setface(x,y,z,1);

    if(themap[x+1][y][z]!=0) setface(x,y,z,3);

    if(themap[x-1][y][z]!=0) setface(x,y,z,0);

    }



    public void setface(int x,int y, int z,int face) {

    int vi=vertices.size();

    float bx,by,bz;

    int x2,y2,z2;

    float halfbsize=bsize/2;

    bx=xbsize;

    by=y
    bsize;

    bz=z*bsize;

    Vector3f pa=new Vector3f(bx-halfbsize,by-halfbsize,bz-halfbsize);

    Vector3f pb=new Vector3f(bx+halfbsize,by-halfbsize,bz-halfbsize);

    Vector3f pc=new Vector3f(bx-halfbsize,by+halfbsize,bz-halfbsize);

    Vector3f pd=new Vector3f(bx+halfbsize,by+halfbsize,bz-halfbsize);



    Vector3f pe=new Vector3f(bx-halfbsize,by-halfbsize,bz+halfbsize);

    Vector3f pf=new Vector3f(bx+halfbsize,by-halfbsize,bz+halfbsize);

    Vector3f pg=new Vector3f(bx-halfbsize,by+halfbsize,bz+halfbsize);

    Vector3f ph=new Vector3f(bx+halfbsize,by+halfbsize,bz+halfbsize);

    Vector2f t1=new Vector2f(0,0);

    Vector2f t2=new Vector2f(1,0);

    Vector2f t3=new Vector2f(0,1);

    Vector2f t4=new Vector2f(1,1);



    switch(face) {

    case 0: // x=-1

    vertices.add(pg);

    vertices.add(pe);

    vertices.add(pa);

    vertices.add(pc);

    texCoord.add(t1);

    texCoord.add(t2);

    texCoord.add(t3);

    texCoord.add(t4);



    break;

    case 1: // y=-1



    vertices.add(pa);

    vertices.add(pe);

    vertices.add(pf);

    vertices.add(pb);

    texCoord.add(t1);

    texCoord.add(t2);

    texCoord.add(t3);

    texCoord.add(t4);



    break;

    case 2: // z=-1

    vertices.add(pc);

    vertices.add(pa);

    vertices.add(pb);

    vertices.add(pd);



    break;

    case 3: // x=1

    vertices.add(pd);

    vertices.add(pb);

    vertices.add(pf);

    vertices.add(ph);

    texCoord.add(t1);

    texCoord.add(t2);

    texCoord.add(t3);

    texCoord.add(t4);



    break;

    case 4: // y=1

    vertices.add(pg);

    vertices.add(pc);

    vertices.add(pd);

    vertices.add(ph);

    texCoord.add(t1);

    texCoord.add(t2);

    texCoord.add(t3);

    texCoord.add(t4);



    break;

    case 5: // z=1

    vertices.add(ph);

    vertices.add(pf);

    vertices.add(pe);

    vertices.add(pg);

    texCoord.add(t1);

    texCoord.add(t2);

    texCoord.add(t3);

    texCoord.add(t4);



    break;



    default: break;

    }

    if((face>-1)&&(face<6)) {

    indexes[ic++]=vi+0;

    indexes[ic++]=vi+1;

    indexes[ic++]=vi+2;

    indexes[ic++]=vi+2;

    indexes[ic++]=vi+3;

    indexes[ic++]=vi+0;

    }

    }



    // load some random data

    public byte[][][] buildMap(int sx,int sy,int sz) {

    byte map[][][]=new byte[sx][sy][sz];

    byte blocktype;

    int x,y,z;

    Random r=new Random();

    for(y=0;y<sy;y++) {

    for(z=0;z<sz;z++) {

    for(x=0;x<sx;x++) {

    blocktype=0; // default

    if(y<3) blocktype=1; // base

    if(r.nextInt(20)==1) { // random splatter

    blocktype=1;

    }

    // set the new block type

    map[x][y][z]=blocktype;

    }

    }

    }

    return map;

    }



    }[/java]

Today I found a way to create a multi-texture box … not with shaders (I will try this later gg) … but quite simple with a MultiFaceBox.



FYI: http://ahoehma.wordpress.com/2011/03/02/multifacebox-mesh-for-bloxel/



Regards

Andreas