Advertisement
shek15470

Untitled

Jun 14th, 2021
1,505
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.15 KB | None | 0 0
  1. #define GL_SILENCE_DEPRECATION //Убираем предупреждения
  2. #define _USE_MATH_DEFINES
  3.  
  4. #include "GLFW/glfw3.h"
  5. #include <stdlib.h>
  6. #include <math.h>
  7. #include <iostream>
  8. #include <cstring>
  9. #include <vector>
  10. #include <ctime>
  11. #include <sstream>
  12. #include <fstream>
  13. #include <time.h>
  14.  
  15. #define SQUARE(a) a * a
  16. #define MODULE_FRICTION_FORCE 10.f
  17. #define MODULE_PULLING_FORCE 10.5f
  18. #define WALL_POS_1 15.f
  19. #define WALL_POS_2 -10.f
  20. GLint w, h;
  21.  
  22. class Point
  23. {
  24.  
  25. public:
  26.  
  27.     long double x;
  28.     long double y;
  29.     long double z;
  30.  
  31.     Point( long double pX , long double pY, long double pZ ){
  32.         x = pX;
  33.         y = pY;
  34.         z = pZ;
  35.     }
  36.     friend bool operator == (const Point & c1,
  37.                              const Point & c2) {
  38.         return c1.x == c2.x && c1.y == c2.y && c1.z == c2.z;
  39.     }
  40. };
  41.  
  42. class vertex {
  43. public:
  44.     Point coord = Point(0,0,0);
  45.     Point norm_vector = Point(0,0,0);
  46. };
  47.  
  48. double sqr(double x) {return x * x; }
  49.  
  50. class Poly
  51. {
  52. public:
  53.     std::vector <vertex> points;
  54.     Point poly_normal = Point(0,0,0);
  55.  
  56.     Poly(Point p1 , Point p2, Point p3){
  57.         vertex x, y, z;
  58.         x.coord = p1;
  59.         y.coord = p2;
  60.         z.coord = p3;
  61.         points.push_back(x); points.push_back(y); points.push_back(z);
  62.     }
  63.  
  64.     void CalcNormals()
  65.     {
  66.         Point a = points[0].coord;
  67.         Point b = points[1].coord;
  68.         Point c = points[2].coord;
  69.  
  70.         long double wrki;
  71.         Point v1 = Point(a.x - b.x, a.y - b.y, a.z - b.z);
  72.         Point v2 = Point(b.x - c.x, b.y - c.y, b.z - c.z);
  73.  
  74.         wrki = sqrt(sqr(v1.y*v2.z - v1.z * v2.y) + sqr(v1.z * v2.x - v1.x * v2.z) + sqr(v1.x * v2.y - v1.y * v2.x));
  75.  
  76.         poly_normal = Point((v1.y * v2.z - v1.z * v2.y) / wrki, (v1.z * v2.x - v1.x * v2.z) / wrki, (v1.x * v2.y - v1.y * v2.x) / wrki);
  77.     }
  78.  
  79.     bool has_vertex(vertex p){
  80.         for (int i = 0; i < points.size(); i++){
  81.             if (points[i].coord == p.coord){
  82.                 return true;
  83.             }
  84.         }
  85.         return false;
  86.     }
  87. };
  88.  
  89. using namespace std;
  90. enum asics{X, Y, Z};
  91. bool light_on = false;
  92. bool normal_flag = false;
  93. bool animation = false;
  94. float move_X = 0.0f;
  95. float move_Y = 0.0f;
  96. float move_Z = 0.0f;
  97. float rot_X = 0.0f;
  98. float rot_Y = 0.0f;
  99. float rot_Z = 0.0f;
  100.  
  101.  
  102. GLuint  box;
  103. GLuint  fig;
  104. GLuint  norm;
  105.  
  106. int current_asic = X;
  107. int change_height = 100;
  108. int num_poly = 6;
  109. float mode = GL_LINE_LOOP;
  110. vector < vector <Point> > figure;
  111. vector < Poly > poly_fig;
  112.  
  113.  
  114. void resize_callback(GLFWwindow *window, int new_w, int new_h) {
  115.     w = new_w, h = new_h;
  116. }
  117.  
  118. void drawcube(){
  119.     glBegin(GL_QUADS);
  120.     glColor3f(0.0,1.0,0.0);
  121.     glVertex3f( 1.0, 1.0,-1.0);
  122.     glVertex3f(-1.0, 1.0,-1.0);
  123.     glVertex3f(-1.0, 1.0, 1.0);
  124.     glVertex3f( 1.0, 1.0, 1.0);
  125.     glEnd();
  126.     glBegin(GL_QUADS);
  127.     glColor3f(1.0,0.5,0.0);
  128.     glVertex3f( 1.0,-1.0, 1.0);
  129.     glVertex3f(-1.0,-1.0, 1.0);
  130.     glVertex3f(-1.0,-1.0,-1.0);
  131.     glVertex3f( 1.0,-1.0,-1.0);
  132.     glEnd();
  133.     glBegin(GL_QUADS);
  134.     glColor3f(1.0,0.0,0.0);
  135.     glVertex3f( 1.0, 1.0, 1.0);
  136.     glVertex3f(-1.0, 1.0, 1.0);
  137.     glVertex3f(-1.0,-1.0, 1.0);
  138.     glVertex3f( 1.0,-1.0, 1.0);
  139.     glEnd();
  140.     glBegin(GL_QUADS);
  141.     glColor3f(1.0,1.0,0.0);
  142.     glVertex3f( 1.0,-1.0,-1.0);
  143.     glVertex3f(-1.0,-1.0,-1.0);
  144.     glVertex3f(-1.0, 1.0,-1.0);
  145.     glVertex3f( 1.0, 1.0,-1.0);
  146.     glEnd();
  147.     glBegin(GL_QUADS);
  148.     glColor3f(0.0,0.0,1.0);
  149.     glVertex3f(-1.0, 1.0, 1.0);
  150.     glVertex3f(-1.0, 1.0,-1.0);
  151.     glVertex3f(-1.0,-1.0,-1.0);
  152.     glVertex3f(-1.0,-1.0, 1.0);
  153.     glEnd();
  154.     glBegin(GL_QUADS);
  155.     glColor3f(1.0,0.0,1.0);
  156.     glVertex3f( 1.0, 1.0,-1.0);
  157.     glVertex3f( 1.0, 1.0, 1.0);
  158.     glVertex3f( 1.0,-1.0, 1.0);
  159.     glVertex3f( 1.0,-1.0,-1.0);
  160.     glEnd();
  161.  
  162. }
  163.  
  164. void create_list_box(){ //Оптимизация 3 дисплейный список
  165.     box = glGenLists(1);
  166.     glNewList( box, GL_COMPILE );
  167.     drawcube();
  168.     glEndList();
  169. }
  170.  
  171. void connect_Poly(vector <Point> cir1, vector <Point> cir2){
  172.  
  173.     for (int j = 0; j < cir1.size(); j+=num_poly ){
  174.         float near = j + num_poly;
  175.         if (j + num_poly >= cir1.size()){ near = 0; }
  176.  
  177.         Poly tr1 = Poly(cir1[j], cir2[j], cir2[near]);
  178.         tr1.CalcNormals();
  179.         if (!isnan(tr1.poly_normal.x)) poly_fig.push_back(tr1);
  180.  
  181.  
  182.         Poly tr2 = Poly(cir1[near], cir1[j], cir2[near]);
  183.         tr2.CalcNormals();
  184.         if (!isnan(tr2.poly_normal.x)) poly_fig.push_back(tr2);
  185.     }
  186. }
  187.  
  188. void draw_normals(){
  189.     for (int j = 0; j < poly_fig.size(); j++){
  190.         Poly trinagle = poly_fig[j];
  191.  
  192.         for (int i = 0; i < trinagle.points.size(); i++){
  193.             vertex triangle_vert = trinagle.points[i];
  194.             glColor3f(1,1,1);
  195.             glBegin(GL_LINES);
  196.             glVertex3f(triangle_vert.coord.x, triangle_vert.coord.y, triangle_vert.coord.z);
  197.             glVertex3f(triangle_vert.coord.x + triangle_vert.norm_vector.x, triangle_vert.coord.y + triangle_vert.norm_vector.y, triangle_vert.coord.z + triangle_vert.norm_vector.z);
  198.             glEnd();
  199.         }
  200.     }
  201. }
  202.  
  203. void draw_poly(){
  204.  
  205.     for (int j = 0; j < poly_fig.size(); j++){
  206.         Poly triangle = poly_fig[j];
  207.         glColor3f(0,1,0);
  208.         glBegin(mode);
  209.  
  210.         for (int v = 0; v < triangle.points.size(); v++){
  211.             glNormal3f(triangle.points[v].norm_vector.x, triangle.points[v].norm_vector.y, triangle.points[v].norm_vector.z);
  212.             glVertex3f(triangle.points[v].coord.x, triangle.points[v].coord.y, triangle.points[v].coord.z);
  213.         }
  214.  
  215.         glEnd();
  216.     }
  217. }
  218.  
  219. void countNormal(vertex &x){
  220.  
  221.     vector < Poly > all_poly_with_cur_vert;
  222.     long double x_normal = 0.f;
  223.     long double y_normal = 0.f;
  224.     long double z_normal = 0.f;
  225.  
  226.     for (int i = 0; i < poly_fig.size(); i++){
  227.         Poly triangle = poly_fig[i];
  228.         if (triangle.has_vertex(x)){
  229.             all_poly_with_cur_vert.push_back(triangle);
  230.         }
  231.     }
  232.  
  233.     for (int i = 0; i < all_poly_with_cur_vert.size(); i++){
  234.         Poly tmp = all_poly_with_cur_vert[i];
  235.         x_normal += tmp.poly_normal.x;
  236.         y_normal += tmp.poly_normal.y;
  237.         z_normal += tmp.poly_normal.z;
  238.     }
  239.  
  240.     x_normal = x_normal / double(all_poly_with_cur_vert.size());
  241.     y_normal = y_normal / double(all_poly_with_cur_vert.size());
  242.     z_normal = z_normal / double(all_poly_with_cur_vert.size());
  243.     x.norm_vector.x = x_normal;
  244.     x.norm_vector.y = y_normal;
  245.     x.norm_vector.z = z_normal;
  246.  
  247. }
  248.  
  249. void rebuild(){
  250.     poly_fig.clear();
  251.     int i = 0;
  252.     for (; i < figure.size() - change_height; i+= change_height){
  253.         connect_Poly(figure[i], figure[i+change_height]);
  254.     }
  255.     connect_Poly(figure[i], figure[figure.size() - 1]);
  256.  
  257.     for (int i = 0; i < poly_fig.size(); i++){
  258.         countNormal(poly_fig[i].points[0]);
  259.         countNormal(poly_fig[i].points[1]);
  260.         countNormal(poly_fig[i].points[2]);
  261.     }
  262. }
  263.  
  264. void create_list_fig(){
  265.     glDeleteLists(fig, 1);
  266.     fig = glGenLists(1);
  267.     rebuild();
  268.     glNewList( fig , GL_COMPILE );
  269.     draw_poly();
  270.     glEndList();
  271.  
  272.     glDeleteLists(norm, 1);
  273.     norm = glGenLists(1);
  274.     glNewList( norm , GL_COMPILE );
  275.     draw_normals();
  276.     glEndList();
  277. }
  278.  
  279. void create_circles(float a, float b, float c, float height){
  280.     vector <Point> circle;
  281.     float level = 1 + ( SQUARE(height) / SQUARE(c) );
  282.     for(float i = 0; i <= 2* M_PI; i+=0.1f ) {
  283.         float high_part_drob = (a*a) * (b*b) * level;
  284.         float low_part_drob = ((b*b) * (cosf(i) * cosf(i))) + ((a*a) * (sinf(i) * sinf(i))) ;
  285.         float r = sqrtf( high_part_drob / low_part_drob );
  286.         circle.push_back(Point(cosf( i ) * r, height, sinf( i ) * r));
  287.     }
  288.     figure.push_back(circle);
  289. }
  290.  
  291. void create_fig(float a, float b, float c, float height_low, float height_high){
  292.     float h = height_low;
  293.     while (h <= height_high){
  294.         create_circles(a, b, c, h);
  295.         h+=0.008f;
  296.     }
  297.     create_circles(a, b, c, h);
  298. }
  299.  
  300. float begin_s = 0.0f;
  301. bool pos = true;
  302.  
  303. bool move_1(float result_force_module){
  304.     if (begin_s <= WALL_POS_1){
  305.         move_X -= result_force_module;
  306.         begin_s += result_force_module;
  307.         return true;
  308.     }
  309.     return false;
  310. }
  311.  
  312. bool move_2(float result_force_module){
  313.     if (begin_s >= WALL_POS_2){
  314.         move_X += result_force_module;
  315.         begin_s -= result_force_module;
  316.         return false;
  317.     }
  318.     return true;
  319. }
  320.  
  321. void move_fig_to_wall(){
  322.     float result_force_module = MODULE_PULLING_FORCE - MODULE_FRICTION_FORCE;
  323.     if (result_force_module <= 0){
  324.         glCallList(fig);
  325.     }
  326.     else {
  327.         if (pos) pos = move_1(result_force_module);
  328.         else pos = move_2(result_force_module);
  329.     }
  330.     glCallList(fig);
  331. }
  332.  
  333. void renderScene(void) {
  334.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  335.  
  336.     glLoadIdentity();
  337.     glTranslated(-5.0f, 0.0f,-6.0f);
  338.     glCallList(box);
  339.  
  340.     glLoadIdentity();
  341.     glTranslated(0.0f, 0.0f, -2.0f);
  342.     glTranslated(move_X, move_Y, move_Z);
  343.     glRotatef(rot_Z, 0, 0, 1);
  344.     glRotatef(rot_X, 1, 0, 0);
  345.     glRotatef(rot_Y, 0, 1, 0);
  346.     if (animation) move_fig_to_wall();
  347.     if (!animation) glCallList(fig);
  348.     if(normal_flag) glCallList(norm);
  349.     glLoadIdentity();
  350. }
  351.  
  352. void Save_scene(){
  353.     std::ofstream st("scene.txt");
  354.     st << rot_X << endl;
  355.     st << rot_Y << endl;
  356.     st << rot_Z << endl;
  357.     st << move_X << endl;
  358.     st.close();
  359. }
  360.  
  361.  
  362. void load_scene(){
  363.     std::ifstream st("scene.txt");
  364.     float p;
  365.     int pos = 0;
  366.     while(st){
  367.         st >> p;
  368.         if (pos == 0){rot_X = p;}
  369.         if (pos == 1){rot_Y = p;}
  370.         if (pos == 2){rot_Z = p;}
  371.         if (pos == 3){move_X = p;}
  372.         pos++;
  373.     }
  374.     cout << rot_X << rot_Y << animation << light_on;
  375.     st.close();
  376. }
  377.  
  378.  
  379.  
  380. void light_enable()
  381. {
  382.     glShadeModel(GL_SMOOTH);
  383.  
  384.     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); //Оптимизация 2 Отключение двухстороннего освещения
  385.  
  386.     GLfloat amb[] = {.8f, .8f, .8f, 1.f};
  387.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
  388.  
  389.     GLfloat lightPos[] = {0.f, 0, 0.f, -10.f};
  390.     glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  391.  
  392.     GLfloat light_amb[] = {.75f, .75f, .75f, 1.f};
  393.     glLightfv(GL_LIGHT0, GL_AMBIENT, light_amb);
  394.  
  395.     GLfloat light_diff[] = {.75f, .75f, .75f, 1.f};
  396.     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diff);
  397.  
  398.     GLfloat light_spec[] = {7.5f, 7.5f, 7.5f, 1.f};
  399.     glLightfv(GL_LIGHT0, GL_SPECULAR, light_spec);
  400.  
  401.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.5f);
  402.     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, .5f);
  403.     glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, .01f);
  404. }
  405.  
  406. void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
  407.     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
  408.         glfwSetWindowShouldClose(window, GL_TRUE);
  409.     }
  410.  
  411.     else if (key == GLFW_KEY_A && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  412.         if (num_poly == 16) {}
  413.         else{ num_poly++; create_list_fig(); }
  414.     }
  415.  
  416.     else if (key == GLFW_KEY_N && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  417.         if(normal_flag) { normal_flag = false; }
  418.         else { normal_flag = true; };
  419.     }
  420.  
  421.     else if (key == GLFW_KEY_X && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  422.         current_asic = X;
  423.     }
  424.  
  425.     else if (key == GLFW_KEY_Y && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  426.         current_asic = Y;
  427.     }
  428.  
  429.     else if (key == GLFW_KEY_Z && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  430.         current_asic = Z;
  431.     }
  432.  
  433.     else if (key == GLFW_KEY_W && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  434.         if (change_height == 1) {}
  435.         else { change_height = change_height - 1; create_list_fig();}
  436.     }
  437.  
  438.     else if (key == GLFW_KEY_S && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  439.         change_height = change_height + 1; create_list_fig();
  440.     }
  441.  
  442.     else if (key == GLFW_KEY_M && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  443.         if (mode == GL_TRIANGLES){ mode = GL_LINE_LOOP; create_list_fig();}
  444.         else { mode = GL_TRIANGLES; create_list_fig();}
  445.     }
  446.  
  447.     else if (key == GLFW_KEY_L && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  448.         if (light_on){
  449.             glDisable(GL_LIGHTING);
  450.             glDisable(GL_LIGHT0);
  451.             light_on = false;
  452.         }
  453.         else {
  454.             glEnable(GL_LIGHTING);
  455.             glEnable(GL_LIGHT0);
  456.             light_enable();
  457.             light_on = true;
  458.         }
  459.     }
  460.  
  461.  
  462.     else if (key == GLFW_KEY_F && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  463.         if (animation) { animation = false; }
  464.         else { animation = true; }
  465.     }
  466.  
  467.     else if (key == GLFW_KEY_D && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  468.         if (num_poly == 1) {}
  469.         else {num_poly--; create_list_fig();}
  470.     }
  471.  
  472.     else if (key == GLFW_KEY_LEFT && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  473.         if (current_asic == Z) { move_Z-= 0.1f; }
  474.         if (current_asic == X) { move_X-= 0.1f; }
  475.         if (current_asic == Y) { move_Y-= 0.1f; }
  476.     }
  477.  
  478.     else if (key == GLFW_KEY_RIGHT && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  479.         if (current_asic == Z) { move_Z+= 0.1f; }
  480.         if (current_asic == X) { move_X+= 0.1f; }
  481.         if (current_asic == Y) { move_Y+= 0.1f; }
  482.     }
  483.  
  484.     else if (key == GLFW_KEY_UP && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  485.         if (current_asic == Z) { rot_Z+= 0.4f; }
  486.         if (current_asic == X) { rot_X+= 0.4f; }
  487.         if (current_asic == Y) { rot_Y+= 0.4f; }
  488.     }
  489.  
  490.     else if (key == GLFW_KEY_DOWN && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  491.         if (current_asic == Z) { rot_Z-= 0.4f; }
  492.         if (current_asic == X) { rot_X-= 0.4f; }
  493.         if (current_asic == Y) { rot_Y-= 0.4f; }
  494.     }
  495.  
  496.     else if (key == GLFW_KEY_P && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  497.         if (current_asic == Z) { rot_Z-= 0.4f; }
  498.         if (current_asic == X) { rot_X-= 0.4f; }
  499.         if (current_asic == Y) { rot_Y-= 0.4f; }
  500.     }
  501.  
  502.     else if (key == GLFW_KEY_G && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  503.         Save_scene();
  504.     }
  505.  
  506.     else if (key == GLFW_KEY_B && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  507.         load_scene();
  508.     }
  509.  
  510.  
  511. }
  512.  
  513. void projection(GLint width, GLint height) {
  514.  
  515.     GLfloat k = 0.07;
  516.  
  517.     GLfloat project[] = {
  518.             1.f, 0.f, 0.f, 0.0f,
  519.             0.f, 1.f, 0.f, 0.f,
  520.             0.f, 0.f, 1.f, 0.0f,
  521.             0.f, 0.f, 0.f, 1.f};
  522.  
  523.     glMatrixMode(GL_PROJECTION);
  524.     glLoadIdentity();
  525.  
  526.     glMultMatrixf(project);
  527.  
  528.     glOrtho(-w * k / 2, w * k / 2, -h * k / 2,
  529.             h * k / 2, -(w * k + h * k) / 4, (w * k + h * k) / 4);
  530.  
  531. }
  532.  
  533. int main(int argc, char **argv) {
  534.     float a = 3.0f;
  535.     float b = 2.0f;
  536.     float c = 0.1f;
  537.     float z_low = -5.0f;
  538.     float z_high = 5.0f;
  539.  
  540.     if (!glfwInit()) {
  541.         fprintf(stderr, "Failed to initialize GLFW\n");
  542.         exit(EXIT_FAILURE);
  543.     }
  544.  
  545.     GLFWwindow
  546.             *window = glfwCreateWindow(800, 800, "Lab6", nullptr, nullptr);
  547.     if (!window) {
  548.         fprintf(stderr, "Failed to open GLFW window.\n");
  549.         glfwTerminate();
  550.         exit(EXIT_FAILURE);
  551.     }
  552.  
  553.     glfwMakeContextCurrent(window);
  554.     glfwSetKeyCallback(window, key_callback);
  555.     glfwSetWindowSizeCallback(window, resize_callback);
  556.  
  557.     glfwGetFramebufferSize(window, &w, &h);
  558.  
  559.     create_fig(a, b, c, z_low, z_high);
  560.     create_list_box();
  561.     create_list_fig();
  562.  
  563.     glEnable(GL_DEPTH_TEST); // Оптимизация 1 отключение теста глубины
  564.     glDepthFunc(GL_LEQUAL);
  565.     glEnable(GL_NORMALIZE);
  566.     //glEnable(GL_CULL_FACE); //Оптимизация 4 отброс невидимых граней
  567.  
  568.     while (!glfwWindowShouldClose(window)) {
  569.  
  570.         glClearColor(0, 0, 0, 0);
  571.         glClear(GL_COLOR_BUFFER_BIT);
  572.         glClear(GL_DEPTH_BUFFER_BIT);
  573.  
  574.         glViewport(0, 0, w, h);
  575.         projection(w, h);
  576.         glMatrixMode(GL_MODELVIEW);
  577.         renderScene();
  578.  
  579.         glfwPollEvents();
  580.         glfwSwapBuffers(window);
  581.     }
  582.     glfwDestroyWindow(window);
  583.     glfwTerminate();
  584. }
  585.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement