#include "graphics.h" #include "utils.h" #include #include #include #include #include using namespace Mandelbrot; using namespace mpfr; Graphics::Graphics(int w, int h, std::string title) : w(w), h(h), title(title), from(Vec2mp(0.0, 0.0)), to(Vec2mp(0.0, 0.0)) { SDL_Window *window = SDL_CreateWindow(this->title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, this->w, this->h, 0); if (!window) { std::cout << "Could not create window. " << SDL_GetError() << std::endl; exit(EXIT_FAILURE); } this->window = window; SDL_Renderer *r = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (!r) { std::cout << "Could not create renderer. " << SDL_GetError() << std::endl; exit(EXIT_FAILURE); } this->renderer = r; this->running = true; } void Graphics::drawPoint(const Vec2i &pos, const rgb &col) { SDL_RenderDrawPoint(this->renderer, pos.x, pos.y); } void Graphics::plot(Mandelbrotc const &m) { // std::vector screen = std::vector(); // std::vector screen1 = std::vector(); // #pragma omp parallel sections // { // #pragma omp section // { // for (int i = 0; i < this->w/2; i+=2) { // for (int j = 0; j < this->h/2; j+=2) { // mpreal x = (mpfr::abs(from.x - to.x) * (i / this->w)) + from.x; // mpreal y = (mpfr::abs(from.y - to.y) * (j / this->h)) + from.y; // // std::cout << "px: " << x.to_str() << std::endl; // // std::cout << "py: " << y.to_str() << std::endl; // uint32_t max_iter = 50; // uint32_t iter = mandelbrot(Vec2mp(x, y), max_iter); // std::cout << "iter: " << iter << std::endl; // uint8_t color = 255 - (int)(iter*255/max_iter); // screen.push_back(color); // SDL_SetRenderDrawColor(this->renderer, color, color, color, 255); // SDL_RenderDrawPoint(renderer, (int)i, (int)j); // } // } // } // #pragma omp section // { // for (int i = 1; i < this->w/2; i+=2) { // for (int j = 1; j < this->h/2; j+=2) { // mpreal x = (mpfr::abs(from.x - to.x) * (i / this->w)) + from.x; // mpreal y = (mpfr::abs(from.y - to.y) * (j / this->h)) + from.y; // // std::cout << "px: " << x.to_str() << std::endl; // // std::cout << "py: " << y.to_str() << std::endl; // uint32_t max_iter = 50; // uint32_t iter = mandelbrot(Vec2mp(x, y), max_iter); // std::cout << "iter: " << iter << std::endl; // uint8_t color = 255 - (int)(iter*255/max_iter); // screen1.push_back(color); // SDL_SetRenderDrawColor(this->renderer, color, color, color, 255); // SDL_RenderDrawPoint(renderer, (int)i, (int)j); // } // } // } // } // for (double i = 1.0; i < this->w/2; i+=2) { // for (double j = 1.0; j < this->h/2; j+=2) { // uint8_t color = screen[i*h/2+j]; // SDL_SetRenderDrawColor(this->renderer, color, color, color, 255); // SDL_RenderDrawPoint(renderer, (int)i, (int)j); // } // } // for (double i = 0.0; i < this->w; i++) { // for (double j = 0.0; j < this->h; j++) { // mpreal x = (mpfr::abs(from.x - to.x) * (i / this->w)) + from.x; // mpreal y = (mpfr::abs(from.y - to.y) * (j / this->h)) + from.y; // uint32_t max_iter = 50; // uint32_t iter = mandelbrot(Vec2mp(x, y), max_iter); // //std::cout << "iter: " << iter << std::endl; // uint8_t color = 255 - (iter*255/max_iter); // SDL_SetRenderDrawColor(this->renderer, color, color, color, 255); // SDL_RenderDrawPoint(renderer, (int)i, (int)j); // } // } for (uint32_t i = 0; i < m.s.x; i++) { for (uint32_t j = 0; j < m.s.y; j++) { uint8_t color = 255 - (m.screen[i][j]*255/m.max_iter); SDL_SetRenderDrawColor(this->renderer, color, color, color, 255); SDL_RenderDrawPoint(renderer, (int)i, (int)j); } } } void Graphics::mainLoop() { mpreal fx = mpreal(-2); mpreal fy = mpreal(-1); mpreal tx = mpreal(1); mpreal ty = mpreal(1); this->from = Vec2mp(fx, fy); this->to = Vec2mp(tx, ty); bool mouseDown = false; Vec2i m_start = Vec2i(0, 0); Vec2i m_end = Vec2i(0, 0); Mandelbrotc m = Mandelbrotc(from, to, Vec2i(this->w, this->h), 100); m.thread_count = 16; m.start_threads(true); while (this->running) { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: running = false; break; case SDL_MOUSEWHEEL: if (event.wheel.y > 0) { std::cout << "wheel" << std::endl; this->from.x += 0.2; this->to.x -= 0.2; this->from.y += 0.2; this->to.y -= 0.2; } if (event.wheel.y < 0) { std::cout << "wheel" << std::endl; this->from.x -= 0.2; this->to.x += 0.2; this->from.y -= 0.2; this->to.y += 0.2; } break; case SDL_MOUSEBUTTONDOWN: if (mouseDown) break; mouseDown = true; m_start.x = event.button.x; m_start.y = event.button.y; break; case SDL_MOUSEBUTTONUP: mouseDown = false; break; case SDL_MOUSEMOTION: m_end.x = event.motion.x; m_end.y = event.motion.y; break; } } if (mouseDown) { SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); if (m_start.x < m_end.x) { for (int i = m_start.x; i < m_end.x; i++) { SDL_RenderDrawPoint(renderer, i, m_start.y); SDL_RenderDrawPoint(renderer, i, m_end.y); } } else { for (int i = m_end.x; i < m_start.x; i++) { SDL_RenderDrawPoint(renderer, i, m_start.y); SDL_RenderDrawPoint(renderer, i, m_end.y); } } if (m_start.y < m_end.y) { for (int i = m_start.y; i < m_end.y; i++) { SDL_RenderDrawPoint(renderer, m_start.x, i); SDL_RenderDrawPoint(renderer, m_end.x, i); } } else { for (int i = m_end.y; i < m_start.y; i++) { SDL_RenderDrawPoint(renderer, m_start.x, i); SDL_RenderDrawPoint(renderer, m_end.x, i); } } } // std::cout << "mainloop range " << this->from.x << std::endl; // std::cout << "mainloop range " << this->from.y << std::endl; // std::cout << "mainloop range " << this->to.x << std::endl; // std::cout << "mainloop range " << this->to.y << std::endl; m.start_threads(false); this->plot(m); m.stop_threads(); // std::cout << "done" << std::endl; SDL_RenderPresent(renderer); SDL_SetRenderDrawColor(this->renderer, 255, 255, 255, 255); SDL_RenderClear(renderer); SDL_Delay(100); if (m.done) exit(1); } m.stop_threads(); }