Syllabus Blank 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 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 Appendix. Games and SDL

More Drawing Tools
1. Handy Functions to set World Windows and Viewports

(The code is from your textbook: F.S. Hill, Jr. and Stephen M. Kelley, "Computer Graphics Using OpenGL")

 ```//---------------- setWindow --------------- void setWindow (float left, float right, float bottom, float top) { glMatrixMode (GL_PROJECTION); glLoadIdentity(); gluOrtho2D ((GLdouble)1eft, (GLdouble)right, (GLdouble)bottom, (GLdouble)top); } //---------------- setViewport -------------- void setViewport (int left, int right, int bottom, int top) { glViewport(left, bottom, right - left, top - bottom ); } ```

We may use these functions to automatically set World Window and Viewport

 Aspect ratio of a rectangle = width ----- height
(For diplaying physical objects; width and height measured in same units.)

Suppose world window has aspect ratio R, screen window has width W and height H

2. R > W/H
world window is relatively short and wide, so
setViewport ( 0, W, 0, W/R );

3. R < W/H
world window is relatively tall and narrow, so
setViewport ( 0, H * R, 0, H );
4. We can resize the window by

glutReshapeFunc ( myReshape );

 ``` void myReshape( GLsize W, GLsizei H ) { if ( R > W/H ) //use global aspect ratio R setViewport( 0, W, 0, W/R ); else setViewport( 0, H * R, 0, H ); } ```

5. Developing the Canvas Calss

6. Supporting classes

class Point2: A Point with Real Coordinates
 ```// Support Classes for Canvas class Point2 //single point w/ floating point coordinates { public: Point2(); //contructor 1 Point2(float xx, float yy); //constructor 2 void set(float xx, float yy); float getX(); float getY(); void draw(void); private: float x, y; }; //constructor 1 Point2::Point2() { x = y = 0.0f; } //constructor 2 Point2::Point2(float xx, float yy) { x=xx; y=yy; } void Point2::set(float xx, float yy) { x=xx; y=yy; } float Point2::getX() { return x; } float Point2::getY() { return y; } void Point2::draw(void) { glBegin(GL_POINTS); //draw this point glVertex2f((GLfloat)x, (GLfloat)y); glEnd(); } ```

class RealRect: A rectangle class with real coordinates
 ```//world window rectangle class class RealRect { public: RealRect(); //constructors RealRect(float left, float right, float bottom, float top); void set(float left, float right, float bottom, float top); float getL(void); //left boundary float getR(void); //right float getT(void); float getB(void); void draw(void); //draw this rectangle using OpenGL private: float l, r, b, t; }; //constructors RealRect::RealRect() { l = 0; r=100; b=0; t=100; } RealRect::RealRect(float left, float right, float bottom, float top) { l = left; r=right; b=bottom; t=top; } void RealRect::set(float left, float right, float bottom, float top) { l=left; r=right; b=bottom; t=top; } float RealRect::getL(void) //left boundary { return l; } float RealRect::getR(void) //right { return r; } float RealRect::getT(void) { return t; } float RealRect::getB(void) { return b; } void RealRect::draw(void) { glRectf( l, b, r, t); } ```

7. Class Canvas Interface
 ```class Canvas { public: Canvas(int width, int height, char* windowTitle); //constructor void setWindow(float l, float r, float b, float t); void setViewport(int l, 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); void moveRel(float dx, float dy); private: Point2 CP; //current position in the world IntRect viewport; //the current viewport RealRect window; //the current window } ; ```

8. Class Canvas Implementations
Some member functions implementation of Canvas
 ```//constructor Canvas:: Canvas(int width, int height, char* windowTitle) { char* argv[1]; //dummy argument list for glutinit() char dummyString[8]; argv[0] = dummyString; //hook up the pointer int argc = 1; glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(width, height); glutInitWindowPosition (20,20); glutCreateWindow (windowTitle); 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) } void Canvas:: moveTo(Point2 p) //moves current point CP to point p object { float x1, y1; x1 = p.getX(); y1 = p.getY(); CP.set(x1, y1); } void Canvas:: lineTo(Point2 p) { glBegin (GL_LINES); glVertex2f((GLfloat) CP.getX(), (GLfloat) CP.getY()); glVertex2f((GLfloat) p.getX(), (GLfloat) p.getY()); glEnd(); CP.set(p.getX(), p.getY()); glFlush(); } ```

9. Example of using Class Canvas

main() function
 ```//main.cpp //main loop for canvas graphics #include "canvas.h" void display( void ); void main(void) { extern Canvas cvs; cvs.setWindow(-10.0, 10.0, -10.0, 10.0); cvs.setViewport(0, 500, 0, 500); cvs.setBackgroundColor(1.0, 1.0, 1.0); cvs.setColor(0.0, 0.0, 0.0); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutDisplayFunc(display); glutMainLoop(); } ```

demo_canvas
 ```//demo_canvas.cpp #include "canvas.h" Canvas cvs(640, 480, "try out Canvas"); //global canvas object void display() { cvs.clearScreen(); //clear screen cvs.setColor ( 1.0, 0.0, 0.0 ); cvs.moveTo( 0, 0.0 ); //draw line cvs.lineTo( 5, 5.0 ); cvs.setColor ( 0.0, 1.0, 0.0 ); RealRect box( -1.0, 1.0, -1.0, 2.0 ); //construct a box box.draw(); //draw box glFlush(); } ```

