OpenGL: Simple Use

advertisement
OpenGL: Simple Use
•
•
•
•
Open a window and attach OpenGL to it
Set projection parameters (e.g., field of view)
Setup lighting, if any
Main rendering loop
– Set camera pose with gluLookAt()
• Camera position specified in world coordinates
– Render polygons of model
• Simplest case: vertices of polygons in world coordinates
Creating Geometry
• All geometry composed of vertices (points)
• ‘Primitive type’ defines the shape they describe
• Example vertices: glVertex (x, y, z, w)
– glVertex2d - z coordinate is set to 0.0
– glVertex3d - w coordinate is set to 1.0
– glVertex4d - all coordinates specified (rarely done)
Primitive Types
• GL_POINTS
• GL_LINE
– {S | _STRIP | _LOOP}
• GL_TRIANGLE
– {S | _STRIP | _FAN}
• GL_QUAD
– {S | _STRIP}
• GL_POLYGON
GL_POLYGON
• List of vertices defines polygon edges
• Polygon must be convex
Non-planar Polygons
• Imagine polygon with non-planar vertices
• Some perspectives will be rendered as
concave polygons
• These concave polygons may not rasterize
correctly
Generating Primitives
• Primitive defined within glBegin() and
glEnd()
• Very few GL commands can be executed within
these two GL calls
• Any amount of computation can be performed
glBegin (GL_LINE_LOOP);
for (j=0; j<10; j++) {
angle = 2*M_PI*j/10;
glVertex2f (cos(angle), sin(angle));
}
glEnd();
OpenGL: More Examples
• Example: GL supports quadrilaterals:
glBegin(GL_QUADS);
glVertex3f(-1, 1, 0);
glVertex3f(-1, -1, 0);
glVertex3f(1, -1, 0);
glVertex3f(1, 1, 0);
glEnd();
– This type of operation is called immediate-mode
rendering; each command happens immediately
OpenGL: Front/Back Rendering
• Each polygon has two sides, front and back
• OpenGL can render the two differently
• The ordering of vertices in the list
determines which is the front side:
– When looking at the front side, the vertices go
counterclockwise
• This is basically the right-hand rule
OpenGL: Drawing Triangles
• You can draw multiple triangles between
glBegin(GL_TRIANGLES) and glEnd():
float v1[3], v2[3], v3[3], v4[3];
...
glBegin(GL_TRIANGLES);
glVertex3fv(v1); glVertex3fv(v2); glVertex3fv(v3);
glVertex3fv(v1); glVertex3fv(v3); glVertex3fv(v4);
glEnd();
• Each set of 3 vertices forms a triangle
– What do the triangles drawn above look like?
– How much redundant computation is happening?
OpenGL: Triangle Strips
• An OpenGL triangle strip primitive reduces this
redundancy by sharing vertices:
glBegin(GL_TRIANGLE_STRIP);
glVertex3fv(v0);
v0
glVertex3fv(v1);
glVertex3fv(v2);
glVertex3fv(v3);
glVertex3fv(v4);
glVertex3fv(v5);
v1
glEnd();
–
–
–
–
v2
v4
v5
v3
triangle 0 is v0, v1, v2
triangle 1 is v2, v1, v3 (why not v1, v2, v3?)
triangle 2 is v2, v3, v4
triangle 3 is v4, v3, v5 (again, not v3, v4, v5)
Polygon Rendering Options
• Rendered as points, lines, or filled
• Front and back faces can be rendered separately
using glPolygonMode( )
• glPolygonStipple( ) overlays a
MacPaint-style overlay on the polygon
• glEdgeFlag specifies polygon edges that can be
drawn in line mode
• Normal vectors: normalized is better, but
glEnable(GL_NORMALIZE) will guarantee it
Polygonalization Hints
•
•
•
•
•
Keep orientations (windings) consistent
Best to use triangles (guaranteed planar)
Keep polygon number to minimum
Put more polygons on silhouettes
Avoid T-intersections to avoid cracks
BAD
B
A
C
E
OK
A
B
D
C
• Use exact coordinates for closing loops
OpenGL: Specifying Normals
• Calling glNormal() sets the normal vector for the
following vertices, till next glNormal()
• So flat-shaded lighting requires:
glNormal3f(Nx, Ny, Nz);
glVertex3fv(v0);glVertex3fv(v1);glVertex3fv(v2);
– While smooth shading requires:
glNormal3f(N0x, N0y, N0z); glVertex3fv(v0);
glNormal3f(N1x, N1y, N1z); glVertex3fv(v1);
glNormal3f(N2x, N2y, N2z); glVertex3fv(v2);
– (Of course, lighting requires additional setup…)
OpenGL: Specifying Color
• Calling glColor() sets the color for vertices
following, until the next call to glColor()
– To produce a single aqua-colored triangle:
glColor3f(0.1, 0.5, 1.0);
glVertex3fv(v0); glVertex3fv(v1);
glVertex3fv(v2);
– To produce a Gouraud-shaded triangle:
glColor3f(1, 0, 0); glVertex3fv(v0);
glColor3f(0, 1, 0); glVertex3fv(v1);
glColor3f(0, 0, 1); glVertex3fv(v2);
– In OpenGL, colors can also have a fourth component
 (opacity)
• Generally want  = 1.0 (opaque);
OpenGL: Specifying Viewpoint
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyeX, eyeY, eyeZ,
lookX, lookY, lookZ,
upX, upY, upZ);
eye[XYZ]: camera position in world coordinates
look[XYZ]: a point centered in camera’s view
up[XYZ]: a vector defining the camera’s vertical
• Creates a matrix that transforms points in world coordinates
to camera coordinates
– Camera at origin
– Looking down -Z axis
– Up vector aligned with Y axis
Translations
• For convenience we usually describe objects in
relation to their own coordinate system
• We can translate or move points to a new position
by adding offsets to their coordinates:
 x'  x  tx 
 y '   y   ty 
     
 z '   z  tz 
– Note that this translates all points uniformly
Scaling
• Scaling a coordinate means multiplying each of its
components by a scalar
• Uniform scaling means this scalar is the same for
all components:
2
Scaling
• Non-uniform scaling: different scalars per
component:
X  2,
Y  0.5
• How can we represent this in matrix form?
Scaling
• Scaling operation:
• Or, in matrix form:
 x' ax 
 y '  by 
   
 z '   cz 
 x '   a 0 0  x 
 y'  0 b 0  y 
  
 
 z '  0 0 c   z 
scaling matrix
2-D Rotation
(x’, y’)
(x, y)

x’ = x cos() - y sin()
y’ = x sin() + y cos()
2-D Rotation
(x’, y’)
(x, y)
 f
x = r cos (f)
y = r sin (f)
x’ = r cos (f + )
y’ = r sin (f + )
Trig Identity…
x’ = r cos(f) cos() – r sin(f) sin()
y’ = r sin(f) sin() – r cos(f) cos()
Substitute…
x’ = x cos() - y sin()
y’ = x sin() + y cos()
2-D Rotation
• This is easy to capture in matrix form:
 x' cos  sin   x 
 y '   sin  cos   y 
  
 
• 3-D is more complicated
– Need to specify an axis of rotation
– Simple cases: rotation about X, Y, Z axes
3-D Rotation
• What does the 3-D rotation matrix look like
for a rotation about the Z-axis?
– Build it coordinate-by-coordinate
 x' cos()  sin( ) 0  x 
 y '   sin( ) cos() 0  y 
  
 
 z '   0
0
1  z 
3-D Rotation
• What does the 3-D rotation matrix look like
for a rotation about the Y-axis?
– Build it coordinate-by-coordinate
 x'  cos() 0 sin( )   x 
 y '   0



1
0
y
  
 
 z '   sin( ) 0 cos()  z 
3-D Rotation
• What does the 3-D rotation matrix look like
for a rotation about the X-axis?
– Build it coordinate-by-coordinate
0
0  x
 x' 1
 y '  0 cos()  sin( )  y 
  
 
 z '  0 sin( ) cos()   z 
3-D Rotation
• General rotations in 3-D require rotating
about an arbitrary axis of rotation
• Deriving the rotation matrix for such a
rotation directly is a good exercise in linear
algebra
• Standard approach: express general rotation
as composition of canonical rotations
– Rotations about X, Y, Z
Composing Canonical Rotations
• Goal: rotate about arbitrary vector A by 
– Idea: we know how to rotate about X,Y,Z
•
•
•
•
•
So, rotate about Y by  until A lies in the YZ plane
Then rotate about X by  until A coincides with +Z
Then rotate about Z by 
Then reverse the rotation about X (by -)
Then reverse the rotation about Y (by -)
Composing Canonical Rotations
• First: rotating about Y by  until A lies in YZ
• How exactly do we calculate ?
– Project A onto XZ plane (Throw away y-coordinate)
– Find angle  to X:
 = -(90° - ) =  - 90 °
• Second: rotating about X by  until A lies on Z
• How do we calculate ?
Composing Canonical Rotations
• Why are we slogging through all this
tedium?
• A: Because you’ll have to do it on the test
3-D Rotation Matrices
• So an arbitrary rotation about A composites
several canonical rotations together
• We can express each rotation as a matrix
• Compositing transforms == multiplying matrices
• Thus we can express the final rotation as the
product of canonical rotation matrices
• Thus we can express the final rotation with a
single matrix!
Compositing Matrices
• So we have the following matrices:
p: The point to be rotated about A by 
Ry : Rotate about Y by 
Rx  : Rotate about X by 
Rz : Rotate about Z by 
Rx  -1: Undo rotation about X by 
Ry-1 : Undo rotation about Y by 
• In what order should we multiply them?
Compositing Matrices
• Short answer: the transformations, in order,
are written from right to left
– In other words, the first matrix to affect the
vector goes next to the vector, the second next
to the first, etc.
• So in our case:
p’ = Ry-1 Rx  -1 Rz Rx  Ry p
Rotation Matrices
• Notice these two matrices:
Rx  : Rotate about X by 
Rx  -1: Undo rotation about X by 
• How can we calculate Rx  -1?
Rotation Matrices
• Notice these two matrices:
Rx  : Rotate about X by 
Rx  -1: Undo rotation about X by 
• How can we calculate Rx  -1?
– Obvious answer: calculate Rx (-)
– Clever answer: exploit fact that rotation
matrices are orthonormal
Rotation Matrices
• Notice these two matrices:
Rx  : Rotate about X by 
Rx  -1: Undo rotation about X by 
• How can we calculate Rx  -1?
– Obvious answer: calculate Rx (-)
– Clever answer: exploit fact that rotation matrices are
orthonormal
• What is an orthonormal matrix?
• What property are we talking about?
Rotation Matrices
• Orthonormal matrix:
– orthogonal (columns/rows linearly
independent)
– normalized (columns/rows length of 1)
• The inverse of an orthogonal matrix is just
its transpose:
a b
d e

 h i
1
c
a b
f   d e
 h i
j 
T
c
a
f   b
 c
j 
d
e
f
h
i 
j 
Modeling Transformations
• glTranslate (x, y, z)
– Multiplies the current matrix by a matrix that
moves the object by the given x-, y-, and zvalues
• glRotate (theta, x, y, z)
– Multiplies the current matrix by a matrix that
rotates the object in a counterclockwise
direction about the ray from the origin through
the point (x, y, z)
Modeling Transformations
• glScale (x, y, z)
– Multiplies the current matrix by a matrix that
stretches, shrinks, or reflects an object along the
axes.
Matrix Multiplcations
• Certain commands affect the current matrix in
OpenGL
– glMatrixMode() sets the current matrix
– glLoadIdentity() replaces the current matrix
with an identity matrix
– glTranslate() postmultiplies the current matrix
with a translation matrix
– gluPerspective() postmultiplies the current
matrix with a perspective projection matrix
• It is important that you understand the order in
which OpenGL concatenates matrices
Matrix Operations In OpenGL
• In OpenGL:
– Vertices are multiplied by the MODELVIEW matrix
– The resulting vertices are multiplied by the projection
matrix
• Example:
– Suppose you want to scale an object, translate it, apply
a lookat transformation, and view it under perspective
projection. What order should you make calls?
Matrix Operations in OpenGL
• Problem: scale an object, translate it, apply a lookat
transformation, and view it under perspective
• A correct code fragment:
glMatrixMode(GL_PERSPECTIVE);
glLoadIdentity();
gluPerspective(…);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(…);
glTranslate(…);
glScale(…);
/* Draw the object... */
Matrix Operations in OpenGL
• Problem: scale an object, translate it, apply a lookat
transformation, and view it under perspective
• An incorrect code fragment:
glMatrixMode(GL_PERSPECTIVE);
glLoadIdentity();
glTranslate(…);
glScale(…);
gluPerspective(…);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(…);
/* Draw the object... */
Multiplication Order
glMatrixMode (MODELVIEW);
glLoadIdentity();
glMultMatrix(N); Modelview matrix successively contains:
glMultMatrix(M);
I(dentity), N, NM, NML
glMultMatrix(L);
glBegin(POINTS); The transformed vertex is:
NMLv = N(M(Lv))
glVertex3f(v);
glEnd();
Multiplication Order
• Rotate line segment by 45 degrees about endpoint
Wrong
R(45)
Right
T(-3), R(45), T(3)
OpenGL
T(3)
R(45)
T(-3)
Manipulating Matrix Stacks
• Observation: Certain model transformations are
shared among many models
• We want to avoid continuously reloading the same
sequence of transformations
• glPushMatrix ( )
– push all matrices in current stack down one level and
copy topmost matrix of stack
• glPopMatrix ( )
– pop the top matrix off the stack
Matrix Manipulation - Example
• Drawing a car with wheels and lugnuts
draw_wheel( );
for (j=0; j<5; j++) {
glPushMatrix ();
glRotatef(72.0*j, 0.0, 0.0, 1.0);
glTranslatef (3.0, 0.0, 0.0);
draw_bolt ( );
glPopMatrix ( );
Download