# CS184 AS1: Interactive Polygon Builder

DUE DATE: Friday Jan 28th, 11:00pm

## Aim

You will create an interactive 2D polygon drawing application. It will allow a user to use the mouse to draw a polygon, and write it out to a simplified OBJ file. This assignment aims to accomplish the following:
• Help you to configure your development environment for C++ work.
• Introduce you to OpenGL, C++, OBJ files, coordinate systems and polygons
• Learn the basics of interactive computer graphics

## User Interaction

Your application will allow you to draw a polygon by interactively placing vertices with the mouse. Place points by pressing the left mouse button somewhere in your application, then dragging the temporary vertex and rubber band edge until you are happy with the current edge of the polygon, and release the mouse button. Continue doing this for all the vertices you want to place, and finally close the polygon by clicking the right mouse button. (For Macs, this is equivalent to holding down control and left-clicking).

## Terminology and Conventions

Vertex: The corner of a geometric object, where two or more straight edges connect.
Edge: The straight line between two vertices.
Face: A single polygon
Rubber Banding: Drawing a temporary line between a fixed point and a point being edited to show the position of a future edge.
Coordinates: Position relative to the current coordinate axes. We will use coordinates in the range [-1,+1], and we will place the origin of the coordinate axes at the center of the screen. If there are more coordinates that necessary (for example, drawing 2D in a 3D environment), set all the unnecessary coordinates to 0.
Coordinate System: We use a coordinate system centered at the origin, increasing towards the right and the top of the screen.

## Minimum Specifications

Write a program called `draw` that accomplishes at least the following (and conforms to this user interface):
1. On launch, open a 600px by 600px OpenGL window.
2. Draw a crosshair at the current location of the mouse pointer in the window.
3. On left mouse button DOWN:
• Place a temporary vertex at the current mouse position.
• Move this temporary vertex along with the mouse pointer's movement
• Rubber Banding: If this is not the first vertex placed, draw a line from the previously placed vertex to this temporary one.
4. On left mouse button UP:
• Place a permanent vertex at this position (thus changing the temporary vertex to a permanent one)
• Draw a line from the previous vertex to this new vertex.
5. Always have all the edges between permanent vertices visible as lines.
6. On right mouse button click:
• Close the polygon by drawing a line from the last placed vertex to the first vertex.
• Write out the polygon to polygon.obj in the current directory as an OBJ file. Let the coordinates be in the range [-1, +1] relative to the center of the window. (Thus the vertex at pixel (300,300) maps to (0,0))
• Keep the window open displaying the polygon, but any other action is undefined. Yes, you can crash if the user attempts to add another point, but feel free to do something more elegant such as starting a new polygon (This is a good opportunity to learn memory management in C++).
Read the implementation tips for detailed instructions on accomplishing these things easily.
See an example of the program's interaction in the example implementation applet on the bottom of the page.

Extra Credit Ideas
Berkeley students never fail to impress when given free reigns, so once you've implemented this minimum specification, consider extending this project to do some of the following (ranked approximately in level of difficulty):

• Guides: Temporary horizontal and vertical lines following the cursor.
• Changing color and line width of the polygon
• Drawing multiple polygons, saving each one to a separate .OBJ file
• Changing line style of the polygon (dotted, striped, etc.)
• Snap-To for lines, making it easy to draw horizontal and vertical lines.
Since AS2 will be concerned with modifying an already-created polygon, I suggest you start with AS2 if you want to experiment with that.

## Submission

To submit this project, all of the following needs to be done by the deadline:
• Submit using the submit as1 command on the INST machines:
• A copy of your code, including the whole framework, that compiles on the platform you developed on.
• TWO example OBJ files and accompanying Screen Capture Images of your program displaying the polygons you are submitting. In these screen captures we want to see the actual borders of the window running on your machine, not just a cropped image of the polygon.
• README.txt file describing the platform you compiled your code on and any extra features of your program. This should be one of [Mac, Linux, Solaris, Windows].
• Put on your class website, on a separate page dedicated to AS1:
• The two screen captures of your program's display
• The two OBJ files you generated.
Windows Users: The grader should ONLY have to open your .sln file and press F5 to build and run your solution.
*Nix Users: The grader should ONLY have to run make with the appropriate makefile to build your project. Thus, for Mac and Linux `make` and for solaris `gmake`.

Note: The submit program retains the directory structure of what you send it. Thus, we recommend making a new directory for your assignment on the server, cd'ing into that directory, copying the whole framework with your code into this directory, and running ```yes | submit as1``` to easily submit the whole project to us.

## Framework

Download the framework for all platforms here.

We will be using the same core components throughout this course for all the projects, thus you can start to familiarize yourself with them now. They are:
• OpenGL
• Matrix and Vector library (algebra3.h)
• OBJ parser (not necessary and not included for this project)
• Platform-dependent framework bundle
• C++ Standard Template Library for basic data structures (linked to project through header files)
C++ is a platform-dependent language, thus we will do our best to maintain and release multiple copies of our framework for Windows (Microsoft development environment), Macintosh OSX, Linux and Solaris. If you are having compilation issues, please ask the GSIs! Getting the framework to compile should be very simple, thus ask (preferably in person with the compilation environment available on your laptop).

Our framework, following the layout of most C and C++ based projects, contains:

 `./` `  src/` Contains all the source code for your project. `      main.cpp` Main source code file. `  include/` Contains header files of third party code. `      algebra3.h` Matrix and vector library `  lib/` Contains binary files of third party code. `  makefile` Specifies building instructions in gmake-compatible format

### Coding

Place your source code in the `src` directory, starting with `main.cpp`. You can create more files to organize your source code, even going so far as to follow the Java convention of creating a separate file for each class (in this case `.h` and `.cpp`).

There exists a plethora of tools for C++ authoring. Windows users tend to use the Visual Studio environment, which we recommend (download legally for free here or here). Vim, Emacs and Nedit are all popular text editors used for programming, while Eclipse, Xcode and KDevelop are IDE-based environments that assist greatly in programming.

### Complitation

 Windows You can either install Cygwin and its associated packages (compilers and GLUT) and follow a linux-like approach, or you can download Microsoft Visual Studio (alternative link) to use for development (probably an easier option for windows users). For Visual Studio: Open the .sln file and press F5 to Build Solution. If you are using Visual Studio Express 2005, you should either install the platform sdk (instructions) or (preferably) upgrade to Express 2008 or a full version of Visual Studio for free. Mac OSX You need to install the Xcode developer toolkit from Apple. Register for a free account. From here you can use your favorite editor and compile from the terminal using the same approach as Solaris. Compile with `gmake -f makefile.osx` Linux You need to install gcc (or similar compiler), the standard c++ libraries, and GLUT. On an aptitude-based system (Debian, Ubuntu), you can accomplish this by installing the `build-essential` and `freeglut` package. You can now follow the same instructions as on Solaris. Solaris Assuming you are on one of the instructional machines, you should be able to compile immediately by running `gmake -f makefile`

## Implementation Tips

The Bible of OpenGL programming comes in the form of two books known as the Red Book (The OpenGL Programming Guide) and the Blue Book (The OpenGL Reference Manual). Older editions of this book is available online for free, and luckily not much has changed in the standard of OpenGL.

READ the code given in `main.cpp`! It already contains templates of some incredibly useful OpenGL functions. It demonstrates the basic layout, and how to create classes.

### OpenGL Concepts and Suggested Methods:

You will be using GLUT, an OpenGL windowing system, and basic OpenGL.
• Keyboard and Mouse Capture (using GLUT):
• `glutKeyboardFunc(myKeyboardFunc);`
• `glutMouseFunc(myMouseFunc);`
• 2D Drawing
• `glBegin(int mode)` and `glEnd()` to control drawing.
• `glVertex2f(float x, float y)` to define a vertex. The effect depends on the mode specified in glBegin.

### C++ Concepts in this project

You will find this project quite simple if you use some good C++ organization of your code. You should consider the following suggestions:
• Classes and Objects:
• Consider defining a Polygon class to store the vertices as they are added.
• Consider giving the Polygon class a method to draw itself.
• Consider giving the Polygon class a method to add vertices to itself.
• Consider giving the Polygon a method to write an OBJ file from itself.
• Consider defining a Vertex class to store the vertex data.
• Consider writing accessor functions for the Vertex class' coordinates
• References (or, pointers in disguise):
• Consider keeping a reference to a temporary vertex object, created when the user depressed the left mouse button.
• Consider passing a reference of the temporary vertex object to the polygon object when the user releases the left mouse button, and have the Polygon class deal with adding it to the polygon.
• Event Driven Programming:
Event Driven programming makes the flow of the program depend on events outside of the program's control. OpenGL employs this approach to link your program to OpenGL. You will write functions ("event handlers") that should respond to specific events, and register these functions with, in our case, OpenGL.
• You have to write methods that respond to events from OpenGL. This is already partially in the given framework.
• Consider capturing the mouse events using GLUT (explained in this section).
• Consider having the mouse events update a temporary vertex object and/or the polygon object.
• System Calls:
• Consider using the `ofstream` class for File I/O as demonstrated in this example.
• Libraries:
• Consider using the STL `vector` class to store a list of vertices. Vectors are highly preferred over using arrays!
• Consider using our 2D vector class to store the coordinates of vertices. This will get you up and running with the supplied libraries.

### OBJ Files

This is your first taste of the beautifully simple OBJ file format. OBJ files are ASCII files, with a command per line. you need to be concerned with the following commands for this project:
 `v x y` Define a vertex at coordinates (x,y). It is customary to have coordinates have a range of [-1, +1] in OBJ files. `f v1 ... vn` Define a face with vertices v1 through vn vi refers to the index of a vertex, where vertices are indexed from 1 in the order they appear in the file.
Thus an example OBJ for a rectangle should look something like the following:

``` # OBJ file: v -0.5 0.5 v -0.5 -0.5 v 0.5 -0.5 v 0.5 0.5 f 1 2 3 4 ```
More OBJ File specifications can be found here, various examples here, programs and sample files here and a MAN-page-like reference page by Martin Reddy here

## Example Implementation

Feel free to play with the following Java applet to get an idea of the user interaction we're looking for.

Click with your mouse to add vertices. User Interface follows the project spec.
Left Mouse: Add a new vertex (try dragging the mouse while holding the left button).
Right Mouse: Close the polygon and dump the OBJ file contents.
Note: Your implementation should write the OBJ to disk, NOT display it in the window.