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.

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:

Preview of Homework 1.

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:

  1. An SVGParser (in svgparser.h/cpp) reads in the input svg file(s)
  2. It launches a OpenGL Viewer containing a DrawRend (in drawrend.h/cpp) renderer, which enters an infinite loop and waits for input from the mouse and keyboard.
  3. In DrawRend::redraw() function, the high-level drawing work is done by the various SVGElement child classes (in svg.h/cpp), which then pass their low-level point, line, and triangle rasterization data to appropriate methods of a Rasterizer 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.

  1. The SVG object draws all elements in the SVG file via a sequence of calls to their draw() functions.
  2. 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 in RasterizerImp::rasterize_point() in rasterizer.cpp. The position of SVG elements in an SVG file is defined in a local coordinate frame, so Point::draw() transforms the point’s position into screen-space coordinates before passing it to RasterizerImp::rasterize_point().

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).

Sample locations.

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.