Introduction Transformation matrices Matrix stacks CE325: 3D Computer Graphics 5. Transformations in OpenGL Adrian F. Clark alien@essex.ac.uk VASE Laboratory, School of Computer Science and Electronic Engineering University of Essex 2011–12 /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Outline 1 Introduction 2 Transformation matrices 3 Matrix stacks /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Introduction We’ll first look at hidden surface removal, as that makes objects that we render look much more believable Then, as we have a better idea of how geometry works in computer graphics, we can take another look at transformations in OpenGL We shall then look at transformation matrix stacks and hierarchical modelling /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Hidden surface removal [see opengl-07.c] In OpenGL, the following two calls are needed to enable hidden surface removal: glutInitDisplayMode (GLUT_DEPTH | ...); glEnable (GL_DEPTH_TEST); Then, when the frame buffer is cleared in the display callback, one also “clears” the depth buffer: glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Polygons have only one side One of the idiosyncrasies of most computer graphics systems is that polygons have one side, not two — this is a speed optimization Only polygons where the normal vector, the vector perpendicular to the surface, points towards the camera are visible The convention in OpenGL is that vertices must be specified in anti-clockwise order as looking towards the polygon for its normal vector to point towards the camera and hence be visible This means that a polygonal representation of a solid shape needs to have all its normals pointing outwards, and hence all its polygons specified in anticlockwise order /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Modelview and projection matrices OpenGL has two different transformation matrices, the modelview matrix and the projection matrix. The former is normally associated with the composition of the scene and its virtual camera in the world coordinate system, while the latter is concerned specifically with the formation of the image of the scene. (Note that both of these are 4 × 4 matrices and operate on homogeneous coordinates.) Whenever the application program specifies a coordinate c for drawing, OpenGL transforms it by the modelview matrix M and the projection matrix P: c0 = PMc /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Both M and P are initially the identity transformation (i.e., do nothing). It is up to the application program to ensure that these matrices have sensible values. You select which transformation matrix is to be affected using glMatrixMode which takes a single argument: GL PROJECTION to select the projection matrix GL MODELVIEW to select the modelview matrix Normally, applications set M in their display callback and P in their reshape callback, which is invoked when the window is re-sized or re-shaped, as we shall shortly see. /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Transformations in OpenGL A fairly common sequence of calls is something like glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glTranslatef (1.0, 0.0, 0.0); glScalef (1.5, 1.0, 0.5); glVertex3f (1.0, 1.0, 1.0); The OpenGL functions that affect the current transformation matrix do so by post-multiplication, so the sequence of transformation invocations must be specified in the reverse order to the desired effect. This all seems fairly crazy to the author but it’s something we have to live with. /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks The routines glLoadIdentity, glTranslatef and glScalef are all fairly obvious. There is also glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z) which performs an anti-clockwise rotation of angle degrees around the vector pointing from the origin to (x, y , z). /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Matrix stacks In fact, the modelview matrix isn’t a single matrix stored within OpenGL, it’s actually the top of a stack: 0 (top) 4 × 4 matrix A0 1 4 × 4 matrix A1 ... N ... 4 × 4 matrix AN This makes it easier for OpenGL to support hierarchical modelling. You push the current matrix stack using glPushMatrix (); /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks The new matrix on the top of the stack is the same as the one pushed down one level. 0 (top) 4 × 4 matrix A0 1 4 × 4 matrix A0 2 4 × 4 matrix A1 ... N +1 ... 4 × 4 matrix AN Similarly, you pop the stack using glPopMatrix (); It is essential that there are the same number of pushes and pops of the matrix stack in a display routine. /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Example: an articulated arm To show the use of matrix stacks, the program in opengl-08.c defines a simple articulated arm and allows the user to change its joint angles interactively. The display is in RGB (i.e., colour) mode. This is the default display mode, so we haven’t had to specify it until now. /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks We have introduced a reshape function to handle interactive re-sizing and re-shaping of the window, and registered it with a call to glutReshapeFunc. The reshape callback firstly sets OpenGL’s viewport to fill the window. It then sets up the projection matrix using gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far) Here, fovy is the angle of the field of view in the yz-plane, and aspect is the aspect ratio of the viewport. Only points that lie at distances that lie between near and far from the camera are drawn; others are clipped. /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks The code in the keyboard callback is used to change the shoulder and elbow rotations. The upper and lower arms can be modelled using scaled cubes; but we need modelling transformations to orient them correctly. Since the origin of the local coordinate system is originally at the centre of each cube, we need to move it to one edge for it to pivot correctly. The glTranslatef call establishes the pivot point and glRotatef performs the rotation. We then translate back to the centre of the cube and scale it before drawing it. The calls of glPushMatrix and glPopMatrix restrict the effect of the glScalef call. /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks To build a second segment, we move the local coordinate system to the second pivot point. Since the coordinate system has previously been rotated, the x-axis is already oriented along the length of the rotated arm. Hence, we can translate along the x-axis to establish the pivot point. /home/alien/environment/tex/ces- Introduction Transformation matrices Matrix stacks Nate Robins’ OpenGL tutorials A good way to get a feel for different aspects of OpenGL is to use a set of tutorials developed by Nate Robins and available from http: //www.cs.utah.edu/~narobins/opengl.html The transformation and projection tutorials are particularly useful for this lecture. There is a zip-file of compiled programs for Win32 systems which also contains complete source code. Linux users can download and unpack the same file, and compile the programs using a Makefile. /home/alien/environment/tex/ces-