10. Drawing Arcs and Circles using Canvas

• Polygon  ```Canvas cvs(500, 500, "try out Canvas"); //global canvas object void polygon(int n, float cx, 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) + cx, radius * sin(angle) + cy); for(int k=0; k < n; k++) //repeat n times { angle += angleInc; cvs.lineTo(radius * cos(angle) + cx, radius * sin(angle) + cy); } } //polygon ```

• Circle  ```void drawCircle(Point2 center, float radius) { glColor3f(1.0, 0.0, 0.0); //red glLineWidth( 2.0 ); const int numVerts = 50; //many-sided polygon to approximate circle. polygon(numVerts, center.getX(), center.getY(), radius, 0); glPointSize ( 3 ); center.draw(); glFlush(); }//drawCircle ```

• Arc  ``` void drawArc(Point2 center, float radius, float startAngle, float sweep) { // startAngle and sweep are in degrees glColor3f(0.0, 0.0, 1.0); //blue 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 cx = 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)); } ```

• An example of drawing polygon, circle, arc  ```void display(void) { int n = 5; float radius = 3.0; //display at upper right hand quadrant float cx = 4.0, cy = 4.0; cvs.clearScreen(); //draw a polygon polygon( n, cx, cy, radius, 0.0); //center at lower left quadrant Point2 circle_center( -4.0, -4.5 ); drawCircle( circle_center, radius ); //center at lower right quadrant Point2 arc_center( 4.0, -4.5 ); //starts at 30 deg, sweep through 120 degrees drawArc( arc_center, radius, 30, 120 ); } ```

11. Turtle Graphics Revisited

A coding example: drawing a hook

 ```void Canvas::forward ( float dist, int isVisible ) { const float RadPerDeg = 0.017453393; //radians per degree float x = CP.getX() + dist * cos ( RadPerDeg * CD ); float y = CP.getY() + dist * sin ( RadPerDeg * CD ); if ( isVisible ) lineTo( x, y ); else moveTo ( x, y ); }//forward ``` ```//L is length of short side void draw_hook( float L ) { cvs.forward( 3*L, 1 ); cvs.turn( 90 ); cvs.forward( L, 1 ); cvs.turn( 90 ); cvs.forward( L, 1 ); cvs.turn( 90 ); } void display(void) { cvs.clearScreen(); cvs.moveTo(0.0, 0.0); //starts at center cvs.turnTo ( 0.0 ); //points horizontally draw_hook ( 0.5 ); } ```

12. Parametric Form for A Curve

Implicit form
describes a curve by a function F(x, y) that provides a relationship between x- and y- coordinates

F( x, y ) = 0;     ( x, y ) on curve

Examples:

A straight line: F( x, y ) = Ax + By +C

A circle: F( x, y ) = x2 + y2 - R2

F( x, y ) is also called inside-outside function

 F(x, y) = 0 for all ( x, y ) on curve F(x, y) > 0 for all ( x, y ) outside curve F(x, y) < 0 for all ( x, y ) inside curve

Parametric form
produces different points on the curve based on a parameter

x = x(t)
y = y(t)
Example: A straight line:
x(t) = a + bt
y(t) = c + dt

An ellipse ( implicit form: (x/W)2 + (y/H)2 = 1 )

x(t) = W * cos(t)
y(t) = H * sin (t)

A parabola ( implicit form: y2 - 4ax = 0 )

x(t) = at2
y(t) = 2at

A hyperbola ( (x/a)2 - (y/b)2 = 1 )

x(t) = a * sec ( t )
y(t) = b * tan ( t )

 ``` //parabola double a = 8, t, x, y; t = -4; x = a * t * t; y = 2 * a * t; cvs.moveTo ( x, y ); for ( t = -4; t <= 4; t += 0.1 ) { x = a * t * t; y = 2 * a * t; cvs.lineTo ( x, y ); } ```

Polar Coordinate Shapes

Polar coordinates ( r(t), θ(t) )

x(t) = r(t) cos ( θ(t) )
y(t) = r(t) sin ( θ(t) )
In many cases, r may be expressed as a function of θ directly, i.e. r = f ( θ ) x = f(θ) * cos ( θ )
y = f(θ) * sin ( θ )

Examples:

13. Cardioid: f(θ) = K ( 1 + cos ( θ ) )
14. Rose curves: f(θ) = K cos ( nθ )
15. Archimedean spiral: f(θ) = A θ
16. logarithmic spiral: f(θ) = Ke
 ```cvs.setWindow ( -100, 100, -100, 100 ); double K = 0.01, a = 0.35, x, y, f, t; const double pi = 3.14159; t = 0; f = K * exp ( a * t ); x = f * cos ( t ); y = f * sin ( t ); cvs.moveTo ( x, y ); for ( t = 0; t <= 8 * pi; t += 0.1 ) { f = K * exp ( a * t ); x = f * cos ( t ); y = f * sin ( t ); cvs.lineTo ( x, y ); } ```