Posted by
Hugo Lizzi on
Jan 31, 2020; 5:01pm
URL: https://forum.jogamp.org/Multi-Texturing-tp4040312.html
I just updated by project to Java3D 1.7. I was surprised at how easy it was.
I would like to say how much I appreciate that Java3D is being maintained.
I don't see any other UI that is as easy.
Now for my problem.
I am trying to do multi-texturing. From what I can tell of the "Getting Started with Java3D API" tutorial there are 2 types of multi-texturing.
The first type is called multi-level texturing where 2 or more texture images overlay each other (also called mipmaps).
Instructions for doing this type of multi-texturing are given in "Getting Started" chapter 7.6.
The second type is just called multi-texturing where 2 or more texture images are applied to different parts of the same Visual Object.
Instructions for doing this type of multi-texturing are given in "Getting Started" chapter 7.8.
I am trying to do the second.
I created a simple zero thickness 3D rectangle with the intention of applying one texture on the front and one on the back.
But no matter how I write the code, the second texture gets put on the back OK,
but the front just gets color from the edge of the second texture.
It seems like the second TextureUnitState is applied to the whole Visual Object overwriting the first.
If anyone can point out an error I would be very appreciative.
Here is my code after 100 hours of trial and error (mostly error).
/**
* Uses JDK 12.0.1 and Java3D version 1.7
*/
public class MultiTexTest extends JFrame {
static final long serialVersionUID = 1;
public static void main( String[] args ) { new MultiTexTest(); }
public MultiTexTest() {
setPreferredSize( new Dimension( 600, 400 ) );
GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas3D = new Canvas3D( config );
canvas3D.setBounds( 0, 0, 1000, 1000 );
add( canvas3D );
MultiTexRectangle multiTexRectangle = new MultiTexRectangle( canvas3D );
TransformGroup rectangleTrans = new TransformGroup();
rectangleTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
rectangleTrans.addChild( multiTexRectangle );
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, 8000);
RotationInterpolator rotator = new RotationInterpolator(
rotationAlpha, rectangleTrans, yAxis, 0f, (float) Math.PI*2f );
BoundingSphere bounds = new BoundingSphere( new Point3d(0, 0, 0), 600 );
rotator.setSchedulingBounds( bounds );
BranchGroup branchGroupRoot = new BranchGroup();
branchGroupRoot.addChild( rectangleTrans );
branchGroupRoot.addChild( rotator );
branchGroupRoot.compile();
SimpleUniverse simpleU = new SimpleUniverse( canvas3D );
simpleU.getViewingPlatform().setNominalViewingTransform();
simpleU.addBranchGraph( branchGroupRoot );
pack();
setVisible( true );
}
}
import java.io.IOException;
import java.net.URL;
import org.jogamp.java3d.Appearance;
import org.jogamp.java3d.Canvas3D;
import org.jogamp.java3d.GeometryArray;
import org.jogamp.java3d.Shape3D;
import org.jogamp.java3d.Texture;
import org.jogamp.java3d.TextureAttributes;
import org.jogamp.java3d.TextureUnitState;
import org.jogamp.java3d.TriangleArray;
import org.jogamp.java3d.utils.image.TextureLoader;
import org.jogamp.vecmath.Point3f;
import org.jogamp.vecmath.TexCoord2f;
import org.jogamp.vecmath.Vector3f;
public class MultiTexRectangle extends Shape3D {
GeometryArray geometryArray;
Appearance appearance = new Appearance();
int[] texCoordSetMap = new int[2];
Point3f[] vertexArray = new Point3f[12]; // Vertex Coords for 2 sided rectangle
Vector3f[] normalArray = new Vector3f[12];
TexCoord2f[] textureArray0 = new TexCoord2f[6]; // Texture Coords for front of rectangle
TexCoord2f[] textureArray1 = new TexCoord2f[6]; // Texture Coords for back of rectangle
public MultiTexRectangle( Canvas3D canvas3D ) {
vertexArray[0] = new Point3f(.6f, .4f, 0);
normalArray[0] = new Vector3f(0, 0, 1f);
textureArray0[0] = new TexCoord2f(1f, 1f);
vertexArray[1] = new Point3f(0, .4f, 0);
normalArray[1] = new Vector3f(0, 0, 1f);
textureArray0[1] = new TexCoord2f(0f, 1f);
vertexArray[2] = new Point3f(0, 0, 0);
normalArray[2] = new Vector3f(0, 0, 1f);
textureArray0[2] = new TexCoord2f(0f, 0f);
vertexArray[3] = new Point3f(0, 0, 0);
normalArray[3] = new Vector3f(0, 0, 1f);
textureArray0[3] = new TexCoord2f(0f, 0f);
vertexArray[4] = new Point3f(.6f, 0, 0);
normalArray[4] = new Vector3f(0, 0, 1f);
textureArray0[4] = new TexCoord2f(1f, 0f);
vertexArray[5] = new Point3f(.6f, .4f, 0);
normalArray[5] = new Vector3f(0, 0, 1f);
textureArray0[5] = new TexCoord2f(1f, 1f);
vertexArray[6] = new Point3f(0, .4f, 0);
normalArray[6] = new Vector3f(0, 0, -1f);
textureArray1[0] = new TexCoord2f(0f, 1f);
vertexArray[7] = new Point3f(.6f, .4f, 0);
normalArray[7] = new Vector3f(0, 0, -1f);
textureArray1[1] = new TexCoord2f(1f, 1f);
vertexArray[8] = new Point3f(.6f, 0, 0);
normalArray[8] = new Vector3f(0, 0, -1f);
textureArray1[2] = new TexCoord2f(1f, 0f);
vertexArray[9] = new Point3f(.6f, 0, 0);
normalArray[9] = new Vector3f(0, 0, -1f);
textureArray1[3] = new TexCoord2f(1f, 0f);
vertexArray[10] = new Point3f(0, 0, 0);
normalArray[10] = new Vector3f(0, 0, -1f);
textureArray1[4] = new TexCoord2f(0f, 0f);
vertexArray[11] = new Point3f(0, .4f, 0);
normalArray[11] = new Vector3f(0, 0, -1f);
textureArray1[5] = new TexCoord2f(0f, 1f);
URL image0, image1;
try {
image0 = new URL( "
http://www.relativitysimulation.com/Images/Soup-Label.jpg" );
image1 = new URL( "
http://www.relativitysimulation.com/Images/Sky-Ground.jpg" );
}
catch ( IOException e ) {
System.out.println("FAILURE trying to load image files from URLs. Can't apply multi-texture.");
System.out.println( e );
return;
}
TextureLoader texLoader0 = new TextureLoader( image0, canvas3D );
Texture texture0 = texLoader0.getTexture();
TextureAttributes texAttrib0 = new TextureAttributes();
TextureUnitState unitState0 = new TextureUnitState( texture0, texAttrib0, null );
TextureLoader texLoader1 = new TextureLoader( image1, canvas3D );
Texture texture1 = texLoader1.getTexture();
TextureAttributes texAttrib1 = new TextureAttributes();
TextureUnitState unitState1 = new TextureUnitState( texture1, texAttrib1, null );
TextureUnitState[] stateArray = new TextureUnitState[2];
stateArray[0] = unitState0; // First element in TextureUnitState array gets Soup-Label texture
stateArray[1] = unitState1; // Second element in TextureUnitState array gets Sky-Ground texture
texCoordSetMap[0] = 0; // First element in Texture Coord Set gets first Texture Unit State
texCoordSetMap[1] = 1; // Second element in Texture Coord Set gets second Texture Unit State
geometryArray = new TriangleArray( 12, TriangleArray.COORDINATES | TriangleArray.NORMALS
| TriangleArray.TEXTURE_COORDINATE_2, 2, texCoordSetMap );
geometryArray.setCoordinates( 0, vertexArray );
geometryArray.setNormals( 0, normalArray );
geometryArray.setTextureCoordinates( texCoordSetMap[0], 0, textureArray0 ); // Soup-Label goes on rectangle front
geometryArray.setTextureCoordinates( texCoordSetMap[1], 6, textureArray1 ); // Sky-Ground goes on rectangle back
setGeometry( geometryArray );
appearance.setTextureUnitState( stateArray );
setAppearance( appearance );
}
}