Chapter 3
Chapter 3
ATTRIBUTES OF
GRAPHICS PRIMITIVES
Chapter outline
2
• Introduction
• Color attributes
• Point attributes
• Line attributes
• Fill-Area Attributes
• Character Attributes
• Aliasing
Introduction
3
Attributes of graphics primitives can be defined a parameter that affects the way the primitive is
displayed.
For instance the drawing color and the way the line is drew defines line attributes.
State system (or state machine)
o A graphics system that maintains a list for the current values of attributes and other parameters
(state variables or state parameters).
o We assign a value to one or more state parameters, that is, we put the system into a certain state.
o The state will be persistent until we change the value of a state parameter
o The graphics system behaviors are determined by these system state, which can be modified by
calling OpenGL functions.
Introduction
4
We have two color state variables namely drawing and the background color variables.
we can define colors in two different ways:
RGB: the color is defined as the combination of its red, green and blue components.
RGBA: the color is defined as the combination of its red, green and blue components
together with an alpha value, which indicates the degree of opacity/transparency of the
color.
The background color was defined with an alpha value, whereas the drawing color did
not.
If no alpha value is defined it is assumed to be equal to 1, which is completely opaque.
7
Reduce the amount of storage required by just storing an index for each pixel in the frame buffer.
The actual colors are stored in a separate look-up table, and the index looks up a color in this
table.
Therefore, using color look-up tables, we can only have a limited number of different colors in
the scene.
Although color look-up tables do save storage, they slow down the rasterization process as an
extra look-up operation is required.
Color look-up was commonly used in the early days of computer graphics when memory was
expensive.
OpenGL uses direct storage by default, but the programmer can choose to use a color look-up
table if they wish.
8
We change the current drawing color using the glColor* function and the
current background color using the glClearColor function.
The background color is always set using an RGBA color representation
OpenGL Color Functions
9
In an OpenGL color routines use one function to set the color for the display window, and use
another function to specify a color for the straight-line segment, points etc.
Set the color display mode to RGB with the statement
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
The first constant in the argument list states that we are using a single buffer for the frame buffer,
and the second constant puts us into the RGB mode, which is the default color mode.
In the RGB (or RGBA) mode, we select the current color components with the
function
glColor* (colorComponents);
Suffix codes are similar to those for the glVertex function.
We use a code of either 3 or 4 to specify the RGB or RGBA mode along with
the numerical data-type code and an optional vector suffix.
OpenGL Color Functions
10
The suffix codes for the numerical data types are b (byte), i (integer), s (short), f (float), and d
(double).
Floating-point values for the color components are in the range from 0.0 to 1.0, and the default color
components for glColor.
glColor3f(1.0,0.0,0.0); // set drawing color to red.
glClearColor(1.0,1.0,1.0,1.0); // set background color to opaque white.
An OpenGL color selection can be assigned to individual point positions
within
glBegin/glEnd pairs
we can define alpha values for background colors, these values will not be used unless we enable the
color blending feature of OpenGL.
To use color blending in OpenGL we use the line:
glEnable(GL_BLEND);
Point Attributes
11
Points are the simplest type of primitive, so the only attributes we can modify are the
color and size of the point.
In a state system, the displayed color and size of a point is determined by the current
values stored in the attribute list.
Color components are set with RGB values or an index into a color table.
For a raster system, point size is an integer multiple of the pixel size,
so that a large point is displayed as a square block of pixels
12
15
If |m| ≤ 1 plot extra pixels vertically, i.e. same x-coordinate, different y-
coordinate, as in Figure 2(a).
If |m| > 1, plot extra pixels horizontally, i.e. same y-coordinate, different x-
coordinate, as in Figure 2(b).
16
Although this approach is simple and effective, there are two slight problems:
The actual thickness of a plotted line depends on its slope. Although this is a small
weakness of the technique most graphics packages do not attempt to address this problem.
You can notice this effect in, for example, the Paint accessory in Microsoft Windows.
The ends of lines are either vertical or horizontal. Depending on whether we are plotting
extra pixels in the horizontal or vertical directions, the line ends will be horizontal or
vertical.
Line Style
The style of a line refers to whether it is plotted as a solid line, dotted, or dashed.
The normal approach to changing line style is to define a pixel mask.
A pixel mask specifies a sequence of bit values that determine whether pixels in the plotted
line should be on or off.
OpenGL Line Attribute Functions
17
For example, the pixel mask 11111000 means a dash length of 5 pixels followed by a spacing of 3 pixels.
In other words, if the bit in the pixel mask is a 1, we plot a pixel, and if it is a zero, we leave a space.
OpenGL Line Attribute Functions
OpenGL Line-color Function
The line color is specified using the built in function
glColor3*(RGB);
OpenGL Line-Width Function
Line width is set in OpenGL with the function
glLineWidth (width);
We assign a floating-point value to parameter width, and this value is rounded to the nearest nonnegative
integer.
If the input value rounds to 0.0, the line is displayed with a standard width of 1.0, which is the default
width.
18
Fill Styles
A basic fill-area attribute provided by a general graphics library is the display style of the interior.
We can display a region with a single color, a specified fill pattern, or in a “hollow” style by showing
only the boundary of the region.
These three fill styles are illustrated in Fig below
Fill-Area Attributes
1. Scan-line approach: Scan-line fill algorithms are automatic (i.e. they require no user
intervention) and are commonly used by general-purpose graphics packages such as
OpenGL.
The scan-line fill algorithm automatically fills any non-degenerate polygon by
considering each scan-line (i.e. row of the frame buffer) in turn.
We move across the scan-line, from left-to-right, until we reach a boundary
Then we start plotting pixels in the fill color and continue to move
across the scan-line.
When we reach another boundary we stop filling. At the next boundary we start filling
again, and so on
Scan-line approach:
23
The starting point (i.e. the far left of the scan-line) is assumed to be outside the polygon,
so points between the first and second boundary crossings are assumed to be inside.
This process is illustrated in Figure 9.
The scan-line fill algorithm works well for simple polygons, but there are cases in which
it can experience problems. We now consider such a case, illustrated in Figure 10.
The scan-line algorithm must always treat vertices as two boundary crossings:
if we did not then as we crossed the vertex in scan-line x in Figure 10 the algorithm
would stop filling when it should continue.
Scan-line approach:
24
Seed-based fill algorithms have the advantage that they can fill arbitrarily complex
shapes.
They are less efficient than scan-line algorithms, and require user interaction in the form
of specifying a seed-point (i.e. a starting point for the fill, known to be inside the
boundary).
Therefore they are typically used by interactive packages such as paint programs.
In this section we will examine two similar techniques: boundary-fill and flood-fill.
Both are recursive in nature and work by starting from the seed point and painting
outwards until some boundary condition is met.
The difference between the two algorithms is in the nature of the boundary condition.
Boundary fill
27
One question that we must answer before implementing boundary-fill is ,what exactly
we mean by a neighboring point.
Figure 12 shows that there are two possible interpretations of a neighbour: 4-connected
and 8-connected neighbors'.
Both interpretations can be useful, although using 8-connected neighbours can lead to
the algorithm, escaping‟ from thin diagonal boundaries, so 4-connected neighbours are
more commonly used.
Boundary fill
29
Another issue that we must consider is what to do if the region to be filled is already partly
filled.
For example, in Figure 13 the boundary color is grey, the fill color is red and the seed-point is
the pixel marked by the letter ‘S’
Since boundary-fill will not process any pixels that are already in the fill color, in this
example only half of the fill-area will be filled:
The algorithm will stop when it reaches the already-filled pixels.
One solution to this problem is to preprocess the fill area to remove any partly-filled areas.
Boundary fill
30
Flood Fill:
31
It is very similar to boundary-fill, but instead of filling until it reaches a particular boundary color, it
continues to fill whilst the pixels are in specific interior color.
Therefore, first we must define a seed point, a fill color and an interior color.
Pseudocode for flood-fill is given below:
Start with seed point
If current pixel in interior color:
Fill pixel using fill color
Again, for flood-fill we have the same issues regarding partly-filled areas and what we mean by a
neighboring pixel.
Actually the two algorithms are very similar, and in many cases their operation will be identical.
But flood fill can be more useful for cases where the boundary is not in a single color. such as that shown
in Figure 14
Flood Fill:
32
OpenGL Fill-Area Attribute Functions
OpenGL provides a number of features to modify33the appearance of fill-area polygons.
First, we can choose to fill the polygon or just display an outline (i.e. wireframe rendering).
We do this by changing the display mode using the glPolygonMode routine. The basic form of this
function is:
glPolygonMode(face, displayMode) ;
Here, the face argument can take any of the following values:
GL_FRONT: apply changes to front-faces of polygons only.
GL_BACK: apply changes to back-faces of polygons only.
GL_FRONT_AND_BACK: apply changes to front and back faces of polygons.
The displayMode argument can take any of these values:
GL_FILL: fill the polygon faces.
GL_LINE: draw only the edges of the polygons (wireframe rendering).
GL_POINT: draw only the vertices of the polygons.
34
For example, the following code draws a polygon with four vertices using wireframe
rendering for the front face.
In addition to changing the polygon drawing mode, we can also specify a fill pattern
for polygons.
We do this using the polygon stipple feature of OpenGL. The steps can be
summarized as:
Define a fill pattern
Enable the polygon stipple feature of OpenGL
Draw polygons For example, the following code draws an eight-sided polygon with a
35
Character primitives can be used to display text characters. There are two different
types of representation for characters:
1. Bitmap :
Using a bitmap representation (or font), characters are stored as a grid of pixel values.
This is a simple representation that allows fast rendering of the character.
However, such representations are not easily scalable:
If we want to draw a larger version of a character defined using a bitmap, we will get an
aliasing effect (the edges of the characters will appear jagged due to the low resolution).
Character Attributes
37
40
OpenGL on its own does not contain any routines dedicated to drawing text characters.
However, the glut library does contain two different routines for drawing individual
characters (not strings).
Raster position: specifies where the character should be drawn.
We need to do this only once for each sequence of characters. After each character is drawn
the raster position will be automatically updated ready for drawing the next character.
To set the raster position we use the glRasterPos2i routine.
For example, glRasterPos2i(x, y) positions the raster at coordinate location (x, y).
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, ‘a’);
This will draw the character “a” in a monospace bitmap font with width 9 and height 15
pixels.
42
There are a number of alternative symbolic constants that we can use in place of
GLUT_BITMAP_9_BY_15 to specify different types of bitmap font. For example,
GLUT_BITMAP_8_BY_13
GLUT_BITMAP_9_BY_15.
We can specify proportional bitmap fonts using the following symbolic constants:
GLUT_BITMAP_TIMES_ROMAN_10
GLUT_BITMAP_HELVETICA_10
Here, the number represents the height of the font. Alternatively, we can use stroke fonts
using the glutStrokeCharacter routine. For example,
glutStrokeCharacter(GLUT_STROKE_ROMAN, ‘a’);
This will draw the letter “a” using the Roman stroke font, which is a proportional font. We
can specify a monospace stroke font using the following symbolic constant:
GLUT_STROKE_MONO_ROMAN
43
The attributes that change the appearance of character primitives are:
Size
Style/font
Color
46
The term antialiasing refers to any technique (hardware or software) that compensates for the effects of
aliasing.
There are three possible anti-aliasing algorithms.
Super-sampling
Area sampling
Pixel phasing
Supper-sampling
The super-sampling technique is also known as postfiltering
It attempts to compensate for the effects of under-sampling (i.e. reduced resolution) by super-sampling
(increasing the resolution) before plotting.
To plot an antialiased line, the basic idea of supersampling is as follows:
Super-sample‟ the image (i.e. increase its resolution).
Plot the line in the supersampled image.
Count the number of plotted points within each corresponding „real‟ pixel.
Plot the real‟ pixel with an intensity that is proportional to the count of supersampled pixels
Supper-sampling
47
For example, Figure 21 shows a supersampled image (to the left) with a straight-line
plotted in it.
‘Real pixels in the original image correspond to a 3x3 block of pixels in the
supersampled image.
To find the intensity for each original pixel, we count the number of supersampled
pixels that are on‟.
For the bottom left ‘real pixel there are three plotted supersampled pixels – this is the
maximum number possible, so we plot this pixels with the maximum intensity (in this
case, black).
For the bottom centre pixel, there is only one supersampled pixel that is ‘on’,
so we use an intensity that is 1/3 of the maximum.
Supersampling
48
For the center pixel there are two supersampled pixels that are ‘on, so we
plot this pixel with 2/3 the maximum intensity, and so on.
The overall effect of this approach is to ‘blur’ the edges of the line slightly,
reducing the staircase effect.
Area Sampling
49
In practice, computing the exact area of overlap can be time consuming.
Therefore a simplified implementation of area sampling approximates the
area by counting supersampled pixels that are inside the primitive.
This is illustrated in Figure 23(b).
So if there are 6 overlapping supersampled pixels (as in the bottom-left
‘real’ pixel), we say that the area of overlap is approximately 6/9 = 67%.
In fact, this approximation of area sampling is very similar to the
supersampling technique described above.
Pixel Phasing
51
Supersampling and area sampling were both software techniques, i.e. they were
algorithms that processed image data to produce antialiased image data.
The final technique, pixel phasing, is a hardware technique.
Therefore, it is not possible to use pixel phasing to perform antialiasing
unless you are using a display monitor that uses it.
The basic idea is that the CRT beam is shifted by a fraction of a pixel to bring the plotted
pixels closer to the true mathematical line.
The hardware normally enables the pixel position to be shifted by 1/2, 1/3, or 1/4 of a
pixel.
Some systems allow the pixel size to be adjusted too.
Although this technique can produce impressive results, most monitors do not support it
so specialised hardware is necessary.
OpenGL Anti-Aliasing Functions
52