Ch-6 State Managment
Ch-6 State Managment
glVertex3dv(dvect);
Displayed solid
GL_LINE_STRIP
A series of connected lines
GL_LINE_LOOP
A closed loop
Wide and Stippled Lines
void glLineWidth(GLfloat width);
Sets the width in pixels for rendered lines
void glLineStipple(GLint factor, GLshort pattern);
Sets the current stippling pattern (dashed or dotted) for
lines
Pattern is a 16-bit series of 0s and 1s
1 means one pixel drawing, and 0 not drawing
Factorstretches the pattern multiplying each bit
Trun on and off stippling
glEnable(GL_LINE_STIPPLE)
glDisable(GL_LINE_STIPPLE)
Example of Stippled Lines
glLineStipple(1, 0x3F07);
Pattern 0x3F07 translates to 0011111100000111
Line is drawn with 3 pixels on, 5 off, 6 on, and 2 off
• glLineStipple(2, 0x3F07);
Factor is 2
Line is drawn with 6 pixels on, 10 off, 12 on, and 4 off
Polygon
Areas enclosed by singled closed loops of line
segments
GL_TRIANGLES
Draws first three vertices as a triangle
GL_QUADS
Quadilateral is a four-sided polygon
Drawing Polygons
v1 v3
GL_TRIANGLE_STRIP
v5
Draws a series of triangles using
vertices in the order
v0 v2 v4
v0,v1,v2; v2,v1,v3
v2,v3,v4; v4,v3,v5
All triangles are drawn with the
v1
same orientation (clockwise order) v2
GL_TRIANGLE_FAN v3
One vertex is in common to v0 v4
all triangles
Clockwise orientation v5
GL_QUAD_STRIP
Draws a series of quadrilaterals
Polygons as Points and Outlines
void glPolygonMode(GLenum face, Glenum
mode);
Controls the drawing mode for a polygon’s
front and back faces
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);
glPolygonMode(GL_FRONT_AND_BACK,
GL_POINT);
By convention, polygons whose vertices
appear in counterclockwise order are front-
facing
GL_CCW
Deciding Front- or Back Facing
Decision based the sign of the polygon’s area, a computed in window coordinates
n−1
1
a= ∑ [ x i y iÅ 1−x iÅ 1 y i ]
For GL_CCW, if a>0 means the polygon be front-facing, then a<0 means the back-
facing
2 i= 0
For GL_CW, if a<0 for front-facing, then a>0 for back-facing
Reversing and Culling Polygons
void glFrontFace(GLenum mode);
Controls how front-facing polygons are
determined.
Default mode is GL_CCW (vertices in
counterclockwise order)
Needs to be enabled.
P
v2
Vertex Arrays
OpenGL requires many function calls to
render geometric primitives.
Drawing a 20−sided polygon requires 22
function calls: one call to glBegin(), one call
for each of the vertices, and a final call to
glEnd().
For some systems, function calls have a
great deal of overhead and can hinder
performance
An additional problem is the redundant
processing of vertices that are shared
OpenGL has vertex array routines that allow you to specify
a lot of vertex−related data with just a few arrays and to
access that data with equally few function calls.
Using vertex array routines, all 20 vertices in a 20−sided
polygon could be put into one array and called with one
function.
If each vertex also had a surface normal, all 20 surface
normals could be put into another array and also called with
one function.
Arranging data in vertex arrays may increase the
performance of your application. Using vertex arrays reduces
the number of function calls, which improves performance.
Also, using vertex arrays may allow non−redundant
processing of shared vertices.
There are three steps to using vertex
arrays to render geometry:
Activate (enable) up to six arrays, each to
store a different type of data: vertex
coordinates,RGB colors, color indices,
surface normals, texture coordinates, or
polygon edge flags.
Put data into the array or arrays. The
arrays are accessed by the addresses of (that
is, pointers to) their memory locations
Draw geometry with the data
Step 1: Enabling Arrays
The first step is to call glEnableClientState() with an
enumerated parameter, which activates the chosen array.
void glEnableClientState(GLenum array)
Specifies the array to enable.
Symbolic constants GL_VERTEX_ARRAY,
GL_COLOR_ARRAY, GL_INDEX_ARRAY,
GL_NORMAL_ARRAY, GL_TEXTURE_COORD_ARRAY, and
GL_EDGE_FLAG_ARRAY are acceptable parameters.
If you use lighting, you may want to define a surface normal for
every vertex.
To use vertex arrays for that case, you activate both the
surface normal and vertex coordinate arrays:
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
void glDisableClientState(GLenum array);
Specifies the array to disable. Accepts the same
symbolic constants as glEnableClientState().
The reason we just dont call glEnable() and
glDisable() instead of glEnableClientState() and
the long arguments is that glEnable() and
glDisable() can be stored in a display list, but the
specification of vertex arrays cannot, because the
data remains on the client’s side.
Step 2: Specifying Data for the
Arrays
There is a straightforward way by which a single command specifies
a single array in the client space.
There are six different routines to specify arrays. one routine for
each kind of array.
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const
GLvoid *pointer); Specifies where spatial coordinate data can be
accessed.
pointer is the memory address of the first coordinate of the first vertex
in the array.
type specifies the data type (GL_SHORT, GL_INT, GL_FLOAT, or
GL_DOUBLE) of each coordinate in the array.
size is the number of coordinates per vertex, which must be 2, 3, or 4.
stride is the byte offset between consecutive vertexes. If stride is 0, the
vertices are understood to be tightly packed in the array
To access the other five arrays, there are five similar routines:
The main differences among the routines are
whether size and type are unique or must be
specified.
For example, a surface normal always has
three components, so it is redundant to
specify its size.
An edge flag is always a single Boolean, so
neither size nor type needs to be mentioned.
legal values for size and data types.
Step 3: Dereferencing and
Rendering
Until the contents of the vertex arrays are dereferenced,
the arrays remain on the client side, and their contents
are easily changed.
In Step 3, contents of the arrays are obtained, sent
down to the server,and then sent down the graphics
processing pipeline for rendering.
There are three ways to obtain data:
from a single array element (indexed location),
from a sequence of array elements, and
from an ordered list of array elements.
Dereference a Single Array Element
void glArrayElement(GLint ith) Obtains the data of one (the ith)
vertex for all currently enabled arrays.
For the vertex coordinate array, the corresponding command would
be glVertex[size][type]v(), where size is one of [2,3,4], and type is
one of [s,i,f,d] for GLshort, GLint, GLfloat, and Gldouble
respectively. Both size and type were defined by glVertexPointer().
For other enabled arrays, glArrayElement() calls glEdgeFlagv(),
glTexCoord[size][type]v(), glColor[size][type]v(), glIndex[type]v(),
and glNormal[type]v(). If the vertex coordinate array is enabled,
The glVertex*v() routine is executed last, after the execution (if
enabled) of up to five corresponding array values.
glArrayElement() is usually called between glBegin() and glEnd().
If called outside, glArrayElement() sets the current state for all
enabled arrays, except for vertex, which has no current state.
Dereference a List of Array Elements
glArrayElement() is good for randomly "hopping around" your data
arrays.
A similar routine, glDrawElements(), is good for hopping around your data
arrays in a more orderly manner.
void glDrawElements(GLenum mode, GLsizei count, GLenum type, void
*indices);
Defines a sequence of geometric primitives using count number of
elements, whose indices are stored in the array indices.
type must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT,
or GL_UNSIGNED_INT, indicating the data type of the indices array.
mode specifies what kind of primitives are constructed and is one of the
same values that is accepted by glBegin();
for example, GL_POLYGON, GL_LINE_LOOP, GL_LINES, GL_POINTS, and so
on.
Two Ways to Use glDrawElements()
static GLubyte frontIndices = {4, 5, 6, 7};
static GLubyte rightIndices = {1, 2, 6, 5};
static GLubyte bottomIndices = {0, 1, 5, 4};
static GLubyte backIndices = {0, 3, 2, 1};
static GLubyte leftIndices = {0, 4, 7, 3};
static GLubyte topIndices = {2, 3, 7, 6};