Presentation is loading. Please wait.

Presentation is loading. Please wait.

Computer Graphics using OpenGL, 3 rd Edition F. S. Hill, Jr. and S. Kelley Chapter 9.4 – 9.7 Tools for Raster Displays S. M. Lea University of North Carolina.

Similar presentations


Presentation on theme: "Computer Graphics using OpenGL, 3 rd Edition F. S. Hill, Jr. and S. Kelley Chapter 9.4 – 9.7 Tools for Raster Displays S. M. Lea University of North Carolina."— Presentation transcript:

1 Computer Graphics using OpenGL, 3 rd Edition F. S. Hill, Jr. and S. Kelley Chapter 9.4 – 9.7 Tools for Raster Displays S. M. Lea University of North Carolina at Greensboro © 2007, Prentice Hall

2 Bresenham Line Drawing How does the line-drawing routine in OpenGL work? –For a straight line that is neither horizontal nor vertical, we need to calculate which pixels need to be colored to draw the line. –We will look at several possible algorithms. –In all cases, the line is being drawn from (a x, a y ) to (b x, b y )

3 Example

4 Bresenham Line Drawing (2) Brute force approach: –Line has slope m = (b y – a y )/(b x – a x ) which can be calculated once. –Equation for the line: y = m (x – a x ) + a y –Step from a x to b x in steps of size one pixel; for each pixel, calculate round (m (x – a x ) + a y ) and color the resulting pixel. Requires a multiplication, a subtraction, an addition, and a round for each pixel – Expensive! Slow!

5 Bresenham Line Drawing (3) Differential Approach: y = m (x – a x ) + a y means that dy = m*dx, where dx = 1 pixel. –For each step of 1 in x, we add m to the current y value y c and calculate round(y c + m). This still requires a floating addition and a round. It is better than the brute force approach, but still not great in terms of time and calculations.

6 Bresenham Approach Bresenham Approach: Bresenham changed the question: Not "What is the value of y at x+1?", but "Which pixel do we set next?"

7 Bresenham Approach (2) Bresenham's approach uses no floating point arithmetic and no rounding. We will examine the algorithm in detail for the case where 0 < slope < 1 for the line. –We start by defining the extents of the line segment in x and y: W = b x – a x, and H = b y – a y. We have 0 < H < W. (Why?) –The line equation is –W(y-a y ) + H(x – a x ) = 0. (How do we know this?)

8 Bresenham Approach (3) Let F(x, y) = –2 W(y - a y ) + 2 H(x – a x ). The factors of 2 make life simpler later on. We define the midpoint M of pixels U and L as M = (p x +1, p y +1/2).

9 Bresenham Approach (4) We set U if the ideal line falls above M, and L if it falls below. That is, if F (M x, M y ) < 0, we set L (y stays the same); else we set U (y increases by 1). The key now is finding the value of F.

10 Bresenham Approach (5) At M, F = -2W(p y +1/2- a y ) + 2H(p x +1-a x ). Consider how F changes: The M is either M' if we did not increment y in the previous step, or M'' if we did. M' = (p x +2, p y +1/2); M'' = (p x +2, p y +3/2).

11 Bresenham Approach (6) Case 1: if F was negative in the previous step (y was not incremented), then F(p x +2, p y +1/2) = -2W(p y +1/2 – a y ) + 2H(p x +2-a x ). We subtract the value of F from the previous step, F = -2W(p y +1/2-a y ) + 2H(p x +1-a x ), to get the amount of change in F: F(p x +2, p y +1/2) = F(M x,M y ) + 2H.

12 Bresenham Approach (7) Case 2: if F was positive on the previous step (y was incremented), then F(p x +2, p y +3/2) = -2W(p y +3/2 – a y ) + 2H(p x +2-a x ) = F(M x,M y ) – 2(W – H). In either case, F has a constant added to it: 2H if y was not incremented, and -2(W- H) if y was incremented.

13 Bresenham Approach (8) What are the starting values? M = (a x +1, a y +1/2), so F(a x, a y ) = -2W(a y +1/2-a y ) + 2H(a x +1-a x ) = 2H-W initially. Code:

