├── RayTutNew ├── image.h ├── camera.cpp ├── camera.h ├── RayTutNew.sln ├── ray.h ├── color.h ├── color.cpp ├── image.cpp ├── ray.cpp ├── shape.h ├── main.cpp ├── vectormath.h ├── vectormath.cpp ├── RayTutNew.vcxproj.filters ├── shape.cpp └── RayTutNew.vcxproj ├── .gitattributes └── .gitignore /RayTutNew/image.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGE_H 2 | #define IMAGE_H 3 | 4 | #include 5 | 6 | #include "color.h" 7 | 8 | class Image 9 | { 10 | protected: 11 | int width, height; 12 | Color* data; 13 | 14 | public: 15 | Image(int width, int height); 16 | 17 | virtual ~Image(); 18 | 19 | int getWidth() const; 20 | int getHeight() const; 21 | 22 | Color* getPixel(int x, int y); 23 | 24 | void saveImage(std::string filename, 25 | float exposure = 1.0f, float gamma = 2.2f) const; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /RayTutNew/camera.cpp: -------------------------------------------------------------------------------- 1 | #include "camera.h" 2 | 3 | #include 4 | 5 | PerspectiveCamera::PerspectiveCamera(Point origin, 6 | Vector target, Vector upguide, float fov, float aspectRatio) 7 | : origin(origin) 8 | { 9 | forward = (target - origin).normalized(); 10 | right = cross(forward, upguide).normalized(); 11 | up = cross(right, forward); 12 | 13 | h = tan(fov); 14 | w = h * aspectRatio; 15 | } 16 | 17 | Ray PerspectiveCamera::makeRay(Vector2 point) const 18 | { 19 | Vector direction = 20 | forward + point.u * w * right + point.v * h * up; 21 | 22 | return Ray(origin, direction.normalized()); 23 | } 24 | -------------------------------------------------------------------------------- /RayTutNew/camera.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERA_H 2 | #define CAMERA_H 3 | 4 | #include "vectormath.h" 5 | #include "ray.h" 6 | 7 | class Camera 8 | { 9 | public: 10 | virtual ~Camera() { } 11 | 12 | virtual Ray makeRay(Vector2 point) const = 0; 13 | }; 14 | 15 | class PerspectiveCamera : public Camera 16 | { 17 | protected: 18 | Point origin; 19 | Vector forward; 20 | Vector up; 21 | Vector right; 22 | 23 | float h, w; 24 | 25 | public: 26 | PerspectiveCamera(Point origin, Vector target, 27 | Vector upguide, float fov, float aspectRatio); 28 | 29 | virtual Ray makeRay(Vector2 point) const; 30 | }; 31 | 32 | #endif // CAMERA_H 33 | -------------------------------------------------------------------------------- /RayTutNew/RayTutNew.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RayTutNew", "RayTutNew.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64 15 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64 16 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64 17 | {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /RayTutNew/ray.h: -------------------------------------------------------------------------------- 1 | #ifndef RAY_H 2 | #define RAY_H 3 | 4 | #include "vectormath.h" 5 | #include "color.h" 6 | 7 | // In order to prevent bouncing rays self-intersecting 8 | #define RAY_T_MIN 0.0001f 9 | 10 | // 'Infinite' distance, used as a default value 11 | #define RAY_T_MAX 1.0e30f 12 | 13 | struct Ray 14 | { 15 | Point origin; // start 16 | Vector direction; 17 | float tMax; 18 | 19 | Ray(); 20 | Ray(const Ray& r); 21 | Ray(const Point& origin, const Vector& direction, 22 | float tMax = RAY_T_MAX); 23 | 24 | virtual ~Ray(); 25 | 26 | Ray& operator =(const Ray& r); 27 | 28 | Point calculate(float t) const; 29 | }; 30 | 31 | class Shape; 32 | 33 | struct Intersection 34 | { 35 | Ray ray; 36 | float t; 37 | Shape *pShape; 38 | Color color; 39 | 40 | Intersection(); 41 | Intersection(const Intersection& i); 42 | Intersection(const Ray& ray); 43 | 44 | virtual ~Intersection(); 45 | 46 | Intersection& operator =(const Intersection& i); 47 | 48 | bool intersected() const; 49 | Point position() const; 50 | }; 51 | 52 | #endif // RAY_H 53 | -------------------------------------------------------------------------------- /RayTutNew/color.h: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_H 2 | #define COLOR_H 3 | 4 | struct Color 5 | { 6 | float r, g, b; 7 | 8 | Color(); 9 | Color(float l); 10 | Color(float r, float g, float b); 11 | 12 | virtual ~Color(); 13 | 14 | void clamp(float min = 0.0f, float max = 1.0f); 15 | void applyGammaCorrection(float exposure, float gamma); 16 | 17 | Color& operator =(const Color& c); 18 | Color& operator +=(const Color& c); 19 | Color& operator *=(const Color& c); 20 | Color& operator *=(float f); 21 | }; 22 | 23 | inline Color operator +(const Color& c1, const Color& c2) 24 | { 25 | return Color(c1.r + c2.r, 26 | c1.g + c2.g, 27 | c1.b + c2.b); 28 | } 29 | 30 | inline Color operator *(const Color& c1, const Color& c2) 31 | { 32 | return Color(c1.r * c2.r, 33 | c1.g * c2.g, 34 | c1.b * c2.b); 35 | } 36 | 37 | inline Color operator *(const Color& c, float f) 38 | { 39 | return Color(c.r * f, 40 | c.g * f, 41 | c.b * f); 42 | } 43 | 44 | inline Color operator *(float f, const Color& c) 45 | { 46 | return Color(f * c.r, 47 | f * c.g, 48 | f * c.b); 49 | } 50 | 51 | #endif // COLOR_H 52 | -------------------------------------------------------------------------------- /RayTutNew/color.cpp: -------------------------------------------------------------------------------- 1 | #include "color.h" 2 | 3 | #include 4 | #include 5 | 6 | Color::Color() 7 | : r(0.0f), g(0.0f), b(0.0f) 8 | { 9 | } 10 | 11 | Color::Color(float l) 12 | : r(l), g(l), b(l) 13 | { 14 | } 15 | 16 | Color::Color(float r, float g, float b) 17 | : r(r), g(g), b(b) 18 | { 19 | } 20 | 21 | Color::~Color() 22 | { 23 | } 24 | 25 | void Color::clamp(float min, float max) 26 | { 27 | r = std::max(min, std::min(max, r)); 28 | g = std::max(min, std::min(max, g)); 29 | b = std::max(min, std::min(max, b)); 30 | } 31 | 32 | void Color::applyGammaCorrection(float exposure, float gamma) 33 | { 34 | r = std::pow(r * exposure, gamma); 35 | g = std::pow(g * exposure, gamma); 36 | b = std::pow(b * exposure, gamma); 37 | } 38 | 39 | Color& Color::operator =(const Color& c) 40 | { 41 | r = c.r; 42 | g = c.g; 43 | b = c.b; 44 | return *this; 45 | } 46 | 47 | Color& Color::operator +=(const Color& c) 48 | { 49 | r += c.r; 50 | g += c.g; 51 | b += c.b; 52 | return *this; 53 | } 54 | 55 | Color& Color::operator *=(const Color& c) 56 | { 57 | r *= c.r; 58 | g *= c.g; 59 | b *= c.b; 60 | return *this; 61 | } 62 | 63 | Color& Color::operator *=(float f) 64 | { 65 | r *= f; 66 | g *= f; 67 | b *= f; 68 | return *this; 69 | } 70 | -------------------------------------------------------------------------------- /RayTutNew/image.cpp: -------------------------------------------------------------------------------- 1 | #include "image.h" 2 | 3 | #include 4 | #include 5 | 6 | Image::Image(int width, int height) 7 | : width(width), height(height) 8 | { 9 | data = new Color[width * height]; 10 | } 11 | 12 | Image::~Image() 13 | { 14 | delete[] data; 15 | } 16 | 17 | int Image::getWidth() const 18 | { 19 | return width; 20 | } 21 | 22 | int Image::getHeight() const 23 | { 24 | return height; 25 | } 26 | 27 | Color* Image::getPixel(int x, int y) 28 | { 29 | return data + (x + y * width); 30 | } 31 | 32 | void Image::saveImage(std::string filename, 33 | float exposure, float gamma) const 34 | { 35 | uchar* imgData = new uchar[4 * width * height]; 36 | 37 | for (int x = 0; x < width; x++) 38 | { 39 | for (int y = 0; y < height; y++) 40 | { 41 | Color curColor = data[x + y * width]; 42 | curColor.applyGammaCorrection(exposure, gamma); 43 | curColor.clamp(); 44 | 45 | imgData[4 * (x + y * width) + 3] = 255; 46 | imgData[4 * (x + y * width) + 2] = 47 | (uchar)(curColor.r * 255.0f); 48 | imgData[4 * (x + y * width) + 1] = 49 | (uchar)(curColor.g * 255.0f); 50 | imgData[4 * (x + y * width) + 0] = 51 | (uchar)(curColor.b * 255.0f); 52 | } 53 | } 54 | 55 | QImage img(imgData, width, height, QImage::Format_RGB32); 56 | img.save(QString(filename.c_str())); 57 | 58 | delete[] imgData; 59 | } 60 | -------------------------------------------------------------------------------- /RayTutNew/ray.cpp: -------------------------------------------------------------------------------- 1 | #include "ray.h" 2 | 3 | Ray::Ray() 4 | : origin(0.0f, 0.0f, 0.0f), 5 | direction(), 6 | tMax(RAY_T_MAX) 7 | { 8 | } 9 | 10 | Ray::Ray(const Ray& r) 11 | : origin(r.origin), 12 | direction(r.direction), 13 | tMax(r.tMax) 14 | { 15 | } 16 | 17 | Ray::Ray(const Point& origin, const Vector& direction, float tMax) 18 | : origin(origin), 19 | direction(direction), 20 | tMax(tMax) 21 | { 22 | } 23 | 24 | Ray::~Ray() 25 | { 26 | } 27 | 28 | Ray& Ray::operator =(const Ray& r) 29 | { 30 | origin = r.origin; 31 | direction = r.direction; 32 | tMax = r.tMax; 33 | return *this; 34 | } 35 | 36 | Point Ray::calculate(float t) const 37 | { 38 | return origin + direction * t; 39 | } 40 | 41 | 42 | Intersection::Intersection() 43 | : ray(), 44 | t(RAY_T_MAX), 45 | pShape(NULL) 46 | { 47 | } 48 | 49 | Intersection::Intersection(const Intersection& i) 50 | : ray(i.ray), 51 | t(i.t), 52 | pShape(i.pShape) 53 | { 54 | } 55 | 56 | Intersection::Intersection(const Ray& ray) 57 | : ray(ray), 58 | t(ray.tMax), 59 | pShape(NULL) 60 | { 61 | } 62 | 63 | Intersection::~Intersection() 64 | { 65 | } 66 | 67 | Intersection& Intersection::operator =(const Intersection& i) 68 | { 69 | ray = i.ray; 70 | t = i.t; 71 | pShape = i.pShape; 72 | return *this; 73 | } 74 | 75 | bool Intersection::intersected() const 76 | { 77 | return (pShape != NULL); 78 | } 79 | 80 | Point Intersection::position() const 81 | { 82 | return ray.calculate(t); 83 | } 84 | -------------------------------------------------------------------------------- /RayTutNew/shape.h: -------------------------------------------------------------------------------- 1 | #ifndef SHAPE_H 2 | #define SHAPE_H 3 | 4 | #include 5 | 6 | #include "vectormath.h" 7 | #include "ray.h" 8 | 9 | class Shape 10 | { 11 | public: 12 | virtual ~Shape() { } 13 | 14 | virtual bool intersect(Intersection& intersection) = 0; 15 | virtual bool doesIntersect(const Ray& ray) = 0; 16 | }; 17 | 18 | class ShapeSet : public Shape 19 | { 20 | protected: 21 | std::vector shapes; 22 | 23 | public: 24 | ShapeSet(); 25 | 26 | virtual ~ShapeSet(); 27 | 28 | void addShape(Shape* shape); 29 | 30 | virtual bool intersect(Intersection& intersection); 31 | virtual bool doesIntersect(const Ray& ray); 32 | }; 33 | 34 | class Plane : public Shape 35 | { 36 | protected: 37 | Point position; 38 | Vector normal; 39 | Color color; 40 | 41 | public: 42 | Plane(const Point& position, const Vector& normal, 43 | const Color& color = Color(1.0f, 1.0f, 1.0f)); 44 | 45 | virtual ~Plane(); 46 | 47 | virtual bool intersect(Intersection& intersection); 48 | virtual bool doesIntersect(const Ray& ray); 49 | }; 50 | 51 | class Sphere : public Shape 52 | { 53 | protected: 54 | Point centre; 55 | float radius; 56 | Color color; 57 | 58 | public: 59 | Sphere(const Point& centre, float radius, 60 | const Color& color = Color(1.0f, 1.0f, 1.0f)); 61 | 62 | virtual ~Sphere(); 63 | 64 | virtual bool intersect(Intersection& intersection); 65 | virtual bool doesIntersect(const Ray& ray); 66 | }; 67 | 68 | #endif // SHAPE_H 69 | -------------------------------------------------------------------------------- /RayTutNew/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "image.h" 4 | #include "camera.h" 5 | #include "shape.h" 6 | 7 | void rayTrace(Image& image, Camera* camera, Shape* scene) 8 | { 9 | for (int x = 0; x < image.getWidth(); x++) 10 | { 11 | for (int y = 0; y < image.getHeight(); y++) 12 | { 13 | Vector2 screenCoord((2.0f*x) / image.getWidth() - 1.0f, 14 | (-2.0f*y) / image.getHeight() + 1.0f); 15 | Ray ray = camera->makeRay(screenCoord); 16 | 17 | Color* curPixel = image.getPixel(x, y); 18 | 19 | Intersection intersection(ray); 20 | if (scene->intersect(intersection)) 21 | { 22 | *curPixel = intersection.color; 23 | } 24 | else 25 | { 26 | *curPixel = Color(0.0f); 27 | } 28 | } 29 | } 30 | } 31 | 32 | int main(int argc, char *argv[]) 33 | { 34 | // QCoreApplication a(argc, argv); 35 | 36 | int width = 1920; 37 | int height = 1080; 38 | 39 | Image image(width, height); 40 | PerspectiveCamera camera(Point(-5.0f, 1.0f, 0.0f), 41 | Vector(0.0f, 1.0f, 0.0f), Vector(), 25.0f * PI / 180.0f, 42 | (float)width / (float)height); 43 | 44 | ShapeSet scene; 45 | 46 | Plane floor(Point(0.0f, 0.0f, 0.0f), Vector(), 47 | Color(0.5f, 1.0f, 0.5f)); 48 | scene.addShape(&floor); 49 | 50 | Sphere sphere(Point(0.0f, 1.0f, 0.0f), 1.0f, 51 | Color(0.5f, 0.5f, 1.0f)); 52 | scene.addShape(&sphere); 53 | 54 | rayTrace(image, &camera, &scene); 55 | 56 | image.saveImage("out.png"); 57 | 58 | // return a.exec(); 59 | } 60 | -------------------------------------------------------------------------------- /RayTutNew/vectormath.h: -------------------------------------------------------------------------------- 1 | #ifndef MATHS_H 2 | #define MATHS_H 3 | 4 | #ifndef NULL 5 | #define NULL 0 6 | #endif 7 | 8 | #ifndef PI 9 | #define PI 3.1415926f 10 | #endif 11 | 12 | inline float sqr(float n) 13 | { 14 | return n * n; 15 | } 16 | 17 | struct Vector 18 | { 19 | float x, y, z; 20 | 21 | Vector(); 22 | Vector(const Vector& v); 23 | Vector(float x, float y, float z); 24 | Vector(float f); 25 | 26 | virtual ~Vector(); 27 | 28 | inline float length2(); 29 | inline float length(); 30 | 31 | float normalize(); 32 | Vector normalized(); 33 | 34 | Vector& operator =(const Vector& v); 35 | Vector& operator +=(const Vector& v); 36 | Vector& operator -=(const Vector& v); 37 | Vector& operator *=(float f); 38 | Vector& operator /=(float f); 39 | Vector operator -() const; 40 | }; 41 | 42 | float dot(Vector v1, Vector v2); 43 | Vector cross(Vector v1, Vector v2); 44 | 45 | inline Vector operator +(const Vector& v1, const Vector& v2) 46 | { 47 | return Vector(v1.x + v2.x, 48 | v1.y + v2.y, 49 | v1.z + v2.z); 50 | } 51 | 52 | inline Vector operator -(const Vector& v1, const Vector& v2) 53 | { 54 | return Vector(v1.x - v2.x, 55 | v1.y - v2.y, 56 | v1.z - v2.z); 57 | } 58 | 59 | inline Vector operator *(const Vector& v1, const Vector& v2) 60 | { 61 | return Vector(v1.x * v2.x, 62 | v1.y * v2.y, 63 | v1.z * v2.z); 64 | } 65 | 66 | inline Vector operator *(const Vector& v, float f) 67 | { 68 | return Vector(v.x * f, 69 | v.y * f, 70 | v.z * f); 71 | } 72 | 73 | inline Vector operator *(float f, const Vector& v) 74 | { 75 | return Vector(f * v.x, 76 | f * v.y, 77 | f * v.z); 78 | } 79 | 80 | inline Vector operator /(const Vector& v1, const Vector& v2) 81 | { 82 | return Vector(v1.x / v2.x, 83 | v1.y / v2.y, 84 | v1.z / v2.z); 85 | } 86 | 87 | inline Vector operator /(const Vector& v, float f) 88 | { 89 | return Vector(v.x / f, 90 | v.y / f, 91 | v.z / f); 92 | } 93 | 94 | inline Vector operator /(float f, const Vector& v) 95 | { 96 | return Vector(f / v.x, 97 | f / v.y, 98 | f / v.z); 99 | } 100 | 101 | typedef Vector Point; 102 | 103 | struct Vector2 104 | { 105 | float u, v; 106 | 107 | Vector2(); 108 | Vector2(const Vector2& v); 109 | Vector2(float u, float v); 110 | Vector2(float f); 111 | 112 | virtual ~Vector2(); 113 | 114 | Vector2& operator =(const Vector2& v); 115 | }; 116 | 117 | #endif // MATHS_H 118 | -------------------------------------------------------------------------------- /RayTutNew/vectormath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vectormath.h" 4 | 5 | Vector::Vector() 6 | : x(0.0f), 7 | y(1.0f), 8 | z(0.0f) 9 | { 10 | } 11 | 12 | Vector::Vector(const Vector& v) 13 | : x(v.x), 14 | y(v.y), 15 | z(v.z) 16 | { 17 | } 18 | 19 | Vector::Vector(float x, float y, float z) 20 | : x(x), 21 | y(y), 22 | z(z) 23 | { 24 | } 25 | 26 | Vector::Vector(float f) 27 | : x(f), 28 | y(f), 29 | z(f) 30 | { 31 | } 32 | 33 | Vector::~Vector() 34 | { 35 | } 36 | 37 | inline float Vector::length2() 38 | { 39 | return sqr(x) + sqr(y) + sqr(z); 40 | } 41 | 42 | inline float Vector::length() 43 | { 44 | return std::sqrt(length2()); 45 | } 46 | 47 | float Vector::normalize() 48 | { 49 | float l = length(); 50 | 51 | *this /= l; 52 | 53 | return l; 54 | } 55 | 56 | Vector Vector::normalized() 57 | { 58 | Vector v(*this); 59 | v.normalize(); 60 | return v; 61 | } 62 | 63 | float dot(Vector v1, Vector v2) 64 | { 65 | return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; 66 | } 67 | 68 | Vector cross(Vector v1, Vector v2) 69 | { 70 | return Vector(v1.y * v2.z - v1.z * v2.y, 71 | v1.z * v2.x - v1.x * v2.z, 72 | v1.x * v2.y - v1.y * v2.x); 73 | } 74 | 75 | Vector& Vector::operator =(const Vector& v) 76 | { 77 | x = v.x; 78 | y = v.y; 79 | z = v.z; 80 | 81 | return *this; 82 | } 83 | 84 | Vector& Vector::operator +=(const Vector& v) 85 | { 86 | x += v.x; 87 | y += v.y; 88 | z += v.z; 89 | return *this; 90 | } 91 | 92 | Vector& Vector::operator -=(const Vector& v) 93 | { 94 | x -= v.x; 95 | y -= v.y; 96 | z -= v.z; 97 | return *this; 98 | } 99 | 100 | Vector& Vector::operator *=(float f) 101 | { 102 | x *= f; 103 | y *= f; 104 | z *= f; 105 | return *this; 106 | } 107 | 108 | Vector& Vector::operator /=(float f) 109 | { 110 | x /= f; 111 | y /= f; 112 | z /= f; 113 | return *this; 114 | } 115 | 116 | Vector Vector::operator -() const 117 | { 118 | return Vector(-x, -y, -z); 119 | } 120 | 121 | Vector2::Vector2() 122 | : u(0.0f), 123 | v(0.0f) 124 | { 125 | } 126 | 127 | Vector2::Vector2(const Vector2 &v) 128 | : u(v.u), 129 | v(v.v) 130 | { 131 | } 132 | 133 | Vector2::Vector2(float u, float v) 134 | : u(u), 135 | v(v) 136 | { 137 | } 138 | 139 | Vector2::Vector2(float f) 140 | : u(f), 141 | v(f) 142 | { 143 | } 144 | 145 | Vector2::~Vector2() 146 | { 147 | } 148 | 149 | Vector2& Vector2::operator =(const Vector2& v) 150 | { 151 | u = v.u; 152 | this->v = v.v; 153 | return *this; 154 | } 155 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /RayTutNew/RayTutNew.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 14 | qrc;* 15 | false 16 | 17 | 18 | {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} 19 | qrc;* 20 | false 21 | 22 | 23 | {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} 24 | moc;h;cpp 25 | False 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | 52 | 53 | Header Files 54 | 55 | 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | Header Files 68 | 69 | 70 | Header Files 71 | 72 | 73 | -------------------------------------------------------------------------------- /RayTutNew/shape.cpp: -------------------------------------------------------------------------------- 1 | #include "shape.h" 2 | 3 | ShapeSet::ShapeSet() 4 | { 5 | } 6 | 7 | ShapeSet::~ShapeSet() 8 | { 9 | } 10 | 11 | void ShapeSet::addShape(Shape* shape) 12 | { 13 | shapes.push_back(shape); 14 | } 15 | 16 | bool ShapeSet::intersect(Intersection& intersection) 17 | { 18 | bool doesIntersect = false; 19 | 20 | for (std::vector::iterator iter = shapes.begin(); 21 | iter != shapes.end(); 22 | ++iter) 23 | { 24 | Shape *curShape = *iter; 25 | if (curShape->intersect(intersection)) 26 | doesIntersect = true; 27 | } 28 | 29 | return doesIntersect; 30 | } 31 | 32 | bool ShapeSet::doesIntersect(const Ray& ray) 33 | { 34 | for (std::vector::iterator iter = shapes.begin(); 35 | iter != shapes.end(); 36 | ++iter) 37 | { 38 | Shape *curShape = *iter; 39 | if (curShape->doesIntersect(ray)) 40 | return true; 41 | } 42 | 43 | return false; 44 | } 45 | 46 | 47 | Plane::Plane(const Point& position, const Vector& normal, 48 | const Color& color) 49 | : position(position), 50 | normal(normal), 51 | color(color) 52 | { 53 | } 54 | 55 | Plane::~Plane() 56 | { 57 | } 58 | 59 | bool Plane::intersect(Intersection& intersection) 60 | { 61 | // First, check if we intersect 62 | float dDotN = dot(intersection.ray.direction, normal); 63 | 64 | if (dDotN == 0.0f) 65 | { 66 | // We just assume the ray is not embedded in the plane 67 | return false; 68 | } 69 | 70 | // Find point of intersection 71 | float t = dot(position - intersection.ray.origin, normal) 72 | / dDotN; 73 | 74 | if (t <= RAY_T_MIN || t >= intersection.t) 75 | { 76 | // Outside relevant range 77 | return false; 78 | } 79 | 80 | intersection.t = t; 81 | intersection.pShape = this; 82 | intersection.color = color; 83 | 84 | return true; 85 | } 86 | 87 | bool Plane::doesIntersect(const Ray& ray) 88 | { 89 | // First, check if we intersect 90 | float dDotN = dot(ray.direction, normal); 91 | 92 | if (dDotN == 0.0f) 93 | { 94 | // We just assume the ray is not embedded in the plane 95 | return false; 96 | } 97 | 98 | // Find point of intersection 99 | float t = dot(position - ray.origin, normal) / dDotN; 100 | 101 | if (t <= RAY_T_MIN || t >= ray.tMax) 102 | { 103 | // Outside relevant range 104 | return false; 105 | } 106 | 107 | return true; 108 | } 109 | 110 | 111 | Sphere::Sphere(const Point& centre, float radius, 112 | const Color& color) 113 | : centre(centre), 114 | radius(radius), 115 | color(color) 116 | { 117 | } 118 | 119 | Sphere::~Sphere() 120 | { 121 | } 122 | 123 | bool Sphere::intersect(Intersection& intersection) 124 | { 125 | // Transform ray so we can consider origin-centred sphere 126 | Ray localRay = intersection.ray; 127 | localRay.origin -= centre; 128 | 129 | // Calculate quadratic coefficients 130 | float a = localRay.direction.length2(); 131 | float b = 2 * dot(localRay.direction, localRay.origin); 132 | float c = localRay.origin.length2() - sqr(radius); 133 | 134 | // Check whether we intersect 135 | float discriminant = sqr(b) - 4 * a * c; 136 | 137 | if (discriminant < 0.0f) 138 | { 139 | return false; 140 | } 141 | 142 | // Find two points of intersection, t1 close and t2 far 143 | float t1 = (-b - std::sqrt(discriminant)) / (2 * a); 144 | float t2 = (-b + std::sqrt(discriminant)) / (2 * a); 145 | 146 | // First check if close intersection is valid 147 | if (t1 > RAY_T_MIN && t1 < intersection.t) 148 | { 149 | intersection.t = t1; 150 | } 151 | else if (t2 > RAY_T_MIN && t2 < intersection.t) 152 | { 153 | intersection.t = t2; 154 | } 155 | else 156 | { 157 | // Neither is valid 158 | return false; 159 | } 160 | 161 | // Finish populating intersection 162 | intersection.pShape = this; 163 | intersection.color = color; 164 | 165 | return true; 166 | } 167 | 168 | bool Sphere::doesIntersect(const Ray& ray) 169 | { 170 | // Transform ray so we can consider origin-centred sphere 171 | Ray localRay = ray; 172 | localRay.origin -= centre; 173 | 174 | // Calculate quadratic coefficients 175 | float a = localRay.direction.length2(); 176 | float b = 2 * dot(localRay.direction, localRay.origin); 177 | float c = localRay.origin.length2() - sqr(radius); 178 | 179 | // Check whether we intersect 180 | float discriminant = sqr(b) - 4 * a * c; 181 | 182 | if (discriminant < 0.0f) 183 | { 184 | return false; 185 | } 186 | 187 | // Find two points of intersection, t1 close and t2 far 188 | float t1 = (-b - std::sqrt(discriminant)) / (2 * a); 189 | if (t1 > RAY_T_MIN && t1 < ray.tMax) 190 | return true; 191 | 192 | float t2 = (-b + std::sqrt(discriminant)) / (2 * a); 193 | if (t2 > RAY_T_MIN && t2 < ray.tMax) 194 | return true; 195 | 196 | return false; 197 | } 198 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | out.png 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | [Xx]64/ 21 | [Xx]86/ 22 | [Bb]uild/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # DNX 46 | project.lock.json 47 | artifacts/ 48 | 49 | *_i.c 50 | *_p.c 51 | *_i.h 52 | *.ilk 53 | *.meta 54 | *.obj 55 | *.pch 56 | *.pdb 57 | *.pgc 58 | *.pgd 59 | *.rsp 60 | *.sbr 61 | *.tlb 62 | *.tli 63 | *.tlh 64 | *.tmp 65 | *.tmp_proj 66 | *.log 67 | *.vspscc 68 | *.vssscc 69 | .builds 70 | *.pidb 71 | *.svclog 72 | *.scc 73 | 74 | # Chutzpah Test files 75 | _Chutzpah* 76 | 77 | # Visual C++ cache files 78 | ipch/ 79 | *.aps 80 | *.ncb 81 | *.opendb 82 | *.opensdf 83 | *.sdf 84 | *.cachefile 85 | *.VC.db 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | 145 | # TODO: Un-comment the next line if you do not want to checkin 146 | # your web deploy settings because they may include unencrypted 147 | # passwords 148 | #*.pubxml 149 | *.publishproj 150 | 151 | # NuGet Packages 152 | *.nupkg 153 | # The packages folder can be ignored because of Package Restore 154 | **/packages/* 155 | # except build/, which is used as an MSBuild target. 156 | !**/packages/build/ 157 | # Uncomment if necessary however generally it will be regenerated when needed 158 | #!**/packages/repositories.config 159 | # NuGet v3's project.json files produces more ignoreable files 160 | *.nuget.props 161 | *.nuget.targets 162 | 163 | # Microsoft Azure Build Output 164 | csx/ 165 | *.build.csdef 166 | 167 | # Microsoft Azure Emulator 168 | ecf/ 169 | rcf/ 170 | 171 | # Windows Store app package directory 172 | AppPackages/ 173 | BundleArtifacts/ 174 | 175 | # Visual Studio cache files 176 | # files ending in .cache can be ignored 177 | *.[Cc]ache 178 | # but keep track of directories ending in .cache 179 | !*.[Cc]ache/ 180 | 181 | # Others 182 | ClientBin/ 183 | [Ss]tyle[Cc]op.* 184 | ~$* 185 | *~ 186 | *.dbmdl 187 | *.dbproj.schemaview 188 | *.pfx 189 | *.publishsettings 190 | node_modules/ 191 | orleans.codegen.cs 192 | 193 | # RIA/Silverlight projects 194 | Generated_Code/ 195 | 196 | # Backup & report files from converting an old project file 197 | # to a newer Visual Studio version. Backup files are not needed, 198 | # because we have git ;-) 199 | _UpgradeReport_Files/ 200 | Backup*/ 201 | UpgradeLog*.XML 202 | UpgradeLog*.htm 203 | 204 | # SQL Server files 205 | *.mdf 206 | *.ldf 207 | 208 | # Business Intelligence projects 209 | *.rdl.data 210 | *.bim.layout 211 | *.bim_*.settings 212 | 213 | # Microsoft Fakes 214 | FakesAssemblies/ 215 | 216 | # GhostDoc plugin setting file 217 | *.GhostDoc.xml 218 | 219 | # Node.js Tools for Visual Studio 220 | .ntvs_analysis.dat 221 | 222 | # Visual Studio 6 build log 223 | *.plg 224 | 225 | # Visual Studio 6 workspace options file 226 | *.opt 227 | 228 | # Visual Studio LightSwitch build output 229 | **/*.HTMLClient/GeneratedArtifacts 230 | **/*.DesktopClient/GeneratedArtifacts 231 | **/*.DesktopClient/ModelManifest.xml 232 | **/*.Server/GeneratedArtifacts 233 | **/*.Server/ModelManifest.xml 234 | _Pvt_Extensions 235 | 236 | # LightSwitch generated files 237 | GeneratedArtifacts/ 238 | ModelManifest.xml 239 | 240 | # Paket dependency manager 241 | .paket/paket.exe 242 | 243 | # FAKE - F# Make 244 | .fake/ 245 | -------------------------------------------------------------------------------- /RayTutNew/RayTutNew.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {B12702AD-ABFB-343A-A199-8E24837244A3} 15 | Qt4VSv1.0 16 | 17 | 18 | 19 | Application 20 | v140 21 | 22 | 23 | Application 24 | v140 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | $(SolutionDir)$(Platform)\$(Configuration)\ 33 | 34 | 35 | $(SolutionDir)$(Platform)\$(Configuration)\ 36 | 37 | 38 | 39 | UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;%(PreprocessorDefinitions) 40 | Disabled 41 | ProgramDatabase 42 | MultiThreadedDebugDLL 43 | .;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;%(AdditionalIncludeDirectories) 44 | true 45 | 46 | 47 | Console 48 | $(OutDir)\$(ProjectName).exe 49 | $(QTDIR)\lib;%(AdditionalLibraryDirectories) 50 | true 51 | qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;%(AdditionalDependencies) 52 | 53 | 54 | 55 | 56 | UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;%(PreprocessorDefinitions) 57 | 58 | MultiThreadedDLL 59 | .;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;%(AdditionalIncludeDirectories) 60 | true 61 | 62 | 63 | Console 64 | $(OutDir)\$(ProjectName).exe 65 | $(QTDIR)\lib;%(AdditionalLibraryDirectories) 66 | false 67 | qtmain.lib;Qt5Core.lib;Qt5Gui.lib;%(AdditionalDependencies) 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Performing Custom Build Tools 84 | 85 | 86 | 87 | 88 | 89 | 90 | Performing Custom Build Tools 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | --------------------------------------------------------------------------------