最近对图形学比较感兴趣,虽然感觉找不到工作,但是帅,我花点时间学一下,刚好练习一下C++
输出一个图像
ppm
当我们启动一个渲染器时,我们需要一种方式来查看我们的图像。最简单的方式就是将它写入文件中,这里我们使用PPM格式(因为它比较简单)
image.png
这是PPM文件格式在维基中的表现:
第一行是文件描述子 什么P1 P2
P3代表了不同的图像类型,这里我们使用P3——像素图
第二行是像素的宽高 先宽后高
第三行表示每个像素分量的最大值 255 即8位色彩深度
下面是像素的信息,每一行的最后用换行符结尾
图形学的Hello World
我们可以用简单的代码实现一个这样的图片:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <iostream> int main () { int image_width = 256 ; int image_height = 256 ; std::cout << "P3\n" << image_width << " " << image_width << "\n255\n" ; for (int j =0 ;j<image_height;j++){ for (int i=0 ;i<image_width;i++){ auto r = double (i)/(image_width-1 ); auto g = double (j)/(image_height -1 ); auto b = 0.0 ; int ir = int (255.999 *r); int ig = int (255.999 *g); int ib = int (255.999 *b); std::cout << ir << ' ' << ig << ' ' << ib << '\n' ; } } }
我们将输入定向到一个文件中,然后更改后缀名打开
image.png
可以看到我们生成的图片啦
添加一个程序进度指示器
有时候长时间渲染需要进行跟踪,以判断是否陷入死循环中,或者查看渲染进度。
我们可以通过添加日志输出流来实现这个问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> int main () { int image_width = 256 ; int image_height = 256 ; std::cout << "P3\n" << image_width << " " << image_width << "\n255\n" ; for (int j =0 ;j<image_height;j++){ std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; for (int i=0 ;i<image_width;i++){ auto r = double (i)/(image_width-1 ); auto g = double (j)/(image_height -1 ); auto b = 0.0 ; int ir = int (255.999 *r); int ig = int (255.999 *g); int ib = int (255.999 *b); std::cout << ir << ' ' << ig << ' ' << ib << '\n' ; } } std::clog << "\rDone \n" ; }
这样就可以啦