Thank you!
Here it is, maximally compressed. With a little bit of work I will be able to post something that actually runs. Or, I could include a small flash presentation of what happens on the screen. This is a JPanel which is later included in a JFrame.
package laba;
import pmgjutils.Value;
import pmgjutils.ValuePanel;
import javax.swing.;
import java.util.;
import java.awt.;
import java.awt.event.;
import net.java.games.jogl.*;
public class ImaxToPost extends JPanel {
private GLCanvas myGLCanvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
private ArrayList myContents = new ArrayList();
private ArrayList my3DObjects = new ArrayList(); // Basically an ArrayList of ints representing gl lists.
/*
Value.Double is basically a Double which triggers a callback when changed. Value.DoubleWheelable is a similar thing except it creates a
a little gui component that looks like a wheel. Value.Boolean is the same for boolean except it creates a checkbox Etc…
*/
private Value.DoubleWheelable myTheta = new Value.DoubleWheelable(“Longitudal Angle, \u03b8 (in units of \u03c0)”, .5, 0.01, 1);
private Value.DoubleWheelable myPhi = new Value.DoubleWheelable(“Azimuthal Angle, \u03c6 (in units of \u03c0)”, -.5, 0.01, 0);
private Value.DoubleWheelable myZoom = new Value.DoubleWheelable(“Zoom”, 2.0, 0.1, 1);
private Value.Boolean myPerspectivePresent = new Value.Boolean(“Perspective?”, false);
private Value.DoubleRange myPersp = new Value.DoubleRange(“View Angle”, Math.PI/3, 0, Math.PI);
public GLCanvas pGetCanvas3D() { return myGLCanvas; }
private static void gRefreshCanvas(GLCanvas inCanvas) {
// Experiments with threads. Basically calles myGLCanvas.display();
final GLCanvas canvas = inCanvas;
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// System.out.println("About the give the repaint command! " + Thread.currentThread().getName());
canvas.display();
// }
// });
}
public ImaxToPost() {
setLayout(new BorderLayout());
Value[] values = new Value[] {
myZoom, myTheta, myPhi, myPerspectivePresent, myPersp,
Value.SEPARATOR, Value.SEPARATOR };
for (int v = 0; v < values.length; v++) { // refresh when a view paramter changed.
values[v].pAddValueListener(new Value.Listener() {
public void pOnAction(Value.Event inE) { gRefreshCanvas(myGLCanvas); }
});
}
InteractionListeners il = new InteractionListeners();
myGLCanvas.addComponentListener(il);
myGLCanvas.addMouseListener(il);
myGLCanvas.addMouseMotionListener(il);
}
public void pKickStart() {
myGLCanvas.addGLEventListener(new OnScreenGLEventListener());
add(myGLCanvas, BorderLayout.CENTER);
}
public class OnScreenGLEventListener implements GLEventListener {
public void init(GLDrawable inDrawable) {
System.out.println("Init is being called by " + Thread.currentThread().getName());
GL gl = inDrawable.getGL();
gl.glClearColor(1f, 1f, 1f, 1f);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
gl.glEnable(GL.GL_POLYGON_OFFSET_LINE);
// Lights
gl.glEnable(GL.GL_LIGHTING);
gl.glLightModelfv(GL.GL_LIGHT_MODEL_AMBIENT, new float[] { 1f, 1f, 1f, 1f }); // was .6 .6 .6 1
gl.glDisable(GL.GL_CULL_FACE) ;
gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_TRUE) ;
}
public void display(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
public void displayChanged(GLDrawable inDrawable, boolean inWhat, boolean inWhen) {}
public void reshape(GLDrawable drawable, int x, int y, int width, int height) {}
public void display(GLDrawable inDrawable) {
// System.err.println(Thread.currentThread().getName());
// try { throw new RuntimeException(); } catch (Exception inE) { inE.printStackTrace(System.out); }
GL gl = inDrawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
pSetView(inDrawable, false);
for (int i = 0; i < myContents.size(); i++) {
Buildable buildable = (Buildable) myContents.get(i); // Definition of Buildable below
if (buildable.pHasBeenTouched()) {
Object obj = buildable.pGenerate3D(inDrawable, null);
if (my3DObjects.size() > i && my3DObjects.get(i) != null)
my3DObjects.set(i, obj);
else
my3DObjects.add(i, obj);
buildable.pUntouch();
}
if (buildable.pIsVisible() && ((Integer) my3DObjects.get(i)).intValue() != 0)
gl.glCallList(((Integer) my3DObjects.get(i)).intValue()); // Reveals implementation
}
gl.glFlush();
}
}
/*
public interface Buildable {
public abstract Object pGenerate3D(net.java.games.jogl.GLDrawable drawable, Object inOther);
public abstract String pGetName();
public abstract boolean pIsVisible();
public boolean pHasBeenTouched();
public Buildable pTouch();
public Buildable pUntouch();
}
*/
public void pSetView(GLDrawable inDrawable, boolean inFlip) {
pSetView( (double) myGLCanvas.getSize().width / myGLCanvas.getSize().height, inDrawable, inFlip);
}
public void pSetView(double inAspect, GLDrawable inDrawable, boolean inFlip) {
GL gl = inDrawable.getGL();
GLU glu = inDrawable.getGLU();
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
double dim = myZoom.pValue();
if (myPerspectivePresent.pValue()) {
glu.gluPerspective(myPersp.pValue()*180/Math.PI, inAspect, .1, 100000.0);
dim = myZoom.pValue() / Math.tan(myPersp.pValue() / 2);
}
else
gl.glOrtho(-myZoom.pValue() * inAspect, myZoom.pValue() * inAspect, -myZoom.pValue(), myZoom.pValue(), -10.0, 100.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
double theta = myTheta.pValue() * Math.PI;
double phi = myPhi.pValue() * Math.PI;
double upOrDown = 1 - 2 * (int) (pmgjutils.math.PmgMath.gMod(theta, 2 * Math.PI) / Math.PI);
glu.gluLookAt(dim * Math.sin(theta) * Math.cos(phi),
dim * Math.sin(theta) * Math.sin(phi), dim * Math.cos(theta),
0.0, 0.0, 0.0,
0.0, 0.0, (!inFlip)?upOrDown:-upOrDown);
}
private class InteractionListeners implements MouseListener, MouseMotionListener, ComponentListener {
private int myLastX, myLastY;
public void mousePressed(MouseEvent inME) {
if (inME.getButton() == MouseEvent.BUTTON1) {
myLastX = inME.getX();
myLastY = inME.getY();
}
else if (inME.getButton() == MouseEvent.BUTTON3) {
int x0 = (int) ((GLCanvas) inME.getSource()).getParent().getBounds().getX();
int y0 = (int) ((GLCanvas) inME.getSource()).getParent().getBounds().getY();
int x = inME.getX(), y = inME.getY();
}
}
public void mouseDragged(MouseEvent inME) {
if ((inME.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0) return;
if ((inME.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) != 0 ) {
myZoom.pIncrement((inME.getY() - myLastY)/30.0/Math.PI);
}
else if ((inME.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0 ) {
myPersp.pIncrement(-(inME.getY() - myLastY)/600.0/Math.PI);
}
else {
myPhi.pIncrement( -(inME.getX() - myLastX)/300.0/Math.PI);
myTheta.pIncrement(-(inME.getY() - myLastY)/300.0/Math.PI);
}
myLastX = inME.getX();
myLastY = inME.getY();
}
public void mouseMoved(MouseEvent inME) { }
public void mouseReleased(MouseEvent e) { }
public void mouseClicked(MouseEvent inME) {
if (inME.getButton() == MouseEvent.BUTTON1 && inME.getClickCount() == 2) {
myPerspectivePresent.pNegate();
return;
}
final MouseEvent e = inME;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int x = e.getX(), y = e.getY();
GL gl = myGLCanvas.getGL();
char[] l = new char[3];
gl.glReadPixels(x, y, 3, 3, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, l);
System.out.println(x + " " + y + " " + (int) l[0] + " " + (int) l[1] + " " + (int) l[2]);
}
});
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void componentHidden(ComponentEvent inCE) { }
public void componentShown(ComponentEvent inCE) { }
public void componentMoved(ComponentEvent inCE) { }
public void componentResized(ComponentEvent inCE) { }
}
}