Advertisement
_freez

Untitled

May 20th, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 26.24 KB | None | 0 0
  1. // glfw_30.cpp : Defines the entry point for the console application.
  2. //  http://www.glfw.org/docs/latest/quick.html
  3.  
  4. #include "stdafx.h"
  5. #include "Math.h"
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include <vector>
  10. #include <iostream>
  11. #include <fstream>
  12. #include <iomanip>
  13. #include <cstdio>
  14. #include <time.h>
  15. #include <tchar.h>
  16. #include <windows.h>
  17.  
  18. const float M_PI = 3.14f;
  19. using namespace std;
  20.  
  21. #define SCREEN_WIDTH 600      
  22. #define SCREEN_HEIGHT 600
  23. #define SCREEN_RATIO float(SCREEN_HEIGHT)/float(SCREEN_WIDTH)
  24. #define ROTATE_EPS 0.05f
  25. #define START_X_ANGLE 0
  26. #define START_X 360-START_X_ANGLE
  27. #define START_Y_ANGLE 0
  28. #define START_Y 360-START_Y_ANGLE
  29. #define CAMERA_EPS 0.0002f
  30. #define MOVEMENT_EPS 0.0005f
  31. #define X 1
  32. #define Y 2
  33. #define Z 3
  34. #define MAX_VERTECES 100
  35.  
  36. // оптимизация 1 - использование векторной версии glVertex
  37. //#define OPTIMIZATION1
  38. // оптимизация 2 - отключение нормализации векторов нормалей
  39. //#define OPTIMIZATION2
  40. // оптимизация 3 - отключение интерполяции цветов
  41. //#define OPTIMIZATION3
  42. // оптимизация 4 - использование текстуры меньшего размера (64*64 вместо 256*256)
  43. //#define OPTIMIZATION4
  44. // оптимизация 5 - дисплейные списки
  45. #define OPTIMIZATION5
  46.  
  47. double A, B, C, D;
  48. double screen_width, screen_height;
  49. char rotate_x_flag = 0, rotate_y_flag = 0, fill_flag = 0, rotate_x_ret_flag = 0, rotate_y_ret_flag = 0, camera_rotate_x = 0, camera_rotate_y = 0,
  50. cameraX_ret_flag = 0, cameraY_ret_flag = 0, cameraZ_ret_flag = 0, cube_or_cyl_flag = 0, left_button = 0, d2_flag = 0, texture_flag = 1;
  51. float rotate_x = 0, rotate_y = 0, scale = 1.0f, angleX = 0, angleY = 0, cursorX = 0, cursorY = 0;
  52. float camera[3] = { 0.0f, 0.0f, 0.3f };
  53. float target[3] = { 0.0f, 0.0f, 0.0f };
  54. int numb = 10;
  55. float modelview_matrix[16];
  56. unsigned long long time_counter = 0;
  57. unsigned int texture[1];
  58.  
  59. struct Point3D { float x, y, z; };
  60. typedef Point3D Vector3D;
  61.  
  62. Vector3D movement_vector, displacement;
  63.  
  64. bool check(char m, float a) {
  65.     switch (m) {
  66.     case X:
  67.         return (((a > -1) || (movement_vector.x > 0)) && ((a < 1) || (movement_vector.x < 0)));
  68.     case Y:
  69.         return (((a > -1) || (movement_vector.y > 0)) && ((a < 1) || (movement_vector.y < 0)));
  70.     case Z:
  71.         return (((a > -1) || (movement_vector.z > 0)) && ((a < 1) || (movement_vector.z < 0)));
  72.     }
  73.     return false;
  74. }
  75.  
  76. class Cylinder {
  77. private:
  78.     int amount;
  79.     float radius_a, radius_b;
  80.     /*float top_center[3] = { 0.0f, 0.0f, 0.1f }, bottom_center[3] = { 0.0f, 0.0f, -0.1f };*/
  81.     Point3D top_center, bottom_center;
  82.     Point3D **matrix, **top, **bottom;
  83.     int fast_draw;
  84.  
  85. public:
  86.     Cylinder(int n, float bottom_center_init_y, float top_center_init_y, float radius_a_init, float radius_b_init) {
  87.         this->top_center.x = 0.0f;
  88.         this->top_center.y = top_center_init_y;
  89.         this->top_center.z = 0.1f;
  90.         this->bottom_center.x = 0.0f;
  91.         this->bottom_center.y = bottom_center_init_y;
  92.         this->bottom_center.z = -0.1f;
  93.         this->radius_a = radius_a_init;
  94.         this->radius_b = radius_b_init;
  95.         matrix = NULL;
  96.         top = NULL;
  97.         bottom = NULL;
  98.         update(n);
  99.     }
  100.  
  101.     int get_vertices_count() {
  102.         return amount;
  103.     }
  104.  
  105.     volatile void update(int n)     {
  106.         Point3D **matrix_x = (Point3D**)malloc(sizeof(Point3D*)*n);
  107.         if (matrix_x != NULL) {
  108.             for (int i = 0; i < n; i++) {
  109.                 matrix_x[i] = (Point3D*)malloc(sizeof(Point3D)*n);
  110.                 if (matrix_x == NULL) return;
  111.             }
  112.             int i = 0, j = 0;
  113.             for (float t = 0; i < n; t += 2 * M_PI / n) {
  114.                 for (j = 0; j < n; j++) {
  115.                     matrix_x[j][i].x = radius_a * sin(t) - j*(top_center.x - bottom_center.x) / (n - 1);
  116.                     matrix_x[j][i].y = top_center.y - j*(top_center.y - bottom_center.y) / (n - 1);
  117.                     matrix_x[j][i].z = radius_b * cos(t) - j*(top_center.z - bottom_center.z) / (n - 1);
  118.                 }
  119.                 i++;
  120.             }
  121.             for (int i = 0; i < amount; i++) free(matrix[i]);
  122.             free(matrix);
  123.             matrix = matrix_x;
  124.         }
  125.  
  126.         Point3D **top_x = (Point3D**)malloc(sizeof(Point3D*)*n);
  127.         if (top_x != NULL) {
  128.             for (int i = 0; i < n; i++) {
  129.                 top_x[i] = (Point3D*)malloc(sizeof(Point3D)*n);
  130.                 if (top_x == NULL) return;
  131.             }
  132.             for (int i = 0; i < n; i++) {
  133.                 top_x[0][i].x = 0.0f;
  134.                 top_x[0][i].y = top_center.y;
  135.                 top_x[0][i].z = 0.0f;
  136.                 top_x[n - 1][i].x = matrix[0][i].x;
  137.                 top_x[n - 1][i].y = matrix[0][i].y;
  138.                 top_x[n - 1][i].z = matrix[0][i].z;
  139.             }
  140.             for (int i = 1; i < n - 1; i++) {
  141.                 for (int j = 0; j < n; j++) {
  142.                     top_x[i][j].x = top_x[0][j].x - i*(top_x[0][j].x - top_x[n - 1][j].x) / (n - 1);
  143.                     top_x[i][j].y = top_x[0][j].y - i*(top_x[0][j].y - top_x[n - 1][j].y) / (n - 1);
  144.                     top_x[i][j].z = top_x[0][j].z - i*(top_x[0][j].z - top_x[n - 1][j].z) / (n - 1);
  145.  
  146.                 }
  147.             }
  148.             for (int i = 0; i < amount; i++) free(top[i]);
  149.             free(top);
  150.             top = top_x;
  151.         }
  152.  
  153.         Point3D **bottom_x = (Point3D**)malloc(sizeof(Point3D*)*n);
  154.         if (bottom_x != NULL) {
  155.             for (int i = 0; i < n; i++) {
  156.                 bottom_x[i] = (Point3D*)malloc(sizeof(Point3D)*n);
  157.                 if (bottom_x == NULL) return;
  158.             }
  159.             for (int i = 0; i < n; i++) {
  160.                 bottom_x[0][i].x = bottom_center.x - top_center.x;
  161.                 bottom_x[0][i].y = bottom_center.y;
  162.                 bottom_x[0][i].z = bottom_center.z - top_center.z;
  163.                 bottom_x[n - 1][i].x = matrix[n - 1][i].x;
  164.                 bottom_x[n - 1][i].y = matrix[n - 1][i].y;
  165.                 bottom_x[n - 1][i].z = matrix[n - 1][i].z;
  166.             }
  167.             for (int i = 1; i < n - 1; i++) {
  168.                 for (int j = 0; j < n; j++) {
  169.                     bottom_x[i][j].x = bottom_x[0][j].x - i*(bottom_x[0][j].x - bottom_x[n - 1][j].x) / (n - 1);
  170.                     bottom_x[i][j].y = bottom_x[0][j].y - i*(bottom_x[0][j].y - bottom_x[n - 1][j].y) / (n - 1);
  171.                     bottom_x[i][j].z = bottom_x[0][j].z - i*(bottom_x[0][j].z - bottom_x[n - 1][j].z) / (n - 1);
  172.  
  173.                 }
  174.             }
  175.             for (int i = 0; i < amount; i++) free(bottom[i]);
  176.             free(bottom);
  177.             bottom = bottom_x;
  178.         }
  179.         amount = n;
  180. #if defined(OPTIMIZATION5)
  181.         init_display_list();
  182. #endif
  183.     }
  184.  
  185.     void draw_part(Point3D point1, Point3D point2, Point3D point3, Point3D point4, Vector3D normal) {
  186.        
  187.         float point1v[3] = { point1.x, point1.y, point1.z };
  188.         float point2v[3] = { point2.x, point2.y, point2.z };
  189.         float point3v[3] = { point3.x, point3.y, point3.z };
  190.         float point4v[3] = { point4.x, point4.y, point4.z };
  191.         float normalv[3] = { normal.x, normal.y, normal.z };
  192.  
  193.         glBegin(fill_flag ? GL_LINE_STRIP : GL_QUADS);
  194. #if defined(OPTIMIZATION1)
  195.         glNormal3fv(normalv);
  196.  
  197.         if (texture_flag) {
  198.             glTexCoord2f(0.0f, 0.0f);   glVertex3fv(point1v);
  199.             glTexCoord2f(1.0f, 0.0f);   glVertex3fv(point2v);
  200.             glTexCoord2f(1.0f, 1.0f);   glVertex3fv(point3v);
  201.             glTexCoord2f(0.0f, 1.0f);   glVertex3fv(point4v);
  202.         }
  203.         else {
  204.             glVertex3fv(point1v);
  205.             glVertex3fv(point2v);
  206.             glVertex3fv(point3v);
  207.             glVertex3fv(point4v);
  208.         }
  209. #else
  210.         glNormal3f(normal.x, normal.y, normal.z);
  211.  
  212.         if (texture_flag) {
  213.             glTexCoord2f(0.0f, 0.0f);   glVertex3f(point1.x, point1.y, point1.z);
  214.             glTexCoord2f(1.0f, 0.0f);   glVertex3f(point2.x, point2.y, point2.z);
  215.             glTexCoord2f(1.0f, 1.0f);   glVertex3f(point3.x, point3.y, point3.z);
  216.             glTexCoord2f(0.0f, 1.0f);   glVertex3f(point4.x, point4.y, point4.z);
  217.         }
  218.         else {
  219.             glVertex3f(point1.x, point1.y, point1.z);
  220.             glVertex3f(point2.x, point2.y, point2.z);
  221.             glVertex3f(point3.x, point3.y, point3.z);
  222.             glVertex3f(point4.x, point4.y, point4.z);
  223.         }
  224. #endif
  225.        
  226.         glEnd();
  227.     }
  228.  
  229.     volatile void draw() {
  230.         int n = amount;
  231.         glColor3ub(0xFF, 0xFF, 0xFF);
  232.  
  233.         for (int i = 0; i < n; i++) {
  234.             for (int j = 0; j < n; j++) {
  235.                 Point3D point1, point2, point3, point4;
  236.                 Vector3D normal;
  237.                 point1 = matrix[i][j];
  238.                 point2 = matrix[(i + 1) % n][j];
  239.                 point3 = matrix[(i + 1) % n][(j + 1) % n];
  240.                 point4 = matrix[i][(j + 1) % n];
  241.                 normal.x = (point2.y - point1.y)*(point3.z - point1.z) - (point3.y - point1.y)*(point2.z - point1.z);
  242.                 normal.y = (point2.x - point1.x)*(point3.z - point1.z) - (point3.x - point1.x)*(point2.z - point1.z);
  243.                 normal.z = (point2.x - point1.x)*(point3.y - point1.y) - (point3.x - point1.x)*(point2.y - point1.y);
  244.                
  245.                 draw_part(point1, point2, point3, point4, normal);
  246.             }
  247.         }
  248.  
  249.         for (int i = 0; i < n - 1; i++) {
  250.             for (int j = 0; j < n; j++) {
  251.                 Vector3D normal;
  252.                 normal.x = 0.0f;
  253.                 normal.y = 1.0f;
  254.                 normal.z = 0.0f;
  255.  
  256.                 draw_part(top[i][j], top[(i + 1) % n][j], top[(i + 1) % n][(j + 1) % n], top[i][(j + 1) % n], normal);
  257.                 draw_part(bottom[i][j], bottom[(i + 1) % n][j], bottom[(i + 1) % n][(j + 1) % n], bottom[i][(j + 1) % n], normal);
  258.  
  259.             }
  260.            
  261.         }
  262.     }
  263.  
  264.     void init_display_list() {
  265.         fast_draw = glGenLists(1);
  266.         glNewList(fast_draw, GL_COMPILE);
  267.         draw();
  268.         glEndList();
  269.     }
  270.  
  271.     void call_display_list() {
  272.         glCallList(fast_draw);
  273.     }
  274.  
  275.     void drawing() {
  276. #if defined(OPTIMIZATION5)
  277.         call_display_list();
  278. #else
  279.         draw();
  280. #endif
  281.     }
  282.  
  283.     void change_vertices_number(int y) {
  284.         if (y < 2) {
  285.             int temp_amount = amount;
  286.             switch (y) {
  287.             case 1:
  288.                 if (amount <= MAX_VERTECES) update(++temp_amount);
  289.                 break;
  290.             case -1:
  291.                 if (amount >= 6) update(--temp_amount);
  292.                 break;
  293.             }
  294.         }
  295.         else {
  296.             update(y);
  297.         }
  298.     }
  299.  
  300.     int check_borders() {
  301.         glMatrixMode(GL_MODELVIEW);
  302.         glLoadIdentity();
  303.         glTranslatef(displacement.x, displacement.y, displacement.z);
  304.         glScalef(scale, scale, scale);
  305.         glRotatef(rotate_x, 1, 0, 0);
  306.         glRotatef(rotate_y, 0, 1, 0);
  307.         glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix);
  308.         glMatrixMode(GL_MODELVIEW);
  309.         glLoadIdentity();
  310.  
  311.         bool flag;
  312.         for (int i = 0; i < amount; i++) {
  313.             float x, y, z, w, x_, y_, z_, w_;
  314.             x = matrix[0][i].x;
  315.             y = matrix[0][i].y;
  316.             z = matrix[0][i].z;
  317.             w = 1;
  318.  
  319.             x_ = modelview_matrix[0] * x +
  320.                 modelview_matrix[4] * y +
  321.                 modelview_matrix[8] * z +
  322.                 modelview_matrix[12] * w;
  323.             y_ = modelview_matrix[1] * x +
  324.                 modelview_matrix[5] * y +
  325.                 modelview_matrix[9] * z +
  326.                 modelview_matrix[13] * w;
  327.             z_ = modelview_matrix[2] * x +
  328.                 modelview_matrix[6] * y +
  329.                 modelview_matrix[10] * z +
  330.                 modelview_matrix[14] * w;
  331.             w_ = modelview_matrix[3] * x +
  332.                 modelview_matrix[7] * y +
  333.                 modelview_matrix[11] * z +
  334.                 modelview_matrix[15] * w;
  335.  
  336.             x_ = x_ * w_;
  337.             y_ = y_ * w_;
  338.             z_ = z_ * w_;
  339.             w_ = w_ * w_;
  340.  
  341.             flag = check(X, x_);
  342.             if (!flag) return X;
  343.  
  344.             flag = check(Y, y_);
  345.             if (!flag) return Y;
  346.  
  347.             flag = check(Z, z_);
  348.             if (!flag) return Z;
  349.         }
  350.         for (int i = 0; i < amount; i++) {
  351.             float x, y, z, w, x_, y_, z_, w_;
  352.             x = matrix[amount - 1][i].x;
  353.             y = matrix[amount - 1][i].y;
  354.             z = matrix[amount - 1][i].z;
  355.             w = 1;
  356.  
  357.             x_ = modelview_matrix[0] * x +
  358.                 modelview_matrix[4] * y +
  359.                 modelview_matrix[8] * z +
  360.                 modelview_matrix[12] * w;
  361.             y_ = modelview_matrix[1] * x +
  362.                 modelview_matrix[5] * y +
  363.                 modelview_matrix[9] * z +
  364.                 modelview_matrix[13] * w;
  365.             z_ = modelview_matrix[2] * x +
  366.                 modelview_matrix[6] * y +
  367.                 modelview_matrix[10] * z +
  368.                 modelview_matrix[14] * w;
  369.             w_ = modelview_matrix[3] * x +
  370.                 modelview_matrix[7] * y +
  371.                 modelview_matrix[11] * z +
  372.                 modelview_matrix[15] * w;
  373.  
  374.             x_ = x_ * w_;
  375.             y_ = y_ * w_;
  376.             z_ = z_ * w_;
  377.             w_ = w_ * w_;
  378.  
  379.             flag = check(X, x_);
  380.             if (!flag) return X;
  381.  
  382.             flag = check(Y, y_);
  383.             if (!flag) return Y;
  384.  
  385.             flag = check(Z, z_);
  386.             if (!flag) return Z;
  387.         }
  388.         return 0;
  389.     }
  390. };
  391. Cylinder *cylinder;
  392.  
  393. static void cursor_callback(GLFWwindow* window, double x, double y) {
  394.     if (left_button) {
  395.         if ((cursorX == 0) && (cursorY == 0)) {
  396.             cursorX = (float)x;
  397.             cursorY = (float)y;
  398.         }
  399.         else {
  400.             rotate_x += -((float)y - cursorY) * ROTATE_EPS * 10;
  401.             rotate_y += -((float)x - cursorX) * ROTATE_EPS * 10;
  402.             cursorX = (float)x;
  403.             cursorY = (float)y;
  404.         }
  405.  
  406.     }
  407.     else {
  408.         cursorX = (float)x;
  409.         cursorY = (float)y;
  410.     }
  411. }
  412.  
  413. void save_scene() {
  414.     ofstream f;
  415.     f.open("scene.txt");
  416.     f << displacement.x << endl;
  417.     f << displacement.y << endl;
  418.     f << displacement.z << endl;
  419.     f << movement_vector.x << endl;
  420.     f << movement_vector.y << endl;
  421.     f << movement_vector.z << endl;
  422.     f << rotate_x << endl;
  423.     f << rotate_y << endl;
  424.     f << rotate_x_ret_flag << endl;
  425.     f << rotate_y_ret_flag << endl;
  426.     f.close();
  427.     cout << "Scene was saved." << endl;
  428. }
  429.  
  430. void load_scene() {
  431.     ifstream f;
  432.     f.open("scene.txt");
  433.     f >> displacement.x;
  434.     f >> displacement.y;
  435.     f >> displacement.z;
  436.     f >> movement_vector.x;
  437.     f >> movement_vector.y;
  438.     f >> movement_vector.z;
  439.     f >> rotate_x;
  440.     f >> rotate_y;
  441.     f >> rotate_x_ret_flag;
  442.     f >> rotate_y_ret_flag;
  443.     f.close();
  444.     cout << "Scene was loaded." << endl;
  445. }
  446.  
  447. static void wheel_callback(GLFWwindow* window, double x, double y) {
  448.     cylinder->change_vertices_number((int)y);
  449. }
  450.  
  451. static void mouse_callback(GLFWwindow* window, int button, int action, int mods)
  452. {
  453.     if (button == GLFW_MOUSE_BUTTON_RIGHT)
  454.     {
  455.         texture_flag ^= 1;
  456.     }
  457.  
  458.     if (button == GLFW_MOUSE_BUTTON_LEFT)
  459.     {
  460.         left_button ^= 1;
  461.     }
  462. }
  463.  
  464. static void resize_callback(GLFWwindow* window, int width, int height) {
  465.     if (width > height) {
  466.         glViewport((width - height) / 2, 0, height, height);
  467.     }
  468.     else {
  469.         glViewport(0, (height - width) / 2, width, width);
  470.     }
  471.     glMatrixMode(GL_PROJECTION);
  472.     glLoadIdentity();
  473.     if (d2_flag) gluPerspective(40.0, (GLfloat)screen_width / (GLfloat)screen_height, 1.0, 20.0);
  474.     glMatrixMode(GL_MODELVIEW);
  475.  
  476.     screen_width = width;
  477.     screen_height = height;
  478. }
  479.  
  480. static void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
  481.     /*
  482.     * http://www.glfw.org/docs/latest/group__keys.html
  483.     */
  484.  
  485.     //cout << key << " " << scancode << " " << action << " " << mods << endl;
  486.  
  487.     switch (action)
  488.     {
  489.     case GLFW_PRESS:
  490.         switch (key)
  491.         {
  492.         case GLFW_KEY_ESCAPE:
  493.             glfwSetWindowShouldClose(window, GL_TRUE);
  494.             break;
  495.         case GLFW_KEY_N:
  496.             fill_flag ^= 1;
  497.             break;
  498.         case GLFW_KEY_M:
  499.             cube_or_cyl_flag ^= 1;
  500.             break;
  501.         case GLFW_KEY_UP:
  502.             rotate_x_flag = 1;
  503.             rotate_y_ret_flag = 0;
  504.             rotate_x_ret_flag = 0;
  505.             break;
  506.         case GLFW_KEY_DOWN:
  507.             rotate_x_flag = -1;
  508.             rotate_y_ret_flag = 0;
  509.             rotate_x_ret_flag = 0;
  510.             break;
  511.         case GLFW_KEY_LEFT:
  512.             rotate_y_flag = 1;
  513.             rotate_y_ret_flag = 0;
  514.             rotate_x_ret_flag = 0;
  515.             break;
  516.         case GLFW_KEY_RIGHT:
  517.             rotate_y_flag = -1;
  518.             rotate_y_ret_flag = 0;
  519.             rotate_x_ret_flag = 0;
  520.             break;
  521.         case GLFW_KEY_EQUAL:
  522.             scale += 0.05f;
  523.             /* numb += 2;
  524.             cylinder->update(numb); */
  525.             break;
  526.         case GLFW_KEY_MINUS:
  527.             scale -= 0.05f;
  528.             /* if (numb > 8) {
  529.             numb -= 2;
  530.             cylinder->update(numb);
  531.             } */
  532.             break;
  533.         case GLFW_KEY_SPACE:
  534.             rotate_x_ret_flag ^= 1;
  535.             rotate_x = (float)((int)(rotate_x * 10) % 3600) / 10;
  536.             if (rotate_x < START_X - 360) rotate_x += 360;
  537.             rotate_y_ret_flag ^= 1;
  538.             rotate_y = (float)((int)(rotate_y * 10) % 3600) / 10;
  539.             if (rotate_y < START_X - 360) rotate_y += 360;
  540.             angleX = START_X;
  541.             angleY = START_Y;
  542.             movement_vector.x = 0.0f;
  543.             movement_vector.y = 0.0f;
  544.             movement_vector.z = 0.0f;
  545.             rotate_x_flag = 0;
  546.             rotate_y_flag = 0;
  547.             break;
  548.         case GLFW_KEY_Z:
  549.             save_scene();
  550.             cout << time_counter << endl;
  551.  
  552.             break;
  553.         case GLFW_KEY_C:
  554.             load_scene();
  555.             break;
  556.         case GLFW_KEY_D:
  557.             movement_vector.x -= 1.0f;
  558.             break;
  559.         case GLFW_KEY_A:
  560.             movement_vector.x += 1.0f;
  561.             break;
  562.         case GLFW_KEY_W:
  563.             movement_vector.y += 1.0f;
  564.             break;
  565.         case GLFW_KEY_S:
  566.             movement_vector.y -= 1.0f;
  567.             break;
  568.         case GLFW_KEY_Q:
  569.             movement_vector.z += 1.0f;
  570.             break;
  571.         case GLFW_KEY_E:
  572.             movement_vector.z -= 1.0f;
  573.             break;
  574.         case GLFW_KEY_X:
  575.             d2_flag ^= 1;
  576.             if (d2_flag == 1) {
  577.                 glMatrixMode(GL_PROJECTION);
  578.                 glLoadIdentity();
  579.                 gluPerspective(40.0, (GLfloat)screen_width / (GLfloat)screen_height, 1.0, 20.0);
  580.                 glMatrixMode(GL_MODELVIEW);
  581.             } else {
  582.                 glMatrixMode(GL_PROJECTION);
  583.                 glLoadIdentity();
  584.                 glMatrixMode(GL_MODELVIEW);
  585.             };
  586.             break;
  587.         case GLFW_KEY_V:
  588.             if (time_counter > 0)
  589.                 time_counter = 0;
  590.             else
  591.                 time_counter = 1;
  592.             break;
  593.         }
  594.         break;
  595.     case GLFW_RELEASE:
  596.         switch (key)
  597.         {
  598.         case GLFW_KEY_RIGHT:
  599.         case GLFW_KEY_LEFT:
  600.             rotate_y_flag = 0;
  601.             break;
  602.         case GLFW_KEY_UP:
  603.         case GLFW_KEY_DOWN:
  604.             rotate_x_flag = 0;
  605.             break;
  606.         /*case GLFW_KEY_A:
  607.         case GLFW_KEY_D:
  608.             camera_rotate_x = 0;
  609.             break;
  610.         case GLFW_KEY_W:
  611.         case GLFW_KEY_S:
  612.             camera_rotate_y = 0;
  613.             break;*/
  614.         }
  615.         break;
  616.     }
  617. }
  618.  
  619. void drawCube() {
  620.     glBegin(fill_flag ? GL_LINES : GL_QUADS);
  621.     glColor3ub(0xFF, 0x01, 0x01); // Red
  622.     glVertex3f(-0.2f, -0.2f, 0.2f);
  623.     glVertex3f(-0.2f, 0.2f, 0.2f);
  624.     glVertex3f(0.2f, 0.2f, 0.2f);
  625.     glVertex3f(0.2f, -0.2f, 0.2f);
  626.  
  627.     glColor3ub(0xFF, 0x81, 0x01); // Orange
  628.     glVertex3f(-0.2f, -0.2f, -0.2f);
  629.     glVertex3f(-0.2f, 0.2f, -0.2f);
  630.     glVertex3f(0.2f, 0.2f, -0.2f);
  631.     glVertex3f(0.2f, -0.2f, -0.2f);
  632.  
  633.     glColor3ub(0xFF, 0xFF, 0xFF); // White
  634.     glVertex3f(0.2f, 0.2f, -0.2f);
  635.     glVertex3f(-0.2f, 0.2f, -0.2f);
  636.     glVertex3f(-0.2f, 0.2f, 0.2f);
  637.     glVertex3f(0.2f, 0.2f, 0.2f);
  638.  
  639.     glColor3ub(0xFF, 0xE2, 0x01); // Yellow
  640.     glVertex3f(0.2f, -0.2f, -0.2f);
  641.     glVertex3f(-0.2f, -0.2f, -0.2f);
  642.     glVertex3f(-0.2f, -0.2f, 0.2f);
  643.     glVertex3f(0.2f, -0.2f, 0.2f);
  644.  
  645.     glColor3ub(0x4C, 0x14, 0xC0); // Blue
  646.     glVertex3f(-0.2f, -0.2f, -0.2f);
  647.     glVertex3f(-0.2f, -0.2f, 0.2f);
  648.     glVertex3f(-0.2f, 0.2f, 0.2f);
  649.     glVertex3f(-0.2f, 0.2f, -0.2f);
  650.  
  651.     glColor3ub(0x01, 0xD7, 0x01); // Green
  652.     glVertex3f(0.2f, -0.2f, -0.2f);
  653.     glVertex3f(0.2f, -0.2f, 0.2f);
  654.     glVertex3f(0.2f, 0.2f, 0.2f);
  655.     glVertex3f(0.2f, 0.2f, -0.2f);
  656.     glEnd();
  657. }
  658.  
  659. void draw_box() {
  660.     glBegin(GL_LINES);
  661.     glColor3ub(0xFF, 0xFF, 0xFF); // Red
  662.     glVertex3f(-1.0f, -1.0f, 1.0f);
  663.     glVertex3f(-1.0f, 1.0f, 1.0f);
  664.     glVertex3f(1.0f, 1.0f, 1.0f);
  665.     glVertex3f(1.0f, -1.0f, 1.0f);
  666.  
  667.     glVertex3f(-1.0f, -1.0f, -1.0f);
  668.     glVertex3f(-1.0f, 1.0f, -1.0f);
  669.     glVertex3f(1.0f, 1.0f, -1.0f);
  670.     glVertex3f(1.0f, -1.0f, -1.0f);
  671.  
  672.     glVertex3f(1.0f, 1.0f, -1.0f);
  673.     glVertex3f(-1.0f, 1.0f, -1.0f);
  674.     glVertex3f(-1.0f, 1.0f, 1.0f);
  675.     glVertex3f(1.0f, 1.0f, 1.0f);
  676.  
  677.     glVertex3f(1.0f, -1.0f, -1.0f);
  678.     glVertex3f(-1.0f, -1.0f, -1.0f);
  679.     glVertex3f(-1.0f, -1.0f, 1.0f);
  680.     glVertex3f(1.0f, -1.0f, 1.0f);
  681.  
  682.     glVertex3f(-1.0f, -1.0f, -1.0f);
  683.     glVertex3f(-1.0f, -1.0f, 1.0f);
  684.     glVertex3f(-1.0f, 1.0f, 1.0f);
  685.     glVertex3f(-1.0f, 1.0f, -1.0f);
  686.  
  687.     glVertex3f(1.0f, -1.0f, -1.0f);
  688.     glVertex3f(1.0f, -1.0f, 1.0f);
  689.     glVertex3f(1.0f, 1.0f, 1.0f);
  690.     glVertex3f(1.0f, 1.0f, -1.0f);
  691.     glEnd();
  692. }
  693.  
  694. void drawGrid() {
  695.     float quad_size = 0.1f, bound = 10;
  696.     for (float i = -bound; i <= bound; i += 1)
  697.     {
  698.         glBegin(GL_LINES);
  699.         glColor3ub(0x01, 0xD7, 0x01); // Green
  700.         glVertex3f(-bound * quad_size, -0.5f, i * quad_size);
  701.         glVertex3f(bound * quad_size, -0.5f, i * quad_size);
  702.  
  703.         glVertex3f(i * quad_size, -0.5f, -bound * quad_size);
  704.         glVertex3f(i * quad_size, -0.5f, bound * quad_size);
  705.         glEnd();
  706.     }
  707. }
  708.  
  709. void decrease_speed() {
  710.     movement_vector.x *= 0.9f;
  711.     movement_vector.y *= 0.9f;
  712.     movement_vector.z *= 0.9f;
  713. }
  714.  
  715. void refresh_data()
  716. {
  717.     if (scale > 1.3f) scale = 1.3f;
  718.     else if (scale < 0.5f) scale = 0.5f;
  719.     if (rotate_x_ret_flag) {
  720.         if (rotate_x >= START_X - 2 * ROTATE_EPS || rotate_x <= START_X - 360 + 2 * ROTATE_EPS) {
  721.             rotate_x = START_X;
  722.             rotate_x_ret_flag = 0;
  723.         }
  724.         else if (rotate_x >(360 - 2 * START_X_ANGLE) / 2) rotate_x += ROTATE_EPS;
  725.         else if (rotate_x < (360 - 2 * START_X_ANGLE) / 2) rotate_x -= ROTATE_EPS;
  726.     }
  727.     if (rotate_y_ret_flag) {
  728.         if (rotate_y >= START_Y - 2 * ROTATE_EPS || rotate_y <= START_Y - 360 + 2 * ROTATE_EPS) {
  729.             rotate_y = START_Y;
  730.             rotate_y_ret_flag = 0;
  731.         }
  732.         else if (rotate_y >(360 - 2 * START_Y_ANGLE) / 2) rotate_y += ROTATE_EPS;
  733.         else if (rotate_y < (360 - 2 * START_Y_ANGLE) / 2) rotate_y -= ROTATE_EPS;
  734.     }
  735.     rotate_x += (float)rotate_x_flag * ROTATE_EPS;
  736.     rotate_y += (float)rotate_y_flag * ROTATE_EPS;
  737.     camera[0] += (float)camera_rotate_x * CAMERA_EPS;
  738.     camera[1] += (float)camera_rotate_y * CAMERA_EPS;
  739.  
  740.     displacement.x += movement_vector.x * MOVEMENT_EPS;
  741.     displacement.y += movement_vector.y * MOVEMENT_EPS;
  742.     displacement.z += movement_vector.z * MOVEMENT_EPS;
  743.  
  744.     int checking = cylinder->check_borders();
  745.     switch (checking) {
  746.     case 0:
  747.         break;
  748.     case X:
  749.         movement_vector.x *= -1;
  750.         decrease_speed();
  751.         break;
  752.     case Y:
  753.         movement_vector.y *= -1;
  754.         decrease_speed();
  755.         break;
  756.     case Z:
  757.         movement_vector.z *= -1;
  758.         decrease_speed();
  759.         break;
  760.     }
  761. }
  762.  
  763.  
  764. unsigned int load_texture_custom(const char *imagepath) {
  765.  
  766.     unsigned char header[54];
  767.     unsigned int dataPos;
  768.     unsigned int width, height;
  769.     unsigned int imageSize;
  770.     unsigned char *data;
  771.  
  772.     FILE *file;
  773.     fopen_s(&file, imagepath, "rb");
  774.     if (!file) {
  775.         cout << "Изображение не может быть открыто" << endl;
  776.         return 0;
  777.     }
  778.  
  779.     if (fread(header, 1, 54, file) != 54) { // Если мы прочитали меньше 54 байт, значит возникла проблема
  780.         cout << "Некорректный BMP-файл" << endl;
  781.         return false;
  782.     }
  783.  
  784.     if (header[0] != 'B' || header[1] != 'M') {
  785.         cout << "Некорректный BMP-файл" << endl;
  786.         return 0;
  787.     }
  788.  
  789.     // Читаем необходимые данные
  790.     dataPos = *(int*)&(header[0x0A]); // Смещение данных изображения в файле
  791.     imageSize = *(int*)&(header[0x22]); // Размер изображения в байтах
  792.     width = *(int*)&(header[0x12]); // Ширина
  793.     height = *(int*)&(header[0x16]); // Высота
  794.  
  795.     // Некоторые BMP-файлы имеют нулевые поля imageSize и dataPos, поэтому исправим их
  796.     if (imageSize == 0)    imageSize = width*height * 3; // Ширину * Высоту * 3, где 3 - 3 компоненты цвета (RGB)
  797.     if (dataPos == 0)      dataPos = 54; // В таком случае, данные будут следовать сразу за заголовком
  798.  
  799.     data = new unsigned char[imageSize];
  800.  
  801.     fread(data, 1, imageSize, file);
  802.     fclose(file);
  803.  
  804.     unsigned int textureID;
  805.     glGenTextures(1, &textureID);
  806.     glBindTexture(GL_TEXTURE_2D, textureID);
  807.  
  808.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
  809.  
  810.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  811.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  812.  
  813.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  814.  
  815.     glEnable(GL_TEXTURE_2D);
  816.  
  817.     return textureID;
  818. }
  819.  
  820. void initLightnMaterial()
  821. {
  822.     //http://esate.ru/uroki/OpenGL/uroki_opengl/_p4077/
  823.  
  824.     glEnable(GL_LIGHTING);
  825.     glEnable(GL_LIGHT0);
  826.     glEnable(GL_DEPTH_TEST);
  827.     glEnable(GL_SMOOTH);
  828. #if !defined(OPTIMIZATION2)
  829.     glEnable(GL_NORMALIZE);
  830. #endif
  831. #if defined(OPTIMIZATION3)
  832.     glShadeModel(GL_FLAT);
  833. #endif
  834.  
  835.     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  836.    
  837.     float ambient[] = { 0.7f, 0.7f, 0.7f };
  838.     float diffuse[] = { 0.4f, 0.7f, 0.2f };
  839.     float specular[] = { 0.5f, 0.5f, 0.5f };
  840.     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
  841.     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
  842.     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
  843.     glEnable(GL_COLOR_MATERIAL);
  844.  
  845.     float light_ambient[] = { 0.0f, 0.0f, 0.0f };
  846.     float light_diffuse[] = { 1.0f, 1.0f, 1.0f };
  847.     float light_specular[] = { 1.0f, 1.0f, 1.0f };
  848.     float light_position[] = { 0.0f, 0.0f, -1.0f, 1.0f };
  849.  
  850.     glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
  851.     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  852.     glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
  853.     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  854.  
  855.     float att = 3;
  856.     float radius = 1;
  857.     float kQ = att / (3 * radius * radius);
  858.     float kL = att / (3 * radius);
  859.     float kC = att / 3;
  860.  
  861.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, kC);
  862.     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, kL);
  863.     glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, kQ);
  864. }
  865.  
  866. int main()
  867. {
  868.     glfwInit();
  869.     GLFWwindow* window;
  870.     window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "My lab", NULL, NULL);
  871.     int attrib;
  872.     attrib = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
  873.     attrib = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
  874.     attrib = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
  875.     glfwMakeContextCurrent(window);
  876.     glfwSetKeyCallback(window, keyboard_callback);
  877.     glfwSetFramebufferSizeCallback(window, resize_callback);
  878.     glfwSetMouseButtonCallback(window, mouse_callback);
  879.     glfwSetCursorPosCallback(window, cursor_callback);
  880.     glfwSetScrollCallback(window, wheel_callback);
  881.     resize_callback(window, SCREEN_WIDTH, SCREEN_HEIGHT);
  882.  
  883.     cylinder = new Cylinder(numb, -0.3f, 0.3f, 0.1f, 0.2f);
  884.     movement_vector.x = 0.0f;
  885.     movement_vector.y = 0.0f;
  886.     movement_vector.z = 1.0f;
  887.     displacement.x = 0.0f;
  888.     displacement.y = 0.0f;
  889.     displacement.z = 0.0f;
  890.  
  891.     initLightnMaterial();
  892. #if defined(OPTIMIZATION4)
  893.     texture[0] = load_texture_custom("tex0m.bmp");
  894. #else
  895.     texture[0] = load_texture_custom("tex0.bmp");
  896. #endif
  897.  
  898.     rotate_y_flag = 1;
  899.     keyboard_callback(window, GLFW_KEY_X, 45, GLFW_PRESS, 0);
  900.  
  901.     __int64 ctr1 = 0, ctr2 = 0, freq = 0;
  902.     int acc = 0, i = 0;
  903.     int temp_vertices_amount;
  904.     ofstream f;
  905.     while (!glfwWindowShouldClose(window))
  906.     {
  907.         glfwPollEvents();
  908.        
  909.         refresh_data();
  910.  
  911.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  912.  
  913.  
  914.         glMatrixMode(GL_MODELVIEW);
  915.         glLoadIdentity();
  916.  
  917.         if (d2_flag) gluLookAt(0, 0, -3, 0, 0, 0, 0, 1, 0);
  918.  
  919.         glDisable(GL_LIGHTING);
  920.             draw_box();
  921.         glEnable(GL_LIGHTING);
  922.  
  923.         glTranslatef(displacement.x, displacement.y, displacement.z);
  924.         glScalef(scale, scale, scale);
  925.  
  926.         glRotatef(rotate_x, 1, 0, 0);
  927.         glRotatef(rotate_y, 0, 1, 0);
  928.         cylinder->drawing();
  929.  
  930.         glfwSwapBuffers(window);
  931.         glFlush();
  932.  
  933.         if (time_counter > 0) {
  934.             if (time_counter == 1) {
  935.                 temp_vertices_amount = cylinder->get_vertices_count();
  936.                 cylinder->change_vertices_number(MAX_VERTECES);
  937.                 QueryPerformanceCounter((LARGE_INTEGER *)&ctr1);
  938.                 time_counter = 2;
  939.             }
  940.             time_counter++;
  941.             if (time_counter == 300) {
  942.                 QueryPerformanceCounter((LARGE_INTEGER *)&ctr2);
  943.                 QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
  944.                 //cout << "100 Increment time: " << ((ctr2 - ctr1) * 1.0 / freq) << " seconds with " << cylinder->get_vertices_count() << " vertices.\n" << endl;
  945.                 f.open("tests.txt", ios_base::app);
  946.                 f << ((ctr2 - ctr1) * 1.0 / freq) << endl;
  947.                 f.close();
  948.  
  949.                 cout << ((ctr2 - ctr1) * 1.0 / freq) << endl;
  950.  
  951.                 time_counter = 1;
  952.                 cylinder->change_vertices_number(temp_vertices_amount);
  953.             }
  954.         }
  955.  
  956.     }
  957.  
  958.     glfwDestroyWindow(window);
  959.     glfwTerminate();
  960.  
  961.     return 0;
  962. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement