Advertisement
dark-s0ul

fractal.cpp

Dec 14th, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.95 KB | None | 0 0
  1. using namespace std;
  2.  
  3. #define GLEW_STATIC
  4. #include <GL/glew.h>
  5. #include <GLFW/glfw3.h>
  6.  
  7. #include <iostream>
  8. #include <vector>
  9. #include <string.h>
  10. #include <complex>
  11. #include <fstream>
  12.  
  13. const char *vertex = R"(
  14.     #version 330 core
  15.     layout (location = 0) in vec3 position;
  16.     layout (location = 1) in vec3 color;
  17.     layout (location = 2) in vec2 texCoord;
  18.  
  19.     out vec3 ourColor;
  20.     out vec2 TexCoord;
  21.  
  22.     void main() {
  23.         gl_Position = vec4(position, 1.0f);
  24.         ourColor = color;
  25.         TexCoord = texCoord;
  26.     }
  27. )";
  28.  
  29. const char *fragment = R"(
  30.     #version 330 core
  31.  
  32.     uniform vec2 screenSize;
  33.     uniform sampler2D image;
  34.  
  35.     in vec3 ourColor;
  36.     in vec2 TexCoord;
  37.  
  38.     out vec4 color;
  39.  
  40.     uniform sampler2D ourTexture;
  41.  
  42.     void main() {
  43.         color = texture(ourTexture, TexCoord);
  44.     }
  45. )";
  46.  
  47. GLuint compileShader(GLenum shaderType, const char* source) {
  48.     GLuint shader = glCreateShader(shaderType);
  49.     if (shader) {
  50.         glShaderSource(shader, 1, &source, NULL);
  51.         glCompileShader(shader);
  52.         GLint status = 0;
  53.         glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  54.         if (!status) {
  55.             GLint log_len;
  56.             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len);
  57.             if (log_len > 0) {
  58.                 vector<char> message(log_len + 1);
  59.                 glGetShaderInfoLog(shader, log_len, NULL, &message[0]);
  60.                 printf("%s\n", &message[0]);
  61.             }
  62.             glDeleteShader(shader);
  63.             shader = 0;
  64.         }
  65.     }
  66.     return shader;
  67. }
  68.  
  69. GLuint createShader(const char* vertexSource, const char* fragmentSource) {
  70.     GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexSource);
  71.     if (!vertexShader) return 0;
  72.    
  73.     GLuint pixelShader = compileShader(GL_FRAGMENT_SHADER, fragmentSource);
  74.     if (!pixelShader) return 0;
  75.  
  76.     GLuint program = glCreateProgram();
  77.     if (program) {
  78.         glAttachShader(program, vertexShader);
  79.         glAttachShader(program, pixelShader);
  80.         glLinkProgram(program);
  81.         GLint status = GL_FALSE;
  82.         glGetProgramiv(program, GL_LINK_STATUS, &status);
  83.         if (status != GL_TRUE) {
  84.             GLint log_len;
  85.             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len);
  86.             if (log_len > 0) {
  87.                 vector<char> message(log_len + 1);
  88.                 glGetProgramInfoLog(program, log_len, NULL, &message[0]);
  89.                 printf("%s\n", &message[0]);
  90.             }
  91.             glDeleteProgram(program);
  92.             program = 0;
  93.         }
  94.     }
  95.     return program;
  96. }
  97.  
  98. struct Color {
  99.     unsigned char r, g, b;
  100. };
  101.  
  102. struct TextureData {
  103.     GLuint bufferId;
  104.     int width, height;
  105.     Color *pixels;
  106.  
  107.     TextureData(int width, int height) : width(width), height(height) {
  108.         pixels = new Color[width * height];
  109.         glGenTextures(1, &bufferId);
  110.         glBindTexture(GL_TEXTURE_2D, bufferId);
  111.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  112.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  113.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  114.         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  115.         glBindTexture(GL_TEXTURE_2D, 0);
  116.  
  117.         apply();
  118.     }
  119.  
  120.     void apply() {
  121.         glBindTexture(GL_TEXTURE_2D, bufferId);
  122.         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
  123.         glBindTexture(GL_TEXTURE_2D, 0);
  124.     }
  125.  
  126.     ~TextureData() {
  127.         delete[] pixels;
  128.     }
  129.  
  130.     Color getPixel(int x, int y) {
  131.         return pixels[y * width + x];
  132.     }
  133.  
  134.     void setPixel(int x, int y, Color color) {
  135.         pixels[y * width + x] = color;
  136.     }
  137. };
  138.  
  139. int main() {
  140.     glfwInit();
  141.     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  142.     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  143.     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  144.     glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
  145.  
  146.     GLFWwindow* window = glfwCreateWindow(800, 600, "Computer graphics", nullptr, nullptr);
  147.     if (window == nullptr) {
  148.         cout << "Failed to create GLFW window" << endl;
  149.         glfwTerminate();
  150.         return -1;
  151.     }
  152.     glfwMakeContextCurrent(window);
  153.  
  154.     glewExperimental = GL_TRUE;
  155.     if (glewInit() != GLEW_OK) {
  156.         cout << "Failed to initialize GLEW" << endl;
  157.         return -1;
  158.     }
  159.  
  160.     int width, height;
  161.     glfwGetFramebufferSize(window, &width, &height);
  162.     glViewport(0, 0, width, height);
  163.  
  164.     auto shader = createShader(vertex, fragment);
  165.  
  166.     GLfloat vertices[] = {
  167.         // Positions          // Colors           // Texture Coords
  168.          1,  1, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // Top Right
  169.          1, -1, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // Bottom Right
  170.         -1, -1, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // Bottom Left
  171.         -1,  1, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // Top Left
  172.     };
  173.     GLuint indices[] = {  // Note that we start from 0!
  174.         0, 1, 3, // First Triangle
  175.         1, 2, 3  // Second Triangle
  176.     };
  177.     GLuint VBO, VAO, EBO;
  178.     glGenVertexArrays(1, &VAO);
  179.     glGenBuffers(1, &VBO);
  180.     glGenBuffers(1, &EBO);
  181.  
  182.     glBindVertexArray(VAO);
  183.  
  184.     glBindBuffer(GL_ARRAY_BUFFER, VBO);
  185.     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  186.  
  187.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
  188.     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
  189.  
  190.     // Position attribute
  191.     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
  192.     glEnableVertexAttribArray(0);
  193.     // Color attribute
  194.     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
  195.     glEnableVertexAttribArray(1);
  196.     // TexCoord attribute
  197.     glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
  198.     glEnableVertexAttribArray(2);
  199.     glBindVertexArray(0); // Unbind VAO
  200.  
  201.  
  202.     enum { pallete_size = 64 };
  203.     unsigned char pallete[pallete_size][3];
  204.     for (int i = 0; i < pallete_size; i++) {
  205.         pallete[i][0] = i < (2 * pallete_size / 3) ? (i * 255 * 3 / (2 * pallete_size)) : 255;
  206.         pallete[i][1] = i < pallete_size / 3 ? 0 : (i  - pallete_size / 3) * 255 * 3 / (2 * pallete_size);
  207.         pallete[i][2] = 0;
  208.     }
  209.  
  210.     TextureData texture(width, height);
  211.     for (int y = 0; y < height; ++y) {
  212.         for (int x = 0; x < width; ++x) {
  213.             complex<double> c(1.0 * (x - (width - height) / 2.0) / height * 4.0 - 2.0, 1.0 * y / height * 4.0 - 2.0);
  214.             complex<double> z(0.0, 0.0);
  215.  
  216.             int n = 0;
  217.             while (n < pallete_size) {
  218.                 z = z * z + c;
  219.                 if (abs(z) > 2.0) break;
  220.                 ++n;
  221.             }
  222.             unsigned char r = pallete[n][0];
  223.             unsigned char g = 0;//pallete[n][1];
  224.             unsigned char b = 0;//pallete[n][2];
  225.  
  226.             texture.setPixel(x, y, Color{r, g, b});
  227.         }
  228.     }
  229.     texture.apply();
  230.  
  231.  
  232.     glUseProgram(shader);
  233.     glUniform2f(glGetUniformLocation(shader, "screenSize"), width, height);
  234.  
  235.     while(!glfwWindowShouldClose(window)) {
  236.         glfwPollEvents();
  237.  
  238.         glClearColor(0, 0, 1, 1);
  239.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  240.  
  241.         glActiveTexture(GL_TEXTURE0);
  242.         glBindTexture(GL_TEXTURE_2D, texture.bufferId);
  243.         glUniform1i(glGetUniformLocation(shader, "ourTexture"), 0);
  244.        
  245.         // Draw container
  246.         glBindVertexArray(VAO);
  247.         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  248.         glBindVertexArray(0);
  249.        
  250.         glfwSwapBuffers(window);
  251.     }
  252.     glUseProgram(0);
  253.     glfwTerminate();
  254.     return 0;
  255. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement