SHARE
TWEET

Grafika masodik hazi

Sa2x Jul 23rd, 2019 88 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2.  
  3. //=============================================================================================
  4. // Mintaprogram: Z�ld h�romsz�g. Ervenyes 2018. osztol.
  5. //
  6. // A beadott program csak ebben a fajlban lehet, a fajl 1 byte-os ASCII karaktereket tartalmazhat, BOM kihuzando.
  7. // Tilos:
  8. // - mast "beincludolni", illetve mas konyvtarat hasznalni
  9. // - faljmuveleteket vegezni a printf-et kiveve
  10. // - Mashonnan atvett programresszleteket forrasmegjeloles nelkul felhasznalni es
  11. // - felesleges programsorokat a beadott programban hagyni!!!!!!!
  12. // - felesleges kommenteket a beadott programba irni a forrasmegjelolest kommentjeit kiveve
  13. // ---------------------------------------------------------------------------------------------
  14. // A feladatot ANSI C++ nyelvu forditoprogrammal ellenorizzuk, a Visual Studio-hoz kepesti elteresekrol
  15. // es a leggyakoribb hibakrol (pl. ideiglenes objektumot nem lehet referencia tipusnak ertekul adni)
  16. // a hazibeado portal ad egy osszefoglalot.
  17. // ---------------------------------------------------------------------------------------------
  18. // A feladatmegoldasokban csak olyan OpenGL fuggvenyek hasznalhatok, amelyek az oran a feladatkiadasig elhangzottak
  19. // A keretben nem szereplo GLUT fuggvenyek tiltottak.
  20. //
  21. // NYILATKOZAT
  22. // ---------------------------------------------------------------------------------------------
  23. // Nev    : Balint Sandor
  24. // Neptun : UTHQB2
  25. // ---------------------------------------------------------------------------------------------
  26. // ezennel kijelentem, hogy a feladatot magam keszitettem, es ha barmilyen segitseget igenybe vettem vagy
  27. // mas szellemi termeket felhasznaltam, akkor a forrast es az atvett reszt kommentekben egyertelmuen jeloltem.
  28. // A forrasmegjeloles kotelme vonatkozik az eloadas foliakat es a targy oktatoi, illetve a
  29. // grafhazi doktor tanacsait kiveve barmilyen csatornan (szoban, irasban, Interneten, stb.) erkezo minden egyeb
  30. // informaciora (keplet, program, algoritmus, stb.). Kijelentem, hogy a forrasmegjelolessel atvett reszeket is ertem,
  31. // azok helyessegere matematikai bizonyitast tudok adni. Tisztaban vagyok azzal, hogy az atvett reszek nem szamitanak
  32. // a sajat kontribucioba, igy a feladat elfogadasarol a tobbi resz mennyisege es minosege alapjan szuletik dontes.
  33. // Tudomasul veszem, hogy a forrasmegjeloles kotelmenek megsertese eseten a hazifeladatra adhato pontokat
  34. // negativ elojellel szamoljak el es ezzel parhuzamosan eljaras is indul velem szemben.
  35. //=============================================================================================
  36.  
  37. #include "framework.h"
  38. vec3 eye = vec3(0, 0,1.5);
  39. vec3 lookat = vec3(0, 0, 0);
  40. int maxDepth = 10;
  41. int n = 3;
  42. bool INIT = true;
  43.  
  44. struct Material {
  45.     vec3 ka, kd, ks;
  46.     float  shininess;
  47.     vec3 F0;
  48.     vec3 n, kappa;
  49.     bool rough, reflective = false;
  50.     Material(vec3 _kd, vec3 _ks, float _shininess) : ka(_kd * M_PI), kd(_kd), ks(_ks) { shininess = _shininess; }
  51. };
  52.  
  53. struct Hit {
  54.     float t;
  55.     vec3 position, normal;
  56.     vec3 n;
  57.     vec3 kappa;
  58.     Material * material;
  59.     Hit() { t = -1; }
  60. };
  61.  
  62. struct Ray {
  63.     vec3 start, dir;
  64.     Ray(vec3 _start, vec3 _dir) { start = _start; dir = normalize(_dir); }
  65. };
  66.  
  67. class Intersectable {
  68. protected:
  69.     Material * material;
  70.    
  71. public:
  72.     virtual Hit intersect(const Ray& ray) = 0;
  73.    
  74. };
  75.  
  76.  
  77.  
  78. class Ellipsoid :public Intersectable {
  79.    
  80.     vec3 params;
  81.     bool reflective;
  82. public:
  83.     vec3 Centre;
  84.     Ellipsoid(vec3 c, vec3 p, Material* m) {
  85.        
  86.         Centre = c;
  87.         params = p;
  88.         material = m;
  89.        
  90.     }
  91.  
  92.    
  93.    
  94.  
  95.    
  96.     virtual Hit intersect(const Ray & ray) override
  97.     {
  98.         Hit hit;
  99.         float sx = ray.start.x;
  100.         float sy = ray.start.y;
  101.         float sz = ray.start.z;
  102.         float dx = ray.dir.x;
  103.         float dy = ray.dir.y;
  104.         float dz = ray.dir.z;
  105.  
  106.         float a = (dx *dx) *(params.y *params.y) *(params.z *params.z) + (dy *dy) *(params.x *params.x) *(params.z *params.z) + (dz *dz) *(params.x *params.x) *(params.y *params.y);
  107.         float b = 2 * (params.y *params.y) *(params.z *params.z) *((sx - Centre.x)*dx) + 2 * (params.x *params.x) *(params.z *params.z) *((sy - Centre.y)*dy) + 2 * (params.x *params.x) *(params.y *params.y) *((sz - Centre.z)*dz);
  108.         float c = (sx - Centre.x)*(sx - Centre.x)*(params.y*params.y)*(params.z * params.z) + (sy - Centre.y)*(sy - Centre.y)*(params.x*params.x)*(params.z * params.z) + (sz - Centre.z)*(sz - Centre.z)*(params.x*params.x)*(params.y * params.y) -(params.x * params.x) *(params.y * params.y) *(params.z * params.z);
  109.  
  110.         float d = b * b - 4.0f * a * c;
  111.  
  112.         if (d < 0) return hit;
  113.         float t1 = (-b + sqrt(d)) / (2.0f * a);
  114.         float t2 = (-b - sqrt(d)) / (2.0f * a);
  115.         if (t1 <= 0) return hit;
  116.        
  117.         hit.t = (t2 > 0) ? t2 : t1;
  118.         hit.position = ray.start + ray.dir * hit.t;
  119.  
  120.         vec3 N = vec3(2 * (hit.position.x - Centre.x) / (params.x *params.x), 2 * (hit.position.y - Centre.y) / ( params.y * params.y), 2 * (hit.position.z - Centre.z)/(params.z*params.z));
  121.  
  122.        
  123.         hit.normal = normalize(N);
  124.         hit.material = material;
  125.  
  126.         return hit;
  127.     }
  128.  
  129.  
  130.    
  131.    
  132.  
  133. };
  134.  
  135. class Camera {
  136.    
  137. public:
  138.     vec3 eye, lookat, right, up;
  139.     void set(vec3 _eye, vec3 _lookat, vec3 vup, double fov) {
  140.         eye = _eye;
  141.         lookat = _lookat;
  142.         vec3 w = eye - lookat;
  143.         float f = length(w);
  144.         right = normalize(cross(vup, w)) * f * tan(fov / 2);
  145.         up = normalize(cross(w, right)) * f * tan(fov / 2);
  146.     }
  147.     Ray getRay(int X, int Y) {
  148.         vec3 dir = lookat + right * (2.0 * (X + 0.5) / windowWidth - 1) + up * (2.0 * (Y + 0.5) / windowHeight - 1) - eye;
  149.         return Ray(eye, dir);
  150.     }
  151. };
  152.  
  153. struct Light {
  154.     vec3 direction;
  155.     vec3 Le;
  156.     Light(vec3 _direction, vec3 _Le) {
  157.         direction = normalize(_direction);
  158.         Le = _Le;
  159.     }
  160. };
  161.  
  162. float rnd() { return (float)rand() / RAND_MAX / 10; }
  163.  
  164. const float epsilon = 0.0001f;
  165. class Glass : public Intersectable {
  166.    
  167.     vec3 A;
  168.     vec3 B;
  169.     vec3 C;
  170.     vec3 D;
  171.    
  172.     Material* material;
  173. public:
  174.     vec3 N;
  175.    
  176.    
  177.     Glass(vec3 _A, vec3 _D, vec3 _B, vec3 _C, Material* _material) {
  178.         A = _A;
  179.         B = _B;
  180.         C = _C;
  181.         D = _D;
  182.        
  183.         material = _material;
  184.        
  185.         material->n = vec3(0.17, 0.35, 1.5);
  186.         material->kappa = vec3(3.1, 2.7, 1.9);
  187.    
  188.        
  189.         N = cross((B - A), (C - A));
  190.         N = normalize(N);
  191.        
  192.    
  193.     }
  194.    
  195.     virtual Hit intersect(const Ray & ray) override
  196.     {
  197.         Hit hit;
  198.        
  199.         float t = (dot(A - ray.start, N) / dot(ray.dir, N) );
  200.        
  201.         if (t < 0) return hit;
  202.  
  203.        
  204.         vec3 pos = ray.start + ray.dir * t;
  205.        
  206.        
  207.         if (((dot(cross(B - A,pos - A), N)) > 0) &&
  208.             ((dot(cross(C - B,pos - B),N)) > 0) &&
  209.             ((dot(cross(D - C, pos - C), N)) > 0) &&
  210.             ((dot(cross(A - D,pos - D), N)) > 0)) {
  211.            
  212.             hit.material = material;
  213.             hit.position = pos;
  214.            
  215.             hit.normal = N;
  216.             hit.t = t;
  217.            
  218.         }
  219.         return hit;
  220.        
  221.        
  222.        
  223.     }
  224.  
  225.    
  226.  
  227. };
  228. vec3 vec3Divide (vec3 v1, vec3 v2)  { return vec3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z); }
  229. class Scene {
  230.     std::vector<Intersectable *> objects;
  231.     std::vector<Light *> lights;
  232.     std::vector<Ellipsoid*> ellipsoids;
  233.     vec3 La;
  234. public:
  235.    
  236.     Camera camera;
  237.  
  238.     void refreshPos() {
  239.         for (Ellipsoid* e : ellipsoids) {
  240.            
  241.             float ex = e->Centre.x;
  242.             float ey = e->Centre.y;
  243.            
  244.            
  245.                 float r = rnd();
  246.                 if (ex + r <= 0.2) {
  247.                     e->Centre.x += r;
  248.  
  249.                 }
  250.                 else if (ex - r >= -0.2) {
  251.                     e->Centre.x -= r;
  252.                 }
  253.                 r = rnd();
  254.                 if (ey + r <= 0.2) {
  255.                     e->Centre.y+= r;
  256.                 }
  257.                 else if (ex - r >= -0.2) {
  258.                     e->Centre.y -= r;
  259.                 }
  260.  
  261.  
  262.                
  263.         }
  264.  
  265.     }
  266. //A pont koruli adott szoggel valo forgatast stackoverflown kerestem meg.
  267.     void build() {
  268.         std::vector<Ellipsoid*> elitemp;
  269.         if (!INIT) {
  270.             objects.clear();
  271.             for (Ellipsoid* e : ellipsoids) {
  272.                 objects.push_back(e);
  273.                 elitemp.push_back(e);
  274.             }
  275.            
  276.            
  277.         }
  278.         lights.clear();
  279.        
  280.         vec3 vup = vec3(0, 1, 0);
  281.         float fov = 45 * M_PI / 180;
  282.         camera.set(eye, lookat, vup, fov);
  283.  
  284.         vec3 centre = lookat;
  285.         centre.z += 1.0f;
  286.         vec3 back_centre = lookat;
  287.         back_centre.z -= 2.0f;
  288.    
  289.  
  290.  
  291.         La = vec3(0.4f, 0.4f, 0.4f);
  292.         vec3 lightDirection(0, 0, 6), Le(2, 2, 2);
  293.         lights.push_back(new Light(lightDirection, Le));
  294.    
  295.         vec3 kd(0.3f, 0.2f, 0.1f), ks(2, 2, 2);
  296.         vec3 kd1(0.5f, 0.3f, 0.5f), ks1(2, 2, 2);
  297.         vec3 kd2(0.2f, 0.3f, 0.4f), ks2(2, 2, 2);
  298.         vec3 kd3(1.0f, 1.0f, 1.0f), ks3(2, 2, 2);
  299.        
  300.         Material * material = new Material(kd, ks, 100);
  301.         Material * material1 = new Material(kd, ks, 100);
  302.         Material * material2 = new Material(kd1, ks1, 100);
  303.         Material * material3 = new Material(kd2, ks2, 100);
  304.         Material * material4 = new Material(kd3, ks3, 100);
  305.        
  306.         material->reflective = true;
  307.         material->rough = false;
  308.         material1->reflective = false;
  309.         material1->rough = true;
  310.         material2->reflective = false;
  311.         material2->rough = true;
  312.         material3->reflective = false;
  313.         material3->rough = true;
  314.         material4->reflective = false;
  315.         material4->rough = true;
  316.        
  317.         for (int i = 0; i < n ; i++) {
  318.             float sinalfa = sinf( i * 2.0f * M_PI / n);
  319.             float cosalfa = cosf( i * 2.0f * M_PI / n);
  320.             vec3 actual;
  321.             vec3 next;
  322.             actual.x = lookat.x + 0.6*cosalfa;
  323.             actual.y = lookat.y + 0.6*sinalfa;
  324.             actual.z = centre.z;
  325.             sinalfa = sinf((i + 1) *2.0f * M_PI / n);
  326.             cosalfa = cosf((i + 1) *2.0f * M_PI / n);
  327.             next.x = lookat.x + 0.6*cosalfa;
  328.             next.y = lookat.y + 0.6*sinalfa;
  329.             next.z = centre.z;
  330.             objects.push_back(new Glass(vec3(actual.x, actual.y, centre.z), vec3(actual.x, actual.y, back_centre.z), vec3(next.x, next.y, centre.z), vec3(next.x, next.y, back_centre.z), material));
  331.  
  332.         }
  333.         if (INIT) {
  334.             Ellipsoid* e1 = new Ellipsoid(vec3(0.0f, 0.18f, back_centre.z), vec3(0.05f, 0.1f, 0.15f), material1);
  335.             Ellipsoid* e2 = new Ellipsoid(vec3(-0.1f, -0.1f, back_centre.z), vec3(0.2f, 0.15f, 0.1f), material2);
  336.             Ellipsoid* e3 = new Ellipsoid(vec3(0.18f, -0.05f, back_centre.z), vec3(0.05f, 0.1f, 0.15f), material3);
  337.             objects.push_back(e1);
  338.             objects.push_back(e2);
  339.             objects.push_back(e3);
  340.             ellipsoids.push_back(e1);
  341.             ellipsoids.push_back(e2);
  342.             ellipsoids.push_back(e3);
  343.             INIT = false;
  344.         }
  345.        
  346.        
  347.        
  348.     }
  349.  
  350.     void render(std::vector<vec4>& image) {
  351.         for (int Y = 0; Y < windowHeight; Y++) {
  352. #pragma omp parallel for
  353.             for (int X = 0; X < windowWidth; X++) {
  354.                 vec3 color = trace(camera.getRay(X, Y));
  355.                 image[Y * windowWidth + X] = vec4(color.x, color.y, color.z, 1);
  356.             }
  357.         }
  358.     }
  359.  
  360.    
  361.     Hit firstIntersect(Ray ray) {
  362.         Hit bestHit;
  363.         for (Intersectable * object : objects) {
  364.             Hit hit = object->intersect(ray);
  365.             if (hit.t > 0 && (bestHit.t < 0 || hit.t < bestHit.t))  bestHit = hit;
  366.         }
  367.         if (dot(ray.dir, bestHit.normal) > 0) bestHit.normal = bestHit.normal * (-1);
  368.         return bestHit;
  369.     }
  370.  
  371.     bool shadowIntersect(Ray ray) {
  372.         for (Intersectable * object : objects) if (object->intersect(ray).t > 0) return true;
  373.         return false;
  374.     }
  375.     vec3 Fresnel(vec3 inDir, vec3 normal, vec3 n, vec3 kappa) {
  376.         float cosa = -dot(inDir, normal);
  377.         vec3 one(1, 1, 1);
  378.         vec3 F0 = vec3Divide(((n - one) * (n - one) + kappa * kappa) ,
  379.             ((n + one) * (n + one) + kappa * kappa));
  380.         return F0 + (one - F0) * pow(1 - cosa, 5);
  381.  
  382.     }
  383.  
  384.     vec3 reflect(vec3 inDir, vec3 normal) {
  385.         inDir = normalize(inDir);
  386.         normal = normalize(normal);
  387.         return inDir - normal * dot(normal, inDir) *2.0f ;
  388.     }
  389.    
  390.    
  391.    
  392.     vec3 trace(Ray ray, int depth = 0) {
  393.         if (depth > maxDepth) return La;
  394.         Hit hit = firstIntersect(ray);
  395.         if (hit.t < 0) return La;
  396.        
  397.  
  398.         vec3 outRadiance = vec3(0, 0, 0);
  399.  
  400.         if (hit.material->rough) {
  401.            
  402.             outRadiance = hit.material->ka * La;
  403.             for (Light * light : lights) {
  404.                 vec3 v = light->direction;
  405.                
  406.                 Ray shadowRay(hit.position + hit.normal * epsilon, v);
  407.                 float cosTheta = dot(hit.normal, v);
  408.                 if (cosTheta > 0 && !shadowIntersect(shadowRay)) {
  409.                    
  410.                     outRadiance = outRadiance + light->Le * hit.material->kd * cosTheta;
  411.                     vec3 halfway = normalize(-ray.dir + v);
  412.                     float cosDelta = dot(hit.normal, halfway);
  413.                    
  414.                     if (cosDelta > 0) {
  415.                        
  416.                         outRadiance = outRadiance + light->Le * hit.material->ks * powf(cosDelta, hit.material->shininess);
  417.                        
  418.                     }
  419.                    
  420.                 }
  421.             }
  422.  
  423.         }
  424.        
  425.         if (hit.material->reflective) {
  426.            
  427.        
  428.             vec3 reflectionDir = reflect(ray.dir, hit.normal);
  429.             hit.normal = normalize(hit.normal);
  430.             Ray reflectRay(hit.position + hit.normal * epsilon, reflectionDir);
  431.            
  432.             outRadiance = outRadiance +  trace(reflectRay,depth + 1) * Fresnel(ray.dir, hit.normal, hit.material->n, hit.material->kappa);
  433.        
  434.        
  435.         }
  436.        
  437.         return outRadiance;
  438.  
  439.     }
  440.    
  441. };
  442.  
  443. GPUProgram gpuProgram;
  444. Scene scene;
  445.  
  446.  
  447.  
  448. const char *vertexSource = R"(
  449.     #version 330
  450.     precision highp float;
  451.  
  452.     layout(location = 0) in vec2 cVertexPosition;  
  453.     out vec2 texcoord;
  454.  
  455.     void main() {
  456.         texcoord = (cVertexPosition + vec2(1, 1))/2;                           
  457.         gl_Position = vec4(cVertexPosition.x, cVertexPosition.y, 0, 1);        
  458.     }
  459. )";
  460.  
  461.  
  462. const char *fragmentSource = R"(
  463.     #version 330
  464.     precision highp float;
  465.  
  466.     uniform sampler2D textureUnit;
  467.     in  vec2 texcoord;         
  468.     out vec4 fragmentColor;    
  469.  
  470.     void main() {
  471.         fragmentColor = texture(textureUnit, texcoord);
  472.     }
  473. )";
  474.  
  475. class FullScreenTexturedQuad {
  476.     unsigned int vao;  
  477.     Texture * pTexture;
  478. public:
  479.     void Create(std::vector<vec4>& image) {
  480.         glGenVertexArrays(1, &vao);
  481.         glBindVertexArray(vao);    
  482.  
  483.         unsigned int vbo;      
  484.         glGenBuffers(1, &vbo); 
  485.  
  486.        
  487.         glBindBuffer(GL_ARRAY_BUFFER, vbo);
  488.         float vertexCoords[] = { -1, -1,  1, -1,  1, 1,  -1, 1 };  
  489.         glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoords), vertexCoords, GL_STATIC_DRAW);
  490.         glEnableVertexAttribArray(0);
  491.         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);  
  492.  
  493.         pTexture = new Texture(windowWidth, windowHeight, image);
  494.     }
  495.  
  496.     void Draw() {
  497.         glBindVertexArray(vao);
  498.         pTexture->SetUniform(gpuProgram.getId(), "textureUnit");
  499.         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);   
  500.     }
  501. };
  502.  
  503. FullScreenTexturedQuad fullScreenTexturedQuad;
  504.  
  505.  
  506. void onInitialization() {
  507.     glViewport(0, 0, windowWidth, windowHeight);
  508.     scene.build();
  509.     std::vector<vec4> image(windowWidth * windowHeight);
  510.     long timeStart = glutGet(GLUT_ELAPSED_TIME);
  511.     scene.render(image);
  512.     long timeEnd = glutGet(GLUT_ELAPSED_TIME);
  513.     printf("Rendering time: %d milliseconds\n", (timeEnd - timeStart));
  514.     fullScreenTexturedQuad.Create(image);
  515.  
  516.    
  517.     gpuProgram.Create(vertexSource, fragmentSource, "fragmentColor");
  518. }
  519.  
  520.  
  521. void onDisplay() {
  522.     fullScreenTexturedQuad.Draw();
  523.     glutSwapBuffers();                             
  524. }
  525.  
  526.  
  527. void onKeyboard(unsigned char key, int pX, int pY) {
  528.     if (key == 'a') {       n++;
  529.        
  530.         scene.build();
  531.         std::vector<vec4> image(windowWidth * windowHeight);
  532.         scene.render(image);
  533.         fullScreenTexturedQuad.Create(image);
  534.         glutSwapBuffers();
  535.     }
  536. }
  537.  
  538.  
  539. void onKeyboardUp(unsigned char key, int pX, int pY) {
  540.  
  541. }
  542.  
  543.  
  544. void onMouse(int button, int state, int pX, int pY) {
  545. }
  546.  
  547.  
  548. void onMouseMotion(int pX, int pY) {
  549. }
  550.  
  551.  
  552. void onIdle() {
  553.     static float tend = 0;
  554.     const float dt = 0.01;
  555.     float tstart = tend;
  556.     tend = glutGet(GLUT_ELAPSED_TIME) / 1000.0f;
  557.     for (float t = tstart; t < tend; t += dt)
  558.         {
  559.         scene.refreshPos();
  560.         }
  561.  
  562.     scene.build();
  563.     std::vector<vec4> image(windowWidth * windowHeight);
  564.     scene.render(image);
  565.     fullScreenTexturedQuad.Create(image);
  566.     glutPostRedisplay();
  567.  
  568.  
  569. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top