
// External imports
import java.awt.*;
import java.awt.event.*;

import java.io.File;
import java.net.MalformedURLException;

import java.net.URL;

import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;

import javax.media.opengl.GLCapabilities;

// Local imports
import org.j3d.aviatrix3d.*;

import org.j3d.aviatrix3d.output.graphics.SimpleAWTSurface;
import org.j3d.aviatrix3d.output.graphics.DebugAWTSurface;
import org.j3d.aviatrix3d.pipeline.graphics.GraphicsCullStage;
import org.j3d.aviatrix3d.pipeline.graphics.DefaultGraphicsPipeline;
import org.j3d.aviatrix3d.pipeline.graphics.GraphicsOutputDevice;
import org.j3d.aviatrix3d.pipeline.graphics.NullCullStage;
import org.j3d.aviatrix3d.pipeline.graphics.SimpleTransparencySortStage;
import org.j3d.aviatrix3d.pipeline.graphics.GraphicsSortStage;
import org.j3d.aviatrix3d.management.SingleThreadRenderManager;
import org.j3d.aviatrix3d.management.SingleDisplayCollection;

/**
 * Example application that demonstrates a multiple level layers within a
 * single viewport. One object is placed in each layer and it
 * should show the two objects with the front layer always rendered in front
 * of the background layer. The front layer is fixed, but the back layer
 * animates in such a way that, if both objects were in the one scene, it
 * would move in front and then behind it.
 *
 * @author Justin Couch
 * @version $Revision: 1.2 $
 */
