WARNING
Content Under Development

See release page for latest official PDF version.

**Chapter 1: Output an image** Whenever you start a renderer, you need a way to see an image. The most straightforward way is to write it to a file. The catch is, there are so many formats and many of those are complex. I always start with a plain text ppm file. Here’s a nice description from Wikipedia: ![Image 1-1: PPM Example](../assets/img01-1.jpg) Let’s make some C++ code to output such a thing: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ #include int main() { int nx = 200; int ny = 100; std::cout << "P3\n" << nx << " " << ny << "\n255\n"; for (int j = ny-1; j >= 0; j--) { for (int i = 0; i < nx; i++) { float r = float(i) / float(nx); float g = float(j) / float(ny); float b = 0.2; int ir = int(255.99*r); int ig = int(255.99*g); int ib = int(255.99*b); std::cout << ir << " " << ig << " " << ib << "\n"; } } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are some things to note in that code: 1. The pixels are written out in rows with pixels left to right. 2. The rows are written out from top to bottom. 3. By convention, each of the red/green/blue components range from 0.0 to 1.0. We will relax that later when we internally use high dynamic range, but before output we will tone map to the zero to one range, so this code won’t change. 4. Red goes from black to fully on from left to right, and green goes from black at the bottom to fully on at the top. Red and green together make yellow so we should expect the upper right corner to be yellow. Opening the output file (in ToyViewer on my mac, but try it in your favorite viewer and google “ppm viewer” if your viewer doesn’t support it) shows: ![Image 1-2](../assets/img01-2.jpg) Hooray! This is the graphics “hello world”. If your image doesn’t look like that, open the output file in a text editor and see what it looks like. It should start something like this: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ P3 200 100 255 0 253 51 1 253 51 2 253 51 3 253 51 4 253 51 5 253 51 6 253 51 7 253 51 8 253 51 9 253 51 10 253 51 11 253 51 12 253 51 13 253 51 14 253 51 15 253 51 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If it doesn’t, then you probably just have some newlines or something similar that is confusing the image reader. If you want to produce more image types than PPM, I am a fan of `stb_image.h` available on github.