@Cakey + Ihkbob
Thanks for your quick. Yesterday I played around the whole day with your suggestions. Everything works fine.
@ Ihkbob
I even wrote some lines with an animator. To rise my learning curve even a bit more! → See below. Thanks for mention it.
Again, thanks you two. It helped me very much.
Jaquelin
In case someone is interested in the animator solution Ihkbob mentioned see this code. Take a look at moveToLeftAccess() and how the other two classes use this method.
My “Main-Class”
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLJPanel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.sun.opengl.util.FPSAnimator;
@SuppressWarnings("serial")
public class TriangleGL extends JFrame {
//private static int DEFAULT_FPS = 80;
private static final int JPANEL_WIDTH = 512; // initial size of panel
private static final int JPANEL_HEIGHT = 512;
private TriangleGLListener triangleGLListener;
private GLJPanel jCanvas;
private static ValueChanger valueChanger;
private FPSAnimator animator;
private static int DEFAULT_FPS = 40;
private static float moveToLeft = 0;
public static final int SET = 1;
public static final int GET = 2;
public TriangleGL() {
super("Frame for my frist triangle");
Container container = this.getContentPane();
container.setLayout(new BorderLayout());
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
animator.stop();
valueChanger.interrupt();
System.exit(0);
}
});
JPanel renderJPanel = makeRenderPanel();
container.add(renderJPanel, BorderLayout.CENTER);
pack();
setVisible(true);
animator.start();
}
public static void main(String[] args) {
valueChanger = new ValueChanger();
valueChanger.start();
new TriangleGL();
}
private JPanel makeRenderPanel() {
JPanel renderJPanel = new JPanel();
renderJPanel.setLayout(new BorderLayout());
renderJPanel.setPreferredSize(new Dimension(JPANEL_WIDTH, JPANEL_HEIGHT));
GLCapabilities glCapabilities = new GLCapabilities();
glCapabilities.setAlphaBits(8);
jCanvas = new GLJPanel(glCapabilities);
triangleGLListener = new TriangleGLListener(this);
jCanvas.addGLEventListener(triangleGLListener);
animator = new FPSAnimator(jCanvas, DEFAULT_FPS, true);
renderJPanel.add(jCanvas, BorderLayout.CENTER);
return renderJPanel;
}
/**
* Thread-save method to read and write moveToLeft
*
* @param mode GET or SET value
* @param newValue New value.
* @return
*/
public static synchronized float moveToLeftAccess(int mode, float newValue) {
switch(mode) {
case (SET):
moveToLeft = newValue;
break;
case (GET):
// return value at end of method (see below)
break;
}
return moveToLeft;
}
}
My GLListener implementation:
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
public class TriangleGLListener implements GLEventListener {
private GLU glu;
public TriangleGLListener(TriangleGL triangle) {
}
// ----------------- listener callbacks -----------------------------
public void display(GLAutoDrawable drawable) {
// System.out.println("display called");
GL gl = drawable.getGL();
// Clear screen and depth buffer
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// Reset view (x = 0, y = 0, z = 0)
gl.glLoadIdentity();
// Move view - C A L L moveToLeftAccess()!!!
gl.glTranslatef(TriangleGL.moveToLeftAccess(TriangleGL.GET, 0.0f), 0.0f, -6.0f);
gl.glBegin(GL.GL_TRIANGLES);
gl.glVertex3f(0.0f, 1.5f, 0.0f); // Top
gl.glVertex3f(-1.0f, 0.0f, 0.0f); // Bottom Left
gl.glVertex3f(1.0f, 0.0f, 0.0f); // Bottom Right
gl.glEnd();
gl.glFlush();
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width,
int height) {
// System.out.println("reshape called");
GL gl = drawable.getGL();
// To avoid division by 0 in aspect ration below (gluPerspective()).
if (height == 0)
height = 1;
// Resizes the current viewport
gl.glViewport(x, y, width, height);
// Select the projection matrix
gl.glMatrixMode(GL.GL_PROJECTION);
// Reset the projection matrix
gl.glLoadIdentity();
glu.gluPerspective(45.0f, (float) width / (float) height, 0.1f, 100.0f);
// Select the ModelView Matrix
gl.glMatrixMode(GL.GL_MODELVIEW);
// Reset the ModelView Matrix
gl.glLoadIdentity();
}
public void init(GLAutoDrawable drawable) {
// System.out.println("init called");
// don't make this gl a global!
GL gl = drawable.getGL();
// this is okay as a global, but only use in callbacks
glu = new GLU();
// Enables Smooth Shading
gl.glShadeModel(GL.GL_SMOOTH);
gl.glEnable(GL.GL_DEPTH_TEST);
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged,
boolean deviceChanged) {
// not implemented yet.
}
}
This class simulates my class which actually calculates some stuff on which changeToLeft depends.
public class ValueChanger extends Thread {
private float moveToLeftInternal;
public ValueChanger() {
moveToLeftInternal = 0;
}
public void run() {
while(true) {
if(isInterrupted()) {
break;
}
changeMoveToLeft();
}
}
public void changeMoveToLeft() {
if(moveToLeftInternal > -2.0f) {
moveToLeftInternal = moveToLeftInternal - 0.1f;
} else {
// reset value
moveToLeftInternal = 0;
}
TriangleGL.moveToLeftAccess(TriangleGL.SET, moveToLeftInternal);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
interrupt();
}
}
}