类似于:Java3d: Texture is not applied to OBJ model properly
除了我自己生成IndexedTriangleArray并映射纹理。
几何图形很好,但它采用纹理图像左下角的颜色,而不是在整个图像上拉伸它。 Testure.jpg是256 * 256的图像。
编辑:奇怪的是,非索引的TriangleArray工作正常。 所以我认为我设置纹理坐标的方式有问题吗?
(要在IndexedTriangleArray和TriangleArray之间切换,只需在主函数中注释掉该行)
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);
}
}
答案 0 :(得分:0)
不可否认,我可以/应该早点注意到这一点,但是......已经有一段时间了,因为我主动一直在使用Java3D - 从那以后,我主要是挤出我的微薄的知识和记忆,以回答论坛和stackoverfow有关它的问题; - )
但是:您确实使用
设置了顶点的索引ta.setCoordinateIndex(...);
呼叫。但是另外必须使用
设置纹理坐标的索引ta.setTextureCoordinateIndex(0, ...);
0
指的是纹理坐标集(可能有多个纹理,具有不同的坐标集)。除此之外,索引与此处的顶点相同。
这里再次作为MCVE。 (图像名称已更改.Lena规则!)
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GraphicsConfiguration;
import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.ImageComponent2D;
import javax.media.j3d.IndexedTriangleArray;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Texture;
import javax.media.j3d.Texture2D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TriangleArray;
import javax.swing.JFrame;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.TexCoord2f;
import javax.vecmath.Vector3d;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;
public class SEMVCE
{
public static IndexedTriangleArray getITA(int gridSize, float h)
{
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);
}
}
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));
ta.setTextureCoordinateIndex(0, offset + 0, (i * rows + j));
ta.setTextureCoordinateIndex(0, offset + 1, (i * rows + j + 1));
ta.setTextureCoordinateIndex(0, offset + 2, ((i + 1) * rows + j));
ta.setTextureCoordinateIndex(0, offset + 3, ((i + 1) * rows + j));
ta.setTextureCoordinateIndex(0, offset + 4, (i * rows + j + 1));
ta.setTextureCoordinateIndex(0, 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("lena512color.png");
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[])
{
System.setProperty("sun.awt.noerasebackground","true");
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
Canvas3D c = new Canvas3D(config);
JFrame f = new JFrame();
f.getContentPane().add(c, BorderLayout.CENTER);
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
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);
u.addBranchGraph(bg);
setCameraPosition(u.getViewingPlatform(),
new Point3d(gridSize/2,5,-10),
new Point3d(gridSize/2,0,gridSize/2),
new Vector3d(0,1,0));
f.setSize(600,600);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
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);
}
}