Project
Loading...
Searching...
No Matches
GPUDisplayKeys.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#include "GPUDisplay.h"
16#include "frontend/GPUDisplayInfo.inc"
17
18using namespace o2::gpu;
19
20const char* HelpText[] = {
21 "[ESC] Quit",
22 "[n] Next event",
23 "[r] Reset Display Settings",
24 "[l] / [k] / [J] Draw single sector (next / previous sector), draw related sectors (same plane in phi)",
25 "[;] / [:] Show splitting of TPC in sectors by extruding volume, [:] resets",
26 "[#] Invert colors",
27 "[y] / [Y] / ['] / [X] / [M] Start Animation, Add / remove Animation point, Reset Points, Cycle animation camera mode (resets)",
28 "[>] / [<] Toggle config interpolation during Animation / change Animation interval (via movement)",
29 "[g] Draw Grid",
30 "[i] Project onto XY-plane",
31 "[x] Exclude Clusters used in the tracking steps enabled for visualization ([1]-[8])",
32 "[.] Exclude rejected tracks",
33 "[c] Mark flagged clusters (splitPad = 0x1, splitTime = 0x2, edge = 0x4, singlePad = 0x8, rejectDistance = 0x10, rejectErr = 0x20",
34 "[z] Mark fake attached clusters",
35 "[B] Mark clusters attached as adjacent",
36 "[L] / [K] Draw single collisions (next / previous)",
37 "[C] Colorcode clusters of different collisions",
38 "[v] Hide rejected clusters from tracks",
39 "[j] Show tracks segments propagated to adjacent sector in different color / splt CE tracks",
40 "[u] Cycle through track filter",
41 "[E] / [G] Extrapolate tracks / loopers",
42 "[t] / [T] Take Screenshot / Record Animation to pictures",
43 "[Z] Change screenshot resolution (scaling factor)",
44 "[S] / [A] / [D] Enable or disable smoothing of points / smoothing of lines / depth buffer",
45 "[W] / [U] / [V] Toggle anti-aliasing (MSAA at raster level / change downsampling FSAA factor) / toggle VSync",
46 "[F] / [_] / [R] Switch mFullScreen / Maximized window / FPS limit (none, refresh rate, fpsRate)",
47 "[I] Enable / disable GL indirect draw",
48 "[o] / [p] / [O] / [P] Save / restore current camera position / Animation path",
49 "[h] Print Help",
50 "[H] Show info texts",
51 "[q] Start / Stop Qt GUI",
52 "[w] / [s] / [a] / [d] Zoom / Strafe Left and Right",
53 "[pgup] / [pgdn] Strafe up / down",
54 "[e] / [f] Rotate left / right",
55 "[+] / [-] Increase / decrease point size (Hold SHIFT for lines)",
56 "[b] Change FOV (field of view)",
57 "[m] Switch between core / compat renderer path (OpenGL profile, Vulkan smooth lines)",
58 "[MOUSE 1] Look around",
59 "[MOUSE 2] Strafe camera",
60 "[MOUSE 1+2] Zoom / Rotate",
61 "[SHIFT] Slow Zoom / Move / Rotate",
62 "[ALT] / [CTRL] / [ENTER] Focus camera on origin / orient y-axis upwards (combine with [SHIFT] to lock) / Cycle through modes",
63 "[RCTRL] / [RALT] Rotate model instead of camera / rotate TPC around beamline",
64 "[1] ... [8] / [N] Enable display of clusters, preseeds, seeds, starthits, tracklets, tracks, extrapolated tracks, merged tracks / Show assigned clusters in colors",
65 "[F1] / [F2] / [F3] / [F4] Enable / disable drawing of TPC / TRD / TOF / ITS",
66 "[SHIFT] + [F1] to [F4] Enable / disable track detector filter",
67 "[SHIFT] + [F12] Switch track detector filter between AND and OR mode"
68 // FREE: [SPACE] [Q]
69 // Test setting: ^
70};
71
72void GPUDisplay::PrintHelp()
73{
74 mInfoHelpTimer.ResetStart();
75 for (uint32_t i = 0; i < sizeof(HelpText) / sizeof(HelpText[0]); i++) {
76 GPUInfo("%s", HelpText[i]);
77 }
78}
79
80void GPUDisplay::HandleKey(uint8_t key, bool doNotHandleConfigChanges)
81{
82 const GPUSettingsDisplayHeavy oldCfgH = mCfgH;
83 const GPUSettingsDisplayLight oldCfgL = mCfgL;
84 const GPUSettingsDisplayRenderer oldCfgR = mCfgR;
85 if (key == 'n') {
86 mFrontend->mDisplayControl = 1;
87 SetInfo("Showing next event", 1);
88 } else if (key == 27 || key == mFrontend->KEY_ESCAPE) {
89 mFrontend->mDisplayControl = 2;
90 SetInfo("Exiting", 1);
91 } else if (key == 'r') {
92 mResetScene = true;
93 SetInfo("View reset", 1);
94 } else if (key == mFrontend->KEY_ALT && mFrontend->mKeysShift[mFrontend->KEY_ALT]) {
95 mCfgR.camLookOrigin ^= 1;
96 mCfgR.cameraMode = mCfgR.camLookOrigin + 2 * mCfgR.camYUp;
97 SetInfo("Camera locked on origin: %s", mCfgR.camLookOrigin ? "enabled" : "disabled");
98 } else if (key == mFrontend->KEY_CTRL && mFrontend->mKeysShift[mFrontend->KEY_CTRL]) {
99 mCfgR.camYUp ^= 1;
100 mCfgR.cameraMode = mCfgR.camLookOrigin + 2 * mCfgR.camYUp;
101 SetInfo("Camera locked on y-axis facing upwards: %s", mCfgR.camYUp ? "enabled" : "disabled");
102 } else if (key == mFrontend->KEY_ENTER) {
103 mCfgR.cameraMode++;
104 if (mCfgR.cameraMode == 4) {
105 mCfgR.cameraMode = 0;
106 }
107 mCfgR.camLookOrigin = mCfgR.cameraMode & 1;
108 mCfgR.camYUp = mCfgR.cameraMode & 2;
109 const char* modeText[] = {"Descent (free movement)", "Focus locked on origin (y-axis forced upwards)", "Spectator (y-axis forced upwards)", "Focus locked on origin (with free rotation)"};
110 SetInfo("Camera mode %d: %s", mCfgR.cameraMode, modeText[mCfgR.cameraMode]);
111 } else if (key == mFrontend->KEY_ALT) {
112 mFrontend->mKeys[mFrontend->KEY_CTRL] = false; // Release CTRL with alt, to avoid orienting along y automatically!
113 } else if (key == 'l') {
114 if (mCfgL.drawSector >= (mCfgL.drawRelatedSectors ? (NSECTORS / 4 - 1) : (NSECTORS - 1))) {
115 mCfgL.drawSector = -1;
116 SetInfo("Showing all sectors", 1);
117 } else {
118 mCfgL.drawSector++;
119 SetInfo("Showing sector %d", mCfgL.drawSector);
120 }
121 } else if (key == 'k') {
122 if (mCfgL.drawSector <= -1) {
123 mCfgL.drawSector = mCfgL.drawRelatedSectors ? (NSECTORS / 4 - 1) : (NSECTORS - 1);
124 } else {
125 mCfgL.drawSector--;
126 }
127 if (mCfgL.drawSector == -1) {
128 SetInfo("Showing all sectors", 1);
129 } else {
130 SetInfo("Showing sector %d", mCfgL.drawSector);
131 }
132 } else if (key == 'J') {
133 mCfgL.drawRelatedSectors ^= 1;
134 SetInfo("Drawing of related sectors %s", mCfgL.drawRelatedSectors ? "enabled" : "disabled");
135 } else if (key == 'L') {
136 if (mCfgL.showCollision >= mNCollissions - 1) {
137 mCfgL.showCollision = -1;
138 SetInfo("Showing all collisions", 1);
139 } else {
140 mCfgL.showCollision++;
141 SetInfo("Showing collision %d / %d", mCfgL.showCollision, mNCollissions);
142 }
143 } else if (key == 'K') {
144 if (mCfgL.showCollision <= -1) {
145 mCfgL.showCollision = mNCollissions - 1;
146 } else {
147 mCfgL.showCollision--;
148 }
149 if (mCfgL.showCollision == -1) {
150 SetInfo("Showing all collisions", 1);
151 } else {
152 SetInfo("Showing collision %d / %d", mCfgL.showCollision, mNCollissions);
153 }
154 } else if (key == 'F') {
155 mCfgR.fullScreen ^= 1;
156 SetInfo("Toggling full screen (%d)", (int32_t)mCfgR.fullScreen);
157 } else if (key == '_') {
158 mCfgR.maximized ^= 1;
159 SetInfo("Toggling Maximized window (%d)", (int32_t)mCfgR.maximized);
160 } else if (key == 'R') {
161 mCfgR.fpsLimit = (mCfgR.fpsLimit + 1) % 3;
162 if (mCfgR.fpsLimit == GPUDisplayBackend::FPS_LIMIT_RATE) {
163 SetInfo("FPS limit: %d FPS", mCfgR.fpsRate);
164 } else if (mCfgR.fpsLimit == GPUDisplayBackend::FPS_LIMIT_VSYNC) {
165 char rate[32] = "unknown rate";
166 if (mFrontend->getRefreshRate() > 0.f) {
167 snprintf(rate, sizeof(rate), "%.1f Hz", mFrontend->getRefreshRate());
168 }
169 const int32_t mode = mBackend->fpsLimitMode();
171 SetInfo("FPS limit: refresh rate (%s) - VSync disabled, no limit", rate);
173 SetInfo("FPS limit: refresh rate (%s) - not supported by the backend, fallback to %d FPS", rate, mCfgR.fpsRate);
174 } else {
175 SetInfo("FPS limit: refresh rate (%s)", rate);
176 }
177 } else {
178 SetInfo("FPS limit: none");
179 }
180 } else if (key == 'H') {
181 mPrintInfoText += 1;
182 mPrintInfoText &= 3;
183 SetInfo("Info text display - console: %s, onscreen %s", (mPrintInfoText & 2) ? "enabled" : "disabled", (mPrintInfoText & 1) ? "enabled" : "disabled");
184 } else if (key == 'j') {
185 if (mCfgH.separateExtrapolatedTracks) {
186 mCfgH.splitCETracks ^= 1;
187 }
188 mCfgH.separateExtrapolatedTracks ^= 1;
189 SetInfo("Seperated display of tracks propagated to adjacent sectors %s / of CE tracks %s", mCfgH.separateExtrapolatedTracks ? "enabled" : "disabled", mCfgH.splitCETracks ? "enabled" : "disabled");
190 } else if (key == 'c') {
191 if (mCfgH.markClusters == 0) {
192 mCfgH.markClusters = 1;
193 } else if (mCfgH.markClusters >= 0x20) {
194 mCfgH.markClusters = 0;
195 } else {
196 mCfgH.markClusters <<= 1;
197 }
198 SetInfo("Cluster flag highlight mask set to %d (%s)", mCfgH.markClusters,
199 mCfgH.markClusters == 0 ? "off" : mCfgH.markClusters == 1 ? "split pad" : mCfgH.markClusters == 2 ? "split time" : mCfgH.markClusters == 4 ? "edge" : mCfgH.markClusters == 8 ? "singlePad" : mCfgH.markClusters == 0x10 ? "reject distance" : "reject error");
200 } else if (key == 'z') {
201 mCfgH.markFakeClusters ^= 1;
202 SetInfo("Marking fake clusters: %s", mCfgH.markFakeClusters ? "on" : "off");
203 } else if (key == 'b') {
204 if ((mCfgR.fov += 5) > 175) {
205 mCfgR.fov = 5;
206 }
207 SetInfo("Set FOV to %f", mCfgR.fov);
208 } else if (key == 'm') {
209#ifdef GPUCA_DISPLAY_OPENGL_CORE
210 if (backend()->backendType() == GPUDisplayBackend::TYPE_OPENGL) {
211 SetInfo("OpenGL compat profile not available, using core profile", 1);
212 } else
213#endif
214 {
215 mCfgR.rendererCompatSmoothing ^= 1;
216 SetInfo("Using renderer path for %s profile", mCfgR.rendererCompatSmoothing ? "compat" : "core (shader)");
217 }
218 } else if (key == 'B') {
219 mCfgH.markAdjacentClusters++;
220 if (mCfgH.markAdjacentClusters == 5) {
221 mCfgH.markAdjacentClusters = 7;
222 }
223 if (mCfgH.markAdjacentClusters == 9) {
224 mCfgH.markAdjacentClusters = 15;
225 }
226 if (mCfgH.markAdjacentClusters == 17) {
227 mCfgH.markAdjacentClusters = 31;
228 }
229 if (mCfgH.markAdjacentClusters == 34) {
230 mCfgH.markAdjacentClusters = 0;
231 }
232 if (mCfgH.markAdjacentClusters == 33) {
233 SetInfo("Marking protected clusters (%d)", mCfgH.markAdjacentClusters);
234 } else if (mCfgH.markAdjacentClusters == 32) {
235 SetInfo("Marking removable clusters (%d)", mCfgH.markAdjacentClusters);
236 } else {
237 SetInfo("Marking adjacent clusters (%d): rejected %s, tube %s, looper leg %s, low Pt %s, high incl %s", mCfgH.markAdjacentClusters, (mCfgH.markAdjacentClusters & 1) ? "yes" : " no", (mCfgH.markAdjacentClusters & 2) ? "yes" : " no", (mCfgH.markAdjacentClusters & 4) ? "yes" : " no", (mCfgH.markAdjacentClusters & 8) ? "yes" : " no", (mCfgH.markAdjacentClusters & 16) ? "yes" : " no");
238 }
239 } else if (key == 'C') {
240 mCfgL.colorCollisions ^= 1;
241 SetInfo("Color coding of collisions %s", mCfgL.colorCollisions ? "enabled" : "disabled");
242 } else if (key == 'N') {
243 mCfgL.colorClusters ^= 1;
244 SetInfo("Color coding for seed / trrack attachmend %s", mCfgL.colorClusters ? "enabled" : "disabled");
245 } else if (key == 'E') {
246 mCfgL.propagateTracks += 1;
247 if (mCfgL.propagateTracks == 4) {
248 mCfgL.propagateTracks = 0;
249 }
250 const char* infoText[] = {"Hits connected", "Hits connected and propagated to vertex", "Reconstructed track propagated inwards and outwards", "Monte Carlo track"};
251 SetInfo("Display of propagated tracks: %s", infoText[mCfgL.propagateTracks]);
252 } else if (key == 'G') {
253 mCfgH.propagateLoopers ^= 1;
254 SetInfo("Propagation of loopers %s", mCfgH.propagateLoopers ? "enabled" : "disabled");
255 } else if (key == 'v') {
256 mCfgH.hideRejectedClusters ^= 1;
257 SetInfo("Rejected clusters are %s", mCfgH.hideRejectedClusters ? "hidden" : "shown");
258 } else if (key == 'i') {
259 mCfgH.projectXY ^= 1;
260 SetInfo("Projection onto xy plane %s", mCfgH.projectXY ? "enabled" : "disabled");
261 } else if (key == 'S') {
262 mCfgL.smoothPoints ^= true;
263 SetInfo("Smoothing of points %s", mCfgL.smoothPoints ? "enabled" : "disabled");
264 } else if (key == 'A') {
265 mCfgL.smoothLines ^= true;
266 SetInfo("Smoothing of lines %s", mCfgL.smoothLines ? "enabled" : "disabled");
267 } else if (key == 'D') {
268 mCfgL.depthBuffer ^= true;
269 SetInfo("Depth buffer (z-buffer, %u bits) %s", mBackend->DepthBits(), mCfgL.depthBuffer ? "enabled" : "disabled");
270 mBackend->setDepthBuffer();
271 } else if (key == 'W') {
272 mCfgR.drawQualityMSAA *= 2;
273 if (mCfgR.drawQualityMSAA < 2) {
274 mCfgR.drawQualityMSAA = 2;
275 }
276 if (mCfgR.drawQualityMSAA > 16 || mCfgR.drawQualityMSAA > mBackend->getMaxMSAA()) {
277 mCfgR.drawQualityMSAA = 0;
278 }
279 SetInfo("Multisampling anti-aliasing factor set to %d", mCfgR.drawQualityMSAA);
280 } else if (key == 'U') {
281 mCfgR.drawQualityDownsampleFSAA++;
282 if (mCfgR.drawQualityDownsampleFSAA == 1) {
283 mCfgR.drawQualityDownsampleFSAA = 2;
284 }
285 if (mCfgR.drawQualityDownsampleFSAA == 5) {
286 mCfgR.drawQualityDownsampleFSAA = 0;
287 }
288 SetInfo("Downsampling anti-aliasing factor set to %d", mCfgR.drawQualityDownsampleFSAA);
289 } else if (key == 'V') {
290 mCfgR.drawQualityVSync ^= true;
291 SetInfo("VSync: %s", mCfgR.drawQualityVSync ? "enabled" : "disabled");
292 } else if (key == 'I') {
293 mCfgR.useGLIndirectDraw ^= true;
294 SetInfo("OpenGL Indirect Draw %s", mCfgR.useGLIndirectDraw ? "enabled" : "disabled");
295 } else if (key == ';') {
296 mCfgH.xAdd += 60;
297 mCfgH.zAdd += 60;
298 SetInfo("TPC sector separation: %f %f", mCfgH.xAdd, mCfgH.zAdd);
299 } else if (key == ':') {
300 mCfgH.xAdd -= 60;
301 mCfgH.zAdd -= 60;
302 if (mCfgH.zAdd < 0 || mCfgH.xAdd < 0) {
303 mCfgH.zAdd = mCfgH.xAdd = 0;
304 }
305 SetInfo("TPC sector separation: %f %f", mCfgH.xAdd, mCfgH.zAdd);
306 } else if (key == '#') {
307 mCfgL.invertColors ^= 1;
308 } else if (key == 'g') {
309 mCfgL.drawGrid ^= 1;
310 SetInfo("Fast Cluster Search Grid %s", mCfgL.drawGrid ? "shown" : "hidden");
311 } else if (key == 'x') {
312 mCfgL.excludeClusters = (mCfgL.excludeClusters + 1) % 3;
313 SetInfo(mCfgL.excludeClusters ? "Clusters of selected category are excluded from display (%d)" : "Clusters are shown", mCfgL.excludeClusters);
314 } else if (key == '.') {
315 mCfgH.hideRejectedTracks ^= 1;
316 SetInfo("Rejected tracks are %s", mCfgH.hideRejectedTracks ? "hidden" : "shown");
317 } else if (key == '1') {
318 mCfgL.drawClusters ^= 1;
319 } else if (key == '2') {
320 mCfgL.drawInitLinks ^= 1;
321 } else if (key == '3') {
322 mCfgL.drawLinks ^= 1;
323 } else if (key == '4') {
324 mCfgL.drawSeeds ^= 1;
325 } else if (key == '5') {
326 mCfgL.drawTracklets ^= 1;
327 } else if (key == '6') {
328 mCfgL.drawTracks ^= 1;
329 } else if (key == '7') {
330 mCfgL.drawExtrapolatedTracks ^= 1;
331 } else if (key == '8') {
332 mCfgL.drawFinal ^= 1;
333 } else if (key == mFrontend->KEY_F1) {
334 if (mFrontend->mKeysShift[mFrontend->KEY_F1]) {
335 mCfgH.drawTPCTracks ^= 1;
336 SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int32_t)mCfgH.drawTPCTracks, (int32_t)mCfgH.drawTRDTracks, (int32_t)mCfgH.drawTOFTracks, (int32_t)mCfgH.drawITSTracks);
337 } else {
338 mCfgL.drawTPC ^= 1;
339 SetInfo("Showing TPC Clusters: %d", (int32_t)mCfgL.drawTPC);
340 }
341 } else if (key == mFrontend->KEY_F2) {
342 if (mFrontend->mKeysShift[mFrontend->KEY_F2]) {
343 mCfgH.drawTRDTracks ^= 1;
344 SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int32_t)mCfgH.drawTPCTracks, (int32_t)mCfgH.drawTRDTracks, (int32_t)mCfgH.drawTOFTracks, (int32_t)mCfgH.drawITSTracks);
345 } else {
346 mCfgL.drawTRD ^= 1;
347 SetInfo("Showing TRD Tracklets: %d", (int32_t)mCfgL.drawTRD);
348 }
349 } else if (key == mFrontend->KEY_F3) {
350 if (mFrontend->mKeysShift[mFrontend->KEY_F3]) {
351 mCfgH.drawTOFTracks ^= 1;
352 SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int32_t)mCfgH.drawTPCTracks, (int32_t)mCfgH.drawTRDTracks, (int32_t)mCfgH.drawTOFTracks, (int32_t)mCfgH.drawITSTracks);
353 } else {
354 mCfgL.drawTOF ^= 1;
355 SetInfo("Showing TOF Hits: %d", (int32_t)mCfgL.drawTOF);
356 }
357 } else if (key == mFrontend->KEY_F4) {
358 if (mFrontend->mKeysShift[mFrontend->KEY_F4]) {
359 mCfgH.drawITSTracks ^= 1;
360 SetInfo("Track Filter Mask: TPC:%d TRD:%d TOF:%d ITS:%d", (int32_t)mCfgH.drawTPCTracks, (int32_t)mCfgH.drawTRDTracks, (int32_t)mCfgH.drawTOFTracks, (int32_t)mCfgH.drawITSTracks);
361 } else {
362 mCfgL.drawITS ^= 1;
363 SetInfo("Showing ITS Clusters: %d", (int32_t)mCfgL.drawITS);
364 }
365 } else if (key == mFrontend->KEY_F12 && mFrontend->mKeysShift[mFrontend->KEY_F12]) {
366 mCfgH.drawTracksAndFilter ^= 1;
367 SetInfo("Track filter: %s", mCfgH.drawTracksAndFilter ? "AND" : "OR");
368 } else if (key == 't') {
369 static int32_t nScreenshot = 1;
370 char fname[32];
371 snprintf(fname, 32, "screenshot%d.bmp", nScreenshot++);
372 mRequestScreenshot = true;
373 mScreenshotFile = fname;
374 SetInfo("Taking screenshot (%s)", fname);
375 } else if (key == 'Z') {
376 mCfgR.screenshotScaleFactor += 1;
377 if (mCfgR.screenshotScaleFactor == 5) {
378 mCfgR.screenshotScaleFactor = 1;
379 }
380 SetInfo("Screenshot scaling factor set to %d", mCfgR.screenshotScaleFactor);
381 } else if (key == 'y' || key == 'T') {
382 if (mAnimateVectors[0].size() > 1) {
383 if ((mAnimateScreenshot = (key == 'T'))) {
384 mAnimationExport++;
385 }
386 startAnimation();
387 SetInfo("Starting Animation", 1);
388 } else {
389 SetInfo("Insufficient Animation points to start Animation", 1);
390 }
391 } else if (key == '>') {
392 mAnimationChangeConfig ^= 1;
393 SetInfo("Interpolating visualization settings during Animation %s", mAnimationChangeConfig ? "enabled" : "disabled");
394 } else if (key == 'Y') {
395 setAnimationPoint();
396 SetInfo("Added Animation point (%d points, %6.2f seconds)", (int32_t)mAnimateVectors[0].size(), mAnimateVectors[0].back());
397 } else if (key == 'X') {
398 resetAnimation();
399 SetInfo("Reset Animation points", 1);
400 } else if (key == '\'') {
401 removeAnimationPoint();
402 SetInfo("Removed Animation point", 1);
403 } else if (key == 'M') {
404 mCfgL.animationMode++;
405 if (mCfgL.animationMode == 7) {
406 mCfgL.animationMode = 0;
407 }
408 resetAnimation();
409 if (mCfgL.animationMode == 6) {
410 SetInfo("Animation mode %d - Centered on origin", mCfgL.animationMode);
411 } else {
412 SetInfo("Animation mode %d - Position: %s, Direction: %s", mCfgL.animationMode, (mCfgL.animationMode & 2) ? "Spherical (spherical rotation)" : (mCfgL.animationMode & 4) ? "Spherical (Euler angles)" : "Cartesian", (mCfgL.animationMode & 1) ? "Euler angles" : "Quaternion");
413 }
414 } else if (key == 'u') {
415 mCfgH.trackFilter = (mCfgH.trackFilter + 1) % (mConfig.filterMacros.size() + 1);
416 mUpdateTrackFilter = true;
417 SetInfo("Track filter: %s", mCfgH.trackFilter == 0 ? "None" : mConfig.filterMacros[mCfgH.trackFilter - 1].c_str());
418 } else if (key == 'o') {
419 FILE* ftmp = fopen("glpos.tmp", "w+b");
420 if (ftmp) {
421 int32_t retval = fwrite(&mViewMatrix, sizeof(mViewMatrix), 1, ftmp);
422 if (retval != 1) {
423 GPUError("Error writing position to file");
424 } else {
425 GPUInfo("Position stored to file");
426 }
427 fclose(ftmp);
428 } else {
429 GPUError("Error opening file");
430 }
431 SetInfo("Camera position stored to file", 1);
432 } else if (key == 'p') {
433 FILE* ftmp = fopen("glpos.tmp", "rb");
434 if (ftmp) {
435 int32_t retval = fread(&mViewMatrix, 1, sizeof(mViewMatrix), ftmp);
436 if (retval == sizeof(mViewMatrix)) {
437 GPUInfo("Position read from file");
438 } else {
439 GPUError("Error reading position from file");
440 }
441 fclose(ftmp);
442 } else {
443 GPUError("Error opening file");
444 }
445 SetInfo("Camera position loaded from file", 1);
446 } else if (key == 'O') {
447 FILE* ftmp = fopen("glanimation.tmp", "w+b");
448 if (ftmp) {
449 fwrite(&mCfgL, sizeof(mCfgL), 1, ftmp);
450 int32_t size = mAnimateVectors[0].size();
451 fwrite(&size, sizeof(size), 1, ftmp);
452 for (int32_t i = 0; i < 9; i++) {
453 fwrite(mAnimateVectors[i].data(), sizeof(mAnimateVectors[i][0]), size, ftmp);
454 }
455 fwrite(mAnimateConfig.data(), sizeof(mAnimateConfig[0]), size, ftmp);
456 fclose(ftmp);
457 } else {
458 GPUError("Error opening file");
459 }
460 SetInfo("Animation path stored to file %s", "glanimation.tmp");
461 } else if (key == 'P') {
462 FILE* ftmp = fopen("glanimation.tmp", "rb");
463 if (ftmp) {
464 int32_t retval = fread(&mCfgL, sizeof(mCfgL), 1, ftmp);
465 int32_t size;
466 retval += fread(&size, sizeof(size), 1, ftmp);
467 for (int32_t i = 0; i < 9; i++) {
468 mAnimateVectors[i].resize(size);
469 retval += fread(mAnimateVectors[i].data(), sizeof(mAnimateVectors[i][0]), size, ftmp);
470 }
471 mAnimateConfig.resize(size);
472 retval += fread(mAnimateConfig.data(), sizeof(mAnimateConfig[0]), size, ftmp);
473 (void)retval; // disable unused warning
474 fclose(ftmp);
475 updateConfig();
476 } else {
477 GPUError("Error opening file");
478 }
479 SetInfo("Animation path loaded from file %s", "glanimation.tmp");
480 } else if (key == 'h') {
481 if (mPrintInfoTextAlways) {
482 mPrintInfoTextAlways = false;
483 SetInfo("Showing help text disabled", 1);
484 } else if (mInfoHelpTimer.IsRunning()) {
485 mPrintInfoTextAlways = true;
486 mInfoHelpTimer.Reset();
487 SetInfo("Showing help text until disabled", 1);
488 } else {
489 PrintHelp();
490 SetInfo("Showing help text", 1);
491 }
492 } else if (key == 'q') {
493 if (mFrontend->isGUIRunning()) {
494 SetInfo("Stopping GUI", 1);
495 mFrontend->stopGUI();
496 } else {
497 SetInfo("Starting GUI", 1);
498 mFrontend->startGUI();
499 }
500 }
501 /*
502 else if (key == '^')
503 {
504 mTestSetting++;
505 SetInfo("Debug test variable set to %d", mTestSetting);
506 }
507 */
508
509 if (!doNotHandleConfigChanges) {
510 checkAndApplyConfigChanges(oldCfgH, oldCfgL, oldCfgR);
511 }
512}
513
514void GPUDisplay::checkAndApplyConfigChanges(const GPUSettingsDisplayHeavy& oldCfgH, const GPUSettingsDisplayLight& oldCfgL, const GPUSettingsDisplayRenderer& oldCfgR)
515{
516 if (memcmp((void*)&oldCfgH, (void*)&mCfgH, sizeof(mCfgH)) != 0) {
517 mUpdateEventData = true;
518 }
519 if (mCfgL.propagateTracks != 0 && !mTracksArePropagated) {
520 mUpdateVertexLists = true;
521 }
522 if (memcmp((void*)&oldCfgL, (void*)&mCfgL, sizeof(mCfgL)) != 0 || memcmp((void*)&oldCfgR, (void*)&mCfgR, sizeof(mCfgR)) != 0) {
523 mUpdateDrawCommands = true;
524 }
525 if (oldCfgR.drawQualityMSAA != mCfgR.drawQualityMSAA || oldCfgR.drawQualityDownsampleFSAA != mCfgR.drawQualityDownsampleFSAA || oldCfgL.depthBuffer != mCfgL.depthBuffer || oldCfgR.screenshotScaleFactor != mCfgR.screenshotScaleFactor) {
526 mUpdateRenderPipeline = true;
527 }
528
529 if (oldCfgR.drawQualityVSync != mCfgR.drawQualityVSync) {
530 mFrontend->SetVSync(mCfgR.drawQualityVSync);
531 mBackend->SetVSync(mCfgR.drawQualityVSync);
532 }
533 if (oldCfgR.fullScreen != mCfgR.fullScreen) {
534 mFrontend->SwitchFullscreen(mCfgR.fullScreen);
535 }
536 if (oldCfgR.maximized != mCfgR.maximized) {
537 mFrontend->ToggleMaximized(mCfgR.maximized);
538 }
539 if (oldCfgR.useGLIndirectDraw != mCfgR.useGLIndirectDraw) {
540 mUpdateEventData = true;
541 }
542}
543
545{
546 // GPUError("key %d '%c'", key, (char) key);
547
548 bool shifted = key >= 'A' && key <= 'Z';
549 int32_t press = key;
550 if (press >= 'a' && press <= 'z') {
551 press += 'A' - 'a';
552 }
553 bool oldShift = mFrontend->mKeysShift[press];
554 mFrontend->mKeysShift[press] = shifted;
555 HandleKey(key, true);
556 mFrontend->mKeysShift[press] = oldShift;
557}
558
559void GPUDisplay::PrintGLHelpText(float colorValue)
560{
561 for (uint32_t i = 0; i < sizeof(HelpText) / sizeof(HelpText[0]); i++) {
562 OpenGLPrint(HelpText[i], 40.f, 35 + std::max(20, mDrawTextFontSize + 4) * (1 + i), colorValue, colorValue, colorValue, mInfoHelpTimer.GetCurrentElapsedTime() >= 5 ? (6 - mInfoHelpTimer.GetCurrentElapsedTime()) : 1, false);
563 }
564}
int32_t i
const char * HelpText[]
StringRef key
void Reset()
Definition timer.cxx:108
double GetCurrentElapsedTime(bool reset=false)
Definition timer.cxx:117
int32_t IsRunning()
Definition timer.h:34
void ResetStart()
Definition timer.cxx:70
static constexpr int32_t KEY_F2
static constexpr int32_t KEY_ALT
static constexpr int32_t KEY_F12
static constexpr int32_t KEY_F4
virtual void ToggleMaximized(bool set)=0
static constexpr int32_t KEY_ENTER
static constexpr int32_t KEY_CTRL
static constexpr int32_t KEY_F1
static constexpr int32_t KEY_F3
virtual void SetVSync(bool enable)=0
virtual void SwitchFullscreen(bool set)=0
static constexpr int32_t KEY_ESCAPE
void checkAndApplyConfigChanges(const GPUSettingsDisplayHeavy &oldCfgH, const GPUSettingsDisplayLight &oldCfgL, const GPUSettingsDisplayRenderer &oldCfgR)
void HandleExternalGUIKey(int32_t key)
void HandleKey(uint8_t key, bool doNotHandleConfigChanges=false)
GPUDisplayBackend * backend() const
Definition GPUDisplay.h:75
GLenum mode
Definition glcorearb.h:266
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLenum * rate
Definition glcorearb.h:5735
GLboolean * data
Definition glcorearb.h:298
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)