-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmandelbrot.cpp
More file actions
122 lines (110 loc) · 3.6 KB
/
Copy pathmandelbrot.cpp
File metadata and controls
122 lines (110 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "mandelbrot_kernel.cuh"
#include <SDL3/SDL.h>
#include <cuda_runtime.h>
#include <numeric>
#include <complex>
#include <cmath>
#include <limits>
using DataType = double;
static int max_iterations = 5;
static DataType zoom = 1.0;
static DataType offsetX = 0.0;
static DataType offsetY = 0.0;
const int normal = 1;
const int WIDTH = 800;
const int HEIGHT = 600;
int isInSet(std::complex<DataType> c, int max_iterations)
{
std::complex<DataType> z(0, 0);
int i;
for (int i = 0; i < max_iterations; i++)
{
z = std::pow(z, 2) + c;
if (std::norm(z) > normal)
{
return i;
}
}
return max_iterations;
}
template <typename T>
constexpr T lerp(T a, T b, T t) {
if (std::isnan(a) || std::isnan(b) || std::isnan(t)) {
return std::numeric_limits<T>::quiet_NaN();
}
return a + t * (b - a);
}
void drawFractal(SDL_Renderer* renderer)
{
SDL_RenderClear(renderer);
size_t mem_size = WIDTH * HEIGHT * sizeof(DataType);
DataType* h_screen;
cudaError(cudaMallocHost(&h_screen, mem_size));
DataType* d_screen;
cudaError(cudaMalloc(reinterpret_cast<void**>(&d_screen), mem_size));
launch_calculateScreen(d_screen, zoom, offsetX, offsetY, max_iterations);
cudaMemcpy(h_screen, d_screen, mem_size, cudaMemcpyDeviceToHost);
for (int y = 0; y < HEIGHT; y++)
{
for (int x = 0; x < WIDTH; x++)
{
/*
DataType point_x = lerp(-2.0f / zoom + offsetX, 2.0f / zoom + offsetX, static_cast<DataType>(x)/WIDTH);
DataType point_y = lerp(-2.0f / zoom + offsetY, 2.0f / zoom + offsetY, static_cast<DataType>(y)/HEIGHT);
*/
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
//int iters = isInSet(std::complex<DataType>(point_x, point_y), max_iterations);
if (h_screen[y * WIDTH + x] < max_iterations)
{
SDL_SetRenderDrawColor(renderer,
20 * h_screen[y * WIDTH + x] ,
3 * h_screen[y * WIDTH + x] ,
10 * h_screen[y * WIDTH + x],
255);
}
SDL_RenderPoint(renderer, x, y);
}
}
SDL_RenderPresent(renderer);
}
int main()
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_CreateWindowAndRenderer("Mandelbrot",800, 600,0, &window, &renderer);
if (!window || !renderer) {
SDL_Log("Failed to create window/renderer: %s", SDL_GetError());
return 1;
}
SDL_Event event;
while (true)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_EVENT_QUIT)
{
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
if (event.type == SDL_EVENT_KEY_DOWN)
{
switch (event.key.scancode)
{
case SDL_SCANCODE_W: offsetY -= 0.1 / zoom; break;
case SDL_SCANCODE_S: offsetY += 0.1 / zoom; break;
case SDL_SCANCODE_A: offsetX -= 0.1 / zoom; break;
case SDL_SCANCODE_D: offsetX += 0.1 / zoom; break;
case SDL_SCANCODE_Q: zoom *= 1.1; break;
case SDL_SCANCODE_E: zoom /= 1.1; break;
case SDL_SCANCODE_R: max_iterations += 1; break;
case SDL_SCANCODE_T: max_iterations -= 1; break;
default: break;
}
}
}
drawFractal(renderer);
}
}