CS40 Lab 2: OpenGL

Due 11:59pm Monday 7 February 2011
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/02 folder
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. Since every object will have a color, you can perhaps implement this in the base Drawable class

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 by default.

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.

Getting Started
Running update40 will give you the starter code. You will need to modify the CMakeLists.txt in your labs folder. Uncomment the lines
find_package(GLUT)
find_package(OpenGL)
and add the line
add_subdirectory(02)

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

cumin[labs]$ ls
01/ 02/  CMakeLists.txt
cumin[labs]$ mkdir build
cumin[labs]$ cd build/
cumin[build]$ cmake ..
cumin[build]$ make
cumin[build]$ cd 02
cumin[02]$ ./test_geometry
Next go back and edit drawable.h, drawable.cpp and test_geometry.cpp to implement and test your features. drawable.h will start to grow as you add additional classes, so reduce clutter by implementing your draw methods inside drawable.cpp. Add one feature at a time and go back and test. Lather, rinse, repeat until all features are implemented.
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. 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.

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.