Chap 5
Chap 5
GL_LINE_STRIP
Connected line segments
(a polyline)
GL_LINE_LOOP
Connected line segments, and last
point connected to first point
Line Attributes
Line Attribute
- Line Style
- Line Width
- Line Color
- Pen & Brush options
Wide Lines:
• void glLineWidth(GLfloat width);-default width is 1.0
• . Without antialiasing, widths of 1, 2, and 3 draw lines 1,
2, and 3 pixels wide.
• With antialiasing enabled, noninteger line widths are
possible
• GL_ALIASED_LINE_WIDTH_RANGE with
glGetFloatv()- obtain the range of supported aliased line
widths
• To determine the supported minimum and maximum
sizes of antialiased line widths, and what granularity your
implementation supports, call glGetFloatv(), with
GL_SMOOTH_LINE_WIDTH_RANGE and
GL_SMOOTH_LINE_WIDTH_GRANULARITY
Line Drawing
Description:
Given the specification for a straight line, find the collection of
addressable pixels which most closely approximates this line.
Goals:
Straight lines should appear straight
lines should start and end accurately, matching endpoints with
connecting line
Lines should have constant brightness
Lines should be drawn as rapidly as possible
Problems:
How do we determine which pixels to illuminate to satisfy the
above goals
Vertical, horizontal, and lines with slope = + / - 1, are easy to draw.
Other create problems: stair-case/jaggies/aliasing
It is difficult to determine whether a pixel belongs to an object or not.
Direct Solution:
Solve y = mx + b, where (0, b) is the y-intercept and m is the slope.
Go from 𝑥0 to 𝑥1 :
calculate round(y) from the equation.
Take an example, b = 1 (starting point (0,1)) and m = 3/5.
Then
x = 1, y = 2 = round(8/5)
x = 2, y = 2 = round(11/5)
x = 3, y = 3 = round(14/5)
x = 4, y = 3 = round(17/5)
x = 5, y = 4 = round(20/5)
ideal case of line drawn in graph paper
Choice of pixels in the raster, as integer values:
x = 1, y = 2 = round(8/5)
x = 2, y = 2 = round(11/5)
x = 3, y = 3 = round(14/5)
x = 4, y = 3 = round(17/5)
x = 5, y = 4 = round(20/5)
Rewrite as:
Gives:
Choice: E or NE?
If F(x, y) > 0; then mid point is available below the line
If F(x, y) < 0; then mid point is available above the line
Algorithm for next choice:
if F(M) > 0 /* Q is above M*//* mid point is below line*/
then select NE pixel
else /* Q is below M*/ /*mid point is above line*/
select E
In this figure: Q is above the midpoint
That means line path is near to the NE
Pixel so based on algorithm we can
Choose the NE pixel to draw the line.
Texture Fill
Solid Fill Pattern Fill
Fill-area primitives are normally polygons, as they can be
filled more efficiently by graphics packages
Fill-Area algorithms are used to fill the interior of a
polygonal shape
If the polygon is to be filled we can specify a fill style
Options for filling a defined region include
- choice between a solid color or a pattern fill and
- choices for particular colors and patterns
Polygons are 2-D shapes whose boundary is formed by any
number of connected straight-line segments
- defined by 3 or more coplanar vertices (points positioned on the
same plane)
- Each pair of adjacent vertices is connected in sequence by edges
OpenGL Polygon Fill-Area Functions
To fill polygons with a fill-area pattern:
- Define the pattern
- Enable polygon-fill feature of OpenGL
- Draw polygons
A number of different ways:
glRect*
6 different symbolic constants
For all:
Polygons must be convex (all interior angles ≤ 180o)
Must specify vertices in anti-clockwise order when
viewing the polygon from “outside”
Default fill-style is solid color, determined by current
color settings
glRect*
OpenGL provides special routine that takes 2-D points only
glRect* (x1, y1, x2, y2)
(x1,y1) and (x2,y2) define opposite corners of the rectangle
when we call the glRect* routine, OpenGL will construct a
polygon with vertices defined in the following order:
(x1,y1), (x2,y1), (x2,y2), (x1,y2).
e.g: glRecti(200,100,50,250);
We can draw rectangles with
other functions, but glRect*can
be more efficient
All other fill-area functions use the functions
glBegin… glEnd:
GL_POLYGON
GL_TRIANGLES
GL_TRIANGLE_STRIP
GL_TRAINGLE_FAN
GL_QUADS
GL_QUAD_STRIP
GL_POLYGON:
Displays a single convex polygon
Vertices of the polygon are specified in anti-clockwise
direction
E.g.
glBegin(GL_POLYGON);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glVertex2iv(p6);
glEnd();
GL_TRIANGLES:
Vertex list treated as groups of 3 triangle vertices
Vertices must be specified in anti-clockwise order
E.g.
glBegin(GL_TRIANGLES);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p6);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glEnd();
GL_TRIANGLE_STRIP:
Displays set of connected triangles
First triangle vertices must be anti-clockwise
E.g.
glBegin(GL_TRIANGLE_STRIP);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p6);
glVertex2iv(p3);
glVertex2iv(p5);
glVertex2iv(p4);
glEnd();
GL_TRIANGLE_FAN:
First vertex is the ‘source’ of the fan
Subsequent pairs of vertices form triangles with the
first one
E.g.
glBegin(GL_TRIANGLE_FAN);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glVertex2iv(p6);
glEnd();
GL_QUADS:
Vertex list treated as groups of 4 quadrilateral
vertices
Vertices must be specified in anti-clockwise order,
glBegin(GL_QUADS);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glVertex2iv(p6);
glVertex2iv(p7);
glVertex2iv(p8);
glEnd();
GL_QUAD_STRIP:
One quadrilateral drawn for each pair of vertices
after the first two
glBegin(GL_QUAD_STRIP);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glVertex2iv(p6);
glVertex2iv(p7);
glVertex2iv(p8);
glEnd();
Polygon Details:
• A polygon has two sides—front and back—and might be rendered differently
depending on which side is facing the viewer
• By default, both front and back faces are drawn in the same way. To change
this, or to draw only outlines or vertices, use glPolygonMode().
• void glPolygonMode(GLenum face, GLenum mode);-Controls the drawing
mode for a polygon’s front and back faces.
• The parameter face can be GL_FRONT_AND_BACK, GL_FRONT, or
GL_BACK;
• mode can be GL_POINT, GL_LINE, or GL_FILL to indicate whether the
polygon should be drawn as points, outlined, or filled.
• By default, both the front and back faces are drawn filled. For example; you
can have the front faces filled and the back faces outlined with two calls to
this routine:
• glPolygonMode(GL_FRONT, GL_FILL);
• glPolygonMode(GL_BACK, GL_LINE);
Reversing and Culling Polygon Faces:
Polygons whose vertices appear in counterclockwise order on the
screen are called front-facing.
We can define any surface of any orientationand all clockwise
polygons or all counterclockwise polygons.
• void glFrontFace(GLenum mode);-Controls how front-facing
polygons are determined.
• By default, mode is GL_CCW, to selects counter clockwise
polygons as front facing.
• If mode is GL_CW selects clockwise polygons as front facing.
• void glCullFace(GLenum mode);Indicates which polygons should
be discarded (culled) before they’re converted to screen
coordinates.
• The mode is either GL_FRONT, GL_BACK, or
GL_FRONT_AND_BACK to indicate front-facing, back-facing,
or all polygons.
• To take effect, culling must be enabled using glEnable() with
GL_CULL_FACE; it can be disabled with glDisable() and the
same argument.
• A normal vector (or normal, for short) is a vector that
points in a direction that’s perpendicular to a surface.
• 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).
• You can’t assign normals anywhere other than at the
vertices.
• normal vectors define the orientation of its surface in
space—in particular, its orientation relative to light sources.
• These vectors are used by OpenGL to determine how
much light the object receives at its vertices.
• An object’s normal vectors define the orientation of its
surface in space—in particular, its orientation relative to
light sources.
• These vectors are used by OpenGL to determine how
much light the object receives at its vertices.
• glNormal*() to set the current normal to the value of the
argument passed in.
• Subsequent calls to glVertex*() cause the specified vertices
to be assigned the current normal.
• Often, each vertex has a different normal, which necessitates a
series of alternating calls, as in the below Example.
glBegin (GL_POLYGON);
glNormal3fv(n0); glVertex3fv(v0); glNormal3fv(n1);
glVertex3fv(v1);
glNormal3fv(n2); glVertex3fv(v2);
glNormal3fv(n3);glVertex3fv(v3);
glEnd();
• void glNormal3{bsidf}(TYPE nx, TYPE ny, TYPE nz);
• void glNormal3{bsidf}v(const TYPE *v);
• Sets the current normal vector as specified by the arguments.
The nonvector version (without the v) takes three arguments,
which specify an (nx, ny, nz) vector that’s taken to be the
normal. Alternatively, you can use the vector version of this
function (with the v) and supply a single array of three
elements to specify the desired normal.
• Vertex Array:
• OpenGL requires many function calls to render
geometric primitives.
• Drawing a 20-sided polygon requires at least 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 between
adjacent polygons
• For example, the cube in Figure has six faces
and eight shared vertices. Unfortunately, if
the standard method of describing this
object is used, each vertex has to be
specified three times: once for every face
that uses it. Therefore, 24 vertices are
processed, even though eight would be
enough
• Using vertex arrays can reduces the number of function calls,
which improves performance. Also, using vertex arrays may
allow reuse of already processed shared vertices.
• There are three steps to using vertex arrays to render
geometry:
• Enabling Arrays
• Activate (enable) the appropriate arrays, with each storing a
different type of data: vertex coordinates, surface normals,
RGBA colors, secondary colors, color indices, fog
coordinates, texture coordinates, polygon edge flags, or
vertex attributes for use in a vertex shader
• Specifying Data for the Arrays
• Put data into the array or arrays. The arrays are accessed by
the addresses of that is, pointers to) their memory locations
• Dereferencing and Rendering
• Draw geometry with the data. OpenGL obtains the data
from all activated arrays by dereferencing the pointers
• 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.
• The symbolic constants GL_VERTEX_ARRAY,
GL_COLOR_ARRAY,
GL_SECONDARY_COLOR_ARRAY,
GL_INDEX_ARRAY, GL_NORMAL_ARRAY,
GL_FOG_COORD_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);
• To deactivate the above functions: use the
glEnableClientState() with the same above
symbolic constants
• void glDisableClientState(GLenum array);
• Specifying Data for the Arrays:
• 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 vertices. If stride is 0, the vertices are
understood to be tightly packed in the array.
• Other similar methods are:
• void glColorPointer(GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer);
• void glSecondaryColorPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer);
• void glIndexPointer(GLenum type, GLsizei stride, const
GLvoid *pointer);
• void glNormalPointer(GLenum type, GLsizei stride, const
GLvoid *pointer);
• void glFogCoordPointer(GLenum type, GLsizei stride, const
GLvoid *pointer);
• void glTexCoordPointer(GLint size, GLenum type, GLsizei
stride, const GLvoid *pointer);
• void glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer);
Step 3: Dereferencing and Rendering
• In Step 3, contents of the arrays are obtained, sent
to the server, and then sent down the graphics
processing pipeline for rendering.
• Dereferencing 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(),
glSecondaryColor3[type]v(), glIndex[type]v(),
glNormal3[type]v(), and glFogCoord[type]v(). glArrayElement()
is usually called between glBegin() and glEnd().
• Example Using glArrayElement() to Define Colors and
Vertices
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(3, GL_FLOAT, 0, colors);
glVertexPointer(2, GL_INT, 0, vertices);
glBegin(GL_TRIANGLES);
glArrayElement(2);
glArrayElement(3);
glArrayElement(5);
glEnd();
Character Primitives
Many pictures require text
attributes: Font size, Color and Orientation
Attributes can be set both for entire character strings
(text) and for individual characters
Most graphics packages have some support for
displaying character primitives
Type Faces (fonts) can be divided into two:
Serif – has small lines or accents at the ends of the main
character stroke. And so makes readable.
Sans-Serif – does not have accents.
Arial is a sans-serif font
Verdana is a sans-serif font
Times Roman is a serif font
Garamond is a serif font
Another category of fonts
Monospace font: always take up the same width on the display,
regardless of which character is being drawn
Proportional fonts: width used on the display will be
proportional to the actual width of the character
00111000
01101100
11000110
11000110
11111110
11000110
11000110
00000000
Stroke(outline)
Defined using line/curve primitives
Each character represented (stored) as a series of line
segments
Takes longer time draw than bitmap fonts
we can change the font, colour, and also line width and
line style
width of these lines can be changed using
glLineWidth
style using
glLineStipple
OpenGL Character Primitives
glut library supports display of
character primitives
All characters displayed at current raster position:
glRasterPos2i(x, y);
Bitmap characters are drawn using
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, ‘a’);
To change colour of the character use
glColor* routine
Stroke characters, e.g.
glutStrokeCharacter(GLUT_STROKE_ROMAN_10, ‘a’);
Basic State Management:
• OpenGL maintains many states and state variables. An object may be rendered
with lighting, texturing, hidden surface removal, fog, and other states affecting
its appearance.
• By default, most of these states are initially inactive. These states may be costly
to activate.for example, turning on texture mapping will almost certainly slow
down the process of rendering a primitive.
• To turn many of these states on and off, use these two simple commands:
void glEnable(GLenum capability);
void glDisable(GLenum capability);
• glEnable() turns on a capability, and glDisable() turns it off. More than 60
enumerated values can be passed as parameters to glEnable() or glDisable().
Eg:GL_BLEND GL_DEPTH_TEST, GL_FOG, GL_LINE_STIPPLE and
GL_LIGHTING.
• To check whether a state is currently enabled or disabled.
GLboolean glIsEnabled(GLenum capability);
Returns GL_TRUE or GL_FALSE, depending on whether or not the queried
capability is currently activated.