Syllabus Videos Homework Quizzes Notes Labs Scores Blank

Lecture Notes
Dr. Tong Yu, Sept. 2013
All the materials presented here are adopted from the textbook and the listed references.
 1. Introduction 2. Line Drawing 3. Drawing Objects 4. More Drawing Tools 5. Vertex Array and Vertex Buffer Object 6. Normal Vectors and Polygonal Models of Surfaces 7. Viewing I -- Affine Transformations
 8. Viewing II -- Projections 9. Color 10. Lighting 11. Blending, antialiasing, fog .. 12. Display Lists, Bitmaps and Images 13. Texture Mapping 13. OpenGL Shading Language ( GLSL ) Videos

Line Drawing
1. Bresenham's Line Algorithm

2. Assume: y = mx + b

3. Given two endpoints ( x0, y0 ), ( xn, yn ) we can choose the start point ( xk, yk )
4. We want to decide what's the next pixel to draw; we have eight choices. ( Why? )
5. Assume 0 ≤ m ≤ 1 and x0 < xn
• Our choices are either ( xk + 1, yk ) or ( xk + 1, yk + 1 )

• Let  dlower = y - yk = m ( xk + 1 ) + b - yk
and  dupper = ( yk + 1 ) - y = yk + 1 - m ( xk + 1 ) - b
• To determine which one is closer to the line path:  dlower - dupper = 2m ( xk + 1 ) - 2 yk + 2b - 1

Let m = ( yn - y0 ) / ( xn - x0 ) = Δy / Δx

Define the decision parameter as

 pk = Δx ( dlower - dupper )         (pk negative, choose lower; pk positive, choose upper) = 2Δy.xk - 2Δx.yk + c     ----- ( 1 )
where c = 2Δy + Δx ( 2b - 1 ) is a constant ( independent of pixel position )

Therefore,

pk+1 - pk = 2Δy ( xk+1 - xk ) - 2Δx ( yk+1 - yk ) But, xk+1 = xk + 1 So, pk+1 = pk + 2Δy - 2Δx ( yk+1 - yk )     ---- ( 2 ) with p0 = 2Δy - Δx

In ( 2 ) , yk+1 - yk is either 0 or 1, depending on the sign of pk. From ( 1 ), as Δx >0, if the pixel at yk is closer to the line path than at yk + 1 (i.e. dlower < dupper ), pk is negative and we choose the next pixel to be the lower pixel; otherwise we choose the upper pixel.

 Brensenham's Line Drawing algorithm for |m| < 1 Input two endpoints ( x0, y0 ), ( xn, yn ) where ( x0, y0 ) is the left endpoint. Plot ( x0, y0 ) as first point. Calculate Δx, Δy and p0 = 2Δy - Δx Start with k = 0, perform the test: If pk < 0, the next point to plot is ( xk +1, yk ) and pk+1 = pk + 2 Δy otherwise, the next point to plot is ( xk +1, yk + 1) and pk+1 = pk + 2 Δy - 2 Δx Perform step 4     Δx - 1 times.

6. Sample Implementation:
 ```//bline.cpp : Bresenham Line algorithm, works only for |m| < 1 #include #include #include void init(void) { glClearColor(1.0,1.0,1.0,0.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,400.0,0.0,400.0); } void setPixel(GLint x,GLint y) { glBegin(GL_POINTS); glVertex2i(x,y); glEnd(); } void line() { int x0 = 50, y0=50, xn = 300, yn = 150, x, y; int dx, dy, //deltas pk, //decision parameter k; //looping variable glClear(GL_COLOR_BUFFER_BIT); glColor3f( 1 ,0, 0); setPixel(x0, y0); //plot first point // difference between starting and ending points dx = xn - x0; dy = yn - y0; pk = 2 * dy - dx; x = x0; y = y0; for ( k = 0; k < dx-1; ++k ) { if ( pk < 0 ) { pk = pk + 2 * dy; //calculate next pk //next pixel: (x+1, y ) } else { //next pixel: (x+1, y+1) pk = pk + 2*dy - 2*dx; //calculate next pk ++y; } ++x; setPixel( x, y ); } glFlush(); } int main(int argc,char **argv){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(0,0); glutInitWindowSize(500,500); glutCreateWindow("Bresenham Line"); init(); glutDisplayFunc( line ); glutMainLoop(); return 0; } ```
