Advertisement
Guest User

Untitled

a guest
Dec 14th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.07 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <glew.h>
  4. #include <glfw3.h>
  5. #include <math.h>
  6. #include <iostream>
  7. #include <fstream>
  8. #include <string>
  9. #include "glm/ext.hpp"
  10.  
  11. const float PI = 22.0f / 7.0f;
  12. const float DEG_TO_RAD = PI / 180.0f;
  13.  
  14. class Vertex
  15. {
  16. public:
  17. GLfloat x, y, z;
  18. Vertex(float _x = 0, float _y = 0, float _z = 0)
  19. {
  20. x = _x;
  21. y = _y;
  22. z = _z;
  23. }
  24.  
  25. Vertex operator - (const Vertex& another)
  26. {
  27. Vertex temp(x, y, z);
  28.  
  29. temp.x -= another.x;
  30. temp.y -= another.y;
  31. temp.z -= another.z;
  32.  
  33. return temp;
  34. }
  35.  
  36. Vertex operator + (const Vertex& another)
  37. {
  38. Vertex temp(x, y, z);
  39.  
  40. temp.x += another.x;
  41. temp.y += another.y;
  42. temp.z += another.z;
  43.  
  44. return temp;
  45. }
  46.  
  47. void operator = (const Vertex& another)
  48. {
  49. x = another.x;
  50. y = another.y;
  51. z = another.z;
  52. }
  53.  
  54. Vertex operator * (float multiplier)
  55. {
  56. Vertex temp(x, y, z);
  57.  
  58. temp.x *= multiplier;
  59. temp.y *= multiplier;
  60. temp.z *= multiplier;
  61.  
  62. return temp;
  63. }
  64.  
  65. Vertex operator * (const Vertex& another)
  66. {
  67. Vertex temp(x, y, z);
  68.  
  69. temp.x *= another.x;
  70. temp.y *= another.y;
  71. temp.z *= another.z;
  72.  
  73. return temp;
  74. }
  75.  
  76. void Print()
  77. {
  78. printf("%f %f %f\n", x, y, z);
  79. }
  80.  
  81. void Normalize()
  82. {
  83. float length = pow(pow(x, 2.0f) + pow(y, 2.0f) + pow(z, 2.0f), 0.5f);
  84. x /= length;
  85. y /= length;
  86. z /= length;
  87. }
  88. };
  89.  
  90. float GetLength(const Vertex& vector)
  91. {
  92. float length = pow(vector.x, 2) + pow(vector.y, 2) + pow(vector.z, 2);
  93. length = pow(length, 0.5);
  94. return length;
  95. }
  96.  
  97. Vertex GetNormal(Vertex& a, Vertex& b, Vertex& c, bool clockwise = true)
  98. {
  99. Vertex v0 = b - a;
  100. Vertex v1 = c - a;
  101.  
  102. Vertex normal;
  103.  
  104. normal.x = (v0.y * v1.z) - (v0.z * v1.y);
  105. normal.y = -1.0f * ((v0.x * v1.z) - (v0.z * v1.x));
  106. normal.z = (v0.x * v1.y) - (v0.y - v1.x);
  107.  
  108. float length = GetLength(normal);
  109.  
  110. normal.x = normal.x * (clockwise ? 1.0f : -1.0f) / length;
  111. normal.y = normal.y * (clockwise ? 1.0f : -1.0f) / length;
  112. normal.z = normal.z * (clockwise ? 1.0f : -1.0f) / length;
  113.  
  114. return normal;
  115. }
  116.  
  117. float GetDotProduct(const Vertex& a, const Vertex& b)
  118. {
  119. float dot = a.x * b.x + a.y * b.y + a.z * b.z;
  120. return dot;
  121. }
  122.  
  123. float GetDistance(const Vertex& a, const Vertex& b)
  124. {
  125. float distance = pow((a.x - b.x), 2.0) + pow((a.y - b.y), 2.0) + pow((a.z - b.z), 2.0);
  126. distance = pow(distance, 0.5);
  127. return distance;
  128. }
  129.  
  130. Vertex GetRotationResult(const Vertex& pivot, const Vertex* matrix, Vertex point, bool isEuler = false)
  131. {
  132. Vertex temp, newPosition;
  133. temp = (isEuler) ? point : point - pivot;
  134.  
  135. newPosition.x = temp.x * matrix[0].x + temp.y * matrix[0].y + temp.z * matrix[0].z;
  136. newPosition.y = temp.x * matrix[1].x + temp.y * matrix[1].y + temp.z * matrix[1].z;
  137. newPosition.z = temp.x * matrix[2].x + temp.y * matrix[2].y + temp.z * matrix[2].z;
  138.  
  139. temp = (isEuler) ? newPosition : newPosition + pivot;
  140. return temp;
  141. }
  142.  
  143. void GetRotationMatrix(const Vertex& vector, float angle, Vertex* matrix)
  144. {
  145. matrix[0].x = (cos(angle) + pow(vector.x, 2.0f) * (1.0f - cos(angle)));
  146. matrix[0].y = (vector.x * vector.y * (1.0f - cos(angle)) - vector.z * sin(angle));
  147. matrix[0].z = (vector.x * vector.z * (1.0f - cos(angle)) + vector.y * sin(angle));
  148.  
  149. matrix[1].x = (vector.x * vector.y * (1.0f - cos(angle)) + vector.z * sin(angle));
  150. matrix[1].y = (cos(angle) + pow(vector.y, 2.0f) * (1.0f - cos(angle)));
  151. matrix[1].z = (vector.y * vector.z * (1.0f - cos(angle)) - vector.x * sin(angle));
  152.  
  153. matrix[2].x = (vector.x * vector.z * (1.0f - cos(angle)) - vector.y * sin(angle));
  154. matrix[2].y = (vector.y * vector.z * (1.0f - cos(angle)) + vector.x * sin(angle));
  155. matrix[2].z = (cos(angle) + pow(vector.z, 2.0f) * (1.0f - cos(angle)));
  156. }
  157.  
  158. int GetPascal(int row, int col)
  159. {
  160. if (col > row)
  161. {
  162. return 0;
  163. }
  164. else if (col == 0 || row == 0)
  165. {
  166. return 1;
  167. }
  168. return GetPascal(row - 1, col - 1) + GetPascal(row - 1, col);
  169. }
  170.  
  171. class Shape
  172. {
  173. protected:
  174. int point_size;
  175. int outline_point_size;
  176. int color_size;
  177. int normal_count;
  178. Vertex* points;
  179. Vertex* outline_points;
  180. Vertex* base_colors;
  181. Vertex* colors;
  182. Vertex* normals;
  183. Vertex position;
  184. Vertex euler[3]; //euler X, euler Y, euler Z
  185. GLuint buffer;
  186. GLuint outlineBuffer;
  187. GLuint shader, outlineShader;
  188. GLuint MatrixID;
  189. GLuint colorBuffer;
  190. glm::mat4 mvp;
  191. public:
  192. Shape(float _x = 0, float _y = 0, float _z = 0)
  193. {
  194. position = Vertex(_x, _y, _z);
  195. euler[0] = Vertex(1, 0, 0);
  196. euler[1] = Vertex(0, 1, 0);
  197. euler[2] = Vertex(0, 0, 1);
  198. normal_count = 0;
  199. }
  200.  
  201. Vertex GetPosition()
  202. {
  203. return position;
  204. }
  205.  
  206. int GetPointSize()
  207. {
  208. return point_size;
  209. }
  210.  
  211. int GetOutlinePointSize()
  212. {
  213. return outline_point_size;
  214. }
  215.  
  216. Vertex* GetPoints()
  217. {
  218. return points;
  219. }
  220.  
  221. Vertex* GetOutlinePoints()
  222. {
  223. return outline_points;
  224. }
  225.  
  226. void ShowPoints()
  227. {
  228. for (int i = 0; i < point_size; i++)
  229. {
  230. printf("%f, %f, %f\n", points[i].x, points[i].y, points[i].z);
  231. }
  232. }
  233.  
  234. void InitializeBuffer()
  235. {
  236. glGenBuffers(1, &buffer);
  237. glGenBuffers(1, &outlineBuffer);
  238. glGenBuffers(1, &colorBuffer);
  239. SetArrayBuffer();
  240. }
  241.  
  242. void SetArrayBuffer()
  243. {
  244. SetBuffer();
  245. SetOutlineBuffer();
  246. SetColorBuffer();
  247. }
  248.  
  249. void SetBuffer()
  250. {
  251. glBindBuffer(GL_ARRAY_BUFFER, buffer);
  252. glBufferData(GL_ARRAY_BUFFER, GetPointSize() * sizeof(GL_FLOAT) * 3, GetPoints(), GL_STATIC_DRAW);
  253. }
  254.  
  255. void SetOutlineBuffer()
  256. {
  257. glBindBuffer(GL_ARRAY_BUFFER, outlineBuffer);
  258. glBufferData(GL_ARRAY_BUFFER, GetOutlinePointSize() * sizeof(GL_FLOAT) * 3, GetOutlinePoints(), GL_STATIC_DRAW);
  259. }
  260.  
  261. void SetColorBuffer()
  262. {
  263. glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
  264. glBufferData(GL_ARRAY_BUFFER, color_size * sizeof(GL_FLOAT) * 3, colors, GL_STATIC_DRAW);
  265. }
  266.  
  267. void InitializeShader(const char vertex[], const char fragment[])
  268. {
  269. shader = LoadShaders(vertex, fragment);
  270.  
  271. glm::mat4 Projection = glm::perspective(90.0f * DEG_TO_RAD, 1.0f, 0.1f, 100.0f);
  272.  
  273. // Camera matrix
  274. glm::mat4 View = glm::lookAt(
  275. glm::vec3(0, 1, 2), //Eye position at (0, 1, 2)
  276. glm::vec3(0, 0, 0), // and looks at the origin
  277. glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
  278. );
  279.  
  280. // Model matrix : an identity matrix (model will be at the origin)
  281. glm::mat4 Model = glm::mat4(1.0f);
  282.  
  283. // Our ModelViewProjection : multiplication of our 3 matrices
  284. mvp = Projection * View * Model;
  285.  
  286. MatrixID = glGetUniformLocation(shader, "MVP");
  287. }
  288.  
  289. void InitializeOutlineShader(const char vertex[], const char fragment[])
  290. {
  291. outlineShader = LoadShaders(vertex, fragment);
  292. }
  293.  
  294. void BindBuffer()
  295. {
  296. glEnableVertexAttribArray(0);
  297. glBindBuffer(GL_ARRAY_BUFFER, buffer);
  298. glVertexAttribPointer(
  299. 0, //Set to 0 for coordinates
  300. 3,
  301. GL_FLOAT,
  302. GL_FALSE,
  303. 0,
  304. 0
  305. );
  306. glEnableVertexAttribArray(1);
  307. glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
  308. glVertexAttribPointer(
  309. 1, //Set to 1 for colors
  310. 3,
  311. GL_FLOAT,
  312. GL_FALSE,
  313. 0,
  314. 0
  315. );
  316. }
  317.  
  318. void BindOutlineBuffer()
  319. {
  320. glEnableVertexAttribArray(0);
  321. glBindBuffer(GL_ARRAY_BUFFER, outlineBuffer);
  322. glVertexAttribPointer(
  323. 0,
  324. 3,
  325. GL_FLOAT,
  326. GL_FALSE,
  327. 0,
  328. 0
  329. );
  330. }
  331.  
  332. void DrawPolygon()
  333. {
  334. glUseProgram(shader);
  335. glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);
  336. BindBuffer();
  337. glDrawArrays(GL_TRIANGLES, 0, GetPointSize());
  338. }
  339.  
  340. void DrawPolyline()
  341. {
  342. glUseProgram(outlineShader);
  343. glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);
  344. BindOutlineBuffer();
  345. glDrawArrays(GL_LINES, 0, GetOutlinePointSize());
  346. }
  347.  
  348. void Rotate(const Vertex& pivot, const Vertex& vector, float angle)
  349. {
  350. angle = angle * DEG_TO_RAD;
  351.  
  352. Vertex* rotation_matrix = new Vertex[3];
  353. GetRotationMatrix(vector, angle, rotation_matrix);
  354.  
  355. //Rotate all the points
  356. for (int i = 0; i < point_size; i++)
  357. {
  358. points[i] = GetRotationResult(pivot, rotation_matrix, points[i]);
  359. }
  360.  
  361. for (int i = 0; i < outline_point_size; i++)
  362. {
  363. outline_points[i] = GetRotationResult(pivot, rotation_matrix, outline_points[i]);
  364. }
  365.  
  366. //Rotate the euler direction
  367. for (int i = 0; i < 3; i++)
  368. {
  369. euler[i] = GetRotationResult(pivot, rotation_matrix, euler[i], true);
  370. euler[i].Normalize(); //Normalize the euler since we only need the euler's direction
  371. }
  372.  
  373. //Rotate the normals
  374. for (int i = 0; i < normal_count; i++)
  375. {
  376. normals[i] = GetRotationResult(pivot, rotation_matrix, normals[i], true);
  377. }
  378.  
  379. position = GetRotationResult(pivot, rotation_matrix, position);
  380.  
  381. SetArrayBuffer();
  382. }
  383.  
  384. void Translate(const Vertex& movement)
  385. {
  386. for (int i = 0; i < point_size; i++)
  387. {
  388. points[i] = points[i] + movement;
  389. }
  390.  
  391. for (int i = 0; i < outline_point_size; i++)
  392. {
  393. outline_points[i] = outline_points[i] + movement;
  394. }
  395.  
  396. position = position + movement;
  397.  
  398. SetArrayBuffer();
  399. }
  400.  
  401. Vertex GetEuler(int index)
  402. {
  403. return euler[index];
  404. }
  405.  
  406. void ResetEuler()
  407. {
  408. euler[0] = Vertex(1, 0, 0);
  409. euler[1] = Vertex(0, 1, 0);
  410. euler[2] = Vertex(0, 0, 1);
  411. }
  412.  
  413. ~Shape()
  414. {
  415. delete points;
  416. glDeleteBuffers(1, &buffer);
  417. }
  418. };
  419.  
  420. class Mesh : public Shape
  421. {
  422. int vlib_count;
  423. int vnorm_count;
  424. Vertex* vlib;
  425. Vertex* vnorms;
  426. public:
  427. Mesh(const char file_name[], float _x = 0, float _y = 0, float _z = 0) : Shape(_x, _y, _z)
  428. {
  429. vlib_count = 0;
  430. vnorm_count = 0;
  431. point_size = 0;
  432. LoadVlib(file_name);
  433. GenerateOutlinePoints();
  434. GenerateColors();
  435. }
  436.  
  437. void GenerateColors()
  438. {
  439. color_size = point_size;
  440. base_colors = new Vertex[color_size];
  441. colors = new Vertex[color_size];
  442. for (int i = 0; i < color_size; i++)
  443. {
  444. base_colors[i] = Vertex(0.9f, 0.2f, 0.8f);
  445. }
  446. }
  447.  
  448. void CalculateColors(Vertex& light_source, Vertex& light_color, const Vertex& ambience_multiplier, Vertex& eye_pos, const float& specular_multiplier, const float& shinyness, const float& light_intensity)
  449. {
  450. for (int i = 0; i < point_size; i++)
  451. {
  452. int normal_index = i;
  453.  
  454. //Ambience
  455. Vertex ambience = base_colors[i] * ambience_multiplier;
  456.  
  457. //Diffuse
  458. Vertex light_vec = light_source - points[i];
  459. float light_distance = GetLength(light_vec);
  460. light_vec = light_vec * (1.0f / light_distance);
  461. float cos_angle = GetDotProduct(light_vec, normals[normal_index]);
  462. Vertex diffuse = base_colors[i] * ((cos_angle < 0) ? 0 : cos_angle);
  463.  
  464. //Specular
  465. Vertex eye_vec = eye_pos - points[i];
  466. float eye_distance = GetLength(eye_vec);
  467. eye_vec = eye_vec * (1.0f / eye_distance);
  468. Vertex R = normals[normal_index] * cos_angle * 2.0 - light_vec;
  469. R = R * (1.0f / GetLength(R));
  470. float spec = GetDotProduct(eye_vec, R);
  471. spec = (spec < 0) ? 0 : pow(spec, shinyness);
  472. Vertex specular = Vertex(0, 0, 0);
  473. if (spec > 0)
  474. {
  475. specular = light_color * specular_multiplier * spec;
  476. diffuse = diffuse * (1 - spec);
  477. }
  478.  
  479. //Combined
  480. colors[i] = (ambience + diffuse + specular) * (light_intensity / (pow(light_distance, 2.0)));
  481. }
  482. SetColorBuffer();
  483. }
  484.  
  485. void RandomizeColors()
  486. {
  487. for (int i = 0; i < color_size; i++)
  488. {
  489. float red = (float)(rand() % 100) / 100.0f;
  490. float green = (float)(rand() % 100) / 100.0f;
  491. float blue = (float)(rand() % 100) / 100.0f;
  492. colors[i] = Vertex(red, green, blue);
  493. }
  494. SetColorBuffer();
  495. }
  496.  
  497. void GenerateNormals()
  498. {
  499. normal_count = point_size / 3;
  500. normals = new Vertex[normal_count];
  501. for (int i = 0, j = 0; i < point_size; i += 3, j++)
  502. {
  503. normals[j] = GetNormal(points[i], points[i + 1], points[i + 2], true);
  504. normals[j].x = abs(normals[j].x);
  505. normals[j].y = abs(normals[j].y);
  506. normals[j].z = abs(normals[j].z);
  507. }
  508. }
  509.  
  510. void GenerateOutlinePoints()
  511. {
  512. outline_point_size = point_size * 2;
  513. outline_points = new Vertex[outline_point_size];
  514. for (int i = 0, j = 0; i < point_size; i += 3, j += 6)
  515. {
  516. int first_index = i;
  517. int second_index = i + 1;
  518. int third_index = i + 2;
  519.  
  520. outline_points[j] = points[first_index];
  521. outline_points[j + 1] = points[second_index];
  522. outline_points[j + 2] = points[second_index];
  523. outline_points[j + 3] = points[third_index];
  524. outline_points[j + 4] = points[third_index];
  525. outline_points[j + 5] = points[first_index];
  526. }
  527. }
  528.  
  529. void LoadVlib(const char file_name[])
  530. {
  531. std::string value;
  532. std::string line;
  533. std::ifstream mesh_file(file_name);
  534. if (mesh_file.is_open())
  535. {
  536. while (std::getline(mesh_file, line))
  537. {
  538. if (line.substr(0, line.find(" ")) == "v")
  539. {
  540. Vertex* temp;
  541. temp = vlib;
  542. vlib = new Vertex[vlib_count + 1];
  543. for (int i = 0; i < vlib_count; i++)
  544. {
  545. vlib[i] = temp[i];
  546. }
  547.  
  548. float* values = new float[3];
  549. int value_count = 0;
  550. while (line.length() > 0)
  551. {
  552. line = line.substr(line.find(" ") + 1);
  553. while (line[0] == ' ')
  554. {
  555. line = line.substr(line.find(" ") + 1);
  556. }
  557.  
  558. if (line.find(" ") != -1)
  559. {
  560. value = line.substr(0, line.find(" "));
  561. line = line.substr(line.find(" "));
  562.  
  563. }
  564. else
  565. {
  566. value = line;
  567. line = "";
  568. }
  569. values[value_count] = std::stof(value);
  570. value_count++;
  571. }
  572.  
  573. vlib[vlib_count].x = values[0];
  574. vlib[vlib_count].y = values[1];
  575. vlib[vlib_count].z = values[2];
  576.  
  577. vlib_count++;
  578.  
  579. delete[] temp;
  580. delete[] values;
  581. }
  582.  
  583. if (line.substr(0, line.find(" ")) == "vn")
  584. {
  585. Vertex* temp;
  586. temp = vnorms;
  587. vnorms = new Vertex[vnorm_count + 1];
  588. for (int i = 0; i < vnorm_count; i++)
  589. {
  590. vnorms[i] = temp[i];
  591. }
  592.  
  593. float* values = new float[3];
  594. int value_count = 0;
  595. //std::cout << line << "\n";
  596. while (line.length() > 0)
  597. {
  598. line = line.substr(line.find(" ") + 1);
  599. while (line[0] == ' ')
  600. {
  601. line = line.substr(line.find(" ") + 1);
  602. }
  603.  
  604. if (line.find(" ") != -1)
  605. {
  606. value = line.substr(0, line.find(" "));
  607. line = line.substr(line.find(" "));
  608.  
  609. }
  610. else
  611. {
  612. value = line;
  613. line = "";
  614. }
  615. //std::cout << value << "\n";
  616. values[value_count] = std::stof(value);
  617. value_count++;
  618. }
  619.  
  620. vnorms[vnorm_count].x = values[0];
  621. vnorms[vnorm_count].y = values[1];
  622. vnorms[vnorm_count].z = values[2];
  623.  
  624. vnorm_count++;
  625.  
  626. delete[] temp;
  627. delete[] values;
  628. }
  629.  
  630. if (line.substr(0, line.find(" ")) == "f")
  631. {
  632. Vertex* temp;
  633. Vertex* temp_n;
  634. temp = points;
  635. temp_n = normals;
  636. points = new Vertex[point_size + 3];
  637. normals = new Vertex[point_size + 3];
  638.  
  639. for (int i = 0; i < point_size; i++)
  640. {
  641. points[i] = temp[i];
  642. normals[i] = temp_n[i];
  643. }
  644.  
  645. int* values = new int[3];
  646. int* values_n = new int[3];
  647. int value_count = 0;
  648.  
  649. while (line.length() > 0)
  650. {
  651. line = line.substr(line.find(" ") + 1);
  652. while (line[0] == ' ')
  653. {
  654. line = line.substr(line.find(" ") + 1);
  655. }
  656.  
  657. if (line.find(" ") != -1)
  658. {
  659. value = line.substr(0, line.find(" "));
  660. line = line.substr(line.find(" "));
  661.  
  662. }
  663. else
  664. {
  665. value = line;
  666. line = "";
  667. }
  668.  
  669. std::string value_input = value.substr(0, value.find("/"));
  670. values[value_count] = std::stoi(value_input);
  671.  
  672. value = value.substr(value.find("/") + 1); //vt
  673. value = value.substr(value.find("/") + 1); //vn
  674.  
  675. value_input = value.substr(0, value.find("/"));
  676. values_n[value_count] = std::stoi(value_input);
  677.  
  678. value_count++;
  679. }
  680.  
  681. for (int i = 0; i < 3; i++)
  682. {
  683. points[point_size + i].x = vlib[values[i] - 1].x * 0.1f;
  684. points[point_size + i].y = vlib[values[i] - 1].y * 0.1f;
  685. points[point_size + i].z = vlib[values[i] - 1].z * 0.1f;
  686.  
  687. normals[point_size + i].x = vnorms[values_n[i] - 1].x;
  688. normals[point_size + i].y = vnorms[values_n[i] - 1].y;
  689. normals[point_size + i].z = vnorms[values_n[i] - 1].z;
  690. }
  691.  
  692. point_size += 3;
  693.  
  694. delete[] temp;
  695. delete[] temp_n;
  696. delete[] values;
  697. delete[] values_n;
  698. }
  699. }
  700. mesh_file.close();
  701. normal_count = point_size;
  702. //ShowPoints();
  703. }
  704. }
  705. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement