Similar to: Java3d: Texture is not applied to OBJ model properly
Except that i generate the IndexedTriangleArray myself and map the texture.
The geometry is fine but it takes the colour of the bottom left corner of the texture image instead of stretching it over the entire image. Testure.jpg is a 256*256 image.
Edit: Strangely, The non-indexed TriangleArray works fine. So i assume it's a problem with the way i'm setting the texture coordinates?
( To switch between IndexedTriangleArray and TriangleArray, Just comment out the line in the main function )
import com.sun.j3d.utils.universe.*;
import javax.vecmath.*;
import javax.media.j3d.*;
import java.awt.*;
import org.j3d.geom.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.image.*;
import java.io.*;
public class SEMVCE{
public static IndexedTriangleArray getITA(int gridSize, float h) { //Creates a terrain using indexedTriangleArray geometry
int rows = gridSize,
cols = gridSize;
int vertexCount = gridSize*gridSize;
int cols_1 = cols-1,
rows_1 = rows-1;
IndexedTriangleArray ta = new IndexedTriangleArray( vertexCount, IndexedTriangleArray.COORDINATES | IndexedTriangleArray.TEXTURE_COORDINATE_2, 6*rows_1*cols_1);
Point3f coords[] = new Point3f[vertexCount];
TexCoord2f texCo[] = new TexCoord2f[cols*rows];
//Set the vertices
for(int i=0;i<cols;i++){
for(int j=0;j<rows;j++){
if(i%2==1 && j%2==1 )
coords[i*rows+j] = new Point3f(i,h,j);
else
coords[i*rows+j] = new Point3f(i,0,j);
//texCo[i*rows+j] = new TexCoord2f((float)i/(gridSize-1),(float)j/(gridSize-1) );
}
}
for (int i=0;i<vertexCount;i++){
texCo[i] = new TexCoord2f(coords[i].x /(gridSize-1), coords[i].z /(gridSize-1));
}
ta.setCoordinates(0,coords);
ta.setTextureCoordinates(0,0, texCo);
//Do the indexes
int offset = 0;
for(int i=0;i<cols_1;i++){
for(int j=0;j<rows_1;j++){
offset = (i*rows_1+j)*6;
ta.setCoordinateIndex(offset+0, (i*rows + j));
ta.setCoordinateIndex(offset+1, (i*rows+ j+1 ));
ta.setCoordinateIndex(offset+2, ((i+1)*rows + j));
ta.setCoordinateIndex(offset+3, ((i+1)*rows + j));
ta.setCoordinateIndex(offset+4, (i*rows+ j+1 ));
ta.setCoordinateIndex(offset+5, ((i+1)*rows + j+1));
}
}
return ta;
}
public static TriangleArray getTriangleArray(int gridSize, float h){ //Creates a terrain using TriangleArray geometry
int rows = gridSize,
cols = gridSize;
int cols_1 = cols-1,
rows_1 = rows-1;
int vertexCount = 6*rows_1*cols_1;
TriangleArray ta = new TriangleArray( vertexCount, IndexedTriangleArray.COORDINATES | IndexedTriangleArray.TEXTURE_COORDINATE_2);
Point3f coords[] = new Point3f[vertexCount];
TexCoord2f texCo[] = new TexCoord2f[vertexCount];
//Do the vertices
int offset = 0;
float height = 0;
for(int i=0;i<cols_1;i++){
for(int j=0;j<rows_1;j++){
if(i%3==1 && j%3==1)
height= h;
else
height = 0;
offset = (i*rows_1+j)*6;
coords[offset+0] = new Point3f(i,0, j);
coords[offset+1] = new Point3f((i+1), 0,j);
coords[offset+2] = new Point3f(i, 0, j+1);
coords[offset+3] = new Point3f( (i+1), 0, j);
coords[offset+4] = new Point3f((i+1), 0,j+1);
coords[offset+5] = new Point3f(i,0, j+1);
if(i%2==1 && j%2==1)
coords[offset+0] = new Point3f(i,h, j);
else if(i%2==0 && j%2==0)
coords[offset+4] = new Point3f((i+1), h,j+1);
else if( (i+1)%2==1 && j%2==1){
coords[offset+1] = new Point3f(i+1,h,j);
coords[offset+3] = new Point3f(i+1,h,j);
}
else if( i%2==1 && (j+1)%2==1){
coords[offset+2] = new Point3f(i,h, j+1);
coords[offset+5] = new Point3f(i,h, j+1);
}
}
}
int gridSize_1 = gridSize-1;
for (int i=0;i<vertexCount;i++){
texCo[i] = new TexCoord2f(coords[i].x / gridSize_1, coords[i].z / gridSize_1);
}
ta.setCoordinates(0,coords);
ta.setTextureCoordinates(0,0, texCo);
return ta;
}
public static Texture2D loadTexture(String filename){
//ImageObserver iObserve = new ImageObserver();
TextureLoader loader = new TextureLoader(filename, new Container());
ImageComponent2D image = loader.getImage();
Texture2D texture = new Texture2D(Texture2D.BASE_LEVEL, Texture2D.RGBA, image.getWidth(), image.getHeight() );
texture.setImage(0, image);
texture.setEnable( true );
texture.setBoundaryModeS(Texture.WRAP);
texture.setBoundaryModeT(Texture.WRAP);
return texture;
}
public static Appearance getAppearance(){
Appearance appear = new Appearance();
Texture2D texture = loadTexture("texture.jpg");
appear.setTexture(texture);
PolygonAttributes polygonAttributes = new PolygonAttributes();
polygonAttributes.setCullFace(PolygonAttributes.CULL_NONE);
//appear.setTexCoordGeneration(new TexCoordGeneration());
appear.setPolygonAttributes(polygonAttributes);
return appear;
}
public static void main(String args[]){
SimpleUniverse world = new SimpleUniverse();
int gridSize=11;
//Comment out according to which you want to test
//GeometryArray geometry = getTriangleArray(gridSize,2);
GeometryArray geometry = getITA(gridSize,2);
Shape3D shape= new Shape3D(geometry,getAppearance());
BranchGroup bg = new BranchGroup();
bg.addChild(shape);
world.addBranchGraph(bg);
setCameraPosition(world.getViewingPlatform(), new Point3d(gridSize/2,5,-10), new Point3d(gridSize/2,0,gridSize/2), new Vector3d(0,1,0));//new Point3d(gridSize/2,gridSize/2,gridSize/2), new Point3d(gridSize/2,0,gridSize/2), new Vector3d(0,1,0));
}
public static void setCameraPosition(ViewingPlatform VP,Point3d from, Point3d to, Vector3d v){
TransformGroup viewTransform = VP.getViewPlatformTransform();
Transform3D t3d = new Transform3D();
t3d.lookAt(from,to,v);
t3d.invert();
viewTransform.setTransform(t3d);
}
}