CS488 2D Graphics - evl2D Graphics Luc RENAMBOT 1 Topics • Last time, hardware and frame buffer...

Preview:

Citation preview

CS4882D Graphics

Luc RENAMBOT

1

Topics

• Last time, hardware and frame buffer

• Now, how lines and polygons are drawn in the frame buffer.

• Then, how 2D and 3D models drawing into the frame buffer

• Then, more realistic 2D and 3D models

2

Mathematics vs. Engineering

• We like to think about a scene as mathematical primitives in a world-space

• This scene is then rendered into the frame buffer. Logical separation of the world from the view of that world

• Points are infinitely small

• Line segments are infinitely thin

• Elements converted into discrete pixels

• an obvious easy

• efficient way

3

Scan Conversion of a line

• Process called ‘rasterization’

• Take an analytic (continuous) function and convert (digitize) it

• OpenGL example in world-space:

• glBegin(GL_LINE_STRIP);

• glVertex2f(1.5, 3.0);

• glVertex2f(4.0, 4.0);

• glEnd();4

Polygons

• OpenGL polygons are very restricted to improve speed

• Edges can not intersect (simple polygons)

• Polygon must be convex, not concave

5

Outline or Filled triangle

• Outline

• glBegin(GL_LINE_LOOP);

• glVertex2f(1.5, 3.0);

• glVertex2f(4.0, 4.0);

• glVertex2f(4.0, 1.0);

• glEnd();

6

• Filled

• glBegin(GL_POLYGON);

• glVertex2f(1.5, 3.0);

• glVertex2f(4.0, 4.0);

• glVertex2f(4.0, 1.0);

• glEnd();

Drawing process

• From world-space into viewport coordinates

• 2D world to 2D frame buffer

• 3D world to 2D frame buffer

• Viewport coordinates used to draw lines and polygons

• Two approaches

• Human-friendly

• Computer-friendly7

Simple algorithm

• Given a line segment from leftmost (Xo,Yo) to rightmost (X1,Y1)

• Y=mX+B

• m = deltaY / deltaX = (Y1 - Yo) / ( X1 - Xo)

8

Start = round(Xo)

Stop = round(X1)

for (Xi = Start; Xi <= Stop; Xi++)

illuminate Xi, round(m * Xi + B);

Problems• Each iteration has:

• Comparison

• Fractional multiplication

• Two additions

• Call to round()

• Addition is OK, fractional multiplication is bad, and a function call is very bad as this is done A LOT

• So we need more complex algorithms which use simpler operations to increase the speed

9

Importance of the Slope

• m=1 then each row and each column have a pixel filled in

• 0 <= m< 1 then each column has a pixel and each row has >= 1, so we increment X each iteration and compute Y

• m > 1 then each row has a pixel and each column has >= 1, so we increment Y each iteration and compute X

10

Simple Incremental Algorithm

• Y=mX+B

• m = deltaY / deltaX = (Y1 - Yo) / ( X1 - Xo)

• if deltaX is 1 then deltaY is m

• so if X(i+1) = X(i) + 1 then Y(i+1) = Y(i) + m

11

Simple Incremental Algorithm

• |m| < 1, Starting at the leftmost edge of the line

X = round(Xo)

Y = Yo

while (X <= X1) repeatedly

illuminate X, round(Y)

add 1 to X (moving one pixel column to the right)

add m to Y

12

Features

• + incremental

• - rounding is a time consuming operation(Y)

• - real variables have limited precision, can cause a cumulative error in long line segments (e.g. 1/3)

• - Y must be a floating point variables

13

Midpoint Line Algorithm• Assuming Xo,X1,Yo,Y1 are integers

• Assuming 0 <= m <= 1, we start at the leftmost edge of the line, and move right one pixel-column at a time illuminating the pixel either in the current row (the pixel to the EAST) or the next higher row (the pixel to the NORTHEAST)

14

Midpoint Line Algorithm• Assuming Xo,X1,Yo,Y1 are integers

• Assuming 0 <= m <= 1, we start at the leftmost edge of the line, and move right one pixel-column at a time illuminating the pixel either in the current row (the pixel to the EAST) or the next higher row (the pixel to the NORTHEAST)

14

Equation rewriting

• Form

• F(X,Y) = ax + by + c = 0

• Y = (deltaY / deltaX) * X + B

• 0 = (deltaY / deltaX) * X - Y + B

• 0 = deltaY * X - deltaX * Y + deltaX * B

• F(X,Y) = deltaY * X - deltaX * Y + deltaX * B

15

Properties

• So for any point (Xi,Yi), we can plug Xi,Yi into the above equation and

• F(Xi,Yi) = 0 then (Xi,Yi) is on the line

• F(Xi,Yi) > 0 then (Xi,Yi) is below the line

• F(Xi,Yi) < 0 then (Xi,Yi) is above the line

16

Algorithm• Given that we have illuminated the pixel at

(Xp,Yp), we will next either illuminate

• the pixel to the EAST (Xp+ 1,Yp)

• or the pixel to the NORTHEAST (Xp+ 1,Yp+ 1)

17

Selection

• Midpoint between the EAST and NORTHEAST pixel and see which side of the midpoint the line falls on

• line above the midpoint ➞ illuminate the NORTHEAST pixel

• line below the midpoint ➞ illuminate the EAST pixel

• line exactly on the midpoint ➞ CHOOSE TO illuminate the EAST pixel

• d = F(Xp+1,Yp+0.5)

18

If EAST

• Midpoint is incremented by 1 in X and 0 in Y

• We want to compute the new d without recomputing d from the new Midpoint

• dcurrent = F(Xp + 1,Yp + 0.5)

• Apply F(X,Y)

• dnew = dcurrent + deltaY

19

If NORTHEAST

• Midpoint is incremented by 1 in X and 1 in Y

• We want to compute the new d without recomputing d from the new Midpoint

• dcurrent= F(Xp + 1,Yp + 0.5)

• Apply F(X,Y)

• dnew = dcurrent + deltaY - deltaX

20

Initial conditions

• Initial point (Xo,Yo) is known

• So initial M is at (Xo + 1, Yo + 0.5)

• Since (Xo,Yo) is on the line -> F(Xo,Yo) = 0

• So initial d = deltaY - deltaX / 2

• Division by 2 is removed by multiplying F(X,Y)

• Since d is only concerned with =0,< 0, or > 0 multiplication does not affect it

21

AlgorithmdeltaX = X1 - Xo

deltaY = Y1 - Yo

d = deltaY * 2 - deltaX

deltaE = deltaY * 2

deltaNE = (deltaY - deltaX) * 2

X = Xo

Y = Yo

illuminate X, Y

while (X < X1) repeatedly

if ( d <= 0)

add deltaE to d

add 1 to X

else

add deltaNE to d

add 1 to X

add 1 to Y

illuminate X, Y

22

The full algorithm is given (in Pascal) in the white book as figure 3.8 on p. 78

Features• + incremental

• + only addition done in each iteration

• + all integer variables

• What if the line segment starts on the right and proceeds to the left?

• with plain lines you could reverse the endpoints and draw the line from left to right as described above. If the line has a pattern this simplification will not work

• What about lines with slope < 0 or slope > 1?

• some modifications needed

23

Filling a Polygon

• Want to avoid drawing pixels twice

• Pixels within the boundary of a polygon belong to the polygon

• Pixels on the left and bottom edges belong to a polygon, but not the pixels on the top and right edges

• Want a polygon filling routine that handles convex, concave, intersecting polygons and polygons with interior holes

24

Overall idea

• Moving from bottom to top up the polygon

• Starting at a left edge, fill pixels in spans until you come to a right edge

25

Algorithm• Moving from bottom to top up the polygon

• 1. Find intersections of the current scan line with all edges of polygon

• 2. Sort intersections by increasing x coordinate

• 3. Moving through list of increasing x intersections

• Parity bit = even (0)

• Each intersection inverts the parity bit

• Draw pixels when parity is odd (1)

26

Scan-line algorithm

• As usual there is the straightforward easy way and the convoluted efficient way

• An easy way:

• Given that each line segment can be described using X = Y/m + B

• Each scan line covering the polygon has a unique integer Y value from Ymin to Ymax

• Plugging each of these Y values into the equation gives the corresponding fractional X value

• These values could then be sorted and stored

27

Next time

• More Polygon Filling

• Clipping

28

Recommended