82 GPUSettingsDisplayHeavy oldCfgH = mCfgH;
83 GPUSettingsDisplayLight oldCfgL = mCfgL;
84 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.maxFPSRate ^= 1;
162 SetInfo(
"FPS rate %s", mCfgR.maxFPSRate ?
"not limited" :
"limited");
163 }
else if (
key ==
'H') {
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;
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;
179 mCfgH.markClusters <<= 1;
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) {
190 SetInfo(
"Set FOV to %f", mCfgR.fov);
191 }
else if (
key == 39) {
193#ifdef GPUCA_DISPLAY_OPENGL_CORE
194 SetInfo(
"OpenGL compat profile not available, using core profile", 1);
196 mCfgR.openGLCore ^= 1;
197 SetInfo(
"Using renderer path for OpenGL %s profile", mCfgR.openGLCore ?
"core" :
"compat");
200 SetInfo(
"OpenGL options only available with OpenGL backend");
202 }
else if (
key ==
'B') {
203 mCfgH.markAdjacentClusters++;
204 if (mCfgH.markAdjacentClusters == 5) {
205 mCfgH.markAdjacentClusters = 7;
207 if (mCfgH.markAdjacentClusters == 9) {
208 mCfgH.markAdjacentClusters = 15;
210 if (mCfgH.markAdjacentClusters == 17) {
211 mCfgH.markAdjacentClusters = 31;
213 if (mCfgH.markAdjacentClusters == 34) {
214 mCfgH.markAdjacentClusters = 0;
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);
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");
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;
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;
260 if (mCfgR.drawQualityMSAA > 16 || mCfgR.drawQualityMSAA > mBackend->getMaxMSAA()) {
261 mCfgR.drawQualityMSAA = 0;
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;
269 if (mCfgR.drawQualityDownsampleFSAA == 5) {
270 mCfgR.drawQualityDownsampleFSAA = 0;
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 ==
';') {
282 SetInfo(
"TPC sector separation: %f %f", mCfgH.xAdd, mCfgH.zAdd);
283 }
else if (
key ==
':') {
286 if (mCfgH.zAdd < 0 || mCfgH.xAdd < 0) {
287 mCfgH.zAdd = mCfgH.xAdd = 0;
289 SetInfo(
"TPC sector separation: %f %f", mCfgH.xAdd, mCfgH.zAdd);
290 }
else if (
key ==
'#') {
291 mCfgL.invertColors ^= 1;
292 }
else if (
key ==
'g') {
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;
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);
323 SetInfo(
"Showing TPC Clusters: %d", (int32_t)mCfgL.drawTPC);
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);
331 SetInfo(
"Showing TRD Tracklets: %d", (int32_t)mCfgL.drawTRD);
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);
339 SetInfo(
"Showing TOF Hits: %d", (int32_t)mCfgL.drawTOF);
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);
347 SetInfo(
"Showing ITS Clusters: %d", (int32_t)mCfgL.drawITS);
350 mCfgH.drawTracksAndFilter ^= 1;
351 SetInfo(
"Track filter: %s", mCfgH.drawTracksAndFilter ?
"AND" :
"OR");
352 }
else if (
key ==
't') {
353 static int32_t nScreenshot = 1;
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;
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'))) {
371 SetInfo(
"Starting Animation", 1);
373 SetInfo(
"Insufficient Animation points to start Animation", 1);
375 }
else if (
key ==
'>') {
376 mAnimationChangeConfig ^= 1;
377 SetInfo(
"Interpolating visualization settings during Animation %s", mAnimationChangeConfig ?
"enabled" :
"disabled");
378 }
else if (
key ==
'Y') {
380 SetInfo(
"Added Animation point (%d points, %6.2f seconds)", (int32_t)mAnimateVectors[0].
size(), mAnimateVectors[0].back());
381 }
else if (
key ==
'X') {
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;
393 if (mCfgL.animationMode == 6) {
394 SetInfo(
"Animation mode %d - Centered on origin", mCfgL.animationMode);
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");
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");
405 int32_t retval = fwrite(&mViewMatrix,
sizeof(mViewMatrix), 1, ftmp);
407 GPUError(
"Error writing position to file");
409 GPUInfo(
"Position stored to file");
413 GPUError(
"Error opening file");
415 SetInfo(
"Camera position stored to file", 1);
416 }
else if (
key ==
'p') {
417 FILE* ftmp = fopen(
"glpos.tmp",
"rb");
419 int32_t retval = fread(&mViewMatrix, 1,
sizeof(mViewMatrix), ftmp);
420 if (retval ==
sizeof(mViewMatrix)) {
421 GPUInfo(
"Position read from file");
423 GPUError(
"Error reading position from file");
427 GPUError(
"Error opening file");
429 SetInfo(
"Camera position loaded from file", 1);
430 }
else if (
key ==
'O') {
431 FILE* ftmp = fopen(
"glanimation.tmp",
"w+b");
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);
439 fwrite(mAnimateConfig.data(),
sizeof(mAnimateConfig[0]),
size, ftmp);
442 GPUError(
"Error opening file");
444 SetInfo(
"Animation path stored to file %s",
"glanimation.tmp");
445 }
else if (
key ==
'P') {
446 FILE* ftmp = fopen(
"glanimation.tmp",
"rb");
448 int32_t retval = fread(&mCfgL,
sizeof(mCfgL), 1, ftmp);
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);
455 mAnimateConfig.resize(
size);
456 retval += fread(mAnimateConfig.data(),
sizeof(mAnimateConfig[0]),
size, ftmp);
461 GPUError(
"Error opening file");
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);
469 mPrintInfoTextAlways =
true;
470 mInfoHelpTimer.
Reset();
471 SetInfo(
"Showing help text until disabled", 1);
474 SetInfo(
"Showing help text", 1);
476 }
else if (
key ==
'q') {
478 SetInfo(
"Stopping GUI", 1);
481 SetInfo(
"Starting GUI", 1);
493 if (memcmp((
void*)&oldCfgH, (
void*)&mCfgH,
sizeof(mCfgH)) != 0) {
494 mUpdateEventData =
true;
496 if (memcmp((
void*)&oldCfgL, (
void*)&mCfgL,
sizeof(mCfgL)) != 0 || memcmp((
void*)&oldCfgR, (
void*)&mCfgR,
sizeof(mCfgR)) != 0) {
497 mUpdateDrawCommands =
true;
499 if (oldCfgR.drawQualityMSAA != mCfgR.drawQualityMSAA || oldCfgR.drawQualityDownsampleFSAA != mCfgR.drawQualityDownsampleFSAA || oldCfgL.depthBuffer != mCfgL.depthBuffer || oldCfgR.screenshotScaleFactor != mCfgR.screenshotScaleFactor) {
500 mUpdateRenderPipeline =
true;
503 if (oldCfgR.drawQualityVSync != mCfgR.drawQualityVSync) {
504 mFrontend->
SetVSync(mCfgR.drawQualityVSync);
505 mBackend->SetVSync(mCfgR.drawQualityVSync);
507 if (oldCfgR.fullScreen != mCfgR.fullScreen) {
510 if (oldCfgR.maximized != mCfgR.maximized) {
513 if (oldCfgR.maxFPSRate != mCfgR.maxFPSRate) {
516 if (oldCfgR.useGLIndirectDraw != mCfgR.useGLIndirectDraw) {
517 mUpdateEventData =
true;