diff options
author | Sven Gothel <[email protected]> | 2000-11-18 06:43:49 +0000 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2000-11-18 06:43:49 +0000 |
commit | 880653d31a8f1ff8384fdbc75b84934bceecfdb8 (patch) | |
tree | bdafb71416f176d2a4b73bf716c9dc3f13685a8b /demos/SwingDemos |
Initial revision
Diffstat (limited to 'demos/SwingDemos')
-rw-r--r-- | demos/SwingDemos/CrossColorJPanel.java | 55 | ||||
-rw-r--r-- | demos/SwingDemos/DrawColoredPrimitivesJPanel.java | 79 | ||||
-rwxr-xr-x | demos/SwingDemos/GLSwingDemoApplet.java | 168 | ||||
-rw-r--r-- | demos/SwingDemos/GearsJPanel.java | 382 | ||||
-rw-r--r-- | demos/SwingDemos/InternalGLFrameDemo1.java | 248 | ||||
-rw-r--r-- | demos/SwingDemos/MatrixFuncs.java | 200 | ||||
-rw-r--r-- | demos/SwingDemos/TessJPanel.java | 244 | ||||
-rwxr-xr-x | demos/SwingDemos/gears.java | 370 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLJPanel/GLJPanel.java | 694 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLJPanel/test1.java | 158 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLJPanel/test2.java | 115 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-AWTGraphics/GLPanel.java | 676 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-AWTGraphics/test1.java | 137 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-GLGraphics/GLGraphics.java | 513 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-GLGraphics/GLPanel.java | 692 | ||||
-rw-r--r-- | demos/SwingDemos/test/GLPanel-GLGraphics/test1.java | 129 |
16 files changed, 4860 insertions, 0 deletions
diff --git a/demos/SwingDemos/CrossColorJPanel.java b/demos/SwingDemos/CrossColorJPanel.java new file mode 100644 index 0000000..44a6492 --- /dev/null +++ b/demos/SwingDemos/CrossColorJPanel.java @@ -0,0 +1,55 @@ +import java.awt.*; +import javax.swing.*; +import gl4java.*; +import gl4java.swing.*; + +public class CrossColorJPanel extends GLJPanel +{ + public CrossColorJPanel( ) + { + super(); + } + + + public void init() { + reshape(getSize().width, getSize().height); + } + + public void display() + { + System.out.println("i"); + int i; + + gl.glPushMatrix(); + gl.glClear(GL_COLOR_BUFFER_BIT); + + gl.glBegin(GLEnum.GL_LINES); + gl.glColor4f(0f, 0f, 1f, 1f); + gl.glVertex3i( 0, 0, 0); + gl.glVertex3i( 10, 10, 0); + + gl.glColor4f(0f, 1f, 0f, 1f); + gl.glVertex3i( 0, 10, 0); + gl.glVertex3i( 10, 0, 0); + + gl.glColor4f(1f, 0f, 0f, 1f); + gl.glVertex3i( 0, 5, 0); + gl.glVertex3i( 10, 5, 0); + + gl.glColor4f(1f, 1f, 1f, 1f); + gl.glVertex3i( 5, 0, 0); + gl.glVertex3i( 5, 10, 0); + gl.glEnd(); + + gl.glPopMatrix(); + } + + public void reshape( int width, int height ) + { + gl.glViewport(0, 0, width, height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, 10, 0, 10, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } +} diff --git a/demos/SwingDemos/DrawColoredPrimitivesJPanel.java b/demos/SwingDemos/DrawColoredPrimitivesJPanel.java new file mode 100644 index 0000000..66fc849 --- /dev/null +++ b/demos/SwingDemos/DrawColoredPrimitivesJPanel.java @@ -0,0 +1,79 @@ +/**
+ * @(#) DrawColoredPrimitives.java
+ * @(#) author: Joe Zimmerman (converted to Java by Sven Goethel)
+ */
+
+/* This program is free software under the license of LGPL */
+
+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.swing.*;
+
+public class DrawColoredPrimitivesJPanel extends GLAnimJPanel
+{
+ float rotate;
+
+ float LightAmbient[] = { 0.75f, 0.75f, 0.75f, 1.5f};
+ float LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 0.9f};
+ float LightSpecular[] = { 0.8f, 0.8f, 0.8f, 1.0f};
+
+ public DrawColoredPrimitivesJPanel()
+ {
+ super(false);
+ setAnimateFps(30.0);
+ }
+
+ public void preInit()
+ {
+ stereoView = false;
+ }
+
+ public void init()
+ {
+ reshape(getSize().width, getSize().height);
+
+ gl.glEnable(GL_LIGHT0);
+ gl.glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
+ gl.glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
+ gl.glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);
+
+ glj.gljCheckGL();
+ }
+
+ public void reshape(int width, int height)
+ {
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ glu.gluPerspective(45, (float)width/(float)height, 1, 700);
+ gl.glMatrixMode(GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glViewport(0,0,width,height);
+ }
+
+ public void display()
+ {
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ gl.glMatrixMode(GL_MODELVIEW);
+ gl.glLoadIdentity();
+
+ gl.glColor4f(1, 1, 1, 1);
+
+ rotate++;
+
+ gl.glTranslatef(0, 0, -5);
+ gl.glRotatef(rotate, 0, 1, 0);
+ gl.glBegin(GL_POLYGON);
+ gl.glNormal3f( 1, 0, 0);
+ gl.glColor4f(1, 0, 0, 1); gl.glVertex3f( 0, 1, 0);
+ gl.glColor4f(0, 1, 0, 1); gl.glVertex3f(-1, -1, 0);
+ gl.glColor4f(0, 0, 1, 1); gl.glVertex3f( 1, -1, 0);
+ gl.glEnd();
+ }
+}
diff --git a/demos/SwingDemos/GLSwingDemoApplet.java b/demos/SwingDemos/GLSwingDemoApplet.java new file mode 100755 index 0000000..33b0d95 --- /dev/null +++ b/demos/SwingDemos/GLSwingDemoApplet.java @@ -0,0 +1,168 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; +import gl4java.*; +import gl4java.swing.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +public class GLSwingDemoApplet extends SimpleGLJApplet1 + implements GLEnum, GLUEnum, ActionListener, ItemListener +{ + String[] dataSize = {"offscreen-size: component", + "offscreen-size: 10x10", + "offscreen-size: 50x50", + "offscreen-size: 100x100", + "offscreen-size: 500x500", + "offscreen-size: 1000x1000"}; + + Dimension[] dimSize = { null, + new Dimension(10,10), + new Dimension(50,50), + new Dimension(100,100), + new Dimension(500,500), + new Dimension(1000,1000)}; + + + String[] data = {"CrossColorJPanel", + "GearsJPanel", + "DrawColoredPrimitivesJPanel", + "TessJPanel"}; + + JPanel masterPanel = null; + JComboBox glChoice = null; + JComboBox glOffScrnSize = null; + boolean isAnApplet = true; + + public void init() + { + super.init(); + if(isAnApplet==false) + { + GLContext.gljNativeDebug = true; + GLContext.gljClassDebug = true; + } + + masterPanel = new JPanel (new BorderLayout()); + getContentPane().add("Center",masterPanel); + canvas = new CrossColorJPanel(); + masterPanel.add("Center", canvas); + + JPanel np = new JPanel(); + masterPanel.add("North", np); + glChoice = new JComboBox(data); + glChoice.addItemListener(this); + np.add(glChoice); + glOffScrnSize = new JComboBox(dataSize); + glOffScrnSize.addItemListener(this); + np.add(glOffScrnSize); + + JButton b1, b2; + masterPanel.add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + masterPanel.add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + masterPanel.add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + public static void main(java.lang.String[] args) { + try { + boolean withAWT=false; + + if(args.length>0 && args[0].equals("withAWT")) + withAWT=true; + Frame mainFrame = new Frame("test1"); + + GLSwingDemoApplet applet=new GLSwingDemoApplet(); + + applet.isAnApplet=false; + applet.init(); + applet.start(); + + mainFrame.add(applet); + applet.setSize(480, 480); + + if(withAWT) + { + gears applet2 = new gears(); + applet2.setSize(300, 300); + applet2.init(); + applet2.start(); + mainFrame.add(applet2); + applet2.setSize(300, 300); + } + mainFrame.pack(); + mainFrame.setVisible(true); + + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + Object item = e.getItem(); + System.out.println("item changed: "+source); + + if(glChoice!=null && + glChoice.equals(e.getItemSelectable()) && + e.getStateChange()==ItemEvent.SELECTED && + (item instanceof String)==true + ) + { + String clazzName = (String)item; + try { + Object obj = + Class.forName(clazzName).newInstance(); + if(obj instanceof GLJPanel) + { + if(canvas!=null) + { + masterPanel.remove(canvas); + canvas.cvsDispose(); + } + canvas = (GLJPanel)obj; + canvas.setVisible(true); + masterPanel.add("Center", canvas); + masterPanel.invalidate(); + masterPanel.validate(); + masterPanel.repaint(); + glOffScrnSize.setSelectedIndex(0); + } + if(obj instanceof GLAnimJPanel) + { + ((GLAnimJPanel)obj).start(); + } + } catch (Exception ex) { + System.out.println("Exception during loading: "+ + clazzName); + System.out.println(ex); + } + } else + if(glOffScrnSize!=null && canvas!=null && + glOffScrnSize.equals(e.getItemSelectable()) && + e.getStateChange()==ItemEvent.SELECTED && + (item instanceof String)==true + ) + { + int idx = glOffScrnSize.getSelectedIndex(); + canvas.setOffScreenSize(dimSize[idx]); + } + } +} diff --git a/demos/SwingDemos/GearsJPanel.java b/demos/SwingDemos/GearsJPanel.java new file mode 100644 index 0000000..3d03111 --- /dev/null +++ b/demos/SwingDemos/GearsJPanel.java @@ -0,0 +1,382 @@ +/**
+ * @(#) GearsJPanel.java
+ * @(#) author: Brian Paul (converted to Java by Ron Cemer & Sven Goethel)
+ */
+
+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.swing.*;
+
+public class GearsJPanel extends GLAnimJPanel
+ implements MouseListener, MouseMotionListener
+{
+ private static final float M_PI = 3.14159265359f;
+ private int gear1, gear2, gear3;
+ private float angle = 0.0f;
+
+ private MatrixFuncs mtxfuncs = null;
+ private int prevMouseX, prevMouseY;
+ private boolean mouseRButtonDown = false;
+ private float rot_matrix[] =
+ {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ };
+
+ public GearsJPanel()
+ {
+ super();
+ setAnimateFps(30.0);
+
+ mtxfuncs = new MatrixFuncs();
+ }
+
+ public void init()
+ {
+ System.out.println("init(): " + this);
+ reshape(getSize().width, getSize().height);
+
+ setInitialRotation();
+
+ float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f };
+ float red[] = { 0.8f, 0.1f, 0.0f, 1.0f };
+ float green[] = { 0.0f, 0.8f, 0.2f, 1.0f };
+ float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f };
+
+ gl.glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ gl.glEnable(GL_CULL_FACE);
+ gl.glEnable(GL_LIGHTING);
+ gl.glEnable(GL_LIGHT0);
+ gl.glEnable(GL_DEPTH_TEST);
+
+ /* make the gears */
+ gear1 = gl.glGenLists(1);
+ gl.glNewList(gear1, GL_COMPILE);
+ gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
+ gear(1.0f, 4.0f, 1.0f, 20, 0.7f);
+ gl.glEndList();
+
+ gear2 = gl.glGenLists(1);
+ gl.glNewList(gear2, GL_COMPILE);
+ gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
+ gear(0.5f, 2.0f, 2.0f, 10, 0.7f);
+ gl.glEndList();
+
+ gear3 = gl.glGenLists(1);
+ gl.glNewList(gear3, GL_COMPILE);
+ gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
+ gear(1.3f, 2.0f, 0.5f, 10, 0.7f);
+ gl.glEndList();
+
+ gl.glEnable(GL_NORMALIZE);
+
+ glj.gljCheckGL();
+
+ addMouseListener(this);
+ addMouseMotionListener(this);
+ }
+
+ public void doCleanup()
+ {
+ System.out.println("destroy(): " + this);
+ removeMouseListener(this);
+ removeMouseMotionListener(this);
+ }
+
+ public void reshape(int width, int height)
+ {
+ float h = (float)height / (float)width;
+
+ gl.glViewport(0,0,width,height);
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f);
+ gl.glMatrixMode(GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glTranslatef(0.0f, 0.0f, -40.0f);
+ }
+
+ public void display()
+ {
+ angle += 0.5f;
+
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ gl.glPushMatrix();
+ gl.glMultMatrixf(rot_matrix);
+
+ gl.glPushMatrix();
+ gl.glTranslatef(-3.0f, -2.0f, 0.0f);
+ gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear1);
+ gl.glPopMatrix();
+
+ gl.glPushMatrix();
+ gl.glTranslatef(3.1f, -2.0f, 0.0f);
+ gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear2);
+ gl.glPopMatrix();
+
+ gl.glPushMatrix();
+ gl.glTranslatef(-3.1f, 4.2f, 0.0f);
+ gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear3);
+ gl.glPopMatrix();
+
+ gl.glPopMatrix();
+
+ glj.gljCheckGL();
+ }
+
+ private void gear
+ (float inner_radius,
+ float outer_radius,
+ float width,
+ int teeth,
+ float tooth_depth)
+ {
+ int i;
+ float r0, r1, r2;
+ float angle, da;
+ float u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2.0f;
+ r2 = outer_radius + tooth_depth / 2.0f;
+
+ da = 2.0f * M_PI / teeth / 4.0f;
+
+ gl.glShadeModel(GL_FLAT);
+
+ gl.glNormal3f(0.0f, 0.0f, 1.0f);
+
+ /* draw front face */
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f);
+ }
+ gl.glEnd();
+
+ /* draw front sides of teeth */
+ gl.glBegin(GL_QUADS);
+ da = 2.0f * M_PI / teeth / 4.0f;
+ for (i = 0; i < teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f);
+ }
+ gl.glEnd();
+
+ gl.glNormal3f(0.0f, 0.0f, -1.0f);
+
+ /* draw back face */
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f);
+ }
+ gl.glEnd();
+
+ /* draw back sides of teeth */
+ gl.glBegin(GL_QUADS);
+ da = 2.0f * M_PI / teeth / 4.0f;
+ for (i = 0; i < teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f);
+ }
+ gl.glEnd();
+
+ /* draw outward faces of teeth */
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = 0; i < teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f);
+ u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle);
+ v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle);
+ len = (float)Math.sqrt(u * u + v * v);
+ u /= len;
+ v /= len;
+ gl.glNormal3f(v, -u, 0.0f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f);
+ gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f);
+ u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da);
+ v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da);
+ gl.glNormal3f(v, -u, 0.0f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f);
+ gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f);
+ }
+ gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f);
+ gl.glEnd();
+
+ gl.glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f);
+ }
+ gl.glEnd();
+ }
+
+ // Reset the rotation matrix to the default view.
+ private void setInitialRotation()
+ {
+ float mtxbuf[] = new float[16];
+ float mtxbuf2[] = new float[16];
+
+ mtxfuncs.rotateAroundY(30.0f,mtxbuf);
+ mtxfuncs.rotateAroundX(20.0f,mtxbuf2);
+ mtxfuncs.multiplyMatrices(mtxbuf2,mtxbuf,rot_matrix);
+ fixRotationMatrix();
+ }
+
+ private void fixRotationMatrix()
+ {
+ // Fix any problems with the rotation matrix.
+ rot_matrix[3] =
+ rot_matrix[7] =
+ rot_matrix[11] =
+ rot_matrix[12] =
+ rot_matrix[13] =
+ rot_matrix[14] = 0.0f;
+ rot_matrix[15] = 1.0f;
+ float fac;
+ if ((fac = (float)Math.sqrt
+ ((rot_matrix[0]*rot_matrix[0]) +
+ (rot_matrix[4]*rot_matrix[4]) +
+ (rot_matrix[8]*rot_matrix[8]))) != 1.0f)
+ {
+ if (fac != 0.0f)
+ {
+ fac = 1.0f/fac;
+ rot_matrix[0] *= fac;
+ rot_matrix[4] *= fac;
+ rot_matrix[8] *= fac;
+ }
+ }
+ if ((fac = (float)Math.sqrt
+ ((rot_matrix[1]*rot_matrix[1]) +
+ (rot_matrix[5]*rot_matrix[5]) +
+ (rot_matrix[9]*rot_matrix[9]))) != 1.0f)
+ {
+ if (fac != 0.0f)
+ {
+ fac = 1.0f/fac;
+ rot_matrix[1] *= fac;
+ rot_matrix[5] *= fac;
+ rot_matrix[9] *= fac;
+ }
+ }
+ if ((fac = (float)Math.sqrt
+ ((rot_matrix[2]*rot_matrix[2]) +
+ (rot_matrix[6]*rot_matrix[6]) +
+ (rot_matrix[10]*rot_matrix[10]))) != 1.0f)
+ {
+ if (fac != 0.0f)
+ {
+ fac = 1.0f/fac;
+ rot_matrix[2] *= fac;
+ rot_matrix[6] *= fac;
+ rot_matrix[10] *= fac;
+ }
+ }
+ }
+
+ // Methods required for the implementation of MouseListener
+ public void mouseEntered( MouseEvent evt )
+ {
+ }
+
+ public void mouseExited( MouseEvent evt )
+ {
+ }
+
+ public void mousePressed( MouseEvent evt )
+ {
+ prevMouseX = evt.getX();
+ prevMouseY = evt.getY();
+ if ((evt.getModifiers() & evt.BUTTON3_MASK) != 0)
+ {
+ mouseRButtonDown = true;
+ evt.consume();
+ }
+ }
+
+ public void mouseReleased( MouseEvent evt )
+ {
+ if ((evt.getModifiers() & evt.BUTTON3_MASK) != 0)
+ {
+ mouseRButtonDown = false;
+ evt.consume();
+ }
+ }
+
+ public void mouseClicked( MouseEvent evt )
+ {
+ }
+
+ // Methods required for the implementation of MouseMotionListener
+ public void mouseDragged( MouseEvent evt )
+ {
+ int x = evt.getX();
+ int y = evt.getY();
+ float thetaX = (float)(x-prevMouseX)*(360.0f/(float)getSize().width);
+ float thetaY = (float)(prevMouseY-y)*(360.0f/(float)getSize().height);
+ float mtxbuf[] = new float[16];
+ float mtxbuf2[] = new float[16];
+
+ prevMouseX = x;
+ prevMouseY = y;
+ if ( (thetaX != 0.0f) || (thetaY != 0.0f) )
+ {
+ mtxfuncs.rotateAroundY(((float)thetaX),mtxbuf);
+ if (mouseRButtonDown)
+ mtxfuncs.rotateAroundZ(thetaY,mtxbuf2);
+ else
+ mtxfuncs.rotateAroundX(-thetaY,mtxbuf2);
+ mtxfuncs.multiplyMatrices(mtxbuf2,mtxbuf,mtxbuf);
+ mtxfuncs.multiplyMatrices(rot_matrix,mtxbuf,rot_matrix);
+ fixRotationMatrix();
+ }
+ evt.consume();
+ }
+
+ public void mouseMoved( MouseEvent evt )
+ {
+ }
+}
diff --git a/demos/SwingDemos/InternalGLFrameDemo1.java b/demos/SwingDemos/InternalGLFrameDemo1.java new file mode 100644 index 0000000..ea5cada --- /dev/null +++ b/demos/SwingDemos/InternalGLFrameDemo1.java @@ -0,0 +1,248 @@ +import javax.swing.*; +import javax.swing.event.*; + +import java.awt.event.*; +import java.awt.*; + +import gl4java.swing.*; +import gl4java.*; + +public class InternalGLFrameDemo1 extends JFrame { + JDesktopPane desktop = null; + + public InternalGLFrameDemo1() { + super("InternalGLFrameDemo1"); + + //Make the big window be indented 50 pixels from each edge + //of the screen. + int inset = 50; + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + setBounds(inset, inset, + screenSize.width/2 - inset*2, + screenSize.height/2*3-inset*2); + + //Quit this app when the big window closes. + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + //Set up the GUI. + desktop = new JDesktopPane(); //a specialized layered pane + createFrame(); //Create first window + setContentPane(desktop); + setJMenuBar(createMenuBar()); + + //Make dragging faster: + desktop.putClientProperty("JDesktopPane.dragMode", "outline"); + } + + protected JMenuBar createMenuBar() { + JMenuBar menuBar = new JMenuBar(); + + JMenu menu = new JMenu("Document"); + menu.setMnemonic(KeyEvent.VK_D); + JMenuItem menuItem = new JMenuItem("New"); + menuItem.setMnemonic(KeyEvent.VK_N); + menuItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + createFrame(); + } + }); + menu.add(menuItem); + menuBar.add(menu); + + return menuBar; + } + + protected void createFrame() { + InternalGLFrame frame = new InternalGLFrame("CrossColorJPanel"); + frame.setVisible(true); //necessary as of kestrel + desktop.add(frame); + try { + frame.setSelected(true); + } catch (java.beans.PropertyVetoException e) {} + } + + public static void main(String[] args) { + GLContext.gljNativeDebug = true; + GLContext.gljClassDebug = true; + InternalGLFrameDemo1 frame = new InternalGLFrameDemo1(); + frame.setVisible(true); + } + + static int openFrameCount = 0; + static final int xOffset = 30, yOffset = 30; + static InternalGLFrame activeIF = null; + + public class InternalGLFrame extends JInternalFrame + implements ItemListener, InternalFrameListener + { + String[] data = {"CrossColorJPanel", + "GearsJPanel", + "DrawColoredPrimitivesJPanel", + "TessJPanel"}; + String[] dataSize = {"offscreen-size: component", + "offscreen-size: 10x10", + "offscreen-size: 50x50", + "offscreen-size: 100x100", + "offscreen-size: 500x500", + "offscreen-size: 1000x1000"}; + + Dimension[] dimSize = { null, + new Dimension(10,10), + new Dimension(50,50), + new Dimension(100,100), + new Dimension(500,500), + new Dimension(1000,1000)}; + + + GLJPanel canvas = null; + JComboBox glChoice = null; + JComboBox glOffScrnSize = null; + JComponent master = null; + + public InternalGLFrame(String clazzName) + { + super("Document #" + (++openFrameCount), + true, //resizable + true, //closable + true, //maximizable + true);//iconifiable + + //...Create the GUI and put it in the window... + master = (JComponent) getContentPane(); + master.setLayout(new BorderLayout()); + switchGLJPanel(clazzName); + + JPanel np = new JPanel(); + master.add("North", np); + glChoice = new JComboBox(data); + glChoice.addItemListener(this); + np.add(glChoice); + glOffScrnSize = new JComboBox(dataSize); + glOffScrnSize.addItemListener(this); + np.add(glOffScrnSize); + + setJMenuBar(createIFMenuBar()); + + //...Then set the window size or call pack... + setSize(300,300); + + //Set the window's location. + setLocation(xOffset*openFrameCount, yOffset*openFrameCount); + + addInternalFrameListener(this); + } + + public void switchGLJPanel(String clazzName) + { + try { + Object obj = + Class.forName(clazzName).newInstance(); + if(obj instanceof GLJPanel) + { + if(canvas!=null) + { + master.remove(canvas); + canvas.cvsDispose(); + } + canvas = (GLJPanel)obj; + canvas.setVisible(true); + master.add("Center", canvas); + master.invalidate(); + master.validate(); + master.repaint(); + glOffScrnSize.setSelectedIndex(0); + } + if(obj instanceof GLAnimJPanel) + { + ((GLAnimJPanel)obj).start(); + } + } catch (Exception ex) { + System.out.println("Exception during loading: "+ + clazzName); + System.out.println(ex); + } + + } + + protected JMenuBar createIFMenuBar() + { + JMenuBar menuBar = new JMenuBar(); + + JMenu menu = new JMenu("Document"); + menu.setMnemonic(KeyEvent.VK_D); + JMenuItem menuItem = new JMenuItem("New"); + menuItem.setMnemonic(KeyEvent.VK_N); + menuItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + createIFFrame(); + } + }); + menu.add(menuItem); + menuBar.add(menu); + + return menuBar; + } + + protected void createIFFrame() { + if(activeIF==null) + return; + InternalGLFrame frame = new InternalGLFrame("CrossColorJPanel"); + frame.setVisible(true); //necessary as of kestrel + activeIF.canvas.add(frame); + try { + activeIF.setSelected(true); + } catch (java.beans.PropertyVetoException e) {} + } + + public void itemStateChanged(ItemEvent e) + { + Object source = e.getItemSelectable(); + Object item = e.getItem(); + System.out.println("item changed: "+source); + + if(glChoice!=null && + glChoice.equals(e.getItemSelectable()) && + e.getStateChange()==ItemEvent.SELECTED && + (item instanceof String)==true + ) + { + switchGLJPanel((String)item); + } else + if(glOffScrnSize!=null && canvas!=null && + glOffScrnSize.equals(e.getItemSelectable()) && + e.getStateChange()==ItemEvent.SELECTED && + (item instanceof String)==true + ) + { + int idx = glOffScrnSize.getSelectedIndex(); + canvas.setOffScreenSize(dimSize[idx]); + } + } + + public void internalFrameClosing(InternalFrameEvent e) { + } + + public void internalFrameClosed(InternalFrameEvent e) { + } + + public void internalFrameOpened(InternalFrameEvent e) { + } + + public void internalFrameIconified(InternalFrameEvent e) { + } + + public void internalFrameDeiconified(InternalFrameEvent e) { + } + + public void internalFrameActivated(InternalFrameEvent e) { + activeIF = (InternalGLFrame)e.getSource(); + } + + public void internalFrameDeactivated(InternalFrameEvent e) { + } + } +} diff --git a/demos/SwingDemos/MatrixFuncs.java b/demos/SwingDemos/MatrixFuncs.java new file mode 100644 index 0000000..75493a2 --- /dev/null +++ b/demos/SwingDemos/MatrixFuncs.java @@ -0,0 +1,200 @@ +/**
+ * @(#) MatrixFuncs.java
+ * @(#) author: Ronald B. Cemer
+ * @(#) version: 1.0
+ */
+
+import java.io.*;
+
+public class MatrixFuncs
+{
+ public static final float M_PI = 3.14159265359f;
+
+ // Given the angle in degs, create a 4x4 matrix
+ // in mtx which rotates around the X axis.
+ public void rotateAroundX(float degs, float mtx[])
+ {
+ float rads, rsin, rcos;
+
+ rads = degs*(M_PI/180.0f);
+ rsin = (float)Math.sin(rads);
+ rcos = (float)Math.cos(rads);
+ mtx[0] = 1.0f;
+ mtx[1] = 0.0f;
+ mtx[2] = 0.0f;
+ mtx[3] = 0.0f;
+ mtx[4] = 0.0f;
+ mtx[5] = rcos;
+ mtx[6] = rsin;
+ mtx[7] = 0.0f;
+ mtx[8] = 0.0f;
+ mtx[9] = -rsin;
+ mtx[10] = rcos;
+ mtx[11] = 0.0f;
+ mtx[12] = 0.0f;
+ mtx[13] = 0.0f;
+ mtx[14] = 0.0f;
+ mtx[15] = 1.0f;
+ }
+
+ // Given the angle in degs, create a 4x4 matrix
+ // in mtx which rotates around the Y axis.
+ public void rotateAroundY(float degs, float mtx[])
+ {
+ float rads, rsin, rcos;
+
+ rads = degs*(M_PI/180.0f);
+ rsin = (float)Math.sin(rads);
+ rcos = (float)Math.cos(rads);
+ mtx[0] = rcos;
+ mtx[1] = 0.0f;
+ mtx[2] = -rsin;
+ mtx[3] = 0.0f;
+ mtx[4] = 0.0f;
+ mtx[5] = 1.0f;
+ mtx[6] = 0.0f;
+ mtx[7] = 0.0f;
+ mtx[8] = rsin;
+ mtx[9] = 0.0f;
+ mtx[10] = rcos;
+ mtx[11] = 0.0f;
+ mtx[12] = 0.0f;
+ mtx[13] = 0.0f;
+ mtx[14] = 0.0f;
+ mtx[15] = 1.0f;
+ }
+
+ // Given the angle in degs, create a 4x4 matrix
+ // in mtx which rotates around the Z axis.
+ public void rotateAroundZ(float degs, float mtx[])
+ {
+ float rads, rsin, rcos;
+
+ rads = degs*(M_PI/180.0f);
+ rsin = (float)Math.sin(rads);
+ rcos = (float)Math.cos(rads);
+ mtx[0] = rcos;
+ mtx[1] = rsin;
+ mtx[2] = 0.0f;
+ mtx[3] = 0.0f;
+ mtx[4] = -rsin;
+ mtx[5] = rcos;
+ mtx[6] = 0.0f;
+ mtx[7] = 0.0f;
+ mtx[8] = 0.0f;
+ mtx[9] = 0.0f;
+ mtx[10] = 1.0f;
+ mtx[11] = 0.0f;
+ mtx[12] = 0.0f;
+ mtx[13] = 0.0f;
+ mtx[14] = 0.0f;
+ mtx[15] = 1.0f;
+ }
+
+ // Given two 4x4 matrices in mtx1 and mtx2, multiply
+ // them and put the result in dest.
+ // This routine uses a temporary buffer for the result,
+ // so if dest is the same as mtx1 or mtx2, it will still
+ // work properly.
+ public void multiplyMatrices(float mtx1[], float mtx2[], float dest[])
+ {
+ float nmtx[] = new float[16];
+
+ nmtx[0] =
+ (mtx1[0]*mtx2[0]) +
+ (mtx1[1]*mtx2[4]) +
+ (mtx1[2]*mtx2[8]) +
+ (mtx1[3]*mtx2[12]);
+ nmtx[1] =
+ (mtx1[0]*mtx2[1]) +
+ (mtx1[1]*mtx2[5]) +
+ (mtx1[2]*mtx2[9]) +
+ (mtx1[3]*mtx2[13]);
+ nmtx[2] =
+ (mtx1[0]*mtx2[2]) +
+ (mtx1[1]*mtx2[6]) +
+ (mtx1[2]*mtx2[10]) +
+ (mtx1[3]*mtx2[14]);
+ nmtx[3] =
+ (mtx1[0]*mtx2[3]) +
+ (mtx1[1]*mtx2[7]) +
+ (mtx1[2]*mtx2[11]) +
+ (mtx1[3]*mtx2[15]);
+ nmtx[4] =
+ (mtx1[4]*mtx2[0]) +
+ (mtx1[5]*mtx2[4]) +
+ (mtx1[6]*mtx2[8]) +
+ (mtx1[7]*mtx2[12]);
+ nmtx[5] =
+ (mtx1[4]*mtx2[1]) +
+ (mtx1[5]*mtx2[5]) +
+ (mtx1[6]*mtx2[9]) +
+ (mtx1[7]*mtx2[13]);
+ nmtx[6] =
+ (mtx1[4]*mtx2[2]) +
+ (mtx1[5]*mtx2[6]) +
+ (mtx1[6]*mtx2[10]) +
+ (mtx1[7]*mtx2[14]);
+ nmtx[7] =
+ (mtx1[4]*mtx2[3]) +
+ (mtx1[5]*mtx2[7]) +
+ (mtx1[6]*mtx2[11]) +
+ (mtx1[7]*mtx2[15]);
+ nmtx[8] =
+ (mtx1[8]*mtx2[0]) +
+ (mtx1[9]*mtx2[4]) +
+ (mtx1[10]*mtx2[8]) +
+ (mtx1[11]*mtx2[12]);
+ nmtx[9] =
+ (mtx1[8]*mtx2[1]) +
+ (mtx1[9]*mtx2[5]) +
+ (mtx1[10]*mtx2[9]) +
+ (mtx1[11]*mtx2[13]);
+ nmtx[10] =
+ (mtx1[8]*mtx2[2]) +
+ (mtx1[9]*mtx2[6]) +
+ (mtx1[10]*mtx2[10]) +
+ (mtx1[11]*mtx2[14]);
+ nmtx[11] =
+ (mtx1[8]*mtx2[3]) +
+ (mtx1[9]*mtx2[7]) +
+ (mtx1[10]*mtx2[11]) +
+ (mtx1[11]*mtx2[15]);
+ nmtx[12] =
+ (mtx1[12]*mtx2[0]) +
+ (mtx1[13]*mtx2[4]) +
+ (mtx1[14]*mtx2[8]) +
+ (mtx1[15]*mtx2[12]);
+ nmtx[13] =
+ (mtx1[12]*mtx2[1]) +
+ (mtx1[13]*mtx2[5]) +
+ (mtx1[14]*mtx2[9]) +
+ (mtx1[15]*mtx2[13]);
+ nmtx[14] =
+ (mtx1[12]*mtx2[2]) +
+ (mtx1[13]*mtx2[6]) +
+ (mtx1[14]*mtx2[10]) +
+ (mtx1[15]*mtx2[14]);
+ nmtx[15] =
+ (mtx1[12]*mtx2[3]) +
+ (mtx1[13]*mtx2[7]) +
+ (mtx1[14]*mtx2[11]) +
+ (mtx1[15]*mtx2[15]);
+ dest[0] = nmtx[0];
+ dest[1] = nmtx[1];
+ dest[2] = nmtx[2];
+ dest[3] = nmtx[3];
+ dest[4] = nmtx[4];
+ dest[5] = nmtx[5];
+ dest[6] = nmtx[6];
+ dest[7] = nmtx[7];
+ dest[8] = nmtx[8];
+ dest[9] = nmtx[9];
+ dest[10] = nmtx[10];
+ dest[11] = nmtx[11];
+ dest[12] = nmtx[12];
+ dest[13] = nmtx[13];
+ dest[14] = nmtx[14];
+ dest[15] = nmtx[15];
+ }
+}
diff --git a/demos/SwingDemos/TessJPanel.java b/demos/SwingDemos/TessJPanel.java new file mode 100644 index 0000000..f070823 --- /dev/null +++ b/demos/SwingDemos/TessJPanel.java @@ -0,0 +1,244 @@ +/* + * Copyright (c) 1993-1997, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * Permission to use, copy, modify, and distribute this software for + * any purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright notice + * and this permission notice appear in supporting documentation, and that + * the name of Silicon Graphics, Inc. not be used in adverti(float)Math.sing + * or publicity pertaining to distribution of the software without specific, + * written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" + * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY + * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, + * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF + * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN + * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE + * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227f.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227f-7013 and/or in similar or successor + * clauses in the FAR or the DOD or NASA FAR Supplement. + * Unpublished-- rights reserved under the copyright laws of the + * United States. Contractor/manufacturer is Silicon Graphics, + * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * tess.c + * This program demonstrates polygon tessellation. + * Two tesselated objects are drawn. The first is a + * rectangle with a triangular hole. The second is a + * smooth shaded, self-intersecting star. + * + * Note the exterior rectangle is drawn with its vertices + * in counter-clockwise order, but its interior clockwise. + * Note the combineCallback is needed for the self-intersecting + * star. Also note that removing the TessProperty for the + * star will make the interior unshaded (WINDING_ODD). + */ + +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +import gl4java.*; +import gl4java.awt.*; +import gl4java.swing.*; +import java.applet.*; +import java.awt.*; +import java.awt.Dimension; +import java.awt.event.*; +import java.lang.*; +import java.util.*; + +public class TessJPanel extends GLJPanel +{ + public static double rect[/*4*/][/*3*/] = + {{50.0, 50.0, 0.0}, + {200.0, 50.0, 0.0}, + {200.0, 200.0f, 0.0}, + {50.0, 200.0, 0.0}}; + public static double tri[/*3*/][/*3*/] = + {{75.0, 75.0, 0.0}, + {125.0, 175.0, 0.0}, + {175.0, 75.0, 0.0}}; + public static double star[/*5*/][/*6*/] = + {{250.0, 50.0, 0.0, 1.0, 0.0, 1.0}, + {325.0, 200.0, 0.0, 1.0, 1.0, 0.0}, + {400.0, 50.0, 0.0, 0.0, 1.0, 1.0}, + {250.0, 150.0, 0.0, 1.0, 0.0, 0.0}, + {400.0, 150.0, 0.0, 0.0, 1.0, 0.0}}; + + protected GLUTFunc glut = null; + + int startList=-1; + boolean exit = false; + + public TessJPanel() { + super(); + } + + public void init() { + int i; + glut = new GLUTFuncLightImplWithFonts(gl, glu); + + int tobj; + + gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + startList = gl.glGenLists(2); + + tobj = glu.gluNewTess(); + glu.gluTessCallback ( tobj, GLU_TESS_VERTEX, gl, + "glVertex3dv", "([D)V", + 3, 0, 0, 0, 0); + glu.gluTessCallback ( tobj, GLU_TESS_BEGIN, this, + "beginCallback", "(I)V", + 0, 0, 0, 0, 0); + glu.gluTessCallback ( tobj, GLU_TESS_END, this, + "endCallback", "()V", + 0, 0, 0, 0, 0); + glu.gluTessCallback ( tobj, GLU_TESS_ERROR, this, + "errorCallback", "(I)V", + 0, 0, 0, 0, 0); + + /* rectangle with triangular hole inside */ + gl.glNewList(startList, GL_COMPILE); + gl.glShadeModel(GL_FLAT); + glu.gluTessBeginPolygon(tobj, (double[])null); + glu.gluTessBeginContour(tobj); + glu.gluTessVertex(tobj, rect[0], rect[0]); + glu.gluTessVertex(tobj, rect[1], rect[1]); + glu.gluTessVertex(tobj, rect[2], rect[2]); + glu.gluTessVertex(tobj, rect[3], rect[3]); + glu.gluTessEndContour(tobj); + glu.gluTessBeginContour(tobj); + glu.gluTessVertex(tobj, tri[0], tri[0]); + glu.gluTessVertex(tobj, tri[1], tri[1]); + glu.gluTessVertex(tobj, tri[2], tri[2]); + glu.gluTessEndContour(tobj); + glu.gluTessEndPolygon(tobj); + gl.glEndList(); + + glu.gluTessCallback ( tobj, GLU_TESS_VERTEX, this, + "vertexCallback", "([D)V", + 6, 0, 0, 0, 0); + glu.gluTessCallback ( tobj, GLU_TESS_BEGIN, this, + "beginCallback", "(I)V", + 0, 0, 0, 0, 0); + glu.gluTessCallback ( tobj, GLU_TESS_END, this, + "endCallback", "()V", + 0, 0, 0, 0, 0); + glu.gluTessCallback ( tobj, GLU_TESS_ERROR, this, + "errorCallback", "(I)V", + 0, 0, 0, 0, 0); + glu.gluTessCallback ( tobj, GLU_TESS_COMBINE, this, + "combineCallback", "([D[D[F[D)V", + 3, 4*6, 4, 6, 0); + + /* smooth shaded, self-intersecting star */ + gl.glNewList(startList + 1, GL_COMPILE); + gl.glShadeModel(GL_SMOOTH); + glu.gluTessProperty(tobj, GLU_TESS_WINDING_RULE, + GLU_TESS_WINDING_POSITIVE); + glu.gluTessBeginPolygon(tobj, (double[])null); + glu.gluTessBeginContour(tobj); + glu.gluTessVertex(tobj, star[0], star[0]); + glu.gluTessVertex(tobj, star[1], star[1]); + glu.gluTessVertex(tobj, star[2], star[2]); + glu.gluTessVertex(tobj, star[3], star[3]); + glu.gluTessVertex(tobj, star[4], star[4]); + glu.gluTessEndContour(tobj); + glu.gluTessEndPolygon(tobj); + gl.glEndList(); + + glu.gluDeleteTess(tobj); + + reshape(getSize().width, getSize().height); + + glj.gljCheckGL(); + } + + public void display() + { + if(exit) return; + + gl.glClear(GL_COLOR_BUFFER_BIT); + gl.glColor3f(1.0f, 1.0f, 1.0f); + gl.glCallList(startList); + gl.glCallList(startList + 1); + } + + public void beginCallback(int which) + { + gl.glBegin(which); + } + + public void errorCallback(int errorCode) + { + String str; + + gl.glColor3f( 0.9f, 0.9f, 0.9f ); + gl.glRasterPos2i( 5, 5 ); + + str = glu.gluErrorString( errorCode ); + + glut.glutBitmapString(glut.GLUT_BITMAP_9_BY_15, str); + exit = true; + } + + public void endCallback() + { + gl.glEnd(); + } + + public void vertexCallback(double[/*6*/] vertex) + { + double[] col = new double[3]; + System.arraycopy(vertex, 3, col, 0, 3); + + gl.glColor3dv(col); + gl.glVertex3dv(vertex); + } + + /* combineCallback is used to create a new vertex when edges + * intersect. coordinate location is trivial to calculate, + * but weight[4] may be used to average color, normal, or texture + * coordinate data. In this program, color is weighted. + */ + public void combineCallback(double coords[/*3*/], + double vertex_data[/*4x6*/], + float weight[/*4*/], double[/*6*/] dataOut ) + { + int i; + + dataOut[0] = coords[0]; + dataOut[1] = coords[1]; + dataOut[2] = coords[2]; + for (i = 3; i < 6; i++) + dataOut[i] = weight[0] * vertex_data[0*6+i] + + weight[1] * vertex_data[1*6+i] + + weight[2] * vertex_data[2*6+i] + + weight[3] * vertex_data[3*6+i]; + } + + public void reshape(int w, int h) + { + gl.glViewport( 0, 0, w, h ); + + gl.glMatrixMode( GL_PROJECTION ); + gl.glLoadIdentity(); + glu.gluOrtho2D(0.0f, (double) w, 0.0f, (double) h); + } +} diff --git a/demos/SwingDemos/gears.java b/demos/SwingDemos/gears.java new file mode 100755 index 0000000..db7e97a --- /dev/null +++ b/demos/SwingDemos/gears.java @@ -0,0 +1,370 @@ +/**
+ * @(#) gears.java
+ * @(#) author: Brian Paul (converted to Java by Ron Cemer and Sven Goethel)
+ *
+ * This version is equal to Brian Paul's version 1.2 1999/10/21
+ */
+
+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 gears extends SimpleGLAnimApplet1
+{
+
+ /* Initialize the applet */
+
+
+ public void init()
+ {
+ super.init();
+ Dimension d = getSize();
+ canvas = new gearsCanvas(d.width, d.height);
+ add("Center", canvas);
+ }
+
+
+ public static void main( String args[] )
+ {
+ Frame mainFrame = new Frame("gears");
+
+ gears applet = new gears();
+
+ applet.setSize(300, 300);
+ applet.init();
+ applet.start();
+
+ mainFrame.add(applet);
+
+ mainFrame.pack();
+ mainFrame.setVisible(true);
+ }
+
+
+ /* Local GLAnimCanvas extension class */
+
+
+ private class gearsCanvas extends GLAnimCanvas implements MouseListener, MouseMotionListener
+ {
+ private static final float M_PI = 3.14159265f;
+
+ private long T0 = 0;
+ private long Frames = 0;
+
+ private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f;
+ private int gear1, gear2, gear3;
+ private float angle = 0.0f;
+
+ private int prevMouseX, prevMouseY;
+ private boolean mouseRButtonDown = false;
+
+ public gearsCanvas(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);
+
+ float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f };
+ float red[] = { 0.8f, 0.1f, 0.0f, 1.0f };
+ float green[] = { 0.0f, 0.8f, 0.2f, 1.0f };
+ float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f };
+
+ gl.glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ gl.glEnable(GL_CULL_FACE);
+ gl.glEnable(GL_LIGHTING);
+ gl.glEnable(GL_LIGHT0);
+ gl.glEnable(GL_DEPTH_TEST);
+
+ /* make the gears */
+ gear1 = gl.glGenLists(1);
+ gl.glNewList(gear1, GL_COMPILE);
+ gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
+ gear(1.0f, 4.0f, 1.0f, 20, 0.7f);
+ gl.glEndList();
+
+ gear2 = gl.glGenLists(1);
+ gl.glNewList(gear2, GL_COMPILE);
+ gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
+ gear(0.5f, 2.0f, 2.0f, 10, 0.7f);
+ gl.glEndList();
+
+ gear3 = gl.glGenLists(1);
+ gl.glNewList(gear3, GL_COMPILE);
+ gl.glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
+ gear(1.3f, 2.0f, 0.5f, 10, 0.7f);
+ gl.glEndList();
+
+ gl.glEnable(GL_NORMALIZE);
+
+ glj.gljCheckGL();
+
+ addMouseListener(this);
+ addMouseMotionListener(this);
+
+ T0=System.currentTimeMillis();
+ }
+
+ public void doCleanup()
+ {
+ System.out.println("destroy(): " + this);
+ removeMouseListener(this);
+ removeMouseMotionListener(this);
+ }
+
+ public void reshape(int width, int height)
+ {
+ float h = (float)height / (float)width;
+
+ gl.glViewport(0,0,width,height);
+ gl.glMatrixMode(GL_PROJECTION);
+ gl.glLoadIdentity();
+ gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f);
+ gl.glMatrixMode(GL_MODELVIEW);
+ gl.glLoadIdentity();
+ gl.glTranslatef(0.0f, 0.0f, -40.0f);
+ }
+
+ public void display()
+ {
+ if (glj.gljMakeCurrent() == false) return;
+
+ angle += 2.0f;
+
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ gl.glPushMatrix();
+ gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f);
+ gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
+ gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
+
+ gl.glPushMatrix();
+ gl.glTranslatef(-3.0f, -2.0f, 0.0f);
+ gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear1);
+ gl.glPopMatrix();
+
+ gl.glPushMatrix();
+ gl.glTranslatef(3.1f, -2.0f, 0.0f);
+ gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear2);
+ gl.glPopMatrix();
+
+ gl.glPushMatrix();
+ gl.glTranslatef(-3.1f, 4.2f, 0.0f);
+ gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f);
+ gl.glCallList(gear3);
+ gl.glPopMatrix();
+
+ gl.glPopMatrix();
+
+ glj.gljSwap();
+ glj.gljCheckGL();
+ glj.gljFree();
+
+ Frames++;
+
+ long t=System.currentTimeMillis();
+ if(t - T0 >= 5000)
+ {
+ double seconds = (double)(t - T0) / 1000.0;
+ double fps = (double)Frames / seconds;
+ System.out.println(Frames+" frames in "+seconds+" seconds = "+
+ fps+" FPS");
+ T0 = t;
+ Frames = 0;
+ }
+ }
+
+ private void gear
+ (float inner_radius,
+ float outer_radius,
+ float width,
+ int teeth,
+ float tooth_depth)
+ {
+ int i;
+ float r0, r1, r2;
+ float angle, da;
+ float u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2.0f;
+ r2 = outer_radius + tooth_depth / 2.0f;
+
+ da = 2.0f * M_PI / teeth / 4.0f;
+
+ gl.glShadeModel(GL_FLAT);
+
+ gl.glNormal3f(0.0f, 0.0f, 1.0f);
+
+ /* draw front face */
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f);
+ if(i < teeth)
+ {
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f);
+ }
+ }
+ gl.glEnd();
+
+ /* draw front sides of teeth */
+ gl.glBegin(GL_QUADS);
+ for (i = 0; i < teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f);
+ }
+ gl.glEnd();
+
+ /* draw back face */
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f);
+ }
+ gl.glEnd();
+
+ /* draw back sides of teeth */
+ gl.glBegin(GL_QUADS);
+ for (i = 0; i < teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f);
+ }
+ gl.glEnd();
+
+ /* draw outward faces of teeth */
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = 0; i < teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f);
+ u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle);
+ v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle);
+ len = (float)Math.sqrt(u * u + v * v);
+ u /= len;
+ v /= len;
+ gl.glNormal3f(v, -u, 0.0f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f);
+ gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f);
+ gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f);
+ u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da);
+ v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da);
+ gl.glNormal3f(v, -u, 0.0f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f);
+ gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f);
+ }
+ gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f);
+ gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f);
+ gl.glEnd();
+
+ gl.glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++)
+ {
+ angle = i * 2.0f * M_PI / teeth;
+ gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f);
+ gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f);
+ }
+ gl.glEnd();
+ }
+
+ // Methods required for the implementation of MouseListener
+ public void mouseEntered( MouseEvent evt )
+ {
+ }
+
+ public void mouseExited( MouseEvent evt )
+ {
+ }
+
+ public void mousePressed( MouseEvent evt )
+ {
+ prevMouseX = evt.getX();
+ prevMouseY = evt.getY();
+ if ((evt.getModifiers() & evt.BUTTON3_MASK) != 0)
+ {
+ mouseRButtonDown = true;
+ evt.consume();
+ }
+ }
+
+ public void mouseReleased( MouseEvent evt )
+ {
+ if ((evt.getModifiers() & evt.BUTTON3_MASK) != 0)
+ {
+ mouseRButtonDown = false;
+ evt.consume();
+ }
+ }
+
+ public void mouseClicked( MouseEvent evt )
+ {
+ }
+
+ // Methods required for the implementation of MouseMotionListener
+ public void mouseDragged( MouseEvent evt )
+ {
+ int x = evt.getX();
+ int y = evt.getY();
+ Dimension size = getSize();
+
+ float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width);
+ float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height);
+
+ prevMouseX = x;
+ prevMouseY = y;
+
+ view_rotx += thetaX;
+ view_roty += thetaY;
+
+ evt.consume();
+ }
+
+ public void mouseMoved( MouseEvent evt )
+ {
+ }
+ }
+}
diff --git a/demos/SwingDemos/test/GLJPanel/GLJPanel.java b/demos/SwingDemos/test/GLJPanel/GLJPanel.java new file mode 100644 index 0000000..166437b --- /dev/null +++ b/demos/SwingDemos/test/GLJPanel/GLJPanel.java @@ -0,0 +1,694 @@ +//package gl4java.swing; + +import gl4java.*; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class GLJPanel extends JPanel + implements GLEnum, GLUEnum, + ComponentListener, WindowListener, MouseListener +{ + protected GLContext glj = null; + public GLFunc gl = null; + public GLUFunc glu = null; + + protected boolean mustResize = false; + + protected boolean cvsInitialized=false; + + protected boolean needCvsDispose = false; + + /** + * Visual pre-set for doubleBuffer, default: true + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected boolean doubleBuffer = true; + + /** + * Visual pre-set for stencil-bit number, default: 0 + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected int stencilBits = 0; + + /** + * Visual pre-set for stereoView, default: false + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected boolean stereoView = false; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected boolean rgba = true; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected boolean createOwnWindow = false; + + /** + * The context with witch display lists and textures will be shared. + * + * @see GLJPanel#preInit + * @see GLJPanel#paint + */ + protected GLContext sharedGLContext; + + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLJPanel could not load def. native libs."); + } + + /** + * + * Constructor + * + * @param gl_Name The name of the GLFunc implementation + * If gl_Name==null, the default class will be used ! + * + * @param glu_Name The name of the GLUFunc implementation + * If gl_LibName==null, the default class will be used ! + * + * @param layout the layout manager + * @param isDoubleBuffered the flag indicates, + * if double buffer should be used + * + */ + public GLJPanel( String gl_Name, + String glu_Name, + LayoutManager layout, boolean isDoubleBuffered + ) + { + super( layout, isDoubleBuffered ); + + if( (gl=GLContext.createGLFunc(gl_Name)) ==null) + { + System.out.println("GLFunc implementation "+gl_Name+" not created"); + } + if( (glu=GLContext.createGLUFunc(glu_Name)) ==null) + { + System.out.println("GLUFunc implementation "+glu_Name+" not created"); + } + + /* to be able for RESIZE event's */ + addComponentListener(this); + + setOpaque(false); + } + + /** + * + * Constructor + * + * @param layout the layout manager + * @param isDoubleBuffered the flag indicates, + * if double buffer should be used + * + */ + public GLJPanel( LayoutManager layout, boolean isDoubleBuffered ) + { + this(null, null, layout, isDoubleBuffered); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + * @param isDoubleBuffered the flag indicates, + * if double buffer should be used + */ + public GLJPanel( boolean isDoubleBuffered ) + { + this(null, null, new FlowLayout(), isDoubleBuffered); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + * @param layout the layout manager + */ + public GLJPanel(LayoutManager layout) + { + this(null, null, layout, true); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + */ + public GLJPanel( ) + { + this(null, null, new FlowLayout(), true); + } + + /** + * Used to return the created GLContext + */ + public final GLContext getGLContext() { return glj; } + + /** + * Safe the toplevel window + */ + protected Window topLevelWindow = null; + + /** + * + * This function returns the found TopLevelWindow, + * which contains this Canvas .. + * + * @return void + * + * @see GLJPanel#paint + */ + public final Window getTopLevelWindow() + { return topLevelWindow; } + + /** + * this function overrides the Canvas paint method ! + * + * For the first paint, + * the user function preInit is called, a GLContext is created + * and the user function init is called ! + * + * Also, if a GL Context exist, GLJPanel's sDisplay-method will be called + * to do OpenGL-rendering. + * + * The sDisplay method itself calls the display-method ! + * sDisplay is needed to be thread-safe, to manage + * the resize functionality and to safe the time per frame. + * + * To define your rendering, you should overwrite the display-method + * in your derivation. + * + * @see gl4java.GLContext#GLContext + * @see GLJPanel#cvsIsInit + * @see GLJPanel#sDisplay + * @see GLJPanel#display + * @see GLJPanel#preInit + * @see GLJPanel#init + */ + public synchronized final void paintComponent(Graphics g) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::paintComponent()"); + //super.paintComponent(g); + setOpaque(false); + if(glj == null ) + { + preInit(); + glj = new GLContext ( this, gl, glu, + createOwnWindow, + doubleBuffer, stereoView, + rgba, stencilBits, + sharedGLContext ); + + if(glj!=null) + { + createOwnWindow = glj.isOwnWindowCreated(); + doubleBuffer = glj.isDoubleBuffer(); + stencilBits = glj.getStencilBitNumber(); + stereoView = glj.isStereoView(); + rgba = glj.isRGBA(); + } + + init(); + + // fetch the top-level window , + // to add us as the windowListener + // + Container _c = getParent(); + Container c = null; + + while(_c!=null) + { + c = _c; + _c = _c.getParent(); + } + + if(c instanceof Window) { + topLevelWindow = (Window)c; + topLevelWindow.addComponentListener(this); + topLevelWindow.addMouseListener(this); + } else { + topLevelWindow = null; + System.out.println("toplevel is not a Window: "+c); + } + + if(topLevelWindow!=null) + { + topLevelWindow.addWindowListener(this); + } else { + System.out.println("no parent found for "+getName()); + System.out.flush(); + } + if(glj!=null && glj.gljIsInit()) + cvsInitialized=true; + } + /* + if( mustResize ) size = getSize(); + g.setClip(0, 0, size.width, size.height ); + */ + sPaint(g); + } + + /** + * + * This is the thread save rendering-method called by paint. + * The actual thread will be set to highes priority befor calling + * 'display'. After 'display' the priority will be reset ! + * + * 'gljFree' will be NOT called after 'display'. + * + * We tested the above to use multi-threading and + * for the demonstration 'glDemos' it works ;-)) ! + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay -- OR YOU MUST KNOW WHAT YOU ARE DOING THEN ! + * + * @return void + * + * @see GLJPanel#paint + * @see GLJPanel#display + */ + public synchronized final void sPaint( Graphics g ) + { + boolean ok = true; + + long _s = System.currentTimeMillis(); + + if(!cvsIsInit()) + return; + + /* + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLJPanel: problem in use() method"); + return; + } + */ + + if( mustResize ) + { + if( (ok = glj.gljMakeCurrent()) == true ) + { + Dimension size = getSize(); + glj.gljResize( size.width, size.height ) ; + reshape(size.width, size.height); + mustResize = false; + } + } + if(ok) + { + display(); + g.setClip(getBounds()); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_self = System.currentTimeMillis()-_s; + + /* + GLGraphics glg1 = (GLGraphics)glg.create(); + try { + super.paint(glg1); + } finally { + glg1.dispose(); + } + */ + //super.paint(g); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_total = System.currentTimeMillis()-_s; + } + + } + + /** + * + * This is the rendering-method called by sDisplay + * (and sDisplay is called by paint !). + * The derived-class (Your Subclass) will redefine this, to draw it's own... + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay ! + * + * 'sDisplay' manages a semaphore to avoid reentrance of + * the display function !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @return void + * + * @see GLJPanel#sDisplay + * @see GLJPanel#paint + */ + public void display() + { + } + + /** + * + * This is your pre-init method. + * preInit is called just BEFORE the GL-Context is created. + * You should override preInit, to initialize your visual-stuff, + * like the protected vars: doubleBuffer and stereoView + * + * @return void + * + * @see GLJPanel#paint + * @see GLJPanel#doubleBuffer + * @see GLJPanel#stereoView + * @see GLJPanel#rgba + * @see GLJPanel#stencilBits + */ + public void preInit() + { + } + + /** + * + * This is your init method. + * init is called right after the GL-Context is initialized. + * You should override init, to initialize your stuff needed + * by OpenGL an Java ! + * + * @return void + * + * @see GLJPanel#paint + */ + public void init() + { + } + + /** + * This method is used to clean up any OpenGL stuff (delete textures + * or whatever) prior to actually deleting the OpenGL context. + * You should override this with your own version, if you need to do + * any cleanup work at this phase. + * This functions is called within cvsDispose + * + * @return void + * + * @see GLJPanel#cvsDispose + */ + public void doCleanup() + { + } + + /** + * This function returns, if everything is init: the GLContext, + * the and the users init function + * This value is set in the paint method! + * + * @return boolean + * + * @see GLJPanel#paint + * @see GLJPanel#init + */ + public boolean cvsIsInit() + { + return cvsInitialized; + } + + protected long _f_dur_self = 0; + protected long _f_dur_total = 0; + + /** + * + * This is the reshape-method called by paint. + * The derived-class (Your Subclass) will redefine this, + * to manage your individual reshape ... + * + * This �reshape� method will be invoked after the first paint command + * after GLJPanel.componentResize is called AND only if �gljUse� was + * succesfull (so a call of gljUse is redundant). + * �reshape� is not an overloading of java.awt.Component.reshape, + * �reshape� is more like �glut�-reshape. + * + * GLJPanel.reshape allready has a simple default implementation, + * which calls �gljResize� and �glViewport� - so you may be can + * left this one as it is (no need to overload). + * The needed call to �gljResize� is done by hte invoker paint ! + * + * @param width the new width + * @param height the new height + * @return void + * + * @see GLJPanel#paint + * @see GLJPanel#sDisplay + */ + public void reshape( int width, int height ) + { + if(GLContext.gljClassDebug) + System.out.println("GLJPanel::reshape bounds("+getBounds()+")"); + gl.glViewport(0,0, width, height); + } + + /* JAU */ + /* + public final void setBounds(int x, int y, int width, int height) { + reshape(x, y, width, height); + } + public final void setBounds(Rectangle r) { + reshape(r.x, r.y, r.width, r.height); + } + + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + if(glj==null || !glj.gljIsInit() || !glj.gljMakeCurrent()) + { + System.out.println("GLJPanel::setBounds(): problem in use() method"); + return; + } + reshape(width-x, height-y); + glj.gljCheckGL(); + glj.gljFree(); + size = new Dimension(width-x, height-y); + } + */ + + + /** + * + * �componentResized� is the componentListeners event handler. + * + * This method sets the variable �mustResize� to true, + * so the upcoming �paint� method-call will invoke �reshape� ! + * + * This little look-alike complicating thing is done, + * to avoid an Exception by using the glContext from more than + * one concurrent thread�s ! + * + * You cannot override this implementation, it is final + * - override �reshape' instead ! + * + * @param e the element, which is resized + * @return void + * + * @see GLJPanel#paint + * @see GLJPanel#reshape + */ + public void componentResized(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.println("GLJPanel::componentResized("+e.getComponent()+")"); + if(glj!=null && glj.gljIsInit() && e.getComponent()==this ) + { + mustResize = true; + //repaint(); + } + } + + public void componentMoved(ComponentEvent e) + { + /* + if(GLContext.gljClassDebug) + System.out.print("GLJPanel::componentMoved("+e.getComponent()+")"); + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + + public void componentShown(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLJPanel::componentShown("+e.getComponent()+")"); + } + + public void componentHidden(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLJPanel::componentHidden("+e.getComponent()+")"); + } + + public void mouseClicked(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("."); + } + public void mouseEntered(MouseEvent e) + { + /* + if(GLContext.gljClassDebug) + System.out.print("GLJPanel::mouseEntered("+e.getComponent()+")"); + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + public void mouseExited(MouseEvent e) + {} + public void mousePressed(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("<"); + } + public void mouseReleased(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print(">"); + } + + public void windowOpened(WindowEvent e) + { + } + + /** + * + * �windowClosing� is the windowListeners event handler + * for the topLevelWindow of this Canvas ! + * + * This methods free�s AND destroy�s + * the GL Context with �glj.gljDestroy� ! + * + * @return void + * + */ + public void windowClosing(WindowEvent e) + { + if(e.getComponent().equals(topLevelWindow)) + { + cvsDispose(); + } + } + + /** + * + * �windowClosed� is the windowListeners event handler. + * + * @return void + * + */ + public void windowClosed(WindowEvent e) + { + if (needCvsDispose) cvsDispose(); + } + + public void windowIconified(WindowEvent e) + { + } + + public void windowDeiconified(WindowEvent e) + { + } + + public void windowActivated(WindowEvent e) + { + } + + public void windowDeactivated(WindowEvent e) + { + } + + /** + * You should call this before releasing/dispose this Window ! + * Also you can overwrite this class, + * to dispose your own elements, e.g. a Frame etc. - + * but be shure that you call + * cvsDispose implementation call this one ! + * + * This function calls gljDestroy of GLContext ! + * + * @see gl4java.GLContext#gljDestroy + * @see GLJPanel#doCleanup + */ + public void cvsDispose() + { + cvsInitialized = false; + if (glj != null) + { + if (glj.gljIsInit()) + { + /* Sometimes the Microsoft VM calls the + Applet.stop() method but doesn't have + permissions to do J/Direct calls, so + this whole block of code will throw a + security exception. If this happens, + however, windowClosing() will still + call us again later and we will have + another opportunity to shut down the + context, so it all works out fine. */ + try + { + glj.gljFree(); + doCleanup(); + //locks and free's GLContext + glj.setEnabled(false); + glj.gljDestroy(); + needCvsDispose = false; + } + catch (Exception ex) + { + needCvsDispose = true; + } + } + } + + // Setting glj to null will simply cause paint() to re-initialize. + // We don't want that to happen, so we will leave glj non-null. + } + + /** + * get methods + */ + public final int cvsGetWidth() { + return getSize().width; + } + public final int cvsGetHeight() { + return getSize().height; + } +} + diff --git a/demos/SwingDemos/test/GLJPanel/test1.java b/demos/SwingDemos/test/GLJPanel/test1.java new file mode 100644 index 0000000..3dcb96a --- /dev/null +++ b/demos/SwingDemos/test/GLJPanel/test1.java @@ -0,0 +1,158 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; +import gl4java.*; +import gl4java.awt.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +public class test1 extends JApplet + implements GLEnum, GLUEnum, ActionListener, ItemListener +{ + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLCanvas could not load def. native libs."); + } + + protected class test1Panel extends GLJPanel + implements ActionListener, ItemListener + { + public test1Panel( LayoutManager layout, boolean isDoubleBuffered) + { + super(layout, isDoubleBuffered); + GLContext.gljNativeDebug = true; + GLContext.gljClassDebug = true; + doubleBuffer = false; + } + + + public void init() { + System.out.println("<i>"); + //glg = new GLGraphics(gl, glu); + reshape(getSize().width, getSize().height); + } + + public void display() + { + if( glj.gljMakeCurrent() == false ) { + System.out.println("problem in use() method"); + return; + } + + System.out.println("<p>"); + + int i; + + gl.glPushMatrix(); + gl.glClear(GL_COLOR_BUFFER_BIT); + + gl.glColor4f(0f, 0f, 1f, 1f); + + int width=getSize().width; + int height=getSize().height; + + gl.glBegin(GLEnum.GL_LINES); + gl.glVertex3i( 0, 0, 0); + gl.glVertex3i( 10, 10, 0); + gl.glVertex3i( 0, 10, 0); + gl.glVertex3i( 10, 0, 0); + gl.glEnd(); + + gl.glPopMatrix(); + + glj.gljSwap(); + glj.gljCheckGL(); + glj.gljFree(); + } + + public void reshape( int width, int height ) + { + Rectangle bounds = getBounds(); + System.out.println("reshape("+width+", "+height+")"); + System.out.println("reshape bounds("+bounds+")"); + //gl.glViewport(0,0, width, height); + gl.glViewport(bounds.x, bounds.y, + bounds.width, bounds.height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, 10, 0, 10, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + + } + + test1Panel tst1cvs1; + + public void init() + { + JPanel jp1 = new JPanel (new BorderLayout(), false); + setContentPane(jp1); + tst1cvs1 = new test1Panel(new BorderLayout(), false); + jp1.add("Center", tst1cvs1); + + String[] data = {"one", "two", "three", "four"}; + JList dataList = new JList(data); + jp1.add("North", dataList); + + JButton b1, b2; + jp1.add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + jp1.add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + jp1.add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + public static void main(java.lang.String[] args) { + try { + Frame mainFrame = new Frame("test1"); + + test1 applet=new test1(); + + applet.setSize(400, 400); + applet.init(); + applet.start(); + + mainFrame.add(applet); + + mainFrame.pack(); + mainFrame.setVisible(true); + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + +} diff --git a/demos/SwingDemos/test/GLJPanel/test2.java b/demos/SwingDemos/test/GLJPanel/test2.java new file mode 100644 index 0000000..c479133 --- /dev/null +++ b/demos/SwingDemos/test/GLJPanel/test2.java @@ -0,0 +1,115 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; + +public class test2 extends JApplet + implements ActionListener, ItemListener +{ + protected class test2Panel extends JPanel + implements ActionListener, ItemListener + { + public test2Panel( LayoutManager layout, boolean isDoubleBuffered) + { + super(layout, isDoubleBuffered); + } + + + public void paintComponent(Graphics g) + { + System.out.println("<p>"); + + super.paintComponent(g); + + g.setColor(Color.blue); + + int width=getSize().width; + int height=getSize().height; + + g.drawLine ( 0, height/2, width, height/2 ); + g.drawLine ( width/2, 0, width/2, height ); + + g.setColor(Color.yellow); + + g.drawLine ( 0, 0, width, height); + g.drawString("Left-top", 0, 10); + g.drawString("GLGraphics - CENTER", width/2, height/2); + g.drawString("Right - Bottom (nearly)", width*2/3, height*2/3); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + + } + + test2Panel tst1cvs1; + + public void init() + { + JPanel jp1 = new JPanel (new BorderLayout(), false); + setContentPane(jp1); + tst1cvs1 = new test2Panel(new BorderLayout(), false); + jp1.add("Center", tst1cvs1); + + String[] data = {"one", "two", "three", "four"}; + JList dataList = new JList(data); + jp1.add("North", dataList); + + JButton b1, b2; + jp1.add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + jp1.add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + jp1.add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + public static void main(java.lang.String[] args) { + try { + Frame mainFrame = new Frame("test2"); + + test2 applet=new test2(); + + applet.setSize(400, 400); + applet.init(); + applet.start(); + + mainFrame.add(applet); + + mainFrame.pack(); + mainFrame.setVisible(true); + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + +} diff --git a/demos/SwingDemos/test/GLPanel-AWTGraphics/GLPanel.java b/demos/SwingDemos/test/GLPanel-AWTGraphics/GLPanel.java new file mode 100644 index 0000000..4c7989d --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-AWTGraphics/GLPanel.java @@ -0,0 +1,676 @@ +//package gl4java.awt; + +import gl4java.*; + +import java.awt.*; +import java.awt.event.*; + +public class GLPanel extends Panel + implements GLEnum, GLUEnum, + ComponentListener, WindowListener, MouseListener +{ + protected GLContext glj = null; + public GLFunc gl = null; + public GLUFunc glu = null; + + protected boolean mustResize = false; + + protected boolean cvsInitialized=false; + + protected boolean needCvsDispose = false; + + /** + * Visual pre-set for doubleBuffer, default: true + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean doubleBuffer = true; + + /** + * Visual pre-set for stencil-bit number, default: 0 + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected int stencilBits = 0; + + /** + * Visual pre-set for stereoView, default: false + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean stereoView = false; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean rgba = true; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean createOwnWindow = false; + + /** + * The context with witch display lists and textures will be shared. + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected GLContext sharedGLContext; + + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLPanel could not load def. native libs."); + } + + /** + * + * Constructor + * + * @param width the canvas initial-prefered width + * @param height the canvas initial-prefered height + * + * @param gl_Name The name of the GLFunc implementation + * If gl_Name==null, the default class will be used ! + * + * @param glu_Name The name of the GLUFunc implementation + * If gl_LibName==null, the default class will be used ! + * + */ + public GLPanel( String gl_Name, + String glu_Name + ) + { + super( new BorderLayout() ); + + if( (gl=GLContext.createGLFunc(gl_Name)) ==null) + { + System.out.println("GLFunc implementation "+gl_Name+" not created"); + } + if( (glu=GLContext.createGLUFunc(glu_Name)) ==null) + { + System.out.println("GLUFunc implementation "+glu_Name+" not created"); + } + + /* to be able for RESIZE event's */ + addComponentListener(this); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + * @param width the canvas initial-prefered width + * @param height the canvas initial-prefered height + * + */ + public GLPanel( ) + { + this(null, null); + } + + /** + * Used to return the created GLContext + */ + public final GLContext getGLContext() { return glj; } + + /** + * + * Overridden update + * This one only call's the paint method, without clearing + * the background - thats hopefully done by OpenGL ;-) + * + * @param g the Graphics Context + * @return void + * + * @see GLPanel#paint + */ + public void update(Graphics g) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::update(): isShowing()="+isShowing()); + if(isShowing()) + { + /* let's let OpenGL clear the background ... */ + paint(g); + } + } + + + /** + * Safe the toplevel window + */ + protected Window topLevelWindow = null; + + /** + * + * This function returns the found TopLevelWindow, + * which contains this Canvas .. + * + * @return void + * + * @see GLPanel#paint + */ + public final Window getTopLevelWindow() + { return topLevelWindow; } + + /** + * this function overrides the Canvas paint method ! + * + * For the first paint, + * the user function preInit is called, a GLContext is created + * and the user function init is called ! + * + * Also, if a GL Context exist, GLPanel's sDisplay-method will be called + * to do OpenGL-rendering. + * + * The sDisplay method itself calls the display-method ! + * sDisplay is needed to be thread-safe, to manage + * the resize functionality and to safe the time per frame. + * + * To define your rendering, you should overwrite the display-method + * in your derivation. + * + * @see gl4java.GLContext#GLContext + * @see GLPanel#cvsIsInit + * @see GLPanel#sDisplay + * @see GLPanel#display + * @see GLPanel#preInit + * @see GLPanel#init + */ + public synchronized final void paint( Graphics g ) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::paint()"); + if(glj == null ) + { + preInit(); + glj = new GLContext ( this, gl, glu, + createOwnWindow, + doubleBuffer, stereoView, + rgba, stencilBits, + sharedGLContext ); + + if(glj!=null) + { + createOwnWindow = glj.isOwnWindowCreated(); + doubleBuffer = glj.isDoubleBuffer(); + stencilBits = glj.getStencilBitNumber(); + stereoView = glj.isStereoView(); + rgba = glj.isRGBA(); + } + + init(); + + // fetch the top-level window , + // to add us as the windowListener + // + Container _c = getParent(); + Container c = null; + + while(_c!=null) + { + c = _c; + _c = _c.getParent(); + } + + if(c instanceof Window) { + topLevelWindow = (Window)c; + topLevelWindow.addComponentListener(this); + topLevelWindow.addMouseListener(this); + } else { + topLevelWindow = null; + System.out.println("toplevel is not a Window: "+c); + } + + if(topLevelWindow!=null) + { + topLevelWindow.addWindowListener(this); + } else { + System.out.println("no parent found for "+getName()); + System.out.flush(); + } + if(glj!=null && glj.gljIsInit()) + cvsInitialized=true; + } + /* + if( mustResize ) size = getSize(); + g.setClip(0, 0, size.width, size.height ); + */ + sPaint(g); + } + + /** + * + * This is the thread save rendering-method called by paint. + * The actual thread will be set to highes priority befor calling + * 'display'. After 'display' the priority will be reset ! + * + * 'gljFree' will be NOT called after 'display'. + * + * We tested the above to use multi-threading and + * for the demonstration 'glDemos' it works ;-)) ! + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay -- OR YOU MUST KNOW WHAT YOU ARE DOING THEN ! + * + * @return void + * + * @see GLPanel#paint + * @see GLPanel#display + */ + public synchronized final void sPaint( Graphics g ) + { + boolean ok = true; + + long _s = System.currentTimeMillis(); + + if(!cvsIsInit()) + return; + + /* + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLPanel: problem in use() method"); + return; + } + */ + + if( mustResize ) + { + Dimension size = getSize(); + glj.gljResize( size.width, size.height ) ; + reshape(size.width, size.height); + mustResize = false; + } + if(ok) + { + display(); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_self = System.currentTimeMillis()-_s; + + /* + GLGraphics glg1 = (GLGraphics)glg.create(); + try { + super.paint(glg1); + } finally { + glg1.dispose(); + } + */ + super.paint(g); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_total = System.currentTimeMillis()-_s; + + glj.gljSwap(); + glj.gljFree(); + } + + } + + /** + * + * This is the rendering-method called by sDisplay + * (and sDisplay is called by paint !). + * The derived-class (Your Subclass) will redefine this, to draw it's own... + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay ! + * + * 'sDisplay' manages a semaphore to avoid reentrance of + * the display function !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @return void + * + * @see GLPanel#sDisplay + * @see GLPanel#paint + */ + public void display() + { + } + + /** + * + * This is your pre-init method. + * preInit is called just BEFORE the GL-Context is created. + * You should override preInit, to initialize your visual-stuff, + * like the protected vars: doubleBuffer and stereoView + * + * @return void + * + * @see GLPanel#paint + * @see GLPanel#doubleBuffer + * @see GLPanel#stereoView + * @see GLPanel#rgba + * @see GLPanel#stencilBits + */ + public void preInit() + { + } + + /** + * + * This is your init method. + * init is called right after the GL-Context is initialized. + * You should override init, to initialize your stuff needed + * by OpenGL an Java ! + * + * @return void + * + * @see GLPanel#paint + */ + public void init() + { + } + + /** + * This method is used to clean up any OpenGL stuff (delete textures + * or whatever) prior to actually deleting the OpenGL context. + * You should override this with your own version, if you need to do + * any cleanup work at this phase. + * This functions is called within cvsDispose + * + * @return void + * + * @see GLPanel#cvsDispose + */ + public void doCleanup() + { + } + + /** + * This function returns, if everything is init: the GLContext, + * the and the users init function + * This value is set in the paint method! + * + * @return boolean + * + * @see GLPanel#paint + * @see GLPanel#init + */ + public boolean cvsIsInit() + { + return cvsInitialized; + } + + protected long _f_dur_self = 0; + protected long _f_dur_total = 0; + + /** + * + * This is the reshape-method called by paint. + * The derived-class (Your Subclass) will redefine this, + * to manage your individual reshape ... + * + * This �reshape� method will be invoked after the first paint command + * after GLPanel.componentResize is called AND only if �gljUse� was + * succesfull (so a call of gljUse is redundant). + * �reshape� is not an overloading of java.awt.Component.reshape, + * �reshape� is more like �glut�-reshape. + * + * GLPanel.reshape allready has a simple default implementation, + * which calls �gljResize� and �glViewport� - so you may be can + * left this one as it is (no need to overload). + * The needed call to �gljResize� is done by hte invoker paint ! + * + * @param width the new width + * @param height the new height + * @return void + * + * @see GLPanel#paint + * @see GLPanel#sDisplay + */ + public void reshape( int width, int height ) + { + if(GLContext.gljClassDebug) + System.out.println("GLPanel::reshape bounds("+getBounds()+")"); + gl.glViewport(0,0, width, height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, width, height, 0, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } + + /* JAU */ + /* + public final void setBounds(int x, int y, int width, int height) { + reshape(x, y, width, height); + } + public final void setBounds(Rectangle r) { + reshape(r.x, r.y, r.width, r.height); + } + + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + if(glj==null || !glj.gljIsInit() || !glj.gljMakeCurrent()) + { + System.out.println("GLPanel::setBounds(): problem in use() method"); + return; + } + reshape(width-x, height-y); + glj.gljCheckGL(); + glj.gljFree(); + size = new Dimension(width-x, height-y); + } + */ + + + /** + * + * �componentResized� is the componentListeners event handler. + * + * This method sets the variable �mustResize� to true, + * so the upcoming �paint� method-call will invoke �reshape� ! + * + * This little look-alike complicating thing is done, + * to avoid an Exception by using the glContext from more than + * one concurrent thread�s ! + * + * You cannot override this implementation, it is final + * - override �reshape' instead ! + * + * @param e the element, which is resized + * @return void + * + * @see GLPanel#paint + * @see GLPanel#reshape + */ + public void componentResized(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.println("GLPanel::componentResized("+e.getComponent()+")"); + if(glj!=null && glj.gljIsInit() && e.getComponent()==this ) + { + mustResize = true; + //repaint(); + } + } + + public void componentMoved(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentMoved("+e.getComponent()+")"); + /* + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + + public void componentShown(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentShown("+e.getComponent()+")"); + } + + public void componentHidden(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentHidden("+e.getComponent()+")"); + } + + public void mouseClicked(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("."); + } + public void mouseEntered(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::mouseEntered("+e.getComponent()+")"); + /* + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + public void mouseExited(MouseEvent e) + {} + public void mousePressed(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("<"); + } + public void mouseReleased(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print(">"); + } + + public void windowOpened(WindowEvent e) + { + } + + /** + * + * �windowClosing� is the windowListeners event handler + * for the topLevelWindow of this Canvas ! + * + * This methods free�s AND destroy�s + * the GL Context with �glj.gljDestroy� ! + * + * @return void + * + */ + public void windowClosing(WindowEvent e) + { + if(e.getComponent().equals(topLevelWindow)) + { + cvsDispose(); + } + } + + /** + * + * �windowClosed� is the windowListeners event handler. + * + * @return void + * + */ + public void windowClosed(WindowEvent e) + { + if (needCvsDispose) cvsDispose(); + } + + public void windowIconified(WindowEvent e) + { + } + + public void windowDeiconified(WindowEvent e) + { + } + + public void windowActivated(WindowEvent e) + { + } + + public void windowDeactivated(WindowEvent e) + { + } + + /** + * You should call this before releasing/dispose this Window ! + * Also you can overwrite this class, + * to dispose your own elements, e.g. a Frame etc. - + * but be shure that you call + * cvsDispose implementation call this one ! + * + * This function calls gljDestroy of GLContext ! + * + * @see gl4java.GLContext#gljDestroy + * @see GLPanel#doCleanup + */ + public void cvsDispose() + { + cvsInitialized = false; + if (glj != null) + { + if (glj.gljIsInit()) + { + /* Sometimes the Microsoft VM calls the + Applet.stop() method but doesn't have + permissions to do J/Direct calls, so + this whole block of code will throw a + security exception. If this happens, + however, windowClosing() will still + call us again later and we will have + another opportunity to shut down the + context, so it all works out fine. */ + try + { + glj.gljFree(); + doCleanup(); + //locks and free's GLContext + glj.setEnabled(false); + glj.gljDestroy(); + needCvsDispose = false; + } + catch (Exception ex) + { + needCvsDispose = true; + } + } + } + + // Setting glj to null will simply cause paint() to re-initialize. + // We don't want that to happen, so we will leave glj non-null. + } + + /** + * get methods + */ + public final int cvsGetWidth() { + return getSize().width; + } + public final int cvsGetHeight() { + return getSize().height; + } +} + diff --git a/demos/SwingDemos/test/GLPanel-AWTGraphics/test1.java b/demos/SwingDemos/test/GLPanel-AWTGraphics/test1.java new file mode 100644 index 0000000..b9786a0 --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-AWTGraphics/test1.java @@ -0,0 +1,137 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; +import gl4java.*; +import gl4java.awt.*; +import gl4java.swing.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +public class test1 extends JApplet + implements GLEnum, GLUEnum +{ + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLCanvas could not load def. native libs."); + } + + protected class test1Panel extends GLPanel + implements ActionListener, ItemListener + { + public test1Panel() { + super(); + GLContext.gljNativeDebug = true; + GLContext.gljClassDebug = true; + //String[] data = {"one", "two", "three", "four"}; + //JList dataList = new JList(data); + //add("North", dataList); + JButton b1, b2; + add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + + public void init() { + System.out.println("<i>"); + //glg = new GLGraphics(gl, glu); + reshape(getSize().width, getSize().height); + } + + public void display() + { + if( glj.gljMakeCurrent() == false ) { + System.out.println("problem in use() method"); + return; + } + + System.out.println("<p>"); + + int i; + + gl.glPushMatrix(); + gl.glClear(GL_COLOR_BUFFER_BIT); + + gl.glColor4f(0f, 0f, 1f, 1f); + + int width=getSize().width; + int height=getSize().height; + + gl.glBegin(GLEnum.GL_LINES); + gl.glVertex3i( 0, 0, 0); + gl.glVertex3i( 10, 10, 0); + gl.glVertex3i( 0, 10, 0); + gl.glVertex3i( 10, 0, 0); + gl.glEnd(); + + gl.glPopMatrix(); + + glj.gljSwap(); + glj.gljCheckGL(); + glj.gljFree(); + } + + public void reshape( int width, int height ) + { + System.out.println("reshape("+width+", "+height+")"); + System.out.println("reshape bounds("+getBounds()+")"); + gl.glViewport(0,0, width, height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, 10, 0, 10, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + + } + + test1Panel tst1cvs1; + + public void init() + { + tst1cvs1 = new test1Panel(); + tst1cvs1.setSize(400,400); + setContentPane(tst1cvs1); + } + + public static void main(java.lang.String[] args) { + try { + Frame mainFrame = new Frame("test1"); + + test1 applet=new test1(); + + applet.setSize(400, 400); + applet.init(); + applet.start(); + + mainFrame.add(applet); + + mainFrame.pack(); + mainFrame.setVisible(true); + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } +} diff --git a/demos/SwingDemos/test/GLPanel-GLGraphics/GLGraphics.java b/demos/SwingDemos/test/GLPanel-GLGraphics/GLGraphics.java new file mode 100644 index 0000000..835febf --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-GLGraphics/GLGraphics.java @@ -0,0 +1,513 @@ +/** + * @(#) GLGraphics.java + */ + +//package gl4java.awt; + +import gl4java.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +import java.awt.*; +import java.awt.image.*; +import java.awt.event.*; +import java.awt.image.ImageObserver; +import java.text.*; + +public class GLGraphics + extends java.awt.Graphics + implements Cloneable +{ + +protected final boolean debug = false; + +/** + * this is the original Graphics context + */ +protected Graphics g = null; + +protected GLContext glj = null; +protected GLFunc gl = null; +protected GLUFunc glu = null; +protected GLUTFunc glut = null; +protected int currentGlutFont = GLUTEnum.GLUT_BITMAP_TIMES_ROMAN_10; +protected int x_orig = 0; +protected int y_orig = 0; +protected int z_orig = 0; + +//protected Color clr = Color.black; +//protected Shape clip = null; +//protected Font fnt = null; + +public GLGraphics (Graphics g, GLContext glj, GLFunc gl, GLUFunc glu) { + this.g=g; + this.glj=glj; + this.gl=gl; + this.glu=glu; + glut = new GLUTFuncLightImplWithFonts(gl, glu); +} + +public GLGraphics (Graphics g, GLContext glj, GLFunc gl, GLUFunc glu, GLUTFunc glut) { + this.g=g; + this.glj=glj; + this.gl=gl; + this.glu=glu; + this.glut=glut; +} + +protected GLGraphics (GLContext glj, GLFunc gl, GLUFunc glu, GLUTFunc glut) { + this.glj=glj; + this.gl=gl; + this.glu=glu; + this.glut=glut; +} + +protected Object clone() + throws CloneNotSupportedException +{ + GLGraphics glg = new GLGraphics(g, glj, gl, glu, glut); + //glg.g=g.create(); + glg.x_orig=x_orig; + glg.y_orig=y_orig; + glg.z_orig=z_orig; + glg.currentGlutFont=currentGlutFont; + + //glg.clr = clr; + //glg.clip=clip; + //glg.fnt = fnt; + + return glg; +} + +public Graphics create () { + try { + return ((Graphics)clone()); + } + catch (CloneNotSupportedException _) { + return (null); + } +} + +public Graphics create ( int x, int y, int width, int height ) { + if(debug) + System.out.println("Graphics::create("+x+","+y+","+width+","+height+")"); + // slow, generic version + Graphics g = create(); + + // modify cloned state acording to request + g.translate( x, y); + g.clipRect( 0, 0, width, height); // spec says this should be the intersection + + return g; +} + +public void clearRect ( int x, int y, int width, int height ) +{ + if(debug) + System.out.println("Graphics::clearRect("+x+","+y+","+width+","+height+")"); +} + +public void clipRect ( int x, int y, int width, int height ) +{ g.clipRect(x, y, width, height); +} + +public void copyArea ( int x, int y, int width, int height, int dx, int dy ) +{ + if(debug) + System.out.println("Graphics::copyArea("+x+","+y+","+width+","+height+","+dx+","+dy+")"); +} + +public void dispose () +{ + //g.dispose(); +} + +public void drawArc ( int x, int y, int width, int height, + int startAngle, int arcAngle ) +{ + if(debug) + System.out.println("Graphics::drawArc("+x+","+y+","+width+","+height+","+startAngle+","+arcAngle+")"); +} + +public boolean drawImage (Image img, int x, int y, Color bgcolor, + ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage("+x+","+y+","+bgcolor+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + return false; +} + +public boolean drawImage ( Image img, int x, int y, ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage("+x+","+y+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + + glDrawImage(observer, img, x_orig+x, y_orig+y, z_orig); + return false; +} + +public boolean drawImage ( Image img, int x, int y, int width, int height, + Color background, ImageObserver observer ) +{ + if(debug) + System.out.println("Graphics::drawImage("+x+","+y+","+width+","+height+","+background+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + return false; +} + +public boolean drawImage ( Image img, int x, int y, int width, int height, + ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage("+x+","+y+","+width+","+height+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + return false; +} + +public boolean drawImage ( Image img, + int dx0, int dy0, int dx1, int dy1, + int sx0, int sy0, int sx1, int sy1, + Color bgColor, ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage(..)"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return false; + } + return false; +} + +public boolean drawImage ( Image img, + int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + ImageObserver observer) +{ + if(debug) + System.out.println("Graphics::drawImage(..)"); + return false; +} + +public void drawLine ( int x1, int y1, int x2, int y2 ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawLine("+x1+","+y1+","+x2+","+y2+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glBegin(GLEnum.GL_LINES); + gl.glVertex3i( x_orig+x1, y_orig+y1, z_orig); + gl.glVertex3i( x_orig+x2, y_orig+y2, z_orig); + gl.glEnd(); +} + +public void drawOval ( int x, int y, int width, int height ) +{ + if(debug) + System.out.println("Graphics::drawOval("+x+","+y+","+width+","+height+")"); +} + +public void drawPolygon ( int xPoints[], int yPoints[], int nPoints ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawPolygon(...)"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glPolygonMode(GLEnum.GL_FRONT_AND_BACK, GLEnum.GL_LINE); + gl.glBegin(GLEnum.GL_POLYGON); + for(int i=0; i<nPoints; i++) + gl.glVertex3i( x_orig+xPoints[i], y_orig+yPoints[i], z_orig); + gl.glEnd(); +} + +public void drawPolyline ( int xPoints[], int yPoints[], int nPoints ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawPolyline(...)"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glPolygonMode(GLEnum.GL_FRONT_AND_BACK, GLEnum.GL_LINE); + gl.glBegin(GLEnum.GL_POLYGON); + for(int i=0; i<nPoints; i++) + gl.glVertex3i( x_orig+xPoints[i], y_orig+yPoints[i], z_orig); + gl.glEnd(); +} + +public void drawRoundRect ( int x, int y, int width, int height, + int arcWidth, int arcHeight) +{ + if(debug) + System.out.println("Graphics::drawRoundRect("+x+","+y+","+width+","+height+","+arcWidth+","+arcHeight+")"); +} + +public void drawString ( String str, int x, int y ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawString("+x+","+y+","+str+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glRasterPos3d(x_orig+x, y_orig+y, z_orig); + glut.glutBitmapString(currentGlutFont,str); +} + +public void drawString(java.text.AttributedCharacterIterator aci, int x, int y) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::drawStringACI("+x+","+y+")"); + StringBuffer sb = new StringBuffer(); + for(char c = aci.first(); c != CharacterIterator.DONE; c = aci.next()) + sb.append(c); + drawString(sb.toString(), x, y); +} + +public void fillArc ( int x, int y, int width, int height, + int startAngle, int arcAngle ) +{ + if(debug) + System.out.println("Graphics::fillArc("+x+","+y+","+width+","+height+","+startAngle+","+arcAngle+")"); +} + +public void fillOval ( int x, int y, int width, int height ) +{ + if(debug) + System.out.println("Graphics::fillOval("+x+","+y+","+width+","+height+")"); +} + +public void fillPolygon ( int xPoints[], int yPoints[], int nPoints ) +{ + if(debug) + System.out.println("Graphics::fillPolygon(..)"); +} + +public void fillRect ( int x, int y, int width, int height ) +{ + if(debug) + System.out.println("Graphics::fillRect("+x+","+y+","+width+","+height+")"); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glPolygonMode(GLEnum.GL_FRONT_AND_BACK, GLEnum.GL_FILL); + gl.glBegin(GLEnum.GL_POLYGON); + gl.glVertex3i( x_orig+x, y_orig+y, z_orig); + gl.glVertex3i( x_orig+x+width, y_orig+y, z_orig); + gl.glVertex3i( x_orig+x+width, y_orig+y+height, z_orig); + gl.glVertex3i( x_orig+x, y_orig+y+height, z_orig); + gl.glVertex3i( x_orig+x, y_orig+y, z_orig); + gl.glEnd(); +} + +public void fillRoundRect ( int x, int y, int width, int height, + int arcWidth, int arcHeight ) +{ + if(debug) + System.out.println("Graphics::fillRoundRect("+x+","+y+","+width+","+height+","+arcWidth+","+arcHeight+")"); +} + +public Shape getClip () +{ return g.getClip(); } + +public Rectangle getClipBounds() +{ return null; } + +public Color getColor() +{ return g.getColor(); } + +public Font getFont() +{ return g.getFont(); } + +public FontMetrics getFontMetrics ( Font fnt ) +{ return g.getFontMetrics(fnt); } + +public void setClip ( Shape clip ) +{ g.setClip(clip); } + +public void setClip ( int x, int y, int width, int height ) +{ g.setClip(x, y, width, height); } + +public void setColor ( Color clr ) +{ + if(debug) + System.out.println("Graphics("+x_orig+","+y_orig+")::setColor("+clr+")"); + g.setColor(clr); + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLGraphics: problem in use() method"); + return; + } + gl.glColor4d(clr.getRed()/255.0, clr.getGreen()/255.0, + clr.getBlue()/255.0, clr.getAlpha()/255.0); +} + +public void setFont ( Font newFnt ) +{ g.setFont(newFnt); + if(debug) + System.out.println("Graphics("+(x_orig)+","+(y_orig)+")::setFont("+newFnt.getName()+" / "+ newFnt.getFamily()+" / "+ newFnt.getSize()+")"); + switch(newFnt.getSize()) + { + case 8: + currentGlutFont = GLUTEnum.GLUT_BITMAP_8_BY_13; + break; + case 9: + currentGlutFont = GLUTEnum.GLUT_BITMAP_9_BY_15; + break; + case 10: + currentGlutFont = GLUTEnum.GLUT_BITMAP_TIMES_ROMAN_10; + break; + case 24: + currentGlutFont = GLUTEnum.GLUT_BITMAP_TIMES_ROMAN_24; + break; + /* + case 10: + currentGlutFont = GLUTEnum.GLUT_BITMAP_HELVETICA_10; + break; + */ + case 12: + currentGlutFont = GLUTEnum.GLUT_BITMAP_HELVETICA_12; + break; + case 18: + currentGlutFont = GLUTEnum.GLUT_BITMAP_HELVETICA_18; + break; + default: + currentGlutFont = GLUTEnum.GLUT_BITMAP_TIMES_ROMAN_10; + } +} + +public void setPaintMode() +{} + +public void setXORMode ( Color newXorClr ) +{} + +public void translate ( int x, int y ) +{ + x_orig+=x; + y_orig+=y; + if(debug) + System.out.println("Graphics("+(x_orig-x)+","+(y_orig-y)+")::translate("+x+","+y+") -> ("+x_orig+","+y_orig+")"); + g.translate(x, y); +} + +protected void glDrawImage(ImageObserver observer, Image image, + int xpos, int ypos, int zpos) +{ + int imageWidth = image.getWidth(observer); + int imageHeight = image.getHeight(observer); + int glFormat=GLEnum.GL_RGB; //def. RGB type + int comps=3; //def. RGB type + + if(debug) + System.out.println("Graphics("+(x_orig)+","+(y_orig)+")::glDrawImage("+xpos+","+ypos+") ("+imageWidth+","+imageHeight+")"); + + /* This is Java2 only code :-( + BufferedImage image = + new BufferedImage(imageWidth, imageHeight, + BufferedImage.TYPE_INT_RGB); + + Graphics g = image.createGraphics(); + g.drawImage(img,0,0,comp); + + imageWidth = image.getWidth(); + imageHeight = image.getHeight(); + */ + + // Read entire PNG image (doesn't throw exceptions) + int[] iPixels = new int[imageWidth * imageHeight]; + + PixelGrabber pp=new PixelGrabber(image, + 0,0, + imageWidth, imageHeight, + iPixels, + 0, + imageWidth); + try + { + pp.grabPixels(); + } + catch (InterruptedException e) + { + System.err.println("interrupted waiting for pixel!"); + return; + } + if ((pp.getStatus() & ImageObserver.ABORT) != 0) + { + System.err.println("image fetch aborted or errored"); + return; + } + + /* This is Java2 only code :-( + int imagetype = image.getType(); + switch(imagetype) + { + case BufferedImage.TYPE_INT_RGB: + glFormat=GLEnum.GL_RGB; + comps=3; + break; + case BufferedImage.TYPE_INT_ARGB: + case BufferedImage.TYPE_INT_ARGB_PRE: + glFormat=GLEnum.GL_RGBA; + comps=4; + break; + default: + System.err.println("unsupported format: "+imagetype); + return; + }; + */ + + byte[] pixel=new byte[imageWidth * imageHeight * comps]; + + byte alpha=0; + byte red=0; + byte green=0; + byte blue=0; + int offset=0; + int aPixel; + int y_desc, y_asc; + for(y_desc=imageHeight-1, y_asc=0; y_desc>=0; y_desc--, y_asc++) + { + for(int x=0;x<imageWidth;x++) + { + aPixel = iPixels[y_desc*imageWidth + x]; + + if(glFormat==GLEnum.GL_RGBA) + alpha =new Integer( (aPixel >> 24) & 0xff ).byteValue(); + red =new Integer( (aPixel >> 16) & 0xff ).byteValue(); + green =new Integer( (aPixel >> 8) & 0xff ).byteValue(); + blue =new Integer( (aPixel ) & 0xff ).byteValue(); + + pixel[offset++]=red; + pixel[offset++]=green; + pixel[offset++]=blue; + if(glFormat==GLEnum.GL_RGBA) + pixel[offset++]=alpha; + } + } + gl.glPixelStorei(GLEnum.GL_UNPACK_ALIGNMENT, 1); + gl.glDrawBuffer(GLEnum.GL_FRONT); + gl.glRasterPos3i(xpos, ypos+imageHeight, zpos); + gl.glDrawPixels(imageWidth, imageHeight, + glFormat, GLEnum.GL_UNSIGNED_BYTE, + pixel); + gl.glDrawBuffer(GLEnum.GL_BACK); +} +} diff --git a/demos/SwingDemos/test/GLPanel-GLGraphics/GLPanel.java b/demos/SwingDemos/test/GLPanel-GLGraphics/GLPanel.java new file mode 100644 index 0000000..266595e --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-GLGraphics/GLPanel.java @@ -0,0 +1,692 @@ +//package gl4java.awt; + +import gl4java.*; + +import java.awt.*; +import java.awt.event.*; + +public class GLPanel extends Panel + implements GLEnum, GLUEnum, + ComponentListener, WindowListener, MouseListener +{ + protected GLContext glj = null; + public GLFunc gl = null; + public GLUFunc glu = null; + public GLGraphics glg = null; + + protected boolean mustResize = false; + + protected boolean cvsInitialized=false; + + protected boolean needCvsDispose = false; + + /** + * Visual pre-set for doubleBuffer, default: true + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean doubleBuffer = true; + + /** + * Visual pre-set for stencil-bit number, default: 0 + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected int stencilBits = 0; + + /** + * Visual pre-set for stereoView, default: false + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean stereoView = false; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean rgba = true; + + /** + * Visual pre-set for RGBA usage, default: true - of course ;-) + * This value is updated after a GLContext is created with the + * original updated value of GLContext ! + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected boolean createOwnWindow = false; + + /** + * The context with witch display lists and textures will be shared. + * + * @see GLPanel#preInit + * @see GLPanel#paint + */ + protected GLContext sharedGLContext; + + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLPanel could not load def. native libs."); + } + + /** + * + * Constructor + * + * @param width the canvas initial-prefered width + * @param height the canvas initial-prefered height + * + * @param gl_Name The name of the GLFunc implementation + * If gl_Name==null, the default class will be used ! + * + * @param glu_Name The name of the GLUFunc implementation + * If gl_LibName==null, the default class will be used ! + * + */ + public GLPanel( String gl_Name, + String glu_Name + ) + { + super( new BorderLayout() ); + + if( (gl=GLContext.createGLFunc(gl_Name)) ==null) + { + System.out.println("GLFunc implementation "+gl_Name+" not created"); + } + if( (glu=GLContext.createGLUFunc(glu_Name)) ==null) + { + System.out.println("GLUFunc implementation "+glu_Name+" not created"); + } + + /* to be able for RESIZE event's */ + addComponentListener(this); + } + + /** + * + * Constructor + * + * Uses the default GLFunc and GLUFunc implementation ! + * + * @param width the canvas initial-prefered width + * @param height the canvas initial-prefered height + * + */ + public GLPanel( ) + { + this(null, null); + } + + /** + * Used to return the created GLContext + */ + public final GLContext getGLContext() { return glj; } + + /** + * + * Overridden update + * This one only call's the paint method, without clearing + * the background - thats hopefully done by OpenGL ;-) + * + * @param g the Graphics Context + * @return void + * + * @see GLPanel#paint + */ + public void update(Graphics g) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::update(): isShowing()="+isShowing()); + if(isShowing()) + { + /* let's let OpenGL clear the background ... */ + paint(g); + } + } + + + /** + * Safe the toplevel window + */ + protected Window topLevelWindow = null; + + /** + * + * This function returns the found TopLevelWindow, + * which contains this Canvas .. + * + * @return void + * + * @see GLPanel#paint + */ + public final Window getTopLevelWindow() + { return topLevelWindow; } + + /** + * this function overrides the Canvas paint method ! + * + * For the first paint, + * the user function preInit is called, a GLContext is created + * and the user function init is called ! + * + * Also, if a GL Context exist, GLPanel's sDisplay-method will be called + * to do OpenGL-rendering. + * + * The sDisplay method itself calls the display-method ! + * sDisplay is needed to be thread-safe, to manage + * the resize functionality and to safe the time per frame. + * + * To define your rendering, you should overwrite the display-method + * in your derivation. + * + * @see gl4java.GLContext#GLContext + * @see GLPanel#cvsIsInit + * @see GLPanel#sDisplay + * @see GLPanel#display + * @see GLPanel#preInit + * @see GLPanel#init + */ + public synchronized final void paint( Graphics g ) + { + //JAU + if(GLContext.gljClassDebug) + System.out.println("GPanel::paint()"); + if(glj == null ) + { + preInit(); + glj = new GLContext ( this, gl, glu, + createOwnWindow, + doubleBuffer, stereoView, + rgba, stencilBits, + sharedGLContext ); + + if(glj!=null) + { + createOwnWindow = glj.isOwnWindowCreated(); + doubleBuffer = glj.isDoubleBuffer(); + stencilBits = glj.getStencilBitNumber(); + stereoView = glj.isStereoView(); + rgba = glj.isRGBA(); + } + + init(); + + // fetch the top-level window , + // to add us as the windowListener + // + Container _c = getParent(); + Container c = null; + + while(_c!=null) + { + c = _c; + _c = _c.getParent(); + } + + if(c instanceof Window) { + topLevelWindow = (Window)c; + topLevelWindow.addComponentListener(this); + topLevelWindow.addMouseListener(this); + } else { + topLevelWindow = null; + System.out.println("toplevel is not a Window: "+c); + } + + if(topLevelWindow!=null) + { + topLevelWindow.addWindowListener(this); + } else { + System.out.println("no parent found for "+getName()); + System.out.flush(); + } + if(glj!=null && glj.gljIsInit()) + cvsInitialized=true; + } + if(glg!=null) + glg.dispose(); + glg = new GLGraphics(g, glj, gl, glu); + /* + if( mustResize ) size = getSize(); + g.setClip(0, 0, size.width, size.height ); + */ + sPaint(g); + } + + /** + * + * This is the thread save rendering-method called by paint. + * The actual thread will be set to highes priority befor calling + * 'display'. After 'display' the priority will be reset ! + * + * 'gljFree' will be NOT called after 'display'. + * + * We tested the above to use multi-threading and + * for the demonstration 'glDemos' it works ;-)) ! + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay -- OR YOU MUST KNOW WHAT YOU ARE DOING THEN ! + * + * @return void + * + * @see GLPanel#paint + * @see GLPanel#display + */ + public synchronized final void sPaint( Graphics g ) + { + boolean ok = true; + + long _s = System.currentTimeMillis(); + + if(!cvsIsInit()) + return; + + /* + if( glj.gljMakeCurrent() == false ) { + System.out.println("GLPanel: problem in use() method"); + return; + } + */ + + if( mustResize ) + { + Dimension size = getSize(); + glj.gljResize( size.width, size.height ) ; + reshape(size.width, size.height); + mustResize = false; + } + if(ok) + { + display(); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_self = System.currentTimeMillis()-_s; + + /* + GLGraphics glg1 = (GLGraphics)glg.create(); + try { + super.paint(glg1); + } finally { + glg1.dispose(); + } + */ + super.paint(glg); + if(GLContext.gljClassDebug) + glj.gljCheckGL(); + _f_dur_total = System.currentTimeMillis()-_s; + + glj.gljSwap(); + glj.gljFree(); + } + + } + + public Graphics getGraphics() + { + if(glg==null) + return super.getGraphics(); + return glg.create(); + } + + public Graphics getNativeGraphics() + { + return super.getGraphics(); + } + + /** + * + * This is the rendering-method called by sDisplay + * (and sDisplay is called by paint !). + * The derived-class (Your Subclass) will redefine this, to draw it's own... + * + * BE SURE, if you want to call 'display' by yourself + * (e.g. in the run method for animation) + * YOU HAVE TO CALL sDisplay ! + * + * 'sDisplay' manages a semaphore to avoid reentrance of + * the display function !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @return void + * + * @see GLPanel#sDisplay + * @see GLPanel#paint + */ + public void display() + { + } + + /** + * + * This is your pre-init method. + * preInit is called just BEFORE the GL-Context is created. + * You should override preInit, to initialize your visual-stuff, + * like the protected vars: doubleBuffer and stereoView + * + * @return void + * + * @see GLPanel#paint + * @see GLPanel#doubleBuffer + * @see GLPanel#stereoView + * @see GLPanel#rgba + * @see GLPanel#stencilBits + */ + public void preInit() + { + } + + /** + * + * This is your init method. + * init is called right after the GL-Context is initialized. + * You should override init, to initialize your stuff needed + * by OpenGL an Java ! + * + * @return void + * + * @see GLPanel#paint + */ + public void init() + { + } + + /** + * This method is used to clean up any OpenGL stuff (delete textures + * or whatever) prior to actually deleting the OpenGL context. + * You should override this with your own version, if you need to do + * any cleanup work at this phase. + * This functions is called within cvsDispose + * + * @return void + * + * @see GLPanel#cvsDispose + */ + public void doCleanup() + { + } + + /** + * This function returns, if everything is init: the GLContext, + * the and the users init function + * This value is set in the paint method! + * + * @return boolean + * + * @see GLPanel#paint + * @see GLPanel#init + */ + public boolean cvsIsInit() + { + return cvsInitialized; + } + + protected long _f_dur_self = 0; + protected long _f_dur_total = 0; + + /** + * + * This is the reshape-method called by paint. + * The derived-class (Your Subclass) will redefine this, + * to manage your individual reshape ... + * + * This �reshape� method will be invoked after the first paint command + * after GLPanel.componentResize is called AND only if �gljUse� was + * succesfull (so a call of gljUse is redundant). + * �reshape� is not an overloading of java.awt.Component.reshape, + * �reshape� is more like �glut�-reshape. + * + * GLPanel.reshape allready has a simple default implementation, + * which calls �gljResize� and �glViewport� - so you may be can + * left this one as it is (no need to overload). + * The needed call to �gljResize� is done by hte invoker paint ! + * + * @param width the new width + * @param height the new height + * @return void + * + * @see GLPanel#paint + * @see GLPanel#sDisplay + */ + public void reshape( int width, int height ) + { + if(GLContext.gljClassDebug) + System.out.println("GLPanel::reshape bounds("+getBounds()+")"); + gl.glViewport(0,0, width, height); + gl.glMatrixMode(GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(0, width, height, 0, -50.0,50.0); + gl.glMatrixMode(GL_MODELVIEW); + } + + /* JAU */ + /* + public final void setBounds(int x, int y, int width, int height) { + reshape(x, y, width, height); + } + public final void setBounds(Rectangle r) { + reshape(r.x, r.y, r.width, r.height); + } + + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + if(glj==null || !glj.gljIsInit() || !glj.gljMakeCurrent()) + { + System.out.println("GLPanel::setBounds(): problem in use() method"); + return; + } + reshape(width-x, height-y); + glj.gljCheckGL(); + glj.gljFree(); + size = new Dimension(width-x, height-y); + } + */ + + + /** + * + * �componentResized� is the componentListeners event handler. + * + * This method sets the variable �mustResize� to true, + * so the upcoming �paint� method-call will invoke �reshape� ! + * + * This little look-alike complicating thing is done, + * to avoid an Exception by using the glContext from more than + * one concurrent thread�s ! + * + * You cannot override this implementation, it is final + * - override �reshape' instead ! + * + * @param e the element, which is resized + * @return void + * + * @see GLPanel#paint + * @see GLPanel#reshape + */ + public void componentResized(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.println("GLPanel::componentResized("+e.getComponent()+")"); + if(glj!=null && glj.gljIsInit() && e.getComponent()==this ) + { + mustResize = true; + //repaint(); + } + } + + public void componentMoved(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentMoved("+e.getComponent()+")"); + /* + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + + public void componentShown(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentShown("+e.getComponent()+")"); + } + + public void componentHidden(ComponentEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::componentHidden("+e.getComponent()+")"); + } + + public void mouseClicked(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("."); + } + public void mouseEntered(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("GLPanel::mouseEntered("+e.getComponent()+")"); + /* + if(e.getComponent().equals(topLevelWindow)) + { + repaint(); + } + */ + } + public void mouseExited(MouseEvent e) + {} + public void mousePressed(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print("<"); + } + public void mouseReleased(MouseEvent e) + { + if(GLContext.gljClassDebug) + System.out.print(">"); + } + + public void windowOpened(WindowEvent e) + { + } + + /** + * + * �windowClosing� is the windowListeners event handler + * for the topLevelWindow of this Canvas ! + * + * This methods free�s AND destroy�s + * the GL Context with �glj.gljDestroy� ! + * + * @return void + * + */ + public void windowClosing(WindowEvent e) + { + if(e.getComponent().equals(topLevelWindow)) + { + cvsDispose(); + } + } + + /** + * + * �windowClosed� is the windowListeners event handler. + * + * @return void + * + */ + public void windowClosed(WindowEvent e) + { + if (needCvsDispose) cvsDispose(); + } + + public void windowIconified(WindowEvent e) + { + } + + public void windowDeiconified(WindowEvent e) + { + } + + public void windowActivated(WindowEvent e) + { + } + + public void windowDeactivated(WindowEvent e) + { + } + + /** + * You should call this before releasing/dispose this Window ! + * Also you can overwrite this class, + * to dispose your own elements, e.g. a Frame etc. - + * but be shure that you call + * cvsDispose implementation call this one ! + * + * This function calls gljDestroy of GLContext ! + * + * @see gl4java.GLContext#gljDestroy + * @see GLPanel#doCleanup + */ + public void cvsDispose() + { + cvsInitialized = false; + if (glj != null) + { + if (glj.gljIsInit()) + { + /* Sometimes the Microsoft VM calls the + Applet.stop() method but doesn't have + permissions to do J/Direct calls, so + this whole block of code will throw a + security exception. If this happens, + however, windowClosing() will still + call us again later and we will have + another opportunity to shut down the + context, so it all works out fine. */ + try + { + glj.gljFree(); + doCleanup(); + //locks and free's GLContext + glj.setEnabled(false); + glj.gljDestroy(); + needCvsDispose = false; + } + catch (Exception ex) + { + needCvsDispose = true; + } + } + } + + // Setting glj to null will simply cause paint() to re-initialize. + // We don't want that to happen, so we will leave glj non-null. + } + + /** + * get methods + */ + public final int cvsGetWidth() { + return getSize().width; + } + public final int cvsGetHeight() { + return getSize().height; + } +} + diff --git a/demos/SwingDemos/test/GLPanel-GLGraphics/test1.java b/demos/SwingDemos/test/GLPanel-GLGraphics/test1.java new file mode 100644 index 0000000..1b8bf4b --- /dev/null +++ b/demos/SwingDemos/test/GLPanel-GLGraphics/test1.java @@ -0,0 +1,129 @@ +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.Dimension; +import javax.swing.*; +import gl4java.*; +import gl4java.swing.*; +import gl4java.utils.glut.*; +import gl4java.utils.glut.fonts.*; + +public class test1 extends JApplet + implements GLEnum, GLUEnum +{ + static { + if(GLContext.loadNativeLibraries(null, null, null)==false) + System.out.println("GLCanvas could not load def. native libs."); + } + + protected class test1Panel extends GLPanel + implements ActionListener, ItemListener + { + public test1Panel() { + super(); + GLContext.gljNativeDebug = true; + GLContext.gljClassDebug = true; + //String[] data = {"one", "two", "three", "four"}; + //JList dataList = new JList(data); + //add("North", dataList); + JButton b1, b2; + add("East", (b1 = new JButton("E"))); + b1.setActionCommand("east"); + b1.addActionListener(this); + add("West", (b2 = new JButton("W"))); + b2.setActionCommand("west"); + b2.addActionListener(this); + + JCheckBox c1; + add("South", (c1 = new JCheckBox("SouthButton", true))); + c1.addItemListener(this); + } + + GLGraphics glg = null; + + public void init() { + System.out.println("<i>"); + //glg = new GLGraphics(gl, glu); + reshape(getSize().width, getSize().height); + } + + public void display() + { + System.out.println("<p>"); + + int i; + + glg = (GLGraphics)getGraphics(); + + gl.glPushMatrix(); + gl.glClear(GL_COLOR_BUFFER_BIT); + + glg.setColor(Color.blue); + + int width=getSize().width; + int height=getSize().height; + + glg.drawLine ( 0, height/2, width, height/2 ); + glg.drawLine ( width/2, 0, width/2, height ); + + glg.setColor(Color.yellow); + + glg.drawLine ( 0, 0, width, height); + glg.drawString("Left-top", 0, 10); + glg.drawString("GLGraphics - CENTER", width/2, height/2); + glg.drawString("Right - Bottom (nearly)", width*2/3, height*2/3); + gl.glPopMatrix(); + + glj.gljCheckGL(); + } + + public void reshape(int width, int height) + { + System.out.println("reshape("+width+", "+height+")"); + super.reshape(width, height); + } + + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("east")) { + System.out.println("East pressed"); + } else if (e.getActionCommand().equals("west")) { + System.out.println("West pressed"); + } + } + + public void itemStateChanged(ItemEvent e) { + Object source = e.getItemSelectable(); + System.out.println("item changed: "+source); + } + + } + + test1Panel tst1cvs1; + + public void init() + { + tst1cvs1 = new test1Panel(); + tst1cvs1.setSize(400,400); + setContentPane(tst1cvs1); + } + + public static void main(java.lang.String[] args) { + try { + Frame mainFrame = new Frame("test1"); + + test1 applet=new test1(); + + applet.setSize(400, 400); + applet.init(); + applet.start(); + + mainFrame.add(applet); + + mainFrame.pack(); + mainFrame.setVisible(true); + } catch (Throwable exception) { + System.err.println("Exception occurred in main()"); + exception.printStackTrace(System.out); + } + } +} |