kneb
February 26, 2011, 12:55am
1
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 100100 8]; // 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]
kneb
February 27, 2011, 6:36am
2
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
My mesh comes out as a solid color how can i get the texture to cover the entire mesh?
pspeed
February 27, 2011, 7:45am
3
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.
kneb
February 27, 2011, 11:59pm
4
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.
normen
February 28, 2011, 12:22am
5
All that info should be available in the wiki if you look carefully.
ahoehma
February 28, 2011, 8:06am
6
I guess you should not use “m_ColorMap” any longer … use “ColorMap”.
Regards
Andreas
PS:
***craft rulez
http://code.google.com/p/bloxel/
kneb
March 1, 2011, 5:49am
7
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 100100 8]; // 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