Skip to content

Commit 6d4872d

Browse files
committed
add screenshot capturing
1 parent a5ccf88 commit 6d4872d

File tree

6 files changed

+53
-9
lines changed

6 files changed

+53
-9
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ Click + drag to draw a rectangle to zoom into.
4141

4242
### Keyboard
4343

44-
- <kbd>space</kbd> -- reset viewer
44+
- <kbd>space</kbd> -- take screenshot
45+
- <kbd>r</kbd> -- reset viewer
4546
- <kbd>+</kbd>/<kbd>=</kbd> -- zoom in
4647
- <kbd>-</kbd> -- zoom out
4748
- <kbd>.</kbd> -- increase detail (iterations)

src/input.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "SDL.h"
33
#include <iostream>
44

5-
void Input::HandleInput(Mandelbrot &instance) const {
5+
void Input::handleInput(Mandelbrot &instance, Renderer &renderer) const {
66
SDL_Event e;
77

88
while (SDL_PollEvent(&e)) {
@@ -65,6 +65,10 @@ void Input::HandleInput(Mandelbrot &instance) const {
6565
break;
6666
}
6767
case SDLK_SPACE: {
68+
renderer.captureScreenshot();
69+
break;
70+
}
71+
case SDLK_r: {
6872
instance.resetBounds();
6973
break;
7074
}

src/input.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55

66
// forward declaration for use in function signature
77
class Mandelbrot;
8+
class Renderer;
89

910
class Input {
1011
public:
11-
void HandleInput(Mandelbrot &instance) const;
12+
void handleInput(Mandelbrot &instance, Renderer &renderer) const;
1213
};
1314

1415
#endif

src/mandelbrot.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ void renderLoop(MessageQueue<RenderOptions> &queue, bool &running) {
6363
if (options) {
6464
updatePixelsInRange(options.value());
6565
}
66-
std::cout << running << std::endl;
6766
}
6867
}
6968

@@ -78,6 +77,7 @@ void Mandelbrot::resetBounds() {
7877
zoom = 1.0;
7978
center_y = 0.0;
8079
center_x = -1.0;
80+
max_iterations = 50;
8181
setBoundsFromState();
8282
}
8383

@@ -206,7 +206,7 @@ void Mandelbrot::run(Input const &Input, Renderer &renderer) {
206206
Uint32 prev_frame_end = SDL_GetTicks();
207207

208208
while (running) {
209-
Input.HandleInput(*this);
209+
Input.handleInput(*this, renderer);
210210

211211
Uint32 frame_start = SDL_GetTicks();
212212

@@ -217,7 +217,7 @@ void Mandelbrot::run(Input const &Input, Renderer &renderer) {
217217

218218
Uint32 calculate_duration = SDL_GetTicks() - frame_start;
219219

220-
renderer.updateWindowTitle(calculate_duration);
220+
renderer.updateWindowTitle(max_iterations, x_min, x_max, y_min, y_max);
221221
dirty = false;
222222
}
223223

src/renderer.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "renderer.h"
2+
#include <filesystem>
23
#include <iostream>
34
#include <string>
45

@@ -51,6 +52,31 @@ Renderer::~Renderer() {
5152
SDL_Quit();
5253
}
5354

55+
void Renderer::captureScreenshot() {
56+
SDL_Surface *screenshot =
57+
SDL_CreateRGBSurface(0, screen_width, screen_height, 32, 0x00ff0000,
58+
0x0000ff00, 0x000000ff, 0xff000000);
59+
60+
SDL_RenderReadPixels(sdl_renderer, NULL, SDL_PIXELFORMAT_ARGB8888,
61+
screenshot->pixels, screenshot->pitch);
62+
63+
// Figure out the next free screenshot path will be
64+
unsigned int next_screenshot_slot = 0;
65+
std::filesystem::path output_path{
66+
"screenshot-" + std::to_string(next_screenshot_slot) + ".bmp"};
67+
68+
while (std::filesystem::exists(output_path)) {
69+
next_screenshot_slot++;
70+
output_path = std::filesystem::path(
71+
"screenshot-" + std::to_string(next_screenshot_slot) + ".bmp");
72+
}
73+
74+
SDL_SaveBMP(screenshot, output_path.c_str());
75+
SDL_FreeSurface(screenshot);
76+
77+
std::cout << "Wrote out " << output_path << std::endl;
78+
}
79+
5480
void Renderer::render(SDL_Rect selection) {
5581

5682
// Apply pixels vector to texture
@@ -74,7 +100,16 @@ void Renderer::render(SDL_Rect selection) {
74100
SDL_RenderPresent(sdl_renderer);
75101
}
76102

77-
void Renderer::updateWindowTitle(unsigned int render_time) {
78-
std::string title{"Mandelbrot -- last render " + std::to_string(render_time)};
103+
void Renderer::updateWindowTitle(unsigned int iterations, double x_min,
104+
double x_max, double y_min, double y_max) {
105+
std::string title{std::to_string(iterations) + " iterations -- top left (" +
106+
std::to_string(x_min) + "," + std::to_string(y_min) +
107+
") bottom right (" + std::to_string(x_max) + "," +
108+
std::to_string(y_max) + ")"};
109+
110+
// Change window title to reflect current view
79111
SDL_SetWindowTitle(sdl_window, title.c_str());
112+
113+
// Log title also to console for debugging purposes
114+
std::cout << title << std::endl;
80115
}

src/renderer.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ class Renderer {
1010
Renderer(unsigned int screen_width, unsigned int screen_height);
1111
~Renderer();
1212

13+
void captureScreenshot();
14+
1315
void render(SDL_Rect selection);
14-
void updateWindowTitle(unsigned int render_time);
16+
void updateWindowTitle(unsigned int iterations, double x_min, double x_max,
17+
double y_min, double y_max);
1518

1619
// get mutable access to pixel data
1720
std::vector<Uint32> &getPixels() { return pixels; };

0 commit comments

Comments
 (0)