package it.classx.util.java3d; import java.awt.Frame; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.image.BufferedImage; import javax.media.j3d.Canvas3D; import javax.media.j3d.GraphicsConfigTemplate3D; import javax.media.j3d.ImageComponent2D; import javax.media.j3d.Raster; import javax.vecmath.Point3f; import sun.misc.Perf; import sun.misc.PerformanceLogger; import com.sun.j3d.utils.universe.SimpleUniverse; /** * PictureGrabber is designed to be used as an offscreen canvas which can take a * picture of a model with an alpha masked background. This is done by reading * the canvas into a raster with a depth componant, and then checking which * pixels were written too and which were not. * */ public class PictureGrabberCanvas3D extends Canvas3D { private int width; private int height; private ImageComponent2D offscreenBuffer; private BufferedImage pic; // construct the grabber public PictureGrabberCanvas3D(GraphicsConfiguration config, int width, int height) { super(config, true); this.width = width; this.height = height; this.getScreen3D().setPhysicalScreenWidth(0.0254 / 90.0 * width); this.getScreen3D().setPhysicalScreenHeight(0.0254 / 90.0 * height); this.getScreen3D().setSize(width, height); // create the offscreen buffer pic = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); offscreenBuffer = new ImageComponent2D(ImageComponent2D.FORMAT_RGB, pic, true, false); this.setOffScreenBuffer(offscreenBuffer); offscreenBuffer.setCapability(ImageComponent2D.ALLOW_IMAGE_READ); } private static GraphicsConfiguration getOffscreenGraphicsConfig() { GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); template.setDoubleBuffer(GraphicsConfigTemplate3D.UNNECESSARY); template.setSceneAntialiasing(GraphicsConfigTemplate3D.PREFERRED); GraphicsConfiguration gcfg = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(template); return gcfg; } /** * This will take the picture immediately by forcing a frame draw. This is * only acceptable if the canvas is an offscreen canvas. */ public BufferedImage takePicture() { long f = Perf.getPerf().highResFrequency(); long c = Perf.getPerf().highResCounter(); renderOffScreenBuffer(); waitForOffScreenRendering(); System.out.println((Perf.getPerf().highResCounter()-c)*1000/f); return pic; } }