4-Using Transformations in OpenGL
4-Using Transformations in OpenGL
10/14/2013 1
Transformations in OpenGL
• Modelling
• Viewing
– orient camera
– projection
• Animation
• Map to screen
10/14/2013 2
Camera Analogy
• 3D is just like taking a photograph (lots of
photographs!)
viewing
volume
camera
model
tripod
10/14/2013 3
Camera Analogy and Transformations
• Viewing transformations
– tripod–define position and
orientation of the viewing
volume in the world
• Modeling transformations
– moving the model
• Projection transformations
– adjust the lens of the camera
• Viewport transformations
– enlarge or reduce the
physical photograph
10/14/2013 4
Coordinate Systems and Transformations
• Steps in forming an image
– Specify geometry (world coordinates)
– Specify camera (camera coordinates)
– Project (window coordinates)
– Map to viewport (screen coordinates)
• Each step uses transformations
• Every transformation is equivalent to a change
in coordinate systems (frames)
10/14/2013 5
Homogeneous Coordinates
• Each vertex has an extra value, w
10/14/2013 6
Homogeneous Coordinates
• If a is nonzero, then (x, y, z, w) T and (ax, ay, az,
aw)T represent the same homogeneous vertex
• A 3D Euclidean space point (x, y, z) T becomes
the homogeneous vertex (x, y, z, 1.0) T
• As w is nonzero, the homogeneous vertex (x, y,
z, w)T corresponds to the 3D point (x/w, y/w,
z/w)T
• Directions (directed line segments) can be
represented with w = 0.0
10/14/2013 7
Homogeneous Visualization
• Divide by w to normalize (homogenize)
• W = 0? Point at infinity (direction)
(0, 0, 1) = (0, 0, 2) = … w= 1
(7, 1, 1) = (14, 2, 2) = …
w= 2
(4, 5, 1) = (8, 10, 2) = …
10/14/2013 8
Vertex transformations
• Vertex transformations and projections can all be
represented by applying an appropriate 4 x 4 matrix to
the vertex coordinates.
• All affine operations are matrix multiplications
• All matrices are stored column-major in OpenGL
• Matrices are always post-multiplied
• Product of matrix and vector is
=
10/14/2013 9
Specifying Transformations
• Programmer has two styles of specifying
transformations
1. Specify matrices
– glLoadMatrix(), glMultMatrix()
2. Specify operation
– glRotate(), glTranslate(), glScale(),
glOrtho()
– Programmer does not have to remember the exact
matrices
10/14/2013 10
Programming Transformations
• Prior to rendering, view, locate, and orient:
– Eye / camera position
– 3D geometry
• Manage the matrices
– Including matrix stack
• Combine (composite) transformations
10/14/2013 11
Transformation Pipeline
normalized
object eye clip window
device
v
e
r Modelview Projection Perspective Viewport
t
e Matrix Matrix Division Transform
x
Modelview Projection
Modelview • other calculations here
l
– material color
l
l
– shade model (flat)
– polygon rendering mode
– polygon culling
– clipping
10/14/2013 12
Matrix Operations
• Specify Current Matrix Stack
– glMatrixMode(GL_MODELVIEW or
GL_PROJECTION)
• Other Matrix or Stack Operations
– glLoadIdentity(), glPushMatrix(),
glPopMatrix()
• Viewport
– usually same as window size
– viewport aspect ratio should be same as projection
transformation or resulting image may be distorted
– glViewport(x, y, width, height)
10/14/2013 13
Viewing Transformations
10/14/2013 14
Viewing Transformations
• Position the camera/eye in
the scene
– place the tripod down; aim
camera
• To "fly through" a scene
– change viewing
transformation and
redraw scene
10/14/2013 15
Using gluLookAt()
• gluLookAt(eyex, eyey, eyez,
aimx, aimy, aimz,
upx, upy, upz)
– up vector determines unique orientation
– careful of degenerate positions
10/14/2013 16
Default View
• In the default position
– the camera is at
the origin,
– looking down
the negative z-axis,
– and has the positive
y-axis as straight up.
• This is the same as calling
gluLookAt(0.0, 0.0, 0.0,
0.0, 0.0, -100.0,
0.0, 1.0, 0.0);
10/14/2013 17
Using gluLookAt()
• gluLookAt(4.0, 2.0, 1.0,
2.0, 4.0, -3.0,
2.0, 2.0, -1.0);
10/14/2013 18
Projection Tutorial
10/14/2013 19
Modeling Transformations
10/14/2013 20
Modeling Transformations
• Move object
– glTranslate{fd}(x, y, z)
• Dilate (stretch or shrink) or mirror object
– glScale{fd}(x, y, z) x y z
• Rotate object around arbitrary axis
– glRotate{fd}(angle, x, y, z)
– angle is in degrees
10/14/2013 21
Translation Transformation
• The call glTranslate*(x, y, z) generates T, where
T=
10/14/2013 22
Scale Transformation
• glScale*(x, y, z) generates S =
10/14/2013 23
Rotation Transformation
• The glRotate*() command generates a
matrix for rotation about an arbitrary axis.
• Rotating about the Oz axis
glRotate*(a, 0, 0, 1)
10/14/2013 24
Rotation Transformation
• Rotating about the Ox axis
glRotate*(a, 1, 0, 0):
• Rotating about the Oy axis
glRotate*(a, 0, 1, 0):
10/14/2013 25
General rotations
• The call glRotate*(a, x, y, z) generates R as
follows:
– Let v = (x, y, z)T, and u = v/||v|| = (x’, y’, z’)T.
– Also let S =
10/14/2013 26
Rodrigues Formula
• About (kx, ky, kz), a unit
vector on an arbitrary axis
c = cos , s = sin
10/14/2013 27
Bài tập
• Xác định ma trận của phép quay
glRotatef(30.0f, 1.0f, 1.0f, 0.0f)
10/14/2013 28
Order of transformations
• In general not commutative: order matters!
10/14/2013 30
Non-commutative Composition
• Scale then Translate: p' = T(Sp) = TSp
TS =
10/14/2013 31
Transformation Tutorial
10/14/2013 32
Compositing Modeling Transformations
• Problem 1: hierarchical objects
– One position depends upon a previous position
– Robot arm or hand; sub-assemblies
10/14/2013 33
Hierarchical Scene Graph
Drawing a Scene Graph
• Draw scene with pre-and-post-order traversal
– Apply node, draw children, undo node if applicable
• Nodes can carry out any function
– Geometry, transforms, groups, color, …
• Requires stack to “undo” post children
– Transform stacks in OpenGL
• Caching and instancing possible
• Instances make it a DAG, not strictly a tree
Example
/* draw sun */
glut.glutWireSphere(1.0, 20, 16);
/* draw smaller planet */
glRotatef((float) year, 0.0f, 1.0f, 0.0f);
glTranslatef(2.0f, 0.0f, 0.0f);
glRotatef((float) day, 0.0f, 1.0f, 0.0f);
glut.glutWireSphere(0.2, 10, 10);
10/14/2013 36
Compositing Modeling Transformations
• Problem 2: objects move relative to absolute world
origin
– My object rotates around the wrong origin
• Make it spin around its center or something else
• Solution: fixed coordinate system
– modeling transformations move objects around fixed
coordinate system
– pre-multiply column-major matrices
– OpenGL post-multiplies matrices
– must reverse order of operations to achieve desired effect
10/14/2013 37
Example: object spin around its center
• You’ll adjust to reading a lot of code backwards!
• Typical sequence
glTranslatef(x, y, z);
glRotatef(theta, ax, ay, az);
glTranslatef(-x, -y, -z);
dwawObject();
• Here (x, y, z) is the fixed point.
– first move it to the origin (last transformation in code)
– Then rotate about the axis (ax, ay, az)
– And finally move fixed point back.
10/14/2013 38
Connection: Viewing and Modeling
10/14/2013 39
Connection: Viewing and Modeling
• Moving camera is equivalent to moving every
object in the world towards a stationary camera
• Viewing transformations are equivalent to
several modeling transformations
– View tranformation matrix E places the camera within
the scene
– Then we apply E-1 to
all points in the world
– Move the eye (camera)
by updating E
10/14/2013 40
OpenGL Viewing Code
• In OpenGL, we can use the built-in transformation
calls to specify the viewing transformation
• The camera is positioned in the scene with
translation by [vTx, vTy, vTz] and rotation about
the X, Y, and Z axis:
void setupView() {
// Inverse viewing transformation
glRotatef(-vAngleZ, 0.0, 0.0, 1.0);
glRotatef(-vAngleY, 0.0, 1.0, 0.0);
glRotatef(-vAngleX, 1.0, 0.0, 0.0);
glTranslatef(-vTx, -vTy, -vTz);
}
10/14/2013 41
Constructing a Frame
gluLookAt(eyex, eyey, eyez,
aimx, aimy, aimz,
upx, upy, upz)
10/14/2013 42
Rotation
• Rotation takes the unit world to our desired
camera:
10/14/2013 43
Translation
• Translation to the eye point:
10/14/2013 44
Composing the Result
• The final camera transformation is:
E = TR =
10/14/2013 45
The Viewing Transformation
• Transforming all points P in the world with E -1:
V = R-1T-1 =
• Where these are normalized vectors
a = Peye – Paim
r = up x a
u=axr
10/14/2013 46
Projection Transformation
10/14/2013 47
Projection Transformation
• To lower dimensional space (here 3D -> 2D)
– Preserve straight lines
• Shape of viewing frustum
• Perspective projection
• Orthographic parallel projection
10/14/2013 48
Demo
10/14/2013 49
Orthographic projection
• The viewing volume is a rectangular parallelepiped.
• Vertexes of an object are "projected" towards infinity.
• Distance from the camera doesn’t affect how large
an object appears
Example: Simply
project onto xy
plane, drop z
coordinate
10/14/2013 50
Orthographic projection
• Specify the orthographic viewing frustum by
– specifying minimum and maximum x, y coordinates
– Indicating range of distances along the z-axis by
specifying near and far planes
10/14/2013 51
Orthographic Projections matrix
• Here is the orthographic world-to-clip
transformation:
10/14/2013 52
Orthographic Projection in OpenGL
• This matrix is constructed with
the following OpenGL call:
glOrtho(left, right, bottom, top, zNear,
zFar)
• And the 2D version (another GL utility function):
gluOrtho2D(left, right, bottom, top)
– Just a call to glOrtho() with zNear = -1 and zFar = +1
• Usually, the following code is
part of the initialization routine:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(left, right, bottom, top, near, far);
glMatrixMode(GL_MODELVIEW);
10/14/2013
… 53
Perspective Projections
• Artists (Donatello, Brunelleschi, and Da Vinci)
during the renaissance discovered the
importance of perspective for making images
appear realistic
• Parallel lines intersect at a point
10/14/2013 54
Perspective projection
• Characteristic of perspective projection is
foreshortening:
– The farther an object is from the camera, the smaller
it appears in the final image
10/14/2013 55
Perspective projection
glFrustum(left, right, bottom, top,
zNear, zFar)
10/14/2013 56
Perspective projection
gluPerspective(fovy, aspect, zNear, zFar)
– fovy = vertical field of view in degrees
– aspect = image width / height at near depth
– Can only specify symmetric viewing frustums where the
viewing window is centered around the –z axis.
10/14/2013 57
OpenGL Perspective Matrix
• Mapping the perspective viewing frustum in OpenGL
to clip space involves some affine transformations
• OpenGL uses a clever composition of these
transformations with the perspective projection
matrix:
10/14/2013 58
Viewport Transformation
10/14/2013 59
Viewport Transformation
10/14/2013 61
Common Transformation Usage
• 3 examples of reshape() routine
– restate projection & viewing transformations
• Usually called when window resized
10/14/2013 62
reshape(): Perspective & LookAt
public void reshape(GLAutoDrawable drawable,
int x, int y, int width, int height) {
GL2 gl = drawable.getGL().getGL2();
if (height == 0) height = 1; // prevent divide by zero
float aspect = (float) width / height;
0.0);
reshape(): Perspective & Translate
• Same effect as previous LookAt
public void reshape(GLAutoDrawable drawable,
int x, int y, int width, int height) {
GL2 gl = drawable.getGL().getGL2();
if (height == 0) height = 1; // prevent divide by zero
float aspect = (float) width / height;
gl.glMatrixMode(GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0, aspect, 0.1, 100.0);
gl.glMatrixMode(GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0.0, 0.0, -5.0);
}
10/14/2013 64
reshape(): Ortho
public void reshape(GLAutoDrawable drawable,
int x, int y, int width, int height) {
GL2 gl = drawable.getGL().getGL2();
double aspect = (double) width / height;
double left = -2.5, right = 2.5;
double bottom = -2.5, top = 2.5;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL_PROJECTION);
gl.glLoadIdentity();
if (aspect < 1.0) {
left *= aspect; right *= aspect;
} else {
bottom /= aspect; top /= aspect;
}
gl.glOrtho(left, right, bottom, top, near, far);
gl.glMatrixMode(GL_MODELVIEW);
gl.glLoadIdentity();
}
10/14/2013 65
Additional Clipping Planes
• At least 6 more clipping planes available
• Good for cross-sections
• Modelview matrix moves clipping plane
clipped
– glEnable(GL_CLIP_PLANEi)
– glClipPlane(GL_CLIP_PLANEi, Gldouble[]
coeff)
Ax + By + Cz + D < 0
10/14/2013 66
Reversing Coordinate Projection
• Screen space back to world space
glGetIntegerv(GL_VIEWPORT, int viewport[4])
glGetDoublev(GL_MODELVIEW_MATRIX,
double mvmatrix[16])
glGetDoublev(GL_PROJECTION_MATRIX,
double projmatrix[16])
gluUnProject(GLdouble winx, winy, winz,
mvmatrix[16], projmatrix[16],
int viewport[4],
double[] objx, double[] objy,
double[] objz)
• gluProject goes from world to screen space
10/14/2013 67