0% found this document useful (0 votes)
16 views60 pages

Autocad, 3D Max Opengl Opengl Opengl Open Graphic Library: Opengl Rendering Opengl Opengl

Uploaded by

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

Autocad, 3D Max Opengl Opengl Opengl Open Graphic Library: Opengl Rendering Opengl Opengl

Uploaded by

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

Autocad , 3D Max

OpenGl
OpenGL
Open Graphic Library OpenGL

OpenGL
OpenGL
OpenGL

OpenGL rendering
OpenGL

OpenGL
OpenGL
OS/2 Linux Windows OpenGL
OpenGL
Graphical Device Interface GDI OpenGL
GDI32.DLL GDI
GDI
GLU32.DLL OpenGL
OpenGL32.DLL

OpenGL
gl OpenGL
glClearColor opengl32.lib
GL OpenGL
GL _ COLOR_ BUFFER_BIT Underscore
3 glColor3f() 3f
OpenGL f

OpenGL c
GLbyte Signed char 8 Bit b
GLshort short 16 Bit s
GLint , GLsizei Long 32 Bit i
GLfloat,GLclampf Float 32 Bit f
GLdouble , GLclamped double 64 Bit d
GLubyte , GLboolean Unsigned char 8 Bit ub
GLushort Unsigned short 16 Bit us
GLunit , GLenum , Unsigned long 32 Bit ui
GLbitfield

2
Computer Graphics CS 330 Spring 2011

Chapter 1,
Introduction to Computer Graphics (C.G.)

1.1 WHAT IS COMPUTER GRAPHICS?


C.G. is pictures that generated by a computer.
o Found in magazines, on TV, typeset of characters.
o natural.
o Have an artificial feeling to achieve some visual effect.
o Mixing real and imagined scene in movies.

C.G. is a tools used to make pictures.


o Hardware tools include

input devices as point to items and draw figures


the computer itself is a hardware tool
o Software tools
Graphics libraries have functions to
Draw a simple line, circle, characters, ..
Draw and manage windows with pull-down menus and
Set up a camera in 3D to make snapshots of objects stored in database.

1.2 WHERE COMPUTER-GENERATE PICTURE ARE USED


C.G. can draw pictures of actual objects, and it can also draw things that never existed. The programmer
describes an object through some algorithms, and the program generates a picture from this model.
1. Art, Entertainment, and Publishing
o Used in production of movies, television programs, books, and magazines.
o The cost of the graphics systems decreased besides the software.
o Create special effects, animation, and high-quality publications.

Movie, Production, Animation, and Special Effects


Computer animations are seen on T.V.
Animations are created by writing a sequence of images onto film or videotape, each image being only
slightly different from the one before. When the film is played back at 20 to 30 frames a second, the
human eye blend the image and see smooth motion.
Computer Games
The player moves joysticks and pulls triggers, and the computer-generated image responds instantly.
Browsing on the World Wide Web
The user moves the mouse to a spot on the screen and click to choose the next Web site to visit. The
browser must be rapidly interpret the data and draw it on the screen as high quality text and graphics.
Side, Book, and Magazine Design
The user can interactively move text and graphics around to find the most pleasing arrangement.
A paint system is another tool for generating images by computer. The user sketching, using a tablet or
light pen, and selecting colors and patterns to create the desired effects.

2. Computer Graphics and Image processing


C.G. task is to create pictures and image in a computer.
Dr Taleb Obaid 1/1

Computer Graphics CS 330 Spring 2011

Image processing task is to improve or alter images that were created elsewhere. Processing can remove
specks, enhance the contrast, and sharpen its image and highlight, as in Fig 1.2.

Fig 1.2, enhancing an image, (a) Original, (b) Enhancement

3. Monitoring a process
Complex systems (factories, power plants,..) must be monitored to watch out (by human) for impending
trouble, as in Fig 1.3.

Fig 1.3, Monitoring a manufacturing process

4. Displaying Simulations
A variety of systems can be profitably simulated. These systems might be exist, never be built, or exist
only as equations and algorithms. Flight simulator as shown in Fig. 1.4

Dr Taleb Obaid 1/2


Computer Graphics CS 330 Spring 2011

Fig 1.4, A woman wear a head-mounted display and data gloves to interact with a virtual world

5. Computer-Aided Design
A number of disciplines use computer graphics to facilitate the design of system or product. The
computer holds a model of device in memory, and a picture based on the model is displayed for user to
examine.
Computer-aided Architectural Design
C.G. can help architects design buildings. Architect can make adjustments to the floor plan, moving a
wall, adjusting a window.

Electrical-aided Architectural Design


The model in Fig 1.5 shows a symbolic description of an electronic circuit that might form part of a new
computer. The designer can add new circuit elements (gates) by selecting from a menu of icons and
dragging to desired position in the circuit. The designer can add, delete, and connect gates.

6. Scientific Analysis and Visualization


Scientific data are complex and the relationships among the variable can be difficult to visualize. Graphics
is a good tool to represent scientific information. When data are displayed, you have new insights into
the process you are investigating.

Dr Taleb Obaid 1/3

Computer Graphics CS 330 Spring 2011

Fig1.5, Digital logic design application

Fig 1.7, Mathematical displays of (a) a complex mathematical surface and (b) a mathematical defined
solid object.

Dr Taleb Obaid 1/4


Computer Graphics CS 330 Spring 2011

1.3 ELEMENTS OF PICTURES CREATED IN COMPUTER GRAPHICS

The basic objects of pictures are composed are called output primitives, such as polylines, text, filled
region, and raster images.
The attributes of a graphic primitive are the characteristics that affect how it appears, such as color and
thickness.
1. Polylines
A polylines is a connected sequence of straight lines.

Fig 1.8, (a) A polyline drawing of a dinosaur, (b) A plot of a mathematical function,
(c) A wire-frame rendering of three dimensional object.

Polylines can appear as a smooth curve, Fig 1.9. shows a blowup of a curve, revealing its underlying
short line segments.

Fig 1.9, A curved line made up of straight-line segments.

Pictures made up of polylines are called line drawing.


A line segment is specified by its two endpoints (x1, y1) and (x 2, y2) . a drawing routine for line might be
drawLine (x1, y1, x2, y2);
A dot might be programmed using the routine
drawDot (x1, y1).
A polyline with several lines, these lines call an edge, and two adjacent lines meet at a vertex.
Polyline are specified as a list of vertices,
(x0, y0), (x1, y0 n, yn).

Dr Taleb Obaid 1/5

Computer Graphics CS 330 Spring 2011

Fig 1.10, A sample polyline

To draw polylines, we will need a tool such as the routine


drawPolyline (poly);
where the variable poly is a list of endpoints (xi, yi).

A polyline need not form a closed figure, but if the first and last points are connected by an edge, the
polyline is a polygon, as in Fig. 1.11

Fig 1.11, Examples of polyline

Attribute of Lines and Polylines


Ployline attributes are the color and thickness of its edges, the manner in which the edges are dashed,
and in which thick edges blend together at endpoints, as in Fig. 1.12 and 1.13, the routines such as:
setDash (dash7) or setLineThickness (thickness)

Fig 1.12, Polylines with different attributes

Dr Taleb Obaid 1/6


Computer Graphics CS 330 Spring 2011

Fig 1.13, Some ways of joining two thick lines is a polyline

2. Text
There are two display modes:
Text mode: used for simple input and output of characters to control the operating system or edit the
code in a program. A built-in character generating alphabetic, numeric, and punctuation characters

Graphics mode offers a richer set of character shapes than text mode, as in Fig 1.14
drawstring (x, y, string);
Text Attributes
font (type face), color, size, spacing, and orientation. Font is a specific
set of character shapes in a particular style and size, as in Fig 1.15.

Fig 1.14, some text drawn graphically

The shape of character can be defined by a polyline or by an arrangement of dots, as in Fig 1.16.

Fig 1.15, Some examples of fonts.

Dr Taleb Obaid 1/7

Computer Graphics CS 330 Spring 2011

Fig 1.16, A character shape defined by (a) a polyline and (b) a pattern of dots.

3. Filled Regions
The filled region (fill area) primitive is a shape filled with some color or pattern. The boundary is a polygon
as in Fig. 1.17.

Fig 1.17, Examples of filled polygons

One would use a routine like


fillPolygon (poly, pattern);
where poly is a variable hold the data for the polygon, and pattern contains some description of the
pattern used for filling. Fig. 1.18 shows the use of filled regions to shade the different faces of a 3D object.

Fig. 1.18, Filling polygonal faces of 3D objects to suggest proper shading

Dr Taleb Obaid 1/8


Computer Graphics CS 330 Spring 2011

4. Raster Image
cell
pixel see the individual cells; instead, it blends them together and
synthesizes an overall picture.

Fig 1.19, (a) A raster image of a chess. (b) A blowup of the image.

A raster image is stored in a computer as an array of numerical values. Each value represents the value
of the pixel stored there pixel map bitmap
figure represented as a bit map, (b) shows the numerical values of the pixel map for the upper left 6x8
portion.

Fig 1.20, A simple figure represented as a bit map.

How are raster image created?


1. Hand-designed images
A designer figures out what values are needed for each cell and types them into memory.
2. Computed Images

Dr Taleb Obaid 1/9

Computer Graphics CS 330 Spring 2011

An algorithm is used to render a scene, which might be modeled abstractly in computer memory.
For example a scene might consist of a single yellow, smooth sphere illuminated by a light source
that emanates orange light.

3. Scanned Image
A photograph or television image can be digitized. A grid is placed over the original image, and at
each grid point, the closest
thereby created is then stored in a file for later use.

5. Representation of Shades of Gray and color in Raster Images


An important aspect of a raster image is the manner in which the various shades of gray or colors are
represented in the bitmap. The most common methods:

1. Gray-scale Raster Images


If there are only two pixel values in a raster image, it is called bi-level, -bit-per-

Fig 1.26 (a) A bi-level image of a curser,


(b) A bit map of the image.

When the pixels in a gray-scale image take on more than two values. Gray-scale are classified in
terms of their pixel depth, the number of bits needed to represent their gray levels. There are 2n
gray levels in an image with pixel depth n. the common values:
Two bits per pixel produce 4 gray levels.

Dr Taleb Obaid 1 / 10
Computer Graphics CS 330 Spring 2011

Four bits per pixel produce 16 gray levels.


Eight bits per pixel produce 256 gray levels.

Fig 1.27, Sixteen (4-bit) levels of gray

Effect of Pixel Depth: Gray-scale Quantization


When an image uses eight bits per pixel is altered so that fewer bits per pixel are utilized, this caused to
loss a significant in quantity. This effect is called banding.

Fig 1.22, A scanned image Fig .24, Examples of image enhancement.

2. Color Raster Images


Color images are desirable more than gray-
numerical value that somehow represents a color. The common way is to describe a color as a
combination of amounts of red, green, and blue light. Each pixel value is an ordered triple, such as (23,
14, 51) that describes the intensities of the red, green, and blue components.
The number of bits used to represent the color of each pixel is called the color depth of the pixel.

Fig 1.31, A common correspondence between color value and perceived color.

Dr Taleb Obaid 1 / 11

Computer Graphics CS 330 Spring 2011

The highest quality images, known as true-color images, have a color depth of 24 and so use a byte for
each component.

1.4 GRAPHICS DISPLAY DEVICES


The hardware devices include video monitors, plotter, and printers. A rich variety of graphics displays
has been developed.

1. Line-Drawing Display
The pen plotter is an example, which moves a pen invisibly over a piece of paper to some spot that is
specified by the computer, puts the pen down, and then sweeps the pen across to another spot, leaving
of a line drawing is related to the precision with which the pen
is positioned and the sharpness of the lines are drawn.
Kinds of pen plotter:
Flatbed Plotter, move the pen in two dimensions over a stationary sheet of paper.
Drum Plotter, move the paper back and forth at the top of the drum to provide the other direction.
There are also video displays vector random-scan calligraphic
line drawings. These devices have internal circuitry to sweep an electronic beam from point to point
leaving a glowing trail.
Vector displays cannot show smoothly-shaded regions, so is usually simulated by cross-hatching with
different line pattern, as in Fig 1.33.

Fig 1.33, Cross-hatching to simulate filling a region


2. Raster Display
The most familiar raster displays are video monitor connected to PCs and workstations, and the flat-
panel display to portable PCs.
Other common displays produce hard copy of an image: laser printer, dot matrix, ink-jet plotter, and
film recorder.
Raster devices have a display surface on which the image is presented. As in Fig 1.35.

Fig 1.35, The built-in coordinate system for the surface of a raster display.

Dr Taleb Obaid 1 / 12
Computer Graphics CS 330 Spring 2011

Raster displays are connected to a frame buffer, a region of memory sufficiently large to hold all of the
pixel values, (i.e., to hold the bit map of the image). Figure 1.36 suggests how an image is created and
display

Fig 1.36, Block diagram of a computer with raster display

In this figure, the graphics program is stored in system memory and executed instruction by instruction
by CPU. The program computes the values (color) for each pixel and loads the values into the frame
buffer. A
appropriate physical spot on the display surface. The convector takes a pixel value and converts it to the
corresponding quantity that produce a spot of the color on the display.
The Scanning Process
Figure 1.37 provide details of the scanning process. Main issue is how each pixel value in the frame buffer

Fig 1.37, Scanning out an image from the frame buffer to the display surface.

In this figure, each pixels in frame buffer have 2-D address (x, y) and have a specific memory location
mem [x][y]. the scan controller send logical address (x, y) to the frame buffer and simultaneously,

Dr Taleb Obaid 1 / 13

Computer Graphics CS 330 Spring 2011

physical (geometric) position (x, y) on the display surface. The value mem [x][y] is
converted to a color and sent to the proper physical position.

Video Monitors
Based on a cathode-ray tube (CRT). Figure 1.38 adds some details on the conversion process from pixel

Fig

1.38, Operation of a color video monitor display system

green,
and blue components use a pair of bits. The pairs are fed to three Digital-to-Analog Convectors which
convert logical values like 01 into actual voltage.

Fig 1.39, Input-Output characteristic of a two-bit DAC

The red, green, and blue components of a pixel each use a pair of bits. The pairs are fed to three digital-
to-analog converters (DACs) , which convert logical values like 01 into actual voltages, as in Fig 1.39,
where max is the largest voltage level the DAC can produce.
The scan controller addresses one pixel value, mem[x][y], in the frame buffer at the same time

Dr Taleb Obaid 1 / 14
Computer Graphics CS 330 Spring 2011

coils. The glow of a phosphor dot quickly fades when the stimulus is removed, a CRT image must be
refreshed to prevent disturbing flicker.
Scanning proceeds row by row through the frame buffer, each row providing pixel values for one
scan line across the CRT. The order of scanning is usually from left to right along a scan line and from
top to bottom.
The expensive systems have a frame buffer that supports 24 planes of memory. Each of the DACs has
eight input bits, so there are 256 levels of red, 256 of green, and 256 of blue, the total 224 = 16 million
colors.
The monochrome video display a single color in different intensities. The CRT has only on type of
phosphor; so, produce various intensities of one color.
In fig 1.38, the pixel values 001101 send

3. Index Color and the Lookup Table


some systems use a method of associating pixel values with colors, a color lookup table (LUT).

Fig 1.40, A color display system that incorporate an LUT.

The color depth is six bits stored in each pixel. These bits are used as an index into a table of 64 (=26)
values,
In Fig 1.40, LUT[39] contains the 15-
5 others drive
under program control, using some system routine such as setPalette()
setPalette (39, 17, 25, 4);
would set the value in LUT [39] to 15-bit quantity 10001 11001 00100 (since 17 is 10001 in binary, 25 is
11001, and 4 is 00100).
drawDot (479, 532, 39); // set pixel at (479, 532) to value 39

Dr Taleb Obaid 1 / 15

Computer Graphics CS 330 Spring 2011

Suppose that a raster display system has a color depth of b bits and that each LUT entry is w bits wide.
Then the system can display 2w colors, any 2b at one time.
To compare the costs of two systems, one with an LUT and one without, Fig 1.41 shows an example of
two 1,024-by-1,280-pixel displays (1.3 million pixel).

Fig 1.41, Comparison of Two raster display system

System 1 (expensive) The first system has a 24-bit-per-pixel frame buffer and no LUT, so each of its 1.3
million pixel (=224) colors. The amount of memory required for the frame buffer in this system is
1,024x1,280x24 bits (6 megabytes).

System 2 (inexpensive) The second has an 8-bit-per-pixel frame buffer along with an LUT, and the LUT is
24 bits wide. The system can display 224 different colors, but only 256 at a time. The amount of memory
is 1,024x1,280x8 (1 megabyte).

4 Other Raster Display Devices


flat-panel displays, as Fig 1.42. each pixel is addressed by a horizontal
grid wire and a vertical grid wire. In the case of a liquid crystal display (LCD), the electric field alters the
polarization of log crystalline molecules in the LCD material. The light either allows to pass through the
panel or prevents it from passing through.

Active matrix panels are LCD panels that have a tiny transistor at each pixel location. The transistor
responds to the electric field to allowing the display of different levels of brightness. This transistor has
memory that holds the crystals in their adjusted state , so that the display need not be refreshed.

The plasma panel displays has similar to Fig 1.42, but the material in the effective places a tiny neon bulb
at pixel location. This bulb is turned on or off.

Dr Taleb Obaid 1 / 16
Computer Graphics CS 330 Spring 2011

Fig 1.42, Flat-panel display

5 Hard-Copy Raster Devices


Film recorders The screen is a strip of photographic film, and the electron beam exposes the film as
it sweeps over it (once) in a raster pattern.
Laser printer Scan out raster patters from an internal frame buffer, rapidly sweeping a laser beam
over an internal drawing surface.
Inkjet plotter Produce hard-copy raster images in color. A tiny nozzle sweep over the paper and

Dot matrix prints place dots at a density of 70 dots per inch (dpi). Laser produce densities of 600 dpi, so
produce very high-quality graphics.

1.5 GRAPHICS INPUT PRIMITIVES AND DEVICE


Many input devices let the user control the computer.
1. Types of Input Graphics Primitives
Each device transmits a particular kind of data to the program. Different types of data are called input
primitives:
String, producing a string of characters and thus modeling the action of a keyboard.
Choice, reports a selection from a fixed number of item.
Valuator, produces a real value between 0.0 and 1.0, to fix the length of a line, the speed of an action,
the size of a picture.
Locator, a basic requirement in interactive graphics is to allow the user to point to a position on the
display. The locator input primitive performs this function.
Pick, is used to identify a portion of a picture for further processing.

Dr Taleb Obaid 1 / 17

Computer Graphics CS 330 Spring 2011

2. Types of Physical Input Devices


Keyboard, sends strings of characters to the application upon request. Some have cursor keys or function
keys used to produce choice input primitives.
Buttons, the user presses one of the buttons to perform a choice input function.
Mouse, as the user slides the mouse over the desktop, the mouse sends information about the changes
in its position to the workstation. The mouse is used to perform a locate or a pick function.
Tablet, like a mouse, is used to generate locate or pick input primitives. The user can tape a picture onto
the surface of the tablet and then move the stylus over it, pressing down to send information about each
new point that is selected to the workstation.

Fig 1.45, A graphics Tablet

Joystick and Trackball, Joystick has a lever that can be pivoted in any direction to indicate position. The
trackball has a large ball that can be rotated in any direction with the thumb to alter the position of the
cursor.

Knobs, used for interactive design of three-dimensional objects. The user can rotate a displayed object
in three dimensions by adjusting the position of three separate knobs.

Space Ball and Data Glove, Both are designed to give a user explicit control over several variables at
once, by performing hand and finger motions.

Digitizing Three-dimensional Objects and Capturing Motion


Fig 1.49, shows a device that can measure the locations of points in space, allowing three-dimensional
shapes to captured. Fig 1.50, can track the position of several points on a moving body allowing the
detailed motions of a dancer to be captured.

Dr Taleb Obaid 1 / 18
Computer Graphics CS 330 Spring 2011

Fig 1.49, Digitizing a three-dimensional shape.

Fig 1.50,

Dr Taleb Obaid 1 / 19

Computer Graphics CS 330 Spring 2011

Chapter 2,
Getting Started; Drawing Figures
Goals
Writing programs that produce pictures.
Learn the basic ingredients found in every OpenGL program.
Develop some elementary graphics tools for drawing lines, polylines, and polygons.
Develop tools that allow the user to control a program with mouse and keyboard.

2.1 GETTING STARTED MAKING PICTURES


To get stared, you need an environment that let you write and execute programs. This environment
includes hardware to display pictures and a library of software tools. Every graphics program begins with
Initializations that establish the desired display mode.

Fig 2.1, Some common varieties of display layouts

Fig 2.1(a), entire screen is used foe drawing. Coordinates x and y are measured in pixels, with x increasing
to the right and y in creasing downward.
Fig. 2.1(b), different rectangular windows on the display screen at one time. Initialization involves creating
and opening a new window for graphics.
Fig 2.1(c),
upward.

The basic tool has:


setPixel (x, y, color); sets the individual pixel at location (x, y) to the color specified by color.

line (x1, y1, x2, y2); draws a line between (x1, y1) and (x 2, y2).

To draw Fig 2.1 we may used:


line (100, 50, 150, 80);
line (150, 80, 0, 290);
moveto (x, y); moves the pen invisibly to location (x, y).
lineto (x, y) draws a line from the current position to (x, y)
To draw Fig 2.1 we may used:
Dr Taleb Obaid 2/1
Computer Graphics CS 330 Spring 2011

moveto (100, 50);


lineto (150, 80);
lineto (0, 290);

1. Device-independent Programming and OpenGL


Writing graphics applications is made available, can be complied and run on a variety of graphics
environments, with the guarantee that will produce nearly identical graphical output on each display. This
is known as device-independent graphics programming, OpenGL offer such a tool.

call to produce graphics.

2. Windows-based Programming
Many graphics systems are windows based and manage the display of multiple overlapping windows. The
user can move windows around and resize them.

Event-driven Programming
Means that the program responds to various events, such as click a mouse, press a key, resize a window.
The programmer organizes a program as a collection of callback functions that are executed when events
occur.

glutMouseFunct (myMouse); // register the mouse action function


register the function myMouse () as the function to be executed when a mouse event occurs.

Fig 2.2, shows a skeleton of an example main () function.

void main ( ) {
initialize things
create a screen window
glutDisplayFunc (myDisplay) ; // register the redraw function
glutReshapeFunc (myReshape) ; // register the reshape function
glutMouseFunc (myMouse) ; // register the mouse action function
glutKeyboardFunc (myKeyboard) ; // register the keyboard action function
perhaps initialize other things
glutMainLoop ();
}
all of the callback functions are defined here

Fig 2.2 A skeleton of an event-driven program using OpenGL

There are
glutDisplayFunc (myDisplay);
event. This happens when the window is first opened and when the window is exposed by moving
another window off of it. The function myDisplay () is registered as the callback function for a
redraw event.

Dr Taleb Obaid 2/2

Computer Graphics CS 330 Spring 2011

glutReshapeFunction (myReshap); screen windows can be reshaped by the user, dragging a corner
of the window to new position with mouse. myReshape () is registered with the reshape events,
and automatically passed arguments that report the new width and height of the reshape window.

glutMouseFunc (myMouse); when one mouse buttons is pressed or released, a mouse event
occurs. The function myMouse () is automatically passed arguments that describe the location of
the mouse and nature of the action.

glutKeyboardFunc (myKeyboard); registers the function mykeyaboard () with event of pressing or


releasing some key on the keyboard and automatically passed arguments that tell which key was
pressed.

If a program does not make use of a mouse (or keyboard), the corresponding callback function need not
be registered or written. The mouse click (or key pressed) have no effect in the program.

3. Opening a Window for Drawing


The first task in making pictures is to open a screen window for drawing. Fig 2.3 show entire main ()
function to draw graphics in a screen window.

void main (int argc, char** argv {


glutInit (&argc, argv); // initialize the toolkit
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowSize (640,480); // set window size
glutInitWindowPosition (100, 150); // set window position on screen
glutCreateWindow ("my first attempt"); // open the screen window
// register the callback functions
glutDisplayFunc (myDisplay);
glutReshapeFunc (myReshape);
glutMouseFunc (myMouse);
glutKeyboardFunc (myKeyboard);
myInit (); // additional initializations as necessary
glutMainLoop(); // go into a perpetual loop
}

Fig 2.3, Code using the OpenGL Utility Toolkit to open the initial window for drawing.

The first five calls use the OpenGL Utility Toolkit to open a window for drawing.
glutInit (&argc, argv); This function initialize the OpenGL Utility Toolkit. Its arguments are the
standard ones for passing information about the command lines.
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); specifies how the display should be initialized.
The built-in constants GLUT_SINGLE and GLUT_RGB, which are ORed together, indicate that a
single display buffer should be allocated and that colors are specified.
glutInitWindowSize (640,480); specifies the screen window should initially be 640 pixel wide by
480 pixel high. You may resize the window as desired.

Dr Taleb Obaid 2/3


Computer Graphics CS 330 Spring 2011

glutInitWindowPosition (100, 150


positioned on the screen 100 pixels over from the left edge and 150 pixels down from the top. You
can move this window wherever desired.
glutCreateWindow ("my first attempt"); This function actually opens and displays the screen

2. DRAWING BASIC GRAPHICS PRIMITIVES


The drawing commands will be placed in the callback function associated with a redraw event, such as
myDisplay () function.
We first establish the coordinate system where the objects will appear. We begin with an intuitive
coordinate system, which is 640 pixel wide by 480 pixels high.

Fig 2.4, The initial coordinate system for drawing

OpenGL provides tools for drawing all of the output primitives. To draw object, you pass a list of vertices.
The list occurs between two functions glBegin () and glEnd ().

glBegin (GL_POINTS);
glVertex2i (100, 50);
glVertex2i (100, 130);
glVertex2i (150, 130);
glEnd ();

Fig 2.5, Drawing three dots


Dr Taleb Obaid 2/4

Computer Graphics CS 330 Spring 2011

The constant GL_POINTS is built-into OpenGL. To draw other primitives, you replace GL_POINTS with
GL_LINES, GL_POLYGON, etc.
The function glVertex2i () have several variations, that distinguish the number and type of arguments
passed to the function, as in Fig 2.6.

Fig 2.6, Format of OpenGL command

indicates a function from OpenGL library. Then basic command root, followed by the number of
arguments sent to the function (3 and 4), the argument i for integer, f or d for a floating-point value).

OpenGL Data Types


The OpenGL types are listed in Fig 2.7.

Fig
2.7,

Command suffixes and argument data types

Dr Taleb Obaid 2/5


Computer Graphics CS 330 Spring 2011

-bit integer, when your use 16-bit integer, this caused a problem
as in the following code.

void drawDot (int x, int y) { danger: pass ints


glBegin (GL_POINTS); // draw dot at integer point (x, y)
glVertex2i ( x, y);
glEnd ();
}

The safer code as:


void drawDot (GLint x, GLint y) {
glBegin (GL_POINTS); // draw dot at integer point (x, y)
glVertex2i ( x, y);
glEnd ();
}

The OpenGL State


OpenGL keeps track of many state variables, such as current size of a point, color,
values of a state variable remains active until a new value is given.
The color of a drawing can be specified using

glColor3f (1.0,0.0, 0.0); // set drawing color to red


glColor3f (0.0,0.0, 0.0); // set drawing color to black
glColor3f (1.0,1.0, 1.0); // set drawing color to white
glColor3f (1.0,1.0, 0.0); // set drawing color to yellow

The background color is set with glClearColor (red, green, blue, alpha) , where alpha specifies a degree of
transparency. To clear the entire window to the background color, use
glClear (GL_COLOR_BUFFER_BIT).
The argument GL_COLOR_BUFFER_BIT is a constant.

Establishing the Coordinate System


The coordinate system will seem obscure here, but latter will be clearer. OpenGL performs a large number
of transformations using matrices to do this, and the command in myInit (). The gluOrtho2D () routine sets
the transformation we need for screen window.
void myInit (void) {
glMatrixMode (GLPROJECTION);
glLoadIdentity ();
gluOrtho2D (0.0, 640.0, 0.0, 480.0);
}
Putting It All Together
Fig 2.10 shows a complete program that draws the lowly three dots. The initialization in myInit () set up
the coordinate system, the point size, the background color, and the drawing color. The drawing
Is encapsulated in the callback function myDisplay (). glFlush () is called after the dots are drawn, to ensure
that all data are processed and sent to the display.

Dr Taleb Obaid 2/6

Computer Graphics CS 330 Spring 2011

include <windows.h> // use as needed for your system


