@ Definitive Opengl
@ Definitive Opengl
An Interactive Introduction to
OpenGL Programming
Dave Shreiner
Ed Angel
Vicki Shreiner
1
An Interactive Introduction to OpenGL Programming
This course provides a general introduction and overview to the OpenGL API
(Application Programming Interface) and its features. OpenGL is a rendering
library available on almost any computer which supports a graphics monitor.
Today, we’ll discuss the basic elements of OpenGL: rendering points, lines,
polygons and images, as well as more advanced features as lighting and texture
mapping.
2
An Interactive Introduction to OpenGL Programming
3
An Interactive Introduction to OpenGL Programming
4
An Interactive Introduction to OpenGL Programming
5
An Interactive Introduction to OpenGL Programming
What Is OpenGL?
Graphics rendering API
• high-quality color images composed of geometric
and image primitives
• window system independent
• operating system independent
OpenGL is a library for doing computer graphics. By using it, you can create
interactive applications which render high-quality color images composed of
3D geometric objects and images.
OpenGL is window and operating system independent. As such, the part of your
application which does rendering is platform independent. However, in order
for OpenGL to be able to render, it needs a window to draw into. Generally,
this is controlled by the windowing system on whatever platform you’re
working on.
6
An Interactive Introduction to OpenGL Programming
OpenGL Architecture
Per Vertex
Polynomial Operations &
Evaluator Primitive
Assembly
Texture
Memory
Pixel
Operations
This is the most important diagram you will see today, representing the flow of
graphical information, as it is processed from CPU to the frame buffer.
There are two pipelines of data flow. The upper pipeline is for geometric,
vertex-based primitives. The lower pipeline is for pixel-based, image
primitives. Texturing combines the two types of primitives together.
There is a pull-out poster in the back of the OpenGL Reference Manual (“Blue
Book”), which shows this diagram in more detail.
7
An Interactive Introduction to OpenGL Programming
OpenGL as a Renderer
Geometric primitives
• points, lines and polygons
Image Primitives
• images and bitmaps
• separate pipeline for images and geometry
• linked through texture mapping
Rendering depends on state
• colors, materials, light sources, etc.
8
An Interactive Introduction to OpenGL Programming
Related APIs
AGL, GLX, WGL
• glue between OpenGL and windowing systems
GLU (OpenGL Utility Library)
• part of OpenGL
• NURBS, tessellators, quadric shapes, etc.
GLUT (OpenGL Utility Toolkit)
• portable windowing API
• not officially part of OpenGL
9
An Interactive Introduction to OpenGL Programming
application program
OpenGL Motif
widget or similar GLUT
GLX, AGL
or WGL GLU
10
The above diagram illustrates the relationships of the various libraries and
window system components.
Generally, applications which require more user interface support will use a
library designed to support those types of features (i.e. buttons, menu and scroll
bars, etc.) such as Motif or the Win32 API.
Prototype applications, or ones that don’t require all the bells and whistles of a
full GUI, may choose to use GLUT instead because of its simplified
programming model and window system independence.
10
An Interactive Introduction to OpenGL Programming
Preliminaries
Header Files
• #include <GL/gl.h>
• #include <GL/glu.h>
• #include <GL/glut.h>
Libraries
Enumerated Types
• OpenGL defines numerous types for compatibility
– GLfloat, GLint, GLenum, etc.
11
11
An Interactive Introduction to OpenGL Programming
GLUT Basics
Application Structure
• Configure and open window
• Initialize OpenGL state
• Register input callback functions
• render
• resize
• input: keyboard, mouse, etc.
• Enter event processing loop
12
Here’s the basic structure that we’ll be using in our applications. This is
generally what you’d do in your own OpenGL applications.
The steps are:
1) Choose the type of window that you need for your application and initialize
it.
2) Initialize any OpenGL state that you don’t need to change every frame of
your program. This might include things like the background color, light
positions and texture maps.
3) Register the callback functions that you’ll need. Callbacks are routines you
write that GLUT calls when a certain sequence of events occurs, like the
window needing to be refreshed, or the user moving the mouse. The most
important callback function is the one to render your scene, which we’ll discuss
in a few slides.
4) Enter the main event processing loop. This is where your application
receives events, and schedules when callback functions are called.
12
An Interactive Introduction to OpenGL Programming
Sample Program
void main( int argc, char** argv )
{
int mode = GLUT_RGB|GLUT_DOUBLE;
glutInitDisplayMode( mode );
glutCreateWindow( argv[0] );
init();
glutDisplayFunc( display );
glutReshapeFunc( resize );
glutKeyboardFunc( key );
glutIdleFunc( idle );
glutMainLoop();
}
13
13
An Interactive Introduction to OpenGL Programming
OpenGL Initialization
Set up whatever state you’re going to use
void init( void )
{
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glClearDepth( 1.0 );
glEnable( GL_LIGHT0 );
glEnable( GL_LIGHTING );
glEnable( GL_DEPTH_TEST );
}
14
Here’s the internals of our initialization routine, init(). Over the course of
the day, you’ll learn what each of the above OpenGL calls do.
14
An Interactive Introduction to OpenGL Programming
15
Rendering Callback
Do all of your drawing here
glutDisplayFunc( display );
void display( void )
{
glClear( GL_COLOR_BUFFER_BIT );
glBegin( GL_TRIANGLE_STRIP );
glVertex3fv( v[0] );
glVertex3fv( v[1] );
glVertex3fv( v[2] );
glVertex3fv( v[3] );
glEnd();
glutSwapBuffers();
}
16
16
An Interactive Introduction to OpenGL Programming
Idle Callbacks
Use for animation and continuous update
glutIdleFunc( idle );
void idle( void )
{
t += dt;
glutPostRedisplay();
}
17
17
An Interactive Introduction to OpenGL Programming
Above is a simple example of a user input callback. In this case, the routine was
registered to receive keyboard input. GLUT supports user input through a
number of devices including the keyboard, mouse, dial and button boxes and
spaceballs.
18
An Interactive Introduction to OpenGL Programming
Elementary Rendering
19
19
An Interactive Introduction to OpenGL Programming
Elementary Rendering
Geometric Primitives
Managing OpenGL State
OpenGL Buffers
20
In this section, we’ll be discussing the basic geometric primitives that OpenGL
uses for rendering, as well as how to manage the OpenGL state which controls
the appearance of those primitives.
OpenGL also supports the rendering of bitmaps and images, which is discussed
in a later section.
Additionally, we’ll discuss the different types of OpenGL buffers, and what
each can be used for.
20
An Interactive Introduction to OpenGL Programming
GL_TRIANGLES
GL_QUADS
GL_TRIANGLE_FAN
GL_QUAD_STRIP GL_TRIANGLE_STRIP
21
21
An Interactive Introduction to OpenGL Programming
Simple Example
void drawRhombus( GLfloat color[] )
{
glBegin( GL_QUADS );
glColor3fv( color );
glVertex2f( 0.0, 0.0 );
glVertex2f( 1.0, 0.0 );
glVertex2f( 1.5, 1.118 );
glVertex2f( 0.5, 1.118 );
glEnd();
}
22
22
An Interactive Introduction to OpenGL Programming
glVertex3fv( v )
23
The OpenGL API calls are designed to accept almost any basic data type, which
is reflected in the calls name. Knowing how the calls are structured makes it
easy to determine which call should be used for a particular data format and
size.
For instance, vertices from most commercial models are stored as three
component floating point vectors. As such, the appropriate OpenGL command
to use is glVertex3fv( coords ).
As mentioned before, OpenGL uses homogenous coordinates to specify
vertices. For glVertex*() calls which don’t specify all the coordinates
( i.e. glVertex2f()), OpenGL will default z = 0.0, and w = 1.0 .
23
An Interactive Introduction to OpenGL Programming
24
OpenGL organizes vertices into primitives based upon which type is passed into
glBegin(). The possible types are:
GL_POINTS GL_LINE_STRIP
GL_LINES GL_LINE_LOOP
GL_POLYGON GL_TRIANGLE_STRIP
GL_TRIANGLES GL_TRIANGLE_FAN
GL_QUADS GL_QUAD_STRIP
24
An Interactive Introduction to OpenGL Programming
Models CPU DL
Pixel
Texture
Raster Frag FB
RGBA mode
25
25
An Interactive Introduction to OpenGL Programming
Shapes Tutorial
26
This is the first of the series of Nate Robins’ tutorials. This tutorial illustrates
the principles of rendering geometry, specifying both colors and vertices.
The shapes tutorial has two views: a screen-space window and a command
manipulation window.
In the command manipulation window, pressing the LEFT mouse while the
pointer is over the green parameter numbers allows you to move the mouse in
the y-direction (up and down) and change their values. With this action, you can
change the appearance of the geometric primitive in the other window. With the
RIGHT mouse button, you can bring up a pop-up menu to change the primitive
you are rendering. (Note that the parameters have minimum and maximum
values in the tutorials, sometimes to prevent you from wandering too far. In an
application, you probably don’t want to have floating-point color values less
than 0.0 or greater than 1.0, but you are likely to want to position vertices at
coordinates outside the boundaries of this tutorial.)
In the screen-space window, the RIGHT mouse button brings up a different
pop-up menu, which has menu choices to change the appearance of the
geometry in different ways.
The left and right mouse buttons will do similar operations in the other tutorials.
26
An Interactive Introduction to OpenGL Programming
Controlling Rendering
Appearance
From Wireframe to Texture Mapped
27
27
An Interactive Introduction to OpenGL Programming
28
Each time OpenGL processes a vertex, it uses data stored in its internal state
tables to determine how the vertex should be transformed, lit, textured or any of
OpenGL’s other modes.
28
An Interactive Introduction to OpenGL Programming
29
The general flow of any OpenGL rendering is to set up the required state, then
pass the primitive to be rendered, and repeat for the next primitive.
In general, the most common way to manipulate OpenGL state is by setting
vertex attributes, which include color, lighting normals, and texturing
coordinates.
29
An Interactive Introduction to OpenGL Programming
30
Setting OpenGL state usually includes modifying the rendering attribute, such
as loading a texture map, or setting the line width. Also for some state changes,
setting the OpenGL state also enables that feature ( like setting the point size or
line width ).
Other features need to be turned on. This is done using glEnable(), and
passing the token for the feature, like GL_LIGHT0 or
GL_POLYGON_STIPPLE.
30
An Interactive Introduction to OpenGL Programming
Transformations
31
31
An Interactive Introduction to OpenGL Programming
Transformations in OpenGL
Modeling
Viewing
• orient camera
• projection
Animation
Map to screen
32
32
An Interactive Introduction to OpenGL Programming
Camera Analogy
3D is just like taking a photograph (lots of
photographs!)
viewing
volume
camera
model
tripod
33
33
An Interactive Introduction to OpenGL Programming
Viewing transformations
• tripod–define position and orientation of the viewing volume
in the world
Modeling transformations
• moving the model
Viewport transformations
• enlarge or reduce the physical photograph
34
Note that human vision and a camera lens have cone-shaped viewing volumes.
OpenGL (and almost all computer graphics APIs) describe a pyramid-shaped
viewing volume. Therefore, the computer will “see” differently from the natural
viewpoints, especially along the edges of viewing volumes. This is particularly
pronounced for wide-angle “fish-eye” camera lenses.
34
An Interactive Introduction to OpenGL Programming
35
35
An Interactive Introduction to OpenGL Programming
Affine Transformations
Want transformations which preserve
geometry
• lines, polygons, quadrics
Affine = line preserving
• Rotation, translation, scaling
• Projection
• Concatenation (composition)
36
36
An Interactive Introduction to OpenGL Programming
Homogeneous Coordinates
• each vertex is a column vector
x
r y
v =
z
• w is usually 1.0 w
• all operations are matrix multiplications
• directions (directed line segments) can be represented with
w = 0.0
37
37
An Interactive Introduction to OpenGL Programming
3D Transformations
A vertex is transformed by 4 x 4 matrices
• all affine operations are matrix multiplications
• all matrices are stored column-major in OpenGL
• matrices are always post-multiplied
v
• product of matrix and vector is M v
m0 m4 m8 m12
m m5 m9 m13
M= 1
m2 m6 m10 m14
m3 m7 m11 m15
38
38
An Interactive Introduction to OpenGL Programming
Specifying Transformations
Programmer has two styles of specifying
transformations
• specify matrices (glLoadMatrix, glMultMatrix)
• specify operation (glRotate, glOrtho)
Programmer does not have to remember the
exact matrices
• check appendix of Red Book (Programming Guide)
39
39
An Interactive Introduction to OpenGL Programming
Programming Transformations
Prior to rendering, view, locate, and orient:
• eye/camera position
• 3D geometry
Manage the matrices
• including matrix stack
Combine (composite) transformations
40
Because transformation matrices are part of the state, they must be defined prior
to any vertices to which they are to apply.
In modeling, we often have objects specified in their own coordinate systems
and must use OpenGL transformations to bring the objects into the scene.
OpenGL provides matrix stacks for each type of supported matrix (ModelView,
projection, texture) to store matrices.
40
An Interactive Introduction to OpenGL Programming
Transformation Poly.
Per
Vertex
Pipeline CPU DL
Pixel
Texture
Raster Frag FB
41
An Interactive Introduction to OpenGL Programming
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 )
42
glLoadMatrix*() replaces the matrix on the top of the current matrix stack.
glMultMatrix*(), post-multiples the matrix on the top of the current matrix
stack. The matrix argument is a column-major 4 x 4 double or single precision
floating point matrix.
Matrix stacks are used because it is more efficient to save and restore matrices
than to calculate and multiply new matrices. Popping a matrix stack can be said
to “jump back” to a previous location or orientation.
glViewport() clips the vertex or raster position. For geometric primitives, a
new vertex may be created. For raster primitives, the raster position is
completely clipped.
There is a per-fragment operation, the scissor test, which works in situations
where viewport clipping doesn’t. The scissor operation is particularly good for
fine clipping raster (bitmap or image) primitives.
42
An Interactive Introduction to OpenGL Programming
Projection Transformation
Shape of viewing frustum
Perspective projection
gluPerspective( fovy, aspect, zNear, zFar )
glFrustum( left, right, bottom, top, zNear, zFar )
43
An Interactive Introduction to OpenGL Programming
Applying Projection
Transformations
Typical use (orthographic projection)
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, zNear, zFar );
44
44
An Interactive Introduction to OpenGL Programming
Viewing Transformations
45
45
An Interactive Introduction to OpenGL Programming
Projection Tutorial
46
The RIGHT mouse button controls different menus. The screen-space view
menu allows you to choose different models. The command-manipulation menu
allows you to select different projection commands (including glOrtho and
glFrustum).
46
An Interactive Introduction to OpenGL Programming
Modeling Transformations
Move object
glTranslate{fd}( x, y, z )
Rotate object around arbitrary axis (x y z)
glRotate{fd}( angle, x, y, z )
• angle is in degrees
Dilate (stretch or shrink) or mirror object
glScale{fd}( x, y, z )
47
47
An Interactive Introduction to OpenGL Programming
Transformation Tutorial
48
For right now, concentrate on changing the effect of one command at a time.
After each time that you change one command, you may want to reset the
values before continuing on to the next command.
The RIGHT mouse button controls different menus. The screen-space view
menu allows you to choose different models. The command-manipulation menu
allows you to change the order of the glTranslatef() and
glRotatef() commands. Later, we will see the effect of changing the order
of modeling commands.
48
An Interactive Introduction to OpenGL Programming
Modeling
49
49
An Interactive Introduction to OpenGL Programming
If you get this wrong, you may see nothing in your image. Switching from right
to left handed coordinates is equivalent to rotating the camera 180 degrees!
One way to think of problem is that the viewing system is left-handed so
distances from the camera are measured from the camera to the object.
50
An Interactive Introduction to OpenGL Programming
51
Example: Suppose the user resizes the window. Do we see the same objects?
What if the new aspect ratio is different from the original? Can we avoid
distortion of objects?
What we should do is application dependent. Hence users should write their
own reshape callbacks.
Typical reshape callbacks alter the projection matrix or the viewport.
51
An Interactive Introduction to OpenGL Programming
52
Using the viewport width and height as the aspect ratio for gluPerspective
eliminates distortion.
52
An Interactive Introduction to OpenGL Programming
53
Moving all objects in the world five units away from you is mathematically the
same as “backing up” the camera five units.
53
An Interactive Introduction to OpenGL Programming
54
In this routine, we first compute the aspect ratio (aspect) of the new viewing
area. We’ll use this value to modify the world space values (left, right,
bottom, top) of the viewing frustum depending on the new shape of the
viewing volume
54
An Interactive Introduction to OpenGL Programming
55
Continuing from the previous page, we determine how to modify the viewing
volume based on the computed aspect ratio. After we compute the new world
space values, we call glOrtho()to modify the viewing volume.
55
An Interactive Introduction to OpenGL Programming
Compositing Modeling
Transformations
Problem 1: hierarchical objects
• one position depends upon a previous position
• robot arm or hand; sub-assemblies
Solution 1: moving local coordinate system
• modeling transformations move coordinate system
• post-multiply column-major matrices
• OpenGL post-multiplies matrices
56
56
An Interactive Introduction to OpenGL Programming
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 2: 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
57
57
An Interactive Introduction to OpenGL Programming
58
Use of additional clipping places may slow rendering as they are usually
implemented in software.
58
An Interactive Introduction to OpenGL Programming
59
An Interactive Introduction to OpenGL Programming
60
60
An Interactive Introduction to OpenGL Programming
61
In this section we talk about adding the necessary steps for producing smooth
interactive animations with OpenGL using double buffering. Additionally, we
discuss hidden surface removal using depth buffering.
61
An Interactive Introduction to OpenGL Programming
Double Poly.
Per
Vertex
Buffering CPU DL
Pixel
Texture
Raster Frag FB
1 1
2 2
4 4
Front 8 8 Back
16 16
Buffer Buffer
Display
62
Double buffer is a technique for tricking the eye into seeing smooth animation
of rendered scenes. The color buffer is usually divided into two equal halves,
called the front buffer and the back buffer.
The front buffer is displayed while the application renders into the back buffer.
When the application completes rendering to the back buffer, it requests the
graphics display hardware to swap the roles of the buffers, causing the back
buffer to now be displayed, and the previous front buffer to become the new
back buffer.
62
An Interactive Introduction to OpenGL Programming
63
63
An Interactive Introduction to OpenGL Programming
1 1
2 2
4 4
Color 8 8 Depth
16 16
Buffer Buffer
Display
64
64
An Interactive Introduction to OpenGL Programming
65
An Interactive Introduction to OpenGL Programming
66
In main(),
1) GLUT initializes and creates a window named “Tetrahedron”
2) set OpenGL state which is enabled through the entire life of the program
in init()
3) set GLUT’s idle function, which is called when there are no user events
to process.
4) enter the main event processing loop of the program.
66
An Interactive Introduction to OpenGL Programming
67
67
An Interactive Introduction to OpenGL Programming
68
In drawScene(),
1) the color buffer is cleared to the background color
2) a triangle strip is rendered to create a tetrahedron (use your imagination
for the details!)
3) the front and back buffers are swapped.
68
An Interactive Introduction to OpenGL Programming
Lighting
69
69
An Interactive Introduction to OpenGL Programming
Lighting Principles
Lighting simulates how objects reflect light
• material composition of object
• light’s color and position
• global lighting parameters
• ambient light
• two sided lighting
• available in both color index
and RGBA mode
70
70
An Interactive Introduction to OpenGL Programming
71
OpenGL lighting is based on the Phong lighting model. At each vertex in the
primitive, a color is computed using that primitives material properties along
with the light settings.
The color for the vertex is computed by adding four computed colors for the
final vertex color. The four contributors to the vertex color are:
• Ambient is color of the object from all the undirected light in a scene.
• Diffuse is the base color of the object under current lighting. There
must be a light shining on the object to get a diffuse contribution.
• Specular is the contribution of the shiny highlights on the object.
• Emission is the contribution added in if the object emits light (i.e.
glows)
71
An Interactive Introduction to OpenGL Programming
Surface Poly.
Per
Vertex
Normals CPU DL
Pixel
Texture
Raster Frag FB
72
The lighting normal tells OpenGL how the object reflects light around a vertex.
If you imagine that there is a small mirror at the vertex, the lighting normal
describes how the mirror is oriented, and consequently how light is reflected.
glNormal*() sets the current normal, which is used in the lighting
computation for all vertices until a new normal is provided.
Lighting normals should be normalized to unit length for correct lighting
results. glScale*() affects normals as well as vertices, which can change
the normal’s length, and cause it to no longer be normalized. OpenGL can
automatically normalize normals, by enabling glEnable(GL_NORMALIZE).
or glEnable(GL_RESCALE_NORMAL). GL_RESCALE_NORMAL is a
special mode for when your normals are uniformly scaled. If not, use
GL_NORMALIZE which handles all normalization situations, but requires the
computation of a square root, which can potentially lower performance
OpenGL evaluators and NURBS can provide lighting normals for generated
vertices automatically.
72
An Interactive Introduction to OpenGL Programming
Material Properties
Define the surface properties of a primitive
glMaterialfv( face, property, value );
GL_DIFFUSE Base color
73
Material properties describe the color and surface properties of a material (dull,
shiny, etc.). OpenGL supports material properties for both the front and back of
objects, as described by their vertex winding.
The OpenGL material properties are:
• GL_DIFFUSE - base color of object
• GL_SPECULAR - color of highlights on object
• GL_AMBIENT - color of object when not directly illuminated
• GL_EMISSION - color emitted from the object (think of a firefly)
• GL_SHININESS - concentration of highlights on objects. Values
range from 0 (very rough surface - no highlight) to 128 (very shiny)
Material properties can be set for each face separately by specifying either
GL_FRONT or GL_BACK, or for both faces simultaneously using
GL_FRONT_AND_BACK.
73
An Interactive Introduction to OpenGL Programming
Light Properties
glLightfv( light, property, value );
• light specifies which light
• multiple lights, starting with GL_LIGHT0
glGetIntegerv( GL_MAX_LIGHTS, &n );
• properties
• colors
• position and type
• attenuation
74
The glLight() call is used to set the parameters for a light. OpenGL
implementations must support at least eight lights, which are named
GL_LIGHT0 through GL_LIGHTn, where n is one less than the maximum
number supported by an implementation.
OpenGL lights have a number of characteristics which can be changed from
their default values. Color properties allow separate interactions with the
different material properties. Position properties control the location and type of
the light and attenuation controls the natural tendency of light to decay over
distance.
74
An Interactive Introduction to OpenGL Programming
75
OpenGL lights can emit different colors for each of a materials properties. For
example, a light’s GL_AMBIENT color is combined with a material’s
GL_AMBIENT color to produce the ambient contribution to the color - likewise
for the diffuse and specular colors.
75
An Interactive Introduction to OpenGL Programming
Types of Lights
76
OpenGL supports two types of lights: infinite (directional) and local (point)
light sources. The type of light is determined by the w coordinate of the light’s
position.
76
An Interactive Introduction to OpenGL Programming
77
77
An Interactive Introduction to OpenGL Programming
78
In this tutorial, concentrate on noticing the effects of different material and light
properties. Additionally, compare the results of using a local light versus using
an infinite light.
In particular, experiment with the GL_SHININESS parameter to see its affects
on highlights.
78
An Interactive Introduction to OpenGL Programming
79
79
An Interactive Introduction to OpenGL Programming
80
80
An Interactive Introduction to OpenGL Programming
81
81
An Interactive Introduction to OpenGL Programming
1
fi =
k c + kl d + k q d 2
82
Each OpenGL light source supports attenuation, which describes how light
diminishes with distance. The OpenGL model supports quadratic attenuation,
and utilizes the following attenuation factor, fi, where d is the distance from the
eyepoint to the vertex being lit:
1
fi =
k c + kl d + k q d 2
where:
• kc is the GL_CONSTANT_ATTENUATION term
• kl is the GL_LINEAR_ATTENUATION term
• kq is the GL_QUADRATIC_ATTENUATION term
82
An Interactive Introduction to OpenGL Programming
83
Properties which aren’t directly connected with materials or lights are grouped
into light model properties. With OpenGL 1.2, there are four properties
associated with the lighting model:
1) Two-sided lighting uses the front and back material properties for
illuminating a primitive.
2) Global ambient color initializes the global ambient contribution of
the lighting equation.
3) Local viewer mode disables an optimization which provides faster
lighting computations. With local viewer mode on, you get better light
results at a slight performance penalty.
4) Separate specular color is a mode for maintaining better specular
highlights in certain texture mapped conditions. This is a new feature for
OpenGL 1.2.
83
An Interactive Introduction to OpenGL Programming
84
As with all of computing, time versus space is the continual tradeoff. To get the
best results from OpenGL lighting, your models should be finely tessellated to
get the best specular highlights and diffuse color boundaries. This yields better
results, but usually at a cost of more geometric primitives, which could slow
application performance.
To achieve maximum performance for lighting in your applications, use a
single infinite light source. This minimizes the amount of work that OpenGL
has to do to light every vertex.
84
An Interactive Introduction to OpenGL Programming
85
85
An Interactive Introduction to OpenGL Programming
86
OpenGL is not only a complete interface for 3D rendering, it’s also a very
capable image processing engine. In this section we discuss some of the basic
functions of OpenGL for rendering color-pixel rectangles and single-bit
bitmaps, as well as how to read color information from the framebuffer.
OpenGL doesn’t render images, per se, since images usually are stored in some
file with an image format associated with it (for example, JPEG images).
OpenGL only knows how to render rectangles of pixels, not decode image files.
86
An Interactive Introduction to OpenGL Programming
Pixel-based primitives
Bitmaps
• 2D array of bit masks for pixels
• update pixel color based on current color
Images
• 2D array of pixel color information
• complete color information for each pixel
OpenGL doesn’t understand image formats
87
87
An Interactive Introduction to OpenGL Programming
Per
Poly.
Vertex
Pixel Pipeline CPU DL Raster Frag FB
Texture
Pixel
Texture glCopyTex*Image();
Memory
glReadPixels(), glCopyPixels()
Just as there’s a pipeline that geometric primitives go through when they are
processed, so do pixels. The pixels are read from main storage, processed to
obtain the internal format which OpenGL uses, which may include color
translations or byte-swapping. After this, each pixel from the image is
processed by the fragment operations discussed in the last section, and finally
rasterized into the framebuffer.
In addition to rendering into the framebuffer, pixels can be copied from the
framebuffer back into host memory, or transferred into texture mapping
memory.
For best performance, the internal representation of a pixel array should match
the hardware. For example, for a 24 bit frame buffer, 8-8-8 RGB would
probably be a good match, but 10-10-10 RGB could be bad. Warning: non-
default values for pixel storage and transfer can be very slow.
88
An Interactive Introduction to OpenGL Programming
glRasterPos3f( x, y, z )
• raster position transformed like geometry
• discarded if raster position is
outside of viewport
Raster Position
89
Images are positioned by specifying the raster position, which maps the lower
left corner of an image primitive to a point in space. Raster positions are
transformed and clipped the same as vertices. If a raster position fails the clip
check, no fragments are rasterized.
89
An Interactive Introduction to OpenGL Programming
Rendering Bitmaps
height
(xmove ymove) after rendering
yorig
width
xorig
xmove
90
90
An Interactive Introduction to OpenGL Programming
91
91
An Interactive Introduction to OpenGL Programming
Rendering Images
glDrawPixels( width, height, format, type,
pixels )
• render pixels with lower left of
image at current raster position
• numerous formats and data types
for specifying storage in memory
• best performance by using format and type that
matches hardware
92
92
An Interactive Introduction to OpenGL Programming
Reading Pixels
glReadPixels( x, y, width, height, format,
type, pixels )
• read pixels starting at specified (x,y) position in
framebuffer
• pixels automatically converted from framebuffer
format into requested format and type
Framebuffer pixel copy
glCopyPixels( x, y, width, height, type )
93
Just as you can send pixels to the framebuffer, you can read the pixel values
back from the framebuffer to host memory for doing storage or image
processing.
Pixels read from the framebuffer are processed by the pixel storage and transfer
modes, as well as converting them into the format and type requested, and
placing them in host memory.
Additionally, pixels can be copied from the framebuffer from one location to
another using glCopyPixels(). Pixels are processed by the pixel storage
and transfer modes before being returned to the framebuffer.
93
An Interactive Introduction to OpenGL Programming
Pixel Zoom
glPixelZoom( x, y )
• expand, shrink or reflect pixels
around current raster position
• fractional zoom supported
Raster glPixelZoom(1.0, -1.0);
Position
94
94
An Interactive Introduction to OpenGL Programming
95
When pixels are read from or written to host memory, pixels can be modified
by storage and transfer modes.
Storage modes control how host memory is accessed and written to, including
byte swapping and addressing, and modifying how memory is accessed to read
only a small subset of the original image.
Transfer modes allow pixel modifications as they are processed. This includes
scaling and biasing the color component values, as well as replacing color
values using color lookup tables.
95
An Interactive Introduction to OpenGL Programming
Texture Mapping
96
96
An Interactive Introduction to OpenGL Programming
DL
Per
Vertex
Raster Frag FB
Texture
Pixel
In this section, we’ll discuss texture ( sometimes also called image ) mapping.
Texture mapping augments the colors specified for a geometric primitive with
the colors stored in an image. An image can be a 1D, 2D, or 3D set of colors
called texels. 2D textures will be used throughout the section for
demonstrations, however, the processes described are identical for 1D and 3D
textures.
Some of the many uses of texture mapping include:
• simulating materials like wood, bricks or granite
• reducing the complexity ( number of polygons ) of a geometric object
• image processing techniques like image warping and rectification,
rotation and scaling
• simulating reflective surfaces like mirrors or polished floors
97
An Interactive Introduction to OpenGL Programming
Texture Mapping
z x
geometry screen
t
image
s 98
Textures are images that can be thought of as continuous and be one, two, three,
or four dimensional. By convention, the coordinates of the image are s, t, r and
q. Thus for the two dimensional image above, a point in the image is given by
its (s, t) values with (0, 0) in the lower-left corner and (1, 1) in the top-right
corner.
A texture map for a two-dimensional geometric object in (x, y, z) world
coordinates maps a point in (s, t) space to a corresponding point on the screen.
98
An Interactive Introduction to OpenGL Programming
99
The advantage of texture mapping is that visual detail is in the image, not in the
geometry. Thus, the complexity of an image does not affect the geometric
pipeline (transformations, clipping) in OpenGL. Texture is added during
rasterization where the geometric and pixel pipelines meet.
99
An Interactive Introduction to OpenGL Programming
Texture Example
The texture (below) is a
256 x 256 image that has been
mapped to a rectangular
polygon which is viewed in
perspective
100
100
An Interactive Introduction to OpenGL Programming
Applying Textures I
Three steps
specify texture
• read or generate image
• assign to texture
assign texture coordinates to vertices
specify texture parameters
• wrapping, filtering
101
101
An Interactive Introduction to OpenGL Programming
Applying Textures II
• enable texturing
• supply texture coordinates for vertex
• coordinates can also be generated
102
The general steps to enable texturing are listed above. Some steps are optional,
and due to the number of combinations, complete coverage of the topic is
outside the scope of this course.
Here we use the texture object approach. Using texture objects may enable
your OpenGL implementation to make some optimizations behind the scenes.
As with any other OpenGL state, texture mapping requires that glEnable()
be called. The tokens for texturing are:
GL_TEXTURE_1D - one-dimensional texturing
GL_TEXTURE_2D - two-dimensional texturing
GL_TEXTURE_3D - three-dimensional texturing
2D texturing is the most commonly used. 1D texturing is useful for applying
contours to objects ( like altitude contours to mountains ); 3D texturing is useful
for volume rendering.
102
An Interactive Introduction to OpenGL Programming
Raster Frag FB
Image
CPU DL
Texture
Pixel
103
An Interactive Introduction to OpenGL Programming
104
If your image does not meet the power of two requirement for a dimension, the
gluScaleImage() call will resample an image to a particular size. It uses a
simple box filter (which computes the weighted average of adjacent pixels to
generate the new pixel values) to interpolate the new images pixels from the
source image.
Additionally, gluScaleImage() can be used to convert from one data type
( i.e. GL_FLOAT ) to another type, which may better match the internal format
in which OpenGL stores your texture. Converting types using
gluScaleImage() can help your application save memory.
104
An Interactive Introduction to OpenGL Programming
Specifying a Texture:
Other Methods
105
105
An Interactive Introduction to OpenGL Programming
Mapping a Poly.
Per
Texture
Vertex
c (0.4, 0.2)
b
B C
0, 0 1, 0 s (0.8, 0.4)
106
When you want to map a texture onto a geometric primitive, you need to
provide texture coordinates. The glTexCoord*() call sets the current
texture coordinates. Valid texture coordinates are between 0 and 1, for each
texture dimension, and the default texture coordinate is ( 0, 0, 0, 1 ). If you pass
fewer texture coordinates than the currently active texture mode ( for example,
using glTexCoord1d() while GL_TEXTURE_2D is enabled ), the
additionally required texture coordinates take on default values.
106
An Interactive Introduction to OpenGL Programming
Ax + By + Cz + D = 0
generation modes
• GL_OBJECT_LINEAR
• GL_EYE_LINEAR
• GL_SPHERE_MAP
107
You can have OpenGL automatically generate texture coordinates for vertices
by using the glTexGen() and glEnable(GL_TEXTURE_GEN_{STRQ}).
The coordinates are computed by determining the vertex’s distance from each
of the enabled generation planes.
As with lighting positions, texture generation planes are transformed by the
ModelView matrix, which allows different results based upon when the
glTexGen() is issued.
There are three ways in which texture coordinates are generated:
GL_OBJECT_LINEAR - textures are fixed to the object ( like wall paper )
GL_EYE_LINEAR - texture fixed in space, and object move through
texture ( like underwater light shining on a swimming fish)
GL_SPHERE_MAP - object reflects environment, as if it were made of
mirrors (like the shiny guy in Terminator 2)
107
An Interactive Introduction to OpenGL Programming
108
This tutorial demonstrates the power and ease of texture mapping. Begin by
merely manipulating the texture and vertex coordinates; notice their
relationship.
Next, change the texture filter parameters with the glTexParameter*()
function. Notice the quality decrease as the mode’s changed to GL_NEAREST.
This mode is the fastest for rendering with texture maps, but has the least
quality. As you try other texture filter modes, note the changes in visual
quality. Make sure to change the size of the texture quad (or other object) in
the screen-space window.
Continue to experiment by changing the wrap modes for the s- and t-
coordinates with the glTexParameter*() function. Note the effects that
changing the wrap modes has when the texture coordinates outside the range
[0,1].
Finally, experiment with the texture environment utilizing the glTexEnv*()
call. The most common texture environment modes are GL_MODULATE, and
GL_REPLACE; the other’s are used less, but none less useful.
108
An Interactive Introduction to OpenGL Programming
109
Textures and the objects being textured are rarely the same size ( in pixels ).
Filter modes determine the methods used by how texels should be expanded
( magnification ), or shrunk ( minification ) to match a pixel’s size. An
additional technique, called mipmapping is a special instance of a minification
filter.
Wrap modes determine how to process texture coordinates outside of the [0,1]
range. The available modes are:
GL_CLAMP - clamp any values outside the range to closest valid value,
causing the edges of the texture to be “smeared” across the primitive
GL_REPEAT - use only the fractional part of the texture coordinate, causing
the texture to repeat across an object
Finally, the texture environment describes how a primitives fragment colors and
texel colors should be combined to produce the final framebuffer color.
Depending upon the type of texture ( i.e. intensity texture vs. RGBA texture )
and the mode, pixels and texels may be simply multiplied, linearly combined,
or the texel may replace the fragment’s color altogether.
109
An Interactive Introduction to OpenGL Programming
Filter Modes
Example:
glTexParameteri( target, type, mode );
Filter modes control how pixels are minified or magnified. Generally a color is
computed using the nearest texel or by a linear average of several texels.
The filter type, above is one of GL_TEXTURE_MIN_FILTER or
GL_TEXTURE_MAG_FILTER.
The mode is one of GL_NEAREST, GL_LINEAR, or special modes for
mipmapping. Mipmapping modes are used for minification only, and have
values of:
GL_NEAREST_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR
GL_LINEAR_MIPMAP_NEAREST
GL_LINEAR_MIPMAP_LINEAR
Full coverage of mipmap texture filters is outside the scope of this course.
110
An Interactive Introduction to OpenGL Programming
Mipmapped Textures
Mipmap allows for prefiltered texture maps of
decreasing resolutions
Lessens interpolation errors for smaller textured
objects
Declare mipmap level during texture definition
glTexImage*D( GL_TEXTURE_*D, level, … )
GLU mipmap builder routines
gluBuild*DMipmaps( … )
OpenGL 1.2 introduces advanced LOD controls
111
111
An Interactive Introduction to OpenGL Programming
Wrapping Mode
Example:
glTexParameteri( GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S, GL_CLAMP )
glTexParameteri( GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T, GL_REPEAT )
s
GL_REPEAT GL_CLAMP
texture
wrapping wrapping
112
Wrap mode determines what should happen if a texture coordinate lies outside
of the [0,1] range. If the GL_REPEAT wrap mode is used, for texture
coordinate values less than zero or greater than one, the integer is ignored and
only the fractional value is used.
If the GL_CLAMP wrap mode is used, the texture value at the extreme (either 0
or 1) is used.
112
An Interactive Introduction to OpenGL Programming
Texture Functions
Controls how texture is applied
glTexEnv{fi}[v]( GL_TEXTURE_ENV, prop, param )
GL_TEXTURE_ENV_MODE modes
• GL_MODULATE
• GL_BLEND
• GL_REPLACE
Set blend color with GL_TEXTURE_ENV_COLOR
113
The texture mode determines how texels and fragment colors are combined.
The most common modes are:
GL_MODULATE - multiply texel and fragment color
GL_BLEND - linearly blend texel, fragment, env color
GL_REPLACE - replace fragment’s color with texel
If prop is GL_TEXTURE_ENV_COLOR, param is an array of four floating point
values representing the color to be used with the GL_BLEND texture function.
113
An Interactive Introduction to OpenGL Programming
114
114
An Interactive Introduction to OpenGL Programming
Texture Objects
Like display lists for texture images
• one image per texture object
• may be shared by several graphics contexts
Avoids reloading of textures as long as there is
sufficient texture memory
Generate texture names
glGenTextures( n, *texIds );
115
The first step in creating texture objects is to have OpenGL reserve some
indices for your objects. glGenTextures() will request n texture ids and
return those values back to you in texIds.
To begin defining a texture object, you call glBindTexture() with the id
of the object you want to create. The target is one of
GL_TEXTURE_{123}D(). All texturing calls become part of the object until
the next glBindTexture() is called.
To have OpenGL use a particular texture object, call glBindTexture()
with the target and id of the object you want to be active.
To delete texture objects, use glDeleteTextures( n, *texIds ),
where texIds is an array of texture object identifiers to be deleted.
115
An Interactive Introduction to OpenGL Programming
116
If you utilize more than one texture map in your application, you will generally
call glBindTexture() more than one time per image. The first time will
be to “open” the texture object for creation; when you load the texture and set
its parameters. You’ll do this one for each texture map you will use, most often
in the initialization section of your application.
The second call to glBindTexture() should occur before you wish to
render object using the texture map stored in that texture object. This will
probably occur once per rendered frame (assuming that you need to render
object that use this texture).
116
An Interactive Introduction to OpenGL Programming
117
117
An Interactive Introduction to OpenGL Programming
Texture Residency
Working set of textures
• high-performance, usually hardware accelerated
• textures must be in texture objects
• a texture in the working set is resident
• for residency of current texture, check
GL_TEXTURE_RESIDENT state
If too many textures, not all are resident
• can set priority to have some kicked out first
• establish 0.0 to 1.0 priorities for texture objects
118
118
An Interactive Introduction to OpenGL Programming
119
119
An Interactive Introduction to OpenGL Programming
120
120
An Interactive Introduction to OpenGL Programming
121
121
An Interactive Introduction to OpenGL Programming
Per Vertex
Polynomial Operations &
Evaluator Primitive
Assembly
Display Listed
Texture
Memory
Pixel
Operations
122
In immediate mode, primitives (vertices, pixels) flow through the system and
produce images. These data are lost. New images are created by reexecuting the
display function and regenerating the primitives.
In retained mode, the primitives are stored in a display list (in “compiled”
form). Images can be recreated by “executing” the display list. Even without a
network between the server and client, display lists should be more efficient
than repeated executions of the display function.
122
An Interactive Introduction to OpenGL Programming
Display Lists
Per
Poly.
Vertex
123
123
An Interactive Introduction to OpenGL Programming
Display Lists
Not all OpenGL routines can be stored in display
lists
State changes persist, even after a display list is
finished
Display lists can call other display lists
Display lists are not editable, but you can fake it
• make a list (A) which calls other lists (B, C, and D)
• delete and replace B, C, and D, as needed
124
Some routines cannot be stored in a display list. Here are some of them:
all glGet* routines
glIs* routines (e.g., glIsEnabled, glIsList, glIsTexture)
glGenLists glDeleteLists glFeedbackBuffer
glSelectBuffer glRenderMode glVertexPointer
glNormalPointer glColorPointer glIndexPointer
glReadPixels glPixelStore glGenTextures
glTexCoordPointer glEdgeFlagPointer
glEnableClientState glDisableClientState
glDeleteTextures glAreTexturesResident
glFlush glFinish
If there is an attempt to store any of these routines in a display list, the routine is
executed in immediate mode. No error occurs.
124
An Interactive Introduction to OpenGL Programming
125
One of the most convenient uses of display lists is repetition of the same
graphical object. This technique is sometimes called instancing, carried over
from the same concept in object-oriented programming.
In the above case, the wheels of the car are all drawn using the same display
lists, with the only difference being different modeling transformations used to
position each of the tires in the appropriate place.
125
An Interactive Introduction to OpenGL Programming
Advanced Primitives
Vertex Arrays
Bernstein Polynomial Evaluators
• basis for GLU NURBS
• NURBS (Non-Uniform Rational B-Splines)
GLU Quadric Objects
• sphere
• cylinder (or cone)
• disk (circle)
126
126
An Interactive Introduction to OpenGL Programming
Vertex Poly.
Per
Vertex
Arrays CPU DL
Pixel
Texture
Raster Frag FB
128
An Interactive Introduction to OpenGL Programming
129
129
An Interactive Introduction to OpenGL Programming
Blending
Per
Poly.
Vertex
130
An Interactive Introduction to OpenGL Programming
Blending Tutorial
131
The blending tutorial provides an opportunity to explore how pixel blending can
be used to create interest effects. The source and destination colors are scaled
in the manner specified by the parameters set with glBlendFunc(). The
pixels are combined mathematically using the operation specified in
glBlendEquation(). glBlendEquation(), along with several of
the blending modes, are only supported if the GL_imaging extension is
supported.
131
An Interactive Introduction to OpenGL Programming
Multi-pass Rendering
Blending allows results from multiple
drawing passes to be combined together
• enables more complex rendering algorithms
Example of bump-mapping
done with a multi-pass
OpenGL algorithm
132
132
An Interactive Introduction to OpenGL Programming
Antialiasing
Removing the Jaggies
glEnable( mode )
•GL_POINT_SMOOTH
•GL_LINE_SMOOTH
•GL_POLYGON_SMOOTH
• alpha value computed by computing
sub-pixel coverage
• available in both RGBA and colormap modes
133
Antialiasing is a process to remove the jaggies which is the common name for
jagged edges of rasterized geometric primitives. OpenGL supports antialiasing
of all geometric primitives by enabling both GL_BLEND and one of the
constants listed above.
Antialiasing is accomplished in RGBA mode by computing an alpha value for
each pixel that the primitive touches. This value is computed by subdividing the
pixel into subpixels and determining the ratio used subpixels to total subpixels
for that pixel. Using the computed alpha value, the fragment’s colors are
blended into the existing color in the framebuffer for that pixel.
Color index mode requires a ramp of colors in the colormap to simulate the
different values for each of the pixel coverage ratios.
In certain cases, GL_POLYGON_SMOOTH may not provide sufficient results,
particularly if polygons share edges. As such, using the accumulation buffer for
full scene antialising may be a better solution.
133
An Interactive Introduction to OpenGL Programming
Accumulation Buffer
Problems of compositing into color buffers
• limited color resolution
• clamping
• loss of accuracy
• Accumulation buffer acts as a “floating point”
color buffer
• accumulate into accumulation buffer
• transfer results to frame buffer
134
134
An Interactive Introduction to OpenGL Programming
135
If we want to average n images, we can add in each with a value of 1 and read
the result with a factor of 1/n. Equivalently, we can accumulate each with a
factor of 1/n and read back with a factor of 1.
135
An Interactive Introduction to OpenGL Programming
Accumulation Buffer
Applications
Compositing
Full Scene Antialiasing
Depth of Field
Filtering
Motion Blur
136
Compositing, which combines several images into a single image, done with the
accumulation buffer generally gives better results than blending multiple passes
into the framebuffer.
Full scene antialiasing utilizes compositing in the accumulation buffer to
smooth the jagged edges of all objects in the scene. Depth of field, simulates
how a camera lens can focus on a single object while other objects in the view
may be out of focus.
Filtering techniques, such as convolutions and blurs (from image processing)
can be done easily in the accumulation buffer by rendering the same image
multiple times with slight pixel offsets.
Motion blur, a technique often used in Saturday morning cartoons, simulates
motion in a stationary object. We can do with the accumulation buffer by
rendering the same scene multiple times, and varying the position of the object
we want to appear as moving for each render pass. Compositing the results will
give the impression of the object moving.
136
An Interactive Introduction to OpenGL Programming
137
137
An Interactive Introduction to OpenGL Programming
Focal Plane
Front Plane
Depth of field images can be produced by shifting the eyepoint around in the
same parallel plane as to the focal plane. By compositing the resulting images
together, objects near the center of the viewing frustum are kept in focus, while
objects farther from the focal plane are composited to be a little blurry.
138
An Interactive Introduction to OpenGL Programming
Fog
139
139
An Interactive Introduction to OpenGL Programming
Fog Tutorial
140
In this tutorial, experiment with the different fog modes, and in particular, the
parameters which control either the fog density (for exponential mode) and the
start and end distances (for linear mode).
140
An Interactive Introduction to OpenGL Programming
Feedback Mode
Transformed vertex data is returned to the
application, not rendered
• useful to determine which primitives will make it
to the screen
Need to specify a feedback buffer
glFeedbackBuffer( size, type, buffer )
Select feedback mode for rendering
glRenderMode( GL_FEEDBACK )
141
141
An Interactive Introduction to OpenGL Programming
Selection Mode
Method to determine which primitives are
inside the viewing volume
Need to set up a buffer to have results
returned to you
glSelectBuffer( size, buffer )
142
Selection mode is a way to determine which primitives fall within the viewing
volume. As compared to feedback mode, where all the vertex data for a
primitive is returned to you, selection mode only returns back a “name” which
you assign for the primitive.
142
An Interactive Introduction to OpenGL Programming
143
Selection mode uses names to identify primitives that pass the selection test.
Any number of primitives can share the same name, allowing groups of
primitives to be identified as a logical object.
After specifying the selection buffer, it must be initialized first by calling
glPushName() . A hierarchy of names can be set up by calling
glPushName() to obtain a new level in the hierarchy, and glLoadName()
to uniquely name each node in the hierarchy.
glInitNames() can be used to completely clear out an existing name
hierarchy.
143
An Interactive Introduction to OpenGL Programming
Picking
Picking is a special case of selection
Programming steps
• restrict “drawing” to small region near pointer
use gluPickMatrix() on projection matrix
• enter selection mode; re-render scene
• primitives drawn near cursor cause hits
• exit selection; analyze hit records
144
144
An Interactive Introduction to OpenGL Programming
Picking Template
glutMouseFunc( pickMe );
145
145
An Interactive Introduction to OpenGL Programming
146
146
An Interactive Introduction to OpenGL Programming
glMatrixMode( GL_PROJECTION );
glPopMatrix();
hits = glRenderMode( GL_RENDER );
/* process nameBuffer */
}
147
Completing our example, we restore the projection matrix to its pre-pick matrix
mode, and process our hits with the data returned back to us in the selection
buffer provided previously.
147
An Interactive Introduction to OpenGL Programming
Picking Ideas
For OpenGL Picking Mechanism
• only render what is pickable (e.g., don’t clear screen!)
• use an “invisible” filled rectangle, instead of text
• if several primitives drawn in picking region, hard to use z
values to distinguish which primitive is “on top”
Alternatives to Standard Mechanism
• color or stencil tricks (for example, use glReadPixels() to
obtain pixel value from back buffer)
148
There are a few tricks that make picking more useful and simpler to use:
• In order to make picking as fast as possible, only render what’s
pickable.
• Try to use simple geometry to simulate a more complex object. For
example, use a filled rectangle as compared to a text string, or the
bounding sphere of a complicated polygonal object.
The selection mechanism returns the depth values of objects, which can be used
to sort objects based on their distance from the eyepoint.
OpenGL selection and picking methods aren’t the only ways to determine what
primitives are on the screen. In some cases, it may be faster and easier to use
unique colors for each object, render the scene into the back-buffer, and read
the pixel or pixels which are of interest (like the hot spot on a cursor). Looking
up the color may be much faster and more direct than parsing the hit list
returned from selection.
148
An Interactive Introduction to OpenGL Programming
Framebuffer
Depth Logical
Blending Dithering
Test Operations
149
In order for a fragment to make it to the frame buffer, it has a number of testing
stages and pixel combination modes to go through.
The tests that a fragment must pass are:
• scissor test - an additional clipping test
• alpha test - a filtering test based on the alpha color component
• stencil test - a pixel mask test
• depth test - fragment occlusion test
Each of these tests is controlled by a glEnable() capability.
If a fragment passes all enabled tests, it is then blended, dithered and/or
logically combined with pixels in the framebuffer. Each of these operations can
be enabled and disabled.
149
An Interactive Introduction to OpenGL Programming
Scissor Box
Additional Clipping Test
glScissor( x, y, w, h )
• any fragments outside of box are clipped
• useful for updating a small section of a viewport
• affects glClear() operations
150
150
An Interactive Introduction to OpenGL Programming
Alpha Test
Per
Poly.
Vertex
151
Alpha values can also be used for fragment testing. glAlphaFunc() sets a
value which, if glEnable(GL_ALPHA_TEST) has been called, will test
every fragment’s alpha against the value set, and if the test fails, the fragment is
discarded.
The functions which glAlphaFunc() can use are:
GL_NEVER GL_LESS
GL_EQUAL GL_LEQUAL
GL_GREATER GL_NOTEQUAL
GL_GEUQAL GL_ALWAYS
The default is GL_ALWAYS, which always passes fragments.
Alpha testing is particularly useful when combined with texture mapping with
textures which have an alpha component. This allows your texture map to act as
a localized pixel mask. This technique is commonly used for objects like trees
or fences, where modeling the objects (and all of its holes) becomes prohibitive.
151
An Interactive Introduction to OpenGL Programming
Stencil Buffer
Per
Poly.
Vertex
152
Unlike other buffers, we do not draw into the stencil buffer. We set its values
with the stencil functions. However, the rendering can alter the values in the
stencil buffer depending on whether a fragment passes or fails the stencil test.
152
An Interactive Introduction to OpenGL Programming
153
The two principal functions for using the stencil buffer are
glStencilFunc()which controls how the bits in the stencil buffer are used
to determine if a particular pixel in the framebuffer is writable.
glStencilOp()controls how the stencil buffer values are updated, based on
three tests:
1) did the pixel pass the stencil test specified with glStencilFunc()
2) did the pixel fail the depth test for that pixel.
3) did the pixel pass the depth test for that pixel. This would mean that the
pixel in question would have appeared in the image.
153
An Interactive Introduction to OpenGL Programming
Creating a Mask
Initialize Mask
glInitDisplayMode( …|GLUT_STENCIL|… );
glEnable( GL_STENCIL_TEST );
glClearStencil( 0x1 );
154
154
An Interactive Introduction to OpenGL Programming
155
After the stencil mask is specified, we can use the mask to selectively update
pixels. With the first set of commands, we only update the pixels where the
stencil buffer is set to 0x01 in the stencil buffer.
In the second example, we set the stencil state up to render only to pixels where
the stencil value is not 0x01.
155
An Interactive Introduction to OpenGL Programming
Dithering
glEnable( GL_DITHER )
Dither colors for better looking results
• Used to simulate more available colors
156
Dithering is a technique to trick the eye into seeing a smoother color when only
a few colors are available. Newspaper’s use this trick to make images look
better. OpenGL will modify a fragment’s color value with a dithering table
before it is written into the framebuffer.
156
An Interactive Introduction to OpenGL Programming
157
157
An Interactive Introduction to OpenGL Programming
158
158
An Interactive Introduction to OpenGL Programming
Advanced Imaging
Imaging Subset
• Only available if GL_ARB_imaging defined
• Color matrix
• Convolutions
• Color tables
• Histogram
• MinMax
• Advanced Blending
159
159
An Interactive Introduction to OpenGL Programming
Summary / Q & A
Dave Shreiner
Ed Angel
Vicki Shreiner
160
160
An Interactive Introduction to OpenGL Programming
On-Line Resources
• http://www.opengl.org
• start here; up to date specification and lots of sample code
• news:comp.graphics.api.opengl
• http://www.sgi.com/software/opengl
• http://www.mesa3d.org/
• Brian Paul’s Mesa 3D
• http://www.cs.utah.edu/~narobins/opengl.html
• very special thanks to Nate Robins and Pete Shaheen for the OpenGL
Tutors
• source code for tutors available here!
161
161
An Interactive Introduction to OpenGL Programming
Books
OpenGL Programming Guide, 3rd Edition
OpenGL Reference Manual, 3rd Edition
OpenGL Programming for the X Window
System
• includes many GLUT examples
Interactive Computer Graphics: A top-down
approach with OpenGL, 2nd Edition
162
162
An Interactive Introduction to OpenGL Programming
163
163