Computer graphics/2013-2014/Laboratory 7

Keyboard and mouse control
User input is very important especially in interactive graphic applications such as games or simulators by allowing the user to control the camera or interact with objects in the scene in real time. Usually this is done through the use of a keyboard and a mouse, and occasionally through a joystick, microphone (voice commands), or other input device.

If we want to be informed of keyboard an mouse events we have to register specific listeners besides the GLEventListener:
 * KeyListener -- used to inform us of keyboard events
 * MouseListener -- used to inform us of mouse clicks
 * MouseMotionListener -- used to inform us of mouse movement

These issues are AWT specific, thus they are assumed to be known. You could find more information at the following links:


 * AWT Fundamentals -- Short Course
 * JOGL: A Beginner's Guide and Tutorial

Please pay attention as the mouse coordinates are given in the view-port coordinates -- that is how we obtain the number of pixels from left and top -- and we must transform them in the object coordinates.

'''Important: OpenGL applications require the user to handle keyboard and mouse events in a different thread that the one on which it is performing the OpenGL operations as these operations cannot occur directly inside the mouse or keyboard handlers. A mouse or keyboard listener may invoke the GLDrawable instance's repaint method thus forcing the redisplay.'''

Links:


 * java.awt.event:
 * KeyListener
 * MouseListener

In order to enable your JOGL application to handle mouse or keyboard events you need to implement several interfaces:


 * KeyListener
 * keyPressed method
 * keyReleased method
 * keyTyped method
 * MouseListener
 * mousePressed method
 * mouseReleased method
 * mouseClicked method
 * mouseEntered method
 * mouseExited method
 * MouseMotionListener
 * mouseMoved method
 * mouseDragged method

The following fragment of code exemplifies the previous:

MORE ON MODELVIEW MANAGEMENT
The scene in (J)OGL is manipulated by using the ModelView Matrix Besides this matrix the Projection Matrix is used for defining the viewing volume.

Revisit Computer graphics -- 2013-2014 -- info.uvt.ro/Laboratory 2 for more details.

Next we will learn about how we can transform our scene and more precisely how we can move, scale or rotate objects. To do this first we need to remember that (J)OGL uses 4x4 matrices to store scene information. We can always choose to save the current matrix by using the glPushMatrix method (function) which pushes the current matrix on the stack. In the same way calling glPopMatrix method (function) retrieves the last saved matrix. This is useful for example when we want to draw planet Earth in orbit and then draw the Moon around it.

Transformations: Rotation, Translation, Scaling
Model transformations involve rotating, scaling or translating objects in your scene.

IMPORTANT: One has to pay attention to the order these transformations are applied as a translation after a rotation does not produce the same effect as a rotation followed by a translation.

(J))OGL puts at the programmer's disposal a couple of very intuitive methods (functions) for handling object transformations: glRotate*(angle, x, y, z), glScale*( factorX, factorY, factorZ) (for values inside the (0-1) interval the object gets scaled down) and glTranslate*(x, y, z).

IMPORTANT: In (J)OGL the operations need to be placed in the code in the opposite order than in reality. For example a translation followed by a rotation in real life, is represented in (J)OGL as a rotation followed by a translation. See this for details.

For example the next fragment of code places a sphere at the center of the screen and makes another one rotate around it. It also explains how glPushMatrix and glPopMatrix methods (functions) work:

Camera control
An important feature in 3D graphics is the ability to control the camera. This ability allows the user to navigate through the scene, zooming in objects, avoiding others, orienting himself in space, etc.

There are basically two ways of controlling your camera:
 * keeping the camera fixed and moving the world (rotations, translations) to keep the illusion of movement. For details see . The basic ideas for this approach are:
 * rotate the world around the origin in the opposite direction of the camera rotation
 * and translate the world in the opposite manner that the camera has been translated
 * move the camera around and draw the 3D environment relative to coordinate system origin

Solution 2: Use the gluLookAt method to re-orientate and reposition the camera
For those interested we also show the solution for the second variant in which we use the gluLookAt method to re-orientate and reposition the camera. The following code fragment shows how we can define methods for handling the moving and aiming of the camera. An additional the polarToCartesian method is used to convert polar (spherical) coordinates to Cartesian coordinates. The aimCamera and moveCamera methods are being called inside the display method at the beginning just after the glClear method call:

IMPORTANT: By default if azimuth and elevation are set to 0 then the camera is oriented parallel with the positive Z axis towards infinity.

API

 * javax.media.opengl:
 * GL:
 * glPushMatrix
 * glPopMatrix
 * glRotatef(float, float, float, float)
 * glTranslatef(float, float, float)
 * glScalef(float, float, float)

Exercises

 * Add three spheres to the scene: the first one should be placed at the center of the scene, the second should rotate around the first one and the third one around the second one (Sun-Earth-Moon system).
 * Each sphere should have a texture applied on it.
 * The second sphere should have two textures on it as follows: the first one represents the earth surface, while the second shows the clouds. The clouds should also move on the sphere surface.
 * Also lighting and materials should be enabled. One ambiental plus a diffuse light near the center of the scene to simulate light from the Sun should exist. Make the Sun glow (emission light).
 * HINT: use two concentric spheres and apply blending to make the clouds mix with the surface.
 * Add camera control to the previous scene so that the user could explore the surroundings. Try both methods described in this laboratory. Which one is more suited?