Advertisement
SalmaYasser

Untitled

Feb 26th, 2020
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.14 KB | None | 0 0
  1. #include <glad/glad.h>
  2. #include <glfw3.h>
  3. #include <math.h>
  4. #include <vector>
  5. #include <stack>
  6. #include <iostream>
  7. #include <fstream>
  8. #include <chrono>
  9. #include <random>
  10. #include <sstream>
  11. typedef float HeatmapType;
  12. using namespace std;
  13.  
  14. vector<float> vertices;
  15. // settings
  16. const int IMAGE_HEIGHT = 200;
  17. const int IMAGE_WIDTH = 200;
  18. const int RED_ITERS = 200;
  19. const int BLUE_ITERS = 800;
  20. const int GREEN_ITERS = 200;
  21. const long long int SAMPLE_COUNT = IMAGE_WIDTH * IMAGE_HEIGHT * 100;
  22.  
  23. class Complex
  24. {
  25. public:
  26. Complex(double r = 0.0, double i = 0.0)
  27. : _r(r), _i(i)
  28. {
  29. }
  30.  
  31. Complex(const Complex &) = default;
  32.  
  33. double r() const { return _r; }
  34. double i() const { return _i; }
  35.  
  36. Complex operator*(const Complex &other)
  37. {
  38. // (a + bi) (c + di)
  39. return Complex(_r * other._r - _i * other._i, _r * other._i + _i * other._r);
  40. }
  41.  
  42. Complex operator+(const Complex &other)
  43. {
  44. return Complex(_r + other._r, _i + other._i);
  45. }
  46.  
  47. double sqmagnitude() const
  48. {
  49. return _r * _r + _i * _i;
  50. }
  51.  
  52. private:
  53. double _r, _i;
  54. };
  55.  
  56. //
  57. // Utility
  58. //
  59. void AllocHeatmap(HeatmapType **&o_heatmap, int width, int height)
  60. {
  61. o_heatmap = new HeatmapType *[height];
  62. for (int i = 0; i < height; ++i)
  63. {
  64. o_heatmap[i] = new HeatmapType[width];
  65. for (int j = 0; j < width; ++j)
  66. {
  67. o_heatmap[i][j] = 0;
  68. }
  69. }
  70. }
  71.  
  72. void FreeHeatmap(HeatmapType **&o_heatmap, int height)
  73. {
  74. for (int i = 0; i < height; ++i)
  75. {
  76. delete[] o_heatmap[i];
  77. o_heatmap[i] = nullptr;
  78. }
  79. delete o_heatmap;
  80. o_heatmap = nullptr;
  81. }
  82.  
  83. vector<Complex> buddhabrotPoints(const Complex &c, int nIterations)
  84. {
  85. int n = 0;
  86. Complex z;
  87.  
  88. vector<Complex> toReturn;
  89. toReturn.reserve(nIterations);
  90.  
  91. while (n < nIterations && z.sqmagnitude() <= 2.0)
  92. {
  93. z = z * z + c;
  94. ++n;
  95.  
  96. toReturn.push_back(z);
  97. }
  98.  
  99. // If point remains bounded through nIterations iterations, the point
  100. // is bounded, therefore in the Mandelbrot set, therefore of no interest to us
  101. if (n == nIterations)
  102. {
  103. return vector<Complex>();
  104. }
  105. else
  106. {
  107. return toReturn;
  108. }
  109. }
  110.  
  111. int rowFromReal(double real, double minR, double maxR, int imageHeight)
  112. {
  113. // [minR, maxR]
  114. // [0, maxR - minR] // subtract minR from n
  115. // [0, imageHeight] // multiply by (imageHeight / (maxR - minR))
  116. return (int)((real - minR) * (imageHeight / (maxR - minR)));
  117. }
  118.  
  119. int colFromImaginary(double imag, double minI, double maxI, int imageWidth)
  120. {
  121. return (int)((imag - minI) * (imageWidth / (maxI - minI)));
  122. }
  123.  
  124. void GenerateHeatmap(HeatmapType **o_heatmap, int imageWidth, int imageHeight,
  125. const Complex &minimum, const Complex &maximum, int nIterations, long long nSamples,
  126. HeatmapType &o_maxHeatmapValue, string consoleMessagePrefix)
  127. {
  128. mt19937 rng;
  129. uniform_real_distribution<double> realDistribution(minimum.r(), maximum.r());
  130. uniform_real_distribution<double> imagDistribution(minimum.i(), maximum.i());
  131.  
  132. rng.seed(chrono::high_resolution_clock::now().time_since_epoch().count());
  133. // Collect nSamples samples... (sample is just a random number c)
  134. for (long long sampleIdx = 0; sampleIdx < nSamples; ++sampleIdx)
  135. {
  136. // Each sample, get the list of points as the function
  137. // escapes to infinity (if it does at all)
  138.  
  139. Complex sample(realDistribution(rng), imagDistribution(rng));
  140. vector<Complex> pointsList = buddhabrotPoints(sample, nIterations);
  141.  
  142. for (Complex &point : pointsList)
  143. {
  144. if (point.r() <= maximum.r() && point.r() >= minimum.r() && point.i() <= maximum.i() && point.i() >= minimum.i())
  145. {
  146. int row = rowFromReal(point.r(), minimum.r(), maximum.r(), imageHeight);
  147. int col = colFromImaginary(point.i(), minimum.i(), maximum.i(), imageWidth);
  148. ++o_heatmap[row][col];
  149.  
  150. if (o_heatmap[row][col] > o_maxHeatmapValue)
  151. {
  152. o_maxHeatmapValue = o_heatmap[row][col];
  153. }
  154. }
  155. }
  156. }
  157. }
  158.  
  159. float colorFromHeatmap(HeatmapType inputValue, HeatmapType maxHeatmapValue, float maxColor)
  160. {
  161. double scale = (1.0f * (maxColor)) / (1.0f * maxHeatmapValue);
  162. return inputValue * scale;
  163. }
  164.  
  165. void framebuffer_size_callback(GLFWwindow *window, int width, int height);
  166. void mouse_button_callback(GLFWwindow *window, int button, int action, int mods);
  167. void processInput(GLFWwindow *window);
  168.  
  169. const char *vertexShaderSource = "#version 330 core\n"
  170. "layout (location = 0) in vec3 aPos;\n"
  171. "layout (location = 1) in vec3 aColor;\n"
  172. "out vec3 vertexColor;\n"
  173. "void main()\n"
  174. "{\n"
  175. " gl_Position = vec4(aPos,1.0);\n"
  176. "vertexColor = aColor;\n"
  177. "}\0";
  178. const char *fragmentShaderSource = "#version 330 core\n"
  179. "out vec4 FragColor;\n"
  180. "in vec3 vertexColor;\n"
  181. "void main()\n"
  182. "{\n"
  183. " FragColor = vec4(vertexColor, 1.0);\n"
  184. "}\n\0";
  185.  
  186. int points;
  187.  
  188. float mapX(float x)
  189. {
  190. return x * 2.0 / IMAGE_WIDTH - 1.0;
  191. }
  192.  
  193. float mapY(float y)
  194. {
  195. return y * 2.0 / IMAGE_HEIGHT - 1.0;
  196. }
  197.  
  198. int main()
  199. {
  200. const Complex MINIMUM(-2.0, -2.0);
  201. const Complex MAXIMUM(2.0, 2.0);
  202. vector<float> vertices;
  203. vertices.reserve(IMAGE_HEIGHT * IMAGE_WIDTH);
  204.  
  205. // Allocate a heatmap of the size of our image
  206. HeatmapType maxHeatmapValue = 0;
  207. HeatmapType **red;
  208. HeatmapType **green;
  209. HeatmapType **blue;
  210. AllocHeatmap(red, IMAGE_WIDTH, IMAGE_HEIGHT);
  211. AllocHeatmap(green, IMAGE_WIDTH, IMAGE_HEIGHT);
  212. AllocHeatmap(blue, IMAGE_WIDTH, IMAGE_HEIGHT);
  213.  
  214. GenerateHeatmap(red, IMAGE_WIDTH, IMAGE_HEIGHT, MINIMUM, MAXIMUM, RED_ITERS,
  215. SAMPLE_COUNT, maxHeatmapValue, "Red Channel: ");
  216. GenerateHeatmap(blue, IMAGE_WIDTH, IMAGE_HEIGHT, MINIMUM, MAXIMUM, BLUE_ITERS,
  217. SAMPLE_COUNT, maxHeatmapValue, "Blue Channel: ");
  218.  
  219. GenerateHeatmap(green, IMAGE_WIDTH, IMAGE_HEIGHT, MINIMUM, MAXIMUM, GREEN_ITERS,
  220. SAMPLE_COUNT, maxHeatmapValue, "green Channel: ");
  221.  
  222. // Scale the heatmap down
  223. for (int row = 0; row < IMAGE_HEIGHT; ++row)
  224. {
  225. for (int col = 0; col < IMAGE_WIDTH; ++col)
  226. {
  227.  
  228. red[row][col] = colorFromHeatmap(red[row][col], maxHeatmapValue, 1);
  229. blue[row][col] = colorFromHeatmap(blue[row][col], maxHeatmapValue, 1);
  230. green[row][col] = colorFromHeatmap(green[row][col], maxHeatmapValue, 1);
  231.  
  232. //cout<<red[row][col]<<endl;
  233. vertices.push_back(-mapX(col));
  234. vertices.push_back(-mapY(row));
  235. vertices.push_back(0.0f);
  236. vertices.push_back(red[row][col]);
  237. vertices.push_back(green[row][col]);
  238. vertices.push_back(blue[row][col]);
  239.  
  240. // cout<<red[row][col]<<endl;
  241. //vertices.push_back(0.0f);
  242. //vertices.push_back(0.0f);
  243. }
  244. }
  245.  
  246. // glfw: initialize and configure
  247. // ------------------------------
  248. glfwInit();
  249. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  250. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  251. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  252.  
  253. #ifdef __APPLE__
  254. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
  255. #endif
  256.  
  257. // glfw window creation
  258. // --------------------
  259. GLFWwindow *window = glfwCreateWindow(IMAGE_WIDTH, IMAGE_HEIGHT, "Algorithmic Modeling Fractal Buddhabrot Set", NULL, NULL);
  260. if (window == NULL)
  261. {
  262. std::cout << "Failed to create GLFW window" << std::endl;
  263. glfwTerminate();
  264. return -1;
  265. }
  266. glfwMakeContextCurrent(window);
  267. glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
  268. // glfwSetMouseButtonCallback(window, mouse_button_callback);
  269.  
  270. // glad: load all OpenGL function pointers
  271. // ---------------------------------------
  272. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
  273. {
  274. std::cout << "Failed to initialize GLAD" << std::endl;
  275. return -1;
  276. }
  277.  
  278. // build and compile our shader program
  279. // ------------------------------------
  280. // vertex shader
  281. int vertexShader = glCreateShader(GL_VERTEX_SHADER);
  282. glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
  283. glCompileShader(vertexShader);
  284. // check for shader compile errors
  285. int success;
  286. char infoLog[512];
  287. glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
  288. if (!success)
  289. {
  290. glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
  291. std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
  292. << infoLog << std::endl;
  293. }
  294. // fragment shader
  295. int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  296. glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
  297. glCompileShader(fragmentShader);
  298. // check for shader compile errors
  299. glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
  300. if (!success)
  301. {
  302. glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
  303. std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"
  304. << infoLog << std::endl;
  305. }
  306. // link shaders
  307. int shaderProgram = glCreateProgram();
  308. glAttachShader(shaderProgram, vertexShader);
  309. glAttachShader(shaderProgram, fragmentShader);
  310. glLinkProgram(shaderProgram);
  311. // check for linking errors
  312. glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
  313. if (!success)
  314. {
  315. glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
  316. std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n"
  317. << infoLog << std::endl;
  318. }
  319. glDeleteShader(vertexShader);
  320. glDeleteShader(fragmentShader);
  321.  
  322. // set up vertex data (and buffer(s)) and configure vertex attributes
  323. // ------------------------------------------------------------------
  324.  
  325. points = vertices.size();
  326.  
  327. // uncomment this call to draw in wireframe polygons.
  328. //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  329.  
  330. // render loop
  331. cout << "done" << endl;
  332. unsigned int VBO, VAO;
  333.  
  334. glGenVertexArrays(1, &VAO);
  335. glGenBuffers(1, &VBO);
  336. // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
  337. glBindVertexArray(VAO);
  338.  
  339. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  340. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), &vertices[0], GL_STATIC_DRAW);
  341.  
  342. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
  343. glEnableVertexAttribArray(0);
  344. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
  345. glEnableVertexAttribArray(1);
  346. // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
  347. glBindBuffer(GL_ARRAY_BUFFER, 0);
  348.  
  349. // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
  350. // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
  351. glBindVertexArray(0);
  352. // -----------
  353. while (!glfwWindowShouldClose(window))
  354. {
  355.  
  356. processInput(window);
  357.  
  358. //glClearColor(1,1, 1, 1.0f);
  359. //glClear(GL_COLOR_BUFFER_BIT);
  360.  
  361. // draw our first triangle
  362. glUseProgram(shaderProgram);
  363. glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
  364. glDrawArrays(GL_POINTS, 0, points);
  365. glfwSwapBuffers(window);
  366. glfwPollEvents();
  367. // ------------------------------------------------------------------
  368. }
  369.  
  370. //glDeleteVertexArrays(1, &VAO);
  371. //glDeleteBuffers(1, &VBO);
  372. // optional: de-allocate all resources once they've outlived their purpose:
  373. // ------------------------------------------------------------------------
  374.  
  375. // glfw: terminate, clearing all previously allocated GLFW resources.
  376.  
  377. glfwTerminate();
  378. return 0;
  379. }
  380.  
  381. // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
  382. // ---------------------------------------------------------------------------------------------------------
  383. void processInput(GLFWwindow *window)
  384. {
  385. if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
  386. glfwSetWindowShouldClose(window, true);
  387. }
  388.  
  389. // glfw: whenever the window size changed (by OS or user resize) this callback function executes
  390. // ---------------------------------------------------------------------------------------------
  391.  
  392. void framebuffer_size_callback(GLFWwindow *window, int width, int height)
  393. {
  394. // make sure the viewport matches the new window dimensions; note that width and
  395. // height will be significantly larger than specified on retina displays.
  396. glViewport(0, 0, width, height);
  397. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement