Keyboard input not updating display

I have some experience doing OpenGL with C/C++, but I’m new to jogl and having issues getting key input to work. I’m trying to write a simple translation function and all my debugging printlns work, but the actual display doesn’t.

Can anyone see what I’m doing wrong?

package cubepackage;

import com.sun.opengl.util.FPSAnimator;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLJPanel;
import javax.media.opengl.glu.GLU;


/**
 * Engine.java
 * 
 */
public class Engine implements GLEventListener 
{     
    cubeFactory cube = new cubeFactory();
    
    public void init(GLAutoDrawable drawable) 
    {
        // Use debug pipeline
        // drawable.setGL(new DebugGL(drawable.getGL()));

        GL gl = drawable.getGL();
        System.err.println("INIT GL IS: " + gl.getClass().getName());

        // Enable VSync
        gl.setSwapInterval(1);

        // Setup the drawing area and shading mode
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glShadeModel(GL.GL_SMOOTH); // try setting this to GL_FLAT and see what happens.
    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) 
    {
        GL gl = drawable.getGL();
        GLU glu = new GLU();

        if (height <= 0)
        { // avoid a divide by zero error!
        
            height = 1;
        }
        final float h = (float) width / (float) height;
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, h, 1.0, 20.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }
    
    float x = 1;
    float y = (float) 1.0;
    float z = (float) 1.0;
    float nearX = 0;
    float farX = x;
    float nearY = y;
    float farY = 0;
    float nearZ = 0;
    float farZ = z;
    int numBoxes = 3;

    public void display(GLAutoDrawable drawable) 
    {
        GL gl = drawable.getGL();

        // Clear the drawing area
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        // Reset the current matrix to the "identity"
        gl.glLoadIdentity();
        
        gl.glRotatef(0.0f, 0.0f, 0.0f, 0.0f);

        // Move the "drawing cursor" around
        //gl.glTranslatef(0.0f, 0.0f, -10.0f);
        cube.finalizeTranslate(gl);
        
        //Here's where we start drawing. ORDER MATTERS.
        //In case you want to do textures or something, you need to draw
        //everything in counter-clockwise order.
        // Draw A Quad
        gl.glBegin(GL.GL_QUADS);
        
            gl.glColor3f(0.5f, 0.5f, 1.0f);    // Set the current drawing color to light blue            
            cube.drawCube(gl);
            
        // Done Drawing The Quad
        gl.glEnd();

        // Flush all drawing operations to the graphics card
        gl.glFlush();
    }
    
    public void main() 
    {      
        userInterface frame = new userInterface();
        GLJPanel canvas = frame.getGLJPanel();
        
        
        //layout setup
        frame.add(canvas);
        
        canvas.addGLEventListener(new Engine());
        
        
        //DO THIS OR KEYLISTENERS WON'T WORK
        canvas.requestFocusInWindow();
        
        //frame.add(canvas);
        frame.setSize(800, 600);
        FPSAnimator animator = new FPSAnimator(canvas, 10);
        animator.setRunAsFastAsPossible( false );
        frame.addWindowListener(new WindowAdapter() 
        {

            @Override
            public void windowClosing(WindowEvent e) 
            {
                // Run this on another thread than the AWT event queue to
                // make sure the call to Animator.stop() completes before
                // exiting
                new Thread(new Runnable() 
                {

                    public void run() 
                    {
                        System.exit(0);
                    }
                }).start();
            }
        });
        
        // Center frame
        frame.setLocationRelativeTo(null);


        frame.setVisible(true);
        animator.start();        
        
        commandHub hub = new commandHub(this, frame, cube);
        
        canvas.addKeyListener(hub);
        frame.addMouseListener(hub);
        frame.addMouseMotionListener(hub);
    }

    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) 
    {
    }
}


Here’s where the translation code is:

    public void translatePosX()
    {
        distanceX += 0.5;
    }
    public void translateNegX()
    {
        distanceX -= 0.5;
    }
    public void translatePosY()
    {
        distanceY += 0.5;
    }
    public void translateNegY()
    {
        distanceY -= 0.5;
    }
    public void translatePosZ()
    {
        distanceZ += 0.5;
    }
    public void translateNegZ()
    {
        distanceZ -= 0.5;
    }
    
    public void finalizeTranslate(GL gl)
    {
        gl.glTranslatef(distanceX, distanceY, distanceZ);
    }

Key input method:

    public void keyTyped(KeyEvent e) 
    {
        System.out.println(e.getKeyChar());
        
        switch(e.getKeyChar())
        {
            case 'd':
                System.out.println("move right");
                cubeFac.translatePosX();
                break;
            case 'a':
                System.out.println("move left");
                cubeFac.translateNegX();
                break;
                
            case 'p':
                System.out.println("move up");
                cubeFac.translatePosY();
                break;
            
            case ';':
                System.out.println("move down");
                cubeFac.translateNegY();
                break;
                
            case 's':
                System.out.println("move back");
                cubeFac.translatePosZ();
                break;
             
            case 'w':
                System.out.println("move forward");
                cubeFac.translateNegZ();
                break;
        }
    }

Thanks

You most probably have a component focus problem. Try calling frame.setFocusEnabled(false) and canvas.requestFocus() in your main method.

On a side note: please try to adhere to java code conventions, especially the naming conventions to make your code more readable for the outside world.

It’s not a focus issue, I figured out where the issue is, but I’m not sure what’s going on.

When a key is pressed, translate[Direction]Axis (e.g. translatePosX()) is called in CommandHub, but the parameter updates aren’t being applied to finalizeTranslation().

This should print different values when a key is pressed, but it doesn’t.

public void finalizeTranslate(GL gl)
    {
        System.out.println("x: " + distanceX + "y: " + distanceY + "z: " + distanceZ);
        gl.glTranslatef(distanceX, distanceY, distanceZ);
    }

Ah ok, I haven’t looked too deep into your source. So you are saying, the printlns do work (the “move up” etc. shows up), so I assume the distance_ vars also do change (checked it?). Does the animator work (is display called periodically)? If yes, the only thing I can image is a “forgotten” glLoadIdentity() in drawCube()…

They (as in the distance variables) don’t work, and that’s what odd to me.

Also, I’m loading the identity matrix in display() before calling drawCube(). I’m trying to compartmentalise things slowly (I started with the little RGB triangle and blue square demo).

By the way, I fixed the class names so they’re SomeClass instead of someClass. Is that what you were referring to when you mentioned the naming conventions issue?

I fixed it. Turns out there were 2 instances of my Engine class.

This line was breaking it:

 canvas.addGLEventListener(new Engine());

Modifying it thusly fixed it:

 canvas.addGLEventListener(this);

Exactly.

Ouch :wink:

Great that you solved the problem. In regards to your naming conventions, however, you should also be careful as to what you pick for a name. For example, above, you create a main() method which happens to be non-static (which is most likely new Engine() didn’t really work). Java uses a ‘special’ static main() method as an execution point for a java application, making your method appear similar. It is still syntactically functional, but harder for another person to understand (eg me, since I saw main and assumed it was static, in which case your original code would have been valid).

Oh, I forgot about that. It originally was the actual main() function, but I forgot to change the name in the process of debugging. Thanks for pointing that out. It’s now runEngine().