aboutsummaryrefslogtreecommitdiffstats
path: root/demos/RonsDemos/glutplane.java
diff options
context:
space:
mode:
Diffstat (limited to 'demos/RonsDemos/glutplane.java')
-rw-r--r--demos/RonsDemos/glutplane.java334
1 files changed, 334 insertions, 0 deletions
diff --git a/demos/RonsDemos/glutplane.java b/demos/RonsDemos/glutplane.java
new file mode 100644
index 0000000..c1e0e52
--- /dev/null
+++ b/demos/RonsDemos/glutplane.java
@@ -0,0 +1,334 @@
+/**
+ * @(#) glutplane.java
+ * @(#) author: Mark J. Kilgard (converted to Java by Ron Cemer)
+ */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+import java.applet.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.lang.*;
+import java.util.*;
+import java.io.*;
+import java.util.*;
+import gl4java.GLContext;
+import gl4java.awt.GLAnimCanvas;
+import gl4java.applet.SimpleGLAnimApplet1;
+
+public class glutplane extends SimpleGLAnimApplet1
+{
+ /* Initialize the applet */
+
+
+ public void init()
+ {
+ super.init();
+ Dimension d = getSize();
+ canvas = new glutplaneCanvas(d.width, d.height);
+ add("Center", canvas);
+ }
+
+
+ private class planeobj
+ {
+ float speed = 0.0f; /* zero speed means not flying */
+ float red = 0.0f, green = 0.0f, blue = 0.0f;
+ float theta = 0.0f;
+ float x = 0.0f, y = 0.0f, z = 0.0f, angle = 0.0f;
+
+ public void setColor(float r, float g, float b)
+ {
+ red = r;
+ green = g;
+ blue = b;
+ }
+ };
+
+
+ /* Local GLAnimCanvas extension class */
+
+
+ private class glutplaneCanvas extends GLAnimCanvas
+ implements MouseListener, ActionListener
+ {
+ private final double M_PI = 3.14159265;
+ private final double M_PI_2 = 1.57079632;
+ private final int MAX_PLANES = 15;
+ private final String ADD_PLANE = "Add plane";
+ private final String REMOVE_PLANE = "Remove plane";
+ private final String SUSPEND_RESUME = "Suspend/resume animation";
+
+ private planeobj planes[] = null;
+ private Random random = null;
+ private PopupMenu menu = null;
+ private boolean menu_showing = false;
+ private boolean save_suspended = false;
+
+ public glutplaneCanvas(int w, int h)
+ {
+ super(w, h);
+ GLContext.gljNativeDebug = false;
+ GLContext.gljClassDebug = false;
+ setAnimateFps(30.0);
+ }
+
+ public void preInit()
+ {
+ doubleBuffer = true;
+ stereoView = false;
+ }
+
+ public void init()
+ {
+ System.out.println("init(): " + this);
+ reshape(getSize().width, getSize().height);
+
+ gl.glClearDepth(1.0f);
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 20.0f);
+ gl.glMatrixMode(GL_MODELVIEW);
+ /* add three initial random planes */
+ planes = new planeobj[MAX_PLANES];
+ for (int i = 0; i < MAX_PLANES; i++)
+ planes[i] = new planeobj();
+ random = new Random(System.currentTimeMillis());
+ add_plane();
+ add_plane();
+ add_plane();
+
+ glj.gljCheckGL();
+
+ menu = new PopupMenu("Options");
+ menu.add(ADD_PLANE);
+ menu.add(REMOVE_PLANE);
+ menu.add(SUSPEND_RESUME);
+ menu.addActionListener(this);
+ add(menu);
+
+ addMouseListener(this);
+ }
+
+ public void doCleanup()
+ {
+ System.out.println("destroy(): " + this);
+ removeMouseListener(this);
+ menu.removeActionListener(this);
+ }
+
+ public void reshape(int width, int height)
+ {
+ gl.glViewport(0,0,width,height);
+ }
+
+ public void display()
+ {
+ if (glj.gljMakeCurrent() == false) return;
+
+ tick();
+
+ float red, green, blue;
+
+ gl.glClear(GL_DEPTH_BUFFER_BIT);
+ /* paint black to blue smooth shaded polygon for background */
+ gl.glDisable(GL_DEPTH_TEST);
+ gl.glShadeModel(GL_SMOOTH);
+ gl.glBegin(GL_POLYGON);
+ gl.glColor3f(0.0f, 0.0f, 0.0f);
+ gl.glVertex3f(-20f, 20f, -19f);
+ gl.glVertex3f(20f, 20f, -19f);
+ gl.glColor3f(0.0f, 0.0f, 1.0f);
+ gl.glVertex3f(20f, -20f, -19f);
+ gl.glVertex3f(-20f, -20f, -19f);
+ gl.glEnd();
+ /* paint planes */
+ gl.glEnable(GL_DEPTH_TEST);
+ gl.glShadeModel(GL_FLAT);
+ for (int i = 0; i < MAX_PLANES; i++)
+ {
+ if (planes[i].speed != 0.0f)
+ {
+ gl.glPushMatrix();
+ gl.glTranslatef(planes[i].x, planes[i].y, planes[i].z);
+ gl.glRotatef(290.0f, 1.0f, 0.0f, 0.0f);
+ gl.glRotatef(planes[i].angle, 0.0f, 0.0f, 1.0f);
+ gl.glScalef(1.0f / 3.0f, 1.0f / 4.0f, 1.0f / 4.0f);
+ gl.glTranslatef(0.0f, -4.0f, -1.5f);
+ gl.glBegin(GL_TRIANGLE_STRIP);
+ /* left wing */
+ gl.glVertex3f(-7.0f, 0.0f, 2.0f);
+ gl.glVertex3f(-1.0f, 0.0f, 3.0f);
+ red = planes[i].red;
+ green = planes[i].green;
+ blue = planes[i].blue;
+ gl.glColor3f(red,green,blue);
+ gl.glVertex3f(-1.0f, 7.0f, 3.0f);
+ /* left side */
+ gl.glColor3f(0.6f * red, 0.6f * green, 0.6f * blue);
+ gl.glVertex3f(0.0f, 0.0f, 0.0f);
+ gl.glVertex3f(0.0f, 8.0f, 0.0f);
+ /* right side */
+ gl.glVertex3f(1.0f, 0.0f, 3.0f);
+ gl.glVertex3f(1.0f, 7.0f, 3.0f);
+ /* final tip of right wing */
+ gl.glColor3f(red, green, blue);
+ gl.glVertex3f(7.0f, 0.0f, 2.0f);
+ gl.glEnd();
+ gl.glPopMatrix();
+ }
+ }
+
+ glj.gljSwap();
+ glj.gljCheckGL();
+ glj.gljFree();
+
+ // if (!isSuspended()) repaint(); // Animate at full speed.
+ }
+
+ // Methods required for the implementation of MouseListener
+ public void mouseEntered(MouseEvent evt)
+ {
+ }
+
+ public void mouseExited(MouseEvent evt)
+ {
+ }
+
+ public void mousePressed(MouseEvent evt)
+ {
+ // If user presses right mouse button within canvas area,
+ // suspend animation and pop up menu.
+ // If menu was already popped up and user presses either
+ // mouse button within canvas area, resume animation
+ // because the menu will have been removed automatically.
+ if (!menu_showing)
+ {
+ if ((evt.getModifiers() & evt.BUTTON3_MASK) != 0)
+ {
+ menu_showing = true;
+ save_suspended = isSuspended();
+ if (!save_suspended)
+ {
+ setSuspended(true);
+ repaint(100);
+ try
+ {
+ Thread.currentThread().sleep(200);
+ }
+ catch (Exception e)
+ { }
+ }
+ menu.show(this,evt.getX(),evt.getY());
+ }
+ else
+ {
+ // Must be left button.
+ if (isSuspended()) repaint();
+ }
+ }
+ else
+ {
+ menu_showing = false;
+ setSuspended(save_suspended);
+ }
+ }
+
+ public void mouseReleased(MouseEvent evt)
+ {
+ }
+
+ public void mouseClicked(MouseEvent evt)
+ {
+ }
+
+ // Method required for the implementation of ActionListener
+ public void actionPerformed(ActionEvent evt)
+ {
+ String c = evt.getActionCommand();
+ if (c.equals(ADD_PLANE))
+ {
+ add_plane();
+ }
+ else if (c.equals(REMOVE_PLANE))
+ {
+ remove_plane();
+ }
+ else if (c.equals(SUSPEND_RESUME))
+ {
+ if (menu_showing)
+ save_suspended = !save_suspended;
+ else
+ setSuspended(!isSuspended()); // not likely to happen
+ }
+ if (menu_showing)
+ {
+ menu_showing = false;
+ setSuspended(save_suspended);
+ }
+ }
+
+ private void tick_per_plane(int i)
+ {
+ float theta = planes[i].theta += planes[i].speed;
+ planes[i].z = -9.0f + 4.0f * (float)Math.cos(theta);
+ planes[i].x = 4 * (float)Math.sin(2.0f * theta);
+ planes[i].y = (float)Math.sin(theta / 3.4f) * 3.0f;
+ planes[i].angle = (float)
+ (((Math.atan(2.0) + M_PI_2) * Math.sin(theta) - M_PI_2) *
+ 180.0 / M_PI);
+ if (planes[i].speed < 0.0f) planes[i].angle += 180.0f;
+ }
+
+ private void add_plane()
+ {
+ for (int i = 0; i < MAX_PLANES; i++)
+ {
+ if (planes[i].speed == 0.0f)
+ {
+ int c = random.nextInt() & 0x07;
+ while (c == 0) c = random.nextInt() & 0x07;
+ float r = (float)((c >> 2) & 0x01);
+ float g = (float)((c >> 1) & 0x01);
+ float b = (float)(c & 0x01);
+ // Blue fades into the background; lighten it up.
+ if (c == 0x01) r = g = 0.4f;
+ planes[i].setColor(r,g,b);
+ planes[i].speed =
+ ((float)(random.nextInt() % 20)) * 0.001f + 0.02f;
+ if ((random.nextInt() & 0x01) != 0)
+ planes[i].speed *= -1.0f;
+ planes[i].theta =
+ ((float)(random.nextInt() % 257))*0.1111f;
+ tick_per_plane(i);
+ if (isSuspended()) repaint();
+ return;
+ }
+ }
+ }
+
+ private void remove_plane()
+ {
+ for (int i = MAX_PLANES - 1; i >= 0; i--)
+ {
+ if (planes[i].speed != 0.0f)
+ {
+ planes[i].speed = 0.0f;
+ if (isSuspended()) repaint();
+ return;
+ }
+ }
+ }
+
+ private void tick()
+ {
+ for (int i = 0; i < MAX_PLANES; i++)
+ {
+ if (planes[i].speed != 0.0f)
+ tick_per_plane(i);
+ }
+ }
+ }
+}