Advertisement
Guest User

lehetjo nincs referencia mibnden global

a guest
Nov 22nd, 2017
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.57 KB | None | 0 0
  1. //=============================================================================================
  2. // Framework for the ray tracing homework
  3. // ---------------------------------------------------------------------------------------------
  4. // Name : Kovacs Daniel Kristof
  5. // Neptun : FSJNT3
  6. //=============================================================================================
  7.  
  8. #define _USE_MATH_DEFINES
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12.  
  13. #if defined(__APPLE__)
  14. #include <GLUT/GLUT.h>
  15. #include <OpenGL/gl3.h>
  16. #include <OpenGL/glu.h>
  17. #else
  18. #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
  19. #include <windows.h>
  20. #endif
  21. #include <GL/glew.h> // must be downloaded
  22. #include <GL/freeglut.h> // must be downloaded unless you have an Apple
  23. #endif
  24.  
  25. const unsigned int windowWidth = 600, windowHeight = 600;
  26.  
  27. // OpenGL major and minor versions
  28. int majorVersion = 3, minorVersion = 3;
  29. float PI = 3.14159265359;
  30. struct vec3 {
  31. float x, y, z;
  32.  
  33. vec3(float x0 = 0, float y0 = 0, float z0 = 0) { x = x0; y = y0; z = z0; }
  34.  
  35. vec3 operator*(float a) const { return vec3(x * a, y * a, z * a); }
  36.  
  37. vec3 operator/(float a) const { return vec3(x / a, y / a, z / a); }
  38.  
  39. vec3 operator+(const vec3& v) const {
  40. return vec3(x + v.x, y + v.y, z + v.z);
  41. }
  42. vec3& operator+= (const vec3 & rhs) {
  43. x += rhs.x;
  44. y += rhs.y;
  45. z += rhs.z;
  46. return *this;
  47. }
  48. vec3 operator-(const vec3& v) const {
  49. return vec3(x - v.x, y - v.y, z - v.z);
  50. }
  51. vec3 operator*(const vec3& v) const {
  52. return vec3(x * v.x, y * v.y, z * v.z);
  53. }
  54. vec3 operator-() const {
  55. return vec3(-x, -y, -z);
  56. }
  57. vec3 normalize() const {
  58. return (*this) * (1 / (Length() + 0.000001));
  59. }
  60. float Length() const { return sqrtf(x * x + y * y + z * z); }
  61.  
  62. operator float*() { return &x; }
  63. };
  64.  
  65. float dot(const vec3& v1, const vec3& v2) {
  66. return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
  67. }
  68.  
  69. vec3 cross(const vec3& v1, const vec3& v2) {
  70. return vec3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x);
  71. }
  72.  
  73.  
  74.  
  75. // row - major matrix 3x3
  76. struct mat3 {
  77. float m[3][3];
  78. public:
  79. mat3() {}
  80. mat3(float m00, float m01, float m02,
  81. float m10, float m11, float m12,
  82. float m20, float m21, float m22) {
  83. m[0][0] = m00; m[0][1] = m01; m[0][2] = m02;
  84. m[1][0] = m10; m[1][1] = m11; m[1][2] = m12;
  85. m[2][0] = m20; m[2][1] = m21; m[2][2] = m22;
  86.  
  87. }
  88. mat3 operator*(const mat3& right) {
  89. mat3 result;
  90. for (int i = 0; i < 3; i++) {
  91. for (int j = 0; j < 3; j++) {
  92. result.m[i][j] = 0;
  93. for (int k = 0; k < 3; k++) result.m[i][j] += m[i][k] * right.m[k][j];
  94. }
  95. }
  96. return result;
  97. }
  98. operator float*() { return &m[0][0]; }
  99.  
  100. vec3 dot(vec3 v) {
  101. vec3 res = v;
  102. res.x = v.x*m[0][0] + v.y*m[1][0] + v.z*m[2][0];
  103. res.y = v.x*m[0][1] + v.y*m[1][1] + v.z*m[2][1];
  104. res.z = v.x*m[0][2] + v.y*m[1][2] + v.z*m[2][2];
  105. return res;
  106. }
  107. float getElement(int x, int y) { return m[x][y]; } // visszaadja a a mátrix megfelelo elemet
  108. };
  109.  
  110.  
  111. float epsilon = 0.001f;
  112.  
  113. struct Light {
  114. vec3 p;
  115. vec3 Lout;
  116. Light() {
  117. }
  118.  
  119. Light(vec3 p, vec3 Lout) {
  120. this->p = p;
  121. this->Lout = Lout;
  122. }
  123.  
  124. float getDist(vec3 r) {
  125. return (r - p).Length();
  126. }
  127.  
  128. vec3 getLightDir(vec3 r) {
  129. return p - r;
  130. }
  131.  
  132. vec3 getInRad(vec3 r) {
  133. return Lout * (1 / pow(getDist(r), 2));
  134. }
  135. };
  136.  
  137.  
  138. struct Ray {
  139. vec3 P0;
  140. vec3 dir;
  141.  
  142. Ray(vec3 P0, vec3 dir) {
  143. this->P0 = P0;
  144. this->dir = dir;
  145. }
  146. };
  147.  
  148. struct Camera {
  149. vec3 eye;
  150. vec3 lookat;
  151. vec3 up;
  152. vec3 right;
  153. float XM;
  154. float YM;
  155.  
  156. Camera() {
  157. }
  158. Camera(vec3 eye, vec3 lookat, vec3 up, vec3 right) {
  159. this->eye = eye;
  160. this->lookat = lookat;
  161. this->up = up;
  162. this->right = right;
  163. XM = windowWidth;
  164. YM = windowHeight;
  165. }
  166.  
  167. Ray GetRay(float x, float y) {
  168. vec3 p = lookat + right*(2 * x / XM - 1) + up * (2 * y / YM - 1);
  169. return Ray(p, p - eye);
  170. }
  171. };
  172.  
  173.  
  174. struct Material {
  175.  
  176. //TODO F0 szamolas
  177. vec3 F0;
  178. float n;
  179. vec3 kd;
  180. vec3 ks;
  181. vec3 ka;
  182. float shininess;
  183. bool reflective;
  184. bool refractive;
  185. bool rough;
  186.  
  187. Material() {
  188.  
  189. }
  190.  
  191. Material(vec3 F0, float n, vec3 kd, vec3 ks, float shin, bool refl, bool refr, bool rou) {
  192. this->F0 = F0;
  193. this->n = n;
  194. this->kd = kd;
  195. this->ks = ks;
  196. shininess = shin;
  197. reflective = refl;
  198. refractive = refr;
  199. rough = rou;
  200. }
  201.  
  202.  
  203. vec3 refract(vec3 inDirection, vec3 normal) {
  204. float ior = n;
  205. float cosa = -dot(normal, inDirection);
  206. if (cosa < 0) { cosa = -cosa; normal = -normal; ior = 1 / n; }
  207. float disc = 1 - (1 - cosa * cosa) / ior / ior;
  208. if (disc < 0) return reflect(inDirection, normal);
  209. return inDirection / ior + normal * (cosa / ior - sqrt(disc));
  210. }
  211. vec3 reflect(vec3 inDirection, vec3 normal)
  212. {
  213. return inDirection - normal * dot(normal, inDirection) * 2.0f;
  214. };
  215.  
  216. vec3 Fresnel(vec3 inDir, vec3 normal) {
  217. float cosa = fabs(dot(normal, inDir));
  218. return F0 + (vec3(1, 1, 1) - F0) * pow(1 - cosa, 5);
  219. }
  220.  
  221. vec3 shade(vec3 normal, vec3 viewDirection, vec3 lightDirection, vec3 inRadiance)
  222. {
  223. vec3 reflRad(0, 0, 0);
  224. float cosTheta = dot(normal, lightDirection);
  225. if (cosTheta < 0) return reflRad;
  226. reflRad = inRadiance * kd * cosTheta;;
  227. vec3 halfway = (viewDirection + lightDirection).normalize();
  228. float cosDelta = dot(normal, halfway);
  229. if (cosDelta < 0) return reflRad;
  230. return reflRad + inRadiance * ks * pow(cosDelta, shininess);
  231. }
  232.  
  233. };
  234.  
  235. float F0(float n, float k) {
  236. return ((n - 1)*(n - 1) + k*k) / ((n + 1)*(n + 1) + k*k);
  237. }
  238.  
  239. struct Hit {
  240. vec3 position;
  241. vec3 normal;
  242. float t;
  243. Material* material;
  244. Hit() { t = -1; }
  245. Hit(float t, vec3 pos, vec3 norm, Material* mat) {
  246. this->t = t;
  247. position = pos;
  248. normal = norm;
  249. material = mat;
  250. }
  251. };
  252.  
  253. struct Intersectable
  254. {
  255. Material* material;
  256. virtual Hit intersect(const Ray& ray) = 0;
  257.  
  258. Intersectable() {
  259.  
  260. }
  261.  
  262. Intersectable(Material* m) {
  263. material = m;
  264. }
  265. };
  266.  
  267. Camera camera;
  268.  
  269. struct Plane : public Intersectable {
  270. vec3 P0;
  271. vec3 normal;
  272.  
  273. Plane() {
  274. }
  275. Plane(vec3 P0, vec3 n, Material* m) :Intersectable(m) {
  276. this->P0 = P0;
  277. normal = n;
  278. }
  279. Hit intersect(const Ray& ray) {
  280. Hit hit;
  281.  
  282. if (dot(normal, ray.dir) == 0) {
  283. return hit;
  284. }
  285. hit.t = (dot(normal, P0) - dot(normal, ray.P0)) / (dot(normal, ray.dir));
  286. hit.normal = normal;
  287. hit.material = material;
  288. hit.position = ray.P0 + ray.dir*hit.t;
  289. return hit;
  290. }
  291. };
  292.  
  293. class Torus
  294. {
  295. float R = 0.8f;
  296. float r = 0.1f;
  297.  
  298. public:
  299. float getGaussianCurve(float u) {
  300. return (1 / r) * (cosf(u) / (R + r * cosf(u)));
  301. }
  302. void setR(float R, float r) {
  303. this->R = R;
  304. this->r = r;
  305. }
  306.  
  307. float getX(float u, float v)
  308. {
  309. u *= (float)2 * PI;
  310. v *= (float)2 * PI;
  311. return (R + r*cosf(u))*cosf(v);
  312. }
  313. float getY(float u, float v)
  314. {
  315. u *= (float)2 * PI;
  316. v *= (float)2 * PI;
  317. return (R + r*cosf(u))*sinf(v);
  318. }
  319. float getZ(float u, float v)
  320. {
  321. u *= (float)2 * PI;
  322. return r*sinf(u);
  323. }
  324.  
  325. };
  326. Torus torus;
  327.  
  328. class Cylinder : public Intersectable {
  329. vec3 r0;
  330. vec3 vh;
  331. float R;
  332. public:
  333. Cylinder() {
  334. }
  335.  
  336. Cylinder(vec3 r0, vec3 vh, float r, Material* m) :Intersectable(m) {
  337. this->r0 = r0;
  338. this->vh = vh;
  339. R = r;
  340. }
  341.  
  342. Hit intersect(const Ray& ray) {
  343. Hit hit;
  344. float a = dot(ray.dir, ray.dir) - powf(dot(ray.dir, vh), 2);
  345. float b = 2 * (dot(ray.P0 - r0, ray.dir) - dot(vh, ray.dir) * dot(ray.P0 - r0, vh));
  346. float c = dot(ray.P0 - r0, ray.P0 - r0) - powf(dot(ray.P0 - r0, vh), 2) - powf(R, 2);
  347. float D = powf(b, 2) - 4 * a*c;
  348. if (D > 0) {
  349. float t1 = (-1 * b + sqrtf(D)) / (2 * a);
  350. float t2 = (-1 * b - sqrtf(D)) / (2 * a);
  351.  
  352. if (t1 >= 0 && t2 < 0) {
  353. hit.t = t1;
  354. }
  355. else if (t1<0 && t2 >= 0) {
  356. hit.t = t2;
  357. }
  358. else if (t1>t2) {
  359. hit.t = t2;
  360. }
  361. else {
  362. hit.t = t1;
  363. }
  364. }
  365. else if (D<0) {
  366. return hit;
  367. }
  368. else {
  369. hit.t = (-1 * b) / (2 * a);
  370. }
  371.  
  372. hit.position = ray.P0 + ray.dir*hit.t;
  373. hit.normal = ((ray.P0 + ray.dir*hit.t - r0) * 2 - vh * (dot(ray.P0, vh) + dot(ray.dir, vh) * hit.t - dot(r0, vh)) * 2) / R;
  374. hit.material = material;
  375. return hit;
  376. }
  377. };
  378.  
  379. class Triangle :public Intersectable {
  380. vec3 r1;
  381. vec3 r2;
  382. vec3 r3;
  383. vec3 normal;
  384. vec3 p;
  385. public:
  386. Triangle() {
  387.  
  388. }
  389. Triangle(vec3 a, vec3 b, vec3 c, Material* m) :Intersectable(m) {
  390. r1 = a;
  391. r2 = b;
  392. r3 = c;
  393. calculateNormal();
  394. }
  395.  
  396. void calculateNormal() {
  397. normal = cross((r1 - r3), (r2 - r3));
  398. }
  399. Hit intersect(const Ray& ray) {
  400. Hit hit;
  401. float t = float(dot(r1 - ray.P0, normal)) / float((dot(ray.dir, normal)));
  402. if (t > 0) {
  403. p = ray.P0 + ray.dir*t;
  404. }
  405. else {
  406. return hit;
  407. }
  408.  
  409. if (dot(cross(r2 - r1, p - r1), normal) > 0 &&
  410. dot(cross(r3 - r2, p - r2), normal) > 0 &&
  411. dot(cross(r1 - r3, p - r3), normal) > 0) {
  412. hit.t = t;
  413. }
  414.  
  415. else {
  416. hit.t = 0;
  417. }
  418. hit.position = ray.P0 + ray.dir*hit.t;
  419. hit.normal = normal;
  420. hit.material = material;
  421.  
  422. return hit;
  423. }
  424.  
  425. };
  426.  
  427.  
  428. vec3 background[windowWidth * windowHeight]; // The image, which stores the ray tracing result
  429.  
  430. Light lights[3];
  431. Material gold;
  432. Material glass;
  433. Material silver;
  434. Material m2;
  435. Material m3;
  436. Material m4;
  437. Triangle t1;
  438. Triangle t6;
  439. Triangle t5;
  440. Cylinder room;
  441. Plane roomFloor;
  442. Plane roomCeiling;
  443.  
  444. int counter = 0;
  445. vec3 test = vec3(3, 2, 1);
  446.  
  447.  
  448.  
  449. struct Scene {
  450. vec3 La = vec3(0.5f, 0.5f, 0.5f);
  451.  
  452.  
  453.  
  454. int lightsdb = 0;
  455. int maxdepth = 10;
  456. vec3 a = vec3(-0.71, 0, 1);
  457. vec3 b = vec3(0.5, 0.1, 1);
  458. vec3 c = vec3(-0.45, 0, 1.2);
  459. vec3 torus1Coord[7][7];
  460. vec3 torus2Coord[7][7];
  461. vec3 torus3Coord[7][7];
  462. Intersectable* objects[150];
  463. Triangle torus1[90];
  464. Triangle torus2[90];
  465. Triangle torus3[90];
  466.  
  467.  
  468. int objectdb = 0;
  469. void coorinatesOfTorus( float scale, float moveX, float moveY, float moveZ, float alpha, float beta, float g) {
  470. int i = 0;
  471. int j = 0;
  472.  
  473.  
  474. mat3 ZrotateM = mat3(cosf(alpha), -sinf(alpha), 0,
  475. sinf(alpha), cosf(alpha), 0,
  476. 0, 0, 1);
  477.  
  478. mat3 YrotateM = mat3(cosf(beta), 0, sinf(beta),
  479. 0, 1, 0,
  480. -sinf(beta), 0, sinf(beta));
  481.  
  482.  
  483. mat3 XrotateM = mat3(1, 0, 0,
  484. 0, cosf(g), -sinf(g),
  485. 0, sinf(g), cosf(g));
  486. for (float u = 0; u < 2 * PI; u = u + 0.8, i++)
  487. {
  488. for (float v = 0; v < 2 * PI; v = v + 0.8, j++)
  489. {
  490. vec3 Zrotated = ZrotateM.dot(vec3(torus.getX(u, v)*scale, torus.getY(u, v)*scale, torus.getZ(u, v) + 0.30f));
  491. vec3 Yrotated = YrotateM.dot(Zrotated);
  492. vec3 Xrotated = XrotateM.dot(Yrotated);
  493. vec3 fin = vec3(Xrotated.x + moveX, Xrotated.y + moveY, Xrotated.z + moveZ);
  494. torus1Coord[i][j] = fin;
  495.  
  496. }
  497. j = 0;
  498. }
  499. }
  500.  
  501. Scene() {
  502.  
  503.  
  504. }
  505. void tesselate1( Material * m) {
  506. coorinatesOfTorus( 0.5f, 0.0f, 0.65f, 0.45f, 1.2*PI, 0.57f, PI / 2.0f);
  507. coorinatesOfTorus( 0.46f, -0.1f, 0.2f, 0.60f, PI / 2.3f, 3.0f, 0.3f);
  508. coorinatesOfTorus( 0.7f, 0.2f, 0.5f, 0.60f, PI / 4.0f, PI / 2.5f, PI / 5.2f);
  509. Triangle t[90];
  510. int c = 0;
  511. for (size_t i = 0; i < 7; i++)
  512. {
  513. for (size_t j = 0; j < 7; j++)
  514. {
  515. torus1[c] = Triangle(torus1Coord[i][j], torus1Coord[i + 1][j], torus1Coord[i + 1][j + 1], m);
  516. c++;
  517.  
  518. torus1[c] = Triangle(torus1Coord[i][j], torus1Coord[i + 1][j + 1], torus1Coord[i][j + 1], m);
  519. c++;
  520. }
  521. }
  522. }
  523.  
  524. void build() {
  525. camera = Camera(vec3(0.0f, 0.0f, -1.0f), vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f), vec3(1.0f, 0.0f, 0.0f));
  526. lights[0] = Light(vec3(1.7f, 1.0f, 3.0f), vec3(1.0f, 1.0f, 1.0f));
  527. lights[1] = Light(vec3(-2.0f, 1.0f, 2.0f), vec3(1.0f, 1.0f, 1.0f));
  528. lights[2] = Light(vec3(0.0f, 0.0f, 1.5f), vec3(1.0f, 1.0f, 1.0f));
  529. lightsdb = 3;
  530. silver = Material(vec3(F0(0.14, 4.1), F0(0.16, 2.3), F0(0.13, 3.1)), 1.5, vec3(1, 0, 0), vec3(1, 1, 1), 10, true, false, false);
  531. gold = Material(vec3(F0(0.17, 3.1), F0(0.35, 2.7), F0(1.5, 1.9)), 0, vec3(1, 0, 0), vec3(1, 1, 1), 10, true, false, false);
  532. m2 = Material(vec3(0, 0, 0), 1.5f, vec3(0, 0, 1), vec3(1, 1, 1), 15, false, false, true);
  533. m3 = Material(vec3(0, 0, 0), 0, vec3(0.97, 0.7, 0.9), vec3(1, 1, 1), 15, false, false, true);
  534. m4 = Material(vec3(0, 0, 0), 0, vec3(1, 1, 0), vec3(1, 1, 1), 10, false, false, true);
  535. glass = Material(vec3(F0(1.5f, 0), F0(1.5f, 0), F0(1.5f, 0)), 1.5, vec3(1, 0, 0), vec3(1, 1, 1), 10, false, true, false);
  536. t1 = Triangle(a, b, c, &m2);
  537. room = Cylinder(vec3(0.0f, 0.0f, 2.5f), vec3(0.0f, 1.0f, 0.0f), 3.5f, &m2);
  538. roomFloor = Plane(vec3(0, -1.5f, 0), vec3(0, 1, 0), &m3);
  539. roomCeiling = Plane(vec3(0, 1.5f, 0), vec3(0, -1, 0), &m3);
  540. t5 = Triangle(torus1Coord[0][0], torus1Coord[1][0], torus1Coord[1][1], &gold);
  541. t6 = Triangle(torus1Coord[0][0], torus1Coord[0][1], torus1Coord[1][1], &gold);
  542. tesselate1( &gold);
  543. //tesselate(torus2, torus2Coord, &glass);
  544. //tesselate(torus3, torus3Coord, &silver);
  545. objects[objectdb] = &room;
  546. objectdb++;
  547. objects[objectdb] = &roomCeiling;
  548. objectdb++;
  549. objects[objectdb] = &roomFloor;
  550. objectdb++;
  551.  
  552. for (size_t i = 0; i < 49; i++)
  553. {
  554.  
  555. objects[objectdb] = &torus1[i];
  556. objectdb++;
  557. /*
  558. objects[objectdb] = &torus2[i];
  559. objectdb++;
  560. objects[objectdb] = &torus3[i];
  561. objectdb++;
  562. */
  563. }
  564.  
  565. }
  566.  
  567. void Render() {
  568. for (int x = 0; x < windowWidth; x++) {
  569. for (int y = 0; y < windowHeight; y++) {
  570. Ray ray = camera.GetRay((float)x, (float)y);
  571.  
  572. background[y * windowWidth + x] = trace(ray, 0);
  573. }
  574. }
  575. }
  576.  
  577. vec3 trace(Ray ray, int depth) {
  578. if (depth > maxdepth) return La;
  579. vec3 outRadiance(0, 0, 0);
  580. Hit hit = firstIntersect(ray);
  581. if (hit.t < 0) return La;
  582. vec3 V = (ray.dir*-1).normalize();
  583. vec3 N = hit.normal.normalize();
  584. vec3 r = hit.position;
  585. if (hit.material->rough) {
  586. outRadiance = hit.material->kd * La; //csak az ambiens fenyt figyelembe veve
  587. for (int i = 0; i < lightsdb; i++) { //vegigmegyek az osszes absztrakt fenyforrason
  588. vec3 Ll = lights[i].getLightDir(hit.position).normalize();
  589. Ray shadowRay(r + Nesign(N, V), Ll);
  590.  
  591. Hit shadowHit = firstIntersect(shadowRay); //Ezzel eldontjuk, hogy latszik-e az adott objektum
  592. if (shadowHit.t < 0 || shadowHit.t > lights[i].getDist(r)) {
  593. outRadiance += hit.material->shade(N, V, shadowRay.dir, lights[i].getInRad(r));
  594. }
  595. }
  596. }
  597. if (hit.material->reflective) {
  598. vec3 reflectionDir = hit.material->reflect(ray.dir, N);
  599. Ray reflectedRay(r + Nesign(N, V), reflectionDir);
  600. outRadiance += trace(reflectedRay, depth + 1)*hit.material->Fresnel(V, N);
  601. }
  602. if (hit.material->refractive) {
  603. vec3 refractionDir = hit.material->refract(ray.dir, N);
  604. Ray refractedRay(r - Nesign(N, V), refractionDir);
  605. outRadiance += trace(refractedRay, depth + 1)*(vec3(1, 1, 1) - hit.material->Fresnel(V, N));
  606. }
  607. return outRadiance;
  608. }
  609.  
  610. Hit firstIntersect(Ray ray) {
  611. Hit bestHit;
  612. for (int i = 0;i< objectdb; i++) {
  613. Intersectable* obj = objects[i];
  614. Hit hit = obj->intersect(ray); // hit.t < 0 if no intersection
  615. if (hit.t > 0 && (bestHit.t < 0 || hit.t < bestHit.t)) bestHit = hit;
  616. }
  617. return bestHit;
  618. }
  619.  
  620. vec3 Nesign(vec3 N, vec3 V) {
  621. if (dot(N, V) < 0) {
  622. return N*-1.0f*epsilon;
  623. }
  624. else {
  625. return N*epsilon;
  626. }
  627. }
  628.  
  629. };
  630.  
  631. void getErrorInfo(unsigned int handle) {
  632. int logLen;
  633. glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &logLen);
  634. if (logLen > 0) {
  635. char * log = new char[logLen];
  636. int written;
  637. glGetShaderInfoLog(handle, logLen, &written, log);
  638. printf("Shader log:\n%s", log);
  639. delete log;
  640. }
  641. }
  642.  
  643. // check if shader could be compiled
  644. void checkShader(unsigned int shader, char * message) {
  645. int OK;
  646. glGetShaderiv(shader, GL_COMPILE_STATUS, &OK);
  647. if (!OK) {
  648. printf("%s!\n", message);
  649. getErrorInfo(shader);
  650. }
  651. }
  652.  
  653. // check if shader could be linked
  654. void checkLinking(unsigned int program) {
  655. int OK;
  656. glGetProgramiv(program, GL_LINK_STATUS, &OK);
  657. if (!OK) {
  658. printf("Failed to link shader program!\n");
  659. getErrorInfo(program);
  660. }
  661. }
  662.  
  663. // vertex shader in GLSL
  664. const char *vertexSource = R"(
  665. #version 330
  666. precision highp float;
  667.  
  668. layout(location = 0) in vec2 vertexPosition; // Attrib Array 0
  669.  
  670. out vec2 texcoord;
  671.  
  672. void main() {
  673. texcoord = (vertexPosition + vec2(1, 1))/2; // -1,1 to 0,1
  674. gl_Position = vec4(vertexPosition.x, vertexPosition.y, 0, 1); // transform to clipping space
  675. }
  676. )";
  677.  
  678. // fragment shader in GLSL
  679. const char *fragmentSource = R"(
  680. #version 330
  681. precision highp float;
  682.  
  683. uniform sampler2D textureUnit;
  684. in vec2 texcoord; // interpolated texture coordinates
  685.  
  686. out vec4 fragmentColor; // output that goes to the raster memory as told by glBindFragDataLocation
  687.  
  688. void main() {
  689. fragmentColor = texture(textureUnit, texcoord);
  690. }
  691. )";
  692.  
  693.  
  694. // handle of the shader program
  695. unsigned int shaderProgram;
  696.  
  697. class FullScreenTexturedQuad {
  698. unsigned int vao, textureId; // vertex array object id and texture id
  699. public:
  700. void Create(vec3 image[windowWidth * windowHeight]) {
  701. glGenVertexArrays(1, &vao); // create 1 vertex array object
  702. glBindVertexArray(vao); // make it active
  703.  
  704. unsigned int vbo; // vertex buffer objects
  705. glGenBuffers(1, &vbo); // Generate 1 vertex buffer objects
  706.  
  707. // vertex coordinates: vbo[0] -> Attrib Array 0 -> vertexPosition of the vertex shader
  708. glBindBuffer(GL_ARRAY_BUFFER, vbo); // make it active, it is an array
  709. static float vertexCoords[] = { -1, -1, 1, -1, -1, 1,
  710. 1, -1, 1, 1, -1, 1 }; // two triangles forming a quad
  711. glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoords), vertexCoords, GL_STATIC_DRAW); // copy to that part of the memory which is not modified
  712. // Map Attribute Array 0 to the current bound vertex buffer (vbo[0])
  713. glEnableVertexAttribArray(0);
  714. glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); // stride and offset: it is tightly packed
  715.  
  716. // Create objects by setting up their vertex data on the GPU
  717. glGenTextures(1, &textureId); // id generation
  718. glBindTexture(GL_TEXTURE_2D, textureId); // binding
  719.  
  720. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, windowWidth, windowHeight, 0, GL_RGB, GL_FLOAT, image); // To GPU
  721. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // sampling
  722. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  723. }
  724.  
  725. void Draw() {
  726. glBindVertexArray(vao); // make the vao and its vbos active playing the role of the data source
  727. int location = glGetUniformLocation(shaderProgram, "textureUnit");
  728. if (location >= 0) {
  729. glUniform1i(location, 0); // texture sampling unit is TEXTURE0
  730. glActiveTexture(GL_TEXTURE0);
  731. glBindTexture(GL_TEXTURE_2D, textureId); // connect the texture to the sampler
  732. }
  733. glDrawArrays(GL_TRIANGLES, 0, 6); // draw two triangles forming a quad
  734. }
  735. };
  736.  
  737. // The virtual world: single quad
  738. FullScreenTexturedQuad fullScreenTexturedQuad;
  739.  
  740. Scene scene;
  741.  
  742. // Initialization, create an OpenGL context
  743. void onInitialization() {
  744. glViewport(0, 0, windowWidth, windowHeight);
  745.  
  746. // Ray tracing fills the image called background
  747. scene.build();
  748. scene.Render();
  749.  
  750. fullScreenTexturedQuad.Create(background);
  751.  
  752. // Create vertex shader from string
  753. unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
  754. if (!vertexShader) {
  755. printf("Error in vertex shader creation\n");
  756. exit(1);
  757. }
  758. glShaderSource(vertexShader, 1, &vertexSource, NULL);
  759. glCompileShader(vertexShader);
  760. checkShader(vertexShader, "Vertex shader error");
  761.  
  762. // Create fragment shader from string
  763. unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  764. if (!fragmentShader) {
  765. printf("Error in fragment shader creation\n");
  766. exit(1);
  767. }
  768. glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
  769. glCompileShader(fragmentShader);
  770. checkShader(fragmentShader, "Fragment shader error");
  771.  
  772. // Attach shaders to a single program
  773. shaderProgram = glCreateProgram();
  774. if (!shaderProgram) {
  775. printf("Error in shader program creation\n");
  776. exit(1);
  777. }
  778. glAttachShader(shaderProgram, vertexShader);
  779. glAttachShader(shaderProgram, fragmentShader);
  780.  
  781. // Connect the fragmentColor to the frame buffer memory
  782. glBindFragDataLocation(shaderProgram, 0, "fragmentColor"); // fragmentColor goes to the frame buffer memory
  783.  
  784. // program packaging
  785. glLinkProgram(shaderProgram);
  786. checkLinking(shaderProgram);
  787. // make this program run
  788. glUseProgram(shaderProgram);
  789. }
  790.  
  791. void onExit() {
  792. glDeleteProgram(shaderProgram);
  793. printf("exit");
  794. }
  795.  
  796. // Window has become invalid: Redraw
  797. void onDisplay() {
  798. fullScreenTexturedQuad.Draw();
  799. glutSwapBuffers(); // exchange the two buffers
  800. }
  801.  
  802. // Key of ASCII code pressed
  803. void onKeyboard(unsigned char key, int pX, int pY) {
  804. if (key == 'd') glutPostRedisplay(); // if d, invalidate display, i.e. redraw
  805. }
  806.  
  807. // Key of ASCII code released
  808. void onKeyboardUp(unsigned char key, int pX, int pY) {
  809.  
  810. }
  811.  
  812. // Mouse click event
  813. void onMouse(int button, int state, int pX, int pY) {
  814. if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { // GLUT_LEFT_BUTTON / GLUT_RIGHT_BUTTON and GLUT_DOWN / GLUT_UP
  815. }
  816. }
  817.  
  818. // Move mouse with key pressed
  819. void onMouseMotion(int pX, int pY) {
  820. }
  821.  
  822. // Idle event indicating that some time elapsed: do animation here
  823. void onIdle() {
  824. long time = glutGet(GLUT_ELAPSED_TIME); // elapsed time since the start of the program
  825. }
  826.  
  827. int main(int argc, char * argv[]) {
  828. glutInit(&argc, argv);
  829. #if !defined(__APPLE__)
  830. glutInitContextVersion(majorVersion, minorVersion);
  831. #endif
  832. glutInitWindowSize(windowWidth, windowHeight); // Application window is initially of resolution 600x600
  833. glutInitWindowPosition(100, 100); // Relative location of the application window
  834. #if defined(__APPLE__)
  835. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_3_2_CORE_PROFILE); // 8 bit R,G,B,A + double buffer + depth buffer
  836. #else
  837. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  838. #endif
  839. glutCreateWindow(argv[0]);
  840.  
  841. #if !defined(__APPLE__)
  842. glewExperimental = true; // magic
  843. glewInit();
  844. #endif
  845.  
  846. printf("GL Vendor : %s\n", glGetString(GL_VENDOR));
  847. printf("GL Renderer : %s\n", glGetString(GL_RENDERER));
  848. printf("GL Version (string) : %s\n", glGetString(GL_VERSION));
  849. glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
  850. glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
  851. printf("GL Version (integer) : %d.%d\n", majorVersion, minorVersion);
  852. printf("GLSL Version : %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
  853.  
  854. onInitialization();
  855.  
  856. glutDisplayFunc(onDisplay); // Register event handlers
  857. glutMouseFunc(onMouse);
  858. glutIdleFunc(onIdle);
  859. glutKeyboardFunc(onKeyboard);
  860. glutKeyboardUpFunc(onKeyboardUp);
  861. glutMotionFunc(onMouseMotion);
  862.  
  863. glutMainLoop();
  864. onExit();
  865. return 1;
  866. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement