Anda di halaman 1dari 9

BIRLA INSTITUTE OF TECHNOLOGY & SCIENCE, PILANI IS F311 / CS C471/ IS C471 Computer Graphics First Semester 2013-2014 Lab

# 2 In this lab we will learn some basic functions in OpenGL like polygon fill area functions, attribute functions, display lists, and geometric transformations in 2D. POLYGON FILL AREAS Polygon- refers to those planar shapes that have a closed polyline boundary and no edge crossings. Polygon Classications 1. 2. 3. 4. Convex: All interior angles < 180 graden All line segments between 2 interior points inside the polygon All points are at the same side of line through edge, and From each interior point complete boundary visible

1 2 4

Fig 1. Convex Polygon

Concave: not convex Polygon Fill Functions OpenGL procedures for specifying fill polygons are similar to those for describing a point or a polyline. glVertex() function is used to input the coordinates for a single polygon vertex glBegin/glEnd - A complete polygon is described with a list of vertices placed between this pair. However, there is one additional function that we can use for displaying a rectangle that has an entirely different format.

************************************************************************** NOTE- By default, a polygon interior is displayed in a solid color, determined by the current color settings. However ,there are six different symbolic constants that we can use as the argument in the glBegin function to describe polygon fill areas. ************************************************************************** In OpenGL, fill color and other attributes can be set for each face separately and back/front identification is needed in both two-dimensional and three dimensional viewing routines. Therefore, polygon vertices should be specified in a counterclockwise order as we view the polygon from outside. This identifies the front face for that polygon. Because graphics displays often include rectangular fill areas, OpenGL provides a special rectangle function for directly accepting vertex specifications in the xy plane. glRect* (x1, y1, x2, y2); One corner of this rectangle is at coordinate position (x1, y1), and the opposite corner of the rectangle is at position (x2, y2). Suffix codes for glRect specify the coordinate data type and whether coordinates are to be expressed as array elements. These codes are i (for integer), s (for short), f (for float), d (for double), and v (for vector). The output of the following statement defines the square shown in figure 2. glRecti (200, 100, 50, 250);

Fig. 2.Display of a square fill area using the glRect function.

If we put the coordinate values for this rectangle into arrays, we can generate the same square with the following code. int vertex1 [ ] = {200, 100}; int vertex2 [ ] = {50, 250}; glRectiv (vertex1, vertex2);

When a rectangle is generated with function glRect, the polygon edges are formed between the vertices in the order (x1, y1), (x2, y1), (x2, y2), (x1, y2), and then back to the first vertex. Thus, in the example, we produced a vertex list with a clockwise ordering. Each of the other six OpenGL polygon fill primitives is specified with a symbolic constant in the glBegin function, along with a a list of glVertex commands. With the OpenGL primitive constant GL_POLYGON, we can display a single polygon fill area. For this example, we assume that we have a list of six points, labeled p1 through p6, specifying two dimensional polygon vertex positions in a counterclockwise ordering. Each of the points is represented as an array of (x, y) coordinate values. glBegin (GL_POLYGON); glVertex2iv (p1); glVertex2iv (p2); glVertex2iv (p3); glVertex2iv (p4); glVertex2iv (p5); glVertex2iv (p6); glEnd (); *************************************************************************** NOTE- A polygon vertex list must contain at least three vertices. Otherwise, nothing is displayed. ****************************************************************************

Fig. 3. Displaying polygon fill areas using a list of six vertex positions. (a)A single convex polygon fill area generated with the primitive constant GL_POLYGON. (b) Two unconnected triangles generated with GL_TRIANGLES.

(c) Four connected triangles generated with GL_TRIANGLE_STRIP. (d) Four connected triangles generatedwith GL_TRIANGLE_FAN..

Code example to GL TRIANGLES, we obtain the two separated triangle fill areas

glBegin (GL_TRIANGLES); glVertex2iv (p1); glVertex2iv (p2); glVertex2iv (p6); glVertex2iv (p3); glVertex2iv (p4); glVertex2iv (p5); glEnd ( ); In this case, the first three coordinate points define the vertices for one triangle, the next three points define the next triangle, and so forth. For each triangle fill area, we specify the vertex positions in a counterclockwise order. By reordering the vertex list once more and changing the primitive constant to GL_TRIANGLE_STRIP, we can display the set of connected triangles. glBegin (GL_TRIANGLE_STRIP); glVertex2iv (p1); glVertex2iv (p2); glVertex2iv (p6); glVertex2iv (p3); glVertex2iv (p5); glVertex2iv (p4); glEnd ( ); Another way to generate a set of connected triangles is to use the fan approach, where all triangles share a common vertex. We obtain this arrangement of triangles using the primitive constant GL_TRIANGLE_FAN and the original ordering of our six vertices: glBegin (GL_TRIANGLE_FAN); glVertex2iv (p1); glVertex2iv (p2); glVertex2iv (p3); glVertex2iv (p4); glVertex2iv (p5); glVertex2iv (p6); glEnd ( ); Besides the primitive functions for triangles and a general polygon, OpenGL provides for the specifications of two types of quadrilaterals (four-sided polygons). With the GL_QUADS

primitive constant and the following list of eight vertices, specified as two-dimensional coordinate arrays, we can generate the the output shown in figure 4. glBegin (GL_QUADS); glVertex2iv (p1); glVertex2iv (p2); glVertex2iv (p3); glVertex2iv (p4); glVertex2iv (p5); glVertex2iv (p6); glVertex2iv (p7); glVertex2iv (p8); glEnd ( ); The first four coordinate points define the vertices for one quadrilateral, the next four points define the next quadrilateral, and so on.

