CPSC 324: Computer Graphics, Spring 2001
First Programming Assignment
Your first real programming assignment is to improve the simple drawing program, draw1_double.cc. Currently, the only thing that this program can draw is red lines. But it does have a Clear button that removes all lines and an Undo button that removes the most recently added line. Your improved program will offer a choice of drawing lines, rectangles, or filled rectangles. It will also offer a choice of drawing color.
This assignment is due in class on Tuesday, February 20.
You should have buttons for choosing between the three possible types of figures, lines, rects, and filled rects. After the user clicks on one of these buttons, the user can draw multiple figures of the selected type. Your program will need a global variable to keep track of which type of figure is being drawn. Note that the button might show an icon of the associated figure, rather than a word.
Similarly, the user should be able to select a drawing color. You could make this possible, for example, by having a "palette" of little buttons that show all the available colors. The user selects a color by clicking on the button of that color. After a color is selected, all the drawing that user does will be in that color until the user selects a new color. You will need a global variable to keep track of the current drawing color.
In the draw1_double.cc program, information about the lines that have been drawn is stored in four arrays of type float[] named x1, y1, x2, and y2. The two endpoints for the i-th line are (x1[i],y1[i]) and (x2[i],y2[i]). The information in these arrays is enough to completely redraw the picture in the display() function. Since your program will allow various colors and types of figures, you will need to save more information for each figure. Note that the geometry of a rectangle can still be specified by two points, namely points at opposite corners of the rectangle, so you don't need to store additional coordinates. However, you will have to store the type and color of each figure. The type can be stored in an array of int. If you are using a color palette, the color can also be specified as the int that gives the index of the color in the palette. If you implement RGB colors, as described below, you could use three arrays of type float for the red, green, and blue components of the color.
(With all this data floating around, it would really be better to organize it into an array of struct's (or objects), where a struct holds all the data for a given figure. For example, you could define:
struct FigureData { float x1, y1; // coordinates of one point float x2, y2; // coordinates of other point int type; // code for type of figure int colorIndex; // index of color in palette }However, it is not required that you do this. If you would like to be more object-oriented in your programming, you could even use an array of objects, where an object contains information about the figure as well as a method for drawing the figure.)
If you implement the program as described so far, you can get a maximum of 82% (a grade of B-). For a higher grade, add some of the following options, or other options that you think up on your own:
- Redo. Add a "redo" button. Items that are "undone" are kept in the data structure, but not drawn, so you can "redo" them. You have to keep track of how many items are available to be redone. Anytime a new item is drawn, any redo-able items are lost permanently.
- Visual Feedback for Selections. When the user selects the rectangle, filled rectangle, or line tool, hilite the button in some way -- such as by drawing a white border around it -- so the user can see what tool is selected.
- Draw Squares. In the original draw1_double, a line is constrained to be vertical or horizontal if the user holds down the shift key while clicking the mouse. For rectangles, you could constrain the shape to be a square if the user holds down shift.
- Draw from Center. It can be convenient to start drawing a line or rectangle from the center point of the figure that you want to produce. As you move the mouse, the figure extends in both directions from the starting point. Use this drawing mode when the user holds down the Control key while clicking the mouse.
- RGB Color Choice. Instead of just having a palette with a fixed selection of colors, make it possible for the user to set the levels of red, blue, and green individually by manipulating widgets of some sort.
- Wide lines. Let the user select the width to be used for lines and outlines of rectangles. You could have buttons for each available width, for example. You might also allow dotted and dashed lines.
- Visual Feedback for Buttons. When you press the mouse on a button, it really should change appearance. It should change back when the button is released. Ideally, it should also change back to its original appearance if the mouse is moved outside the button while it is pressed, and if the user releases the mouse while outside the button, then the button's action is not triggered.
- Object editing. Have an "Edit" tool. If this tool is selected, the user can edit objects. For example, the user might be able to drag objects into new positions or resize them. Alternatively, instead of using a tool, use the right mouse button for editing.
- Freehand Sketch Tool. Add a tool that draws a curve when the user clicks and drags the mouse. This tool differs from the others because you have to store a possibly long sequence of points. It will be easiest to do if you are using an object-oriented approach for the data structures in your program.
- Cursors. Look up GLUT's support for cursors in the GLUT documentation. Use glutSetCursor() to change the appearance of the cursor, depending on which tool is selected and/or where the mouse is located in the window. For example, change the cursor to a pointing hand when the cursor is over a button. (You can use glutPassiveMotionFunc() if you want to track the position of the mouse when no mouse buttons are pressed.)
David Eck, February 5, 2001