summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cplx.h26
-rw-r--r--mandel.cu9
-rw-r--r--mandel.h5
-rw-r--r--sdl.cpp27
4 files changed, 59 insertions, 8 deletions
diff --git a/cplx.h b/cplx.h
new file mode 100644
index 0000000..5e1538d
--- /dev/null
+++ b/cplx.h
@@ -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};
+}
diff --git a/mandel.cu b/mandel.cu
index 6d34802..c23f92f 100644
--- a/mandel.cu
+++ b/mandel.cu
@@ -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); \
diff --git a/mandel.h b/mandel.h
index 99d4b60..e154328 100644
--- a/mandel.h
+++ b/mandel.h
@@ -1,9 +1,14 @@
#pragma once
+#include <cstddef>
+#include <cstdint>
+
+
struct Params {
double cx, cy, imgw;
int16_t maxit;
+ int par1, par2;
};
struct Mandel;
diff --git a/sdl.cpp b/sdl.cpp
index ea2f0f9..b854571 100644
--- a/sdl.cpp
+++ b/sdl.cpp
@@ -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