RohamCsiga

Vik Wiki Grafika - Üveg Kocka

Jan 29th, 2014
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.63 KB | None | 0 0
  1. #include <math.h>
  2. #include <stdlib.h>
  3.  
  4. #if defined(__APPLE__)
  5.   #include <OpenGL/gl.h>
  6.   #include <OpenGL/glu.h>
  7.   #include <GLUT/glut.h>
  8. #else
  9.   #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
  10.     #include <windows.h>
  11.   #endif
  12.   #include <GL/gl.h>
  13.   #include <GL/glu.h>
  14.   #include <GL/glut.h>
  15. #endif
  16.  
  17. #ifndef M_PI
  18.   #define M_PI 3.14159265359
  19. #endif
  20.  
  21. template <typename T>
  22. T max(T a, T b) {
  23.   return a > b ? a : b;
  24. }
  25.  
  26. template <typename T>
  27. T min(T a, T b) {
  28.   return a < b ? a : b;
  29. }
  30.  
  31. struct Vector {
  32.   union { float x, r; }; // x és r néven is lehessen hivatkozni erre a tagra.
  33.   union { float y, g; };
  34.   union { float z, b; };
  35.  
  36.   Vector(float v = 0) : x(v), y(v), z(v) { }
  37.   Vector(float x, float y, float z) : x(x), y(y), z(z) { }
  38.   Vector operator+(const Vector& v) const { return Vector(x + v.x, y + v.y, z + v.z); }
  39.   Vector operator-(const Vector& v) const { return Vector(x - v.x, y - v.y, z - v.z); }
  40.   Vector operator*(const Vector& v) const { return Vector(x * v.x, y * v.y, z * v.z); }
  41.   Vector operator/(const Vector& v) const { return Vector(x / v.x, y / v.y, z / v.z); }
  42.   Vector& operator+=(const Vector& v) { x += v.x, y += v.y, z += v.z; return *this; }
  43.   Vector& operator-=(const Vector& v) { x -= v.x, y -= v.y, z -= v.z; return *this; }
  44.   Vector& operator*=(const Vector& v) { x *= v.x, y *= v.y, z *= v.z; return *this; }
  45.   Vector& operator/=(const Vector& v) { x /= v.x, y /= v.y, z /= v.z; return *this; }
  46.   Vector operator-() const { return Vector(-x, -y, -z); }
  47.   float dot(const Vector& v) const { return x*v.x + y*v.y + z*v.z; }
  48.   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); }
  49.   float length() const { return sqrt(x*x + y*y + z*z); }
  50.   Vector normalize() const { float l = length(); if(l > 1e-3) { return (*this/l); } else { return Vector(); } }
  51.   bool isNull() const { return length() < 1e-3; }
  52.   Vector toneMap() const {
  53.     // Filmic tonemap approximation by Jim Hejl
  54.     Vector v = Vector(max(r - 0.004f, 0.0f), max(g - 0.004f, 0.0f), max(b - 0.004f, 0.0f));
  55.     v = (v*(v*6.2f+0.5f))/(v*(v*6.2f+1.7f)+0.06f);
  56.     return Vector(pow(v.x, 2.2f), pow(v.y, 2.2f), pow(v.z, 2.2f));
  57.   }
  58. };
  59.  
  60. // Azoknak, akik a shader kódokban használt szintakszishoz hozzá vannak szokva (mint pl. én)
  61. inline float dot(const Vector& lhs, const Vector& rhs) {
  62.   return lhs.dot(rhs);
  63. }
  64.  
  65. inline Vector cross(const Vector& lhs, const Vector& rhs) {
  66.   return lhs.cross(rhs);
  67. }
  68.  
  69. inline Vector operator+(float f, const Vector& v) {
  70.   return v+f;
  71. }
  72. inline Vector operator-(float f, const Vector& v) {
  73.   return Vector(f) - v;
  74. }
  75. inline Vector operator*(float f, const Vector& v) {
  76.   return v*f;
  77. }
  78. inline Vector operator/(float f, const Vector& v) {
  79.   return Vector(f) / v;
  80. }
  81.  
  82. typedef Vector Color;
  83.  
  84. struct Screen {
  85.   static const int width = 600;
  86.   static const int height = 600;
  87.   static Color image[width * height];
  88.   static void Draw() {
  89.     glDrawPixels(width, height, GL_RGB, GL_FLOAT, image);
  90.   }
  91.   static Color& Pixel(size_t x, size_t y) {
  92.     return image[y*width + x];
  93.   }
  94. };
  95. Color Screen::image[width * height]; // A statikus adattagat out-of-line példányosítani kell (kivéve az inteket és enumokat).
  96.  
  97. struct Ray {
  98.   Vector origin, direction;
  99.   bool in_air;
  100.   Ray(Vector origin = Vector(), Vector direction = Vector(), bool in_air = true)
  101.     : origin(origin), direction(direction.normalize()), in_air(in_air) { }
  102. };
  103.  
  104. struct Intersection {
  105.   Ray ray;
  106.   Vector pos, normal;
  107.   bool is_valid;
  108.   Intersection(Ray ray = Ray(), Vector pos = Vector(), Vector normal = Vector(), bool is_valid = false)
  109.     : ray(ray), pos(pos), normal(normal), is_valid(is_valid) { }
  110. };
  111.  
  112. struct Light {
  113.   enum LightType {Ambient, Directional, Point, Spot} type;
  114.   Vector pos, dir;
  115.   Color color;
  116.   float spot_cutoff;
  117. };
  118.  
  119. struct Material {
  120.   virtual ~Material() { }
  121.   virtual Color getColor(Intersection, const Light[], size_t, int) = 0;
  122. };
  123.  
  124. struct Object {
  125.   Material *mat;
  126.   Object(Material* m) : mat(m) { }
  127.   virtual ~Object() { }
  128.   virtual Intersection intersectRay(Ray) = 0;
  129. };
  130.  
  131. struct Scene {
  132.   static const size_t max_obj_num = 100;
  133.   size_t obj_num;
  134.   Object* objs[max_obj_num];
  135.  
  136.   void AddObject(Object *o) {
  137.     objs[obj_num++] = o;
  138.   }
  139.  
  140.   ~Scene() {
  141.     for(int i = 0; i != obj_num; ++i) {
  142.       delete objs[i];
  143.     }
  144.   }
  145.  
  146.   static const size_t max_lgt_num = 10;
  147.   size_t lgt_num;
  148.   Light lgts[max_obj_num];
  149.  
  150.   void AddLight(const Light& l) {
  151.     lgts[lgt_num++] = l;
  152.   }
  153.  
  154.   static const Vector env_color;
  155.  
  156.   Scene() : obj_num(0) { }
  157.  
  158.   Intersection getClosestIntersection(Ray r, int* index = NULL) const {
  159.     Intersection closest_intersection;
  160.     float closest_intersection_dist;
  161.     int closest_index = -1;
  162.  
  163.     for(int i = 0; i < obj_num; ++i) {
  164.       Intersection inter = objs[i]->intersectRay(r);
  165.       if(!inter.is_valid)
  166.         continue;
  167.       float dist = (inter.pos - r.origin).length();
  168.       if(closest_index == -1 || dist < closest_intersection_dist) {
  169.         closest_intersection = inter;
  170.         closest_intersection_dist = dist;
  171.         closest_index = i;
  172.       }
  173.     }
  174.  
  175.     if(index) {
  176.       *index = closest_index;
  177.     }
  178.     return closest_intersection;
  179.   }
  180.  
  181.   Color shootRay(Ray r, int recursion_level = 0) const {
  182.     if(recursion_level >= 8) {
  183.       return env_color;
  184.     }
  185.  
  186.     int index;
  187.     Intersection inter = getClosestIntersection(r, &index);
  188.  
  189.     if(index != -1) {
  190.       return objs[index]->mat->getColor(inter, lgts, lgt_num, recursion_level).toneMap();
  191.     } else {
  192.       return env_color;
  193.     }
  194.   }
  195. } scene;
  196. const Vector Scene::env_color = Vector(135./255., 206./255., 235./255.);
  197.  
  198. struct Camera {
  199.   Vector pos, plane_pos, right, up;
  200.  
  201.   Camera(float fov, const Vector& eye, const Vector& target, const Vector& plane_up)
  202.       : pos(eye - (target-eye).normalize() / (2*tan((fov*M_PI/180)/2))), plane_pos(eye)
  203.    {
  204.       Vector fwd = (plane_pos - pos).normalize();
  205.       right = cross(fwd, plane_up).normalize();
  206.       up = cross(right, fwd).normalize();
  207.    }
  208.  
  209.   void takePicture() {
  210.     for(int x = 0; x < Screen::height; ++x)
  211.       for(int y = 0; y < Screen::width; ++y)
  212.         capturePixel(x, y);
  213.   }
  214.  
  215.   void capturePixel(float x, float y) {
  216.     Vector pos_on_plane = Vector(
  217.       (x - Screen::width/2) / (Screen::width/2),
  218.       // Itt nem kell megfordítani az y tengelyt. A bal fölső sarok az origó most.
  219.       (y - Screen::height/2) / (Screen::height/2),
  220.       0
  221.     );
  222.  
  223.     Vector plane_intersection = plane_pos + pos_on_plane.x * right + pos_on_plane.y * up;
  224.  
  225.     Ray r = Ray(pos, (plane_intersection - pos).normalize());
  226.     Screen::Pixel(x, y) = scene.shootRay(r);
  227.   }
  228. } camera(60, Vector(-1.2f, 1.5f, -1.5f), Vector(), Vector(0, 1, 0));
  229.  
  230. // Idáig egy általános raytracert definiáltam. Innentől jönnek a konkrétumok.
  231.  
  232. struct DiffuseMaterial : public Material {
  233.   Color own_color;
  234.  
  235.   DiffuseMaterial(const Color& color) : own_color(color) { }
  236.  
  237.   Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
  238.     Color accum_color;
  239.  
  240.     for(int i = 0; i < lgt_num; ++i) {
  241.       const Light& light = lgts[i];
  242.  
  243.       switch(light.type) {
  244.         case Light::Ambient: {
  245.           accum_color += light.color * own_color;
  246.         } break;
  247.         case Light::Directional: {
  248.           // Lőjjünk egy sugarat a fényforrás irányába.
  249.           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.
  250.           Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker);
  251.           if(shadow_checker_int.is_valid) {
  252.             break; // Ha bármivel is ütközik, akkor árnyékban vagyunk
  253.           }
  254.  
  255.           float intensity = max(dot(inter.normal, light.dir.normalize()), 0.0f);
  256.           accum_color += intensity * light.color * own_color;
  257.         } break;
  258.         case Light::Spot: {
  259.           Vector light_to_pos = inter.pos - light.pos;
  260.           if(dot(light_to_pos.normalize(), light.dir) < light.spot_cutoff) {
  261.             break; // Ha nincs megvilágítva, akkor ne csináljuk semmit.
  262.           } // Különben számoljuk pont fényforrással.
  263.         } // NINCS break!
  264.         case Light::Point: {
  265.           // Lőjjünk egy sugarat a fényforrás felől a konkrét pont irányába
  266.           Ray shadow_checker = Ray(light.pos, (inter.pos - light.pos).normalize());
  267.           Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker);
  268.           if(shadow_checker_int.is_valid &&
  269.             (shadow_checker_int.pos-light.pos).length() + 1e-3 < (inter.pos-light.pos).length()) {
  270.             break; // Ha bármivel is ütközik, ami közelebb van a fényhez, mint mi, akkor árnyékban vagyunk
  271.           }
  272.  
  273.           Vector pos_to_light = light.pos - inter.pos;
  274.           float attenuation = pow(1/pos_to_light.length(), 2);
  275.           float intensity = max(dot(inter.normal, pos_to_light.normalize()), 0.0f);
  276.           accum_color += attenuation * intensity * light.color * own_color;
  277.         } break;
  278.       }
  279.     }
  280.  
  281.     return accum_color;
  282.   }
  283. };
  284.  
  285. inline Vector reflect(Vector I, Vector N) {
  286.   return I - (2.0 * dot(N, I)) * N;
  287. }
  288.  
  289. struct SpecularMaterial : DiffuseMaterial {
  290.   const Color specular_color;
  291.   const float shininess;
  292.  
  293.   SpecularMaterial(const Color& diffuse_color, const Color& specular_color, float shininess)
  294.     : DiffuseMaterial(diffuse_color), specular_color(specular_color), shininess(shininess) { }
  295.  
  296.   Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
  297.     Color accum_color = DiffuseMaterial::getColor(inter, lgts, lgt_num, recursion_level);
  298.  
  299.     for(int i = 0; i < lgt_num; ++i) {
  300.       const Light& light = lgts[i];
  301.  
  302.       switch(light.type) {
  303.         case Light::Directional: {
  304.           // Lőjjünk egy sugarat a fényforrás irányába.
  305.           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.
  306.           Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker);
  307.           if(shadow_checker_int.is_valid) {
  308.             break; // Ha bármivel is ütközik, akkor árnyékban vagyunk
  309.           }
  310.  
  311.           float specular_power =
  312.             pow(
  313.               max(0.0f, dot(
  314.                 reflect(-light.dir.normalize(), inter.normal),
  315.                 (camera.pos-inter.pos).normalize())
  316.               ), shininess
  317.             );
  318.           accum_color += specular_power * light.color * specular_color;
  319.         } break;
  320.         case Light::Spot: {
  321.           Vector light_to_pos = inter.pos - light.pos;
  322.           if(dot(light_to_pos.normalize(), light.dir) < light.spot_cutoff) {
  323.             break;
  324.           }
  325.         }
  326.         case Light::Point: {
  327.           Ray shadow_checker = Ray(light.pos, (inter.pos - light.pos).normalize());
  328.           Intersection shadow_checker_int = scene.getClosestIntersection(shadow_checker);
  329.           if(shadow_checker_int.is_valid &&
  330.             (shadow_checker_int.pos-light.pos).length() + 1e-3 < (inter.pos-light.pos).length()) {
  331.             break; // Ha bármivel is ütközik, ami közelebb van a fényhez, mint mi, akkor árnyékban vagyunk
  332.           }
  333.  
  334.           Vector light_to_pos = inter.pos-light.pos;
  335.           float attenuation = pow(1/light_to_pos.length(), 2);
  336.  
  337.           float specular_power =
  338.             pow(
  339.               max(0.0f, dot(
  340.                 reflect((light_to_pos).normalize(), inter.normal),
  341.                 (camera.pos-inter.pos).normalize())
  342.               ), shininess
  343.             );
  344.           accum_color += specular_power * attenuation * light.color * specular_color;
  345.         } break;
  346.         default:
  347.           break;
  348.       }
  349.     }
  350.  
  351.     return accum_color;
  352.   }
  353. };
  354.  
  355. struct MirrorMaterial : public Material {
  356.   Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
  357.     Ray reflected_ray;
  358.     reflected_ray.direction = reflect(inter.ray.direction, inter.normal);
  359.     reflected_ray.origin = inter.pos + 1e-3*reflected_ray.direction;
  360.     return scene.shootRay(reflected_ray, recursion_level+1);
  361.   }
  362. };
  363.  
  364. struct ReflectiveMaterial : public Material {
  365.   const Color F0;
  366.  
  367.   ReflectiveMaterial(Color n, Color k)
  368.     : F0(((n-1)*(n-1) + k*k) /
  369.          ((n+1)*(n+1) + k*k))
  370.   { }
  371.  
  372.   Color F(float cosTheta) {
  373.       return F0 + (1-F0) * pow(1-cosTheta, 5);
  374.   }
  375.  
  376.   Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
  377.     Ray reflected_ray;
  378.     reflected_ray.direction = reflect(inter.ray.direction, inter.normal);
  379.     reflected_ray.origin = inter.pos + 1e-3*reflected_ray.direction;
  380.     return F(dot(-inter.ray.direction, inter.normal)) * scene.shootRay(reflected_ray, recursion_level+1);
  381.   }
  382. };
  383.  
  384. // http://www.opengl.org/sdk/docs/manglsl/xhtml/refract.xml
  385. inline Vector refract(Vector I, Vector N, double n) {
  386.   double k = 1.0 - n * n * (1.0 - dot(N, I) * dot(N, I));
  387.   if (k < 0.0) {
  388.     return Vector();
  389.   } else {
  390.     return n * I - (n * dot(N, I) + sqrt(k)) * N;
  391.   }
  392. }
  393.  
  394. struct RefractiveMaterial : public ReflectiveMaterial {
  395.   float n, n_rec;
  396.  
  397.   RefractiveMaterial(float n, Color k)
  398.     : ReflectiveMaterial(n, k), n(n), n_rec(1 / n)
  399.   { }
  400.  
  401.   Color getColor(Intersection inter, const Light* lgts, size_t lgt_num, int recursion_level) {
  402.     if(dot(inter.ray.direction, inter.normal) > 0) {
  403.       inter.normal = -inter.normal;
  404.     }
  405.  
  406.     Ray reflected;
  407.     reflected.direction = reflect(inter.ray.direction, inter.normal);
  408.     reflected.origin = inter.pos + 1e-3*reflected.direction;
  409.  
  410.     Color reflectedColor, refractedColor;
  411.  
  412.     Ray refracted;
  413.     refracted.direction = refract(inter.ray.direction, inter.normal, inter.ray.in_air ? n : n_rec);
  414.     if(!refracted.direction.isNull()) {
  415.       refracted.origin = inter.pos + 1e-3 * refracted.direction;
  416.       refracted.in_air = !inter.ray.in_air;
  417.  
  418.       Color F_vec = F(dot(-inter.ray.direction, inter.normal));
  419.       reflectedColor = F_vec * scene.shootRay(reflected, recursion_level+1);
  420.       refractedColor = (1 - F_vec) * scene.shootRay(refracted, recursion_level+1);
  421.     } else {
  422.       reflectedColor = scene.shootRay(reflected, recursion_level+1);
  423.     }
  424.  
  425.     return reflectedColor + refractedColor;
  426.   }
  427. };
  428.  
  429. DiffuseMaterial white(Color(1.0f));
  430. DiffuseMaterial blue(Color(0.0f, 0.4f, 1.0f));
  431. SpecularMaterial specular_white(Color(1.0f), Color(3.0f), 32);
  432. SpecularMaterial specular_blue(Color(0.0f, 0.4f, 1.0f), Color(1.0f), 64);
  433. MirrorMaterial mirror;
  434. ReflectiveMaterial silver(Color(0.14, 0.16, 0.13), Color(4.1, 2.3, 3.1));
  435. ReflectiveMaterial copper(Color(0.2, 1.1, 1.2), Color(3.6, 2.6, 2.3));
  436. RefractiveMaterial glass(1.5f, 0);
  437.  
  438. struct Triangle : public Object {
  439.   Vector a, b, c, normal;
  440.  
  441.   // Az óra járásával ellentétes (CCW) körüljárási irányt feltételez ez a kód.
  442.   Triangle(Material* mat, const Vector& a, const Vector& b, const Vector& c)
  443.     : Object(mat), a(a), b(b), c(c) {
  444.       Vector ab = b - a;
  445.       Vector ac = c - a;
  446.       normal = cross(ab.normalize(), ac.normalize()).normalize();
  447.   }
  448.  
  449.   // Ennek a függvénynek a megértéséhez rajzolj magadnak egyszerű ábrákat!
  450.   Intersection intersectRay(Ray r) {
  451.     // Először számoljuk ki, hogy melyen mekkora távot
  452.     // tesz meg a sugár, míg eléri a háromszög síkját
  453.     // A számoláshoz tudnuk kell hogy ha egy 'v' vektort
  454.     // skaliráisan szorzunk egy egységvektorral, akkor
  455.     // az eredmény a 'v'-nek az egységvektorra vetített
  456.     // hossza lesz. Ezt felhasználva, ha a sugár kiindulási
  457.     // pontjából a sík egy pontjba mutató vektort levetítjük
  458.     // a sík normál vektorára, akkor megkapjuk, hogy milyen
  459.     // távol van a sugár kiindulási pontja a síktól. Továbbá,
  460.     // ha az a sugár irányát vetítjük a normálvektorra, akkor meg
  461.     // megtudjuk, hogy az milyen gyorsan halad a sík fele.
  462.     // Innen a már csak a t = s / v képletet kell csak használnunk.
  463.     float ray_travel_dist = dot(a - r.origin, normal) / dot(r.direction, normal);
  464.  
  465.     // Ha a háromszög az ellenkező irányba van, mint
  466.     // amerre a sugár megy, akkor nincs metszéspontjuk
  467.     if(ray_travel_dist < 0)
  468.       return Intersection();
  469.  
  470.     // Számoljuk ki, hogy a sugár hol metszi a sugár síkját.
  471.     Vector plane_intersection = r.origin + ray_travel_dist * r.direction;
  472.  
  473.     /* Most már csak el kell döntenünk, hogy ez a pont a háromszög
  474.        belsejében van-e. Erre két lehetőség van:
  475.      
  476.        - A háromszög összes élére megnézzük, hogy a pontot a hároszög
  477.        egy megfelelő pontjával összekötve a kapott szakasz, és a háromszög
  478.        élének a vektoriális szorzata a normál irányába mutat-e.
  479.        Pl:
  480.      
  481.                  a
  482.                / |
  483.               /  |
  484.              /   |
  485.             /  x |  y
  486.            /     |
  487.           b------c
  488.  
  489.        Nézzük meg az x és y pontra ezt az algoritmust.
  490.        A cross(ab, ax), a cross(bc, bx), és a cross(ca, cx) és kifele mutat a
  491.        képernyőből, ugyan abba az irányba mint a normál vektor. Ezt amúgy a
  492.        dot(cross(ab, ax), normal) >= 0 összefüggéssel egyszerű ellenőrizni.
  493.        Az algoritmus alapján az x a háromszög belsejében van.
  494.  
  495.        Míg az y esetében a cross(ca, cy) befele mutat, a normállal ellenkező irányba,
  496.        tehát a dot(cross(ca, cy), normal) < 0 ami az algoritmus szerint azt jelenti,
  497.        hogy az y pont a háromszögön kívül van.
  498.      
  499.        - A ötlet lehetőség a barycentrikus koordinátáknak azt a tulajdonságát használja
  500.        ki, hogy azok a háromszög belsejében lévő pontokra kivétel nélkül nem negatívak,
  501.        míg a háromszögön kívül lévő pontokra legalább egy koordináta negatív.
  502.        Ennek a megoldásnak a használatához ki kell jelölnünk két tetszőleges, de egymásra
  503.        merőleges vektort a síkon, ezekre le kell vetíteninünk a háromszög pontjait, és
  504.        kérdéses pontot, és az így kapott koordinátákra alakzmanunk kell egy a wikipediáról
  505.        egyszerűen kimásolható képletet:
  506.        http://en.wikipedia.org/wiki/Barycentric_coordinate_system#Converting_to_barycentric_coordinates
  507.      
  508.        Én az első lehetőséget implementálom. */
  509.  
  510.     const Vector& x = plane_intersection;
  511.  
  512.     Vector ab = b - a;
  513.     Vector ax = x - a;
  514.  
  515.     Vector bc = c - b;
  516.     Vector bx = x - b;
  517.  
  518.     Vector ca = a - c;
  519.     Vector cx = x - c;
  520.  
  521.     if(dot(cross(ab, ax), normal) >= 0)
  522.       if(dot(cross(bc, bx), normal) >= 0)
  523.         if(dot(cross(ca, cx), normal) >= 0)
  524.           return Intersection(r, x, normal, true);
  525.  
  526.     return Intersection();
  527.   }
  528. };
  529.  
  530. void onDisplay() {
  531.   glClear(GL_COLOR_BUFFER_BIT);
  532.  
  533.   camera.takePicture();
  534.   Screen::Draw();
  535.  
  536.   glutSwapBuffers();
  537. }
  538.  
  539. void onIdle() {
  540.   static bool first_call = true;
  541.   if(first_call) {
  542.     glutPostRedisplay();
  543.     first_call = false;
  544.   }
  545. }
  546.  
  547. void onInitialization() {
  548.   Light amb = {Light::Ambient, Vector(), Vector(), Color(0.2f, 0.2f, 0.2f)};
  549.   Light point = {Light::Point, Vector(1.5f, 2, 1), Vector(), 0.5f*Color(20.0f, 20.0f, 20.0f)};
  550.   Light point2 = {Light::Point, Vector(-3.2f, 4, 4.5f), Vector(), 0.4f*Color(20.0f, 20.0f, 20.0f)};
  551.   scene.AddLight(amb);
  552.   scene.AddLight(point);
  553.   scene.AddLight(point2);
  554.  
  555.   // Ground
  556.   scene.AddObject(new Triangle(&specular_white, Vector(-10, -1.1f, -10), Vector(-10, -1.1f, +10), Vector(+10, -1.1f, +10)));
  557.   scene.AddObject(new Triangle(&specular_white, Vector(+10, -1.1f, +10), Vector(+10, -1.1f, -10), Vector(-10, -1.1f, -10)));
  558.  
  559.   // Front face
  560.   scene.AddObject(new Triangle(&glass, Vector(+1, -1, -1), Vector(-1, -1, -1), Vector(-1, +1, -1)));
  561.   scene.AddObject(new Triangle(&glass, Vector(-1, +1, -1), Vector(+1, +1, -1), Vector(+1, -1, -1)));
  562.  
  563.   // Back face
  564.   scene.AddObject(new Triangle(&glass, Vector(+1, -1, +1), Vector(-1, -1, +1), Vector(-1, +1, +1)));
  565.   scene.AddObject(new Triangle(&glass, Vector(-1, +1, +1), Vector(+1, +1, +1), Vector(+1, -1, +1)));
  566.  
  567.   // Right face
  568.   scene.AddObject(new Triangle(&glass, Vector(+1, -1, -1), Vector(+1, -1, +1), Vector(+1, +1, +1)));
  569.   scene.AddObject(new Triangle(&glass, Vector(+1, +1, +1), Vector(+1, +1, -1), Vector(+1, -1, -1)));
  570.  
  571.   // Left face
  572.   scene.AddObject(new Triangle(&glass, Vector(-1, -1, -1), Vector(-1, -1, +1), Vector(-1, +1, +1)));
  573.   scene.AddObject(new Triangle(&glass, Vector(-1, +1, +1), Vector(-1, +1, -1), Vector(-1, -1, -1)));
  574.  
  575.   // Upper face
  576.   scene.AddObject(new Triangle(&glass, Vector(-1, +1, -1), Vector(-1, +1, +1), Vector(+1, +1, +1)));
  577.   scene.AddObject(new Triangle(&glass, Vector(+1, +1, -1), Vector(-1, +1, -1), Vector(+1, +1, +1)));
  578.  
  579.   // Lower face
  580.   scene.AddObject(new Triangle(&glass, Vector(-1, -1, +1), Vector(-1, -1, -1), Vector(+1, -1, +1)));
  581.   scene.AddObject(new Triangle(&glass, Vector(+1, -1, -1), Vector(+1, -1, +1), Vector(-1, -1, -1)));
  582. }
  583.  
  584. void onKeyboard(unsigned char key, int, int) {}
  585.  
  586. void onKeyboardUp(unsigned char key, int, int) {}
  587.  
  588. void onMouse(int, int, int, int) {}
  589.  
  590. void onMouseMotion(int, int) {}
  591.  
  592. int main(int argc, char **argv) {
  593.   glutInit(&argc, argv);
  594.   glutInitWindowSize(Screen::width, Screen::height);
  595.   glutInitWindowPosition(100, 100);
  596.   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  597.  
  598.   glutCreateWindow("Grafika pelda program");
  599.  
  600.   glMatrixMode(GL_MODELVIEW);
  601.   glLoadIdentity();
  602.   glMatrixMode(GL_PROJECTION);
  603.   glLoadIdentity();
  604.  
  605.   onInitialization();
  606.  
  607.   glutDisplayFunc(onDisplay);
  608.   glutMouseFunc(onMouse);
  609.   glutIdleFunc(onIdle);
  610.   glutKeyboardFunc(onKeyboard);
  611.   glutKeyboardUpFunc(onKeyboardUp);
  612.   glutMotionFunc(onMouseMotion);
  613.  
  614.   glutMainLoop();
  615.  
  616.   return 0;
  617. }
Advertisement
Add Comment
Please, Sign In to add comment