Fig. 4. Displaying quadrilateral fill areas using a list of eight vertex positions with GL QUADS.

Rearranging the vertex list in the previous quadrilateral code example and changing the primitive constant to GL_QUAD_STRIP, we can obtain the set of connected quadrilaterals. glBegin (GL_QUAD_STRIP); glVertex2iv (p1); glVertex2iv (p2); glVertex2iv (p4); glVertex2iv (p3); glVertex2iv (p5);

glVertex2iv (p6); glVertex2iv (p8); glVertex2iv (p7); glEnd ( );

Fig. 5. Displaying quadrilateral fill areas using a list of eight vertex positions with GL QUAD STRIP.

************************************************************************** OpenGL DISPLAY LISTS Creating and Naming an OpenGL Display List A set of OpenGL commands is formed into a display list by enclosing the commands within the glNewList/glEndList pair of functions. For example, glNewList (listID, listMode}; ... glEndList ( ); The following code segment illustrates the creation and execution of a display list. First set up a display list that contains the description for a regular hexagon, defined in the xy plane using a set of six equally spaced vertices around the circumference of a circle, whose center coordinates are (100, 100) and whose radius is 75. Then we issue a call to function glCallList, which displays the hexagon. const double TWO_PI = 6.2831853; GLuint regHex; GLdouble theta; GLint x, y, k; /* Set up a display list for a regular hexagon.

* Vertices for the hexagon are six equally spaced * points around the circumference of a circle. */ regHex = glGenLists (1); // Get an identifier for the display list. glNewList (regHex, GL_COMPILE); glBegin (GL_POLYGON); for (k = 0; k < 6; k++) { theta = TWO_PI * k / 6.0; x = 100 + 75 * cos (theta); y = 100 + 75 * sin (theta); glVertex2i (x, y); } glEnd ( ); glEndList ( ); glCallList (regHex); The symbolic constant GL_COMPILE_AND_EXECUTE forces to execute the list as soon as the commands are placed in the list. OpenGL LINE-ATTRIBUTE FUNCTIONS The appearance of a straight-line segment in OpenGL with three attribute settings: line color, line width, and line style. The following program outline the use of the OpenGL line attribute functions by plotting three line graphs in different styles and widths.

/* Define a two-dimensional world-coordinate data type. */ typedef struct { float x, y; } wcPt2D; wcPt2D dataPts [5]; void linePlot (wcPt2D dataPts [5]) { int k; glBegin (GL_LINE_STRIP); for (k = 0; k < 5; k++) glVertex2f (dataPts [k].x, dataPts [k].y); glFlush ( ); glEnd ( ); }

/* Invoke a procedure here to draw coordinate axes. */ glEnable (GL_LINE_STIPPLE); /* Input first set of (x, y) data values. */ glLineStipple (1, 0x1C47); // Plot a dash-dot, standard-width polyline. linePlot (dataPts); /* Input second set of (x, y) data values. */ glLineStipple (1, 0x00FF); // Plot a dashed, double-width polyline. glLineWidth (2.0); linePlot (dataPts); /* Input third set of (x, y) data values. */ glLineStipple (1, 0x0101); // Plot a dotted, triple-width polyline. glLineWidth (3.0); linePlot (dataPts); glDisable (GL_LINE_STIPPLE);

Fig. 8 Plotting three data sets with three different OpenGL line styles and line widths: single-width dash-dot pattern, double-width dash pattern, and triple-width dot pattern.

The functions used are glLineWidth(width) it assigns a floating point value to parameter width which is rounded to nearest non negative integer glLineStipple(repeatFactor, pattern) is used for setting the display style for lines The pattern parameter refers to a 16 bit integer that describes how the line should be displayed. A 1 bit in the pattern denotes an on pixel position and a 0 bit indicates an off pixel position. The default pattern is 0xFFFF which results in a solid line. The repeatFactor specifies how many times each bit in the pattern is to be repeated before the next bit is applied.

Exercises Download the file transform2D.cpp that contains functions to perform geometric transformations in 2D. Using this as a template, answer the following questions. 1. Perform a scaling operation with respect to any point (say centroid) of a polygon (say a triangle) with scale factor less than 1, and scale factor greater than 1. Observe that the object moves closer to and farther away from the origin respectively. 2. Scaling an object with respect to a fixed point doesnt affect the fixed point. Show this using the function scale2D given in the file. Use one of the vertices of the triangle as the fixed point and display the triangle both before and after scaling w.r.t. to the fixed point using red and green colors respectively. Highlight the fixed point with blue color and a point size of 3.0. Save the display window as Scale.png. Write your code in a displayfunction named displayScale. 3. The transformations we perform on a primitive are not in general commutative. Show this using rotation and translation. Write two display functions named displayRT and displayTR for the same. Consider a triangle with coordinates at (50.0, 25.0), (150.0, 25.0) and (100.0, 100.0). Render the triangle using blue color. Perform translation of (0,100) and then rotate about origin with theta = 18 degrees. Render the triangle in red. Save the display as TR.png. Now in a new display window render the triangle using blue color. Rotate about origin with theta = 18 degrees and then translate by an amount (0,100). Render the transformed triangle in red. Save the display as RT.png .

Submit the files transform2D.cpp, Scale.png, TR.png and RT.png by emailing to sundaresan.raman@pilani.bits-pilani.ac.in with the subject CG-131-Lab2, latest by Saturday 21st September, 8.00 PM. [Your transform2D.cpp must contain the three display functions displayScale, displayRT and displayTR.].