Task 1: Drawing Single-Color Triangles

Relevant lecture: 2

In this task, you will implement the rasterize_triangle function in rasterizer.cpp. Your solution should:

  • Rasterize the triangle by using the sampling methods described in class.
  • For each pixel, please perform the point-in-triangle tests with a sample point in the center of the pixel, not the corner. The coordinates of your sample should be equal to an integer point plus (.5,.5).
  • In Part 2 you will implement sub-pixel supersampling, but here you should just sample once per pixel and call the fill_pixel() helper function. Follow the example in the rasterize_point function in the starter code.
  • To receive full credit, your implementation should assume that a sample on the boundary of the triangle is to be drawn. You are encouraged but not required to implement the OpenGL edge rules for samples lying exactly on an edge. Do make sure that none of your edges are left un-rasterized.
  • Your implementation should be at least as efficient as sampling only within the bounding box of the triangle (not simply every pixel in the framebuffer).
  • Your code should draw the triangle regardless of the winding order of the vertices (i.e. clockwise or counter-clockwise). Check svg/basic/test6.svg.

When finished, you should be able to render test SVG files with single-color polygons, which are triangulated into triangles elsewhere in the code before being passed to your function. Files basic/test3.svg, basic/test4.svg, basic/test5.svg, and basic/test6.svg should render correctly.

For convenience, here is a list of functions you will need to modify:

  1. RasterizerImp::rasterize_triangle() function in rasterizer.cpp.

Extra Credit (2 pts): Make your triangle rasterizer super fast (e.g., by factoring redundant arithmetic operations out of loops, minimizing memory access, and not checking every sample in the bounding box). Write about the optimizations you used. Use clock() or std::chrono::high_resolution_clock to get precise timing comparisons between your basic and optimized implementations.

For Your Write-Up: Task 1

  • Walk through how you rasterize triangles in your own words.
  • Explain how your algorithm is no worse than one that checks each sample within the bounding box of the triangle. The bounding box of the triangle is defined as the smallest rectangle that can be drawn whilst ensuring that the entire triangle is within it.
  • Show a png screenshot of basic/test4.svg with the default viewing parameters and with the pixel inspector centered on an interesting part of the scene.
    • As a reminder, your screenshots need to be generated by using the 'S' hotkey, not using your operating systems native screenshotting mechanism. You can refer back to our guide on Using the GUI on how to generate these images, and where to find them once they’re generated.
  • Extra credit: Explain any special optimizations you did beyond simple bounding box triangle rasterization, with a timing comparison table (we suggest using the c++ clock() function around the svg.draw() command in DrawRend::redraw() to compare millisecond timings with your various optimizations off and on).