14 Bresenham Approach (9) We have only looked at Bresenham's algorithm for a special case, but small adjustments make it work well in other cases as well. Case a x > b x : see the exercises. –One detail : the code includes F = 0 with F > 0 when y is incremented. –We must ensure, when tracing the line in the other direction, that we include the F = 0 case with the case that causes a decrement in y.

15 Bresenham Approach (10) Lines having slope greater than 1: –Interchange the roles of x and y: step by 1 in y from a y to b y, and use the same test to determine when to increment x. Lines with negative slopes: –Slope between 0 and -1: H automatically has the proper sign. Step in x using the same tests, but decrement the dependent variable rather than increment it. –Slope 1 case).

16 Patterned Lines To draw dotted or dashed lines requires storing the desired line pattern in a sequence of bits (a mask), which stores one full repeat (e.g., 0011111100111111). When drawing the line, the current bit in the mask is retrieved. If the bit is 0, the pixel is not set. If the bit is 1, the pixel is set. The technique can easily be added to Bresenham's algorithm.

17 Patterned Lines (2) For long lines, the pattern is used repeatedly by incrementing cyclically from the end of the pattern back to its beginning. If you want the pattern to be continuous from segment to segment, make the pattern and the pointer into it globally available to Bresenham's algorithm (to make it accessible during successive calls to the algorithm).

18 Patterned Lines: OpenGL Functions glEnable (GL_LINE_STIPPLE) starts patterned drawing. glLineStipple (factor, pattern) draws stippled lines. –Factor is an int which determines the number of times a pattern is repeated. –E.g., a factor of 2 causes each bit in the pattern to be used twice before the next bit is used. Factor can range from 1 to 256.

19 Patterned Lines: OpenGL Functions Pattern is an array of gluByte (binary number: 1 = pixel on, 0 = pixel off). Pattern is specified as a hexadecimal number: each hex digit is converted to four bits. Examples: –0x0000 = 0000000000000000 (all black). –0x0101 = 0000000100000001 (a dotted line) –0x0F0F = 0000111100001111 (dashed line)

20 Patterned Lines: OpenGL Functions –glDisable(GL_LINE_STIPPLE) stops patterned drawing. The figure shows 3 lines, drawn with factors of 1, 2, and 3 respectively.

21 Patterned Lines: Code Fig. 9.27 contains code to draw stippled lines. –glEnable (GL_LINE_STIPPLE); – glLineStipple (1, 0x0F0F); /* dotted */ – drawOneLine (50.0, 125.0, 150.0, 125.0); – glLineStipple (2, 0x0F0F); /* dashed */ – drawOneLine (150.0, 125.0, 250.0, 125.0); – glLineStipple (3, 0x0F0F); /* dash/dot/dash */ – drawOneLine (250.0, 125.0, 350.0, 125.0); – glDisable (GL_LINE_STIPPLE); drawOneLine is defined at the start of the code.

22 Polygon Stippling Enable polygon stippling with glEnable (GL_POLYGON_STIPPLE); Define the stipple pattern using glPolygonStipple (bug); [b], or halftone [c].

23 Polygon Stippling Hexadecimal patterns for bug and for halftone are defined in the text. Code to stipple a polygon (previous figure): glRectf (25.0, 25.0, 125.0, 125.0); //plain white glEnable (GL_POLYGON_STIPPLE); glPolygonStipple (bug); glRectf (125.0, 25.0, 225.0, 125.0); //stippled fly glPolygonStipple (halftone); glRectf (225.0, 25.0, 325.0, 125.0); //halftone rect glDisable (GL_POLYGON_STIPPLE);

24 Defining and Filling Pixel Regions Region: a collection of pixels lying next to one another in some fashion, or being associated by some common property.

25 Defining Regions A pixel-defined region is characterized by the actual pixel colors in a pixmap. –list each pixel coordinate –define as consisting of all pixels having value 77 that are “connected” in some way to pixel (43, 129). –“connected” has to be specified carefully. Either method is tedious and error prone.

26 Defining Regions (2) A symbolic description provides some property that all pixels in region R have. –All pixels closer to a given point (23, 47) than to any of the given points (12, 14), (22, 56), or (35, 45); –All pixels lying within a circle of radius 8 centered at (5, 23); –All pixels inside the polygon with vertices at (32, 56), (120, 546), and (345, 1129), and (80, 87) (a particularly important case).