public class BitmapLayersDemo extends Frame
    implements WindowListener
{
    /** bitwise descriptions for each character of the alphabet */
    private byte CHAR_RASTERS[][] =
    {
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36 },
        { 0x00, 0x00, 0x00, 0x66, 0x66, (byte)0xff, 0x66, 0x66, (byte)0xff, 0x66, 0x66, 0x00, 0x00 },
        { 0x00, 0x00, 0x18, 0x7e, (byte)0xff, 0x1b, 0x1f, 0x7e, (byte)0xf8, (byte)0xd8, (byte)0xff, 0x7e, 0x18 },
        { 0x00, 0x00, 0x0e, 0x1b, (byte)0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, (byte)0xdb, (byte)0xd8, 0x70 },
        { 0x00, 0x00, 0x7f, (byte)0xc6, (byte)0xcf, (byte)0xd8, 0x70, 0x70, (byte)0xd8, (byte)0xcc, (byte)0xcc, 0x6c, 0x38 },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e },
        { 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c },
        { 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30 },
        { 0x00, 0x00, 0x00, 0x00, (byte)0x99, 0x5a, 0x3c, (byte)0xff, 0x3c, 0x5a, (byte)0x99, 0x00, 0x00 },
        { 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, (byte)0xff, (byte)0xff, 0x18, 0x18, 0x18, 0x00, 0x00 },
        { 0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xff, (byte)0xff, 0x00, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03 },
        { 0x00, 0x00, 0x3c, 0x66, (byte)0xc3, (byte)0xe3, (byte)0xf3, (byte)0xdb, (byte)0xcf, (byte)0xc7, (byte)0xc3, 0x66, 0x3c },
        { 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18 },
        { 0x00, 0x00, (byte)0xff, (byte)0xc0, (byte)0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, (byte)0xe7, 0x7e },
        { 0x00, 0x00, 0x7e, (byte)0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, (byte)0xe7, 0x7e },
        { 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, (byte)0xff, (byte)0xcc, 0x6c, 0x3c, 0x1c, 0x0c },
        { 0x00, 0x00, 0x7e, (byte)0xe7, 0x03, 0x03, 0x07, (byte)0xfe, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xff },
        { 0x00, 0x00, 0x7e, (byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xc7, (byte)0xfe, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xe7, 0x7e },
        { 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, (byte)0xff },
        { 0x00, 0x00, 0x7e, (byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xe7, 0x7e, (byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xe7, 0x7e },
        { 0x00, 0x00, 0x7e, (byte)0xe7, 0x03, 0x03, 0x03, 0x7f, (byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xe7, 0x7e },
        { 0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, (byte)0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06 },
        { 0x00, 0x00, 0x00, 0x00, (byte)0xff, (byte)0xff, 0x00, (byte)0xff, (byte)0xff, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60 },
        { 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, (byte)0xc3, (byte)0xc3, 0x7e },
        { 0x00, 0x00, 0x3f, 0x60, (byte)0xcf, (byte)0xdb, (byte)0xd3, (byte)0xdd, (byte)0xc3, 0x7e, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xff, (byte)0xc3, (byte)0xc3, (byte)0xc3, 0x66, 0x3c, 0x18 },
        { 0x00, 0x00, (byte)0xfe, (byte)0xc7, (byte)0xc3, (byte)0xc3, (byte)0xc7, (byte)0xfe, (byte)0xc7, (byte)0xc3, (byte)0xc3, (byte)0xc7, (byte)0xfe },
        { 0x00, 0x00, 0x7e, (byte)0xe7, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xe7, 0x7e },
        { 0x00, 0x00, (byte)0xfc, (byte)0xce, (byte)0xc7, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc7, (byte)0xce, (byte)0xfc },
        { 0x00, 0x00, (byte)0xff, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xfc, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xff },
        { 0x00, 0x00, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xfc, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xff },
        { 0x00, 0x00, 0x7e, (byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xcf, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xe7, 0x7e }, { 0x00, 0x00, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xff, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3 },
        { 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e },
        { 0x00, 0x00, 0x7c, (byte)0xee, (byte)0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 },
        { 0x00, 0x00, (byte)0xc3, (byte)0xc6, (byte)0xcc, (byte)0xd8, (byte)0xf0, (byte)0xe0, (byte)0xf0, (byte)0xd8, (byte)0xcc, (byte)0xc6, (byte)0xc3 },
        { 0x00, 0x00, (byte)0xff, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0, (byte)0xc0 },
        { 0x00, 0x00, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xdb,(byte)0xff,(byte)0xff,(byte)0xe7, (byte)0xc3 },
        { 0x00, 0x00, (byte)0xc7, (byte)0xc7, (byte)0xcf, (byte)0xcf, (byte)0xdf, (byte)0xdb, (byte)0xfb, (byte)0xf3, (byte)0xf3, (byte)0xe3, (byte)0xe3 },
        { 0x00, 0x00, 0x7e,(byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3,(byte)0xe7, 0x7e },
        { 0x00, 0x00,(byte)0xc0, (byte)0xc0,(byte)0xc0,(byte)0xc0, (byte)0xc0,(byte)0xfe, (byte)0xc7, (byte)0xc3, (byte)0xc3, (byte)0xc7,(byte)0xfe },
        { 0x00, 0x00, 0x3f, 0x6e, (byte)0xdf, (byte)0xdb, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, 0x66, 0x3c },
        { 0x00, 0x00, (byte)0xc3,(byte)0xc6, (byte)0xcc, (byte)0xd8,(byte)0xf0,(byte)0xfe, (byte)0xc7, (byte)0xc3, (byte)0xc3, (byte)0xc7, (byte)0xfe },
        { 0x00, 0x00, 0x7e,(byte)0xe7, 0x03, 0x03, 0x07, 0x7e,(byte)0xe0,(byte)0xc0,(byte)0xc0,(byte)0xe7, 0x7e },
        { 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, (byte)0xff },
        { 0x00, 0x00, 0x7e,(byte)0xe7, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3 },
        { 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3 },
        { 0x00, 0x00, (byte)0xc3,(byte)0xe7,(byte)0xff,(byte)0xff, (byte)0xdb, (byte)0xdb, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3 },
        { 0x00, 0x00, (byte)0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, (byte)0xc3 },
        { 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, (byte)0xc3 },
        { 0x00, 0x00,(byte)0xff, (byte)0xc0,(byte)0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, (byte)0xff },
        { 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c },
        { 0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60 },
        { 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)0xc3, 0x66, 0x3c, 0x18 },
        {(byte)0xff,(byte)0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70 },
        { 0x00, 0x00, 0x7f, (byte)0xc3, (byte)0xc3, 0x7f, 0x03, (byte)0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00,(byte)0xfe, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xfe, (byte)0xc0, (byte)0xc0, (byte)0xc0,(byte)0xc0,(byte)0xc0 },
        { 0x00, 0x00, 0x7e, (byte)0xc3,(byte)0xc0, (byte)0xc0,(byte)0xc0, (byte)0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x7f, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03 },
        { 0x00, 0x00, 0x7f, (byte)0xc0, (byte)0xc0, (byte)0xfe, (byte)0xc3, (byte)0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30,(byte)0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e },
        { 0x7e, (byte)0xc3, 0x03, 0x03, 0x7f, (byte)0xc3, (byte)0xc3, (byte)0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xfe, (byte)0xc0, (byte)0xc0,(byte)0xc0,(byte)0xc0 },
        { 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00 },
        { 0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00 },
        { 0x00, 0x00,(byte)0xc6,(byte)0xcc,(byte)0xf8,(byte)0xf0,(byte)0xd8,(byte)0xcc,(byte)0xc6,(byte)0xc0, (byte)0xc0,(byte)0xc0, (byte)0xc0 },
        { 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78 },
        { 0x00, 0x00, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xdb, (byte)0xfe, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00,(byte)0xc6, (byte)0xc6,(byte)0xc6,(byte)0xc6,(byte)0xc6, (byte)0xc6,(byte)0xfc, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x7c,(byte)0xc6,(byte)0xc6,(byte)0xc6, (byte)0xc6,(byte)0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00 },
        { (byte)0xc0,(byte)0xc0,(byte)0xc0,(byte)0xfe, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xfe, 0x00, 0x00, 0x00, 0x00 },
        { 0x03, 0x03, 0x03, 0x7f, (byte)0xc3, (byte)0xc3, (byte)0xc3, (byte)0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00,(byte)0xc0, (byte)0xc0, (byte)0xc0,(byte)0xc0,(byte)0xc0, (byte)0xe0,(byte)0xfe, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00,(byte)0xfe, 0x03, 0x03, 0x7e,(byte)0xc0,(byte)0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30,(byte)0xfc, 0x30, 0x30, 0x30, 0x00 },
        { 0x00, 0x00, 0x7e, (byte)0xc6,(byte)0xc6,(byte)0xc6,(byte)0xc6, (byte)0xc6, (byte)0xc6, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, (byte)0xc3, (byte)0xc3, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, (byte)0xc3,(byte)0xe7,(byte)0xff, (byte)0xdb, (byte)0xc3, (byte)0xc3, (byte)0xc3, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, (byte)0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, (byte)0xc3, 0x00, 0x00, 0x00, 0x00 },
        {(byte)0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, (byte)0xc3, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00,(byte)0xff, 0x60, 0x30, 0x18, 0x0c, 0x06,(byte)0xff, 0x00, 0x00, 0x00, 0x00 },
        { 0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, (byte)0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f },
        { 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 },
        { 0x00, 0x00, (byte)0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, (byte)0xf0 },
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, (byte)0x8f, (byte)0xf1, 0x60, 0x00, 0x00, 0x00 }
    };

    private static final float[] RED = {1, 0, 0};
    private static final float[] GREEN = {0, 1, 0};
    private static final float[] BLUE = {0, 0, 1};
    private static final float[] GREY = {0.3f, 0.3f, 0.3f};

    /** Manager for the scene graph handling */
    private SingleThreadRenderManager sceneManager;

    /** Manager for the layers etc */
    private SingleDisplayCollection displayManager;

    /** Our drawing surface */
    private GraphicsOutputDevice surface;

    public BitmapLayersDemo()
    {
        super("2D Bitmaps Aviatrix3D Demo");

        setLayout(new BorderLayout());
        addWindowListener(this);

        setupAviatrix();
        setupSceneGraph();

        setSize(800, 800);
        setLocation(40, 40);

        // Need to set visible first before starting the rendering thread due
        // to a bug in JOGL. See JOGL Issue #54 for more information on this.
        // http://jogl.dev.java.net
        setVisible(true);
    }

    /**
     * Setup the avaiatrix pipeline here
     */
    private void setupAviatrix()
    {
        // Assemble a simple single-threaded pipeline.
        GLCapabilities caps = new GLCapabilities();
        caps.setDoubleBuffered(true);
        caps.setHardwareAccelerated(true);

        GraphicsCullStage culler = new NullCullStage();
        culler.setOffscreenCheckEnabled(false);

        GraphicsSortStage sorter = new SimpleTransparencySortStage();
        surface = new DebugAWTSurface(caps);
        surface.setColorClearNeeded(false);  // we're using a background
        DefaultGraphicsPipeline pipeline = new DefaultGraphicsPipeline();

        pipeline.setCuller(culler);
        pipeline.setSorter(sorter);
        pipeline.setGraphicsOutputDevice(surface);

        displayManager = new SingleDisplayCollection();
        displayManager.addPipeline(pipeline);

        // Render manager
        sceneManager = new SingleThreadRenderManager();
        sceneManager.addDisplay(displayManager);
        sceneManager.setMinimumFrameInterval(10);

        // Before putting the pipeline into run mode, put the canvas on
        // screen first.
        Component comp = (Component)surface.getSurfaceObject();
        add(comp, BorderLayout.CENTER);
    }

    /**
     * Setup the basic scene which consists of a quad and a viewpoint
     */
    private void setupSceneGraph()
    {
        // Middle layer. Object in the middle of the screen, no background
        Viewpoint vp = new Viewpoint();

        Vector3f trans = new Vector3f(0, 0, 0.1f);

        Matrix4f mat = new Matrix4f();
        mat.setIdentity();
        mat.setTranslation(trans);

        TransformGroup tx = new TransformGroup();
        tx.addChild(vp);
        tx.setTransform(mat);

        Group scene_root = new Group();
        scene_root.addChild(tx);

        BitmapRaster bitmap = new BitmapRaster(8, 13);
        bitmap.setBits(CHAR_RASTERS[4]);

        Pixmap pixmap = new Pixmap();
        pixmap.setRaster(bitmap);

        trans.set(0.2f, 0.5f, 0);
        Matrix4f mat2 = new Matrix4f();
        mat2.setIdentity();
        mat2.setTranslation(trans);

        TransformGroup shape_transform = new TransformGroup();
        shape_transform.addChild(pixmap);
        shape_transform.setTransform(mat2);

        scene_root.addChild(shape_transform);

        SimpleScene scene = new SimpleScene();
        scene.setRenderedGeometry(scene_root);
        scene.setActiveView(vp);

        // Then the basic layer and viewport at the top:
        SimpleViewport view = new SimpleViewport();
        view.setDimensions(0, 0, 500, 500);
        view.setScene(scene);

        SimpleLayer layer = new SimpleLayer();
        layer.setViewport(view);

        Layer[] layers = { layer };
        displayManager.setLayers(layers, 1);
    }

    //---------------------------------------------------------------
    // Methods defined by WindowListener
    //---------------------------------------------------------------

    /**
     * Ignored
     */
    public void windowActivated(WindowEvent evt)
    {
    }

    /**
     * Ignored
     */
    public void windowClosed(WindowEvent evt)
    {
    }

    /**
     * Exit the application
     *
     * @param evt The event that caused this method to be called.
     */
    public void windowClosing(WindowEvent evt)
    {
        sceneManager.shutdown();
        System.exit(0);
    }

    /**
     * Ignored
     */
    public void windowDeactivated(WindowEvent evt)
    {
    }

    /**
     * Ignored
     */
    public void windowDeiconified(WindowEvent evt)
    {
    }

    /**
     * Ignored
     */
    public void windowIconified(WindowEvent evt)
    {
    }

    /**
     * When the window is opened, start everything up.
     */
    public void windowOpened(WindowEvent evt)
    {
        sceneManager.setEnabled(true);
    }

    //---------------------------------------------------------------
    // Local methods
    //---------------------------------------------------------------

    public static void main(String[] args)
    {
        BitmapLayersDemo demo = new BitmapLayersDemo();
        demo.setVisible(true);
    }
}
