SimpleFastOpenAtomicVisualiser
Loading...
Searching...
No Matches
main.h
Go to the documentation of this file.
1#ifndef MAIN_H
2#define MAIN_H
3
4#include <sstream>
5#include <chrono>
6#include <exception>
7#include <algorithm>
8
9#define STB_IMAGE_WRITE_IMPLEMENTATION
10#include <stb_image_write.h>
11
12#include <jGL/jGL.h>
13#include <jGL/OpenGL/openGLInstance.h>
14#include <jGL/Display/desktopDisplay.h>
15#include <jGL/orthoCam.h>
16
17#include <icon.h>
18
19#include <jLog/jLog.h>
20
21#include <atom.h>
22#include <atomRenderer.h>
23#include <bondRenderer.h>
24#include <axes.h>
25#include <util.h>
26#include <glUtils.h>
27#include <structureUtils.h>
28#include <commandLine.h>
29#include <xyz.h>
30#include <config.h>
31#include <camera.h>
32#include <cell.h>
33#include <console.h>
34#include <visualisationState.h>
35#include <neighbours.h>
36
37const float dr = (1.0)*0.5;
38const float dtheta = (3.14)*0.025;
39const float dphi = (2.0*3.14)*0.05;
40
41const float emphasisedAlpha = 1.0f;
42
43bool closing = false;
44
45std::unique_ptr<jGL::jGLInstance> jGLInstance;
46
53void screenshot(glm::ivec2 resolution)
54{
55 std::vector<uint8_t> pixels(resolution.x*resolution.y*4, 0);
57 (
58 0,
59 0,
60 resolution.x,
61 resolution.y,
62 GL_RGBA,
64 pixels.data()
65 );
67 std::string name = timeStamp()+".png";
68 stbi_write_png(name.c_str(), resolution.x, resolution.y, 4, pixels.data(), 4*resolution.x);
69}
70
82(
84 int key,
85 int scancode,
86 int action,
87 int mods
88)
89{
91 {
92 closing = true;
93 }
94 jGL::parseAction(window, key, action);
95}
96
101struct Theme
102{
103 glm::vec4 background;
104 glm::vec4 text;
105};
106
113{
114 return
115 {
116 glm::vec4(5.0, 5.0, 5.0, 255.0)/255.0f,
117 glm::vec4(250.0, 250.0, 250.0, 255.0)/255.0f
118 };
119}
120
127{
128 return
129 {
130 glm::vec4(250.0, 250.0, 250.0, 255.0)/255.0f,
131 glm::vec4(5.0, 5.0, 5.0, 255.0)/255.0f
132 };
133}
134
143bool cameraControls(jGL::DesktopDisplay & display, Camera & camera)
144{
145 bool moved = false;
146 if (display.keyHasAnyEvents(GLFW_KEY_W, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
147 {
148 camera.zoom(-dr);
149 moved = true;
150 }
151 if (display.keyHasAnyEvents(GLFW_KEY_S, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
152 {
153 camera.zoom(dr);
154 moved = true;
155 }
156 if (display.keyHasAnyEvents(GLFW_KEY_Q, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
157 {
158 camera.incline(dtheta);
159 moved = true;
160 }
161 if (display.keyHasAnyEvents(GLFW_KEY_E, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
162 {
163 camera.incline(-dtheta);
164 moved = true;
165 }
166 if (display.keyHasAnyEvents(GLFW_KEY_A, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
167 {
168 camera.rotate(-dphi);
169 moved = true;
170 }
171 if (display.keyHasAnyEvents(GLFW_KEY_D, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
172 {
173 camera.rotate(dphi);
174 moved = true;
175 }
176 return moved;
177}
178
190(
191 jGL::DesktopDisplay & display,
192 std::vector<Atom> & atoms,
193 std::map<int, Element> & emphasisControls,
194 std::multimap<Element, uint64_t> & elementMap,
195 std::vector<float> & alphaOverrides,
196 float deemphasisAlpha
197)
198{
199 bool elementsNeedUpdate = false;
200 if (display.keyHasEvent(GLFW_KEY_LEFT, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_LEFT, jGL::EventType::HOLD))
201 {
202 translate(atoms, {-dr, 0.0, 0.0});
203 elementsNeedUpdate = true;
204 }
205 if (display.keyHasEvent(GLFW_KEY_RIGHT, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_RIGHT, jGL::EventType::HOLD))
206 {
207 translate(atoms, {dr, 0.0, 0.0});
208 elementsNeedUpdate = true;
209 }
210 if (display.keyHasEvent(GLFW_KEY_PERIOD, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_PERIOD, jGL::EventType::HOLD))
211 {
212 translate(atoms, {0.0, -dr, 0.0});
213 elementsNeedUpdate = true;
214 }
215 if (display.keyHasEvent(GLFW_KEY_SLASH, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_SLASH, jGL::EventType::HOLD))
216 {
217 translate(atoms, {0.0, dr, 0.0});
218 elementsNeedUpdate = true;
219 }
220 if (display.keyHasEvent(GLFW_KEY_DOWN, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_DOWN, jGL::EventType::HOLD))
221 {
222 translate(atoms, {0.0, 0.0, -dr});
223 elementsNeedUpdate = true;
224 }
225 if (display.keyHasEvent(GLFW_KEY_UP, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_UP, jGL::EventType::HOLD))
226 {
227 translate(atoms, {0.0, 0.0, dr});
228 elementsNeedUpdate = true;
229 }
230
231 for (const auto & control : emphasisControls)
232 {
233 if (display.keyHasEvent(control.first, jGL::EventType::PRESS))
234 {
235 auto iter = elementMap.equal_range(control.second);
236 while (iter.first != iter.second)
237 {
238 float & alpha = alphaOverrides[iter.first->second];
239 alpha = (alpha == emphasisedAlpha ? deemphasisAlpha : emphasisedAlpha);
240 atoms[iter.first->second].colour.a = alpha;
241 iter.first++;
242 }
243 elementsNeedUpdate = true;
244 }
245 }
246
247 return elementsNeedUpdate;
248}
249
256void setAlpha(std::vector<Atom> & atoms, std::vector<float> alphas)
257{
258 for (uint64_t i = 0; i < atoms.size(); i++) { atoms[i].colour.a = alphas[i]; }
259}
260
270(
271 jGL::DesktopDisplay & display,
272 Camera & camera,
274 std::string progressMessage,
275 Theme theme,
276 const unsigned int resX,
277 const unsigned int resY,
278 bool hideInfo = false
279)
280{
281 double deltas[60];
282 double delta = 0;
283 unsigned frameId = 0;
284 auto tic = std::chrono::high_resolution_clock::now();
285
286 jGLInstance->beginFrame();
287 jGLInstance->setClear(theme.background);
288 jGLInstance->clear();
289
290 cameraControls(display, camera);
291
292 loadingAtoms.updateCamera(camera);
293 loadingAtoms.draw(true);
294
295 std::stringstream debugText;
296
297 if (!hideInfo)
298 {
299 jGLInstance->text(
301 glm::vec2(64.0f, resY-64.0f),
302 0.5f,
303 theme.text
304 );
305 }
306
307 jGLInstance->endFrame();
308 display.loop();
309
310 delta = 0.0;
311 for (int n = 0; n < 60; n++)
312 {
313 delta += deltas[n];
314 }
315 delta /= 60.0;
316 auto toc = std::chrono::high_resolution_clock::now();
317 deltas[frameId] = std::chrono::duration_cast<std::chrono::milliseconds>(toc-tic).count();
318 frameId = (frameId+1) % 60;
319}
320
326void backward(std::unique_ptr<Structure> & structure)
327{
328 uint64_t f = structure->framePosition();
329 if (f > 2) { f -= 2; }
330 else { f = structure->frameCount()-2+f;}
331 structure->readFrame(f);
332}
333
342(
343 const std::vector<Atom> & atoms,
346)
347{
348 for (const auto & atom : atoms)
349 {
350 if (atom.colour.a != 0.0 && atom.colour.a != 1.0)
351 {
352 atomRenderer.setTransparencySorting(true);
353 bondRenderer.setTransparencySorting(true);
354 return;
355 }
356 }
357 atomRenderer.setTransparencySorting(false);
358 bondRenderer.setTransparencySorting(false);
359}
360
361#endif /* MAIN_H */
void translate(std::vector< Atom > &atoms, glm::vec3 r)
Definition atom.h:146
Render atoms as sphere meshes.
Definition atomRenderer.h:27
Render Bonds as ray-traced cylinders.
Definition bondRenderer.h:18
A 3D projective camera centered on a focus moving on a sphere.
Definition camera.h:30
void rotate(float increment)
Rotate about the y OpenGL axis.
Definition camera.h:136
void zoom(float increment)
Increment the zoom.
Definition camera.h:110
void incline(float increment)
Incline about the y OpenGL axis.
Definition camera.h:117
glm::vec< L, float, glm::qualifier::highp > vec
Definition commandLine.h:214
bool closing
Definition main.h:43
void keyEventCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
Override jGL default event callback.
Definition main.h:82
const float dr
Definition main.h:37
void loadingScreenFrame(jGL::DesktopDisplay &display, Camera &camera, AtomRenderer &loadingAtoms, std::string progressMessage, Theme theme, const unsigned int resX, const unsigned int resY, bool hideInfo=false)
Display a frame of the loading screen.
Definition main.h:270
bool atomControls(jGL::DesktopDisplay &display, std::vector< Atom > &atoms, std::map< int, Element > &emphasisControls, std::multimap< Element, uint64_t > &elementMap, std::vector< float > &alphaOverrides, float deemphasisAlpha)
Controls for the Atoms position's.
Definition main.h:190
void setAlpha(std::vector< Atom > &atoms, std::vector< float > alphas)
Set the alpha channel of Atom colours.
Definition main.h:256
void setTransparencySorting(const std::vector< Atom > &atoms, AtomRenderer &atomRenderer, BondRenderer &bondRenderer)
Enable of disable transparency sorting if there are transparent elements.
Definition main.h:342
const float dphi
Definition main.h:39
Theme lightTheme()
A light colour theme.
Definition main.h:126
const float dtheta
Definition main.h:38
std::unique_ptr< jGL::jGLInstance > jGLInstance
Definition main.h:45
void backward(std::unique_ptr< Structure > &structure)
Move back one frame.
Definition main.h:326
void screenshot(glm::ivec2 resolution)
Obtain screen pixels and write to a png.
Definition main.h:53
const float emphasisedAlpha
Definition main.h:41
Theme darkTheme()
A dark colour theme.
Definition main.h:112
bool cameraControls(jGL::DesktopDisplay &display, Camera &camera)
Controls for the camera.
Definition main.h:143
A background and text colour theme.
Definition main.h:102
glm::vec4 background
Definition main.h:103
glm::vec4 text
Definition main.h:104
std::string timeStamp()
Current timestamp.
Definition util.h:179