|
EECS 487 PA1: RasterizationThis assignment is due on Saturday, Oct. 3rd, 2015 at 12 noon.We can help debug until Thu, 10/1, 7 pm. OverviewReview the grading policy page on the course website. Remember that to incorporate publicly available code in your solution is considered cheating in this course. To pass off the implementation of an algorithm as that of another is also considered cheating. For example, if the assignment asks you to implement sort using heap sort and you turn in a working program that uses insertion sort in place of the heap sort, it will be considered cheating. If you can not implement a required algorithm, you must inform the teaching staff when turning in your assignment by documenting it in your writeup. In this assignment you will implement the midpoint line drawing algorithm to rasterize line segments, scan conversion of triangles, line clipping and line anti-aliasing. You will use barycentric coordinates to interpolate colors and provide anti-aliasing for lines and triangles. Graded Tasks (100 points total)
Support Code: VcanvasDownload and extract the support code gzipped tarball. The support code should compile under Linux, Mac OS X, and Windows. We provide a Makefile to build the application on the command line. We do not provide any IDE (Eclipse, Visual Studio, or XCode) project files. If you're going to use an IDE, please take a look at the Makefile to find out which source files, header files, and libraries must be included in your project. For this assignment, the Makefile builds two applications. The first one, called vcanvas, depends only on the files vcanvas.cpp, rasterizer.cpp, rasterizer.h, and xvec.h. The second one, called draw, requires all the .cpp and .h files provided, except vcanvas.cpp. To use an IDE you must create two separate projects, one to build vcanvas, the other to build draw. If you include both draw.cpp and vcanvas.cpp in either project, your IDE will complain and you won't be able to build either program. It may also be helpful to read the details on setting up IDE projects in the Building OpenGL/GLUT Programs course note. Once you've built vcanvas and run it, you should see a window similar to the one from Labs 1 and 2. The program displays a coarse grid of virtual pixels and allows you to draw one line or one triangle at a time. Two clicks on different virtual pixels give you a line. A third click on a pixel different from the first two gives you a triangle. The program is very simple and doesn't check for degenerate, e.g., colinear, triangles. Either of the following actions clears the grid, ready for another line or triangle to be drawn:
Your TasksSearch The vector class
1. Midpoint Algorithm for Line SegmentsThe assignment uses two graphical primitives. The first is the line.
In void Line::drawInRect(XVec4i& clipWin);
The argument clipWin is described in the
Line Clipping section below.
The lines drawn should be 1-pixel thick, that means every row
(or every column, or both) contains at most one pixel.
You can draw a solid red line first to test your line drawing code.
You may, and are expected to, simply adapt your Lab1 code for this
task (which is why it is not worth that many points).
Once your line drawing code is correctly implemented, incorporate color
interpolation across the line using the parametric equation of a line segment;
do not forget to interpolate the alpha values also.
To set pixels use the function:
void drawPoint(XVec2f& p, XVec4f& color);
To test your line drawing code, build and run the vcanvas application.
Click in the virtual canvas to set the first end point of the line.
Then move the mouse and click on another virtual pixel to set the second
end point, release the mouse button and click again (double click) on the
same virtual pixel to draw a line. Moving the mouse before that third
click produces a triangle.
2. Triangle rasterizationThe second graphical primitive is the triangle.
In bool Triangle::containsPoint(XVec2f& p, XVec4f& pointColor);
It returns a boolean denoting whether the point p is
within the triangle; if it is, the function returns true
and sets pointColor to be the interpolated color of the
vertices' colors, using barycentric coordinates. You may, and are
expected to, adapt your Lab2 code for this task. To test your
triangle drawing code, you may want to return only the color blue
initially. Once your triangle drawing code is correctly implemented,
incorporate color interpolation using barycentric coordinates; again,
do not forget to interpolate the alpha values.
Next implement the function: void Triangle::drawInRect(XVec4f& clipWin);
It should draw a triangle using scan conversion; be sure to have it
use the function containsPoint() above! Build and run
the vcanvas application to test your triangle rasterization code.
3. Line ClippingThe argument drawInRect()
function before drawing. When clipping, do not modify the vertices
of the given line segment, instead use local variables to store the
clipped endpoints. If you have written your line rasterization code
above to use the vertices of the given line segment, you would need
to modify it to use the clipped endpoints instead. When a line is clipped,
its color interpolation must be clipped accordingly. For example, if
one vertex is red and the other is green and the line is clipped
three quarters of the way towards green, the clipped line should
show only gradations of green.
Note: the triangle clipping provided in draw.cpp is a brute
force rejection test of every pixel. Do not use the brute
force method for your line clipping. You are required to
implement both the Cohen-Sutherland and the Cyrus-Beck algorithm. Use
Cohen-Sutherland to trivially accept/reject a line. Then clip those
lines that Cohen-Sutherland cannot trivially accept/reject using the
Cyrus-Beck algorithm. If you cannot implement either algorithm, you
must say so in your writeup. To pass off another algorithm as the one
required is considered cheating.
To test your line clipping code, first draw a clipping window by
pressing 'c ', then draw a line with one or both end points outside the
clipping window. Pressing 'c ' repeatedly toggles the clipping window
on and off. The clipping window is of fixed size and location. The
lower left corner of the clipping window is currently set at (4,4) in
virtual pixel coordinates (controlled by macros CMINX and
CMINY in vcanvas.cpp). The size of the clipping
window is (screen_width/2, screen_height/2). Note that a
virtual pixel at coordinate (x, y) is centered at (x+0.5,
y+0.5). So when drawing pixels be aware when you need to use
rintf(), floorf(), or ceilf() to convert
from float to int. When clipping is on,
portion(s) of the displayed line outside the clipping window is shown
in shades of grey and the portion inside the clipping window is shown
in color. Your clipping code should not change the rasterization of a
line (which pixels are turned on to draw the line). However, due to
precision error, you may find some pixels inside the clipping window
near its boundaries to be grayed out. This is ok.
What to Test
Here are some of the cases we will test for:
4. Anti-Aliasing Lines with Area-samplingThe Line object has a member variable denoting whether it should be drawn anti-aliased. If this variable is set to true, draw your line anti-aliased using an area-sampling based algorithm briefly described as follows. Considering only lines with slope Press the ' 5. Anti-Aliasing Triangles with Multi-samplingThe Triangle object has a member variable denoting whether it should be drawn anti-aliased. If this variable is set, draw the triangle anti-aliased using multi-sampling with at least four samples. That is, for every pixel, compute and average the colors of at least four subpixels. Recall that we differentiate multi-sampling from super-sampling. Whereas super-sampling draws into a large buffer and then average down and re-draw to a smaller buffer, multi-sampling averages the color of multiple sub-pixels of a pixel in a single buffer. It does not use multiple buffers of different sizes. You can treat a given pair of pixel coordinates as specifying the lower left corner of the unit area covered by a pixel. Press the ' 6. Creative SceneDraw an interesting scene using the provided drawing application (described in the next section). Do not simply throw down 42 triangles and call it a Picasso. Put some time into it and play! Try to convey lighting or make a happy clown. Graphics is part programming, part math, and part art, so use your imagination! See samples from previous terms in the Image Gallery. Before having fun with this part, read the following section on how to use the drawing application.Draw ApplicationThe support code comes with a simple drawing application that utilizes your rasterizer. To build the drawing program, type "make draw" and run the draw executable binary file. You should see the application running and showing its window. By default, the application is set up to use your sofware renderer. Until you have your software renderer implemented, you would want to toggle the application to use the hardware renderer, as described below, to see how it is supposed to behave.How to UseIt is highly recommended that you skim through the code to understand how this application works (it actually has a lot less code than you might imagine). The application provides two panels, the canvas on the left, the picker on the right. The picker is fixed size and contains a few "sliders" and "buttons"---even if it ducks back to a 1980s UI (such is life with GLUT). To draw a triangle in the canvas, click on the canvas with the left mouse button and do not release. Drag the mouse and then release. This sets the first two vertices of the triangle. Then move the mouse and watch a triangle grow. Click again to set the third vertex to complete the triangle. Repeat to create multiple triangles. To draw a line, do not move the mouse after specifying the second vertex, instead click it at the same location one more time.Clicking on an existing triangle selects it. Selection of triangles
uses the function
The application does not feature undo/redo nor cut/copy/paste. When the grid is on, it is visible; when snapping is on a magnet is shown in the upper left corner; whether rendering is currently done in hardware or software is displayed in the lower right corner. Play, fidget, and have fun! WARNING: The program reads and writes a simple file format. Modify the files created at your own peril. Final ThoughtsAfter completing this project take a moment to understand why hardware and software rendering differ so greatly in speed. Think about how the graphical components on screen interact; this is UI stuff but still heavily graphics-related. Imagine some simple additions to the application and how they may be accomplished. Hopefully those who use Photoshop or Gimp now appreciate their true power.Submission RequirementsTest your compilation! Your submission must compile without errors and warnings (on Visual Studio, warnings of "PBO file not found" is ok). Code that does not compile will be heavily penalized. Create a writeup in text format that discusses:
% cd <to where your image.tga file is located> % /afs/umich.edu/class/eecs487/scripts/postimg <image.tga> [<image2.tga ...>] writeup-uniqname.txt ,
rasterizer.cpp , and, if modified, rasterizer.h .
Your code must not require other external libraries
or include files other than the ones listed in the Makefile.
To turn in your PA1, upload a zipped or gzipped tarball of your
PA1 files to the CTools Drop Box.
Keep your own backup copy!
The timestamp on your uploaded file will be your time of submission.
If this is past the deadline, your submission will be considered late.
You are allowed multiple "submissions" without late-policy implications
as long as you respect the deadline.
Turn in ONLY the files you have modified.
Do not turn in support code we provided that you haven't modified.
Your code must not require other external libraries or include files
other than the ones listed in the Makefile.
For this assignment, you should turn in only your
writeup-uniqname.txt , rasterizer.cpp , and,
if modified, rasterizer.h .
Do not turn in any binary files (object, executable, or image)
with your assignment. Post your image(s) to the course's Image
Gallery using the postimg script as explained above.
Do remove all printf()'s or cout's and cerr's you've added for debugging purposes. GeneralIt is part of the Honor Code of this course that the overall design and final details and implementation of your programming assignments must be your own. If you're stuck in either the design, implementation, or debugging of the assignment, you're allowed and encouraged to consult with your classmates. However, the original design and final implementation details must all be your own. So you cannot come up with the original design together with your classmates. You can consult your classmates only after you've come up with your own design but ran into some specific problems. Similarly for the implementation, you cannot consult your classmates prior to writing your own implementation. And in all cases, you're not allowed to look at any of your classmates' source code, not even in order to help them to debug. The same applies to design and implementation from previous terms.Coding style
Empirical efficiencyWe will check for empirical efficiency both by measuring the memory usage and running time of your code and by reading the code. We will focus on whether you use unnecessary temporary variables, whether you copy data when a simply reference to it will do, whether you use an O(n) algorithm or an O(n^2) algorithm, but not whether you useprintf 's or fprintf 's or cout .
Nor whether your ADTs
have the cleanest interfaces. In general, if the tradeoff is between
illegible and fast code vs. pleasant to read code that is unnoticeably
less efficient, we will prefer the latter. (Of course pleasant to read
code that is also efficient would be best.) However, take heed what you
put in your code. You should be able to account for every class, method,
function, statement, down to every character you put in your code.
Why is it there? Is it necessary to be there? Can you do without?
Perfection is reached not when there is nothing more to add, but when
there is nothing more that can be taken away, someone once said.
Okay, that may be a bit extreme, but do try to mind how you express
yourself in code.
Hints and advice
Testing Your CodeWe will be grading for correctness primarily by running your program on a number of test cases. If you have a single silly bug that causes most of the test cases to fail, you will get a very low score on that part of the programming assignment even though you completed 95% of the work. Most of your grade will come from correctness testing. Therefore, it is imperative that you test your code thoroughly. Each testcase should test only one particular feature of your program. If any part of this document is unclear, ambiguous, contradictory, or just plain wrong, please let one of the teaching staff know. Have fun coding! |