7. Bresenham's Circle Algorithm

8. Only has to consider one eigth of a circle, other parts being symmetric.
9. x2 + y2 = r2

10. Compute the relative error for each of the possible choices ( xk+1, yk ) and ( xk+1, yk - 1 )

11. Error for P1:

 E1(k) = [yk2 - y2] = yk2 + ( xk + 1 )2 - r2

12. Error for P2:

 E2(k) = y2 - (yk - 1)2 = r2 - ( xk + 1 )2 - (yk - 1)2

13. Consider

 dk = ( E1(k) - E2(k) ) / 2 = yk2 + xk2 + 2xk - yk + c
where c = 3/2 - r2 is a constant.

14. If dk < 0 ( i.e. P1 nearer to curve ), pick P1 as next pixel:
yk+1 = yk, and  dk+1 = yk2 + (xk + 1)2 + 2( xk + 1 ) - yk + c = yk2 + xk 2 + 2xk + 1 + 2xk + 2 - yk + c = dk + 2xk + 3

15. If dk > 0 ( i.e. P2 nearer to curve ), pick P2 as next pixel:
yk+1 = yk - 1, and  dk+1 = (yk - 1) 2 + (xk + 1)2 + 2( xk + 1 ) - (yk-1) + c = yk2 - 2yk + 1 + xk2 + 2xk + 1 + 2xk + 2 - (yk-1) + c = dk + 2 (xk - yk) + 5

16. The initial point is ( 0, r ), so we can set d0 = r2 + 02 + 2x0 - r + c = 3/2 - r

17. Sample Implementation:
 ```//bcircle.cpp : Bresenham Circle algorithm #include #include #include void init(void) { glClearColor(1.0,1.0,1.0,0.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,200.0); } void setPixel(GLint x,GLint y) { glBegin(GL_POINTS); glVertex2i(x,y); glEnd(); } void Circle(){ int xCenter=100,yCenter=100,r=50; int x=0,y=r; int d = 3/2 - r; // = 1 - r glClear(GL_COLOR_BUFFER_BIT); glColor3f( 1 ,0, 0); while(x<=y){ setPixel(xCenter+x,yCenter+y); setPixel(xCenter+y,yCenter+x); //find other points by symmetry setPixel(xCenter-x,yCenter+y); setPixel(xCenter+y,yCenter-x); setPixel(xCenter-x,yCenter-y); setPixel(xCenter-y,yCenter-x); setPixel(xCenter+x,yCenter-y); setPixel(xCenter-y,yCenter+x); if (d<0) d += (2*x)+3; else { d += (2*(x-y))+5; y -= 1; } x++; } glFlush(); } int main(int argc,char **argv){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(0,0); glutInitWindowSize(500,500); glutCreateWindow("Bresenham Circle"); init(); glutDisplayFunc(Circle); glutMainLoop(); return 0; } ```
18. Plotting Functions

Suppose we wish to learn the behavior of some mathematical functions f(x) as x varies. For example, how does

f(x) = e-|x| cos ( 2π x ) behave when x varies between 0 and 4? We may plot the function using a code like:
 ```for ( double x = 0; x < 4.0; x += 0.005 ) surf.lineTo ( (int) x, (int) f(x) ); ```

Problem!! What ?
19. The picture produced will be very tiny, because the total span of x is between 0 and 4, covering only four pixels of the screen
20. Therefore, we need to scale and position the values to be plotted so that they cover the screen window appropriately
21. Scaling x
sx = x * VWIDTH / 4.0;
sx = 0, when x = 0; sx = VWIDTH, when x = 4.0
22. Scaling and translating y
In the example, -1 ≤ y ≤ 1; we want sy = 0, when y = 1, and sy = VHEIGHT, when y = -1; so we set
sy = ( -y + 1 ) * VHEIGHT / 2.0;
23. The scaling and translation can be expressed in the form
sx = a * x + c
sy = b * y + d
or in matrix form
 sx sy 1 = a   0   c 0   b   d 0   0   1 x y 1
In our example a = VWIDTH / 4.0, c = 0; b = -VHEIGHT / 2.0, d = VHEIGHT / 2.0