82 const GPUSettingsDisplayHeavy oldCfgH = mCfgH;
83 const GPUSettingsDisplayLight oldCfgL = mCfgL;
84 const GPUSettingsDisplayRenderer oldCfgR = mCfgR;
87 SetInfo(
"Showing next event", 1);
90 SetInfo(
"Exiting", 1);
91 }
else if (
key ==
'r') {
93 SetInfo(
"View reset", 1);
95 mCfgR.camLookOrigin ^= 1;
96 mCfgR.cameraMode = mCfgR.camLookOrigin + 2 * mCfgR.camYUp;
97 SetInfo(
"Camera locked on origin: %s", mCfgR.camLookOrigin ?
"enabled" :
"disabled");
100 mCfgR.cameraMode = mCfgR.camLookOrigin + 2 * mCfgR.camYUp;
101 SetInfo(
"Camera locked on y-axis facing upwards: %s", mCfgR.camYUp ?
"enabled" :
"disabled");
104 if (mCfgR.cameraMode == 4) {
105 mCfgR.cameraMode = 0;
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]);
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);
119 SetInfo(
"Showing sector %d", mCfgL.drawSector);
121 }
else if (
key ==
'k') {
122 if (mCfgL.drawSector <= -1) {
123 mCfgL.drawSector = mCfgL.drawRelatedSectors ? (NSECTORS / 4 - 1) : (NSECTORS - 1);
127 if (mCfgL.drawSector == -1) {
128 SetInfo(
"Showing all sectors", 1);
130 SetInfo(
"Showing sector %d", mCfgL.drawSector);
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);
140 mCfgL.showCollision++;
141 SetInfo(
"Showing collision %d / %d", mCfgL.showCollision, mNCollissions);
143 }
else if (
key ==
'K') {
144 if (mCfgL.showCollision <= -1) {
145 mCfgL.showCollision = mNCollissions - 1;
147 mCfgL.showCollision--;
149 if (mCfgL.showCollision == -1) {
150 SetInfo(
"Showing all collisions", 1);
152 SetInfo(
"Showing collision %d / %d", mCfgL.showCollision, mNCollissions);
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;
163 SetInfo(
"FPS limit: %d FPS", mCfgR.fpsRate);
165 char rate[32] =
"unknown rate";
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);
175 SetInfo(
"FPS limit: refresh rate (%s)",
rate);
178 SetInfo(
"FPS limit: none");
180 }
else if (
key ==
'H') {
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;
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;
196 mCfgH.markClusters <<= 1;
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) {
207 SetInfo(
"Set FOV to %f", mCfgR.fov);
208 }
else if (
key ==
'm') {
209#ifdef GPUCA_DISPLAY_OPENGL_CORE
211 SetInfo(
"OpenGL compat profile not available, using core profile", 1);
215 mCfgR.rendererCompatSmoothing ^= 1;
216 SetInfo(
"Using renderer path for %s profile", mCfgR.rendererCompatSmoothing ?
"compat" :
"core (shader)");
218 }
else if (
key ==
'B') {
219 mCfgH.markAdjacentClusters++;
220 if (mCfgH.markAdjacentClusters == 5) {
221 mCfgH.markAdjacentClusters = 7;
223 if (mCfgH.markAdjacentClusters == 9) {
224 mCfgH.markAdjacentClusters = 15;
226 if (mCfgH.markAdjacentClusters == 17) {
227 mCfgH.markAdjacentClusters = 31;
229 if (mCfgH.markAdjacentClusters == 34) {
230 mCfgH.markAdjacentClusters = 0;
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);
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");
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;
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;
276 if (mCfgR.drawQualityMSAA > 16 || mCfgR.drawQualityMSAA > mBackend->getMaxMSAA()) {
277 mCfgR.drawQualityMSAA = 0;
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;
285 if (mCfgR.drawQualityDownsampleFSAA == 5) {
286 mCfgR.drawQualityDownsampleFSAA = 0;
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 ==
';') {
298 SetInfo(
"TPC sector separation: %f %f", mCfgH.xAdd, mCfgH.zAdd);
299 }
else if (
key ==
':') {
302 if (mCfgH.zAdd < 0 || mCfgH.xAdd < 0) {
303 mCfgH.zAdd = mCfgH.xAdd = 0;
305 SetInfo(
"TPC sector separation: %f %f", mCfgH.xAdd, mCfgH.zAdd);
306 }
else if (
key ==
'#') {
307 mCfgL.invertColors ^= 1;
308 }
else if (
key ==
'g') {
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;
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);
339 SetInfo(
"Showing TPC Clusters: %d", (int32_t)mCfgL.drawTPC);
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);
347 SetInfo(
"Showing TRD Tracklets: %d", (int32_t)mCfgL.drawTRD);
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);
355 SetInfo(
"Showing TOF Hits: %d", (int32_t)mCfgL.drawTOF);
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);
363 SetInfo(
"Showing ITS Clusters: %d", (int32_t)mCfgL.drawITS);
366 mCfgH.drawTracksAndFilter ^= 1;
367 SetInfo(
"Track filter: %s", mCfgH.drawTracksAndFilter ?
"AND" :
"OR");
368 }
else if (
key ==
't') {
369 static int32_t nScreenshot = 1;
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;
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'))) {
387 SetInfo(
"Starting Animation", 1);
389 SetInfo(
"Insufficient Animation points to start Animation", 1);
391 }
else if (
key ==
'>') {
392 mAnimationChangeConfig ^= 1;
393 SetInfo(
"Interpolating visualization settings during Animation %s", mAnimationChangeConfig ?
"enabled" :
"disabled");
394 }
else if (
key ==
'Y') {
396 SetInfo(
"Added Animation point (%d points, %6.2f seconds)", (int32_t)mAnimateVectors[0].
size(), mAnimateVectors[0].back());
397 }
else if (
key ==
'X') {
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;
409 if (mCfgL.animationMode == 6) {
410 SetInfo(
"Animation mode %d - Centered on origin", mCfgL.animationMode);
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");
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");
421 int32_t retval = fwrite(&mViewMatrix,
sizeof(mViewMatrix), 1, ftmp);
423 GPUError(
"Error writing position to file");
425 GPUInfo(
"Position stored to file");
429 GPUError(
"Error opening file");
431 SetInfo(
"Camera position stored to file", 1);
432 }
else if (
key ==
'p') {
433 FILE* ftmp = fopen(
"glpos.tmp",
"rb");
435 int32_t retval = fread(&mViewMatrix, 1,
sizeof(mViewMatrix), ftmp);
436 if (retval ==
sizeof(mViewMatrix)) {
437 GPUInfo(
"Position read from file");
439 GPUError(
"Error reading position from file");
443 GPUError(
"Error opening file");
445 SetInfo(
"Camera position loaded from file", 1);
446 }
else if (
key ==
'O') {
447 FILE* ftmp = fopen(
"glanimation.tmp",
"w+b");
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);
455 fwrite(mAnimateConfig.data(),
sizeof(mAnimateConfig[0]),
size, ftmp);
458 GPUError(
"Error opening file");
460 SetInfo(
"Animation path stored to file %s",
"glanimation.tmp");
461 }
else if (
key ==
'P') {
462 FILE* ftmp = fopen(
"glanimation.tmp",
"rb");
464 int32_t retval = fread(&mCfgL,
sizeof(mCfgL), 1, ftmp);
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);
471 mAnimateConfig.resize(
size);
472 retval += fread(mAnimateConfig.data(),
sizeof(mAnimateConfig[0]),
size, ftmp);
477 GPUError(
"Error opening file");
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);
485 mPrintInfoTextAlways =
true;
486 mInfoHelpTimer.
Reset();
487 SetInfo(
"Showing help text until disabled", 1);
490 SetInfo(
"Showing help text", 1);
492 }
else if (
key ==
'q') {
494 SetInfo(
"Stopping GUI", 1);
497 SetInfo(
"Starting GUI", 1);
509 if (!doNotHandleConfigChanges) {