Hidden surfaces provide occlusion depth cue
Many different algorithms developed over the years
Rendering a polygon means filling pixels
Color buffer contains RGB color of each pixel drawn
Depth buffer contains depth of each pixel drawn
Color | Depth |
---|---|
When drawing a new pixel, compare new depth to what's stored in depth buffer
Color | Depth |
---|---|
Polygons can be drawn in any order
Polygons can intersect
Space must be allocated for the depth buffer:
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH)
Depth buffering must be enabled:
glEnable(GL_DEPTH_TEST)
Depth buffer must be cleared each frame:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
Depth values have limited resolution
i.e. the numbers are not infinitely precise
Rounding errors occur when polygons are filled
Polygon overlap can cause "depth-fighting"
Perspective effects are created by a perspective projection transformation
Perspective + movement also yields motion parallax
Orthographic projection : projects rectilinear box onto display
Objects will not appear to change size with distance
Perspective projection : projects frustum (truncated pyramid) onto
display
Near objects appear larger, distant objects appear smaller
GL's perspective projection is a pin-hole camera, located at the origin, looking down the -Z axis
Camera has a field-of-view - angle representing (horizontal) extent of region viewed
Small angle = narrow field-of-view = telephoto lens
Large angle = wide field-of-view = wide-angle lens
gluPerspective( fovy, aspect, zNear, zFar )
fovy = field of view, in Y direction, in degrees
aspect = aspect ratio (X:Y) of window
zNear = distance to near clipping plane
zFar = distance to far clipping plane
The "eye-point" of the perspective projection is at (0,0,0)
Example:
glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45, 1.333, 0.1, 100) glMatrixMode(GL_MODELVIEW)
The OpenGL camera is always positioned at the origin, looking down the -Z axis.
The camera itself never moves.
Looking at the final image produced, moving a camera is equivalent to moving the world in the opposite direction.
e.g. moving everything to the right is will produce the same image as moving the camera to the left.
To give the effect of moving the perspective viewpoint in OpenGL, use a transformation at the beginning of the frame, which affects all objects.
For example, to move the camera 10 units from the origin
in the +Z direction, translate the world by -10 in Z:
def draw(): glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(fovy, 1, 0.1, 100) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glTranslatef(0, 0, -10) drawObjects()
For general camera movement:
def draw(): global cameraX, cameraY, cameraZ global cameraHeading glLoadIdentity() glRotatef(-cameraHeading, 0, 1, 0) glTranslatef(-cameraX, -cameraY, -cameraZ) drawObjects()
Inverse of glTranslatef(x, y, z) is glTranslatef(-x, -y, -z)
Inverse of glRotatef(angle, x, y, z) is glRotatef(-angle, x, y, z)
Inverse of glScalef(x, y, z) is glScalef(1.0/x, 1.0/y, 1.0/z)
Inverse of a series of transformations is the inverses of the individual transformations, in reverse order.
Alternative method of camera control
gluLookAt computes and applies an appropriate translation & rotation
gluLookAt(cameraX, cameraY, cameraZ, lookX, lookY, lookZ, upX, upY, upZ)
cameraX, cameraY, cameraZ is camera location - point to look from
lookX, lookY, lookZ is point to look at
upX, upY, upZ is "up-direction" for the camera - affects camera roll