Advertisement
maxim_shlyahtin

main

Mar 12th, 2024 (edited)
1,207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.44 KB | None | 0 0
  1. #ifndef MAIN
  2. #define MAIN
  3. #ifdef _WIN32
  4. #include <Windows.h>
  5. #include <GL/GL.h>
  6. #include <GL/GLU.h>
  7. #endif
  8. #ifndef _WIN32
  9. #include <GL/gl.h>
  10. #include <GL/glu.h>
  11. #endif
  12.  
  13. #include <chrono>
  14. #include "ode.cpp"
  15. #include "thread_pool.cpp"
  16. #define _USE_MATH_DEFINES
  17.  
  18. //Choose whether to use SDL1 or SDL2
  19.  
  20.  
  21. #include <SDL.h>
  22. #include <SDL_opengl.h>
  23. #pragma comment(lib,"SDL2.lib")
  24. #pragma comment(lib,"SDL2main.lib")
  25. static SDL_Window* window;
  26. static SDL_Renderer* renderer;
  27. #pragma comment(lib,"opengl32.lib")
  28. #pragma comment(lib,"glu32.lib")
  29.  
  30. static int const screen_size[2] = { 1000, 800 };
  31.  
  32. using glf = GLfloat;
  33. using point3d = std::array<glf, N>;
  34. using method = DOPRI8;
  35.  
  36. double cameraX = 0.0;
  37. double cameraY = 0.0;
  38. const double cameraZ = 20.0;
  39. const double R = 10.0;
  40. double t;
  41. const int number_of_points = 200000;
  42. double dt = 20.0 / 100.0;
  43.  
  44. // переменные для создания потоков
  45. const int number_of_cores = std::thread::hardware_concurrency();
  46. std::vector<method> attractors;
  47.  
  48. std::array<point3d, number_of_points> points;
  49. ThreadPool thread_pool(number_of_cores);
  50.  
  51. int b_val_index = 0;
  52. // красивые формы аттрактора получаются при данных коэффициентах
  53. const int len = 5;
  54. std::array<double, len> b_values = { 0.11, 0.15, 0.215, 0.265, 0.32899 };
  55.  
  56. double red = 1.0f;
  57. double blue = 1.0f;
  58. double green = 1.0f;
  59.  
  60. double step_red = 0.05;
  61. double step_blue = 0.025;
  62. double step_green = 0.016;
  63.  
  64. void process(method& attr, int start, int end, double dt) {
  65.     for (int i = start; i < end; ++i) {
  66.         attr.SetInit({ points[i].at(0), points[i].at(1), points[i].at(2) });
  67.         attr.NextStep(dt);
  68.         points[i] = { static_cast<glf>(attr.getX(0)), static_cast<glf>(attr.getX(1)), static_cast<glf>(attr.getX(2)) };
  69.     }
  70. }
  71.  
  72. void inittializeAttractors() {
  73.     for (size_t i = 0; i < number_of_cores; ++i)
  74.         attractors.push_back(method());
  75. }
  76.  
  77.  
  78. Uint32 callback(Uint32 interval, void* name) {
  79.     //Задаем с период вращения камеры
  80.     std::chrono::time_point<std::chrono::high_resolution_clock> tp = std::chrono::high_resolution_clock::now();
  81.     std::chrono::duration<double, std::micro> dur = tp.time_since_epoch();
  82.     t = dur.count();
  83.  
  84.     cameraX = R * cos((2 * M_PI) / (60.0 * 1000.0) * (t / 1000.0));
  85.     cameraY = R * sin((2 * M_PI) / (60.0 * 1000.0) * (t / 1000.0));
  86.     for (size_t i = 0; i < number_of_cores; ++i) {
  87.         thread_pool.enqueue([i] {
  88.             process(std::ref(attractors[i]), i * number_of_points / number_of_cores,
  89.             (i + 1) * number_of_points / number_of_cores, dt);
  90.             });
  91.     }
  92.     return interval;
  93. }
  94.  
  95. Uint32 colorChange(Uint32 interval, void* name) {
  96.     red += step_red;
  97.     blue += step_blue;
  98.     green += step_green;
  99.     step_red = (red >= 1 || red <= 0) ? -step_red : step_red;
  100.     step_blue = (blue >= 1 || blue <= 0) ? -step_blue : step_blue;
  101.     step_green = (green >= 1 || green <= 0) ? -step_green : step_green;
  102.     return interval;
  103. }
  104.  
  105. static bool get_input(void) {
  106.     SDL_Event event;
  107.     while (SDL_PollEvent(&event)) {
  108.         switch (event.type) {
  109.         case SDL_QUIT: return false; //The little X in the window got pressed
  110.         case SDL_KEYDOWN:
  111.             if (event.key.keysym.sym == SDLK_ESCAPE) {
  112.                 return false;
  113.             }
  114.             if (event.key.keysym.sym == SDLK_w) {
  115.                 b_val_index = (b_val_index + 1) % len;
  116.                 for (size_t i = 0; i < number_of_cores; ++i)
  117.                     attractors[i].b = b_values[b_val_index];
  118.  
  119.             }
  120.             if (event.key.keysym.sym == SDLK_s) {
  121.                 b_val_index = (b_val_index - 1) % len >= 0 ? (b_val_index - 1) % len : len + (b_val_index - 1) % len;
  122.                 for (size_t i = 0; i < number_of_cores; ++i)
  123.                     attractors[i].b = b_values[b_val_index];
  124.  
  125.             }
  126.             std::cout << b_values[b_val_index] << '\n';
  127.             break;
  128.         }
  129.     }
  130.     return true;
  131. }
  132. static void draw(void) {
  133.     //Clear the screen's color and depth (default color is black, but can change with glClearColor(...))
  134.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  135.  
  136.     //Drawing to an area starting at the bottom left, screen_size[0] wide, and screen_size[1] high.
  137.     glViewport(0, 0, screen_size[0], screen_size[1]);
  138.     //OpenGL is a state machine.  Tell it that future commands changing the matrix are to change OpenGL's projection matrix
  139.     glMatrixMode(GL_PROJECTION);
  140.     //Reset the projection matrix
  141.     glLoadIdentity();
  142.     //Multiply a perspective projection matrix into OpenGL's projection matrix
  143.     gluPerspective(45.0, (double)(screen_size[0]) / (double)(screen_size[1]), 0.1, 100.0);
  144.  
  145.     //Tell OpenGL that future commands changing the matrix are to change the modelview matrix
  146.     glMatrixMode(GL_MODELVIEW);
  147.     //Reset the modelview matrix
  148.     glLoadIdentity();
  149.     //Multiply OpenGL's modelview matrix with a transform matrix that simulates a camera at (2,3,4) looking towards the location (0,0,0) with up defined to be (0,1,0)
  150.  
  151.     gluLookAt(cameraX, cameraY, cameraZ, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
  152.     //gluLookAt(-20.0f, -15.0f, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
  153.  
  154.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  155.  
  156.     glColor3f(red, blue, green); // Set the color to white
  157.     //int ind = 6;
  158.     //glColor3f(colors[ind].at(0), colors[ind].at(1), colors[ind].at(2)); // Set the color to white
  159.     glBegin(GL_POINTS);
  160.  
  161.     for (size_t i = 0; i < number_of_points; i++) {
  162.         glVertex3f(points[i].at(0), points[i].at(1), points[i].at(2));
  163.     }
  164.  
  165.     glEnd();
  166.     //OpenGL works best double-buffered.  SDL automatically sets that up for us.  This will draw what we have
  167.     //  just drawn to the screen so that we can see it.
  168.     SDL_GL_SwapWindow(window);
  169. }
  170.  
  171. int main(int argc, char* argv[]) {
  172.     inittializeAttractors();
  173.     //считываем заготовленные точки из файла
  174.     std::ifstream in("prep.txt");
  175.     if (in.is_open()) {
  176.         glf x, y, z;
  177.         int check = 0;
  178.         while (in >> x >> y >> z && check < number_of_points) {
  179.             points[check] = { x, y, z };
  180.             check++;
  181.         }
  182.     }
  183.     in.close();
  184.     //Initialize everything, but don't catch fatal signals; give them to the OS.
  185.     SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_NOPARACHUTE);
  186.  
  187.  
  188.     //Creates the window
  189.     window = SDL_CreateWindow("Thomas' cyclically symmetric attractor", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_size[0], screen_size[1], SDL_WINDOW_OPENGL);
  190.     //Create an OpenGL context.  In SDL 1, this was done automatically.
  191.     SDL_GLContext context = SDL_GL_CreateContext(window);
  192.  
  193.     //We now have an OpenGL context, and can call OpenGL functions.
  194.  
  195.     //Objects need to test each other to see which one is in front.  If you don't do this, you'll "see through" things!
  196.     glEnable(GL_DEPTH_TEST);
  197.  
  198.     SDL_TimerID timerID = SDL_AddTimer(20, callback, const_cast<char*>("SDL"));
  199.     SDL_TimerID timerID_color = SDL_AddTimer(1000, colorChange, const_cast<char*>("SDL"));
  200.  
  201.  
  202.     //Main application loop
  203.     while (true) {
  204.         if (!get_input()) break;
  205.         draw();
  206.     }
  207.  
  208.     SDL_RemoveTimer(timerID);
  209.     SDL_RemoveTimer(timerID_color);
  210.  
  211.     //Clean up
  212.     SDL_GL_DeleteContext(context);
  213.     SDL_DestroyWindow(window);
  214.     SDL_Quit();
  215.  
  216.     //Return success; program exits
  217.     return 0;
  218. }
  219.  
  220. #endif // !MAIN
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement