diff options
-rw-r--r-- | cplx.h | 26 | ||||
-rw-r--r-- | mandel.cu | 9 | ||||
-rw-r--r-- | mandel.h | 5 | ||||
-rw-r--r-- | sdl.cpp | 27 |
4 files changed, 59 insertions, 8 deletions
@@ -0,0 +1,26 @@ +#pragma once + + +struct device_complex { + double x, y; +}; + +template <int N> +__host__ __device__ inline device_complex complex_power(double x, double y, double x2, double y2) { + device_complex next = complex_power<N - 1>(x, y, x2, y2); + return device_complex{ + x * next.x - y * next.y, + x * next.y + y * next.x + }; +} + +template <> +__host__ __device__ inline device_complex complex_power<2>(double x, double y, double x2, double y2) { + return device_complex{x2 - y2, 2 * x * y}; +} + +template <> +__host__ __device__ inline device_complex complex_power<1>(double x, double y, double x2, double y2) { + (void)x2; (void)y2; + return device_complex{x, y}; +} @@ -1,10 +1,10 @@ #include <iostream> #include <cassert> -#include <cstdint> #include <sys/time.h> #include "mandel.h" #include "lodepng.h" #include "bmp.h" +#include "cplx.h" using namespace std; @@ -34,6 +34,7 @@ Params mandel_default_params() { par.cx = -0.5; par.cy = 0.0; par.imgw = 3.5; par.maxit = 512; + par.par1 = par.par2 = 0; return par; } @@ -61,7 +62,7 @@ void mandel_free(Mandel *ctx) { } // These macros may assume that the parameters are simple variable names. -#if 1 +#if 0 #define MANDEL_FUNCTION_REAL(a, b, a2, b2, x, y) (a2 - b2 + x) #define MANDEL_FUNCTION_IMAG(a, b, a2, b2, x, y) (2 * a * b + y) #endif @@ -73,6 +74,10 @@ void mandel_free(Mandel *ctx) { #define MANDEL_FUNCTION_REAL(a, b, a2, b2, x, y) (a2 * a - 3 * a * b * b + x) #define MANDEL_FUNCTION_IMAG(a, b, a2, b2, x, y) (3 * a * a * b - b2 * b + y) #endif +#if 1 +#define MANDEL_FUNCTION_REAL(a, b, a2, b2, x, y) (par->par1 * 0.01 * complex_power<5>(a, b, a2, b2).x + (1.0 - par->par2 * 0.01) * complex_power<2>(a, b, a2, b2).x + x) +#define MANDEL_FUNCTION_IMAG(a, b, a2, b2, x, y) (par->par1 * 0.01 * complex_power<5>(a, b, a2, b2).y + (1.0 - par->par2 * 0.01) * complex_power<2>(a, b, a2, b2).y + y) +#endif #define MANDEL_GENERIC(dst, ctx, par, ix, iy, idx) { \ const double x = (par).cx - (par).imgw / 2 + (par).imgw * (ix) / ((ctx).w-1); \ @@ -1,9 +1,14 @@ #pragma once +#include <cstddef> +#include <cstdint> + + struct Params { double cx, cy, imgw; int16_t maxit; + int par1, par2; }; struct Mandel; @@ -19,7 +19,8 @@ struct State { SDL_Surface *mandelsurf = nullptr; - size_t current_resolution = 4; + static const size_t init_render_resolution = 4; + size_t current_resolution = init_render_resolution; State() { if (SDL_Init(SDL_INIT_VIDEO) < 0) { @@ -47,15 +48,21 @@ struct State { if (SDL_MUSTLOCK(winsurf)) SDL_UnlockSurface(winsurf); } - void update_title() { + string build_title() { stringstream ss; ss << "Mandel " << setprecision(17) << " x=" << par.cx << " y=" << par.cy << " w=" << par.imgw - << " i=" << par.maxit; - SDL_SetWindowTitle(window, ss.str().data()); + << " i=" << par.maxit + << " par1=" << par.par1 + << " par2=" << par.par2; + return ss.str(); + } + + void update_title() { + SDL_SetWindowTitle(window, build_title().data()); } SDL_Event wait_event() const { @@ -120,6 +127,11 @@ struct State { if (par.maxit > 256) { par.maxit -= 128; return action::redraw; } break; + case SDLK_w: par.par1++; return action::redraw; + case SDLK_s: par.par1 = max(1, par.par1) - 1; return action::redraw; + case SDLK_e: par.par2++; return action::redraw; + case SDLK_d: par.par2 = max(1, par.par2) - 1; return action::redraw; + case SDLK_q: return action::quit; } @@ -162,10 +174,10 @@ int main() { switch (action) { case State::action::quit: - return 0; + goto exit_app; case State::action::redraw: - state.current_resolution = 4; + state.current_resolution = State::init_render_resolution; SDL_GetWindowSize(state.window, &state.w, &state.h); cerr << "w=" << state.w << " h=" << state.h << endl; @@ -186,5 +198,8 @@ int main() { break; } } + +exit_app: + cout << state.build_title() << endl; } #endif |