27 Defining Regions (3) Symbolic regions: –the interior of a polygon (used by OpenGL). –Method1: a region is a collection of rectangles –Method 2: a region is a path that defines its boundary.

28 Rectangle-Defined Regions Region: list of rectangles. The rectangles may be as small as a single pixel or as large as an entire pixmap. The region may have holes, and even isolated blobs.

29 Rectangle-Defined Regions (2) Algorithm: –Start at the top and move down scan line by scan line identifying rectangles. –Whenever the set of runs in a scan line differs from those in the scan line above a new set of rectangles begins. –A run is a group of adjacent pixels of the same color that lie on the same scan line. Called a shape representation. Can describe any set of pixels in a pixmap, including a collection of separate regions.

30 Rectangle-Defined Regions (3) Span coherence: many pixels along a scan line have the same value. Scan line coherence: the pattern of pixels of one scan line tends to be similar to the pattern of pixels on the next scan line below. Region representation is most compact when the region has both span coherence and scan line coherence.

31 Rectangle-Defined Regions (4) To translate a region. Region represented in shape form by 30 pixels in x and 55 pixels in y: simply traverse the list, incrementing all x-values by 30 and all y-values by 55. To Double its size. First translate it so that the first run is at the origin (0,0), then double all values in the data structure. Finally, translate it to the desired position.

32 Path-Defined Regions Region defined by its boundary (a path). Path definitions: –Mathematical formula: e.g., (x - 122) 2 + (y - 36) 2 = 25, a circular path 10 pixels in diameter. –Polyline: sequence of pixel locations (x 1, y 1 ), (x 2, y 2 ),..., (x n, y n ); if closed ((x 1, y 1 ) = (x n, y n )), is a polygon. –Sequence of adjacent pixels (chain code): a starting pixel, say (34, 67), and a sequence of moves from pixel to pixel, such as “go up, go right, go down,...”.

33 Path-Defined Regions (2) Example of chain codes:

34 Path-Defined Regions (5) Storing chain codes: starting pixel, number of steps in path, list of steps

35 Path-Defined Regions (6) Manipulating path-defined regions: –Translate: change the starting pixel. –Scale: repeat each symbol k times (k is the scale factor). –Rotate a path 90° CCW: Four-direction chain code: increment each step code by 1 (mod 4). For the 8-direction use a similar increment in the direction number.

36 Path-Defined Regions (7) Filling a region defined by a chain code is complicated; runs of pixels along scan lines are not easily identified. Need to convert the chain code representation into a “shape table”.

37 Filling Polygon-defined Regions Region to be filled is a polygon P described by a set of pixel addresses, p i = (x i, y i ), for i = 1,..., N, specifying the sequence of P 's vertices. To fill P, we work through the frame buffer scan line by scan line, filling in the appropriate portions of each line. The proper portions are determined by finding the intersections of the scan line, say, y = 3, with all the edges of P.

38 Filling Polygon-defined Regions (2) The runs of pixels that lie between pairs of edges must lie inside P and are filled with the desired color.

39 Pseudocode for Filling Pixels for(each scan line L) { }

40 Example of Filling Scan line y = 3 intersects edges e 2, e 3, e 4, and e 5. The intersection x- values are rounded up or down to integers, and sorted: {1, 2, 7, 9}. Two runs are filled: column 1 to 2 and column 7 to 9.

41 Which Edge Pixels Belong to a Polygon A scene may consist of several polygons, some sharing edges. We want to color each edge pixel once. We need rules to determine what the color should be. Example: all shared edges are color B.

42 Which Edge Pixels Belong to a Polygon (2) A polygon owns its left and bottom edges. So when two polygons abut, the edge belongs to the “right-hand” polygon. This edge is drawn only once, in the right hand polygon’s color. If a shared edge is horizontal it is drawn in the upper polygon’s color.

43 Which Edge Pixels Belong to a Polygon (4) Example of pixel coloring for a polygon: left and bottom are colored, top and right are not.

44 Rounding Intersection Points to Ints We want to compute the first and last pixels in the run, xFirst and xLast. – xFirst is the smallest integer that is greater than or equal to xLeft. – xLast is the largest integer strictly less than xRight.

45 Rounding Intersection Points to Ints (2) Example code: #define eps 0.000001 xFirst = (short)(xLeft + 1 - eps);// on xLeft or the next up xLast = (short)(xRight - eps); // one smaller than xRight for (x = xFirst; x <= xLast; x++) setPixel(x, y);

46 Handling Intersections with Vertex and Edge Points If a scan line intersects a vertex or a horizontal edge, difficulties arise in computing the number of intersections. –Examples: A, or B to C below.

47 Handling Intersections with Vertex and Edge Points (2) Rule: ignore intersections with the upper endpoint of an edge, and ignore horizontal edges in intersection calculations. No intersections occur at A and I, one at B and one at H.

48 Improving Algorithm Performance Build and maintain a simple list to locate intersections rapidly: the Active Edge List (AEL) The AEL capitalizes on edge coherence: –Many edges intersected by scan line y are also intersected by scan line (y + 1); –The x-value of the intersection migrates in uniform increments from scan line to scan line.

49 Improving Algorithm Performance (2) Appropriate runs of pixels along each scan line are filled using the AEL. The AEL contains the x-values of all the edge intersections for the current scan line. The x-values are maintained in sorted order, so the first two x-values define the first run; the next two define the next run; and so on.

50 Improving Algorithm Performance (3) Example: Scan- line y = 50 intersects four edges of the polygon at x = 45, 56.66, 70, and 100 in sorted order. The two spans from 45 to 56, and from 70 to 99, are easily filled.

51 Improving Algorithm Performance (4) A linked list AEL is shown below. It stores intersections in order, plus data used to update the list.

52 Improving Algorithm Performance (5) The list stores for each currently intersected edge –The x-value, x int, of the intersection with the current scan line. –The reciprocal, 1/m, of the edge's slope m. –The y-value y high of the upper endpoint of the edge

53 Improving Algorithm Performance (6) The slope 1/m is used to locate the intersections that scan-line y = 51 (the next scan line above) makes with each edge. If an edge has slope m, then moving up by 1 unit causes the intersection x-value to increase by 1/m. A single addition of x int and 1/m finds the intersection point for the next scan-line above.

54 Updating the Edge List Moving to the next scan-line (y) above can cause changes in the AEL. The new scan line may now lie just above an edge in the AEL. –The y-value of the top endpoint of each edge in the AEL makes this situation easy to identify. – If the new y exceeds this upper value, the edge is deleted from the AEL.

55 Updating the Edge List (2) New edges may be encountered, as y becomes equal to the y-value of the lower endpoint of some edges in the polygon. – New edges are added to the AEL by referring to a separate table. The order of x-values of edge intersections may become reversed if two edges cross (non-simple polygons). –The list of intersections must be resorted if this happens.

56 Updating the Edge List (3) Information about each edge in P is placed in an edge table (ET). The ET provides rapid access to the required information during the AEL's updating. The edge table is fashioned as an array of lists, edgetable[ ], one list for each scan line. The ET is created while traversing the polygon to eliminate horizontal edges and shorten others.

57 Updating the Edge List (4) The list for each scan line contains information about any edge of the polygon that has its lower endpoint at that scan line. Many of the lists in the ET are empty. Each edge contains the y lower, 1/m and x int values, with x int = the x-value of the lower endpoint of the edge.

58 Updating the Edge List (5) Edge Table for the sample polygon:

59 Updating the Edge List (5) For the new current scan line at row y, all edges pointed to by edgetable[y] have been reached and are added to the AEL. All values necessary for the AEL are already properly loaded (x int, 1/m and y lower ). Only a few pointers must be adjusted to insert the new edge records. Before filling pixel runs, the AEL is sorted into ascending x int values to assure proper filling.

60 Skeleton Code for Polygon-Fill AEL = NULL; // AEL is initially empty for (y = 0; y <= maxRow; y++) { if( AEL != NULL) // any edges to process? { }


Download ppt "Computer Graphics using OpenGL, 3 rd Edition F. S. Hill, Jr. and S. Kelley Chapter 9.4 – 9.7 Tools for Raster Displays S. M. Lea University of North Carolina."

Similar presentations


Ads by Google