CS40 Lab 1: OpenGL/C++ Intro

Due 11:59pm Wednesday 4 February 2009
For this lab, you will write some small C++ classes that extend the drawable class to support functionality similar to Zelle's graphics python module. You may use the files geometry.h, geometry.cpp, drawable.h, and test_geometry.cpp as a starting point. Please use cmake and out of source builds to compile and test your code. Source should be saved in your labs/01
Geometric Objects
Your code should support the geometric types shown below with a default constructor. Each class must have a void draw(void) method that draws the object on the current display using the appropriate OpenGL commands. There may be more than one way to draw a particular type of object.

Each class above should inherit from the Drawable base class. Multiple inheritance is supported in C++ if you want a richer class hierarchy, but this is not required.

Each class must have a void setColor(GLfloat red, GLfloat green, GLfloat blue) to change the color of the object. For lines, this color should be used as a line color. For other objects, the color indicates the fill color.

Each class must have a void move(GLfloat dx, GLfloat dy) method that translates the object by an amount dx in the horizontal direction and dy in the vertical direction. In OpenGL, the origin is in the lower left corner.

Each class must have a copy constructor that can create a copy or clone of a given object. The cloned copy should initially have the same geometry and color, but can later be moved independently of the original object. Triangles can only clone other Triangles. It does not make sense to have a copy constructor for Triangles that accept Circles.

Additional geometries (points, polygons, ellipses) may be added, or you can add additional features (line thickness, outline color, etc) if you would like.

Testing
Modify test_geometry.cpp to create some geometric features and render them on the screen (Translation: draw something in 2D). You may use gluOrtho2D to set the region coordinates (see page 36 of the text). All of your objects should be stored in an STL vector<Drawable*> such that drawing the scene can be done by simply looping over the vector and calling the draw() method on each object.

If you program dynamically allocates memory (it probably should) using new, be sure to free the memory by calling delete in the appropriate place.

If a class dynamically allocates memory, be sure to write an appropriate destructor.

If all is working well, you should be able to test your code using

cumin[labs]$ ls
01/  CMakeLists.txt
cumin[labs]$ mkdir build
cumin[labs]$ cd build/
cumin[build]$ cmake ..
cumin[build]$ make
cumin[build]$ cd 01
cumin[01]$ ./test_geometry
Hints
OpenGL does not have a circle primitive, so you will have to approximate a circle as a polygon. It may be helpful to use the following parametric definition of a circle with center xc,yc and radius r:
x=xc+r*cos(t)
y=yc+r*sin(t)
For (axis-aligned) ellipses, instead of one radius, there are two semi-major axes lengths denoted a and b in the horizontal and vertical directions. It is often convenient to specify an ellipse by opposite corners of the rectangle bounding the ellipse. Computing the semi-major axes and the parametric form of an ellipse are left as an optional exercise.
Submit
Once you are satisfied with your programs, hand them in by typing handin40 at the unix prompt. You may run handin40 as many times as you like, and only the most recent submission will be recorded. This is useful if you realize after handing in some programs that you'd like to make a few more changes to them.