package visad.test; import java.awt.BorderLayout; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; import javax.media.j3d.Appearance; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.Geometry; import javax.media.j3d.GeometryArray; import javax.media.j3d.Group; import javax.media.j3d.ImageComponent; import javax.media.j3d.ImageComponent2D; import javax.media.j3d.LineAttributes; import javax.media.j3d.PointAttributes; import javax.media.j3d.PolygonAttributes; import javax.media.j3d.QuadArray; import javax.media.j3d.RenderingAttributes; import javax.media.j3d.Shape3D; import javax.media.j3d.Switch; import javax.media.j3d.Texture; import javax.media.j3d.Texture2D; import javax.media.j3d.TextureAttributes; import javax.swing.JFrame; import javax.vecmath.Point3d; import visad.util.Util; import com.sun.j3d.utils.behaviors.vp.OrbitBehavior; import com.sun.j3d.utils.universe.SimpleUniverse; import com.sun.j3d.utils.universe.ViewingPlatform; /** * Creates 2 textures, adds them to a switch, and changes the switch's active * child on a timer. This is a Java3D implementation without any VisAD classes. */ public class J3DTextureTest extends Canvas3D { public static final float BACK2D = -0.01f; private BranchGroup scene; private Switch swit; public J3DTextureTest(int size) throws IOException { super(SimpleUniverse.getPreferredConfiguration()); createSceneGraph(size); SimpleUniverse uverse = new SimpleUniverse(this); ViewingPlatform vp = uverse.getViewingPlatform(); vp.setNominalViewingTransform(); OrbitBehavior orbit = new OrbitBehavior(uverse.getCanvas()); BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 1.0); orbit.setSchedulingBounds(bounds); vp.setViewPlatformBehavior(orbit); uverse.addBranchGraph(scene); Timer timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { int i = 0; public void run() { int idx = i++ % 3; if (idx < 2) { swit.setWhichChild(idx); System.err.println("Switched to child " + idx); } else { swit.setWhichChild(Switch.CHILD_NONE); System.err.println("Switched to NONE"); } } }, 0, 2000); } private void setGeometryCapabilities(GeometryArray array) { array.setCapability(GeometryArray.ALLOW_COLOR_READ); array.setCapability(GeometryArray.ALLOW_COORDINATE_READ); array.setCapability(GeometryArray.ALLOW_COUNT_READ); array.setCapability(GeometryArray.ALLOW_FORMAT_READ); array.setCapability(GeometryArray.ALLOW_NORMAL_READ); array.setCapability(GeometryArray.ALLOW_TEXCOORD_READ); } private Appearance makeAppearance(Geometry geometry) { Appearance appearance = new Appearance(); appearance.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_READ); appearance.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_READ); appearance.setCapability(Appearance.ALLOW_MATERIAL_READ); appearance.setCapability(Appearance.ALLOW_POINT_ATTRIBUTES_READ); appearance.setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_READ); appearance.setCapability(Appearance.ALLOW_RENDERING_ATTRIBUTES_READ); appearance.setCapability(Appearance.ALLOW_TEXGEN_READ); appearance.setCapability(Appearance.ALLOW_TEXTURE_ATTRIBUTES_READ); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); // appearance.setCapability(Appearance.ALLOW_TEXTURE_UNIT_STATE_READ); appearance.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_READ); LineAttributes line = new LineAttributes(); line.setCapability(LineAttributes.ALLOW_ANTIALIASING_READ); line.setCapability(LineAttributes.ALLOW_PATTERN_READ); line.setCapability(LineAttributes.ALLOW_WIDTH_READ); int pattern = LineAttributes.PATTERN_SOLID; line.setLinePattern(pattern); appearance.setLineAttributes(line); PointAttributes point = new PointAttributes(); point.setCapability(PointAttributes.ALLOW_ANTIALIASING_READ); point.setCapability(PointAttributes.ALLOW_SIZE_READ); appearance.setPointAttributes(point); PolygonAttributes polygon = new PolygonAttributes(); polygon.setCapability(PolygonAttributes.ALLOW_CULL_FACE_READ); polygon.setCapability(PolygonAttributes.ALLOW_MODE_READ); polygon.setCapability(PolygonAttributes.ALLOW_NORMAL_FLIP_READ); polygon.setCapability(PolygonAttributes.ALLOW_OFFSET_READ); polygon.setCullFace(PolygonAttributes.CULL_NONE); appearance.setPolygonAttributes(polygon); RenderingAttributes rendering = new RenderingAttributes(); rendering.setCapability(RenderingAttributes.ALLOW_ALPHA_TEST_FUNCTION_READ); rendering.setCapability(RenderingAttributes.ALLOW_ALPHA_TEST_VALUE_READ); rendering.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_READ); rendering.setDepthBufferEnable(true); appearance.setRenderingAttributes(rendering); return appearance; } private void createSceneGraph(int size) throws IOException { scene = new BranchGroup(); scene.setCapability(Group.ALLOW_CHILDREN_WRITE); swit = new Switch(); swit.setCapability(Switch.ALLOW_SWITCH_READ); swit.setCapability(Switch.ALLOW_SWITCH_WRITE); swit.setCapability(BranchGroup.ALLOW_DETACH); swit.setCapability(Group.ALLOW_CHILDREN_READ); swit.setCapability(Group.ALLOW_CHILDREN_WRITE); swit.setCapability(Switch.ALLOW_CHILDREN_WRITE); textureToGroup(swit, makeGeometryArray(), makeImage(255,0,0,255, size, size)); textureToGroup(swit, makeGeometryArray(), makeImage(0,0,255,255, size, size)); scene.addChild(swit); scene.compile(); Util.printSceneGraph(scene); } private GeometryArray makeGeometryArray() { float width = .5f; float height = .5f; float[] grid = new float[]{ -width, -height, 0f, width, -height, 0f, width, height, 0f, -width, height, 0f }; float[] texCoord = new float[] { -width, -height, width, -height, width, height, -width, height }; QuadArray array = new QuadArray(4, GeometryArray.BY_REFERENCE | GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2); setGeometryCapabilities(array); array.setCoordRefFloat(grid); array.setTexCoordRefFloat(0, texCoord); return array; } private BufferedImage makeImage(int r, int b, int g, int a, int width, int height) { System.err.println(String.format("Image color: RGBA(%s,%s,%s,%s)", r,g,b,a)); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR); int pxl = 0; pxl = 255 << 24; pxl += r << 16; pxl += g << 8; pxl += b; int[] pxls = new int[image.getWidth()*image.getHeight()]; for (int i=0; i<pxls.length; i++) { pxls[i] = pxl; } image.setRGB(0, 0, image.getWidth(), image.getHeight(), pxls, 0, width); return image; } public void textureToGroup(Group group, GeometryArray geometry, BufferedImage image) { Appearance appearance = makeAppearance(geometry); TextureAttributes texture_attributes = new TextureAttributes(); texture_attributes.setTextureMode(TextureAttributes.REPLACE); texture_attributes.setPerspectiveCorrectionMode(TextureAttributes.NICEST); appearance.setTextureAttributes(texture_attributes); Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, image.getWidth(), image.getHeight()); System.err.println(String.format("Image width:%s height:%s", image.getWidth(), image.getHeight())); System.err.println(String.format("Texture width:%s height:%s", texture.getWidth(), texture.getHeight())); System.err.println(); texture.setCapability(Texture.ALLOW_IMAGE_READ); ImageComponent2D image2d = new ImageComponent2D(ImageComponent.FORMAT_RGBA, image); image2d.setCapability(ImageComponent.ALLOW_IMAGE_READ); texture.setImage(0, image2d); texture.setMinFilter(Texture.BASE_LEVEL_POINT); texture.setMagFilter(Texture.BASE_LEVEL_POINT); texture.setEnable(true); Shape3D shape = new Shape3D(geometry, appearance); shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ); appearance.setTexture(texture); appearance.setCapability(Appearance.ALLOW_TEXTURE_READ); BranchGroup branch = new BranchGroup(); branch.setCapability(BranchGroup.ALLOW_DETACH); branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ); branch.addChild(shape); if (group.numChildren() > 0) { group.insertChild(branch, 0); } else { group.addChild(branch); } } public static void main(String[] args) throws IOException { int size = 0; try { size = Integer.parseInt(args[0]); } catch (Exception e) { System.err.println("You must provide an image size"); System.exit(1); } JFrame frame = new JFrame("Texture Test Canvas"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); J3DTextureTest canvas = new J3DTextureTest(size); Util.printJ3DProperties(canvas); frame.add(canvas); frame.setSize(800, 600); frame.setVisible(true); } }