shek15470

Untitled

Jun 14th, 2021
677
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define GL_SILENCE_DEPRECATION //Убираем предупреждения
  2. #define _USE_MATH_DEFINES
  3. //#include "GL/glew.h"
  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(){
  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(){ //как дисплейный список для нашей фигуры 7 лаба
  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 light_enable()
  353. {
  354.     glShadeModel(GL_SMOOTH);
  355.  
  356.     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  357.  
  358.     GLfloat amb[] = {.8f, .8f, .8f, 1.f};
  359.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
  360.  
  361.     GLfloat lightPos[] = {0.f, 0, 0.f, -10.f};
  362.     glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  363.  
  364.     GLfloat light_amb[] = {.75f, .75f, .75f, 1.f};
  365.     glLightfv(GL_LIGHT0, GL_AMBIENT, light_amb);
  366.  
  367.     GLfloat light_diff[] = {.75f, .75f, .75f, 1.f};
  368.     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diff);
  369.  
  370.     GLfloat light_spec[] = {7.5f, 7.5f, 7.5f, 1.f};
  371.     glLightfv(GL_LIGHT0, GL_SPECULAR, light_spec);
  372.  
  373.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.5f);
  374.     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, .5f);
  375.     glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, .01f);
  376. }
  377.  
  378. void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
  379.     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
  380.         glfwSetWindowShouldClose(window, GL_TRUE);
  381.     }
  382.  
  383.     else if (key == GLFW_KEY_A && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  384.         if (num_poly == 16) {}
  385.         else{ num_poly++; create_list_fig(); }
  386.     }
  387.  
  388.     else if (key == GLFW_KEY_N && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  389.         if(normal_flag) { normal_flag = false; }
  390.         else { normal_flag = true; };
  391.     }
  392.  
  393.     else if (key == GLFW_KEY_X && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  394.         current_asic = X;
  395.     }
  396.  
  397.     else if (key == GLFW_KEY_Y && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  398.         current_asic = Y;
  399.     }
  400.  
  401.     else if (key == GLFW_KEY_Z && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  402.         current_asic = Z;
  403.     }
  404.  
  405.     else if (key == GLFW_KEY_W && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  406.         if (change_height == 1) {}
  407.         else { change_height = change_height - 1; create_list_fig();}
  408.     }
  409.  
  410.     else if (key == GLFW_KEY_S && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  411.         change_height = change_height + 1; create_list_fig();
  412.     }
  413.  
  414.     else if (key == GLFW_KEY_M && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  415.         if (mode == GL_TRIANGLES){ mode = GL_LINE_LOOP; create_list_fig();}
  416.         else { mode = GL_TRIANGLES; create_list_fig();}
  417.     }
  418.  
  419.     else if (key == GLFW_KEY_L && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  420.         if (light_on){
  421.             glDisable(GL_LIGHTING);
  422.             glDisable(GL_LIGHT0);
  423.             light_on = false;
  424.         }
  425.         else {
  426.             glEnable(GL_LIGHTING);
  427.             glEnable(GL_LIGHT0);
  428.             light_enable();
  429.             light_on = true;
  430.         }
  431.     }
  432.  
  433.  
  434.     else if (key == GLFW_KEY_F && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  435.         if (animation) { animation = false; }
  436.         else { animation = true; }
  437.     }
  438.  
  439.     else if (key == GLFW_KEY_D && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  440.         if (num_poly == 1) {}
  441.         else {num_poly--; create_list_fig();}
  442.     }
  443.  
  444.     else if (key == GLFW_KEY_LEFT && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  445.         if (current_asic == Z) { move_Z-= 0.1f; }
  446.         if (current_asic == X) { move_X-= 0.1f; }
  447.         if (current_asic == Y) { move_Y-= 0.1f; }
  448.     }
  449.  
  450.     else if (key == GLFW_KEY_RIGHT && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  451.         if (current_asic == Z) { move_Z+= 0.1f; }
  452.         if (current_asic == X) { move_X+= 0.1f; }
  453.         if (current_asic == Y) { move_Y+= 0.1f; }
  454.     }
  455.  
  456.     else if (key == GLFW_KEY_UP && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  457.         if (current_asic == Z) { rot_Z+= 0.4f; }
  458.         if (current_asic == X) { rot_X+= 0.4f; }
  459.         if (current_asic == Y) { rot_Y+= 0.4f; }
  460.     }
  461.  
  462.     else if (key == GLFW_KEY_DOWN && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
  463.         if (current_asic == Z) { rot_Z-= 0.4f; }
  464.         if (current_asic == X) { rot_X-= 0.4f; }
  465.         if (current_asic == Y) { rot_Y-= 0.4f; }
  466.     }
  467.  
  468.  
  469. }
  470.  
  471. void projection(GLint width, GLint height) { //как я хочу видеть фигуру
  472.  
  473.     GLfloat k = 0.07;
  474.  
  475.     GLfloat project[] = {
  476.             1.f, 0.f, 0.f, 0.0f,
  477.             0.f, 1.f, 0.f, 0.f,
  478.             0.f, 0.f, 1.f, 0.0f,
  479.             0.f, 0.f, 0.f, 1.f};
  480.  
  481.     glMatrixMode(GL_PROJECTION);
  482.     glLoadIdentity();
  483.  
  484.     glMultMatrixf(project);
  485.  
  486.     glOrtho(-w * k / 2, w * k / 2, -h * k / 2,
  487.             h * k / 2, -(w * k + h * k) / 4, (w * k + h * k) / 4);
  488.  
  489. }
  490.  
  491. int main(int argc, char **argv) {
  492.     float a = 3.0f;
  493.     float b = 2.0f;
  494.     float c = 0.1f;
  495.     float z_low = -5.0f;
  496.     float z_high = 5.0f;
  497.  
  498.     if (!glfwInit()) {
  499.         fprintf(stderr, "Failed to initialize GLFW\n");
  500.         exit(EXIT_FAILURE);
  501.     }
  502.  
  503.     GLFWwindow
  504.             *window = glfwCreateWindow(800, 800, "Lab6", nullptr, nullptr);
  505.     if (!window) {
  506.         fprintf(stderr, "Failed to open GLFW window.\n");
  507.         glfwTerminate();
  508.         exit(EXIT_FAILURE);
  509.     }
  510.  
  511.     glfwMakeContextCurrent(window);
  512.     glfwSetKeyCallback(window, key_callback);
  513.     glfwSetWindowSizeCallback(window, resize_callback);
  514.  
  515.     glfwGetFramebufferSize(window, &w, &h);
  516.  
  517.     create_fig(a, b, c, z_low, z_high);
  518.     create_list_box();
  519.     create_list_fig();
  520.  
  521.     glEnable(GL_DEPTH_TEST);
  522.     glDepthFunc(GL_LEQUAL);
  523.     glEnable(GL_NORMALIZE);
  524.  
  525.  
  526.     while (!glfwWindowShouldClose(window)) {
  527.  
  528.         glClearColor(0, 0, 0, 0);
  529.         glClear(GL_COLOR_BUFFER_BIT);
  530.         glClear(GL_DEPTH_BUFFER_BIT);
  531.  
  532.         glViewport(0, 0, w, h);
  533.         projection(w, h);
  534.         glMatrixMode(GL_MODELVIEW);
  535.         renderScene();
  536.  
  537.         glfwPollEvents();
  538.         glfwSwapBuffers(window);
  539.     }
  540.     glfwDestroyWindow(window);
  541.     glfwTerminate();
  542. }
  543.  
RAW Paste Data