In this project you will implement the midpoint line drawing algorithm to rasterize line segments, as well as a simple method for scan converting triangles. You will also use barycentric coordinates to interpolate colors and use simple anti-aliasing for lines and triangles.
You are given support code for this project that should compile under Linux and Windows. Support code links against PNG and Glut libraries. It reads an input scene file, calls helper functions for each primitive (line or triangle), and brings up an OpenGL window that shows the rendered image. It can also output the resulting image as a PNG file. The input file format is described below, and a number of example input test files is provided.
Modify Rasterizer::RasterizeLine function to implement the midpoint
line rasterization (see section 3.5.1 of the FCG textbook). The
lines should be one pixel wide. At this stage you can ignore the
line colors and render white lines.
Modify Rasterizer::RasterizeTriangle function to implement the
triangle rasterization algorithm from section 3.6.
Add functionality for clipping the lines before scan converting them. The goal is to discard any line segment that lies entirely outside the window, and trim line segments that lie partially outside the window, leaving only parts that are inside the window. This can greatly improve rendering speed for some inputs.
Take into account vertex colors and implement color interpolation as described at the end of section 3.5.2.
Use barycentric coordinates to interpolate vertex colors within the triangle as described in section 3.6.
In the anti-aliased mode you will need to first render into a larger
auxilliary image buffer (of size 3*WIDTH by 3*HEIGHT), and then
post-process the resulting image to downsample it to the original
image buffer. This is a simple method sufficient for our purposes.
For downsampling use the box filter (simply average the colors in
each 3x3 group of pixels). You can modify
Rasterizer::BeginRender and
Rasterizer::EndRender functions to implement these pre-
and post-processing steps.
For lines, render a three-pixel thick line into the auxilliary buffer. You will need to compute new vertex coordinates appropriately. For horizontal and vertical lines, make sure that the anti-aliased result is the same as the one without anti-aliasing.
For triangles, simply adjust the vertex positions and render the triangle into the auxilliary buffer.
When the lighting is on you need to perform the following computation
for each vertex: Assume that the light is positioned very far in the
direction given by a vector L=(1, 1, 1). Normalize vector L and each
vertex normal N, and compute the dot product dot(L,N).
If the dot product is negative assign the resulting vertex color to
be completely black (it faces away from the light). Otherwise assign
the color to be (R*dot(L,N), G*dot(L,N), B*dot(L,N)) where (R,G,B)
is the input vertex color (that is, the color you use when the
lighting is off). Then use the resulting color when rendering
a triangle.
Input files are given in a simple line-based format. Each line specifies a vertex position, a change in rendering mode, or a change in current rendering parameters. At the beginning, the current rendering code is set to default which renders nothing, the current color is white (1.0, 1.0, 1.0), and the current normal is up (0.0, 0.0, 1.0).
Each line starts with a lower-case character followed by zero or more numbers, separated by spaces. The starting character specifies a command. The following commands are defined:
The bottom left pixel is at (0, 0), x-axis goes to the right, and the y-axis goes upwards (this is the OpenGL convention, note the image files like PNG usually have the origin at the top-left corner with y-axis going downwards, the support code handles this during image writing, so that the image you store should look like what you see in a Glut window).
First of all, download the support code archive
Both archives contain the same files, except for the end-of-line formatting.The executable should be called with at least one command-line argument. The first argument specifies the input file name, and the second argument (optional) specifies the output PNG file name. If the second argument is not specified the image is written to output.png. The image file is only saved when 's' is pressed in the glut window.
The following keystrokes are defined in the glut window (you may
map more operations to keys inside KeyboardCallback
function but you should not change the predefined keys below).
The code needs to be linked against png, zlib, and glut libraries, and the compilation requires the corresponding header files. The CAEN Linux setup provides both the libraries and the headers, and no setup is needed (just run make within the proj1 folder). On Windows, we provide the headers in common/include folder and the precompiled libraries in common/lib folder, and Visual Studio project files refer to those (also see the paragraphs below).
The following sequence should work:
download the project archive, unpack it, and run make on it.
Then run the executable with the appropriate scene file from the
data folder. You may try the following commands that pretty much
do these steps:
This should run the application, show its window, save an image
file, and then use gnome image viewer to view it. Once this
works you can start modifying rasterizer.cpp to add your code.
mkdir eecs487f07
cd eecs487f07
wget www.eecs.umich.edu/~guskov/487/p1/code.tar.gz
tar xvzf code.tar.gz
cd code/proj1
make
./proj1 ../data/sample.txt
-- a window should appear, press 's', and then close it.
eog output.png
The project files are for Visual Studio 2003, let Visual Studio 2005 convert it -- it should work fine. You can submit 2003 or 2005 projects.
On CAEN Windows machines, you may need to mount the drive with the project data folder to get a drive letter, and then specify that path in Project Properties/Configuration Properties/Debugging/Working Directory (as well as specifying the scene filename as the command argument).
In order to run the executable on Windows you may need glut DLL installed on your system (this step is NOT needed on CAEN lab machines). This can be done by copying the file common/bin/glut32.dll into a folder that is in your path (something like "C:\Windows\Sys" if you can do that) or into the project folder.
Make sure your code compiles and works on CAEN Linux machines or on CAEN Windows machines. You will need to turn in your source files together with appropriate Makefile (and/or MSVC project files) and a write-up in text format (readme.txt) that discusses:
Copy your code, write-up and any other supporting files
(Makefiles or Visual Studio project files etc) to the following
directory on IFS
/afs/umich.edu/class/eecs487/f07/submit/<uniqname>/p1.
This path is accessible from any machine you've logged into using
your ITCS (umich.edu) password. Report problems to ITCS.
Do not submit any binary files (object, executable, or image) with your project.
The timestamp on your source files and your writeup will indicate the time of submission and if this is past the deadline your submission will be considered late. Therefore, you are allowed multiple 'submissions' as long as you respect the deadline. The submission folders will also be closed for writing right after the deadline.
Test the compilation: Your submission must compile without errors and warnings on CAEN Linux or Windows machines. Mention the platform in your writeup. Code that doesn't compile will be heavily penalized.
Here is a simple scene file with the corresponding image output. See some more examples below.
Note: clipping mode should not affect the image (except perhaps for some rounding of the segment positions on the boundary) -- it should however run much faster for specially designed bad examples that have very long segments off-screen.