Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <math.h>
- #include <stdlib.h>
- #if defined(__APPLE__)
- #include <OpenGL/gl.h>
- #include <OpenGL/glu.h>
- #include <GLUT/glut.h>
- #else
- #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
- #include <windows.h>
- #endif
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glut.h>
- #endif
- #ifndef M_PI
- #define M_PI 3.14159265359
- #endif
- template <typename T>
- T max(T a, T b) {
- return a > b ? a : b;
- }
- template <typename T>
- T min(T a, T b) {
- return a < b ? a : b;
- }
- template <typename T>
- T clamp(T x, T min_v, T max_v) {
- return min(max(x, min_v), max_v);
- }
- struct Vector {
- union { float x, r; }; // x és r néven is lehessen hivatkozni erre a tagra.
- union { float y, g; };
- union { float z, b; };
- Vector(float v = 0) : x(v), y(v), z(v) { }
- Vector(float x, float y, float z) : x(x), y(y), z(z) { }
- Vector operator+(const Vector& v) const { return Vector(x + v.x, y + v.y, z + v.z); }
- Vector operator-(const Vector& v) const { return Vector(x - v.x, y - v.y, z - v.z); }
- Vector operator*(const Vector& v) const { return Vector(x * v.x, y * v.y, z * v.z); }
- Vector operator/(const Vector& v) const { return Vector(x / v.x, y / v.y, z / v.z); }
- Vector& operator+=(const Vector& v) { x += v.x, y += v.y, z += v.z; return *this; }
- Vector& operator-=(const Vector& v) { x -= v.x, y -= v.y, z -= v.z; return *this; }
- Vector& operator*=(const Vector& v) { x *= v.x, y *= v.y, z *= v.z; return *this; }
- Vector& operator/=(const Vector& v) { x /= v.x, y /= v.y, z /= v.z; return *this; }
- Vector operator-() const { return Vector(-x, -y, -z); }
- float dot(const Vector& v) const { return x*v.x + y*v.y + z*v.z; }
- Vector cross(const Vector& v) const { return Vector(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); }
- float length() const { return sqrt(x*x + y*y + z*z); }
- Vector normalize() const { float l = length(); if(l > 1e-3) { return (*this/l); } else { return Vector(); } }
- bool isNull() const { return length() < 1e-3; }
- Vector toneMap() const {
- // Filmic tonemap approximation by Jim Hejl
- Vector v = Vector(max(r - 0.004f, 0.0f), max(g - 0.004f, 0.0f), max(b - 0.004f, 0.0f));
- v = (v*(v*6.2f+0.5f))/(v*(v*6.2f+1.7f)+0.06f);
- return Vector(pow(v.x, 2.2f), pow(v.y, 2.2f), pow(v.z, 2.2f));
- }
- static Vector Random() {
- return Vector(
- -1.0f + 2.0f*rand()/RAND_MAX,
- -1.0f + 2.0f*rand()/RAND_MAX,
- -1.0f + 2.0f*rand()/RAND_MAX
- );
- }
- };
- // Azoknak, akik a shader kódokban használt szintakszishoz hozzá vannak szokva (mint pl. én)
- inline float dot(const Vector& lhs, const Vector& rhs) {
- return lhs.dot(rhs);
- }
- inline Vector cross(const Vector& lhs, const Vector& rhs) {
- return lhs.cross(rhs);
- }
- inline Vector operator+(float f, const Vector& v) {
- return v+f;
- }
- inline Vector operator-(float f, const Vector& v) {
- return Vector(f)-v;
- }
- inline Vector operator*(float f, const Vector& v) {
- return v*f;
- }
- inline Vector operator/(float f, const Vector& v) {
- return Vector(f)/v;
- }
- typedef Vector Color;
- struct Screen {
- static const int width = 600;
- static const int height = 600;
- static Color image[width * height];
- static void Draw() {
- glDrawPixels(width, height, GL_RGB, GL_FLOAT, image);
- }
- static Color& Pixel(size_t x, size_t y) {
- return image[y*width + x];
- }
- };
- Color Screen::image[width * height]; // A statikus adattagat out-of-line példányosítani kell (kivéve az inteket és enumokat).
- struct Ray {
- Vector origin, direction;
- bool in_air;
- Ray(Vector origin = Vector(), Vector direction = Vector(), bool in_air = true)
- : origin(origin), direction(direction.normalize()), in_air(in_air) { }
- };
- struct Photon : public Ray {
- Color color;
- Photon(const Color& color, Vector origin = Vector(), Vector direction = Vector(), bool in_air = true)
- : Ray(origin, direction, in_air), color(color) { }
- };
- struct Intersection {
- Ray ray;
- Vector pos, normal;
- bool is_valid;
- Intersection(Ray ray = Ray(), Vector pos = Vector(), Vector normal = Vector(), bool is_valid = false)
- : ray(ray), pos(pos), normal(normal), is_valid(is_valid) { }
- };
- struct Light {
- enum LightType {Ambient, Directional, Point, Spot} type;
- Vector pos, dir;
- Color color;
- float spot_cutoff;
- };
- struct Material {
- virtual ~Material() { }
- virtual Color getColor(Intersection, const Light[], size_t, int) = 0;
- virtual void interact(Photon photon, Intersection inter, int recursion_level) = 0;
- };
- struct Object {
- Material *mat;
- Object(Material* m) : mat(m) { }
- virtual ~Object() { }
- virtual Intersection intersectRay(Ray) = 0;
- };
- struct Scene {
- static const size_t max_obj_num = 100;
- size_t obj_num;
- Object* objs[max_obj_num];
- void AddObject(Object *o) {
- objs[obj_num++] = o;
- }
- ~Scene() {
- for(int i = 0; i != obj_num; ++i) {
- delete objs[i];
- }
- }
- static const size_t max_lgt_num = 10;
- size_t lgt_num;
- Light lgts[max_obj_num];
- void AddLight(const Light& l) {
- lgts[lgt_num++] = l;
- }
- static const Vector env_color;
- Scene() : obj_num(0) { }
- Intersection getClosestIntersection(Ray r, int* index = NULL) const {
- Intersection closest_intersection;
- float closest_intersection_dist;
- int closest_index = -1;
- for(int i = 0; i < obj_num; ++i) {
- Intersection inter = objs[i]->intersectRay(r);
- if(!inter.is_valid)
- continue;
- float dist = (inter.pos - r.origin).length();
- if(closest_index == -1 || dist < closest_intersection_dist) {
- closest_intersection = inter;
- closest_intersection_dist = dist;
- closest_index = i;
- }
- }
- if(index) {
- *index = closest_index;
- }
- return closest_intersection;
- }
- Color shootRay(Ray r, int recursion_level = 0) const {
- if(recursion_level >= 8) {
- return env_color;
- }
- int index;
- Intersection inter = getClosestIntersection(r, &index);
- if(index != -1) {
- return objs[index]->mat->getColor(inter, lgts, lgt_num, recursion_level).toneMap();
- } else {
- return env_color;
- }
- }
- void shootPhoton(Photon p, int recursion_level = 0) const {
- if(recursion_level >= 8) {
- return;
- }
- int index;
- Intersection inter = getClosestIntersection(p, &index);
- if(index != -1) {
- return objs[index]->mat->interact(p, inter, recursion_level);
- }
- }
- void shootPhotons(size_t num_per_light) const {
- for(int i = 0; i < lgt_num; ++i) {
- for(int j = 0; j < num_per_light; ++j) {
- if(lgts[i].type == Light::Point) {
- Photon p(lgts[i].color * (100.0f/num_per_light), lgts[i].pos);
- p.direction = Vector::Random().normalize();
- shootPhoton(p);
- }
- }
- }
- }
- } scene;
- const Vector Scene::env_color = Vector(135./255., 206./255., 235./255.);
- struct Camera {
- Vector pos, plane_pos, right, up;
- Camera(float fov, const Vector& eye, const Vector& target, const Vector& plane_up)
- : pos(eye - (target-eye).normalize() / (2*tan((fov*M_PI/180)/2))), plane_pos(eye)
- {
- Vector fwd = (plane_pos - pos).normalize();
- right = cross(fwd, plane_up).normalize();
- up = cross(right, fwd).normalize();
- }
- void takePicture() {
- for(int x = 0; x < Screen::height; ++x)
- for(int y = 0; y < Screen::width; ++y)
- capturePixel(x, y);
- }
- void capturePixel(float x, float y) {
- Vector pos_on_plane = Vector(
- (x - Screen::width/2) / (Screen::width/2),
- // Itt nem kell megfordítani az y tengelyt. A bal fölső sarok az origó most.
- (y - Screen::height/2) / (Screen::height/2),
- 0
- );
- Vector plane_intersection = plane_pos + pos_on_plane.x * right + pos_on_plane.y * up;
- Ray r = Ray(pos, (plane_intersection - pos).normalize());
- Screen::Pixel(x, y) = scene.shootRay(r);
- }
- } camera(60, Vector(-1.2f, 1.5f, -1.5f), Vector(), Vector(0, 1, 0));
- // Idáig egy általános raytracert definiáltam. Innentől jönnek a konkrétumok.
- struct DiffuseMaterial : public Material {
- Color diffuse_color;
- DiffuseMaterial(const Color& color) : diffuse_color(color) { }
- Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
- Color accum_color;
- for(int i = 0; i < lgt_num; ++i) {
- const Light& light = lgts[i];
- switch(light.type) {
- case Light::Ambient: {
- accum_color += light.color * diffuse_color;
- } break;
- case Light::Directional: {
- // Lőjjünk egy sugarat a fényforrás irányába.
- Ray shadow_checker = Ray(inter.pos + 1e-3*light.dir, light.dir); // Az irányfény iránya nálam a forrás felé futat.
- Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker);
- if(shadow_checker_int.is_valid) {
- break; // Ha bármivel is ütközik, akkor árnyékban vagyunk
- }
- float intensity = max(dot(inter.normal, light.dir.normalize()), 0.0f);
- accum_color += intensity * light.color * diffuse_color;
- } break;
- case Light::Spot: {
- Vector light_to_pos = inter.pos - light.pos;
- if(dot(light_to_pos.normalize(), light.dir) < light.spot_cutoff) {
- break; // Ha nincs megvilágítva, akkor ne csináljuk semmit.
- } // Különben számoljuk pont fényforrással.
- } // NINCS break!
- case Light::Point: {
- // Lőjjünk egy sugarat a fényforrás felől a konkrét pont irányába
- Ray shadow_checker = Ray(light.pos, (inter.pos - light.pos).normalize());
- Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker);
- if(shadow_checker_int.is_valid &&
- (shadow_checker_int.pos-light.pos).length() + 1e-3 < (inter.pos-light.pos).length()) {
- break; // Ha bármivel is ütközik, ami közelebb van a fényhez, mint mi, akkor árnyékban vagyunk
- }
- Vector pos_to_light = light.pos - inter.pos;
- float attenuation = pow(1/pos_to_light.length(), 2);
- float intensity = max(dot(inter.normal, pos_to_light.normalize()), 0.0f);
- accum_color += attenuation * intensity * light.color * diffuse_color;
- } break;
- }
- }
- return accum_color;
- }
- };
- inline Vector reflect(Vector I, Vector N) {
- return I - (2.0 * dot(N, I)) * N;
- }
- struct SpecularMaterial : DiffuseMaterial {
- const Color specular_color;
- const float shininess;
- SpecularMaterial(const Color& diffuse_color, const Color& specular_color, float shininess)
- : DiffuseMaterial(diffuse_color), specular_color(specular_color), shininess(shininess) { }
- Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
- Color accum_color = DiffuseMaterial::getColor(inter, lgts, lgt_num, recursion_level);
- for(int i = 0; i < lgt_num; ++i) {
- const Light& light = lgts[i];
- switch(light.type) {
- case Light::Directional: {
- // Lőjjünk egy sugarat a fényforrás irányába.
- Ray shadow_checker = Ray(inter.pos + 1e-3*light.dir, light.dir); // Az irányfény iránya nálam a forrás felé futat.
- Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker);
- if(shadow_checker_int.is_valid) {
- break; // Ha bármivel is ütközik, akkor árnyékban vagyunk
- }
- float specular_power =
- pow(
- max(0.0f, dot(
- reflect(-light.dir.normalize(), inter.normal),
- (camera.pos-inter.pos).normalize())
- ), shininess
- );
- accum_color += specular_power * light.color * specular_color;
- } break;
- case Light::Spot: {
- Vector light_to_pos = inter.pos - light.pos;
- if(dot(light_to_pos.normalize(), light.dir) < light.spot_cutoff) {
- break;
- }
- }
- case Light::Point: {
- Ray shadow_checker = Ray(light.pos, (inter.pos - light.pos).normalize());
- Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker);
- if(shadow_checker_int.is_valid &&
- (shadow_checker_int.pos-light.pos).length() + 1e-3 < (inter.pos-light.pos).length()) {
- break; // Ha bármivel is ütközik, ami közelebb van a fényhez, mint mi, akkor árnyékban vagyunk
- }
- Vector light_to_pos = inter.pos-light.pos;
- float attenuation = pow(1/light_to_pos.length(), 2);
- float specular_power =
- pow(
- max(0.0f, dot(
- reflect((light_to_pos).normalize(), inter.normal),
- (camera.pos-inter.pos).normalize())
- ), shininess
- );
- accum_color += specular_power * attenuation * light.color * specular_color;
- } break;
- default:
- break;
- }
- }
- return accum_color;
- }
- };
- struct ReflectiveMaterial : public Material {
- const Color F0;
- ReflectiveMaterial(Color n, Color k)
- : F0(((n-1)*(n-1) + k*k) /
- ((n+1)*(n+1) + k*k))
- { }
- Color F(float cosTheta) {
- return F0 + (1-F0) * pow(1-cosTheta, 5);
- }
- Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
- Ray reflected_ray;
- reflected_ray.direction = reflect(inter.ray.direction, inter.normal);
- reflected_ray.origin = inter.pos + 1e-3*reflected_ray.direction;
- return F(fabs(dot(-inter.ray.direction, inter.normal))) * scene.shootRay(reflected_ray, recursion_level+1);
- }
- void interact(Photon photon, Intersection inter, int recursion_level) {
- Photon reflected(photon);
- reflected.direction = reflect(inter.ray.direction, inter.normal);
- reflected.origin = inter.pos + 1e-3*reflected.direction;
- reflected.color = photon.color;
- scene.shootPhoton(reflected, recursion_level+1);
- }
- };
- inline Vector refract(Vector I, Vector N, double n) {
- double k = 1.0 - n * n * (1.0 - dot(N, I) * dot(N, I));
- if (k < 0.0) {
- return Vector();
- } else {
- return n * I - (n * dot(N, I) + sqrt(k)) * N;
- }
- }
- struct RefractiveMaterial : public ReflectiveMaterial {
- float n, n_rec;
- RefractiveMaterial(float n, Color k)
- : ReflectiveMaterial(n, k), n(n), n_rec(1 / n)
- { }
- Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
- if(dot(inter.ray.direction, inter.normal) > 0) {
- inter.normal = -inter.normal;
- }
- Ray reflected;
- reflected.direction = reflect(inter.ray.direction, inter.normal);
- reflected.origin = inter.pos + 1e-3*reflected.direction;
- Color reflectedColor, refractedColor;
- Ray refracted;
- refracted.direction = refract(inter.ray.direction, inter.normal, inter.ray.in_air ? n : n_rec);
- if(!refracted.direction.isNull()) {
- refracted.origin = inter.pos + 1e-3 * refracted.direction;
- refracted.in_air = !inter.ray.in_air;
- Color F_vec = F(dot(-inter.ray.direction, inter.normal));
- reflectedColor = F_vec * scene.shootRay(reflected, recursion_level+1);
- refractedColor = (1-F_vec) * scene.shootRay(refracted, recursion_level+1);
- } else {
- reflectedColor = scene.shootRay(reflected, recursion_level+1);
- }
- return reflectedColor + refractedColor;
- }
- void interact(Photon photon, Intersection inter, int recursion_level) {
- if(dot(inter.ray.direction, inter.normal) > 0) {
- inter.normal = -inter.normal;
- }
- Photon reflected(photon);
- reflected.direction = reflect(photon.direction, inter.normal);
- reflected.origin = inter.pos + 1e-3*reflected.direction;
- Photon refracted(photon);
- refracted.direction = refract(photon.direction, inter.normal, photon.in_air ? n : n_rec);
- if(!refracted.direction.isNull()) {
- refracted.origin = inter.pos + 1e-3*refracted.direction;
- refracted.in_air = !photon.in_air;
- Color F_vec = F(dot(-photon.direction, inter.normal));
- reflected.color = F_vec * photon.color;
- refracted.color = (1-F_vec) * photon.color;
- scene.shootPhoton(reflected, recursion_level + 1);
- scene.shootPhoton(refracted, recursion_level + 1);
- } else {
- reflected.color = photon.color;
- scene.shootPhoton(reflected, recursion_level + 1);
- }
- }
- };
- struct UVMap {
- virtual void getTexcoord(const Vector&, float*, float*) = 0;
- ~UVMap() {}
- };
- struct GroundUVMap : public UVMap {
- Vector ground_center;
- size_t tex_size, ground_size;
- GroundUVMap(size_t tex_size, size_t ground_size, Vector ground_center = Vector())
- : ground_center(ground_center), tex_size(tex_size), ground_size(ground_size) { }
- void getTexcoord(const Vector& pos, float* u, float* v) {
- *u = (pos.x - ground_center.x + ground_size/2) * tex_size / ground_size;
- *v = (pos.z - ground_center.z + ground_size/2) * tex_size / ground_size;
- }
- };
- template <size_t size>
- struct PhotonMappedMaterial : public SpecularMaterial {
- public:
- Color photon_map[size][size];
- UVMap* uvmap;
- PhotonMappedMaterial(UVMap* uvmap, const Color& diffuse_color, const Color& specular_color, float shininess)
- : SpecularMaterial(diffuse_color, specular_color, shininess), uvmap(uvmap) { }
- Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
- float u, v;
- uvmap->getTexcoord(inter.pos, &u, &v);
- size_t iu = u, iv = v;
- const float fu = u-iu, fv = v-iv, cu = 1-fu, cv = 1-fv;
- Color bilinear_sample;
- if(iu+1 <= size-1 && iv+1 <= size-1) {
- bilinear_sample = cu*cv*photon_map[iu][iv] + fu*cv*photon_map[iu+1][iv] +
- cu*fv*photon_map[iu][iv+1] + fu*fv*photon_map[iu+1][iv+1];
- } else {
- bilinear_sample = photon_map[iu][iv];
- }
- Color spec = SpecularMaterial::getColor(inter, lgts, lgt_num, recursion_level);
- return spec + DiffuseMaterial::diffuse_color * (bilinear_sample);
- }
- void interact(Photon photon, Intersection inter, int recursion_level) {
- if(recursion_level == 0) {
- return;
- }
- float u, v;
- uvmap->getTexcoord(inter.pos, &u, &v);
- size_t iu = u, iv = v;
- const float fu = u-iu, fv = v-iv, cu = 1-fu, cv = 1-fv;
- Color color = photon.color;
- photon_map[iu][iv] += cu*cv*color;
- if(iu+1 <= size-1) {
- photon_map[iu+1][iv] += fu*cv*color;
- }
- if(iv+1 <= size-1) {
- photon_map[iu][iv+1] += cu*fv*color;
- }
- if(iu+1 <= size-1 && iv+1 <= size-1) {
- photon_map[iu+1][iv+1] += fu*fv*color;
- }
- }
- };
- GroundUVMap groundUV(64, 20, Vector(0, -1.1f, 0));
- PhotonMappedMaterial<64> photonMapped(&groundUV, Color(1, 1, 1), Color(4, 4, 4), 32);
- ReflectiveMaterial silver(Color(0.14, 0.16, 0.13), Color(4.1, 2.3, 3.1));
- ReflectiveMaterial copper(Color(0.2, 1.1, 1.2), Color(3.6, 2.6, 2.3));
- RefractiveMaterial glass(1.5, 0);
- struct Triangle : public Object {
- Vector a, b, c, normal;
- // Az óra járásával ellentétes (CCW) körüljárási irányt feltételez ez a kód.
- Triangle(Material* mat, const Vector& a, const Vector& b, const Vector& c)
- : Object(mat), a(a), b(b), c(c) {
- Vector ab = b - a;
- Vector ac = c - a;
- normal = cross(ab.normalize(), ac.normalize()).normalize();
- }
- // Ennek a függvénynek a megértéséhez rajzolj magadnak egyszerű ábrákat!
- Intersection intersectRay(Ray r) {
- // Először számoljuk ki, hogy melyen mekkora távot
- // tesz meg a sugár, míg eléri a háromszög síkját
- // A számoláshoz tudnuk kell hogy ha egy 'v' vektort
- // skaliráisan szorzunk egy egységvektorral, akkor
- // az eredmény a 'v'-nek az egységvektorra vetített
- // hossza lesz. Ezt felhasználva, ha a sugár kiindulási
- // pontjából a sík egy pontjba mutató vektort levetítjük
- // a sík normál vektorára, akkor megkapjuk, hogy milyen
- // távol van a sugár kiindulási pontja a síktól. Továbbá,
- // ha az a sugár irányát vetítjük a normálvektorra, akkor meg
- // megtudjuk, hogy az milyen gyorsan halad a sík fele.
- // Innen a már csak a t = s / v képletet kell csak használnunk.
- float ray_travel_dist = dot(a - r.origin, normal) / dot(r.direction, normal);
- // Ha a háromszög az ellenkező irányba van, mint
- // amerre a sugár megy, akkor nincs metszéspontjuk
- if(ray_travel_dist < 0)
- return Intersection();
- // Számoljuk ki, hogy a sugár hol metszi a sugár síkját.
- Vector plane_intersection = r.origin + ray_travel_dist * r.direction;
- /* Most már csak el kell döntenünk, hogy ez a pont a háromszög
- belsejében van-e. Erre két lehetőség van:
- - A háromszög összes élére megnézzük, hogy a pontot a hároszög
- egy megfelelő pontjával összekötve a kapott szakasz, és a háromszög
- élének a vektoriális szorzata a normál irányába mutat-e.
- Pl:
- a
- / |
- / |
- / |
- / x | y
- / |
- b------c
- Nézzük meg az x és y pontra ezt az algoritmust.
- A cross(ab, ax), a cross(bc, bx), és a cross(ca, cx) és kifele mutat a
- képernyőből, ugyan abba az irányba mint a normál vektor. Ezt amúgy a
- dot(cross(ab, ax), normal) >= 0 összefüggéssel egyszerű ellenőrizni.
- Az algoritmus alapján az x a háromszög belsejében van.
- Míg az y esetében a cross(ca, cy) befele mutat, a normállal ellenkező irányba,
- tehát a dot(cross(ca, cy), normal) < 0 ami az algoritmus szerint azt jelenti,
- hogy az y pont a háromszögön kívül van.
- - A ötlet lehetőség a barycentrikus koordinátáknak azt a tulajdonságát használja
- ki, hogy azok a háromszög belsejében lévő pontokra kivétel nélkül nem negatívak,
- míg a háromszögön kívül lévő pontokra legalább egy koordináta negatív.
- Ennek a megoldásnak a használatához ki kell jelölnünk két tetszőleges, de egymásra
- merőleges vektort a síkon, ezekre le kell vetíteninünk a háromszög pontjait, és
- kérdéses pontot, és az így kapott koordinátákra alakzmanunk kell egy a wikipediáról
- egyszerűen kimásolható képletet:
- http://en.wikipedia.org/wiki/Barycentric_coordinate_system#Converting_to_barycentric_coordinates
- Én az első lehetőséget implementálom. */
- const Vector& x = plane_intersection;
- Vector ab = b - a;
- Vector ax = x - a;
- Vector bc = c - b;
- Vector bx = x - b;
- Vector ca = a - c;
- Vector cx = x - c;
- if(dot(cross(ab, ax), normal) >= 0)
- if(dot(cross(bc, bx), normal) >= 0)
- if(dot(cross(ca, cx), normal) >= 0)
- return Intersection(r, x, normal, true);
- return Intersection();
- }
- };
- void onInitialization() {
- Light amb = {Light::Ambient, Vector(), Vector(), Color(0.2f, 0.2f, 0.2f)};
- Light point = {Light::Point, Vector(-2.2f, 3.5f, 2.9f), Vector(), Color(10.0f, 40.0f, 40.0f)};
- Light point2 = {Light::Point, Vector(1.3f, 1.4f, 1.7f), Vector(), Color(10.0f, 10.0f, 5.0f)};
- Light point3 = {Light::Point, Vector(0.0f, 1.6f, 0.0f), Vector(), Color(5.0f, 5.0f, 5.0f)};
- scene.AddLight(amb);
- scene.AddLight(point);
- scene.AddLight(point2);
- scene.AddLight(point3);
- // Ground
- scene.AddObject(new Triangle(&photonMapped, Vector(-10, -1.1f, -10), Vector(-10, -1.1f, +10), Vector(+10, -1.1f, +10)));
- scene.AddObject(new Triangle(&photonMapped, Vector(+10, -1.1f, +10), Vector(+10, -1.1f, -10), Vector(-10, -1.1f, -10)));
- // Front face
- scene.AddObject(new Triangle(&glass, Vector(+1, -1, -1), Vector(-1, -1, -1), Vector(-1, +1, -1)));
- scene.AddObject(new Triangle(&glass, Vector(-1, +1, -1), Vector(+1, +1, -1), Vector(+1, -1, -1)));
- // Back face
- scene.AddObject(new Triangle(&glass, Vector(+1, -1, +1), Vector(-1, -1, +1), Vector(-1, +1, +1)));
- scene.AddObject(new Triangle(&glass, Vector(-1, +1, +1), Vector(+1, +1, +1), Vector(+1, -1, +1)));
- // Right face
- scene.AddObject(new Triangle(&glass, Vector(+1, -1, -1), Vector(+1, -1, +1), Vector(+1, +1, +1)));
- scene.AddObject(new Triangle(&glass, Vector(+1, +1, +1), Vector(+1, +1, -1), Vector(+1, -1, -1)));
- // Left face
- scene.AddObject(new Triangle(&glass, Vector(-1, -1, -1), Vector(-1, -1, +1), Vector(-1, +1, +1)));
- scene.AddObject(new Triangle(&glass, Vector(-1, +1, +1), Vector(-1, +1, -1), Vector(-1, -1, -1)));
- // Upper face
- scene.AddObject(new Triangle(&glass, Vector(-1, +1, -1), Vector(-1, +1, +1), Vector(+1, +1, +1)));
- scene.AddObject(new Triangle(&glass, Vector(+1, +1, -1), Vector(-1, +1, -1), Vector(+1, +1, +1)));
- // Lower face
- scene.AddObject(new Triangle(&glass, Vector(-1, -1, +1), Vector(-1, -1, -1), Vector(+1, -1, +1)));
- scene.AddObject(new Triangle(&glass, Vector(+1, -1, -1), Vector(+1, -1, +1), Vector(-1, -1, -1)));
- scene.shootPhotons(500000);
- camera.takePicture();
- }
- void onDisplay() {
- glClear(GL_COLOR_BUFFER_BIT);
- Screen::Draw();
- glutSwapBuffers();
- }
- void onIdle() {
- static bool first_call = true;
- if(first_call) {
- glutPostRedisplay();
- first_call = false;
- }
- }
- void onKeyboard(unsigned char key, int, int) {}
- void onKeyboardUp(unsigned char key, int, int) {}
- void onMouse(int, int, int, int) {}
- void onMouseMotion(int, int) {}
- int main(int argc, char **argv) {
- glutInit(&argc, argv);
- glutInitWindowSize(Screen::width, Screen::height);
- glutInitWindowPosition(100, 100);
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
- glutCreateWindow("Grafika pelda program");
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- onInitialization();
- glutDisplayFunc(onDisplay);
- glutMouseFunc(onMouse);
- glutIdleFunc(onIdle);
- glutKeyboardFunc(onKeyboard);
- glutKeyboardUpFunc(onKeyboardUp);
- glutMotionFunc(onMouseMotion);
- glutMainLoop();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment