Advertisement
Guest User

Untitled

a guest
Nov 9th, 2017
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include <assert.h>
  3. #include <windows.h>
  4. #include <stdio.h>
  5. #include <exception>
  6. #include <omp.h>
  7. #include "Complex.h"
  8.  
  9. TCHAR NazwaAplikacji[] = TEXT("FRAKTALE");
  10. TCHAR NazwaKlasy[] = TEXT("OKNOGLOWNE");
  11.  
  12. const int ImageWidth = 1024;
  13. const int ImageHeight = 768;
  14. char *Obraz = NULL;
  15.  
  16. unsigned char NrAlgorytmu = 0;
  17. double CzasPrzetwarzania = 0.0;
  18. TCHAR tAlgorytm[64];
  19. unsigned char tadl = 0;
  20.  
  21. struct RGB { unsigned char B, G, R; };
  22.  
  23. inline unsigned int RoundUp4(const unsigned int i)
  24. {
  25.     return (i+3)&(~3);
  26. }
  27.  
  28. void WyczyscObraz(RGB* Raster, int Width, int Height)
  29. {
  30.     RGB *Punkt;
  31.     for (int y = 0; y < Height; ++y)
  32.     {
  33.         Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);      
  34.         for (int x = 0; x < Width; ++x)
  35.         {
  36.             Punkt->R = 0;
  37.             Punkt->G = 0;
  38.             Punkt->B = 0;          
  39.             ++Punkt;
  40.         }
  41.     }
  42. }
  43.  
  44. // Mandelbrot =====================================================================================
  45.  
  46. int IterateMandelbrot(Complex P, int maxIter)
  47. {
  48.     Complex z = P;
  49.     int cnt = 0;
  50.     while((z.x * z.x + z.y * z.y <= 4)&& (cnt < maxIter)){
  51.         z = ComplexSquare(z);
  52.         z.x += P.x;
  53.         z.y += P.y;
  54.         cnt++;
  55.     }
  56.     return cnt;
  57. }
  58.  
  59. void Mandelbrot(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax)
  60. {
  61.     RGB *Punkt;
  62.     float realInc = (RealMax - RealMin) / Width;
  63.     float imagInc = (ImagMax - ImagMin) / Height;
  64.     Complex z;
  65.     int x, y;
  66.     int cnt;
  67.  
  68.     for (y = 0, z.y = ImagMin; y < Height; ++y, z.y += imagInc)
  69.     {
  70.         Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);
  71.  
  72.         for (x = 0, z.x = RealMin; x < Width; ++x, z.x += realInc)
  73.         {
  74.             cnt = IterateMandelbrot(z, MaxIter);
  75.  
  76.             if(cnt == MaxIter)
  77.             {
  78.                 Punkt->R = 255;
  79.                 Punkt->G = 255;
  80.                 Punkt->B = 255;
  81.             }
  82.             else
  83.             {
  84.                 Punkt->R = 0;
  85.                 Punkt->G = cnt;
  86.                 Punkt->B = 0;
  87.             }
  88.  
  89.             ++Punkt;
  90.         }
  91.     }
  92. }
  93.  
  94. void Mandelbrot_Parallel(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax);
  95.  
  96. // Julia ==========================================================================================
  97.  
  98. int IterateJulia(Complex zInit, int maxIter, Complex c)
  99. {
  100.     Complex z = zInit;
  101.     int cnt = 0;
  102.     while((z.x * z.x + z.y * z.y <= 4)&& (cnt < maxIter)){
  103.         z = ComplexSquare(z);
  104.         z.x += c.x;
  105.         z.y += c.y;
  106.         cnt++;
  107.     }
  108.     return cnt;
  109. }
  110. void Julia_Parallel(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax, Complex c);
  111.  
  112. void Julia(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax, Complex c)
  113. {
  114.     RGB *Punkt;
  115.     float realInc = (RealMax - RealMin) / Width;
  116.     float imagInc = (ImagMax - ImagMin) / Height;
  117.     Complex z;
  118.     int x, y;
  119.     int cnt;
  120.  
  121.     for (y = 0, z.y = ImagMin; y < Height; ++y, z.y += imagInc)
  122.     {
  123.         Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);
  124.  
  125.         for (x = 0, z.x = RealMin; x < Width; ++x, z.x += realInc)
  126.         {
  127.             cnt = IterateJulia(z, MaxIter, c);
  128.  
  129.             if(cnt == MaxIter)
  130.             {
  131.                 Punkt->R = 255;
  132.                 Punkt->G = 255;
  133.                 Punkt->B = 255;
  134.             }
  135.             else
  136.             {
  137.                 Punkt->R = 0;
  138.                 Punkt->G = cnt;
  139.                 Punkt->B = 0;
  140.             }
  141.  
  142.             ++Punkt;
  143.         }
  144.     }
  145. }
  146.  
  147. int tid, nthreads;
  148.  
  149. static void GenerujFraktal()
  150. {
  151.     assert(sizeof(RGB) == 3);
  152.     BITMAPFILEHEADER *bfh = reinterpret_cast<BITMAPFILEHEADER*>(Obraz);
  153.     BITMAPINFO *bi = reinterpret_cast<BITMAPINFO*>(Obraz + sizeof(BITMAPFILEHEADER));
  154.     RGB *Raster = reinterpret_cast<RGB*>(Obraz + bfh->bfOffBits);
  155.  
  156.     int Width = bi->bmiHeader.biWidth;
  157.     int Height = bi->bmiHeader.biHeight;
  158.  
  159.     // Stała C1 uzywane podczas generowania zbioru Julii
  160.     Complex c1;
  161.     c1.x = 0.281f; c1.y = 0.011f;
  162.  
  163.     // Stała C2 uzywane podczas generowania zbioru Julii
  164.     Complex c2;
  165.     c2.x = -0.810f; c2.y = 0.179f;
  166.  
  167.     switch (NrAlgorytmu)
  168.     {
  169.     case 0:
  170.         // Mandelbrot Sekwencyjny ----------------------------------------------------------------------           
  171.         tadl = wsprintf(tAlgorytm, TEXT(". . ."));         
  172.         WyczyscObraz(Raster, Width, Height);
  173.         break;
  174.  
  175.     case 1:        
  176.         tadl = wsprintf(tAlgorytm, TEXT("Mandlebrot Sekwencyjny"));
  177.         Mandelbrot(Raster, Width, Height, 500, -2.0f, 0.8f, -1.0f, 1.0f);          
  178.         break;
  179.  
  180.     case 2:          
  181.         {
  182.             tadl = wsprintf(tAlgorytm, TEXT("Julia Sekwencyjny dla C1"));
  183.             Julia(Raster, Width, Height, 500, -1.0f, 1.0f, -1.0f, 1.0f, c1);
  184.         }
  185.         break;
  186.  
  187.     case 3:        
  188.         tadl = wsprintf(tAlgorytm, TEXT("Julia Sekwencyjny dla C2"));          
  189.         Julia(Raster, Width, Height, 500, -1.0f, 1.0f, -0.8f, 0.8f, c2);
  190.         break;
  191.  
  192.     case 4:        
  193.         tadl = wsprintf(tAlgorytm, TEXT("Mandelbrot Zrównoleglony"));
  194.         Mandelbrot_Parallel(Raster, Width, Height, 500, -2.0f, 0.8f, -1.0f, 1.0f);
  195.         break;     
  196.  
  197.     case 5:        
  198.         tadl = wsprintf(tAlgorytm, TEXT("Julia Zrównoleglony dla C1"));           
  199.         Julia_Parallel(Raster, Width, Height, 500, -1.0f, 1.0f, -1.0f, 1.0f, c1);
  200.  
  201.         break;
  202.  
  203.     case 6:        
  204.         tadl = wsprintf(tAlgorytm, TEXT("Julia Zrównoleglony dla C2"));
  205.         Julia_Parallel(Raster, Width, Height, 500, -1.0f, 1.0f, -0.8f, 0.8f, c2);
  206.  
  207.         break; 
  208.  
  209.     default:           
  210.         tadl = wsprintf(tAlgorytm, TEXT(". . ."));         
  211.         WyczyscObraz(Raster, Width, Height);
  212.         break;
  213.     }
  214. }
  215.  
  216. static void Tworz(const HWND Okno)
  217. {
  218.     BITMAPFILEHEADER   bmfHeader;
  219.     BITMAPINFOHEADER   bi;
  220.  
  221.     bi.biSize = sizeof(BITMAPINFOHEADER);    
  222.     bi.biWidth = ImageWidth;
  223.     bi.biHeight = ImageHeight;
  224.     bi.biPlanes = 1;
  225.     bi.biBitCount = 24;
  226.     bi.biCompression = BI_RGB;    
  227.     bi.biSizeImage = 0;
  228.     bi.biXPelsPerMeter = 0;    
  229.     bi.biYPelsPerMeter = 0;    
  230.     bi.biClrUsed = 0;    
  231.     bi.biClrImportant = 0;
  232.  
  233.     DWORD dwBmpSize = ImageWidth * ImageHeight * bi.biBitCount/8;
  234.     HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
  235.     char *lpbitmap = (char *)GlobalLock(hDIB);
  236.  
  237.     DWORD dwSizeOfDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);   
  238.     bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
  239.     bmfHeader.bfSize = dwSizeOfDIB;
  240.     bmfHeader.bfType = 0x4D42;
  241.  
  242.     Obraz = new char[dwSizeOfDIB];
  243.     CopyMemory(Obraz, &bmfHeader, sizeof(BITMAPFILEHEADER));
  244.     CopyMemory(Obraz + sizeof(BITMAPFILEHEADER), &bi, sizeof(BITMAPINFOHEADER));
  245.     CopyMemory(Obraz + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER), lpbitmap, dwBmpSize);
  246.  
  247.     GlobalUnlock(hDIB);
  248.     GlobalFree(hDIB);
  249. }
  250.  
  251. static void Rysuj(const HWND Okno)
  252. {
  253.     RECT Rozmiar;
  254.     TCHAR Tekst[128];
  255.     PAINTSTRUCT PS;
  256.     unsigned int dl;
  257.     GetClientRect(Okno, &Rozmiar);
  258.     const HDC DC = BeginPaint(Okno, &PS);
  259.     if (Obraz != 0) {
  260.         BITMAPFILEHEADER *bfh = reinterpret_cast<BITMAPFILEHEADER*>(Obraz);
  261.         BITMAPINFO *bi = reinterpret_cast<BITMAPINFO*>(Obraz + sizeof(BITMAPFILEHEADER));
  262.         SetStretchBltMode(DC, HALFTONE);
  263.         StretchDIBits(DC, 0, 0, Rozmiar.right, Rozmiar.bottom, 0, 0, bi->bmiHeader.biWidth, bi->bmiHeader.biHeight,
  264.             static_cast<void*>(Obraz + bfh->bfOffBits), bi, DIB_RGB_COLORS, SRCCOPY);
  265.         dl = swprintf_s(Tekst, TEXT("Czas obliczeń: %.2lf s"), CzasPrzetwarzania);
  266.         TextOut(DC, 5, 5, Tekst, dl);
  267.         TextOut(DC, 5, 25, tAlgorytm, tadl);
  268.     }
  269.     EndPaint(Okno, &PS);
  270. }
  271.  
  272. static void Znak(const HWND Okno, const TCHAR Znak)
  273. {
  274.     if (Znak >= TEXT('0') && Znak <= TEXT('9')) {      
  275.         SYSTEMTIME S1, S2;
  276.         NrAlgorytmu = Znak - TEXT('0');
  277.         SetWindowText(Okno, TEXT("Przetwarzanie..."));     
  278.         GetSystemTime(&S1);
  279.         if (NrAlgorytmu >= 0 && NrAlgorytmu <= 9)
  280.         {
  281.             GenerujFraktal();
  282.         }
  283.         GetSystemTime(&S2);
  284.         CzasPrzetwarzania = 3600.0 * (S2.wHour - S1.wHour) + 60.0 * (S2.wMinute - S1.wMinute)
  285.             + (S2.wSecond - S1.wSecond) + 0.001 * (S2.wMilliseconds - S1.wMilliseconds);       
  286.         InvalidateRect(Okno, NULL, FALSE);
  287.         SetWindowText(Okno, NazwaAplikacji);
  288.         UpdateWindow(Okno);
  289.     }
  290.  
  291.     if(Znak == 27)
  292.     {
  293.         DestroyWindow(Okno);
  294.     }
  295. }
  296.  
  297. static LRESULT CALLBACK FunkcjaOkienkowa(HWND Okno, UINT Komunikat, WPARAM wParam, LPARAM lParam)
  298. {
  299.     switch (Komunikat) {
  300.     case WM_CREATE:
  301.         Tworz(Okno);
  302.         tadl = wsprintf(tAlgorytm, TEXT("..."));
  303.         break;
  304.     case WM_CHAR:
  305.         Znak(Okno, static_cast<TCHAR>(wParam));
  306.         break;
  307.     case WM_PAINT:
  308.         Rysuj(Okno);
  309.         break;
  310.     case WM_DESTROY:
  311.         delete [] Obraz;
  312.         PostQuitMessage(0);
  313.         break;
  314.     default:
  315.         return DefWindowProc(Okno, Komunikat, wParam, lParam);
  316.     }
  317.     return 0;
  318. }
  319.  
  320. static bool RejestrujKlasy()
  321. {
  322.     WNDCLASSEX wc;
  323.     wc.cbSize = sizeof(WNDCLASSEX);
  324.     wc.cbClsExtra = wc.cbWndExtra = 0;
  325.     wc.hbrBackground = (HBRUSH) (1 + COLOR_WINDOW);
  326.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  327.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  328.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  329.     wc.hInstance = GetModuleHandle(NULL);
  330.     wc.lpfnWndProc = &FunkcjaOkienkowa;
  331.     wc.lpszClassName = NazwaKlasy;
  332.     wc.lpszMenuName = NULL;
  333.     wc.style = CS_HREDRAW | CS_VREDRAW;
  334.     return (RegisterClassEx(&wc) != 0);
  335. }
  336.  
  337. static void WyrejestrujKlasy()
  338. {
  339.     UnregisterClass(NazwaKlasy, GetModuleHandle(NULL));
  340. }
  341.  
  342. void Julia_Parallel(RGB* Raster, int Width, int Height
  343.     , int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax, Complex c)
  344. {
  345.     RGB *Punkt;
  346.     float realInc = (RealMax - RealMin) / Width;
  347.     float imagInc = (ImagMax - ImagMin) / Height;
  348.     Complex z;
  349.     int x, y;
  350.     int cnt;
  351.  
  352.     //z.y = ImagMin;
  353.  
  354. #pragma omp parallel private(y, Punkt, x, cnt, z) num_threads(8)
  355.     {
  356.         #pragma omp for
  357.         for (y = 0 ; y < Height; ++y )
  358.         {
  359.         z.y=ImagMin+imagInc*y;
  360.            
  361.             Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);
  362.  
  363.             for (x = 0, z.x = RealMin; x < Width; ++x, z.x += realInc)
  364.             {
  365.                 cnt = IterateJulia(z, MaxIter, c);
  366.  
  367.                 if(cnt == MaxIter)
  368.                 {
  369.                     Punkt->R = 255;
  370.                     Punkt->G = 255;
  371.                     Punkt->B = 255;
  372.                 }
  373.                 else
  374.                 {
  375.                     Punkt->R = 0;
  376.                     Punkt->G = cnt;
  377.                     Punkt->B = 0;
  378.                 }
  379.  
  380.                 ++Punkt;
  381.  
  382.             }
  383.            
  384.             z.y += imagInc;
  385.         }
  386.        
  387.  
  388.     }
  389.  
  390. }
  391. void Mandelbrot_Parallel(RGB* Raster, int Width, int Height, int MaxIter, float RealMin, float RealMax, float ImagMin, float ImagMax)
  392. {
  393.     RGB *Punkt;
  394.     float realInc = (RealMax - RealMin) / Width;
  395.     float imagInc = (ImagMax - ImagMin) / Height;
  396.     Complex z;
  397.     int x, y;
  398.     int cnt;
  399.  
  400.     //z.y = ImagMin;
  401.  
  402. #pragma omp parallel private(y, Punkt, x, cnt, z) num_threads(8)
  403.     {
  404.         #pragma omp for
  405.         for (y = 0 ; y < Height; ++y )
  406.         {
  407.         z.y=ImagMin+imagInc*y;
  408.            
  409.             Punkt = Raster + RoundUp4(y * Width * sizeof(RGB)) / sizeof(RGB);
  410.  
  411.             for (x = 0, z.x = RealMin; x < Width; ++x, z.x += realInc)
  412.             {
  413.                 cnt = IterateMandelbrot(z, MaxIter);
  414.  
  415.                 if(cnt == MaxIter)
  416.                 {
  417.                     Punkt->R = 255;
  418.                     Punkt->G = 255;
  419.                     Punkt->B = 255;
  420.                 }
  421.                 else
  422.                 {
  423.                     Punkt->R = 0;
  424.                     Punkt->G = cnt;
  425.                     Punkt->B = 0;
  426.                 }
  427.  
  428.                 ++Punkt;
  429.  
  430.             }
  431.            
  432.             z.y += imagInc;
  433.         }
  434.        
  435.  
  436.     }
  437.  
  438. }
  439.  
  440. int WINAPI WinMain(HINSTANCE Instancja, HINSTANCE Poprzednia, LPSTR Parametry, int Widocznosc)
  441. {
  442.     // Zarejestruj klasę. Protestuj, jeżeli wystąpił błąd.
  443.     if (!RejestrujKlasy()) {
  444.         MessageBox(NULL, TEXT("Nie udało się zarejestrować klasy okna!"),
  445.             NazwaAplikacji, MB_ICONSTOP | MB_OK);
  446.         return 1;
  447.     }
  448.     // Stwórz główne okno. Również protestuj, jeżeli wystąpił błąd.
  449.     HWND GlowneOkno = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_CLIENTEDGE,
  450.         NazwaKlasy, NazwaAplikacji, WS_OVERLAPPEDWINDOW,
  451.         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  452.         NULL, NULL, Instancja, NULL);
  453.     if (GlowneOkno == NULL) {
  454.         MessageBox(NULL, TEXT("Nie udało się stworzyć głównego okna!"),
  455.             NazwaAplikacji, MB_ICONSTOP | MB_OK);
  456.         return 2;
  457.     }
  458.     // Wyświetl i uaktualnij nowo stworzone okno.
  459.     ShowWindow(GlowneOkno, Widocznosc);
  460.     UpdateWindow(GlowneOkno);
  461.     // Główna pętla komunikatów wątku.
  462.     MSG Komunikat;
  463.     while (GetMessage(&Komunikat, NULL, 0, 0) > 0) {
  464.         TranslateMessage(&Komunikat);
  465.         DispatchMessage(&Komunikat);
  466.     }
  467.     // Zwolnij pamięć klas i zakończ proces.
  468.     WyrejestrujKlasy();
  469.     return static_cast<int>(Komunikat.wParam);
  470. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement