Homework Structure
The homework has 6 tasks, worth a total of 100 possible points. Some require only a few lines of code, while others are more substantial.
Task | Name | Points |
---|---|---|
1 | Drawing Single-Color Triangles | 20 |
2 | Antialiasing by Supersampling | 20 |
3 | Transforms | 10 |
4 | Barycentric coordinates | 10 |
5 | “Pixel sampling” for texture mapping | 15 |
6 | “Level sampling” with mipmaps for texture mapping | 25 |
7 | Extra Credit - Draw Something Creative! |
You will also need to reference our Deliverables, specifically to review our write-up rubric.
Getting started
First, accept the assignment GitHub Classroom. Then, clone the generated private repo. Make sure you clone your private repo.
$ git clone <YOUR_PRIVATE_REPO>
Please consult the article that discusses how to build assignments for more information on how to setup and build the assignment.
As you go through the assignment, refer to the write-up guidelines and deliverables section. It is recommended that you complete each section’s write-up as you finish that section. It’s generally not a good idea to wait until the end to start your write-up. You may also find it helpful to skim the rubric before beginning your work.
Important: To avoid compression artifacts in your images, please do not convert the PNG screenshot images saved by the GUI into JPG or other formats! PNG images are losslessly compressed.
Finally, you may find the following resources helpful:
-
C++ Guide for some quick tips and tricks on getting started with C++. A slightly more detailed C++ guide can be found here.
-
Images as Data on how images and colors are often represented in code.
-
Vectors and Matrices in the CGL Library for a quick refresher on declaring and using vectors and matrices.
-
CGL Vectors API for the API listing of CGL Vectors library.
Using the GUI
You can run the executable with the command
./draw [path to svg file/folder to render]
For example, you could run this command:
./draw ../svg/basic/test1.svg
Note: For Visual Studio, the output folder is 3 layers deep. Therefore you should use
./draw ../../../svg/basic/test1.svg
For Linux / Unix / Mac commandline build, it should be 1 layer deep:./draw ../svg/basic/test1.svg
All the IDEs has some form of debug / launch settings. You can use those to specify the SVG file and then you can use the debugger provided by the IDE. Anyways, the path should always be relative to the executable file!
You’ll see a flower composed of blue dots, based on point and line rasterization provided in the starter code. Most other SVG files won’t render correctly until you work through the assignment. Here are the keyboard shortcuts available (some depend on you implementing various parts of the assignment):
Key | Action |
---|---|
space | return to original viewpoint |
- | decrease sample rate |
= | increase sample rate |
Z | toggle the pixel inspector |
P | switch between texture filtering methods on pixels |
L | switch between texture filtering methods on mipmap levels |
S | save a PNG image screenshot in the current directory |
1 - 9 | switch between svg files in the loaded directory |
The argument passed to draw
can either be a single file or a directory containing multiple svg files, as in
./draw ../svg/basic/
If you load a directory with up to 9 files, you can switch between them using the number keys 1-9 on your keyboard.
Finding Generated Screenshots
You can find the screenshots generated from the 'S'
hotkey in
- The build/ folder of the homework repository in Linux/MacOS
- The out\build\x64-Release folder of the homework repository in a Windows laptop
In both cases, your filenames will be listed as screenshot-*.png
, so if you cannot find them, in both cases, you can search for them within your terminal as
find <path-to-homework-directory> -type f -name "screenshot_*.png"
Familiarize Yourself with the Starter Code
Most of your modifications will be constrained to implementing or modifying functions in rasterizer.cpp
, transforms.cpp
and texture.cpp
.
In addition to modifying these, you will need to understand other source and header files as you work through the homework. As one example, the starter code for this and future assignments use the CGL library. For this assignment, you may want to familiarize yourself with classes defined in vector2D.h
, matrix3x3.h
and color.h
.
Here is a brief sketch of what happens when you launch draw
:
- An
SVGParser
(insvgparser.h/cpp
) reads in the input svg file(s) - It launches a OpenGL
Viewer
containing aDrawRend
(indrawrend.h/cpp
) renderer, which enters an infinite loop and waits for input from the mouse and keyboard. - In
DrawRend::redraw()
function, the high-level drawing work is done by the variousSVGElement
child classes (insvg.h/cpp
), which then pass their low-level point, line, and triangle rasterization data to appropriate methods of aRasterizer
class.
A Simple Example: Drawing Points
You are given starter code that already implements drawing of 2D points. To see how this works, begin by taking a look at SVG::draw()
in svg.h
.
- The SVG object draws all elements in the SVG file via a sequence of calls to their
draw()
functions. - Each element type calls an appropriate draw function on a
Rasterizer
object.- In the case of the
Point
element type,Point::draw()
eventually calls the concrete draw function implemented inRasterizerImp::rasterize_point()
inrasterizer.cpp
. The position of SVG elements in an SVG file is defined in a local coordinate frame, soPoint::draw()
transforms the point’s position into screen-space coordinates before passing it toRasterizerImp::rasterize_point()
.
- In the case of the
The function RasterizerImp::rasterize_point()
is responsible for actually drawing the point. In this assignment we define screen space for an output image of size (target_w, target_h)
as follows:
(0, 0)
corresponds to the top-left of the output image(target_w, target_h)
corresponds to the bottom-right of the output image- Please assume that screen sample positions are located at half-integer coordinates in screen space. That is, the top-left sample point is at coordinate (0.5, 0.5), and the bottom-right sample point is at coordinate (target_w-0.5, target_h-0.5).
You may also wish to read Images as Data for more detail on how colors and images are represented as data.
To rasterize points, we adopt the following rule: a point covers at most one screen sample: the closest sample to the point in screen space. This is implemented as follows, assuming (x, y) is the screen-space location of a point.
int sx = (int) floor(x);
int sy = (int) floor(y);
Of course, the code should not attempt to modify the render target buffer at invalid pixel locations.
if ( sx < 0 || sx >= target_w ) return;
if ( sy < 0 || sy >= target_h ) return;
If the points happen to be on screen, we fill in the pixel with the RGB color associated with the point.
rgb_framebuffer_target[3 * (y * width + x)] = (unsigned char)(c.r * 255);
rgb_framebuffer_target[3 * (y * width + x) + 1] = (unsigned char)(c.g * 255);
rgb_framebuffer_target[3 * (y * width + x) + 2] = (unsigned char)(c.b * 255);
(Note: In this assignment, we do not support partial transparency or alpha blending, even though this is part of the SVG file format.)
Write-Up
We recommend working on your write-up for the assignment as you go. Reference our website tips and advice section for information on best practices.
For each task, we’ll include the relevant write-up desired, which is pulled directly from our Homework 1 Deliverables page. When performing your final checks, please compare against the Deliverables page for the full rubric.
As a reminder, you are primarily graded on your write-up submission. Having a public website is a requirement, and can serve as a portfolio for you to show off your amazing graphics work in future years, but will not be utilized while grading, so please make sure to check that your PDF catches all images and updates that you’ve made to your website.