-
Notifications
You must be signed in to change notification settings - Fork 233
Expand file tree
/
Copy pathscreenshot.cpp
More file actions
124 lines (88 loc) · 3.22 KB
/
screenshot.cpp
File metadata and controls
124 lines (88 loc) · 3.22 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
123
124
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run
#include "polyscope/screenshot.h"
#include "polyscope/polyscope.h"
#include "stb_image_write.h"
#include <algorithm>
#include <string>
namespace polyscope {
namespace state {
// Storage for the screenshot index
size_t screenshotInd = 0;
} // namespace state
// Helper functions
namespace {
bool hasExtension(std::string str, std::string ext) {
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
if (str.length() >= ext.length()) {
return (0 == str.compare(str.length() - ext.length(), ext.length(), ext));
} else {
return false;
}
}
} // namespace
void saveImage(std::string name, unsigned char* buffer, int w, int h, int channels) {
// our buffers are from openGL, so they are flipped
stbi_flip_vertically_on_write(1);
stbi_write_png_compression_level = 0;
// Auto-detect filename
if (hasExtension(name, ".png")) {
stbi_write_png(name.c_str(), w, h, channels, buffer, channels * w);
} else if (hasExtension(name, ".jpg") || hasExtension(name, "jpeg")) {
stbi_write_jpg(name.c_str(), w, h, channels, buffer, 100);
// TGA seems to display different on different machines: our fault or theirs?
// Both BMP and TGA need alpha channel stripped? bmp doesn't seem to work even with this
/*
} else if (hasExtension(name, ".tga")) {
stbi_write_tga(name.c_str(), w, h, channels, buffer);
} else if (hasExtension(name, ".bmp")) {
stbi_write_bmp(name.c_str(), w, h, channels, buffer);
*/
} else {
// Fall back on png
stbi_write_png(name.c_str(), w, h, channels, buffer, channels * w);
}
}
void screenshot(std::string filename, bool transparentBG) {
render::engine->useAltDisplayBuffer = true;
if (transparentBG) render::engine->lightCopy = true; // copy directly in to buffer without blending
// == Make sure we render first
processLazyProperties();
// save the redraw requested bit and restore it below
bool requestedAlready = redrawRequested();
requestRedraw();
draw(false, false);
if (requestedAlready) {
requestRedraw();
}
// these _should_ always be accurate
int w = view::bufferWidth;
int h = view::bufferHeight;
std::vector<unsigned char> buff = render::engine->displayBufferAlt->readBuffer();
// Set alpha to 1
if (!transparentBG) {
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
int ind = i + j * w;
buff[4 * ind + 3] = std::numeric_limits<unsigned char>::max();
}
}
}
// Save to file
saveImage(filename, &(buff.front()), w, h, 4);
render::engine->useAltDisplayBuffer = false;
if (transparentBG) render::engine->lightCopy = false;
}
void screenshot(bool transparentBG) {
char buff[50];
snprintf(buff, 50, "screenshot_%06zu%s", state::screenshotInd, options::screenshotExtension.c_str());
std::string defaultName(buff);
// only pngs can be written with transparency
if (!hasExtension(options::screenshotExtension, ".png")) {
transparentBG = false;
}
screenshot(defaultName, transparentBG);
state::screenshotInd++;
}
void resetScreenshotIndex() { state::screenshotInd = 0; }
} // namespace polyscope