11#include < iostream>
2+ #include < math.h>
23
34#include " Color.h"
45#include " TGAImage.h"
6+ #include " Vector3.h"
7+ #include " Ray.h"
58
69using namespace std ;
710
11+ double hitSphere (const Vector3& center, double radius, const Ray& r)
12+ {
13+ Vector3 oc = r.GetOrigin () - center;
14+ // quaradic equation
15+ double a = r.GetDirection ().Dot (r.GetDirection ());
16+ double b = oc.Dot (r.GetDirection ()) * 2.0 ;
17+ double c = oc.Dot (oc) - (radius * radius);
18+ double discriminant = (b * b) - (4 * a * c);
19+
20+ if (discriminant < 0 )
21+ {
22+ return -1.0 ;
23+ }
24+ else
25+ {
26+ return (-b - sqrt (discriminant)) / (2.0 * a);
27+ }
28+ }
29+
30+ Color rayColor (const Ray& r) {
31+ double t = hitSphere (Vector3 (0 , 0 , -1 ), 0.5 , r);
32+ if (t > 0.0 )
33+ {
34+ Vector3 normal = (r.At (t) - Vector3 (0 , 0 , -1 )).Unit ();
35+ return Color (normal.X + 1 , normal.Y + 1 , normal.Z + 1 ) * 0.5 ;
36+ }
37+
38+ Vector3 unitDirection = r.GetDirection ().Unit ();
39+ double a = (unitDirection.Y + 1.0 ) * 0.5 ;
40+ return Color (1.0 , 1.0 , 1.0 ) * (1.0 - a) + Color (0.5 , 0.7 , 1.0 ) * a;
41+ }
42+
843int main ()
944{
10- int imageWidth = 256 ;
11- int imageHeight = 256 ;
12-
13- TGAImage image (imageWidth, imageHeight, 4 );
14- for (int y = 0 ; y < imageHeight; y++)
15- {
16- for (int x = 0 ; x < imageWidth; x++)
17- {
18- Color color (double (x) / double (imageWidth - 1 ), double (y) / double (imageHeight - 1 ), 0 );
19- image.SetPixel (x, y, color);
20- }
21- }
22- image.WriteTGAFile (" out.tga" );
45+ // Image
46+ double aspectRatio = 16.0 / 9.0 ;
47+ int imageWidth = 400 ;
48+
49+ // Calc height using aspect ratio and ensure it is at least 1
50+ int imageHeight = double (imageWidth) / aspectRatio;
51+ if (imageHeight < 1 )
52+ {
53+ imageHeight = 1 ;
54+ }
55+
56+ TGAImage image (imageWidth, imageHeight, 4 );
57+
58+ // Camera
59+ double focalLength = 1.0 ;
60+ double viewportHeight = 2.0 ;
61+ double viewportWidth = viewportHeight * (double (imageWidth) / double (imageHeight));
62+ Vector3 cameraCenter = Vector3 (0 , 0 , 0 );
63+
64+ // Calc vectors across the horizonal and down the vertical edges of viewport
65+ Vector3 viewportU = Vector3 (viewportWidth, 0 , 0 );// horizontal
66+ Vector3 viewportV = Vector3 (0 , -viewportHeight, 0 );// vertical
67+
68+ // Calc delta vector for pixels across viewport
69+ Vector3 pixelDeltaU = viewportU / imageWidth;
70+ Vector3 pixelDeltaV = viewportV / imageHeight;
71+
72+ // Calc location of upper left pixel
73+ Vector3 viewportUpperLeft = cameraCenter - Vector3 (0 , 0 , focalLength) - viewportU / 2 - viewportV / 2 ;
74+ Vector3 pixel0Center = viewportUpperLeft + (pixelDeltaU + pixelDeltaV) * 0.5 ;
75+
76+ // Render
77+ for (int y = 0 ; y < imageHeight; y++)
78+ {
79+ // clog << "\x1b[2K";
80+ // clog << "\rScanlines remaining: " << (imageHeight - y) << ' ' << flush;
81+
82+ for (int x = 0 ; x < imageWidth; x++)
83+ {
84+ Vector3 pixelCenter = pixel0Center + (pixelDeltaU * x) + (pixelDeltaV * y);
85+ Vector3 rayDirection = pixelCenter - cameraCenter;
86+ Ray ray = Ray (cameraCenter, rayDirection);
87+
88+ // Color color = Color(double(x) / double(imageWidth - 1), double(y) / double(imageHeight - 1), 0);
89+ Color color = rayColor (ray);
90+
91+
92+ image.SetPixel (x, y, color);
93+ }
94+ }
95+ // clog << "\x1b[2K";
96+ // clog << "\rDone";
97+ image.WriteTGAFile (" out.tga" );
2398}
0 commit comments