include <gl/Gl.h>
include <gl/glut.h>
myInit
void myInit (void) {
glClearColor (1.0,1.0,1.0,0.0); // set white background color
glColor3f (0.0f, 0.0f, 0.0f); // set the drawing color
glPointSize( 4.0);
glMatrixMode (GL_PROJECTION)
glLoadIdentity ();
gluOrtho2D (0.0, 640.0, 0.0, 480.0 );

myDisplay
void myDisplay(void {
glClear (GL_COLOR_BUFFER_BIT); // clear the screen
glBegin (GL_POINTS);
glVertex2i(100, 50); // draw three points
glVertex2i(100, 130);
glVertex2i(150, 130);
glEnd ()
glFlush(); // send all output to display

main
void main (int argc, char** argv {
glutInit (&argc, argv); // initialize the toolkit
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowSize (640,480); // set window size
glutInitWindowPosition (100, 150); // set window position on screen
glutCreateWindow ("my first attempt"); // open the screen window
glutDisplayFunc (myDisplay); // register redraw function
myInit ();
glutMainLoop (); // go into a perpetual loop
}

Drawing Dot Constellations


Example 2.12 Drawing the Sierpinski gasket produced by calling drawDot () many times with dot positions
(x0, y0), (x1, y1), (x2, y2
The kth point pk = (xk, yk) is based on the previous point pk-1 :

1. Choose three fixed points T0, T1, T2 to form triangle.


2. Choose the initial point p0 to be drawn by selecting one of the points T0, T1, and T2 at random.
3. Choose one of the three points at random; call it T.
4. Construct the next point pk as the midpoint between T and the previously found point pk-1. i.e.,
pk = midpoint of pk-1 and T.
5. Draw pk using drawDot ().

Dr Taleb Obaid 2/7


Computer Graphics CS 330 Spring 2011

6. back to step 3 until the pattern is satisfying filled in.

Fig 2.12, the Sierpinski Gasket Fig 2.13 Building the Sierpinski Gasket

We define a simple class GLintPoint, that describes a point whose coordinates areintegers.
class GLintPoint {
public:
GLint x, y ;
};
Initialize the array T of three points:
GLintPoint T[3] = { {10, 10}, {300, 30}, {200, 300} }.
We use i = random (3) to choose one points T[i] random, so returns one of the values 0, 1, 2. defined as

random (int m) {
return rand ( ) % m;
}

Fig 2.14, the algorithm, which generates 1000 points of Sierpinski gasket.

void Sierpinski(void) {
GLintPoint T[3]= {{10,10},{300,30},{200, 300}};
int index = random(3); // 0, 1, or 2 equally likely
GLintPoint point = T[index]; // initial point
drawDot(point.x, point.y); // draw initial point
for(int i = 0; i < 1000; i++) // draw 1000 dots
{
index = random(3);
point.x = (point.x + T[index].x) / 2;
point.y = (point.y + T[index].y) / 2;
drawDot (point.x, point.y); }
glFlush();
}

Dr Taleb Obaid 2/8

Computer Graphics CS 330 Spring 2011

Plot of function
f(x) = e-xcos (2 x)
for values of x between 0 and 4.
glBegin (GL_POINTS)
for (Gldouble x = 0; x < 4.0; x += 0.005)
glVsrtix2d (x, f(x));
glEnd ();
glFlush ();

-xcos (2 x) versus x.

The problems are:


Impossible tiny.
The negative values of f(.) will be lie below the window.
So, we need to scale and position the values plotted.

Scaling x, if the range 0 to 4 be scaled so that it covers the entire width of the screen window is screenWidth
pixel. S0,
sx = x * screenWidth / 4.0.
scaling and shifting y The values of f(x) lie between 1 and 1. Let the screen height of screenHeight pixels,
so
sy = (y + 1.0) * screenHeight / 2.0.
note that the conversions from x to sx and from y to sy are of the form
sx = Ax + B and
sy = Cy + D.
Fig 2.15 given the values of A, B, C, and D,
Gldouble A, B, C, D, x;
A = screenWidth / 4.0;
B = 0.0;
C = screenHeight / 2.0;
D = C;
glBegin (GL_POINTS)
for (Gldouble x = 0; x < 4.0; x += 0.005)
glVsrtix2d (A*x + B, C*f(x) + D);
glEnd ();
glFlush ();

Dr Taleb Obaid 2/9


Computer Graphics CS 330 Spring 2011

3. MAKING LINE DRAWLNGS


Every graphics system comes with routines to draw straight lines. OpenGL use GL_LINES as the argument
to glBgin (), and pass it the endpoints as vertices.

glBegin (GL_LINES); // use constant GL_LINES here


glVertex2i (40, 100);
glVertex2i (202, 96);
glEnd ();

The drawLineInt () routine as:

void drawLineInt (Glint x1, Glint y1, Glint x2, Glint y2) {
glBegin (GL_LINES); // use contsatnt GL_LINES here
glVertex2i (x1, y1);
glVertex2i (x2, y2);
glEnd ();
}

OpenGL provides tools for setting the attribute of line.


For color use glColor3f (0.0, 0.0, 0.0),
For thicker lines use glLineWidth (width),
Dotted or dashed lines as in case study 2.5 page 75.

Fig 2.17 Simple picture built from four lines.

3.1 Drawing Polylines and Polygons

by specifying the vertices between glBegin (GL_LINE_STRIP)

To make the polylie into a polygon, replace GL_LINE-STRIP with GL_LINE_LOOP as in Fig 2.18 b

Fig 2.18 A polyline and a polygon

Dr Taleb Obaid 2 / 10

Computer Graphics CS 330 Spring 2011

Ex 2.3.1 Drawing line graphs


Fig 2.19 shows an example, based on the function

f(x) = 300 100 cos (2 x/100) + 30 cos (4 x/100) + 6 cos (6 x/100)


as x varies in steps of 3 for 100 steps. The figure show a sequence of connected line segments, as in the
following cod.
glBegin ( GL_LINE_STRIP);
for (Gldoube x = 0; x < 4.0; x += 0.005) {
define func
glVertex2d (A*x + B, C* func + D);
}
glEnd ();
glFlush ;

Ex 2.3.2 Drawing polyline stored in a file


It is convenient to store a description of the polylines in a file, so that the picture can be redraw.
The file dino.dat contains a collection of polylines. Entire file is available on the web site of the book.

The following cod read from file dino.dat and draw dinosaur.

Dr Taleb Obaid 2 / 11
Computer Graphics CS 330 Spring 2011

Ex 2.3.3 Parameterizing figures


Fig

2.23 shows a simple house, the routine hardwireHouse () , can draw only one house in one size and one
location.

Fig 2.23, A House drawn sing hardwiredHouse ().

void hardwiredHouse (void) {


glBegin (GL_LINE_LOOP);
glVertex2i (40, 40); // draw the shell of house
glVertex2i (40, 90);
glVertex2i (70, 120);

Dr Taleb Obaid 2 / 12

Computer Graphics CS 330 Spring 2011

glVertex2i (100, 90);


glVertex2i (100, 40);
glEnd();

glBegin(GL_LINE_STRIP);
glVertex2i(50, 100); // draw the chimney
glVertex2i(50, 120);
glVertex2i(60, 120);
glVertex2i(60, 110);
glEnd();

// draw the door


// draw the window
}

We can draw families of objects by different parameter values, as in routine parameterizedHouse (), Fig
2.26

Fig 2.26, A village of houses drawn using parameterizedHouse ().

void parameterizedHouse ( GLintPoint peak, GLint width, GLint height)


// the top of house is at the peak; the size of house is given by height and width
{
glBegin (GL_LINE_LOOP);
glVertex2i (peak.x, peak.y); // draw shell of house
glVertex2i (peak.x + width / 2, peak.y - 3 * height /8);
glVertex2i (peak.x + width / 2 peak.y - height);
glVertex2i (peak.x - width / 2, peak.y - height);
glVertex2i (peak.x - width / 2, peak.y - 3 * height /8);
glEnd();
draw chimney, door, and window in the same fashion
}

Dr Taleb Obaid 2 / 13
Computer Graphics CS 330 Spring 2011

Ex 2.3.4 Building a polyline drawer


Some application compute and store the vertices of polyline in a list. We add to our toolbox of routines a
function that accepts the list as a parameter and draws the corresponding polyline.

class Glint PointArray {


const int MAX_NUM = 100;
public:
int num;
GlintPoint pt[MAX_NUM];
};

Fig 2.27 Data type for a linked list of vertices.

Fig 2.28 shows implementation of polyline-drawing routine. The routine takes a parameter closed . The
value of closed sets the argument of glBegin ().

void drawPolyLine (GLintPointArray poly, int closed) {


glBegin (closed ? GL_LINE_LOOP : GL_LINE_STRIP) ;
for (int i = 0; i < poly.num; i++)
glVertex2i (poly.pt[i].x, poly.pt[i].y) ;
glEnd () ;
glFlush () ;
}

Fig 2.28 A linked list data type and drawing a polyline or polygon

2.3.2 Line drawing using moveto () and lineto ()


The effects of the two functions as:
moveto (x, y) : set Current Position (CP) to (x, y)
lineto (x, y) : draw a line from CP to (x, y), the update CP to (x, y).

A polyline based on the list of points (x0, y0 n, yn)


moveto ( x[0], y[0]);
for ( int i = 1; i < n; i++)
lineto ( x[i], y[i]);

#include <windows.h>
#include <GL\GL.h>
class GlintPoint {
public:
GLint x, y;
};
// draw the line

Dr Taleb Obaid 2 / 14

Computer Graphics CS 330 Spring 2011

GLintPoint CP; // global current position


//<<<<<<<<<<<<< moveto >>>>>>>>>>>>>>
void moveto (GLint x, GLint y) {
CP.x = x; CP.y = y; // update the CP
}
//<<<<<<<<<<<< lineTo >>>>>>>>>>>>>>>>>
void lineto (GLint x, GLint y) {
glBegin (GL_LINES);
glVertex2i (CP.x, CP.y);
glVertex2i (x, y);
glEnd ();
glFlush ();
CP.x = x; CP.y = y; // update the CP
}

Fig .29 Defining moveto () ans lineto () OpenGL

2.3.3 Drawing Aligned Rectangles


If a polygon sides are aligned with the coordinate axes, this polygon called aligned rectangle. OpenGL
provides the ready made function.
glRecti (Glint x1, Glint y1, Glint x2, Glint y2);
// draw a rectangle with opposite corner (x1, y1) and (x2, y2);

Fig 2.30 shows what is drawn by the following code:


glClear (1., 1., 1., 0.) ; // white background
glClear (GL_COLOR_BUFFER_BIT); // clear the window
glColor3f (0.6, 0.6, 0.6); // bright gray
glRecti (20.0, 20.0, 100, 70);
glColor3f (0.6, 0.6, 0.6); // dark gray
glRecti (20.0, 20.0, 100, 70);
glFlush ();

Fig 2.30 Two aligned rectangles filled with colors

flurry
(a). Checkerboard in (b),

Dr Taleb Obaid 2 / 15
Computer Graphics CS 330 Spring 2011

//<<<<<<<<<<<<<<< CheckerBoard >>>>>>>>>>>>>


void CheckerBoard(void) {
glClear(GL_COLOR_BUFFER_BIT); // clear the screen
GLdouble r1=0.8, g1=0.8, b1=0.8, r2=0.5, g2=0.5, b2=0.5;
GLint i, j, X1, Y1, X2, Y2, Size = 10;
for ( i=0; i<8; i++)
for ( j=0; j<8; j++) {
if ((i+j) % 2 == 0)
glColor3f (r1, g1, b1);
else
glColor3f (r2, g2, b2);
X1 =100+ j*Size; Y1 =100+ i*Size;
X2 = X1 + Size; Y2 = Y1 + Size;
glRecti (X1, Y1, X2, Y2);
}

glFlush();
}

void drawFlurry (int num, int numColors, int Width, int Height) {
for (int i = 0; i < num; i++) {
GLint x1 = random (Width); // place corner randomly
GLint y1 = random (Height);
GLint x1 = random (Width); // pick the size so it fits
GLint y1 = random (Height);
Glfloat lev = random ( ); // random value, in range 0 to 1
GlColor3f (lev, lev, lev); // set the gray level
glRecti (x1, y1, x2, y2); }
glFlush (); }

2.3.4 Aspect Ration of an Aligned Rectangle


The principal properties of an aligned rectangle are its size, position, color and shape. Its shape is
embodied in its aspect ratio (the ratio of its width to its height,

Dr Taleb Obaid 2 / 16

Computer Graphics CS 330 Spring 2011

aspect ratio = width / height)

Fig 2.32 Examples of aspect ratios of aligned


rectangles.

PRACTIC EXERCISES
2.3.1 Drawing the checkerboard
2.3.2 Alternative ways to specify a rectangle
Instead of two opposite corners, there are:
Its center point, height, and width.
Its upper left corner, width, and aspect ratio.

Write functions drawRectangleCenter (), and drawRectangleCornerSize ().

2.3.3 Different aspect ratio

2.34 Drawing the parametrized house

2.3.5 Scaling and positioning a figure by using parameters


2.3.5 Filling Polygons
OpenGL supports filling convex polygons with a pattern or color.

void ChestBoard (void) {


glClear(GL_COLOR_BUFFER_BIT); // clear the screen
int i,j, N=8, Size=20, Cx=100, Cy=100, X1, Y1;
for ( i=0; i<N; i++)
for ( j=0; j<N; j++) {
if ( (i+j) % 2 == 0)
glColor3f (0, 0 ,0);
else
glColor3f (1, 1, 1);
X1 = Cx + j*Size;
Y1 = Cy + i*Size;
Dr Taleb Obaid 2 / 17
Computer Graphics CS 330 Spring 2011

glRecti(X1, Y1, X1+Size, Y1+Size);


}
glFlush(); // send all output to display
}

Dr Taleb Obaid 2 / 18

Computer Graphics CS 330 Spring 2011

Convex polygon: A polygon is convex if a line connecting any two points of the polygon lines entirely
within it.

Fig 2.35 Convex and non-convex polygons.


Only D, E, and F are convex.

The polygon will be filled in the current color. It can also be filled with a stipple pattern, and paint images
into polygons (texture).

Fig 2.36 several filled convex polygon.

2.3.6 Other Graphics Primitives in OpenGL


Fig 2.37 shows five other objects that OpenGL supports the drawing. The following constant used in glBegin
():
GL_TRIANGLES: takes the list vertices three at a time and draws a separate triangle for each.
GL_QUADS: takes the vertices four at a time and draws a separate quadrilateral for each.
GL_TRIANGLE_STRIP: draws a series of triangles based on triples of vertices: v0, v1, v3,then v2, v1,
v3, then v2,v3, v4, etc.
GL_TRIANGLE_FAN: draws a series of quadrilaterals based on foursomes of vertices: v0, v1, v2, then
v0, v2, v3, then v0,v3,v4, etc.
GL_QUAD_STRIP: draws a series of quadrilaterals based on foursomes of vertices: first v0, v1, v3, v4,
then v2, v3, v5, v4, then v4, v5, v7, v6, etc

Dr Taleb Obaid 2 / 19
Computer Graphics CS 330 Spring 2011

Fig 2.37 Other geometric primitive types

GL_POINTS GL_LINES GL_LINE_STRIP

Dr Taleb Obaid 2 / 20

Computer Graphics CS 330 Spring 2011

Dr Taleb Obaid 2 / 21
Computer Graphics CS 330 Spring 2011

GL_LINE_LOOP
GL_TRIANGLES
GL_TRIANGLE_STRIP

GL_QUADS GL_QUAD_STRIP GL_TRIANGLE_FAN

2.4 SIMPLE INTERACTION WITH THE MOUSE AND KEYBOARD


Interactive graphics applications let the user control the flow of a program by: pointing and clicking the
mouse, pressing keys of the keyboard, using commands:
glutMouseFunc (myMouse), which register myMouse () with the event that occurs when the mouse
button is pressed or released.
glutMotionFunc (myMovedMouse), which register myMovedMouse () with the event that occurs when
the mouse button is moved while one of the buttons is pressed.
glutKeyboardFunc (myKeyboard), which register myKeyboard () with the event that occurs when a
keyboard is pressed.

Dr Taleb Obaid 2 / 22

Computer Graphics CS 330 Spring 2011

2.4.1 Mouse Interaction


We must design the callback function myMouse () to take four parameters:

void myMouse (int button, int state, int x, int y);


When a mouse event occurs, the system calls the registered function, supplying it with values for these
parameters.

The value button will be one of:


GLUT_LEFT_BUTTON,
GLUT_MIDDEL_BUTTON, and
GLUT_RIGHT_BUTTON,
The value of state will be one of GLUT_UP and GLUT_DOWN

The x value is the number of pixels from the left of the window. The y value is the number of pixel down
the top of the window.

Ex 2.4.1 Placing dots with the mouse

void myMouse (int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
drawDot (x, screenHeight y);
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
exit (-1);
}
exit ();
returns 1; // back to the operating system.

Ex 2.4.2 Specifying a rectangle with the mouse


The user be able to draw rectangles whose dimensions are entered with the mouse by clicking the mouse
at two points specify opposite corners, as in Fig 2.38:

void myMouse (int button, int state, int x, int y) {


static GLintPoint corner[2];
static int numCorners = 0; // initial value is 0
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
corner [numCorners] . x = x;
corner [numCorners] . y = screenHeight - y; // flip y coordinate
numCorners++; // have another point
if (numCorners == 2) {
glRecti (corner [0] . x, corner [0] . y, corner [1] . x, corner [1] . y);
numCorners = 0 ; // back to 0 corners
}
}
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
glClear (GL_COLOR_BUFFER_BIT); // clear the window

Dr Taleb Obaid 2 / 23
Computer Graphics CS 330 Spring 2011

glFlush();
}

Ex 2.4.3 Controlling the Sierpinski gasket with the mouse


The user can specify the three vertices of the initial triangle with the mouse. Gather the three points in an
array corner [], and draw the Sierpinsky gasket routine :
static GLintPoint corner [3];
static int numCorners = 0;
if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
corner [numCorners] . x = x;
corner [numCorners] . y = screenHeight y; // flip y
if (++numCorners == 3) {
Sierpinski (corners) ; // draw the gasket
NumCorners = 0 ; } } // back to 0 corner

Ex 2.4.4 Create a polyline using the mouse


Fig 2.39 created with mouse clicks. Retain all the points clicked, for later use. After each click of the mouse,
the window is cleared and entire current polyline is redrawn.

Fig 2.39 Interactive creation of a polyline.

void myMouse(int button, int state, int x, int y) {


#define NUM 20
static GLintPoint List[NUM];
static int last = -1; // last index used so far
// test for mouse button as well as for a full array
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN
&& last < NUM -1){
List [++last].x = x; // add new point to list
List [last].y = screenHeight - y; // window height is 480
glClear (GL_COLOR_BUFFER_BIT) ; // clear the screen

Dr Taleb Obaid 2 / 24

Computer Graphics CS 330 Spring 2011

glBegin (GL_LINE_STRIP); // redraw the polyline


for (int i = 0 ; i <= last ; i++)
glVertex2i (List[i].x, List[i].y) ;
glEnd ();
glFlush();
}
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
last = -1; // reset the list to empty
}

Fig 2.40 A polyline drawer based on mouse clicks


Mouse Motion
Av event of a different types is generated when the mouse is moved while some button is held down. The
callback function, myMoveMouse () is registered with this event by using
glutMotionFunc (myMovedMouse) ;

The callback function must take two parameters myMoveMouse (int x, int y); x and y are the mouse
position when the event occurred.

The callback function myMoveMouse () designed to draw a square at the current mouse position.
void myMovedMouse (int mouseX, int mouseY) {
Glint x = mouseX ; // grab the mouse position
Glint y = screenHeight mousey ; // flip it as usual
Glint brushSize = 5;
glRecti (x, y, x + brushSize, y + brushSize );
glFlush () ;
}

2.4.2 Keyboard Interaction


The callback function myKeyboard () is registered, by pressing a key on the keyboard, through
glutKeyboard (myKeyboard). The function must have the prototype

void myKeyboard (unsigned int key, int y) ;

void myKeyboard (unsigned char theKey, int mouseX, int mouseY) {


GLint x = mouseX;
GLint y = screenHeight mouseY ; // flip the y value as always
switch (theKey) {

break;
case GLUT_KEY_LEFT : List [++last].x = x; // add a point
List [ last] . y = y;

Dr Taleb Obaid 2 / 25
Computer Graphics CS 330 Spring 2011

break;
exit(-1); // terminate the program
default :
break ; // do nothing
}
}

Dr Taleb Obaid 2 / 26

Computer Graphics CS 330 Fall 2009

Chapter 3,
More Drawing Tools
Goals
Introduce viewports and clipping.
Develop the window-to-viewport transformation.
Develop a classical clipping algorithm.
Create tools to draw in world coordinates.
Develop ways to select windows and viewports for optimum viewing.
Draw complex pictures using relative drawing and turtle graphics.
Build figures based on regular polygons and their offspring.
Draw arcs and circles.
Describe parametrically defined curves and to see how to draw them.

INTRODUCTION
In Ch 2, our drawings used the basic coordinate system of the screen window:
Coordinates are in pixels, from zero to screenWidth-1 in x, and from zero to sereenHeight-1 in y. This
means that we can use only positive values of x and y. But, we may not want to think in terms of pixels:
It may think in terms of x varying from, say, -1 to 1, and y varying from -100.0 to 20.0. In this
chapter, we develop methods that let the programmer describe objects in whatever coordinate
system, and automatically scale and shift the picture of an object so that it "comes out right" in the
screen window. The space in which objects are described is called world coordinates, which are the
Cartesian xy-coordinates.
We define a rectangular world window , in world coordinates. The world window specifies which
part of the "world" should be drawn, i.e., whatever lies inside the window should be drawn and
whatever lies outside should be clipped away and not drawn.
We define also a rectangular viewport in the screen window. A mapping (consisting of scaling
and shifting) between the world window and the viewport is established so that when all the objects
in the world are drawn, the parts that lie inside the world window are automatically mapped to the
inside of the viewport. So, the programmer thinks in terms of "looking through a window" at the
objects being drawn and placing a "snapshot" of whatever is seen in that window into the viewport
on the display. This window-viewport approach makes it much easier to do natural things like
"zooming in" on a detail in a scene or "panning around" the scene.

WORLD WINDOWS AND VIEWPORTS


Suppose you want to examine the nature of a certain mathematical function, say.
sine (x) = sin ( x) / x
You want to know how the function bends and wiggles as x varies from - to . So you want a plot
that is centered at (0,0), and that shows sine (x) for closely spaced x-values between, say, -4.0 and 4.0,
as in Fig 3.1

Fig e

Dr Taleb Obaid 3/1


Computer Graphics CS 330 Fall 2009

void myDisplay (void) {


glBegin (GL_LINE_STRIP) ;
for (GLfloat x = -4.0 ; x < 4.0 ; x += 0.1) {
GLfloat y = sin (3.14159 * x) / (3.14159 * x);
glVertex2f (x, y);
}
glEnd ();
gIFlush ();

The key issue here is how the various (x, y) values become scaled and shifted so that the picture
appears properly in the screen window. We accomplish the proper scaling and shifting by setting up
a world window and viewport and then establishing a suitable mapping between them.

Fig 3.2 is an example of a world window and a viewport. The notion is that whatever lies in the world
window is scaled and shifted so that it appears in the viewport; everything else is clipped off and not
displayed.

Fig 3.2 A world window and a viewport

2.1 The Mapping from the Window to the Viewport


The world window is described by its left, top, right, and bottom borders as W.l, W.t, W.r, and W.b,
respectively.
The viewport is described in the coordinate system of the screen window by V.l, V.t, V.r, and V.b,
which are measured in pixels.

Fig 3.3 Specifying the window and viewport

Dr Taleb Obaid 3/2

Computer Graphics CS 330 Fall 2009

The world window and viewport do not have to have the same aspect ratio, although distortion results
if their aspect ratios differ, as in Fig 3.4.

Fig 3.4 A picture mapped from a window to a viewport

Here some distortion is produced.


We derive a mapping or transformation, called the window-to-viewport mapping. This mapping is
based on a formula that produces a point (sx, sy) in the screen window coordinates for any given point
(x, y) in the world. We want the mapping to be "proportional", if x is, say, 40% of the way over from
the left edge of the window, then sx is 40% of the way over from the left edge of the viewport.
Similarly, if y is some fraction f of the height of the window from the bottom, sy must be the same
fraction f up from the bottom of the viewport.

Proportionality forces the mappings to have the linear form


sx = Ax + C,
sx = By + D,
for some constants A, B, C, and D. The constants A and B scale the x and y coordinates, and C and D
shift (or translate) them. How can A, B, C, and D be determined?

Fig 3.5
Proportionality In mapping x to sx
The window-to-viewport transformation,

sx = Ax + C and sy = By + D.
with
A = (V.r V.l) / ( W.r W.l),
C = V.l AW.l
B = (V.t - V.b) / (W.t W.b) ,
D = V.b BW.b.

Dr Taleb Obaid 3/3


Computer Graphics CS 330 Fall 2009

The mapping can be used with any point (x, y) inside or outside the window. Points inside the window
map to points inside the viewport, and points outside the window map to points outside the viewport.

Carefully check the following properties:


if x is at the window's left edge (x = W.l), then sx is at the viewport's left edge (sx = V.l).
if x is at the window's right edge, then sx is at the viewport's right edge.
if x is a fraction f of the way across the window, then sx is a fraction f of the way across the viewport.
if x is outside the window to the left (x < w.l), then sx is outside the viewport to the left (sx < V.l), and
analogously if x is outside to the right.

Ex 3.2.1
Consider the window and viewport of Figure 3.6. The window has (W.l, W.r, W.b, W.t) = (0, 2.0 ,0 ,1.0),
and the viewport has(V.l, V.r, V.b, V.l) = (40, 400, 60, 300).

Fig 3.6 An example of a window and a viewport

Using the formulas, we obtain


A = 180, C = 40, B = 240, and D = 60.
Thus,
sx = 180x + 40; sy = 240y + 60.

We check that this mapping:


Each corner of the window is indeed mapped to the corresponding corner of the viewport. For
example, (2.0,1.0) maps to (400, 300).
The center of the window, (1.0,0.5), maps to the center of the viewport, (220, 180).

3.2.1 Building the mapping


Find values of A, B, C, and D for the case of world of (-100, 100, -60, 60)

Doing It in OpenGL
OpenGL makes it very easy, for 2D drawing, the world window is set by the function gluOrtho2D(),
and viewport is set by the function gIViewport () .These functions have the prototypes:

void gluOrtho2D (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) ;
Dr Taleb Obaid 3/4

Computer Graphics CS 330 Fall 2009

Which sets the window to have a lower left corner of (left, bottom) and an upper right corner of (right,
top), and
void gIViewport (GLint x, GLint y, GLint width, GLint height)

which sets the viewport to have a lower left corner of (x, y) and an upper right corner of (x + width, y
+ height).
By default, the viewport is the entire screen window: Lower left corner (0, 0) and upper right corner
(W, H).

Because OpenGL uses matrices to set up all its transformations, glu0rtho2D () must be preceded by
two "setup" functions: glMatrixMode (GL_PROJECT) and gILoadIdentity ().
Thus, to establish the window and viewport used in Example 3.2.1, we would use the following code:

glMatrixMode (GL_PROJECTION);
gILoadIdentity ();
gluOrtho2D (0.0, 2.0, 0.0, 1.0); // sets the window
gIViewport (40, 60, 360, 240); // sets the viewport

We will make programs more readable if we encapsulate the commands that set the window into a
function setWindow () and Viewport, as in Fig 3.7.

//------------ setWindow -------------


void setWindow (float left, float right, float bottom, float top) {
glMatrixMode (GL_PROJECTION) ;
gILoadIdentity() ;
gluOrtho2D(left, right, bottom, top);
}
// ------------- getViewport --------------
void setViewport (int left, int right, int bottom, int top) {
gIViewport (left, bottom, right - left, top - bottom);
}

Fig 3.7 Handy functions to

Ex 3.2.2 Plotting the sine function, revisited


To plot the sine () function shape of Figure 3.1, It is just a matter of defining the window and viewport.
Assuming that we want to plot the function from closely spaced x-values between -4.0 and 4.0 into a
viewport of width 640 and height 480

void myDisplay (void) { // plot the sine function, using world coordinates

Dr Taleb Obaid 3/5


Computer Graphics CS 330 Fall 2009

setWindow (-5.0, 5.0, -0.3, 1.0) ; // set the window a little wider
setViewport (0, 640, 0, 480) ; // set the viewport
glBegin(GL_LINE_STRIP);
for (GLfloat x = -4.0; x < 4.0; x += 0.1) // draw the plot
glVertex2f (x, sin (3.14159 * x) / (3.14159 * x));
glEnd():
glFlush();
}
Fig 3.8 Plotting the sine function
Ex 3.2.4
Tiling the screen window with the dinosaur motif
Laying lots of copies of the same thing side by side to cover the entire screen window is called tiling
the window. The picture that is copied at different positions is often called a motif.
Tiling a screen window is easily achieved by using a different viewport for each instance of the motif.
Fig 3.10a shows a tiling involving 25 copies of the motif generated by the following code:
setWindow (0, 640.0, 0, 440.0) ; // set a fixed window
for (int 1=0; i < 5; i++) // for each column
for (int j=0; j < 5 ; j++) { // for each row
glViewport (i * 64, j * 44, 64, 44) ;
drawPolylineFile ("dino.dat") ; // draw it again
}
Figure 3.10(b) shows another tiling, motifs are flipped upside down to produce an intriguing effect.
This was done by flipping the window upside down every other iteration: interchanging the top and
bottom values in setWindow(). The code for the double loop was changed to the following:

for (int i = 0; 1 < 5 ; i++)


for (int j = 0; j < 5 ; j++) {
if ((i+j) % 2 -= 0) // if (i+j) is even
setWindow (0.0, 640.0, 0.0, 440.0) ; // right-side-up window
else
setWindow (0.0, 640.0, 440.0, 0.0) ; // upside-down window
glViewport (i * 64, j * 44, 64, 44) ; // set the next viewport
drawPolylineFile ("dino.dat") ; // draw it again

Fig 3.10 Tiling the display with copies of the dinosaur

Ex 3.2.5 Clipping parts of a figure

Dr Taleb Obaid 3/6

Computer Graphics CS 330 Fall 2009

A picture can be clipped, by proper setting of the window. OpenGL automatically clips off parts of
objects that lie outside the world window, as in Fig 3.11.

Fig 3.11 Using the window to Clip parts of a figure.

void setWindow ( double left, double right, double bottom, double top) {
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (left, right, bottom, top);
}
void hexSwirl (void) {
GLdouble Pi = 3.14159, Thi = 0.0, Xc = 200., Yc = 200., R = 2.;
GLdouble Ang, XX, YY;
// glClear (GL_COLOR_BUFFER_BIT);
for (int i = 0; i < 30; i++) {
R += 5;
Thi += 0.05;
glBegin (GL_LINE_STRIP);
for (double k = 0; k <= 6; k++){
Ang = Thi + k * Pi/3.;
XX = R * cos ( Ang );
YY = R * sin ( Ang );
glVertex2d (Xc + XX, Yc + YY );
}
glEnd();
}
glFlush(); // send all output to display
}

void myDisplay (void) {


double left, right, bottom, top;
left = 0.0, right = 400., bottom = 0.0, top = 400.;
glClear (GL_COLOR_BUFFER_BIT);
setWindow (left, right, bottom, top); // entire world window
glViewport (0, 0, 200, 200); // first viewport
hexSwirl ();
glViewport (0, 200, 200, 200); // second viewport
hexSwirl ();

Dr Taleb Obaid 3/7


Computer Graphics CS 330 Fall 2009

setWindow (left, right, bottom, top); // change world window


glViewport (200, 0, 100, 100); // third viewport
hexSwirl ();
setWindow (200, right, 200, top); // change world window
glViewport (200, 200, 200, 200); // forth viewport
hexSwirl ();
}

Achieving a Smooth Animation


The previous approach is not completely satisfying; because of the time it takes to draw each new
figure. What the user sees is a repetitive cycle two actions:

A. Instantaneous erasure of the current figure.


B. A (possibly) slow redrawing of the new figure.

The problem is that the user sees the line-by-line creation of the new frame, which can be distracting.
What the user would like to see is:

A. A steady display of the current figure.


B. Instantaneous replacement of the current figure by the finished new figure.

Dr Taleb Obaid 3/8

Computer Graphics CS 330 Fall 2009

The trick is to draw the new figure "somewhere else" and then to move the completed new figure
onto the user's display. OpenGL offers double buffering to accomplish this task. Memory is set aside
for an extra screen window that is not visible on the actual display, and all drawing is done to that
window, or buffer. The command glutSwapBuffers () then causes the image in the buffer to be
transferred onto the screen window.
OpenGL reserve a separate buffer using GLUT_DOUBLE rather than GLUT_SINGLE.
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
The command glutSwapBuffers () would be placed directly after hexSwirl () in the code.

3.2.2 Setting the Window and Viewport Automatically


Either the programmer input the window and viewport specifications to achieve a certain effect, or
both of these specifications are set up automatically, according to some requirement for the picture.

Setting of the Window


Often, the programmer does not know where the object of interest lies, or how big is, in world
coordinates.
The usual approach is to find a window that includes the entire object. To achieve this, the object's
extent must be found. The extent (or bounding box) of an object is the aligned rectangle that just
covers the object. The extent of the Fig 3.15, shown as a dashed line, is
(left, right, bottom, top) = (0.36, 3.44, -0.51,1.75).

FIGURE 3.15 Using the extent as the window.

The extent can be computed by finding the extreme values of the x- and y-coordinates in the array
p[i]. The left side of the extent is the smallest of the values pt[i].x. Once the extent is known, the
window can be made identical to it. Automatic Setting of the Viewport to Preserve the Aspect Ratio

To draw the largest undistorted version of a figure that will fit in the screen window:
You need to specify a viewport that has the same aspect ratio as the world window. A common wish
is to find the largest such viewport that will fit inside the screen window on the display.

Suppose the aspect ratio of the world window is R and the screen widow has width W and height H.
There are two distinct situations:
The world window may have a larger aspect ratio than the screen window (R > W/H), or it may have
a smaller aspect ratio (R < W/H). The two situations are shown in Figure 3.16.

Dr Taleb Obaid 3/9


Computer Graphics CS 330 Fall 2009

Fig 3.16 Possible aspect ratios for the world and screen windows

Case (a): R > W/H. Here the world window is short and stout relative to the screen window. The
viewport will have width W and height W/R, so it is set with the following command:
setViewport (O, W, 0, W/R);

Case (b): R < W/H. Here the world window is tall and narrow relative to the screen
Window. The viewport will have height H, but width HR, so it is set with the command:
setViewport(0, H * R, 0, H);

Ex 3.2.7 A tall window


Suppose the window has aspect ratio R = 1.6 and the screen window has H = 200 and W = 360, and
hence, W/H = 1.8. Therefore, Case (b) applies, and the viewport is set to have a height of 200 pixels
and a width of 320 (200x1.6)

Ex 3.2.8 A short window


Suppose R = 2 and the screen window is the same as in the previous example, Then Case (a) applies,
and the viewport is set to have a height of 180 (360/2) pixels and
width of 360 pixels.

Resizing the Screen Window; the Resize Event


In a windows-based system the user can resize the screen window at run time, typically by dragging
one of its corners with the mouse. This action generates a resize event that the system can respond
to. A function glutReshapeFunc () be called whenever this event occur
glutReshapeFunc (myReshape); // specifies the function called on a resize event

The registered function, myReshape, have the prototype


void myReshape (GLsizei W, GLsizei H);

(GLsizei is a 32-bit integer; see Figure 2.7.)

Making a Matched Viewport


One common approach is to find a new viewport that both fits into the new screen window and has
the same aspect ratio as the world window:

Dr Taleb Obaid 3 / 10

Computer Graphics CS 330 Fall 2009

void myReshape (GLsizel W, GLsizei H) {


if (R > W/H) // use (global) window aspect ratio
setViewport (0, W, 0, W/R) ;
else
setViewport (0, H * R, 0, H);
}

Fig 3.17 Using a reshape function to set the largest matching viewport upon a resize event.

#include <gl/glut.h>
#include <math.h>
double W = 400., H = 400., left = 0.0, right = 300.,
bottom = 0.0, top = 300., R = right/top ;
//<<<<<<<<<<<< setWindow >>>>>>>>>>>>>>>>>>>>>
void setWindow ( double left, double right, double bottom, double top) {
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (left, right, bottom, top);
}

//<<<<<<<<<<<<<<< setViewport >>>>>>>>>>>>>>>>>>


void setViewport (int left, int right, int bottom, int top) {
glViewport (left, bottom, right - left, top - bottom);
}
void Circle (void) { //<<<<<<<<<<<<<<< Circle >>>>>>>>>>>>>>>>>>
GLdouble Pi = 3.14159, Thi = 0.0, Xc = 200., Yc = 200., R = 50.;
GLdouble Ang, XX, YY;
glClear (GL_COLOR_BUFFER_BIT);
glBegin (GL_LINE_STRIP);
for (double k = 0; k <= 30; k++) {
Ang = k * 2*Pi/30.;
XX = R * cos ( Ang );
YY = R * sin ( Ang );
glVertex2d(Xc + XX, Yc + YY );
}
glEnd();
glFlush();}
// send all output to display
//<<<<<<<<<<<<<< myReshape >>>>>>>>>>>>>>
void myReshape (int W, int H) {
if (R > W/H)
setViewport (0, (int) W, 0, (int) W/R);
else
setViewport (0, (int) H*R, 0, (int) H);
}

Dr Taleb Obaid 3 / 11
Computer Graphics CS 330 Fall 2009

//<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>>>>


void myDisplay (void) {
glClearColor(1.0,1.0,1.0,0.0); // set white background color
glColor3f(1.0f, 0.0f, 0.0f); // set the drawing color
glClear (GL_COLOR_BUFFER_BIT);
setWindow (left, right, bottom, top); // entire world window
Circle ();
}
//<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>
void main (int argc, char** argv)
{

glutDisplayFunc(myDisplay);
glutReshapeFunc (myReshape);

3.4 DEVELOPING THE CANVAS CLASS


We develop a class called Canvas that provides a handy drawing canvas on which to draw the lines,
polygons, etc. of interest. This class provides simple methods for creating the desired screen window
and establishing a world window and viewport, and it ensures that the window-to-viewport mapping
is well defined. It also offers the routines moveTo () and lineTo () that many programmers find
congenial, as well as the useful "turtle graphics" routines we develop later.

Dr Taleb Obaid 3 / 12

Computer Graphics CS 330 Fall 2009

class Point2 : A Point Having Real Coordinates


class Point2 {
public :
Point2 () (x = y = 0.0f ;} // default constructor_l
Point2 (float xx, float yy) {x = xx; y = yy; ) // constructor_2
void set (float xx, float yy) {x = xx; y; }
float getX0 {
return x;
}
float getY0 {
return y;
}
void draw(void) {
gIBegin (GL_POINTS); // draw this point
glVertex2f ((GLfloat) x, (GLfloat) y);
glEnd ();
}
private:
float x, y;
};

class IntRect: An Aligned Rectangle with Integer Coordinates

class IntRect {
public:
IntRect () {l=0; r = 100; b = 0; t = 100;} // constructors
IntRect (int left, int right, int bottom, int top) {
l = left; r = right; b = bottom; t = top; }
void set (int left, int right, int bottom, int top) {
l = left; r = right; b = bottom; t = top; }
void draw (void); // draw this rectangle using OpenGL
private:
int l, r , b , t; };

class RealRect: An Aligned Rectangle with Real Coordinates


class RealRect {
same as intRect except use float instead of int
};

Declaration of Class Canvas


We declare the interface for Canvas in Canvas.h as shown in Figure 3.25. The data members of
Canvas.h include the current position, a window, a viewport, and the window-to-viewport mapping

Dr Taleb Obaid 3 / 13
Computer Graphics CS 330 Fall 2009

class Canvas{
public
Canvas (int width, int height, char* windowTitle) ; // constructor
void setWindow (float 1, float r, float b, float t
void setViewport (int 1, int r, int b, int t)
IntRect getViewport (void) ; // divulge the viewport data
RealRect getWindow(void) ; // divulge the window data
float getWindowAspectRatio (void)
void clearScreen ()
void setBackgroundColor (float r, float g, float b) ;
void setColor (float r, float g, float b) ;
void lineTo (float x, float y) ;
void lineTo (Point2 p) ;
void moveTo (float x. float y) ;
void moveTo (Point2 p) ;
others later
private
Point2 CP // current position in the world
IntRect viewport // the current window
RealRect window // the current viewport
others later
};

Fig 3.25 The header file Canvas.h

Figure 3.26 shows how the Canvas class might typically be used in an application.
Canvas cvs (640, 480, "try out Canvas") ; // global canvas object
//«««««««««««««« display »»»»»»»»»»»
void display (void) {
cvs.clearScreen () ; // clear screen
cvs.setWindow (-10.0, 10.0, -10.0, 10.0) ;
cvs.setViewport (10, 460, 10, 460) ;
cvs .moveTo (0, -10.0) ; // draw a line
cvs.lineTo (0, 10.0) ;
RealRect box ( -2.0, 2.0, -1.0, 1.0) ; // construct a box
box.draw () ; // draw the box
//««««««««««« main »»»»»»»>»»»»»»»»
void main (void) {
// the window is opened in the Canvas constructor
cvs . setBackgroundColor (1.0, 1.0, 1.0) ; // background is white
cvs. setColor (0.0, 0.0, 0.0) ; // set drawing color
glutDisplayFunc (display) ;
glutMainLoop () ;
}

Fig 3.26 Typical usage of the Canvas class.

Dr Taleb Obaid 3 / 14

Computer Graphics CS 330 Fall 2009

The main () routine does no initialization: This has all been done in the Canvas constructor. The
routine main () simply sets the drawing and background colors, registers the function display (), and
enters the main event loop.

3.4.3 Implementation of Class Canvas


The constructor, shown in Figure 3.27
//«««««««««« Canvas constructor »»»»»»»»
Canvas:: Canvas (int width, int height, char* windowTitle) {
char* argv [l]; // dummy argument list for glutlnit()
char dummyString [8];
argv[0] = dummyString; // hook up the pointer
int argc =1; // to satisfy glutlnit ()
glutlnit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (width, height);
glut!nitWindowPosition (20, 20);
glutCreateWindow (windowTitle); // open the screen window
setWindow (0, (float)width, 0, (float)height); //default world window
setViewport (0, width, 0, height); // default viewport
CP.set (0.0f, 0.0f); // initialize the CP to (0, 0)

Fig 3.27 The constructor for the OpenGL version of Canvas

Figure 3.28 shows the implementation of some of the Canvas members functions, such as moveTo (),
lineTo ().
//«««««««««««««««««««« moveTo ««««««««««««««««««««
void Canvas:: moveTo (float x, float y) {
CP.set (x, y);
}
//«««««««««««««««««««« lineTo ««««««««««««««««««««
void Canvas:: lineTo (float x, float y) {
glEegin (GL_LINES);
glVertex2f ((GLfloat) CP.x, (GLfloat) CP.y);
glVertex2f ((GLfloat) x, (GLfloat) y); // draw the line
glEnd () ;
CP.set (x, y); // update the CP
gIFlush ();
}
//«««««««««««««««««« set Window »««««««««««««««««««
void Canvas:: setWindow (float 1, float r, float b, float t) {
gIMatrixMode (GL_PROJECTION);
gILoadIdentity ();
gluOrtho2D ((GLdouble) 1, (GLdouble) r, (GLdouble) b, (GLdouble) t)) ;
window.set (1, r, b, t);

FIGURE 3.28 Implementation of some Canvas member functions.

Dr Taleb Obaid 3 / 15
Computer Graphics CS 330 Fall 2009

3.5 RELATIVE DRAWING


If we add just a few more drawing tools to our tool kit (which is the emerging class Canvas), certain
drawing tasks become much simpler.

3.5.1 Developing moveRel () and lineRel ()


Two new routines are moveRel () and lineRel ().
void Canvas :: moveRel(float dx, float dy) {
CP.set (CP.x + dx, CP.y + dy);
}
void Canvas :: lineRel (float dx, float dy) {
float x = CP.x + dx. y = CP.y + dy;
lineTo(x, y);
CP.set(x, y);
}

Fig 3.29 The functions moveRel() and lineRel ()

Ex 3.5.1 An arrow marker


Markers of different shapes can be placed at various points in a drawing to add emphasis to the
display. Figure 3.30 shows pentagram markers used to highlight the data points in a line graph.

Fig 3.30 Placing markers for emphasis

moveTo (first data point) {


DrawMarker (); // draw a marker there
for (each remaining data point) {
lineTo (the next point)
drawMarker () ; }
}

Dr Taleb Obaid 3 / 16

Computer Graphics CS 330 Fall 2009

Figure 3.31 shows an arrow-shaped marker, drawn using the routine in Figure 3.32. The arrow is
positioned with its uppermost point at the CP. For flexibility, the arrow shape is parameterized
through the four size parameters f, h, t, and w as shown.
void arrow (float f, float h, float t, float w) {
// assumes global Canvas object: cvs
cvs.lineRel (-w - t / 2, -f); // down the left side
cvs.lineRel (w, 0);
cvs.lineRel (0, -h);
cvs.lineRel (t, 0); // across
cvs.lineRel (0, h); // back up
cvs.lineRel (w, 0);
cvs.lineRel (-w - t / 2, f);
}

Fig 3.32 Drawing an arrow using relative moves and draws

//<<<<<<<<<<<<<<<< Star >>>>>>>>>>>>>>>>>>>>


void Star (void) {
GLdouble Pi = 3.14159, Thi = 0.0, Xc = 150., Yc = 150. Ang, XX, YY;
int nPoints = 5, factor = 0;
glBegin (GL_LINE_STRIP);
for (double k = 0; k <= nPoints; k ++){
Ang = factor * 2*Pi/nPoints;
if (Ang > 2*Pi)
Ang = Ang - 2*Pi;
XX = R * cos ( Ang );
YY = R * sin ( Ang );
glVertex2d(Xc + XX, Yc + YY );
factor +=2;
}
glEnd();
glFlush();
}
//<<<<<<<<<<<<<<<<< RelTo >>>>>>>>>>>>>>>>>>>>>
void RelTo (GLdouble dx, GLdouble dy) {
GLdouble X, Y, sX = 300., sY = 300.;
X = CPX + dx; Y = CPY + dy; // CPX and CPY are global
glBegin (GL_LINE_STRIP);
glVertex2d (sX + CPX , sY + CPY);
glVertex2d (sX + X , sY + Y);
glEnd();

Dr Taleb Obaid 3 / 17
Computer Graphics CS 330 Fall 2009

glFlush ();
CPX = X; CPY = Y; } // update CPX and CPY
//<<<<<<<<<<<<<<<<< Arrow >>>>>>>>>>>>>>>>>>>>>
void Arrow (void) {
GLdouble f = 40., h = 40., t = 40., w = 40.;
CPX = 0.; CPY = 0.;
RelTo (-w-t/2., -f);
RelTo (w, 0); RelTo (0, -h);
RelTo (t, 0); RelTo (0, h);
RelTo (w, 0); RelTo (-w-t/2, f);
}

//<<<<<<<<<<<<<<<<< LineTo >>>>>>>>>>>>>>>>>>>>>>


void LineTo (GLdouble X, GLdouble Y) {
glBegin (GL_LINE_STRIP);
glVertex2d (CPX , CPY);
glVertex2d (X , Y);
glEnd();
glFlush ();
CPX = X;
CPY = Y;
}
//<<<<<<<<<<<<<<<<< moveTo >>>>>>>>>>>>>>>>>>
void moveTo (GLdouble X, GLdouble Y) {
CPX = X;
CPY = Y;
}

//<<<<<<<<<<<<<<<< Lines >>>>>>>>>>>>>>>>>>>


void Lines () {
moveTo (200., 200.); LineTo (200., 300.);
LineTo (100., 300.); LineTo (100., 200.);
LineTo (400., 200.); LineTo (400., 300.);
LineTo (400., 300.); LineTo (300., 300.);
LineTo (300., 200.);
moveTo (100., 50.);
LineTo (200., 50.); LineTo (200., 150.);
LineTo (100., 150.); LineTo (100., 50.);
}

Dr Taleb Obaid 3 / 18

Computer Graphics CS 330 Fall 2009

3.5.2 Turtle Graphics


Turtle graphics tool keeps track not only of "where we are" with the CP, but also "the direction in
which we are headed." The turtle is positioned at the CP, headed in a certain direction called the
current direction, CD, the number of degrees measured counterclockwise (CCW) from the positive x-
axis.
It is easy to add functionality to the Canvas class that will "control the turtle." First, CD is added as a
private data member. Then we add three functions:

1. turnTo (float angle). This function turns the turtle to the given angle and is implemented as
void Canvas:: turnTo (float angle) {
CD=angle;
}

2. turn (float angle). This routine turns the turtle through angle degrees counterclockwise:
void Canvas:: turn (angle) {
CD += angle;
}
We use a negative argument to make a right turn. Note that a turn is a relative change in direction;

3. forward (float dist, int isVisible) .This instruction moves the turtle forward in a straight line from
the CP through a distance dist in the current direction CD and updates the CP. If isVisible is nonzero,
a visible line is drawn; otherwise nothing is drawn.
Figure 3.33 shows that, in going forward in the direction CD, the turtle just moves in the x direction a
distance dist cos ( CD/180) and in the y direction a distanced dis*sin ( CD/180), so the
implementation of forward () is immediate:

Fig 3.33 Effect of the forward() routine.

void Canvas:: forward(float dist, int isVisible) {


const float RadPerDeg = 0.017453393; //radians per degree
float x = CP.x + dist * cos (RadPerDeg * CD);
float y = CP.y + dist * sin (RadPerDeg * CD);
if (isVisible)
lineTo(x, y);
else
moveTo(x, y);
}

Dr Taleb Obaid 3 / 19
Computer Graphics CS 330 Fall 2009

Ex 3.5.2 Building a figure upon a hook motif


The three-segment "hook" motif shown in Figure 3.34(a) can be drawn using the commands

forward (3 * L, 1) ; // L is the length of the short sides


turn (90);
forward (L, 1);
turn (90);
forward (L, 1);
turn (90);

Fig 3.34 Building a figure out of several turtle motion

void turnTo (double angle) {


CD = angle;
}
void turn (double angle) {
CD += angle;
}
void forward (double dist, int isVisible) {
const double RadPerDeg = 0.017453393;
double X = CPX + dist * cos (RadPerDeg * CD);
double Y = CPY + dist * sin (RadPerDeg * CD);
if (isVisible)
lineTo (X, Y);
else
moveTo (X, Y);
}
void drawTurtle (void) {
forward (60, 1);
turn (90); forward (40, 1);
turn (90); forward (20, 1);
turn (90); forward (20, 1);
turn (-90); forward (20, 1);
turn (-90); forward (40, 1);
turn (-90); forward (60, 1);
turn (-90); forward (60, 1);
turn (90);
}
The motif

Dr Taleb Obaid 3 / 20

Computer Graphics CS 330 Fall 2009

void myDisplay (void) {

for (int i = 0; i < 4; i++)


drawTurtle ();
} The meander

Ex 3.5.3 Polyspirals
A polyspiral is a polyline wherein each successive segment is larger (or smaller) than its predecessor
by a fixed amount and is oriented at some fixed angle to the predecessor.

for (some number of iterations){


forward (length,1); // draw a line in the current direction
turn (angle); // turn through angle degrees
length += increment; // increment the line length
}

Each time a line is drawn, both its length and direction are incremented. If increment is 0, the figure
neither grows nor shrinks. Figure 3.35 shows several polyspirals.

3.6 FIGURES BASED ON REGULAR POLYGONS

3.6.1 The Regular Polygons


DEFINITION: A polygon is regular if it is simple, if all its sides have equal lengths, and if adjacent sides
meet at equal interior angles.
A polygon is simple if no two of its edges cross each other (more precisely, only adjacent edges can
touch and only at their shared endpoint). We give the name n-gon to a regular polygon having n
sides. Familiar examples are the 4-gon (a square), 5-gon (a regular pentagon), 8-gon (a regular
octagon), and so on.
A 3-gon is an equilateral triangle. Figure 3.41 shows various examples. If the number of sides of an n-
gon is large the polygon approximates a circle in appearance.

Fig 3.4 Examples of n-gons

The vertices of an n-gon lie on a circle, the so-called parent circle of the n-gon, and their locations are
easily calculated. Fig 3.42, the vertices lie equispaced every 60o around the circle. The parent circle of
radius R is centered at the origin, and the first vertex P 0 has been placed on the positive x-axis. The
other vertices follow accordingly, as
Pi = (R cos(ia), R sin(ia)), for i = 1,..., 5, where a is /3 radians. Similarly, the vertices of the general n-
gon lie at
Pi = (R cos (2 i/n),R sin (2 i/n)), for i = 0,..., n-1.

Dr Taleb Obaid 3 / 21
Computer Graphics CS 330 Fall 2009

FIGURE 3.42 Finding the vertices of a 6-gon.

It is simple to implement a routine that draws an n-gon, as shown in Figure 3.43. The n-gon is drawn
centered at (cx, cy), with radius radius, and is rotated through rotAngle degrees.

void ngon (int n, float ex, float cy, float radius, float rotAngle) { // assumes global Canvas object,
cvs
if (n < 3) return; // bad number of sides
double angle = rotAngle * 3.14159265 / 180; // initial angle
double angleinc = 2 * 3.14159265 /n; //angle increment
cvs. moveTo (radius * cos(angle) + ex, radius * sin(angle) + cy);
for(int k = 0; k < n; k++) { // repeat n times
angle += angleinc;
cvs.lineTo(radius * cos(angle) + ex, radius * sin(angle) + cy);
}
}
Fig 3.43 Building an n-gon in memory.

3.6.2 Variations on n-Gons


Interesting variations based on the vertices of an n-gon can also be drawn.
The standard n-gon is drawn in Figure 3.45(a) by connecting adjacent vertices.
Figure 3.45(b) shows a stellation (or starlike figure) formed by connecting every other vertex.
Figure 3.45(c) shows the interesting rosette formed by connecting each vertex to every other vertex.

FIGURE 3.45 A 7-gon and its offspring, (a) The 7-gon, (b) A stellation, (c) A "7-rosette

void Rosette (int N, float radius) {

Dr Taleb Obaid 3 / 22

Computer Graphics CS 330 Fall 2009

Point2 pt[big enough value for largest rosette];


generate the vertices pt[0] ,..., pt[N-1], as In Fig 3.43
for (int i = 0; i < N - 1; 1++)
for (int j = i + 1; j < N ; j++) {
cvs.moveTo (pt[i]); // connect all the vertices
cvs.lineTo (pt[j]);
}
}
The 5-rosette is particularly interesting. Figure 3.47(a) shows a 5-rosette, which is made up of an outer
pentagon and an inner pentagram. Its segments have an interesting relationship: Each segment is
(golden ratio) times longer than the next smaller one. Also, because the edges of the pentagram form
an inner pentagon, an infinite regression of pentagrams is possible, as is shown in Figure 3.47(b).

Fig 3.47 5 Rosetle and infinite regressions of pentagons and pentagrams

Ex 3.6.3 Figures based on two concentric n-gons

Figure 3.48 shows some shapes built upon two concentric parent circles, the outer of radius R and the
inner of radius fR for some fraction f. Each figure uses a variation of an n-gon whose radius alternates
between the inner and outer radii.
Parts (a) and (b) show familiar company logos based on 6-gons and 10-gons. Part (c) is based on the
14-gon, and part (d) shows the inner circle explicitly.

FIGURE 3.48 A family of famous logos.

3.7 DRAWING CIRCLES AND ARCS

Dr Taleb Obaid 3 / 23
Computer Graphics CS 330 Fall 2009

Drawing a circle is equivalent to drawing an n-gon that has a large number of vertices. The routine
draw Circle () shown in Figure 3.55 draws a 50-sided n-gon.

void drawCircle(Point2 center, float radius) {


const int numVerts = 50;
ngon (numVerts, center.getX(), center.getY(), radius, 0)
}

FIGURE 3.55 Drawing a circle based on a 50-gon.

3.7.1 Drawing Arcs


Many figures in art, architecture, and science involve arcs of circles placed in pleasing or significant
arrangements. An arc is described by the position of the center c and radius R of its "parent" circle,
along with its beginning angle a and the angle b, as in Fig 3.56. shows such an arc. If b is positive, the
arc sweeps in a CCW direction from a: if b is negative, the arc sweeps in a CW fashion. A circle is a
special case of an arc, with
a sweep of 360°.

void drawArc (Point2 center, float radius,


float startAngle, float sweep) {
// startAngle and sweep are in degrees
const int n = 30; // number of intermediate segments in arc
float angle = startAngle * 3.14159265 / 180; // initial angle in radians
float angleinc = sweep * 3.14159265 /(180 * n); // angle increment
float ex = center.getX(), cy = center.getY();

cvs.moveTo (cx + radius * cos(angle), cy + radius * sin(angle));


for (int k = 1; k < n; k++, angle += angleInc)
cvs.lineTo (cx + radius * cos(angle), cy +
radius * sin(angle));

Fig 3.57 Drawing an arc of a circle.

With drawArc ( ) in hand, it is a simple matter to build the routine drawCircle (Point2 center, float
radius)
that draws an entire circle by specifying a center and radius. but there are other ways to describe a
circle:

1. The center is given, along with a point on the circle. If c is the center and p is the given point on the
circle, the radius is simply the distance from c to p, found using the usual Pythagorean theorem.

2. Three points are given through which the circle must pass. It is known that a unique circle passes
through any three points that do not lie in a straight line.

EXAMPLES

Dr Taleb Obaid 3 / 24

Computer Graphics CS 330 Fall 2009

Fig 3.59 The yin-yang symbol. Fig 3.60 The seven circle Fig 3.61 A famous logo

Fig 3.62 Blending arcs to form smooth curves (clock) Fig 3.64 Shape based on arcs

Fig 3.65 The teardrop and its construction Fig 3.66 Some figures based on the teardrop

3.8 USING THE PARAMETRIC FORM FOR A CURVE


There are two principal ways to describe the shape of a curved line: implicit form and parametric form.

The implicit form describes a curve by a function F(x, y) that provides a relationship between the x and
y coordinates: The point (x, y) lies on the curve if and only if it satisfies the equation
F(x,y) = 0. (3.7)
For example, the straight line through the points A and B has the implicit form

F(x,y) = (y - Ax)(Bx - Ax) - (x - Ax)(By - Ay) (3.8)

and the circle with radius R centered at the origin has the implicit form
F(x, y)= x 2 + y2 - R2 (3.9)

Dr Taleb Obaid 3 / 25
Computer Graphics CS 330 Fall 2009

You can easily test whether a given point lies on the curve: Simply evaluate F(x, y) at the point. For
certain classes of curves, it is meaningful to speak of an inside and an outside of the curve.

F(x, y) = 0 for all (x, y) on the curve,


F(x, y) > 0 for all (x, y) outside the curve,
F(x, y) < 0 for all (x, y) inside the curve.

3.8.1 Parametric Forms for Curves


A parametric form suggests the movement of a point through time, which we can translate into the
motion of a pen as it sweeps out the curve. The path of a particle traveling along the curve is fixed by
two functions, x( ) and y(), and we speak of (x(t), y(t)) as the position of the particle at time t. The curve
itself is the totality of points "visited" by the particle as t varies over some interval.

Examples: The Line and the Ellipse


The straight line of Equation (3.8) passes through points A and B. We choose a parametric form that
visits A at t = 0 and B at t = 1, obtaining

x(t) = Ax + (Bx - Ax)t (3.12)


and
y(t) = Ay + (By Ay)t.

Thus, the point P(t) = (x(t), y(t)) sweeps through all of the points on the line between A and B as t
varies from 0 to 1. (Check this out!). Another classic example is the ellipse, a slight generalization of
the circle. The ellipse is described parametrically by
x(t) = Wcos (t) (3.13)
and
y(t) = Wsin (r), for 0 t 2 .
where W is the "half width" and H the "half height" of the ellipse. When W and H are equal, the ellipse
is a circle of radius W. Figure 3.69 shows an ellipse, along with the
component functions x(.) and y(.).

FIGURE 3.69 An ellipse described parametrically.


As t varies from 0 to 2 , the point P(t) = (x(t),y(t)) moves once around the ellipse starting (and finishing)
at (W, 0)

Dr Taleb Obaid 3 / 26

Computer Graphics CS 330 Fall 2009

Finding an Implicit Form from a Parametric Form

How do we find the implicit form from the parametric form? The basic step is to combine the two
equations for x(t) and y(t) to somehow eliminate the variable t. For the ellipse we can square both
x/W and y/H and use equation (3-13) to obtain the familiar equation for an ellipse:
(x/W)2 + (y/H)2 =1 (3.14)

3.8.4 Polar Coordinate Shapes


Each point on the curve is represented by an angle and a radial distance r. If r and are each made
a function of t, then as t varies the curve (r(t), (t)) is swept out. This curve also has the Cartesian
representation (x(t), y(t)), where

Fig 3.76 Polar coordinates

x(t) = r(t) cos ( (t)) and y(t) = r(t) sin ( (t))


For each point (r, ), the corresponding Cartesian point (x, y) is given by
x= f( ) cos ( ) and y = f( ) sin ( ).

Fig 3.77 Examples of curves with simple polar forms

Cardioid : f( ) = K (l + cos ( )).


Rose curves: f( ) = K cos (n ), where n specifies the number of petals in the rose. Two cases are shown.

Dr Taleb Obaid 3 / 27
Computer Graphics CS 330 Fall 2009

Archimedean spiral: f( ) = K .
The conic sections (the ellipse, parabola, and hyperbola) all share the polar form
f( ) = 1 / (1 ± e cos( ))
where e is the eccentricity of the section. For e = 1, the shape is a parabola; for 0 e < 1, it is an ellipse;
and for e > 1, it is a hyperbola. From practice exercises page 122, the eccentricity , e = c / W, where
c is the focus of the ellipse, W the width.

Dr Taleb Obaid 3 / 28

Computer Graphics CS 330 Spring 2011

Chapter 5,
Transformations of Objects
Goals of the Chapter
To develop tools for transforming one picture into another
To introduce the fundamental concepts of affine transformations, which perform
combinations of rotations, scaling, and translations
To develop functions that applies affine transformations to objects in computer
programs
To develop tools for transforming coordinate frames
To see how to set up a camera to render a 3D scene using OpenGL
To learn to design scenes in the Scene Design language SDL, and to write programs that
read SDL files and draw the scenes they describe

INTRODUCTION TO TRANSFORMATIONS

Figure 5.1 (a) shows two versions of a simple house, drawn before and after each of its points
has been transformed. In this case the house has been scaled down in size, rotated a small
amount, and then moved up and to the right.
The overall transformation is a combination of three elementary ones: scaling, rotation, and
translation. Figure 5.1(b) shows a 3D house before and after it is similarly transformed: Each 3D
point in the house is subjected to a scaling, a rotation, and a translation by the transformation

Fig 5.1, Drawings of Objects before and after they are transformed

Transformations are very useful in a number of situations

a. We can compose a "scene" out of a number of objects, as in Figure 5.2. The scene is

different sizes, using the proper transformation for each.

Dr Taleb Obaid 5/1


Computer Graphics CS 330 Spring 2011

Fig 5.2 Composing a picture from many instances of a simple form

b. The
fashion the whole shape by appropriate reflections, rotations, and transformations of
the motif.

Fig 5.4 Using

c. A designer may want to view an object from different vantage points and make a picture
from each one. The scene can be rotated and viewed with same camera, but it is more
natural to leave the scene alone and move the camera.

Dr Taleb Obaid 5/2

Computer Graphics CS 330 Spring 2011

Fig 5.5 Viewing a scene from different vantage points


d. In computer animation, several objects must move relative to one another from frame
o frame. This effect can be achieved by shifting and rotating the separate local
coordinate system of each.

Using Transformations with OpenGL

A number of graphics platform, including OpenGL, provide a "graphics pipeline." or a sequence


of operations that are applied lo all points that are "sent through." A drawing is produced by
processing each point

Figure 5,7 shows a simplified view of the OpenGL graphics pipeline. An application sends the
pipeline a sequence of points P1, P2, P3,... using commands like,

glBegin (GL_LINES);
glVertex3f (...); // send PI through the pipeline
glVertex3f (...): // send P2 through the pipeline
glVertex3f (...); // send P3 through the pipeline
glEnd ():

These points first encounter a transformation called the "current transformation" (CT), which
alters their values into a different set of points, say Q1, Q2, Q3 i
describe some geometric object, the points Q i, describe the Transformed version of the same
object. These points are then sent through additional steps and ultimately are used lo draw the
final image on the display.

Dr Taleb Obaid 5/3


Computer Graphics CS 330 Spring 2011

Fig 5.7 The OpenGL pipeline

5.2.1 Transforming Points and Objects


A transformation alters each point P in space (2D or 3D) into a new point Q by means of a specific
formula or algorithm.

Fig 5.8 Mapping points into new points.

As the figure illustrates, an arbitrary point P in the plane is mapped to another point Q. We say
that Q is the image of P under the mapping T. More formally, if S is a set of points, its image T(S)
is the set of all points T(P) , where P is some point in S.

We take the 2D case first, in whichever coordinate frame we are using, points P and Q have the
representations
Px Qx
P = Py and Q = Qy
1 1

respectively. This means that the point P is at location


P = Pxi + Pyj + , and similarly for Q. Px and Py are called the "coordinates" of P.
Qx Px
Qy = T Py or Q = T(P)

Dr Taleb Obaid 5/4

Computer Graphics CS 330 Spring 2011

1 1

Affine transformations have a simple form. The coordinates of Q are linear combinations of those
of P.
Qx m11 Px + m12Py + m13
Qy = m21 Px + m12Py + m23
1 1

The affine transformation of Equation has a useful matrix representation

Qx m11 m12 m13 Px


Qy = m21 m12 m23 Py
1 0 0 1 1

Example 5.2.1
An affine transformation is specified by the matrix

3 0 5
-2 1 2
0 0 1

Find the image Q of points P = (1, 2).


Solution
8 3 0 5 1
2 = -2 1 2 2
1 0 0 1 1

Translation
To translate a picture into a different position on a graphics display
Qx 1 0 m 13 Px
Qy = 0 1 m 23 Py
1 0 0 1 1

or simply
Qx Px + m13
Qy = Py + m23
1 1

So, in ordinary coordinate Q = P + d d is (m12, m23).

Example

Dr Taleb Obaid 5/5


Computer Graphics CS 330 Spring 2011

If the offset vector is (2, 3), every point will be altered into a new point that is two units farther
to right and three units above. The point (1, -5), for instance, is transformed into (3, -2), and the
point (0, 0) is translated into (2, 3).

Scaling
Scaling changes the size of a picture and involves two scale factors, Sx, Sy, for the x- and y-
coordinates.
(Qx, Qy) = (SxPx, SyPy).
The matrix is
Sx 0 0
0 Sy 0
0 0 1

This is called scaling about the origin, because each point P is moved Sx times farther from the
origin in the x-direction and Sy times farther from the origin in the y-direction.

If a scale factor is negative, then there is also a reflection about a coordinate axis. Fig 5.11, the
scaling (Sx, Sy) = (-1, 2) is applied to a collection of points. Each point is both reflected about the
y-axis and scaled by 2 in the y-direction.

Fig 5.11 A scaling and a reflection

1.
If the two factors are the same (Sx = Sy = S) , is a uniform scaling. If S is negative, there are
reflection about both axes.

Rotation

Dr Taleb Obaid 5/6

Computer Graphics CS 330 Spring 2011

A fundamental graphics operation is the rotation of a figure about a given point through some
angle, as in Fig.

Fig 5.13 Rotation of points through an angle of 60o

As When T() is a rotation about the origin, the offset vector d is zero and Q = T(P) the form

Qx = Px cos( ) Pysin( ) 5.9


Qy = Px sin( ) Pycos( )

In terms of its matrix form, a pure rotation about the origin is given by

Qx cos( ) -sin( ) 0 Px
Qy = sin( ) cos( ) 0 Py
1 0 0 1 1

Derivation of the Rotation Mapping


Fig 5.14 shows how to find the coordinates of a point Q that results from rotating point P about
the origin through an angle . If P is at a distance R from the origin at some angle , then

P = (Rcos( ), Rsin( )).

Q must be at the same distance as P and angle ( + ). So,


Qx = R cos( + ), Qy = R sin( + ).
cos( + ) = cos( )cos( ) - sin( )sin( )

and
sin( + ) = sin( )cos( ) + cos( )sin( )
and use
Px = Rcos( + ) and Py = Rsin( + ) to obtain eq. 5.9.

Dr Taleb Obaid 5/7


Computer Graphics CS 330 Spring 2011

Fig 5.14, Derivation of the Rotation mapping

Fig 5.15 An example of shearing


Shearing
- -coordinate of each point is unaffected, whereas
each x-coordinate is translated by an amount that increases linearly with y. A shear in the x-
direction is given by
Qx = Px + hPy, Qy = Py
Where h specifies what fraction of the y-coordinate of P is to be added to the x-coordinate. The
matrix form is
1 h 0
0 1 0
0 0 1

1 0 0
g 1 0
0 0 1

The Inverse of an Affine Transformation

Dr Taleb Obaid 5/8

Computer Graphics CS 330 Spring 2011

If point P is mapped into point Q according to Q = MP, we simply pre-multiply both sides by the
inverse of M denoted by M-1, and write
m22 -m12
M-1 = 1 .
det M -m21 m11

The following matrices for elementary inverse transformations

1. Scaling
1/Sx 0 0
M-1 = 0 1/Sy 0
0 0 1

2. Rotation
cos( ) sin( ) 0
M-1 = -sin( ) cos( ) 0
0 0 1

3. Shearing
1 -h 0
M-1 = 0 1 0
0 0 1

4. Translations
1 0 -m13
M-1 = 0 1 -m23
0 0 1

Dr Taleb Obaid 5/9


Computer Graphics CS 330 Spring 2011

5.2.5 Composing Affine Transformations


An application requires that we build a compound transformation out of several elementary
ones. For example, we may want to
Translate by (3, -4),
Then rotate through 30 o.
Then scale by (2, -1).
Then translate by (0, 15).
And, finally, rotate through 30o.

The process of applying several transformations in succession to form one overall transformation
is called composing the transformations. Fig 5.16 T1() maps P into Q, and T2() maps Q into W. The
nature of W = T2(Q)=T2(T1(P))
Suppose the two transformations are represented by the matrices M 1 and M2. P is transformed
to the point M1P, which is then transformed to M2(M1P). So, the later just (M 2M1)P, and we have
W = MP.
Where M = M2M1.
Notice that the matrices appear in reverse order.

Fig 5.16 The composition of two transformations.

Example 5.2.5 Rotating about an arbitrary (Pivot) point


Suppose we wish to rotate points about some other point in the plane rather than the origin. In
V=(Vx, Vy), and we wish to rotate points such as P through
an angle to position Q.

Fig 5.17 Rotation about a point


To do this, we must relate the rotation about V to an elementary rotation about the origin. The
rotation consists of the following three elementary transformations:

Dr Taleb Obaid 5 / 10

Computer Graphics CS 330 Spring 2011

1. Translate point P through vector v = (-Vx, -Vy).


2. Rotate about the origin through angle .
3. Translate P back through v.

Creating a matrix for each elementary transformation and multiplying the matrices out produces
1 0 Vx cos( ) -sin( ) 0 1 0 -Vx cos( ) -sin( ) d x
0 1 Vy sin( ) cos( ) 0 0 1 -Vy = sin( ) cos( ) dy
0 0 1 0 0 1 0 0 1 cos( ) 0 1

where
dx = -cos( )Vx + sin( )Vy + Vx
dy = -sin( )Vx - cos( )Vy + Vy

Example 5.2.6
Scaling and shearing about arbitrary
-transform-

Example 5.27 Reflections about a tiled line


Consider the line through the origin that makes an angle of with the x-axis. Point A reflects into
point B, and each house shows reflects into the other.
A rotation through the angle (so that the axis of reflection coincides with the x-axis).
A reflection about the x-axis.
A rotation back through

Fig 5.18 reflecting a point about a tiled axis

Dr Taleb Obaid 5 / 11
Computer Graphics CS 330 Spring 2011

We want to develop the transformation that reflects any point P about the line, called the axis
of reflection, to produce point Q.
1. A rotation through the angle (the axis of reflection coincides with the x-axis).
2. A reflection about the x-axis.
3. A rotation back through
The over all transformation is given by the product of the following three matrices:
c s 0 1 0 0 c -s 0 c2-s2 -2sc 0
-s c 0 0 -1 0 s c 0 = -2cs s2-c2 0
0 0 1 0 0 1 0 0 1 0 0 1

where c stand for cos(-), and s for sin(). We can rewrite

cos(2 ) sin(2 ) 0
sin(2 ) - cos(2 ) 0 (a reflection about the axis at angle
0 0 1

5.3 3D Affine Transformations


we use coordinate frames and suppose that we have an origin and three mutually
perpendicular axes in the directions i, j, and k. point P in this frame is given by

P= + Pxi + Pyj + Pzk and so has the representation.

Px
P = Py .
Pz
1

The affine transformation that transform P to Q:

Qx m11 m12 m13 m14 Px


Qy = m21 m12 m23 m24 Py
Qz m31 m32 m33 m34 Px
1 0 0 1 1 1

point Q can be found by multiplying P by M.

Qx Px
Qy = M P y
Qz Pz
1 1

Dr Taleb Obaid 5 / 12

Computer Graphics CS 330 Spring 2011

5.3.1 The Elementary 3D Transformations


Translation
For pure translation, the matrix is
1 0 0 m14
0 1 0 m24
0 0 1 m34
0 0 0 1

Scaling
The matrix is
Sx 0 0 0
0 Sy 0 0
0 0 Sz 0
0 0 0 1

Shearing
The matrix for the simplest elementary shear is the identity matrix with one zero term replaced
by some value, as in
1 0 0 0
f 1 0 0
0 0 1 0
0 0 0 1

Rotations
We often want to rotate an object or a camera in order to obtain different views. We must specify
an axis about which the rotation occurs, rather than just a single point.
The simplest rotation is a rotation about one of the coordinate axes. We call a rotation about the
x-axis an "x-roll," a rotation about the y-axis a "y-roll," and a rotation about the z-axis a "z-roll."

The rotation is through an angle , about the given axis. We define positive angles using a
"looking inward" convention:
Positive values of cause a counterclockwise (CCW) rotation about an axis as one looks inward
from a point on the positive axis toward the origin.

Fig 5,25 Positive rotations about the three axes.

Dr Taleb Obaid 5 / 13
Computer Graphics CS 330 Spring 2011

In the particular case of a 90° rotation:


-roll, the x-axis rotates to the y-axis.
-roll, the y-axis rotates to the z-axis.
-roll, the z-axis rotates to the x-axis.
The following three matrices represent transformations that rotate points through an angle
about a coordinate axis.
1. An x-roll
1 0 0 0
0 c -s 0
R x( ) = 0 s c 0
0 0 0 1

2. A y-roll

c 0 s 0
0 1 0 0
R y( ) = 0 -s c 0
0 0 0 1

3. A z-roll
c -s 0 0
s c 0 0
R z( ) = 0 0 1 0
0 0 0 1

5.5 USING AFFINE TRANSFORMATIONS IN A PROGRAM


We want to see how to apply the theory of affine transformations in a program to carry out the
scaling, rotating, and translating of graphical objects.

Suppose you have a routine house () that draws house #1 in Fig 5.34. But you wish instead to
draw house #2, shown rotated through -30° and then translated through (32, 25). This is a
frequently encountered situation; An object is defined at a convenient size and position, but we
want to draw it (perhaps many times) at different sizes, orientations, and locations.

Fig 5.34 Drawing a rotated and translated house.

Dr Taleb Obaid 5 / 14

Computer Graphics CS 330 Spring 2011

After drawing house #, how do we arrange matters so that house #2 is drawn instead? There are
tow ways:

The Hard Way


With this approach, we construct the matrix for the desired transformation, say, M, and build a
routine, say, transform 2D(), that transforms one point into another, such that
Q = transform2D (M, P);

The routine produces Q=MP, then apply the transformation to each point V [i] in house ().

The Easy Way

The window-to-viewport mapping is "quietly" applied to each vertex as part of moveTo () and
lineTo(). We can have an additional transformation, the current transformation, CT. We enhance
move-To () and linsTo () so that they first quietly apply CT to the argument vertex and then apply
the window-to-viewport mapping.
As in Fig 5.35, When glVertex2d () is called with the argument V, the vertex V is first transformed
by the CT to form point Q, which is then passed through the window to-viewport mapping to
form point S in the screen window.
Fig 5.35 The current transformation is applied to vertices.

How do we extend moveTo () and lineTo () so that they quietly carry out this additional mapping?
If you are not using OpenGL, you must write code that actually performs the transformation.
If you are using OpenGL, the transformation is done automatically! OpenGL maintains a so-called
modelview matrix, and every vertex that is passed down the graphics pipeline is multiplied by
this matrix.
We need only set up the modelview matrix to embody the desired transformation
OpenGL works entirely in 3D, so its modelview matrix produces 3D transformations.

The principal routines for altering the modelview matrix are glRotated(), glScaled (), and
glTranslated (), (d indicated to double). These do not set the CT directly; instead, each

Dr Taleb Obaid 5 / 15
Computer Graphics CS 330 Spring 2011

postmultiplies the CT (the modelview matrix) by a particular matrix, say, M, and puts the result
back into the CT. That is, each of the routines creates a matrix M required for the new
transformation and performs the operation

CT = CT* M
The following are OpenGL routines for applying transformations in the 2D case;

gl Scaled (sx, sy, 1.0);


Postmultiply CT by a matrix that performs a scaling by sx in x and by sy in y; put the result back
into CT. No scaling in z is done.

glTranslatcd (dx, dy, 0);


Postmultiply CT by a matrix that performs a translation by dx in x and by dy in y; put the result
back into CT. No translation in z is done.

glRotated (angle, 0, 0, 1);


Postmultiply CT by a matrix that performs a rotation through angle degrees about the z-axis
[indicated by (0,0,1)], Put the result back into CT.

Since these routines only compose a transformation with the CT, we need some way to get
started:
to initialize the CT to the identity transformation. For that purpose OpenGL provides the routine
gILoadIdentity (). And because the functions listed can be set to work on any of the matrices that
OpenGL supports, we must inform OpenGL which matrix we are altering. This is accomplished
using

gIMatrixMode (GL_MODELV1EW).

cvs.initCT() : //get started with the identity transformation


house (); // draw the untransformed house first
cvs.translate2D (32, 25) // CT now includes translation
cvs.rotate2D (-30.0); // CT now includes translation and rotation
house (); // draw the translaformed house
//<<<<<<<<<<<< initCT >>>>>>>>>>>>>>>
void Canvas:: initCT(void) {
glMatrixMode (GL_MODELVIEW):
glLoadIdentity(); // set CT to the identity matrix
}
//<<<<<<<<<<<< sca1e2D >>>>>>>>>>>>>
void Canvas:: scale2D (double sx, double sy) {
glMaLrixMode (GL_MODELVIEW) ;
gIScaled (sx, sy, 1.0); // set CT to CT * (2D scaling)
}
//<<<<<<<<<<< LranslaLe2D >>>>>>>>>>>>>>>

Dr Taleb Obaid 5 / 16

Computer Graphics CS 330 Spring 2011

void Canvas :: translate2D (donb1e dx, double dy) {


glMatrixMode (GL_MODELVIEW);
glTranslated (dx, dy 0); // set CT to CT * (2D translation)
}
//<<<<<<<<<<< rotatc2D >>>>>>>>>>>>>
void Canvas:: rotate2D (double angle) {
glMatrixMode (GL_MODELVIEW);
glRotated (angle, 0.0, 0.0, 1.0); // set CT to CT * (2D rotation)

EXAMPLE 5.5.1 Capitalizing on rotational symmetry


Figure 5.39(a) shows a star made of stripes that seem to interlock with one another. Suppose
that routine starMotif () draws a part of the star the polygon shown in Figure 5.39(b). Then, to
draw the whole star, we just draw the motif five times, each time rotating it through an additional
72°:

Fig 5.39 Using successive rotations of the coordinate system

for (int count = 0; count < 5 ; count++5) {


starMotif() ;
cvs.rotate2D (72.0): // concatenate another rotation
}

EXAMPLE 5.5.2 Drawing snowflakes


A snowflake has six identical spokes oriented 60° apart, and each spoke is symmetrical about its
own axis. It is easy to produce a complex snowflake by designing one half of a spoke and drawing
it 12 times.

Fig 5.40 Designing a snowflake

Dr Taleb Obaid 5 / 17
Computer Graphics CS 330 Spring 2011

A reflection about the x-axis is achieved by the use of scale 2D (l, -l), so the motif plus its reflection
can be drawn using the following code:
flakeMotif () ; // draw the top half
cva.scals2D(1.0, -1.0) : // flip it vertically
flakeMotif (); // draw the bottom half
cvs.scalc2D(1.0, 1.0); // restore the original axis
To draw the entire snowflake just execute this code six times, with an intervening rotation of 60°:
void drawFlake () {
for (int count = 0; count < 6; count++) {
flakeMotif () ;
cvs.scale2D (l.0. -1.0) :
flakeMotif () ;
cvs.sca1e2D (l .0 , -1,0);
cvs.rotatc2D (60.0);
}
}

5.5.1 Saving the CT for Later Use


A sequences of calls to rotate2D(), scala2D () ,and translate2D () make "additional" or "relative
changes to the CT, but sometimes we may need to "back up"' to some prior CT. To "remember"
the desired CT, we make a copy of it and store it in a convenient location. Then, we can restore
the CT. We may even want to keep a collection of prior CT's, and return to selected ones at key
moments. To do this, you can work with a stack of transformations, as suggested by Figure 5.43.
To save this CT for later use, a copy of it is made and "pushed" onto the stack using a routine
pushCT () .This makes the top two items on the stack identical. The top item can now be altered
further with additional transformation calls. To return to the previous CT, the top item is simply
"popped" off the stack using popCT () and then discarded. That way we can return to the most
recent CT, the next most recent CT, and so forth, in a last-in, first-out order.

The implementation of pushCT () and popCT () is simple with OpenGL, which has routines
glPushMatrix () and glPopMatrix () to manage several different slacks of matrices as in Figure
5.44.

Dr Taleb Obaid 5 / 18

Computer Graphics CS 330 Spring 2011

Fig 5.44 Routines to save and restore CT's

void Canvas:: pushCT (void) {


glMatrixMode (GL_MODELVIEW);
glPushMatrix () ; // push a copy of the top matrix
}

void Canvas:: popCT(vuid) {


glMatrixMode (GL_MODELVIEW);
glPopMatrix () : / / pop the top matrix from the stack
}

EXAMPLE 5.5.5 Tilings made easy


As in Figure 5.45, the motif is drawn centered in its own coordinate system, as shown in Part (a).
Copies of the motif are drawn L units apart in the x-direction and D units apart in the y-direction,
as shown in Part (b).

Fig 5.45 A tiling based on a Motif. (a) The motif, (b) The tiling

Cvs.pushCT () : // so we can return here


cvs. translate2D (W, H); // position for the first motif
for (row = 0; row < 3; row++) { // draw each row
cvs.pushCT ();
for (col = 0; col < 4; co1++) { // draw the next row of motifs
motif ();
cvs.translate2D (L,0); // move to the right
}
cvs.popCT(); // back to the start of this row
cvs.translate2D ( 0 . D) ; / / move up to the next row
}

cvs.popCT(); // back to where we started

Dr Taleb Obaid 5 / 19
Computer Graphics CS 330 Spring 2011

Fig 5.46 Drawing a hexagonal tiling

5.5.3 A hexagonal tiling

Fig 5.49 A simple hexagonal tiling

a. The length of each edge of a hexagon with radius R is also R.


3*R and that
adjacent column are separated horizontally by 3R/2.
c. Using pushCT () and popCTC () and suitable Transformations to keep track of where each row
and column start.

//<<<<<<<<<<<<<<<<<<<< Scale2D >>>>>>>>>>>>>>>>>>


void Scale2D (double sx, double sy) {
glMatrixMode (GL_MODELVIEW);
glScaled (sx, sy, 1.0);
}

//<<<<<<<<<<<<<<<<<< Translate2D >>>>>>>>>>>>>>>>>>


void Translate2D (double dx, double dy) {
glMatrixMode (GL_MODELVIEW);
glTranslated (dx, dy, 0.0);
}

//<<<<<<<<<<<<<<<<<<< Rotate2D >>>>>>>>>>>>>>>>>>


void Rotate2D (double angle) {
glMatrixMode (GL_MODELVIEW);
glRotated (angle, 0.0, 0.0, 1.0);
}
//<<<<<<<<<<<<<<<<<<< T_Letter >>>>>>>>>>>>>>>>>
void T_Letter (void) {
glBegin (GL_LINE_LOOP);

Dr Taleb Obaid 5 / 20

Computer Graphics CS 330 Spring 2011

for (int k = 0; k < nPoints; k++)


glVertex2d(T[k][0], T[k][1]);
glEnd();
glFlush(); // send all output to display
}

//<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>>>>>>


void myDisplay (void) {
double left, right, bottom, top;
left = -200.0, right = 200., bottom = -200.0, top = 200.;
setWindow (left, right, bottom, top); // entire world window
glViewport (0, 0, 400, 400);
T_Letter ();
Scale2D (0.5, 0.5);
T_Letter ();
Scale2D (1.0, -1.0);
T_Letter ();
Translate2D (200., 100.0);
T_Letter ();
Rotate2D (-30);
T_Letter ();
}

Without using glPushMatrix () and glPopMatrix ()


//<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>>>>>>
void myDisplay (void) {
double left, right, bottom, top;
left = -200.0, right = 200., bottom = -200.0, top = 200.;
setWindow (left, right, bottom, top); // entire world window
glPushMatrix ();
glViewport (0, 0, 400, 400);
T_Letter ();
Scale2D (0.5, 0.5);
T_Letter ();
Scale2D (1.0, -1.0);
T_Letter ();
Translate2D (200., 100.0);
T_Letter ();
glPopMatrix ();
Rotate2D (30);
T_Letter ();
}
Using glPushMatrix () and glPopMatrix ();
#include <GL/glut.h>
#include <stdlib.h>
static GLfloat spin = 0.0;

Dr Taleb Obaid 5 / 21
Computer Graphics CS 330 Spring 2011

void init (void) {


glClearColor (1., 1., 1., 0.0);
glShadeModel (GL_FLAT);
}
void display (void) {
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 0.0, 0.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();

// The center of the rectangle is not at the origin.


// The rotation around the origin as in Fig 1
glRotatef (-spin, 0.0, 0.0, 1.0);
glRectf (10.0, 10.0, 40.0, 40.0);

// Translate the rectangle center to the origin, rotated,


// and the translated again, as in Fig 2.
glTranslatef (25.0, 25.0, 0.0);
glRotatef (-spin, 0.0, 0.0, 1.0);
glTranslatef (-25.0, -25.0, 0.0);
glRectf (10.0, 10.0, 40.0, 40.0);
glutSwapBuffers();
}
void spinDisplay_CW (void) {
spin = spin + 1.0;
if (spin > 360.0)
spin = spin -360.0;
glutPostRedisplay ();
}
void spinDisplay_CCW (void) {
spin = spin - 1.0;
if (spin < 360.0)
spin = spin + 360.0;
glutPostRedisplay ();
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (-100.0, 100.0, -100.0, 100.0, -1.0, 1.0);
glMatrixMode (GL_MODELVIEW);
}

void mouse (int button, int state, int x, int y) {


switch (button) {
case GLUT_LEFT_BUTTON:

Dr Taleb Obaid 5 / 22

Computer Graphics CS 330 Spring 2011

if (state == GLUT_DOWN)
glutIdleFunc (spinDisplay_CW);
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc (spinDisplay_CCW);
else
glutIdleFunc (NULL);
break;
default:
break;
}
}
int main (int argc, char**argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (600, 600);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutMouseFunc (mouse);
glutMainLoop();

return 0;
}

Fig 1, The Rotation around the origin, the center of rectangle


Is not coincide on the origin

Fig 2, The Rotation around the center of the rectangle

Dr Taleb Obaid 5 / 23
Computer Graphics CS 330 Spring 2011

5.6 DRAWING 3D SCENES WITH OPENGL


The 2D transformations are special cases of 3D that ignore the third dimension. We have using
the camera as in Fig 5.50, the eye looks along the z-
xy-plane. The view volume of the camera is a rectangular parallelepiped, whose four sidewalls
are determined by the border of the window and whose other two walls are determined by a
near plane and a far plane.

Fig 5.50 Simple viewing used in OpenGL for 2D drawing

Points lying inside the view volume are projected onto the window along lines parallel to the z-
axis, i.e. ignoring the z-components of those points, so 3D point (x1, y1, z1) projects to (x1, y1, 0).
Points lying outside the view volume are clipped off.

Fig 5.51 shows such a camera immersed in a scene. The scene consists of a block, part of which
lies outside the view volume.

Dr Taleb Obaid 5 / 24

Computer Graphics CS 330 Spring 2011

Fig 5.51 A camera to produce parallel views of a scene

Each vertex encounters three matrices:


The modelview matrix
The projection matrix
The viewport matrix

Fig 5.52 The OpenGL Pipline

The modelview matrix provides what we have calling the CT. It combines two effects: the
sequence of modeling transformation applied to objects and the transformation that orients and
positions the camera.

Fig 5.53 effect of the modelview matrix in the graphics pipeline.

Dr Taleb Obaid 5 / 25
Computer Graphics CS 330 Spring 2011

(a) before the transformations. (b) After the modeling transformation.


(c) After the modelview transformation.
Fig 5.53 suggests what the M and V matrices do.
Part (a) shows a unit cube centered at the origin.
Part (b) shows a modeling transformation based on M (scales, rotates,..) the cube into the block,

The V matrix used to rotate and translate the block into a new position. The specific
transforma
with the eye at the origin and view volume aligned with z-axis, as in Part (c).
In the (eye) coordinate, the edges of the view volume are parallel to the x-,y-, and z-
axes. The volume extends from left to right in x, from bottom to top in y, and from near to -far
in z.

The projection matrix scales and shifts each vertex in a particular way, so that all those vertices
that lie inside the view volume will lie inside a standard cube that extends from 1 to 1 in each
dimension.

Fig 5.54 Effect of the projection matrix (for parallel projections).

The viewport matrix maps


maps the standard cube into a block shape whose x and y values extend across the viewport
(screen coordinate) and whose z-component extend from 0 to 1 and retains a measure of the
depth of point.

Figure 5.55 Effect of the viewport transformation

Dr Taleb Obaid 5 / 26

Computer Graphics CS 330 Spring 2011

5.6.2 Some OpenGL Tools for Modeling and Viewing

The following functions are normally used to modify the modelview matrix, which is first made
"current" by executing: gIMatrixMode (GL_MODELVIEW)

glScaled (sx, sy, sz);


Postmultiply the current matrix by a matrix that performs a scaling by sx in x, by sy in y, and by
sz in z. Put the result back into the current matrix
glTranslated (dx, dy . dz);
Postmultiply the current matrix by a matrix that performs a translation by dx in x, by dy in y, and
by dz in z. Put the result back into the current matrix

glRotated(angle, ux , uy , uz);
Postmultiply the current matrix by a matrix that performs a rotation through angle degrees about
the axis that passes through the origin and the point (ux, uy, uz). Put the result back in the
current matrix.

Setting the Camera in OpenGL


The function glOrtho (left, right, bott, top, near, far); establishes as a view volume a
parallelipiped that extends from left to right in x, from bott to top in y, and from near to -far in
z. The minus signs before near and far, because the default camera is located at the origin looking
down the negative z-axis, using a value of 2 for near means to place the near plane at 2, i.e., 2
units in front of eye, 20 for far means place the far plane 20 units in front of eye.

The following code sets the projection matrix:


glMatrixMode (GL_PROJECTION); // make the projection matrix current
glLoadIdentity (); // set it to the identity matrix
glOrtho (left, right, bottom, top, near, far); // multiply it by the new matrix

Positioning and Aiming the Camera


OpenGL offers a function that creates the view matrix and postmultiplies the current matrix by
it.
gluLookAt (eye.x, eye.y, eye.z, look.x, look.y, look.z, up.x, up.y, up.z);

EXAMPLE 5.6.1 Set up a typical camera


Cameras are often set to "look down " on a scene from some nearby position. Fig 5.56 shows a
camera with its eye situated at eye = (4, 4, 4), looking at the origin with look = (0, 1, 0). The
upwards direction is set to up = (0, 1, 0). Suppose we also want the view volume to have
a width of 6.4 and a height of 4.8, and suppose we wish to set near to 1 and far to 50
The camera could be established with the following code
glMatixModR(GL_PROJECTION); // set the view volume
glLoadIdentity ();
gl0rtho (-3.2, 3.2, -2.4, 2.4, 1, 50);
glMatrixMode (GL_MODELVTEW) : // place and aim the camera
glLoadIdantity ();

Dr Taleb Obaid 5 / 27
Computer Graphics CS 330 Spring 2011

gluLookAt (4, 4, 4, 0, 1, 0, 0, 1, 0);

FIGURE 5.56 Setting a camera with gluLookAt ()

5.6.3 Drawing Elementary Shapes Provided by OpenGL


The GLUT provides several ready-made 3D objects, including a sphere, a cone, a torus, the five
Platonic solids, and the teapot. Each is available as a wire-frame model and as a solid model with
faces that can be shaded.

cube: glutWireCube (GLdouble size) ; Each side is of length size .


sphere: glutWireSphere(GLdouble radius, GLint nSlices, GLint nStacks);
torus: glutWireTorus (GLdouble inRad, GLdouble outRad, Glint nSlices, GLint nStacks);
teapot: glutWircTeapot (GLdouble size)
There are also a glutSolidCube (), glutSolidSphere (), etc.,

The torus is determined by the inner radius inRad and outer radius outRad.
The sphere and torus are approximated by polygonal faces, and you can adjust the parameters
nSlices and nStacks to specify how many faces to use in the approximation. nSlices is the number
of subdivisions around the z-axis, and nStacks is the number of "bands" along the z-axis, as if the
shape were a stack of nStacks disks.

The functions used to render four of the Platonic solids are as follows:
tetrahedron: glutWireTetrahedron();
octahedron: glutWireOctahedron ();
dodecahedron: glutWireDodecahedron ();
icosahedron: glutWireIcosahedron ();

All of the preceding shapes are centered at the origin. We also have the following solids:
cone: glutWireCone (GLdouble baseRad, GLdouble height, GLint nSlices, GLint nStacks)

glu Quadrics

Dr Taleb Obaid 5 / 28

Computer Graphics CS 330 Spring 2011

tapered cylinder: gluCylinder (GLUquadricObj * qobj, GLdouble baseRad, GLdouble topRad,


GLdouble
height, GLint nSlices, GLint nStacks)

The axes of the cone and tapered cylinder coincide with the z-axis. Their bases rest on the z = 0
plane and extend to z = height along the z-axis. The radius of the
cone and tapered cylinder at z = 0 is given by baseRad. The radius of the tapered cylinder at z =
height is topRad.

When topRad is 1, there is no taper, and we have the classic right circular cylinder. When topRad
is 0,the tapered cylinder is identical to the cone.

Note that drawing the tapered cylinder in OpenGL requires some extra work. To draw it, you
must;

1. define a new quadric object,


2. set the drawing style ( GLU_LINE for a wire frame, GL_FILL for a solid rendering), and
3. draw the object.

The following code do all of this.

GLUquadricObj * qobj = gluNewQuadric(): // make a quadric object


gluQuadricDrawStyle (qobj, GLU_LlNE); // set style to wireframe
gluCylinder (qobj , baseRad, topRad, height. nSlices. nStacks);
// draw the cylinder

Fig 5.58 Shapes available in the GLU.

EXAMPLE 5.6.2
A scene composed of wire-frame objects Figure 5.59 shows a scene with several objects disposed
at the corners of a unit cube, which itself has one corner at the origin.
The camera is given a view volume that extends from -2 to 2 in y. with an aspect ratio of 640/480.
The near plane is at N = 0.1, the far plane at F = l00. This is accomplished using

g]Ortho (-2.0* aspect, 2.0* aspect, -2.0, 2.0, 0.1, 100);

The camera is positioned with eye = (2, 2, 2), lookAt = (0, 0, 0), and up = (0, 1, 0) (parallel lo the
y-axis), using
gluLookAt (2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

Dr Taleb Obaid 5 / 29
Computer Graphics CS 330 Spring 2011

glutWirecube (2.) glutWireSphere (1.0, 8, 5); glutWireTorus (0.5, 1., 8, 10);

glutWireCone (1.0, 2., 8,


10); glutWireTetrahedron
(); glutWireOctahedron
();

glutWireDodecahedron (); glRotated (ang + 15, 0.5, 0.5, 0.5); glutWireTeapot (1.);

Dr Taleb Obaid 5 / 30

Computer Graphics CS 330 Spring 2011

Fig 5.59 Wire-frame drawing of various primitive shapes

#include <windows.h> //suitable when using Windows 95/98/NT


#include <gl/Gl.h>
#include <gl/Glu.h>
#include <gl/glut.h>
//<<<<<<<<<<<<<<<<<<< axis >>>>>>>>>>>>>>
void axis (double length) {
// draw a z-axis, with cone at end
glPushMatrix();
glBegin (GL_LINES);
glVertex3d (0, 0, 0);
glVertex3d (0,0,length); // along the z-axis
glEnd ();
glTranslated (0, 0,length -0.2);
glutWireCone (0.04, 0.2, 12, 9);

Dr Taleb Obaid 5 / 31
Computer Graphics CS 330 Spring 2011

glPopMatrix ();
}

//<<<<<<<<<<<<<<<<<< displayWire >>>>>>>>>>>>>>>


void displayWire(void) {
glMatrixMode (GL_PROJECTION); // set the view volume shape
glLoadIdentity();
glOrtho (-2.0*64/48.0, 2.0*64/48.0, -2.0, 2.0, 0.1, 100);
glMatrixMode (GL_MODELVIEW); // position and aim the camera
glLoadIdentity();
gluLookAt (2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glClear (GL_COLOR_BUFFER_BIT); // clear the screen


glColor3d (0,0,0); // draw black lines
axis (0.5); // z-axis
glPushMatrix ();
glRotated (90, 0,1.0, 0);
axis (0.5); // y-axis
glRotated (-90.0, 1, 0, 0);
axis (0.5); // z-axis
glPopMatrix ();

glPushMatrix ();
glTranslated (0.5, 0.5, 0.5); // big cube at (0.5, 0.5, 0.5)
glutWireCube (1.0);
glPopMatrix ();

glPushMatrix ();
glTranslated (1.0,1.0,0); // sphere at (1,1,0)
glutWireSphere (0.25, 10, 8);
glPopMatrix ();

glPushMatrix ();
glTranslated (1.0,0,1.0); // cone at (1,0,1)
glutWireCone (0.2, 0.5, 10, 8);
glPopMatrix ();

glPushMatrix ();
glTranslated (1,1,1);
glutWireTeapot (0.2); // teapot at (1,1,1)
glPopMatrix ();

glPushMatrix ();
glTranslated (0, 1.0 ,0); // torus at (0,1,0)
glRotated (90.0, 1,0,0);
glutWireTorus (0.1, 0.3, 10,10);

Dr Taleb Obaid 5 / 32

Computer Graphics CS 330 Spring 2011

glPopMatrix ();

glPushMatrix ();
glTranslated (1.0, 0 ,0); // dodecahedron at (1,0,0)
glScaled (0.15, 0.15, 0.15);
glutWireDodecahedron ();
glPopMatrix ();

glPushMatrix ();
glTranslated (0, 1.0 ,1.0); // small cube at (0,1,1)
glutWireCube (0.25);
glPopMatrix ();

glPushMatrix ();
glTranslated (0, 0 ,1.0); // cylinder at (0,0,1)
GLUquadricObj * qobj;
qobj = gluNewQuadric ();
gluQuadricDrawStyle (qobj,GLU_LINE);
gluCylinder (qobj, 0.2, 0.2, 0.4, 8, 8);
glPopMatrix ();
glFlush ();
}

Dr Taleb Obaid 5 / 33
Computer Graphics CS 330 Spring 2011

//<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>


void main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize(640,480);
glutInitWindowPosition(100, 100);
glutCreateWindow("Transformation tested - wireframes");
glutDisplayFunc(displayWire);
glClearColor(1.0f, 1.0f, 1.0f,0.0f); // background is white
glViewport(0, 0, 640, 480);
glutMainLoop();
}

The main () routine initializes a 640-by-480 pixel screen window, sets the viewport and
background color, and specifies displayWire ().
In displayWire (), the shape and position of the camera are established first. Then each object is
drawn in turn.

Before each modeling transformation is established, a glPushMatrix() is used to remember the


current transformation, and after the object has been drawn, the current transformation is
restored with a glPopMatrix().

Also shown in the figure are the x-, y-, and z-axes, drawn with conical arrow-heads. Displaying
the underlying coordinate system can help to orient the viewer. To draw the x-axis, the z-axis is
rotated 90o about the y-axis to form a rotated system, and the x-axis is redrawn in its new
orientation. Note that this axis is drawn without immersing it in a glPushMaLrix (), glPopMatrix ()
pair, so the next rotation to produce the y-axis takes place in the already rotated coordinate
system.

EXAMPLE 5.6.3 A 3D Scene Rendered with Shading


In this example, we develop a somewhat more complex scene. We also show how easy OpenGL
makes it to draw much more realistic drawings of solid objects by incorporating shading.

Fig 5.61 A simple 3D scene a) using a large view volume, b) using a small view volume

Dr Taleb Obaid 5 / 34

Computer Graphics CS 330 Spring 2011

Two views of a scene are shown in Figure 5.61. Both views use a camera set by

gluLookAt (2.3, 1.3. 2. 0, 0.25, 0, 0.0,1 . 0 , 0 . 0).

Part (a) uses a large view volume that encompasses the whole scene;
Part (b) uses a small view volume that encompasses only a small portion of the scene, thereby
providing a close-up view.

The scene contains three objects resting on a table in the corner of a "room." Each of the three
walls is made by flattening a cube into a thin sheet.

The jack is composed of three stretched spheres oriented at right angles to each other, plus six
small spheres at their ends.
The table consists of a tabletop and four legs. Each of the table's five pieces is a cube that has
been scaled to the desired size and shape. The layout for the table is shown in Figure 5.62 and is
based on Four parameters that characterize the size of its parts: topWidth, topThick, 1egLen, and
legThick. A routine tableLeg () draws each leg and is called four times within the routine table ().
Always, a glPushMatrix (), glPopMatrix () pair surrounds the modeling functions to isolate their
effect

Fig 5.62 Designing the table


The complete code for this program is shown in Fig 5.63. The code shows the various things that
must be done to create shaded images. The position and properties of a light source must be
specified, along with certain properties of the objects' surfaces, in order to describe how they
reflect light

#include <windows.h>

Dr Taleb Obaid 5 / 35
Computer Graphics CS 330 Spring 2011

#include <gl/Gl.h>
#include <gl/Glu.h>
#include <gl/glut.h>
// <<<<<<<<<< wall >>>>>>>>>>>
void wall (double thickness ) {
// draw thin wall with top = xz-plane, corner at origin
glPushMatrix () ;
glTranslated (0.5, 0.5 * thickness, 0.5);
glScaled (1.0, thickness, 1.0);
glutSolidCube (1.0);
glPopMatrix ();
}
// <<<<<<<<<< tablfeLeg >>>>>>>>>>
void tableLeg (double thick, double len) {
glPushMatrix () ;
glTranslated (0, len/2, 0);
glScaled (thick, len, thick);
glutSolidCube (1.0) ;
glPopMatrix ();
}
//<<<<<<<<<< jack part >>>>>>>>>>>>
void jackPart () {
// draw one axis of the unit jack - a stretched sphere
glPushMatrix ();
glScaled (0.2,0.2, 1.0);
glutSolidSphere (1, 15, 15);
glPopMatrix () ;
glPushMatrix () ;
glTranslated (0, 0.1, 2) ; // ball on one end
glutSolidSphere (0.2, 15, 15) ;
glTranslated (0, 0, -2.4);
glutSolidSphere (0.2, 15, 15); // ball on the other end
glPopMatrix ();
}
//<<<<<<<<<<<<< jack >>>>>>>>>>>
void jack() {
// draw a unit jack out of spheroids
glPushMatrix () ;
jackPart ();
glRotated (90.0, 0, 1, 0);
jackPart ();
glRotated (90.0, 1, 0, 0);
jackPart () ;
glPopMatrix () ;
}

Dr Taleb Obaid 5 / 36

Computer Graphics CS 330 Spring 2011

//<<<<<<<<<<<< table >>>>>>>>>>>


void table (double topWid, double topThick, double legThick,
double legLen) {
// draw tha tabi e - a top and four lags
glPushMatrix (); // draw the table top
glTranslated (0, legLen, 0);
glScaled (topWid , topThick, topWid) ;
glutSolidCube (1.0);
glPopMatrix ();
double dist =0.95 * topWid/2.0 - legThick / 2.0;
glPushMatrix ();
glTranslated (dist, 0, dist);
tableLeg (legThick, legLen);
glTranslated (0, 0, -2*dist);
tableLeg (legThick, legLen);
glTranslated(-2*dist, 0, 2*dist);
tableLeg (legThick, legLen);
glTranslated (0, 0, -2*dist);
tableLeg (legThick, legLen);
glPopMatrix();
}
//<<<<<<<<<<<, displaySolid >>>>>>>>>
void displaySolid (void) {
//set properties of the surface material
GLfloat mat_ambient () = { 0.7f, 0.7f, 0.7f, 1.0f}; // gray
GLfloat mat_diffuse () = { 0.6f, 0.6f, 0.6f, 1.0f};
GLfloat mat_specular () = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat mat_shininess [] = { 50.0f};
glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient) ;
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse) ;
glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular) ;
glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess);
// set the light source properties
GLfloat lightIntensity () = {0.7f, 0.7f, 0.7f, 1.0f} ;
GLfloat light_position () = {2.0f, 6.0f, 3.0f, 0.0f} ;
glLightfv (GL_LIGHT0, GL_POSITION, light_position);
glLightfv( GL_LIGHT0, GL_DIFFUSE, lightIntensity) ;
// set the camera
glMatrixMode (GL_PROJECTION);
glLoadIdentity () ;
double winHt = 1.0; // half-height of the window
glOrtho (-winHt* 64/48.0, winHt *64/48.0, -winHt, winHt, 0.1, 100.0) ;
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt(2.3, 1.3, 2, 0, 0.25, 0, 0.0, 1.0, 0.0);
// start drawing

Dr Taleb Obaid 5 / 37
Computer Graphics CS 330 Spring 2011

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ; // clear


glPushMatrix ();
glTranslated (0.4, 0.4, 0.6);
glRotated (45, 0, 0, 1);
glScaled (0.08, 0.08, 0.08);
jack() ; // draw the jack
glPopMatrix ();
glPushMatrix ();
glTranslated (0.6, 0.38, 0.5);
glRotated (30,0, 1,0) ;
glutSolidTeapot (0.08) ; // draw the teapot
glPopMatrix () ;
glPushMatrix ();
glTranslated (0.25 ,0.42, 0.35);// draw the. sphere
glutSolidSphere (0.1, 15, 15) ;
glPopMatrix () ;
glPushMatrix ();
glTranslated (0.4, 0, 0.4) ;
table (0.6, 0.02, 0.02, 0.3); // draw the table
glPopMatrix () ;
wall (0.02); // wall #1 in xz-plane
glPushMatrix () ;
glRotated (90.0, 0.0, 0.0, 1.0);
wall (0.02); // wall #2 in yz-plane
glPopMatrix () ;
glPushMatrix () ;
glRotated (-90.0, 1.0, 0.0, 0.0) ;
wall ( 0.02) ; // wall #3: in xy-plane
glPopMatrix ();
glFlush () ;
}
//<<<<<<<<<<<< main >>>>>>>>>>
void main (int argc, char **argv) {
glutInit (&argc , argv) ;
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (640, 480) ;
glutInitWindowPosition (100, 100) ;
glutCreateWindow ("shaded example - 3D scene") ;
glutDisplayFunc (displaySolid) ;
glEnable (GL_LIGHTING) ; // enable the light source
glEnable (GL_LIGHT0) ;
glShadeModel (GL_SMOOTH) ;
glEnable (GL_DEPTH_TEST) ; // for removal of hidden surfaces
glEnable (GL_NORMALIZE); // normalize vecLors for proper shading
glClearColor (0.1f, 0.1f, 0.1f, 0.0f); // background is light gray
glViewport (0, 0, 640, 480);

Dr Taleb Obaid 5 / 38

Computer Graphics CS 330 Spring 2011

glutMainLoop () ;
}

light_position () = {2.0f, 6.0f, 3.0f, 0.0f} ; light_position() = {5.0f, 0.0f, 0.0f,


0.0f} ;

light_position () = {0.0f, 5.0f, 0.0f, 0.0f} ; light_position () = {0.0f, 0.0f, -5.0f,


0.0f} ;

Dr Taleb Obaid 5 / 39
Computer Graphics CS 330 Spring 2011

gluLookAt(2.3, 1.3, 2, 0, 0.25, 0, 1.0, 0.0, 0.0); gluLookAt(2.3, 1.3, 2, 0, 0.25, 0, 0.0,
0.0,1.0);

5.6.3 Adjusting the Scene

What changes should be made in Figure 5.63 to place the jack on the floor and the sphere
perched on top of the teapot?

Dr Taleb Obaid 5 / 40

Computer Graphics CS 330 Spring 2011

Menus
The windowing systems support a set of widgets, which are special types of windows with which
the user can interact. Widgets sets include menus, buttons, slides bars, and dialog boxes. GLUT
provides limited capabilities, such as menu.

Defining a menu requires:


We must decide what entries are in the menu, i.e., what string will be displayed in each
row of a menu.
We must tie specific actions to the rows.
We must tie each menu to a mouse button.
Menus are usually created either in main() or in an initialization function called from main().

int glutCreateMenu (void (*f)(int value))


Create a top-level menu that uses the callback f(), which is pressed an integer value for the menu
entry. A unique identifier is returned for the menu created.
The menu created becomes the current menu. The current menu can be changed by
glutSetMenu().

void glutSetMenu (int id)


Set the current menu to the menu with identifier id. Entries are added into the current menu by
glutAddMenuEntry(). Each entry consists of two parts:
1. A string displayed for the entry.
2. A value returned when that entry is selected.

void glutAddMenuEntry (char *name, int value)


Adds an entry with name displayed to the current menu; value is returned to the menu callback.

Attached the menu to a mouse button by


void glutAttachMenu (int button)
Attaches the current menu to the specified mouse button (GLUT_RIGHT_BUTTON,
GLUT_MIDDLE_BUTTON, or GLUT_LEFT_BUTTON).

Suppose that we want to use the right mouse button to pop up a menu that will have two entries:
Clear the screen.
End the program.
glutCreateMenu (mymenu);
glutAddMenuEntr

glutAttachMenuEntry (GLUT_RIGHT_BUTTON);

void myMenu (int value) {


if (value == 1) glClear();
if (value == 2) exit(0);
}

We can add submenus to a menu.

Dr Taleb Obaid 5 / 41
Computer Graphics CS 330 Spring 2011

void glutAddSubMenu (char *name, int menu)


Add a submenu entry name as the next entry in the current menu. The value of menu is the ID of
the submenu returned when the submenu was created.

The NULL Callback


Callback functions can be redefined during execution by simply naming a new callback function
in the appropriate function. At times, we want to simply eliminate a callback.
glutIdelFunc (NULL);

Subwindows and Multiple Windows


Some times we want to use multiple windows.

int glutCreateWindow (char *name)


Creates a top-level window name

void glutdestroyWindow (int id)


Destroy the top-level window id.

When a window is created, it becomes the current window, the primitive are rendered to the
current window. We can change this window by:

int glutSetWindow (int id)


Sets the current window to the window with identifier id

We can also create sub-windows of any window. Each sub-window is defined to be a sub-
rectangle of its parent using:

int glutCreateSubWindow (int parant, int x, int y, int width, int height ) ;
Creates a sub-window of parent and returns its ID. The sub-window has its origin at (x, y) and has
size width by height in pixels. The sub-window becomes the current window.

Dr Taleb Obaid 5 / 42

Computer Graphics CS 330 Spring 2011

Some Functions:
void glutIdleFunc (void (*f) (void)) ;
The function f() is executed whenever no other events are to be handled. When we want to
eliminate a callback, we call glutIdelFunction ().

void glutPostRedisplay ();


Requests that display callback be executed.

void glutSwapBuffers ();


Swaps the front and back buffers.

// Menu Program
#include <GL/glut.h>
#include <stdlib.h>
GLsizei ww = 500, wh = 500;
int fill, r=1.0, g=1.0, b=1.0;
void fill_menu (int );
void color_menu (int );
void right_menu (int );
void display (void) {
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(r, g, b);
if (fill == 1)
glBegin (GL_POLYGON);
else
glBegin (GL_LINE_LOOP);
glVertex3f (100.0, 200.0, 0.0);
glVertex3f (200.0, 200.0, 0.0);
glVertex3f (200.0, 300.0, 0.0);
glVertex3f (100.0, 300.0, 0.0);
glEnd();
glFlush ();
}
void init (void) {
glClearColor (0.3, 0.5, 0.3, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
}
void fill_menu (int id) {
if (id == 1)
fill = 1;
else
fill = 0;
glutPostRedisplay();
}

Dr Taleb Obaid 5 / 43
Computer Graphics CS 330 Spring 2011

void color_menu (int id) {


if (id == 1) { r=1.0; g=0.0; b=0.0;}
if (id == 2) { r=0.0; g=1.0; b=0.0;}
if (id == 3) { r=0.0; g=0.0, b=1.0;}
glutPostRedisplay();
}

void right_menu (int id) {

int main (int argc, char**argv) {


int c_menu, f_menu;
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (300, 300);
glutInitWindowPosition (50, 100);
glutCreateWindow ("hello");
glutDisplayFunc (display);

c_menu = glutCreateMenu(color_menu);
glutAddMenuEntry ("Red", 1);
glutAddMenuEntry ("Green", 2);
glutAddMenuEntry ("Blue", 3);

f_menu = glutCreateMenu (fill_menu);


glutAddMenuEntry ("fill on", 1);
glutAddMenuEntry ("fill off", 2);

glutCreateMenu (right_menu);
glutAddSubMenu("Colors", c_menu);
glutAddSubMenu("Fill", f_menu);
glutAttachMenu (GLUT_RIGHT_BUTTON);
init ();
glutMainLoop();
return 0;
}

Dr Taleb Obaid 5 / 44

You might also like