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 rate limiter",
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 "['] Switch between OpenGL core / compat code path",
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: [m] [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
81{
82 GPUSettingsDisplayHeavy oldCfgH = mCfgH;
83 GPUSettingsDisplayLight oldCfgL = mCfgL;
84 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 = 1;
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.maxFPSRate ^= 1;
162 SetInfo("FPS rate %s", mCfgR.maxFPSRate ? "not limited" : "limited");
163 } else if (key == 'H') {
164 mPrintInfoText += 1;
165 mPrintInfoText &= 3;
166 SetInfo("Info text display - console: %s, onscreen %s", (mPrintInfoText & 2) ? "enabled" : "disabled", (mPrintInfoText & 1) ? "enabled" : "disabled");
167 } else if (key == 'j') {
168 if (mCfgH.separateExtrapolatedTracks) {
169 mCfgH.splitCETracks ^= 1;
170 }
171 mCfgH.separateExtrapolatedTracks ^= 1;
172 SetInfo("Seperated display of tracks propagated to adjacent sectors %s / of CE tracks %s", mCfgH.separateExtrapolatedTracks ? "enabled" : "disabled", mCfgH.splitCETracks ? "enabled" : "disabled");
173 } else if (key == 'c') {
174 if (mCfgH.markClusters == 0) {
175 mCfgH.markClusters = 1;
176 } else if (mCfgH.markClusters >= 0x20) {
177 mCfgH.markClusters = 0;
178 } else {
179 mCfgH.markClusters <<= 1;
180 }
181 SetInfo("Cluster flag highlight mask set to %d (%s)", mCfgH.markClusters,
182 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");
183 } else if (key == 'z') {
184 mCfgH.markFakeClusters ^= 1;
185 SetInfo("Marking fake clusters: %s", mCfgH.markFakeClusters ? "on" : "off");
186 } else if (key == 'b') {
187 if ((mCfgR.fov += 5) > 175) {
188 mCfgR.fov = 5;
189 }
190 SetInfo("Set FOV to %f", mCfgR.fov);
191 } else if (key == 39) { // character = "'"
192 if (backend()->backendType() == GPUDisplayBackend::TYPE_OPENGL) {
193#ifdef GPUCA_DISPLAY_OPENGL_CORE
194 SetInfo("OpenGL compat profile not available, using core profile", 1);
195#else
196 mCfgR.openGLCore ^= 1;
197 SetInfo("Using renderer path for OpenGL %s profile", mCfgR.openGLCore ? "core" : "compat");
198#endif
199 } else {
200 SetInfo("OpenGL options only available with OpenGL backend");
201 }
202 } else if (key == 'B') {
203 mCfgH.markAdjacentClusters++;
204 if (mCfgH.markAdjacentClusters == 5) {
205 mCfgH.markAdjacentClusters = 7;
206 }
207 if (mCfgH.markAdjacentClusters == 9) {
208 mCfgH.markAdjacentClusters = 15;
209 }
210 if (mCfgH.markAdjacentClusters == 17) {
211 mCfgH.markAdjacentClusters = 31;
212 }
213 if (mCfgH.markAdjacentClusters == 34) {
214 mCfgH.markAdjacentClusters = 0;
215 }
216 if (mCfgH.markAdjacentClusters == 33) {
217 SetInfo("Marking protected clusters (%d)", mCfgH.markAdjacentClusters);
218 } else if (mCfgH.markAdjacentClusters == 32) {
219 SetInfo("Marking removable clusters (%d)", mCfgH.markAdjacentClusters);
220 } else {
221 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");
222 }
223 } else if (key == 'C') {
224 mCfgL.colorCollisions ^= 1;
225 SetInfo("Color coding of collisions %s", mCfgL.colorCollisions ? "enabled" : "disabled");
226 } else if (key == 'N') {
227 mCfgL.colorClusters ^= 1;
228 SetInfo("Color coding for seed / trrack attachmend %s", mCfgL.colorClusters ? "enabled" : "disabled");
229 } else if (key == 'E') {
230 mCfgL.propagateTracks += 1;
231 if (mCfgL.propagateTracks == 4) {
232 mCfgL.propagateTracks = 0;
233 }
234 const char* infoText[] = {"Hits connected", "Hits connected and propagated to vertex", "Reconstructed track propagated inwards and outwards", "Monte Carlo track"};
235 SetInfo("Display of propagated tracks: %s", infoText[mCfgL.propagateTracks]);
236 } else if (key == 'G') {
237 mCfgH.propagateLoopers ^= 1;
238 SetInfo("Propagation of loopers %s", mCfgH.propagateLoopers ? "enabled" : "disabled");
239 } else if (key == 'v') {
240 mCfgH.hideRejectedClusters ^= 1;
241 SetInfo("Rejected clusters are %s", mCfgH.hideRejectedClusters ? "hidden" : "shown");
242 } else if (key == 'i') {
243 mCfgH.projectXY ^= 1;
244 SetInfo("Projection onto xy plane %s", mCfgH.projectXY ? "enabled" : "disabled");
245 } else if (key == 'S') {
246 mCfgL.smoothPoints ^= true;
247 SetInfo("Smoothing of points %s", mCfgL.smoothPoints ? "enabled" : "disabled");
248 } else if (key == 'A') {
249 mCfgL.smoothLines ^= true;
250 SetInfo("Smoothing of lines %s", mCfgL.smoothLines ? "enabled" : "disabled");
251 } else if (key == 'D') {
252 mCfgL.depthBuffer ^= true;
253 SetInfo("Depth buffer (z-buffer, %u bits) %s", mBackend->DepthBits(), mCfgL.depthBuffer ? "enabled" : "disabled");
254 mBackend->setDepthBuffer();
255 } else if (key == 'W') {
256 mCfgR.drawQualityMSAA *= 2;
257 if (mCfgR.drawQualityMSAA < 2) {
258 mCfgR.drawQualityMSAA = 2;
259 }
260 if (mCfgR.drawQualityMSAA > 16 || mCfgR.drawQualityMSAA > mBackend->getMaxMSAA()) {
261 mCfgR.drawQualityMSAA = 0;
262 }
263 SetInfo("Multisampling anti-aliasing factor set to %d", mCfgR.drawQualityMSAA);
264 } else if (key == 'U') {
265 mCfgR.drawQualityDownsampleFSAA++;
266 if (mCfgR.drawQualityDownsampleFSAA == 1) {
267 mCfgR.drawQualityDownsampleFSAA = 2;
268 }
269 if (mCfgR.drawQualityDownsampleFSAA == 5) {
270 mCfgR.drawQualityDownsampleFSAA = 0;
271 }
272 SetInfo("Downsampling anti-aliasing factor set to %d", mCfgR.drawQualityDownsampleFSAA);
273 } else if (key == 'V') {
274 mCfgR.drawQualityVSync ^= true;
275 SetInfo("VSync: %s", mCfgR.drawQualityVSync ? "enabled" : "disabled");
276 } else if (key == 'I') {
277 mCfgR.useGLIndirectDraw ^= true;
278 SetInfo("OpenGL Indirect Draw %s", mCfgR.useGLIndirectDraw ? "enabled" : "disabled");
279 } else if (key == ';') {
280 mCfgH.xAdd += 60;
281 mCfgH.zAdd += 60;
282 SetInfo("TPC sector separation: %f %f", mCfgH.xAdd, mCfgH.zAdd);
283 } else if (key == ':') {
284 mCfgH.xAdd -= 60;
285 mCfgH.zAdd -= 60;
286 if (mCfgH.zAdd < 0 || mCfgH.xAdd < 0) {
287 mCfgH.zAdd = mCfgH.xAdd = 0;
288 }
289 SetInfo("TPC sector separation: %f %f", mCfgH.xAdd, mCfgH.zAdd);
290 } else if (key == '#') {
291 mCfgL.invertColors ^= 1;
292 } else if (key == 'g') {
293 mCfgL.drawGrid ^= 1;
294 SetInfo("Fast Cluster Search Grid %s", mCfgL.drawGrid ? "shown" : "hidden");
295 } else if (key == 'x') {
296 mCfgL.excludeClusters = (mCfgL.excludeClusters + 1) % 3;
297 SetInfo(mCfgL.excludeClusters ? "Clusters of selected category are excluded from display (%d)" : "Clusters are shown", mCfgL.excludeClusters);
298 } else if (key == '.') {
299 mCfgH.hideRejectedTracks ^= 1;
300 SetInfo("Rejected tracks are %s", mCfgH.hideRejectedTracks ? "hidden" : "shown");
301 } else if (key == '1') {
302 mCfgL.drawClusters ^= 1;
303 } else if (key == '2') {
304 mCfgL.drawInitLinks ^= 1;
305 } else if (key == '3') {
306 mCfgL.drawLinks ^= 1;
307 } else if (key == '4') {
308 mCfgL.drawSeeds ^= 1;
309 } else if (key == '5') {
310 mCfgL.drawTracklets ^= 1;
311 } else if (key == '6') {
312 mCfgL.drawTracks ^= 1;
313 } else if (key == '7') {
314 mCfgL.drawExtrapolatedTracks ^= 1;
315 } else if (key == '8') {
316 mCfgL.drawFinal ^= 1;
317 } else if (key == mFrontend->KEY_F1) {
318 if (mFrontend->mKeysShift[mFrontend->KEY_F1]) {
319 mCfgH.drawTPCTracks ^= 1;
320 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);
321 } else {
322 mCfgL.drawTPC ^= 1;
323 SetInfo("Showing TPC Clusters: %d", (int32_t)mCfgL.drawTPC);
324 }
325 } else if (key == mFrontend->KEY_F2) {
326 if (mFrontend->mKeysShift[mFrontend->KEY_F2]) {
327 mCfgH.drawTRDTracks ^= 1;
328 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);
329 } else {
330 mCfgL.drawTRD ^= 1;
331 SetInfo("Showing TRD Tracklets: %d", (int32_t)mCfgL.drawTRD);
332 }
333 } else if (key == mFrontend->KEY_F3) {
334 if (mFrontend->mKeysShift[mFrontend->KEY_F3]) {
335 mCfgH.drawTOFTracks ^= 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.drawTOF ^= 1;
339 SetInfo("Showing TOF Hits: %d", (int32_t)mCfgL.drawTOF);
340 }
341 } else if (key == mFrontend->KEY_F4) {
342 if (mFrontend->mKeysShift[mFrontend->KEY_F4]) {
343 mCfgH.drawITSTracks ^= 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.drawITS ^= 1;
347 SetInfo("Showing ITS Clusters: %d", (int32_t)mCfgL.drawITS);
348 }
349 } else if (key == mFrontend->KEY_F12 && mFrontend->mKeysShift[mFrontend->KEY_F12]) {
350 mCfgH.drawTracksAndFilter ^= 1;
351 SetInfo("Track filter: %s", mCfgH.drawTracksAndFilter ? "AND" : "OR");
352 } else if (key == 't') {
353 static int32_t nScreenshot = 1;
354 char fname[32];
355 snprintf(fname, 32, "screenshot%d.bmp", nScreenshot++);
356 mRequestScreenshot = true;
357 mScreenshotFile = fname;
358 SetInfo("Taking screenshot (%s)", fname);
359 } else if (key == 'Z') {
360 mCfgR.screenshotScaleFactor += 1;
361 if (mCfgR.screenshotScaleFactor == 5) {
362 mCfgR.screenshotScaleFactor = 1;
363 }
364 SetInfo("Screenshot scaling factor set to %d", mCfgR.screenshotScaleFactor);
365 } else if (key == 'y' || key == 'T') {
366 if (mAnimateVectors[0].size() > 1) {
367 if ((mAnimateScreenshot = (key == 'T'))) {
368 mAnimationExport++;
369 }
370 startAnimation();
371 SetInfo("Starting Animation", 1);
372 } else {
373 SetInfo("Insufficient Animation points to start Animation", 1);
374 }
375 } else if (key == '>') {
376 mAnimationChangeConfig ^= 1;
377 SetInfo("Interpolating visualization settings during Animation %s", mAnimationChangeConfig ? "enabled" : "disabled");
378 } else if (key == 'Y') {
379 setAnimationPoint();
380 SetInfo("Added Animation point (%d points, %6.2f seconds)", (int32_t)mAnimateVectors[0].size(), mAnimateVectors[0].back());
381 } else if (key == 'X') {
382 resetAnimation();
383 SetInfo("Reset Animation points", 1);
384 } else if (key == '\'') {
385 removeAnimationPoint();
386 SetInfo("Removed Animation point", 1);
387 } else if (key == 'M') {
388 mCfgL.animationMode++;
389 if (mCfgL.animationMode == 7) {
390 mCfgL.animationMode = 0;
391 }
392 resetAnimation();
393 if (mCfgL.animationMode == 6) {
394 SetInfo("Animation mode %d - Centered on origin", mCfgL.animationMode);
395 } else {
396 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");
397 }
398 } else if (key == 'u') {
399 mCfgH.trackFilter = (mCfgH.trackFilter + 1) % (mConfig.filterMacros.size() + 1);
400 mUpdateTrackFilter = true;
401 SetInfo("Track filter: %s", mCfgH.trackFilter == 0 ? "None" : mConfig.filterMacros[mCfgH.trackFilter - 1].c_str());
402 } else if (key == 'o') {
403 FILE* ftmp = fopen("glpos.tmp", "w+b");
404 if (ftmp) {
405 int32_t retval = fwrite(&mViewMatrix, sizeof(mViewMatrix), 1, ftmp);
406 if (retval != 1) {
407 GPUError("Error writing position to file");
408 } else {
409 GPUInfo("Position stored to file");
410 }
411 fclose(ftmp);
412 } else {
413 GPUError("Error opening file");
414 }
415 SetInfo("Camera position stored to file", 1);
416 } else if (key == 'p') {
417 FILE* ftmp = fopen("glpos.tmp", "rb");
418 if (ftmp) {
419 int32_t retval = fread(&mViewMatrix, 1, sizeof(mViewMatrix), ftmp);
420 if (retval == sizeof(mViewMatrix)) {
421 GPUInfo("Position read from file");
422 } else {
423 GPUError("Error reading position from file");
424 }
425 fclose(ftmp);
426 } else {
427 GPUError("Error opening file");
428 }
429 SetInfo("Camera position loaded from file", 1);
430 } else if (key == 'O') {
431 FILE* ftmp = fopen("glanimation.tmp", "w+b");
432 if (ftmp) {
433 fwrite(&mCfgL, sizeof(mCfgL), 1, ftmp);
434 int32_t size = mAnimateVectors[0].size();
435 fwrite(&size, sizeof(size), 1, ftmp);
436 for (int32_t i = 0; i < 9; i++) {
437 fwrite(mAnimateVectors[i].data(), sizeof(mAnimateVectors[i][0]), size, ftmp);
438 }
439 fwrite(mAnimateConfig.data(), sizeof(mAnimateConfig[0]), size, ftmp);
440 fclose(ftmp);
441 } else {
442 GPUError("Error opening file");
443 }
444 SetInfo("Animation path stored to file %s", "glanimation.tmp");
445 } else if (key == 'P') {
446 FILE* ftmp = fopen("glanimation.tmp", "rb");
447 if (ftmp) {
448 int32_t retval = fread(&mCfgL, sizeof(mCfgL), 1, ftmp);
449 int32_t size;
450 retval += fread(&size, sizeof(size), 1, ftmp);
451 for (int32_t i = 0; i < 9; i++) {
452 mAnimateVectors[i].resize(size);
453 retval += fread(mAnimateVectors[i].data(), sizeof(mAnimateVectors[i][0]), size, ftmp);
454 }
455 mAnimateConfig.resize(size);
456 retval += fread(mAnimateConfig.data(), sizeof(mAnimateConfig[0]), size, ftmp);
457 (void)retval; // disable unused warning
458 fclose(ftmp);
459 updateConfig();
460 } else {
461 GPUError("Error opening file");
462 }
463 SetInfo("Animation path loaded from file %s", "glanimation.tmp");
464 } else if (key == 'h') {
465 if (mPrintInfoTextAlways) {
466 mPrintInfoTextAlways = false;
467 SetInfo("Showing help text disabled", 1);
468 } else if (mInfoHelpTimer.IsRunning()) {
469 mPrintInfoTextAlways = true;
470 mInfoHelpTimer.Reset();
471 SetInfo("Showing help text until disabled", 1);
472 } else {
473 PrintHelp();
474 SetInfo("Showing help text", 1);
475 }
476 } else if (key == 'q') {
477 if (mFrontend->isGUIRunning()) {
478 SetInfo("Stopping GUI", 1);
479 mFrontend->stopGUI();
480 } else {
481 SetInfo("Starting GUI", 1);
482 mFrontend->startGUI();
483 }
484 }
485 /*
486 else if (key == '^')
487 {
488 mTestSetting++;
489 SetInfo("Debug test variable set to %d", mTestSetting);
490 }
491 */
492
493 if (memcmp((void*)&oldCfgH, (void*)&mCfgH, sizeof(mCfgH)) != 0) {
494 mUpdateEventData = true;
495 }
496 if (memcmp((void*)&oldCfgL, (void*)&mCfgL, sizeof(mCfgL)) != 0 || memcmp((void*)&oldCfgR, (void*)&mCfgR, sizeof(mCfgR)) != 0) {
497 mUpdateDrawCommands = true;
498 }
499 if (oldCfgR.drawQualityMSAA != mCfgR.drawQualityMSAA || oldCfgR.drawQualityDownsampleFSAA != mCfgR.drawQualityDownsampleFSAA || oldCfgL.depthBuffer != mCfgL.depthBuffer || oldCfgR.screenshotScaleFactor != mCfgR.screenshotScaleFactor) {
500 mUpdateRenderPipeline = true;
501 }
502
503 if (oldCfgR.drawQualityVSync != mCfgR.drawQualityVSync) {
504 mFrontend->SetVSync(mCfgR.drawQualityVSync);
505 mBackend->SetVSync(mCfgR.drawQualityVSync);
506 }
507 if (oldCfgR.fullScreen != mCfgR.fullScreen) {
508 mFrontend->SwitchFullscreen(mCfgR.fullScreen);
509 }
510 if (oldCfgR.maximized != mCfgR.maximized) {
511 mFrontend->ToggleMaximized(mCfgR.maximized);
512 }
513 if (oldCfgR.maxFPSRate != mCfgR.maxFPSRate) {
514 mFrontend->mMaxFPSRate = mCfgR.maxFPSRate;
515 }
516 if (oldCfgR.useGLIndirectDraw != mCfgR.useGLIndirectDraw) {
517 mUpdateEventData = true;
518 }
519}
520
522{
523 // GPUError("key %d '%c'", key, (char) key);
524
525 bool shifted = key >= 'A' && key <= 'Z';
526 int32_t press = key;
527 if (press >= 'a' && press <= 'z') {
528 press += 'A' - 'a';
529 }
530 bool oldShift = mFrontend->mKeysShift[press];
531 mFrontend->mKeysShift[press] = shifted;
532 HandleKey(key);
533 mFrontend->mKeysShift[press] = oldShift;
534}
535
536void GPUDisplay::PrintGLHelpText(float colorValue)
537{
538 for (uint32_t i = 0; i < sizeof(HelpText) / sizeof(HelpText[0]); i++) {
539 OpenGLPrint(HelpText[i], 40.f, 35 + std::max(20, mDrawTextFontSize + 4) * (1 + i), colorValue, colorValue, colorValue, mInfoHelpTimer.GetCurrentElapsedTime() >= 5 ? (6 - mInfoHelpTimer.GetCurrentElapsedTime()) : 1, false);
540 }
541}
int32_t i
const char * HelpText[]
StringRef key
void Reset()
Definition timer.cxx:101
double GetCurrentElapsedTime(bool reset=false)
Definition timer.cxx:110
int32_t IsRunning()
Definition timer.h:33
void ResetStart()
Definition timer.cxx:63
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 HandleKey(uint8_t key)
void HandleSendKey(int32_t key)
GPUDisplayBackend * backend() const
Definition GPUDisplay.h:65
GLsizeiptr size
Definition glcorearb.h:659
GLboolean * data
Definition glcorearb.h:298
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)