Advertisement
Guest User

attractor.cpp

a guest
May 9th, 2015
687
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.49 KB | None | 0 0
  1. #define WIN32_LEAN_AND_MEAN
  2. #define WIN32_EXTRA_LEAN
  3.  
  4. #include <windows.h>
  5. #include <gl\gl.h>
  6. #include <gl\glu.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <math.h>
  10. #include <time.h>
  11.  
  12. #include "glext.h"
  13. #include "Font.h"
  14.  
  15. //screen resolution
  16. #define WIDTH 1440
  17. #define HEIGHT 960
  18. #define FULLSCREEN 1
  19. #define BLUR 1
  20. #define MAXBUFFER 3
  21. #define MAXSHADERS 3
  22. #define GLOWRES 8
  23.  
  24. //attractor parameters
  25. #define MAXVERTS 500000
  26. #define MAXCYCLE 1000
  27. #define CYCLETHRESHOLD 50
  28. #define NEARTHRESHOLD 0.0001
  29. #define COLORMULTIPLIER 2.0
  30. #define INITSEED 99438
  31.  
  32. //opengl extensions
  33. PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
  34. PFNGLCREATESHADERPROC glCreateShader = NULL;
  35. PFNGLSHADERSOURCEPROC glShaderSource = NULL;
  36. PFNGLCOMPILESHADERPROC glCompileShader = NULL;
  37. PFNGLATTACHSHADERPROC glAttachShader = NULL;
  38. PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
  39. PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
  40. PFNGLUSEPROGRAMPROC glUseProgram = NULL;
  41. PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL;
  42. PFNGLUNIFORM1FPROC glUniform1f = NULL;
  43. PFNGLUNIFORM2FPROC glUniform2f = NULL;
  44. PFNGLUNIFORM1DPROC glUniform1d = NULL;
  45. PFNGLUNIFORM2DPROC glUniform2d = NULL;
  46. PFNGLUNIFORM1IPROC glUniform1i = NULL;
  47. PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
  48. PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL;
  49. PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL;
  50. PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffers = NULL;
  51. PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = NULL;
  52. PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = NULL;
  53. PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL;
  54. PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = NULL;
  55. PFNGLUNIFORM1FVPROC glUniform1fv = NULL;
  56. PFNGLACTIVETEXTUREARBPROC glActiveTexture = NULL;
  57. PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL;
  58. PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = NULL;
  59. PFNGLBLENDEQUATIONPROC glBlendEquation = NULL;
  60.  
  61. //function prototypes
  62. int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow);
  63. LRESULT CALLBACK wndprc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam);
  64. void gencoefficients(double *c, int seed);
  65. void keydown(WPARAM key);
  66. void keyup(WPARAM key);
  67. void drawquad();
  68.  
  69. //system variables
  70. BOOL key[256];
  71. BOOL active = TRUE;
  72. BOOL exitswitch = FALSE;
  73.  
  74. //attractor variables
  75. int seed = INITSEED;
  76. double c[12];
  77. int dir = 1;
  78. BOOL reset = FALSE;
  79.  
  80. //view variables
  81. float viewx = 0.0;
  82. float viewy = 0.0;
  83. float scale = 0.5;
  84.  
  85. int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow){
  86.  
  87.     //windows variables
  88.     HDC hdc = NULL;
  89.     HGLRC hrc = NULL;
  90.     HWND hwnd = NULL;
  91.     MSG msg;
  92.     PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };
  93.     GLuint pixelformat;
  94.     WNDCLASS wc;
  95.     DWORD dwexstyle;
  96.     DWORD dwstyle;
  97.     int width, height;
  98.     int screenwidth = GetSystemMetrics(SM_CXSCREEN);
  99.     int screenheight = GetSystemMetrics(SM_CYSCREEN);
  100.  
  101.     //attractor variables
  102.     float *v;
  103.     float *color;
  104.     double x = 0.1;
  105.     double y = 0.1;
  106.     double xn, yn;
  107.  
  108.     //frame buffer
  109.     GLuint renderbuffer[MAXBUFFER];
  110.     GLuint framebuffer[MAXBUFFER];
  111.     GLuint texture[MAXBUFFER];
  112.     int *buffer[MAXBUFFER];
  113.  
  114.     //texture passthrough source
  115.     char *passthrough =
  116.         "#version 120\n"
  117.         "uniform sampler2D texture;\n"
  118.         "uniform vec2 resolution;\n"
  119.         "void main(){\n"
  120.         "  vec2 p=gl_FragCoord.xy/resolution.xy;\n"
  121.         "  gl_FragColor=texture2D(texture,p);\n"
  122.         "}\n";
  123.  
  124.     //horizontal glow source
  125.     char *horizontalglow =
  126.         "#version 120\n"
  127.         "uniform sampler2D texture;\n"
  128.         "uniform vec2 resolution;\n"
  129.         "void main(){\n"
  130.         "  float k[15]=float[](0.0212,0.0327,0.0472,0.0637,0.0805,0.0951,0.1051,0.1086,0.1051,0.0951,0.0805,0.0637,0.0472,0.0327,0.0212);\n"
  131.         "  vec2 p=gl_FragCoord.xy/resolution.xy;\n"
  132.         "  vec2 d=vec2(1.0)/resolution.xy;\n"
  133.         "  vec4 c=vec4(0.0);\n"
  134.         "  vec4 ck;\n"
  135.         "  float l;"
  136.         "  for(int i=-7;i<=7;i++){\n"
  137.         "    ck=texture2D(texture,p+d*vec2(float(i),0.0));\n"
  138.         "    c+=1.5*k[i+7]*ck;\n"
  139.         "  }\n"
  140.         "  gl_FragColor=1.5*c;\n"
  141.         "}\n";
  142.  
  143.     //horizontal glow source
  144.     char *verticalglow =
  145.         "#version 120\n"
  146.         "uniform sampler2D texture;\n"
  147.         "uniform vec2 resolution;\n"
  148.         "void main(){\n"
  149.         "  float k[15]=float[](0.0212,0.0327,0.0472,0.0637,0.0805,0.0951,0.1051,0.1086,0.1051,0.0951,0.0805,0.0637,0.0472,0.0327,0.0212);\n"
  150.         "  vec2 p=gl_FragCoord.xy/resolution.xy;\n"
  151.         "  vec2 d=vec2(1.0)/resolution.xy;\n"
  152.         "  vec4 c=vec4(0.0);\n"
  153.         "  vec4 ck;\n"
  154.         "  float l;"
  155.         "  for(int i=-7;i<=7;i++){\n"
  156.         "    ck=texture2D(texture,p+d*vec2(0.0,float(i)));\n"
  157.         "    c+=k[i+7]*ck;\n"
  158.         "  }\n"
  159.         "  gl_FragColor=c;\n"
  160.         "}\n";
  161.  
  162.     //shaders
  163.     int shaderprogram[MAXSHADERS];
  164.     int fragmentshader[MAXSHADERS];
  165.  
  166.     //window attributes
  167.     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  168.     wc.lpfnWndProc = (WNDPROC)wndprc;
  169.     wc.cbClsExtra = 0;
  170.     wc.cbWndExtra = 0;
  171.     wc.hInstance = hinstance;
  172.     wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
  173.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  174.     wc.hbrBackground = NULL;
  175.     wc.lpszMenuName = NULL;
  176.     wc.lpszClassName = "Attractor";
  177.     RegisterClass(&wc);
  178.  
  179.     //create window
  180. #if FULLSCREEN
  181.     DEVMODE dmScreenSettings;
  182.     memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
  183.     dmScreenSettings.dmSize = sizeof(dmScreenSettings);
  184.     dmScreenSettings.dmPelsWidth = screenwidth;
  185.     dmScreenSettings.dmPelsHeight = screenheight;
  186.     dmScreenSettings.dmBitsPerPel = 16;
  187.     dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
  188.     ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
  189.     dwexstyle = WS_EX_APPWINDOW;
  190.     dwstyle = WS_POPUP;
  191.     ShowCursor(FALSE);
  192.     width = screenwidth;
  193.     height = screenheight;
  194.     hwnd = CreateWindowEx(dwexstyle, "Attractor", "Attractor", dwstyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, width, height, NULL, NULL, hinstance, NULL);
  195. #else
  196.     dwexstyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
  197.     dwstyle = WS_OVERLAPPEDWINDOW;
  198.     width = WIDTH;
  199.     height = HEIGHT;
  200.     hwnd = CreateWindowEx(dwexstyle, "Attractor", "Attractor", dwstyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, (screenwidth - WIDTH) / 2, (screenheight - HEIGHT) / 2, width, height, NULL, NULL, hinstance, NULL);
  201. #endif
  202.  
  203.     //attach gl context and show window
  204.     hdc = GetDC(hwnd);
  205.     pixelformat = ChoosePixelFormat(hdc, &pfd);
  206.     SetPixelFormat(hdc, pixelformat, &pfd);
  207.     hrc = wglCreateContext(hdc);
  208.     wglMakeCurrent(hdc, hrc);
  209.     ShowWindow(hwnd, SW_SHOW);
  210.     SetForegroundWindow(hwnd);
  211.     SetFocus(hwnd);
  212.  
  213.     //bind gl extensions
  214.     OutputDebugString("Binding OpenGL extensions...\n");
  215.     glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
  216.     glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader");
  217.     glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource");
  218.     glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader");
  219.     glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
  220.     glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog");
  221.     glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)wglGetProcAddress("glGetProgramInfoLog");
  222.     glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram");
  223.     glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");
  224.     glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation");
  225.     glUniform1f = (PFNGLUNIFORM1FPROC)wglGetProcAddress("glUniform1f");
  226.     glUniform2f = (PFNGLUNIFORM2FPROC)wglGetProcAddress("glUniform2f");
  227.     glUniform1d = (PFNGLUNIFORM1DPROC)wglGetProcAddress("glUniform1d");
  228.     glUniform2d = (PFNGLUNIFORM2DPROC)wglGetProcAddress("glUniform2d");
  229.     glUniform1i = (PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i");
  230.     glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer");
  231.     glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers");
  232.     glGenRenderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT");
  233.     glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbuffer");
  234.     glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorage");
  235.     glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D");
  236.     glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbuffer");
  237.     glUniform1fv = (PFNGLUNIFORM1FVPROC)wglGetProcAddress("glUniform1fv");
  238.     glActiveTexture = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTexture");
  239.     glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers");
  240.     glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffers");
  241.     glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation");
  242.  
  243.     //init frame buffer
  244.     OutputDebugString("Generating frame buffers...\n");
  245.     glGenFramebuffers(MAXBUFFER, framebuffer);
  246.     OutputDebugString("Generating render buffers...\n");
  247.     glGenRenderbuffers(MAXBUFFER, renderbuffer);
  248.     OutputDebugString("Generating textures...\n");
  249.     glGenTextures(MAXBUFFER, texture);
  250.  
  251.     //glow resolution
  252.     int glowwidth = width/GLOWRES;
  253.     int glowheight = height/GLOWRES;
  254.  
  255.     //main scene
  256.     OutputDebugString("Allocating texture 0...\n");
  257.     buffer[0] = (int*)malloc(width*height*sizeof(int));
  258.  
  259.     //vertical glow
  260.     OutputDebugString("Allocating texture 1...\n");
  261.     buffer[1] = (int*)malloc(glowwidth*glowheight*sizeof(int));
  262.  
  263.     //horizontal glow
  264.     OutputDebugString("Allocating texture 1...\n");
  265.     buffer[2] = (int*)malloc(glowwidth*glowheight*sizeof(int));
  266.  
  267.     //main scene
  268.     glBindTexture(GL_TEXTURE_2D, texture[0]);
  269.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer[0]);
  270.     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer[0]);
  271.     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
  272.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  273.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  274.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  275.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  276.  
  277.     //horizontal glow
  278.     glBindTexture(GL_TEXTURE_2D, texture[1]);
  279.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glowwidth, glowheight, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer[1]);
  280.     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer[1]);
  281.     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, glowwidth, glowheight);
  282.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  283.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  284.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  285.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  286.  
  287.     //vertical glow
  288.     glBindTexture(GL_TEXTURE_2D, texture[2]);
  289.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glowwidth, glowheight, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer[2]);
  290.     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer[2]);
  291.     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, glowwidth, glowheight);
  292.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  293.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  294.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  295.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  296.  
  297.     //compile shaders
  298.     OutputDebugString("Compiling shaders...\n");
  299.     char log[2014];
  300.  
  301.     //passthrough shader
  302.     shaderprogram[0] = glCreateProgram();
  303.     fragmentshader[0] = glCreateShader(GL_FRAGMENT_SHADER);
  304.     glShaderSource(fragmentshader[0], 1, (const GLchar**)&passthrough, 0);
  305.     glCompileShader(fragmentshader[0]);
  306.     memset(log, 0, sizeof(log));
  307.     glGetShaderInfoLog(fragmentshader[0], sizeof(log), 0, log);
  308.     OutputDebugString("Passthrough shader log:\n");
  309.     OutputDebugString(log);
  310.     glAttachShader(shaderprogram[0], fragmentshader[0]);
  311.     glLinkProgram(shaderprogram[0]);
  312.  
  313.     //horizontal glow shader
  314.     shaderprogram[1] = glCreateProgram();
  315.     fragmentshader[1] = glCreateShader(GL_FRAGMENT_SHADER);
  316.     glShaderSource(fragmentshader[1], 1, (const GLchar**)&horizontalglow, 0);
  317.     glCompileShader(fragmentshader[1]);
  318.     memset(log, 0, sizeof(log));
  319.     glGetShaderInfoLog(fragmentshader[1], sizeof(log), 0, log);
  320.     OutputDebugString("Horizontal glow shader log:\n");
  321.     OutputDebugString(log);
  322.     glAttachShader(shaderprogram[1], fragmentshader[1]);
  323.     glLinkProgram(shaderprogram[1]);
  324.  
  325.     //passthrough glow shader
  326.     shaderprogram[2] = glCreateProgram();
  327.     fragmentshader[2] = glCreateShader(GL_FRAGMENT_SHADER);
  328.     glShaderSource(fragmentshader[2], 1, (const GLchar**)&verticalglow, 0);
  329.     glCompileShader(fragmentshader[2]);
  330.     memset(log, 0, sizeof(log));
  331.     glGetShaderInfoLog(fragmentshader[2], sizeof(log), 0, log);
  332.     OutputDebugString("Vertical glow shader log:\n");
  333.     OutputDebugString(log);
  334.     glAttachShader(shaderprogram[2], fragmentshader[2]);
  335.     glLinkProgram(shaderprogram[2]);
  336.  
  337.     //init opengl
  338.     glClearColor(0.0, 0.0, 0.0, 0.0);
  339.  
  340. #if BLUR
  341.     //for frame blur
  342.     glClearAccum(0.0, 0.0, 0.0, 1.0);
  343.     glClear(GL_ACCUM_BUFFER_BIT);
  344. #endif
  345.  
  346.     //init attractor
  347.     gencoefficients(c, seed);
  348.     v = (float*)malloc(MAXVERTS * 2 * sizeof(float));
  349.     color = (float*)malloc(MAXVERTS * 3 * sizeof(float));
  350.  
  351.     while (!exitswitch){
  352.         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
  353.             switch (msg.message){
  354.             case WM_QUIT:
  355.                 exitswitch = TRUE;
  356.                 break;
  357.             default:
  358.                 TranslateMessage(&msg);
  359.                 DispatchMessage(&msg);
  360.             }
  361.         }
  362.         else if (active){
  363.  
  364.             //calculate attractor
  365.             bool regularcycledetected = FALSE;
  366.             if (reset){
  367.                 x = 0.1;
  368.                 y = 0.1;
  369.                 reset = FALSE;
  370.             }
  371.             for (int i = 0; i < MAXVERTS; i++){
  372.  
  373.                 //calculate next vertex
  374.                 xn = c[0] + c[1] * x + c[2] * x*x + c[3] * x*y + c[4] * y + c[5] * y*y;
  375.                 yn = c[6] + c[7] * x + c[8] * x*x + c[9] * x*y + c[10] * y + c[11] * y*y;
  376.                 v[i * 2] = xn;
  377.                 v[i * 2 + 1] = yn;
  378.  
  379.                 //calculate color for vertex
  380.                 float length = sqrt((xn - x)*(xn - x) + (yn - y)*(yn - y));
  381.                 //color[i * 3] = (float)(sin((xn - x)*COLORMULTIPLIER) / 2.0 + 0.5);
  382.                 //color[i * 3 + 1] = (float)(sin((yn - y)*COLORMULTIPLIER) / 2.0 + 0.5);
  383.                 //color[i * 3 + 2] = (float)(sin((yn - x)*COLORMULTIPLIER) / 2.0 + 0.5);
  384.                 //color[i * 3 + 2] = (float)(sin(length*COLORMULTIPLIER) / 2.0 + 0.5);
  385.                 color[i * 3] = sin(length*COLORMULTIPLIER+3.14*2.0/3.0) / 2.0 + 0.5;
  386.                 color[i * 3 + 1] = sin(length*COLORMULTIPLIER+3.14/3.0) / 2.0 + 0.5;
  387.                 color[i * 3 + 2] = sin(length*COLORMULTIPLIER) / 2.0 + 0.5;
  388.  
  389.                 //detect cycle
  390.                 if (i % MAXCYCLE == 0 && i != 0){
  391.                     int cyclelength;
  392.                     int cyclecount = 0;
  393.                     for (int j = i - 1; j > i - MAXCYCLE; j--){
  394.                         double dx = v[i * 2] - v[j * 2];
  395.                         double dy = v[i * 2 + 1] - v[j * 2 + 1];
  396.                         if (dx*dx + dy*dy < NEARTHRESHOLD){
  397.                             if (cyclecount == 0){
  398.                                 cyclecount++;
  399.                                 cyclelength = i - j;
  400.                             }
  401.                             else if ((i - j) % cyclelength == 0){
  402.                                 cyclecount++;
  403.                                 if (cyclecount >CYCLETHRESHOLD){
  404.                                     regularcycledetected = TRUE;
  405.                                     break;
  406.                                 }
  407.                             }
  408.                         }
  409.                     }
  410.                 }
  411.  
  412.                 if (xn*xn + yn*yn > 4.0 || regularcycledetected){
  413.                     if (dir)seed++;
  414.                     else seed--;
  415.                     x = 0.1;
  416.                     y = 0.1;
  417.                     gencoefficients(c, seed);
  418.                 }
  419.                 else{
  420.                     x = xn;
  421.                     y = yn;
  422.                 }
  423.             }
  424.    
  425.             //draw attractor at full resolution
  426.             glViewport(0, 0, width, height);
  427.             glBindFramebuffer(GL_FRAMEBUFFER, framebuffer[0]);
  428.             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[0], 0);
  429.             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer[0]);
  430.             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  431.             glLoadIdentity();
  432.  
  433.             //draw attractor           
  434.             glLoadIdentity();
  435.             glUseProgram(0);
  436.             glScalef(scale, scale*WIDTH / HEIGHT, 0.0);
  437.             glTranslatef(viewx, viewy, 0.0);
  438.             //blend
  439.             //glEnable(GL_BLEND);
  440.             //glBlendEquation(GL_FUNC_ADD);
  441.             //glBlendFunc(GL_ONE, GL_ONE);
  442.             glEnableClientState(GL_VERTEX_ARRAY);
  443.             glEnableClientState(GL_COLOR_ARRAY);
  444.             glColorPointer(3, GL_FLOAT, 0, color);
  445.             glVertexPointer(2, GL_FLOAT, 0, v);
  446.             glDrawArrays(GL_POINTS, 0, MAXVERTS * 2 * sizeof(float) / sizeof(float) / 2);
  447.             glDisableClientState(GL_VERTEX_ARRAY);
  448.             glDisableClientState(GL_COLOR_ARRAY);
  449.             //disable blend
  450.             //glDisable(GL_BLEND);
  451.            
  452.  
  453.             //draw horizontal glow
  454.             glViewport(0, 0, glowwidth, glowheight);
  455.             glBindFramebuffer(GL_FRAMEBUFFER, framebuffer[1]);
  456.             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[1], 0);
  457.             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer[1]);
  458.             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  459.             glActiveTexture(GL_TEXTURE0);
  460.             glBindTexture(GL_TEXTURE_2D, texture[0]);
  461.             glLoadIdentity();
  462.             glUseProgram(shaderprogram[1]);
  463.             glUniform2f(glGetUniformLocation(shaderprogram[0], "resolution"), glowwidth, glowheight);
  464.             drawquad();
  465.  
  466.             //draw vertical glow
  467.             glViewport(0, 0, glowwidth, glowheight);
  468.             glBindFramebuffer(GL_FRAMEBUFFER, framebuffer[2]);
  469.             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[2], 0);
  470.             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer[2]);
  471.             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  472.             glActiveTexture(GL_TEXTURE0);
  473.             glBindTexture(GL_TEXTURE_2D, texture[1]);
  474.             glLoadIdentity();
  475.             glUseProgram(shaderprogram[2]);
  476.             glUniform2f(glGetUniformLocation(shaderprogram[0], "resolution"), glowwidth, glowheight);
  477.             drawquad();
  478.  
  479.             //draw final scene
  480.             glBindFramebuffer(GL_FRAMEBUFFER, 0);
  481.             glViewport(0, 0, width, height);
  482.             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  483.             glLoadIdentity();
  484.             //use passthrough program
  485.             glUseProgram(shaderprogram[0]);
  486.             glUniform2f(glGetUniformLocation(shaderprogram[0], "resolution"), width, height);
  487.             //disable depth test
  488.             glDisable(GL_DEPTH_TEST);
  489.             glDepthFunc(GL_ALWAYS);
  490.             //enable blend
  491.             glEnable(GL_BLEND);
  492.             glBlendEquation(GL_FUNC_ADD);
  493.             glBlendFunc(GL_ONE, GL_ONE);
  494.             //draw glow
  495.             glActiveTexture(GL_TEXTURE0);
  496.             glBindTexture(GL_TEXTURE_2D, texture[2]);
  497.             drawquad();
  498.             //draw main scene
  499.             glActiveTexture(GL_TEXTURE0);
  500.             glBindTexture(GL_TEXTURE_2D, texture[0]);
  501.             drawquad();
  502.             //disable blend
  503.             glDisable(GL_BLEND);
  504.  
  505. #if BLUR
  506.             //blur frames
  507.             glAccum(GL_MULT, (GLfloat)(0.95));
  508.             glAccum(GL_ACCUM, (GLfloat)(1.0 - 0.95));
  509.             glAccum(GL_RETURN, (GLfloat)(1.0));
  510.             glFlush();
  511. #endif
  512.  
  513.             SwapBuffers(hdc);
  514.         }
  515.     }
  516.  
  517.     //kill window
  518.     wglMakeCurrent(NULL, NULL);
  519.     wglDeleteContext(hrc);
  520.     ReleaseDC(hwnd, hdc);
  521.     DestroyWindow(hwnd);
  522.     UnregisterClass("Attractor", hinstance);
  523.  
  524.     //free frame buffer
  525.     for (int i = 0; i < MAXBUFFER; i++){
  526.         free(buffer[i]);
  527.     }
  528.     glDeleteFramebuffers(MAXBUFFER, framebuffer);
  529.     glDeleteRenderbuffers(MAXBUFFER, renderbuffer);
  530.     free(v);
  531.     free(color);
  532.  
  533.     return (msg.wParam);
  534. }
  535.  
  536. LRESULT CALLBACK wndprc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam){
  537.     switch (umsg){
  538.     case WM_ACTIVATE:
  539.         if (!HIWORD(wparam)){
  540.             active = TRUE;
  541.         }
  542.         else{
  543.             active = FALSE;
  544.         }
  545.         return 0;
  546.     case WM_CLOSE:
  547.         PostQuitMessage(0);
  548.         return 0;
  549.     case WM_KEYDOWN:
  550.         keydown(wparam);
  551.         key[wparam] = TRUE;
  552.         return 0;
  553.     case WM_KEYUP:
  554.         keyup(wparam);
  555.         key[wparam] = FALSE;
  556.         return 0;
  557.     }
  558.     return DefWindowProc(hwnd, umsg, wparam, lparam);
  559. }
  560.  
  561. void gencoefficients(double *c, int seed){
  562.     srand(seed);
  563.     for (int i = 0; i < 12; i++){
  564.         c[i] = -1.2 + rand() % 24 * 0.1;
  565.     }
  566. }
  567.  
  568. void keydown(WPARAM key){
  569.     switch (key){
  570.     case VK_ESCAPE:
  571.         exitswitch = TRUE;
  572.         break;
  573.     case VK_PRIOR:
  574.         seed--;
  575.         gencoefficients(c, seed);
  576.         dir = 0;
  577.         reset = TRUE;
  578.         break;
  579.     case VK_NEXT:
  580.         seed++;
  581.         gencoefficients(c, seed);
  582.         dir = 1;
  583.         reset = TRUE;
  584.         break;
  585.     case VK_UP:
  586.         viewy -= 0.01 / scale;
  587.         break;
  588.     case VK_DOWN:
  589.         viewy += 0.01 / scale;
  590.         break;
  591.     case VK_LEFT:
  592.         viewx += 0.01 / scale;
  593.         break;
  594.     case VK_RIGHT:
  595.         viewx -= 0.01 / scale;
  596.         break;
  597.     case VK_HOME:
  598.         scale *= 1.01;
  599.         break;
  600.     case VK_END:
  601.         scale *= 0.99;
  602.         break;
  603.     case VK_INSERT:
  604.         scale = 0.5;
  605.         viewx = 0.0;
  606.         viewy = 0.0;
  607.         break;
  608.     }
  609. }
  610.  
  611. void keyup(WPARAM key){
  612. }
  613.  
  614. void drawquad(){
  615.     static float quadverts[] = {
  616.         -1.0, -1.0,
  617.         -1.0, 1.0,
  618.         1.0, 1.0,
  619.         -1.0, -1.0,
  620.         1.0, 1.0,
  621.         1.0, -1.0
  622.     };
  623.     glEnableClientState(GL_VERTEX_ARRAY);
  624.     glVertexPointer(2, GL_FLOAT, 0, quadverts);
  625.     glDrawArrays(GL_TRIANGLES, 0, sizeof(quadverts) / sizeof(float) / 2);
  626.     glDisableClientState(GL_VERTEX_ARRAY);
  627. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement