import java.applet.Applet;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import java.awt.*;
import java.awt.image.*;

public class RenderOnce2 extends Applet {
    int w = 1024, h = 1024;
    long minFrameSpeed = 1000;
    Texture2D tex1, tex2;
    boolean big = false;
    View view;
    boolean manualRender = true;
    Appearance appearance = new Appearance();{
        appearance.setCapability( Appearance.ALLOW_TEXTURE_WRITE );
    }
    TransformGroup TG = new TransformGroup();{
        TG.setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE );
    }
    public Texture2D createTexture( Color c ){
        BufferedImage bi = new BufferedImage( w, h, BufferedImage.TYPE_3BYTE_BGR );
        Graphics g = bi.getGraphics();
        g.setColor( c );
        g.fillRect( 0, 0, w, h );
        ImageComponent2D ic = new ImageComponent2D( ImageComponent.FORMAT_RGB8, bi );
        Texture2D tex = new Texture2D( Texture.BASE_LEVEL, Texture.RGB, w, h );
        tex.setImage( 0, ic );
        return tex;
    }
    public BranchGroup createSceneGraph() {
        tex1 = createTexture( Color.blue );
        tex2 = createTexture( Color.yellow );
        BranchGroup objRoot = new BranchGroup();
        Box b = new Box( 0.3f, 0.3f, 0.3f, Primitive.GENERATE_TEXTURE_COORDS, appearance );
        objRoot.addChild( TG );
        TG.addChild( b );
        Behavior animate = new Behavior(){
            WakeupCondition wakeup = new WakeupOnElapsedFrames( 0 );
            public void initialize(){
                wakeupOn( wakeup );
            }
            public void processStimulus( java.util.Enumeration criteria ){
                change();
                wakeupOn( wakeup );
            }
        };
        animate.setSchedulingBounds( new BoundingSphere() );
        objRoot.addChild( animate );
        objRoot.compile();
        return objRoot;
    }
    public RenderOnce2() {
        setLayout(new BorderLayout());
        Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
        add("Center", c);
        final Button b = new Button( "renderOnce" );
        b.setEnabled( manualRender );
        b.addActionListener( new ActionListener(){
            public void actionPerformed( ActionEvent e ){
                view.renderOnce();
            }
        });
        add( "North", b );
        Button b2 = new Button( "switch mode" );
        b2.addActionListener( new ActionListener(){
            public void actionPerformed( ActionEvent e ){
                manualRender = !manualRender;
                b.setEnabled( manualRender );
                if( manualRender ){
                    view.stopView();
                }else{
                    view.startView();
                }
            }
        });
        add( "South", b2 );

        BranchGroup scene = createSceneGraph();
        SimpleUniverse u = new SimpleUniverse(c);
        u.getViewingPlatform().setNominalViewingTransform();
        u.addBranchGraph(scene);
        view = u.getViewer().getView();
        if( manualRender ){
            view.stopView();
        }
        view.setMinimumFrameCycleTime( minFrameSpeed );
    }
    public void change(){
        Transform3D T = new Transform3D();
        big = !big;
        if( big ){
            T.setScale( 2 );
        }else{
            T.setScale( 1 );
        }
        appearance.setTexture( big ? tex1 : tex2 );
        TG.setTransform( T );
    }
    public static void main(String[] args) {
        new MainFrame(new RenderOnce2(), 256, 256);
    }
}
