refactoring, remove rtweekend header
This commit is contained in:
		
							parent
							
								
									5e36789d2a
								
							
						
					
					
						commit
						75e9bac556
					
				@ -1,6 +1,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "rtweekend.h"
 | 
			
		||||
#include "error.h"
 | 
			
		||||
#include "vec3.h"
 | 
			
		||||
 | 
			
		||||
// for writing to stdout
 | 
			
		||||
#include <iostream>
 | 
			
		||||
@ -8,59 +9,21 @@
 | 
			
		||||
// for writing to socket
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
class colour : public vec3
 | 
			
		||||
{
 | 
			
		||||
    using vec3::vec3;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    friend colour operator*(const colour& u, const colour& v);
 | 
			
		||||
    friend colour lerp(const colour& a, const colour& b, double t);
 | 
			
		||||
 | 
			
		||||
    colour correct_gamma(int samples);
 | 
			
		||||
 | 
			
		||||
    friend void write_colour_to_socket(int sockfd, colour pixel_colour, int samples_per_pixel);
 | 
			
		||||
    friend void write_colour_to_stream(std::ostream &out, colour pixel_colour, int samples_per_pixel);
 | 
			
		||||
    friend int format_component(double component);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const colour pink(254.0/255.0, 226.0/255.0, 170.0/255.0);
 | 
			
		||||
const colour grey(0.133, 0.133, 0.133);
 | 
			
		||||
 | 
			
		||||
void correct_gamma(colour& pixel_colour, int samples)
 | 
			
		||||
{
 | 
			
		||||
    double r = pixel_colour.x();
 | 
			
		||||
    double g = pixel_colour.y();
 | 
			
		||||
    double b = pixel_colour.z();
 | 
			
		||||
 | 
			
		||||
    // divide the colour total by the number of samples and gamma-correct for gamma=2.0
 | 
			
		||||
    auto scale = 1.0 / samples;
 | 
			
		||||
    r = sqrt(scale * r);
 | 
			
		||||
    g = sqrt(scale * g);
 | 
			
		||||
    b = sqrt(scale * b);
 | 
			
		||||
 | 
			
		||||
    pixel_colour = colour(r, g, b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int format_component(double component)
 | 
			
		||||
{
 | 
			
		||||
    return int(256 * math::clamp(component, 0.0, 0.999));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void write_colour_to_stream(std::ostream &out, colour pixel_colour, int samples_per_pixel)
 | 
			
		||||
{
 | 
			
		||||
    correct_gamma(pixel_colour, samples_per_pixel);
 | 
			
		||||
 | 
			
		||||
    auto r = pixel_colour.x();
 | 
			
		||||
    auto g = pixel_colour.y();
 | 
			
		||||
    auto b = pixel_colour.z();
 | 
			
		||||
    
 | 
			
		||||
    // write the translated [0,255] value of each colour component.
 | 
			
		||||
    out << format_component(r) << ' '
 | 
			
		||||
        << format_component(g) << ' '
 | 
			
		||||
        << format_component(b) << '\n';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void write_colour_to_socket(int sockfd, colour pixel_colour, int samples_per_pixel)
 | 
			
		||||
{
 | 
			
		||||
    correct_gamma(pixel_colour, samples_per_pixel);
 | 
			
		||||
 | 
			
		||||
    int r = format_component(pixel_colour.x());
 | 
			
		||||
    int g = format_component(pixel_colour.y());
 | 
			
		||||
    int b = format_component(pixel_colour.z());
 | 
			
		||||
 | 
			
		||||
    // pack values
 | 
			
		||||
    int len = 3;
 | 
			
		||||
    char s[len];
 | 
			
		||||
    sprintf(s, "%c%c%c", r, g, b);
 | 
			
		||||
 | 
			
		||||
    int written = write(sockfd, s, len);
 | 
			
		||||
    if (written < 0)
 | 
			
		||||
    {
 | 
			
		||||
        error("ERROR writing colour to socket");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
void error(const char* message)
 | 
			
		||||
{
 | 
			
		||||
    perror(message);
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
void error(const char* message);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										23
									
								
								include/hit_record.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								include/hit_record.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
class material;
 | 
			
		||||
 | 
			
		||||
struct hit_record
 | 
			
		||||
{
 | 
			
		||||
    point3                      p;
 | 
			
		||||
    vec3                        normal;
 | 
			
		||||
    std::shared_ptr<material>   mat_ptr;
 | 
			
		||||
    double                      t;
 | 
			
		||||
    bool                        front_face;
 | 
			
		||||
 | 
			
		||||
    inline void set_face_normal(const ray& r, const vec3& outward_normal)
 | 
			
		||||
    {
 | 
			
		||||
        front_face = dot(r.direction(), outward_normal) < 0;
 | 
			
		||||
        normal = front_face ? outward_normal : -outward_normal;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@ -1,27 +1,10 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "rtweekend.h"
 | 
			
		||||
#include "ray.h"
 | 
			
		||||
 | 
			
		||||
class material;
 | 
			
		||||
 | 
			
		||||
struct hit_record
 | 
			
		||||
{
 | 
			
		||||
    point3                  p;
 | 
			
		||||
    vec3                    normal;
 | 
			
		||||
    shared_ptr<material>    mat_ptr;
 | 
			
		||||
    double                  t;
 | 
			
		||||
    bool                    front_face;
 | 
			
		||||
 | 
			
		||||
    inline void set_face_normal(const ray& r, const vec3& outward_normal)
 | 
			
		||||
    {
 | 
			
		||||
        front_face = dot(r.direction(), outward_normal) < 0;
 | 
			
		||||
        normal = front_face ? outward_normal : -outward_normal;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
#include "hit_record.h"
 | 
			
		||||
 | 
			
		||||
class hittable
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
        virtual bool hit(const ray& r, double tMin, double tMax, hit_record& rec) const = 0;
 | 
			
		||||
public:
 | 
			
		||||
    virtual bool hit(const ray& r, double tMin, double tMax, hit_record& rec) const = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -20,21 +20,3 @@ class hittable_list : public hittable
 | 
			
		||||
        std::vector<std::shared_ptr<hittable>> objects_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const
 | 
			
		||||
{
 | 
			
		||||
    hit_record temp_rec;
 | 
			
		||||
    bool hit_anything = false;
 | 
			
		||||
    auto closest_so_far = t_max;
 | 
			
		||||
 | 
			
		||||
    for (const auto& object : objects_)
 | 
			
		||||
    {
 | 
			
		||||
        if (object->hit(r, t_min, closest_so_far, temp_rec))
 | 
			
		||||
        {
 | 
			
		||||
            hit_anything = true;
 | 
			
		||||
            closest_so_far = temp_rec.t;
 | 
			
		||||
            rec = temp_rec;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return hit_anything;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "rtweekend.h"
 | 
			
		||||
#include "hittable.h"
 | 
			
		||||
#include "hit_record.h"
 | 
			
		||||
 | 
			
		||||
class material
 | 
			
		||||
{
 | 
			
		||||
@ -13,13 +13,6 @@ class material
 | 
			
		||||
            ray& scattered) const = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
double schlick(double cosine, double refraction_index)
 | 
			
		||||
{
 | 
			
		||||
    auto r0 = (1-refraction_index) / (1+refraction_index);
 | 
			
		||||
    r0 = r0*r0;
 | 
			
		||||
    return r0 + (1-r0)*pow(1-cosine, 5);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class lambertian : public material
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
@ -106,4 +99,11 @@ class dielectric : public material
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        double refraction_index_;
 | 
			
		||||
 | 
			
		||||
        double schlick(double cosine, double refraction_index) const
 | 
			
		||||
        {
 | 
			
		||||
            auto r0 = (1-refraction_index) / (1+refraction_index);
 | 
			
		||||
            r0 = r0*r0;
 | 
			
		||||
            return r0 + (1-r0)*pow(1-cosine, 5);
 | 
			
		||||
        }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
// usings
 | 
			
		||||
 | 
			
		||||
using std::shared_ptr;
 | 
			
		||||
using std::make_shared;
 | 
			
		||||
using std::sqrt;
 | 
			
		||||
 | 
			
		||||
// common headers
 | 
			
		||||
 | 
			
		||||
#include "error.h"
 | 
			
		||||
#include "ray.h"
 | 
			
		||||
#include "vec3.h"
 | 
			
		||||
							
								
								
									
										100
									
								
								include/scene.h
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								include/scene.h
									
									
									
									
									
								
							@ -1,100 +0,0 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "math.h"
 | 
			
		||||
#include "sphere.h"
 | 
			
		||||
#include "colour.h"
 | 
			
		||||
#include "material.h"
 | 
			
		||||
#include "hittable.h"
 | 
			
		||||
#include "hittable_list.h"
 | 
			
		||||
 | 
			
		||||
colour ray_colour(const ray& r, const hittable& world, int depth)
 | 
			
		||||
{
 | 
			
		||||
    hit_record rec;
 | 
			
		||||
    if (depth <= 0)
 | 
			
		||||
    {
 | 
			
		||||
        return grey;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (world.hit(r, 0.001, math::infinity, rec))
 | 
			
		||||
    {
 | 
			
		||||
        ray     scattered;
 | 
			
		||||
        colour  attenuation;
 | 
			
		||||
 | 
			
		||||
        if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
 | 
			
		||||
        {
 | 
			
		||||
            return attenuation * ray_colour(scattered, world, depth-1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return grey;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vec3 unit_direction = normalize(r.direction());
 | 
			
		||||
    auto t = 0.5 * (unit_direction.y() + 1.0) + 0.5;
 | 
			
		||||
 | 
			
		||||
    return lerp(grey, pink, t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
hittable_list random_scene()
 | 
			
		||||
{
 | 
			
		||||
    hittable_list world;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //auto ground_material = make_shared<lambertian>(pink);
 | 
			
		||||
    //world.add(make_shared<sphere>(point3(0,-1000,0), 1000, ground_material));
 | 
			
		||||
 | 
			
		||||
    //for (int a = -11; a < 11; a++)
 | 
			
		||||
    //{
 | 
			
		||||
    //    for (int b = -11; b < 11; b++)
 | 
			
		||||
    //    {
 | 
			
		||||
    //        auto choose_mat = random_double();
 | 
			
		||||
    //        point3 centre(a + 0.9*random_double(), 0.2, b + 0.9*random_double());
 | 
			
		||||
 | 
			
		||||
    //        if ((centre - point3(4, 0.2, 0)).length() > 0.9)
 | 
			
		||||
    //        {
 | 
			
		||||
    //            shared_ptr<material> sphere_material;
 | 
			
		||||
 | 
			
		||||
    //            if (choose_mat < 0.8)
 | 
			
		||||
    //            {
 | 
			
		||||
    //                // diffuse
 | 
			
		||||
    //                //auto albedo = colour::random() * colour::random();
 | 
			
		||||
    //                sphere_material = make_shared<lambertian>(pink);
 | 
			
		||||
    //                world.add(make_shared<sphere>(centre, 0.2, sphere_material));
 | 
			
		||||
    //            }
 | 
			
		||||
    //            else if (choose_mat < 0.95)
 | 
			
		||||
    //            {
 | 
			
		||||
    //                // metal
 | 
			
		||||
    //                auto fuzz = random_double(0, 0.5);
 | 
			
		||||
    //                sphere_material = make_shared<metal>(pink, fuzz);
 | 
			
		||||
    //                world.add(make_shared<sphere>(centre, 0.2, sphere_material));
 | 
			
		||||
    //            }
 | 
			
		||||
    //            else
 | 
			
		||||
    //            {
 | 
			
		||||
    //                // glass
 | 
			
		||||
    //                sphere_material = make_shared<dielectric>(1.5);
 | 
			
		||||
    //                world.add(make_shared<sphere>(centre,0.2, sphere_material));
 | 
			
		||||
    //            }
 | 
			
		||||
    //        }
 | 
			
		||||
    //    }
 | 
			
		||||
    //}
 | 
			
		||||
 | 
			
		||||
    auto material1 = make_shared<dielectric>(1.5);
 | 
			
		||||
    world.add(make_shared<sphere>(point3(0, 0, 0), 3.0, material1));
 | 
			
		||||
 | 
			
		||||
    //auto material2 = make_shared<lambertian>(pink);
 | 
			
		||||
    //world.add(make_shared<sphere>(point3(-4, 1, 0), 1.0, material2));
 | 
			
		||||
    
 | 
			
		||||
    auto material3 = make_shared<metal>(pink, 0.5);
 | 
			
		||||
    int sphere_count = 10;
 | 
			
		||||
    for (int i = 0; i < sphere_count; i++)
 | 
			
		||||
    {
 | 
			
		||||
        float a = 6.28 * (float)i/sphere_count - 100.0;
 | 
			
		||||
        float r = 8.0;
 | 
			
		||||
        float x = r*sin(a);
 | 
			
		||||
        float y = 2.0*cos(a);
 | 
			
		||||
        float z = r*cos(a);
 | 
			
		||||
        point3 pos(x,y,z);
 | 
			
		||||
        world.add(make_shared<sphere>(pos, 2.0, material3));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return world;
 | 
			
		||||
}
 | 
			
		||||
@ -7,7 +7,7 @@ class sphere : public hittable
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
        sphere() {}
 | 
			
		||||
        sphere(point3 centre, double r, shared_ptr<material> m) : 
 | 
			
		||||
        sphere(point3 centre, double r, std::shared_ptr<material> m) : 
 | 
			
		||||
            centre_(centre), 
 | 
			
		||||
            radius_(r),
 | 
			
		||||
            mat_ptr_(m)
 | 
			
		||||
@ -16,49 +16,8 @@ class sphere : public hittable
 | 
			
		||||
        virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const;
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        point3                  centre_;
 | 
			
		||||
        double                  radius_;
 | 
			
		||||
        shared_ptr<material>    mat_ptr_;
 | 
			
		||||
        point3                      centre_;
 | 
			
		||||
        double                      radius_;
 | 
			
		||||
        std::shared_ptr<material>   mat_ptr_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const 
 | 
			
		||||
{
 | 
			
		||||
    vec3 oc = r.origin() - centre_;
 | 
			
		||||
    auto a = r.direction().length_squared();
 | 
			
		||||
    auto half_b = dot(oc, r.direction());
 | 
			
		||||
    auto c = oc.length_squared() - radius_*radius_;
 | 
			
		||||
    auto discriminant = half_b*half_b - a*c;
 | 
			
		||||
 | 
			
		||||
    if (discriminant > 0)
 | 
			
		||||
    {
 | 
			
		||||
        auto root = sqrt(discriminant);
 | 
			
		||||
 | 
			
		||||
        auto temp = (-half_b - root)/a;
 | 
			
		||||
        if (temp < t_max && temp > t_min)
 | 
			
		||||
        {
 | 
			
		||||
            rec.t = temp;
 | 
			
		||||
            rec.p = r.at(rec.t);
 | 
			
		||||
 | 
			
		||||
            vec3 outward_normal = (rec.p - centre_) / radius_;
 | 
			
		||||
            rec.set_face_normal(r, outward_normal);
 | 
			
		||||
            rec.mat_ptr = mat_ptr_;
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        temp = (-half_b + root) / a;
 | 
			
		||||
        if (temp < t_max && temp > t_min)
 | 
			
		||||
        {
 | 
			
		||||
            rec.t = temp;
 | 
			
		||||
            rec.p = r.at(rec.t);
 | 
			
		||||
            
 | 
			
		||||
            vec3 outward_normal = (rec.p - centre_) / radius_;
 | 
			
		||||
            rec.set_face_normal(r, outward_normal);
 | 
			
		||||
            rec.mat_ptr = mat_ptr_;
 | 
			
		||||
            
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -52,5 +52,4 @@ private:
 | 
			
		||||
 | 
			
		||||
// type aliases for vec3
 | 
			
		||||
using point3 = vec3; // 3D point
 | 
			
		||||
using colour = vec3; // RGB colour
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								include/world.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								include/world.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "math.h"
 | 
			
		||||
#include "sphere.h"
 | 
			
		||||
#include "colour.h"
 | 
			
		||||
#include "material.h"
 | 
			
		||||
#include "hittable_list.h"
 | 
			
		||||
 | 
			
		||||
class world : public hittable_list
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    static world* close_glass_sphere();
 | 
			
		||||
    static world* orb_field();
 | 
			
		||||
 | 
			
		||||
    friend colour trace(const world& world, const ray& ray, int depth);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										67
									
								
								src/colour.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/colour.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
#include "colour.h"
 | 
			
		||||
 | 
			
		||||
colour colour::correct_gamma(int samples)
 | 
			
		||||
{
 | 
			
		||||
    double r = x();
 | 
			
		||||
    double g = y();
 | 
			
		||||
    double b = z();
 | 
			
		||||
 | 
			
		||||
    // divide the colour total by the number of samples and gamma-correct for gamma=2.0
 | 
			
		||||
    auto scale = 1.0 / samples;
 | 
			
		||||
    r = sqrt(scale * r);
 | 
			
		||||
    g = sqrt(scale * g);
 | 
			
		||||
    b = sqrt(scale * b);
 | 
			
		||||
 | 
			
		||||
    return colour(r, g, b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int format_component(double component)
 | 
			
		||||
{
 | 
			
		||||
    return int(256 * math::clamp(component, 0.0, 0.999));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void write_colour_to_socket(int sockfd, colour pixel_colour, int samples_per_pixel)
 | 
			
		||||
{
 | 
			
		||||
    pixel_colour = pixel_colour.correct_gamma(samples_per_pixel);
 | 
			
		||||
 | 
			
		||||
    int r = format_component(pixel_colour.x());
 | 
			
		||||
    int g = format_component(pixel_colour.y());
 | 
			
		||||
    int b = format_component(pixel_colour.z());
 | 
			
		||||
 | 
			
		||||
    // pack values
 | 
			
		||||
    int len = 3;
 | 
			
		||||
    char s[len];
 | 
			
		||||
    sprintf(s, "%c%c%c", r, g, b);
 | 
			
		||||
 | 
			
		||||
    int written = write(sockfd, s, len);
 | 
			
		||||
    if (written < 0)
 | 
			
		||||
    {
 | 
			
		||||
        error("ERROR writing colour to socket");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void write_colour_to_stream(std::ostream &out, colour pixel_colour, int samples_per_pixel)
 | 
			
		||||
{
 | 
			
		||||
    pixel_colour = pixel_colour.correct_gamma(samples_per_pixel);
 | 
			
		||||
 | 
			
		||||
    auto r = pixel_colour.x();
 | 
			
		||||
    auto g = pixel_colour.y();
 | 
			
		||||
    auto b = pixel_colour.z();
 | 
			
		||||
    
 | 
			
		||||
    // write the translated [0,255] value of each colour component.
 | 
			
		||||
    out << format_component(r) << ' '
 | 
			
		||||
        << format_component(g) << ' '
 | 
			
		||||
        << format_component(b) << '\n';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
colour operator*(const colour& u, const colour& v)
 | 
			
		||||
{
 | 
			
		||||
    vec3 value = (vec3)u * (vec3)v;
 | 
			
		||||
    return colour(value.x(), value.y(), value.z());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
colour lerp(const colour& a, const colour& b, double t)
 | 
			
		||||
{
 | 
			
		||||
    vec3 value = lerp((vec3)a, (vec3)b, t);
 | 
			
		||||
    return colour(value.x(), value.y(), value.z());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								src/error.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/error.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
#include "error.h"
 | 
			
		||||
 | 
			
		||||
void error(const char* message)
 | 
			
		||||
{
 | 
			
		||||
    perror(message);
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
#include "foo.h"
 | 
			
		||||
							
								
								
									
										20
									
								
								src/hittable_list.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/hittable_list.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
#include "hittable_list.h"
 | 
			
		||||
 | 
			
		||||
bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const
 | 
			
		||||
{
 | 
			
		||||
    hit_record temp_rec;
 | 
			
		||||
    bool hit_anything = false;
 | 
			
		||||
    auto closest_so_far = t_max;
 | 
			
		||||
 | 
			
		||||
    for (const auto& object : objects_)
 | 
			
		||||
    {
 | 
			
		||||
        if (object->hit(r, t_min, closest_so_far, temp_rec))
 | 
			
		||||
        {
 | 
			
		||||
            hit_anything = true;
 | 
			
		||||
            closest_so_far = temp_rec.t;
 | 
			
		||||
            rec = temp_rec;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return hit_anything;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/main.cpp
									
									
									
									
									
								
							@ -1,14 +1,10 @@
 | 
			
		||||
#include "rtweekend.h"
 | 
			
		||||
 | 
			
		||||
#include "scene.h"
 | 
			
		||||
 | 
			
		||||
#include "colour.h"
 | 
			
		||||
#include "camera.h"
 | 
			
		||||
#include "material.h"
 | 
			
		||||
#include "image.h"
 | 
			
		||||
#include "world.h"
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
@ -106,7 +102,7 @@ void send_image_dimensions(int sock, unsigned int width, unsigned int height)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void render(camera& cam, hittable_list& world, int client_sock)
 | 
			
		||||
void render(camera& cam, const world& world, int client_sock)
 | 
			
		||||
{
 | 
			
		||||
    for (int j = HEIGHT - 1; j >= 0; --j)
 | 
			
		||||
    {
 | 
			
		||||
@ -120,7 +116,7 @@ void render(camera& cam, hittable_list& world, int client_sock)
 | 
			
		||||
                auto u = (i + math::random_double()) / (WIDTH-1);
 | 
			
		||||
                auto v = (j + math::random_double()) / (HEIGHT-1);
 | 
			
		||||
                ray r = cam.get_ray(u, v);
 | 
			
		||||
                pixel_colour += ray_colour(r, world, MAX_DEPTH);
 | 
			
		||||
                pixel_colour += trace(world, r, MAX_DEPTH);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // TODO: we should instead write our output to some buffer in memory
 | 
			
		||||
@ -142,8 +138,6 @@ int main()
 | 
			
		||||
 | 
			
		||||
    //std::cout << "P3\n" << WIDTH << ' ' << HEIGHT << "\n255\n";
 | 
			
		||||
 | 
			
		||||
    hittable_list world = random_scene();
 | 
			
		||||
 | 
			
		||||
    auto dist_to_target = 10.0;
 | 
			
		||||
    auto dist_to_focus = dist_to_target + 1.0;
 | 
			
		||||
    auto cam_y = 1.0;
 | 
			
		||||
@ -154,7 +148,9 @@ int main()
 | 
			
		||||
 | 
			
		||||
    camera cam(lookfrom, lookat, vup, 47, ASPECT_RATIO, aperture, dist_to_focus);
 | 
			
		||||
 | 
			
		||||
    render(cam, world, newsockfd);
 | 
			
		||||
    const world* world = world::close_glass_sphere();
 | 
			
		||||
 | 
			
		||||
    render(cam, *world, newsockfd);
 | 
			
		||||
 | 
			
		||||
    // close client socket
 | 
			
		||||
    close(newsockfd);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								src/sphere.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/sphere.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
#include "sphere.h"
 | 
			
		||||
 | 
			
		||||
bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const 
 | 
			
		||||
{
 | 
			
		||||
    vec3 oc = r.origin() - centre_;
 | 
			
		||||
    auto a = r.direction().length_squared();
 | 
			
		||||
    auto half_b = dot(oc, r.direction());
 | 
			
		||||
    auto c = oc.length_squared() - radius_*radius_;
 | 
			
		||||
    auto discriminant = half_b*half_b - a*c;
 | 
			
		||||
 | 
			
		||||
    if (discriminant > 0)
 | 
			
		||||
    {
 | 
			
		||||
        auto root = sqrt(discriminant);
 | 
			
		||||
 | 
			
		||||
        auto temp = (-half_b - root)/a;
 | 
			
		||||
        if (temp < t_max && temp > t_min)
 | 
			
		||||
        {
 | 
			
		||||
            rec.t = temp;
 | 
			
		||||
            rec.p = r.at(rec.t);
 | 
			
		||||
 | 
			
		||||
            vec3 outward_normal = (rec.p - centre_) / radius_;
 | 
			
		||||
            rec.set_face_normal(r, outward_normal);
 | 
			
		||||
            rec.mat_ptr = mat_ptr_;
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        temp = (-half_b + root) / a;
 | 
			
		||||
        if (temp < t_max && temp > t_min)
 | 
			
		||||
        {
 | 
			
		||||
            rec.t = temp;
 | 
			
		||||
            rec.p = r.at(rec.t);
 | 
			
		||||
            
 | 
			
		||||
            vec3 outward_normal = (rec.p - centre_) / radius_;
 | 
			
		||||
            rec.set_face_normal(r, outward_normal);
 | 
			
		||||
            rec.mat_ptr = mat_ptr_;
 | 
			
		||||
            
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								src/world.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/world.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
#include "world.h"
 | 
			
		||||
 | 
			
		||||
colour trace(const world& world, const ray& r, int depth)
 | 
			
		||||
{
 | 
			
		||||
    hit_record rec;
 | 
			
		||||
    if (depth <= 0)
 | 
			
		||||
    {
 | 
			
		||||
        return grey;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (world.hit(r, 0.001, math::infinity, rec))
 | 
			
		||||
    {
 | 
			
		||||
        ray     scattered;
 | 
			
		||||
        colour  attenuation;
 | 
			
		||||
 | 
			
		||||
        if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
 | 
			
		||||
        {
 | 
			
		||||
            return attenuation * trace(world, scattered, depth-1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return grey;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vec3 unit_direction = normalize(r.direction());
 | 
			
		||||
    auto t = 0.5 * (unit_direction.y() + 1.0) + 0.5;
 | 
			
		||||
 | 
			
		||||
    return lerp(grey, pink, t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
world* world::close_glass_sphere()
 | 
			
		||||
{
 | 
			
		||||
    world* w = new world();
 | 
			
		||||
 | 
			
		||||
    auto material1 = std::make_shared<dielectric>(1.5);
 | 
			
		||||
    w->add(std::make_shared<sphere>(point3(0, 0, 0), 3.0, material1));
 | 
			
		||||
 | 
			
		||||
    //auto material2 = make_shared<lambertian>(pink);
 | 
			
		||||
    //world.add(make_shared<sphere>(point3(-4, 1, 0), 1.0, material2));
 | 
			
		||||
    
 | 
			
		||||
    auto material3 = std::make_shared<metal>(pink, 0.5);
 | 
			
		||||
    int sphere_count = 10;
 | 
			
		||||
    for (int i = 0; i < sphere_count; i++)
 | 
			
		||||
    {
 | 
			
		||||
        float a = 6.28 * (float)i/sphere_count - 100.0;
 | 
			
		||||
        float r = 8.0;
 | 
			
		||||
        float x = r*sin(a);
 | 
			
		||||
        float y = 2.0*cos(a);
 | 
			
		||||
        float z = r*cos(a);
 | 
			
		||||
        point3 pos(x,y,z);
 | 
			
		||||
        w->add(std::make_shared<sphere>(pos, 2.0, material3));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return w;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user