Hierarchical Transformations

Hierarchical transformations can be thought of as transformations that are "attached to" other transformations.

They are used to transform objects relative to other objects.

A common use is in articulated bodies.

Adventures of Prince Achmed, Lotte Reiniger

Hierarchical Transformations

We can draw this "car" by transforming the two wheels relative to the body of the car.

We'd like each wheel to be affected by the car body's transformation, but not by any other wheel's transformation.

Hierarchical Transformations

The basic tool needed is commands to save & restore transformation state.

apply body transformation
draw body
save state
apply front wheel transformation
draw wheel
restore saved state
apply rear wheel transformation
draw wheel

PushMatrix / PopMatrix

A transformation is represented mathematically as a matrix.

OpenGL maintains a stack of saved transformation matrices.

glPushMatrix() & glPopMatrix() save and restore transformation state.

Make sure you always have the same number of pushes & pops.

The number of transformations you can save is finite; it is at least 32.

Transformation Hierarchy

Hierarchical transformations are often represented as a tree of transformations.

This is the basis of scene graph systems.

GLUT Devices

GLUT Keyboard Functions

glutKeyboardFunc(func) Called when a 'character' key is hit
glutSpecialFunc(func) Called when a 'special' key is hit
glutKeyboardUpFunc(func) Called when a 'character' key is released
glutSpecialUpFunc(func) Called when a 'special' key is released
glutGetModifiers() Returns state of shift, control, alt keys when event happened
glutIgnoreKeyRepeat(val) Tells GLUT whether to ignore automatic keyboard repeat

GLUT Keyboard Callback

All keyboard callback functions take the form:

    def func(key, x, y):

key is the key pressed or released - either a single-character string (e.g. 'a'), or a special-key constant (e.g. GLUT_KEY_UP)

x, y is the mouse pointer location when the key event occurred

Note: in Python, the same function can be used for both normal & special keys


glutGetModifiers() returns a bit-mask value
i.e. a combination of flags


Test a flag with the & operator. e.g.:

    if glutGetModifiers() & GLUT_ACTIVE_CTRL:

GLUT Mouse Functions

glutMouseFunc(func) Called when a mouse button is pressed
glutMotionFunc(func) Called when mouse moves, while button pressed
glutPassiveMotionFunc(func) Called when mouse moves, with no button pressed
glutGetModifiers() Returns state of shift, control, alt keys when event happened

GLUT Mouse Callback

Mouse-button callback functions take the form:

    def func(button, state, x, y):

button is the button pressed or released - one of GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, or GLUT_RIGHT_BUTTON

state is GLUT_DOWN if the button was pressed, or GLUT_UP if it was released

x, y is the mouse pointer location when the button was pressed or released

GLUT Motion Callback

Mouse-motion callback functions take the form:

    def func(x, y):

x, y is the new mouse pointer location

GLUT Menus

GLUT provides simple pop-up menus

A menu is attached to a mouse button, and appears whenever that button is pressed

If a menu entry is selected, a callback is called with a value associated with that entry

Menus can include sub-menus

GLUT Menu Functions

id = glutCreateMenu(func) Starts defining a new menu (or submenu)
glutAddMenuEntry(label, value) Adds a selectable entry to the current menu
glutAddSubMenu(label, id) Adds a submenu to the current menu
glutAttachMenu(button) Defines mouse button to pop-up the current menu


GLUT Menu Notes

Each menu has a unique ID - a number

ID primarily needed when creating submenus

Value associated with a menu entry must be a single integer

Menus can be changed dynamically
(See glutSetMenu, glutRemoveMenuItem, glutChangeToMenuEntry, glutChangeToSubMenu)

Menus can also be attached & detached from buttons dynamically (See glutDetachMenu)

Creative Commons License
This document is by Dave Pape, and is released under a Creative Commons BY-2.0 License.