import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;

public class gltest extends JFrame implements GLEventListener {
    public static void main(String[] args) {
         GLCanvas canvas = new GLCanvas();
         canvas.addGLEventListener(new gltest(canvas, Integer.parseInt(args[0])));

    }
	gltest(GLCanvas canvas, int r) {
         rounds = r;
         setTitle("gltest");
         setSize(400, 400);
         setVisible(true);
         setDefaultCloseOperation(3);
         getContentPane().add(canvas, BorderLayout.CENTER);
         canvas.display();
	}
	int rounds = 1000;

    public void init(GLAutoDrawable drawable) {}

    public void display(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();
        GLU glu = new GLU();
		final int detail = 1 << 19;
		float[] sinarr = new float[detail];
		for (int i = 0; i < detail; ++i) sinarr[i] = (float)Math.sin(2.0f * Math.PI * i / detail);
		for (int i = 0; i < rounds; ++i) {
			gl.glLoadIdentity();
			gl.glClearColor(0.4f, 0.6f, 1.0f, 1.0f);
			gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
			glu.gluPerspective(45.0, 1.0, 0.01, 100.0);
			glu.gluLookAt(0.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
			gl.glDisable(GL.GL_CULL_FACE);
			gl.glEnable(GL.GL_DEPTH_TEST);
			gl.glRotatef(i, 0.0f, 1.0f, 0.0f);
			gl.glRotatef(3.0f * i, 1.0f, 0.0f, 0.0f);
			gl.glBegin(GL.GL_TRIANGLE_STRIP);
			for (int t = 0; t <= detail; ++t) {
				float w = 2.0f + sinarr[(3 * t + detail / 4) % detail];
				float x = w * sinarr[(2 * t + detail / 4) % detail];
				float y = w * sinarr[2 * t % detail];
				float z = sinarr[3 * t % detail];
				gl.glColor3f(1.0f, (float)t / detail, 0.0f);
				gl.glVertex3f(x - .3f * y, y - .3f * z, z - .3f * x);
				gl.glVertex3f(x + .3f * z, y + .3f * x, z + .3f * y);
			}
			gl.glEnd();
			drawable.swapBuffers();
		}
        dispose();
    }

    // Tätä kutsutaan kun komponentin kokoa muutetaan. Ei tarvetta tässä.
    public void reshape(
            GLAutoDrawable drawable,
            int x,
            int y,
            int width,
            int height
            ) {}

    // Kun värisyvyys muuttuu, kutsutaan tätä. Ei tarvetta tässä.
    public void displayChanged(
            GLAutoDrawable drawable,
            boolean modeChanged,
            boolean deviceChanged
            ) {}
}
