Programming assignment #1 - Paint program

CS 248 - Introduction to Computer Graphics
Autumn Quarter, 2008
Marc Levoy
Handout #3

Demos on Wednesday, October 8

Writeups due on Thursday, October 9 by 2:00pm

Your assignment is to write a 24-bit paint program that runs on the provided virtual machine using the user interface package we also provide.

Required functionality

  1. Overpainting brush. Implement a simple rectangular overpainting brush as described in handout #4. Allow slider control over the color and size of your brush. For color control of this brush and the tinting brush below, provide two sets of three sliders, one set that controls R, G, and B, and a second set that controls H, S, and V (using the single-hexcone colorspace described in section 13.3.4 of the textbook). Allow either set to be used to select the brush color, but keep the other set consistent on the display. For size control of this brush and the tinting brush below, use separate sliders for width and height, or for size and aspect ratio. We suggest the latter.

  2. Tinting brush. Implement a weighted mask-driven tinting brush as described in handout #4. Allow slider control over the color and size of your brush, as described above. Regardless of which set of three sliders (RGB or HSV) you use to select the color of your brush, you should perform your tinting calculations in HSV, as defined by option 2 of the section entitled "Simple tinting" in handout #4, and using the single-hexcone space described in section 13.3.4 of the textbook. Using check boxes, allow the user to select which coordinate(s) are affected: H alone, S alone, V alone, H & S, H & V, S & V, or all three. Non-affected coordinates should remain unchanged. (In other words, leave these coordinates as you found them in the canvas.) Think carefully about interpolating hue (H), given the circularity of that axis. Choose any mask function you like that satisfies the conditions listed at the bottom of the section entitled "Weighted mask-driven tinting" in handout #4. Allow slider control over one or more parameters of your falloff function (other than brush size and aspect ratio).

  3. Brush visualizations. Draw 1x (actual size) and 4x (enlarged by 4x in both X and Y) visualizations of the current brush in a second canvas. These visualizations should depict the size, shape, falloff, and color of the brush. The visualizations should be clearly and always visible, regardless of the brush color, the settings of the H, S, and V check boxes, etc. Update the visualizations whenever a related slider is moved. The purpose of these visualizations is to understand the brush shape in its WYSIWYG, spatially discretized glory. Therefore, in the enlarged visualization, one pixel of the actual brush should be displayed as a 4x4 pixel constant-color block; don't interpolate for the sake of the visualization.

Support software

To ease development across platforms, and to keep you from spending long night(s) in a lonely lab, we have built a Linux virtual machine (VM) that comes pre-installed with all the needed libraries and our user interface package. You can install this machine on any Windows PC or Mac, for example your personal laptop. To begin, please follow the setup instructions at

To eliminate X or OpenGL hacking, we provide a software package, xsupport, that displays any number of windows, called canvases, a programmable number of sliders, and several kinds of buttons. You will need at least two canvases, one for your painting and one for your brush shape visualizations. The size of these canvases is programmable. The package is described in the file assignment1/xsupport/README.xsupport. Everything you need to know is contained in this file. We have copied the assignments folder (/afs/ir/class/cs248/assignments) to the virtual machine's desktop. In the folder ~/Desktop/assignments/assignment1 you will find the starter code for the project. While the program uses C++, it contains no fancy templates or inheritance, so if you know C then you'll be fine. You can develop your paint program one with any tools you like, but all your code must run under our VM for the demo.

Some hints and additional requirements

Submission requirements

There are two parts to submitting your paint program: giving a demo on Wednesday, October 8, and submitting an online writeup by 2:00pm on Thursday, October 9.

For the demos, an online signup sheet will be linked from the CS248 webpage a few days before October 8. Sign up for a one-hour slot sometime during which you will be called upon to give a 10 minute demo. The evening slots will be reserved for SITN students. Other students can sign up for these slots only if all other slots are taken. All demos must be given in the graphics teaching lab, which is Gates Hall B08, basement level, where the myth machines are. To keep the demos fair, you must freeze your executable by 7:30am on demo day and give your demo from that executable. To freeze your executable, run the submitAssignment1 script in ~/Desktop/assigments on the VM. You may make multiple submissions until 7:30am, after which time submission will be disabled for the remainder of the day.

Since you will be demoing from the executable you submitted, make sure it is a Linux executable that runs on an unmodified version of the VM. When you arrive for your demo, we will have the executable you submitted running under a copy of the VM, probably on our own laptop. That said, if you installed the VM to a laptop, you might want to bring that laptop with you, in case there's a problem with the files you submitted. (By the way, every year a few people submit source code but no executable. Make sure you submit an executable.) During the demo, we will ask you to load an image of our choosing. Make sure this functionality works in your code, including proper sizing of the canvas array.

Writeups consist of a commented copy of your source code, a Linux executable that runs on an unmodified version of the VM, a Makefile, and a README describing the functionality implemented. Be brief but complete; one screenful is enough. If you did something especially clever, tell us about it. By the way, if we need to do anything more than 'make' to compile your code, please include these instructions in your README file. To make your submission, place all these files in the assignment1 directory (and optionally subdirectories) and once again run submitAssignment1. You may make multiple submissions; we will consider only your latest submission while grading. If all goes well with the submission, pat yourself on the back and start gearing up for the next project. If not, and the submit script reports errors, please email the error messages with a gzipped tarball of your submission directory to

The assignment will be graded on correctness (40 points), efficiency (20 points), programming style, including your writeup (20 points), and the elegance of your user interface (20 points). Note: you are welcome to fix bugs between freezing your executable for the demo and submitting your writeup. However, the functionality, correctness, efficiency, and UI of your program will be graded based only on what you show us during the demo. Only your source code and your README file will be graded from your submitted writeup.

Extra credit

If you have completed the assignment you can earn extra credit by adding bells and whistles. Here are some suggestions. Feel free to make up your own.

  1. Allow interactive manipulation of brush size, shape, and fall-off directly on the visualizations displayed in the second canvas (as an alternative to sliders). Make your interface intuitive.

  2. Implement a software cursor, used only when the mouse is inside the canvas, that is more suitable for painting than the default arrow cursor. A good cursor would be visible over any image, regardless of color, and it would avoid obscuring too much of the area being painted. Segmentation faults are frowned upon, so remember to clip your cursor to the boundaries of the canvas. You can disable the hardware arrow cursor in xsupport by setting the "DisableHardwareCursor" member of the canvas structure to a non-zero value prior to calling LiftOff().

  3. Implement some fancy brushes, such as a filter brush, smear brush, color cycle brush, or rubber-stamp brush with transparency. We'll describe these and others in the help session for this assignment.

  4. Implement painting on textured paper. Provide some kind of user control over the texture. For inspiration, look at Procreate's Painter program.

  5. Implement cloning such as found in Procreate's Painter. A good paper on this technique is Paul Haeberli's `Paint By Numbers: Abstract Image Representations,' Computer Graphics (Proc. Siggraph), Vol. 24, No. 4, August, 1990, pp. 207-214. (We'll give this paper out in class. In addition, a PDF file with the images in color is linked into the course schedule.

  6. Implement a fill algorithm from section 19.5 of the textbook. For more fun, implement a soft-filling algorithm.

  7. Implement unlimited undo / redo, allowing the user to "cancel" / "restore" the effect of any number of brush strokes (from button down to button up). Why unlimited? An artist working rapidly may lay down many brush strokes before realizing that a mistake has been made. Single-stroke undo is seldom sufficient. Some cleverness will be required to avoid excessive memory use or sluggish response.

  8. Record a painting session (multiple brushstrokes), then allow the user to change one or more brush parameters (color, size, shape, etc.), and "replay" the session, yielding a new painting. For extra fun, allow the user to control which brushstrokes are affected by a change. One way to select brushstrokes is to provide slider-controlled playback of the painting session (using your unlimited undo machinery). Another way would be geometrically, using a bounding rectangle or freeform lasso (like Photoshop).

  9. Display in a third canvas the constant H, constant S, and constant V surfaces from a hexcone or other cylindrical colorspace. (You need to implement all three to get credit for this one.) Allow selection of H, S, and V for your brush from any of these three surfaces. When a value is selected from one of the surfaces, update the other two to display the appropriate slices from the hexcone. For extra credit, add an axonometric or perspective projection of the 3D colorspace showing in color the currently selected constant H, S, and V surfaces.
Copyright © 2008 Marc Levoy
Last update: September 30, 2008 03:09:13 PM