0% found this document useful (0 votes)
7 views

Ch-6 State Managment

lecture

Uploaded by

dejenehundaol91
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Ch-6 State Managment

lecture

Uploaded by

dejenehundaol91
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 40

Chapter 6

State management and


Drawing Geometric Objects
Drawing Primitives
 OpenGL sets three types of drawing
primitives
 Points
 Lines
 Polygons, e.g, traingles
 All primitives are represented in terms of
vertices
 thatdefine the positions of the points
themselves or the ends of line segments or the
corners of polygons
Cont..
void glFlush(void);

Forces previously issued OpenGL commands
to begin execution, thus guaranteeing that they
complete in finite time.

glViewport(): adjusts the pixel rectangle for
drawing to be the entire new window.

The single parameter glClear() indicates which
buffers are to be cleared. In this case, the
program clears only the color buffer, where the
image displayed on the screen is kept.
Cont..

To set a color, use the command glColor3f().

It takes three parameters, all of which are
floating-point numbers between 0.0 and 1.0.

The parameters are, in order, the red, green,
and blue components of the color.

Example :
glColor3f(0.0, 0.0, 0.0); /* black */
glColor3f(1.0, 1.0, 1.0); /* white */

glColor3f(1.0, 0.0, 0.0); /* red */

glColor3f(0.0, 1.0, 0.0); /* green */

glColor3f(1.0, 1.0, 0.0); /* yellow */
Points
 Object of zero dimension (infinitely small)

 Specified by a set of floating-point


numbers (coordinates) called a vertex

 Displayed as a single pixel on screen

 void glPointSize(Glfloat size);


 Sets the size of a rendered point in pixels
Specifying Vertices
 void glVertex{234}{sifd}[v](TYPE coords);
 Specifies a vertex for use in describing a geometric
object
 glVertex2s(2,4);
 glVertex4f(2.3, 1.0, -2.2, 2.0);

 GLdouble dvect[3] = {5.0, 9.0, 4.0);

 glVertex3dv(dvect);

 OpenGL works in homogeneous coordinates


 vertex:: (x, y, z, w)
 w = 1 for default
Displaying Vertices
 Bracket a set of vertices between a call to
glBegin() and a call to glEnd() pair
 Theargument GL_POINTS passed to glBegin()
means drawing vertices in the form of the points
 glBegin(GL_POINTS);
glVertex2f(0.0, 0.0); glVertex2f(4.0,
0.0);
glVertex2f(4.0, 4.0);
glVertex2f(0.0, 4.0);
 glEnd();

 Other drawing options for vertex-data list


 Lines (GL_LINES)
 Polygon (GL_POLYGON)
Lines
 The term line refers to a line segment

 Specified by the vertices at their endpoints

 Displayed solid

 Smooth curves from line segments


Drawing Lines
 To draw a vertex-data list as lines
 glBegin(GL_LINES);
 glVertex2f(0.0, 0.0);
 glVertex2f(4.0, 0.0);
 glVertex2f(4.0, 4.0);
 glVertex2f(0.0, 4.0);
 glEnd();

 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

 Specified by vertices at the corners

 Displayed as solid with the pixels in the interior filled in


Examples: Triangle and Pentagon
Drawing Polygon
 Draw a vertex-data list as a polygon
 glBegin(GL_POLYGON);
 glVertex2f(0.0, 0.0);
 glVertex2f(4.0, 0.0);
 glVertex2f(4.0, 4.0);
 glVertex2f(0.0, 4.0);
 glEnd();

 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.

 void glCullFace(GLenum mode);


 Indicates which polygons (back-facing or
front-facing) should be discarded (culled)
 Needs to be enabled.
Stippling Polygons
 Void glPolygonStipple(const GLbyte *mask);
 Defines the current stipple pattern for the filled polygons.
 The argument is a pointer to a 32x32 bitmap (a mask of
0s and 1s).
 Where 1 appears the corresponding pixel is drawn and o
appears to be not drawn.
 Needs to be enabled and disabled.
 glEnable(GL_POLYGON_STIPPLE);
 glDisable(GL_POLYGON_STIPPLE);
Normal Vectors
 Points in a direction that’s perpendicular
to a surface.
 The normal vectors are used in lighting
calculations.
 void glNormal3(bsidf)(TYPE nx, TYPE
ny, TYPE nz);
 Sets the current normal vector as specified
by the arguments.
 void glNormal3(bsidf)v(const TYPE *v);
 Vector version supplying a single array v of
three element.

For a flat surface, one perpendicular direction is
the same for every point on the surface,

But for a general curved surface, the normal
direction might be different at each point on the
surface.

With OpenGL, you can specify a normal for
each polygon or for each vertex.

Vertices of the same polygon might share the
same normal (for a flat surface) or have different
normals (for a curved surface).

But you can’t assign normals anywhere other
than at the vertices.
Finding Normal Vector
 Make two vectors from any three vertices v1, v2 and v3
 P = v1 - v2; Q = v2 - v3

 Cross product of these vectors is perpendicular to


polygonal surface
 N = P x Q = [Px Py Pz] x [Qx Qy Qz]
 = [PyQz-QyPz) (QxPz-PxQz) (PxQy-QxPy]
 = [Nx Ny Nz]

 Normalize the vector v3


 n = [nx ny nz] = [Nx/L Ny/L Nz/L]
 where L is length of the vector [Nx Ny Nz]
v1 Q

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};

glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, frontIndices);


glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, rightIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, bottomIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, backIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, leftIndices);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, topIndices);
Or better still, crunch all the indices together:
static GLubyte allIndices = {4, 5, 6, 7, 1, 2, 6, 5, 0, 1, 5, 4, 0, 3, 2, 1, 0,
4, 7, 3, 2, 3, 7, 6};
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, allIndices);

Note that it is an error to encapsulate glDrawElements() between a
glBegin()/glEnd() pair.

With both glArrayElement() and glDrawElements(), it is also possible
that your OpenGL implementation caches recently processed vertices,
allowing your application to "share" or "reuse" vertices.

Take the aforementioned cube, for example, which has six faces
(polygons) but only eight vertices.

Each vertex is used by exactly three faces.

Without glArrayElement() or glDrawElements(), rendering all six faces
would require processing twenty−four vertices.

implementation of OpenGL may be able to minimize redundancy and
process as few as eight vertices.
Dereference a Sequence of Array Elements

While glArrayElement() and glDrawElements() "hop
around" your data arrays, glDrawArrays() plows straight
through them.
void glDrawArrays(GLenum mode, GLint first, GLsizei count);

Constructs a sequence of geometric primitives using array
elements starting at first and ending at first +count−1 of
each enabled array.

mode specifies what kinds of primitives are constructed
and is one of the same values accepted by glBegin();
for example, GL_POLYGON, GL_LINE_LOOP, GL_LINES,
GL_POINTS, and so on.
Attribute Groups

OpenGL groups related state variables
into an attribute group.

For example, the GL_LINE_BIT attribute
consists of five state variables:

the line width, the GL_LINE_STIPPLE
enable status, the line stipple pattern, the
line stipple repeat counter, and the
GL_LINE_SMOOTH enable status.

Some state variables are in more than one
attribute group.
For example, the state variable,
GL_CULL_FACE, is part of both the polygon
and the enable attribute groups.

The special mask, GL_ALL_ATTRIB_BITS, is
used to save and restore all the state variables
in all the attribute groups

You might also like