Project
Loading...
Searching...
No Matches
GPUDisplayFrontendGlut.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// Now the other headers
19#include "GPULogging.h"
20#include <cstdio>
21#include <cstring>
22#include <GL/freeglut.h>
23#include <unistd.h>
24#ifdef GPUCA_BUILD_EVENT_DISPLAY_X11
25#include <GL/glx.h>
26#include <GL/glxext.h>
27#endif
28
29#include <pthread.h>
30using namespace o2::gpu;
31static GPUDisplayFrontendGlut* me = nullptr;
32
38
39void GPUDisplayFrontendGlut::displayFunc() // TODO: Functions should be lambdas, to get rid of the static me variable!
40{
41 me->DrawGLScene();
42 glutSwapBuffers();
43 me->waitForFPSLimit();
44}
45
46void GPUDisplayFrontendGlut::glutLoopFunc()
47{
48 me->HandleExternalGUISignals();
49 displayFunc();
50}
51
52int32_t GPUDisplayFrontendGlut::GetKey(int32_t key)
53{
54 if (key == GLUT_KEY_UP) {
55 return KEY_UP;
56 }
57 if (key == GLUT_KEY_DOWN) {
58 return KEY_DOWN;
59 }
60 if (key == GLUT_KEY_LEFT) {
61 return KEY_LEFT;
62 }
63 if (key == GLUT_KEY_RIGHT) {
64 return KEY_RIGHT;
65 }
66 if (key == GLUT_KEY_PAGE_UP) {
67 return KEY_PAGEUP;
68 }
69 if (key == GLUT_KEY_PAGE_DOWN) {
70 return KEY_PAGEDOWN;
71 }
72 if (key == GLUT_KEY_HOME) {
73 return KEY_HOME;
74 }
75 if (key == GLUT_KEY_END) {
76 return KEY_END;
77 }
78 if (key == GLUT_KEY_INSERT) {
79 return KEY_INSERT;
80 }
81 if (key == GLUT_KEY_F1) {
82 return KEY_F1;
83 }
84 if (key == GLUT_KEY_F2) {
85 return KEY_F2;
86 }
87 if (key == GLUT_KEY_F3) {
88 return KEY_F3;
89 }
90 if (key == GLUT_KEY_F4) {
91 return KEY_F4;
92 }
93 if (key == GLUT_KEY_F5) {
94 return KEY_F5;
95 }
96 if (key == GLUT_KEY_F6) {
97 return KEY_F6;
98 }
99 if (key == GLUT_KEY_F7) {
100 return KEY_F7;
101 }
102 if (key == GLUT_KEY_F8) {
103 return KEY_F8;
104 }
105 if (key == GLUT_KEY_F9) {
106 return KEY_F9;
107 }
108 if (key == GLUT_KEY_F10) {
109 return KEY_F10;
110 }
111 if (key == GLUT_KEY_F11) {
112 return KEY_F11;
113 }
114 if (key == GLUT_KEY_F12) {
115 return KEY_F12;
116 }
117 if (key == 112 || key == 113) {
118 return KEY_SHIFT;
119 }
120 if (key == 114) {
121 return KEY_CTRL;
122 }
123 if (key == 115) {
124 return KEY_RCTRL;
125 }
126 if (key == 116) {
127 return KEY_ALT;
128 }
129
130 return (0);
131}
132
133void GPUDisplayFrontendGlut::GetKey(int32_t key, int32_t& keyOut, int32_t& keyPressOut, bool special)
134{
135 int32_t specialKey = special ? GetKey(key) : 0;
136 // GPUInfo("Key: key %d (%c) (special %d) -> %d (%c) special %d (%c)", key, (char) key, (int32_t) special, (int32_t) key, key, specialKey, (char) specialKey);
137
138 if (specialKey) {
139 keyOut = keyPressOut = specialKey;
140 } else {
141 keyOut = keyPressOut = key;
142 if (keyPressOut >= 'a' && keyPressOut <= 'z') {
143 keyPressOut += 'A' - 'a';
144 }
145 }
146}
147
148void GPUDisplayFrontendGlut::keyboardDownFunc(uint8_t key, int32_t x, int32_t y)
149{
150 int32_t handleKey = 0, keyPress = 0;
151 GetKey(key, handleKey, keyPress, false);
152 me->mKeysShift[keyPress] = glutGetModifiers() & GLUT_ACTIVE_SHIFT;
153 me->mKeys[keyPress] = true;
154 me->HandleKey(handleKey);
155}
156
157void GPUDisplayFrontendGlut::keyboardUpFunc(uint8_t key, int32_t x, int32_t y)
158{
159 int32_t handleKey = 0, keyPress = 0;
160 GetKey(key, handleKey, keyPress, false);
161 me->mKeys[keyPress] = false;
162 me->mKeysShift[keyPress] = false;
163}
164
165void GPUDisplayFrontendGlut::specialDownFunc(int32_t key, int32_t x, int32_t y)
166{
167 int32_t handleKey = 0, keyPress = 0;
168 GetKey(key, handleKey, keyPress, true);
169 me->mKeysShift[keyPress] = glutGetModifiers() & GLUT_ACTIVE_SHIFT;
170 me->mKeys[keyPress] = true;
171 me->HandleKey(handleKey);
172}
173
174void GPUDisplayFrontendGlut::specialUpFunc(int32_t key, int32_t x, int32_t y)
175{
176 int32_t handleKey = 0, keyPress = 0;
177 GetKey(key, handleKey, keyPress, true);
178 me->mKeys[keyPress] = false;
179 me->mKeysShift[keyPress] = false;
180}
181
182void GPUDisplayFrontendGlut::ResizeSceneWrapper(int32_t width, int32_t height)
183{
184 if (!me->mFullScreen) {
185 me->mWidth = width;
186 me->mHeight = height;
187 }
188 me->ResizeScene(width, height);
189}
190
191void GPUDisplayFrontendGlut::mouseFunc(int32_t button, int32_t state, int32_t x, int32_t y)
192{
193 if (button == 3) {
194 me->mMouseWheel += 100;
195 } else if (button == 4) {
196 me->mMouseWheel -= 100;
197 } else if (state == GLUT_DOWN) {
198 if (button == GLUT_LEFT_BUTTON) {
199 me->mMouseDn = true;
200 } else if (button == GLUT_RIGHT_BUTTON) {
201 me->mMouseDnR = true;
202 } else if (button == GLUT_MIDDLE_BUTTON) {
203 me->mMouseDnM = true;
204 }
205 me->mMouseDnX = x;
206 me->mMouseDnY = y;
207 } else if (state == GLUT_UP) {
208 if (button == GLUT_LEFT_BUTTON) {
209 me->mMouseDn = false;
210 } else if (button == GLUT_RIGHT_BUTTON) {
211 me->mMouseDnR = false;
212 } else if (button == GLUT_MIDDLE_BUTTON) {
213 me->mMouseDnM = false;
214 }
215 }
216}
217
218void GPUDisplayFrontendGlut::mouseMoveFunc(int32_t x, int32_t y)
219{
220 me->mMouseMvX = x;
221 me->mMouseMvY = y;
222}
223
224void GPUDisplayFrontendGlut::mMouseWheelFunc(int32_t button, int32_t dir, int32_t x, int32_t y) { me->mMouseWheel += dir; }
225
226int32_t GPUDisplayFrontendGlut::FrontendMain()
227{
228 if (backend()->backendType() != GPUDisplayBackend::TYPE_OPENGL) {
229 fprintf(stderr, "Only OpenGL backend supported\n");
230 return 1;
231 }
232 me = this;
233 mCanDrawText = 1;
234 if (drawTextFontSize() == 0) {
235 drawTextFontSize() = 12;
236 }
237
238 int32_t nopts = 2;
239 char opt1[] = "progname";
240 char opt2[] = "-direct";
241 char* opts[] = {opt1, opt2};
242 glutInit(&nopts, opts);
243 glutInitContextVersion(GL_MIN_VERSION_MAJOR, GL_MIN_VERSION_MINOR);
244 glutInitContextProfile(mBackend->CoreProfile() ? GLUT_CORE_PROFILE : GLUT_COMPATIBILITY_PROFILE);
245 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
246 glutInitWindowSize(INIT_WIDTH, INIT_HEIGHT);
247 glutCreateWindow(DISPLAY_WINDOW_NAME);
248 glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
249
250 if (mBackend->ExtInit()) {
251 fprintf(stderr, "Error initializing GL extension wrapper\n");
252 return (-1);
253 }
254 if (InitDisplay()) {
255 fprintf(stderr, "Error in OpenGL initialization\n");
256 return (1);
257 }
258
259 glutDisplayFunc(displayFunc);
260 glutIdleFunc(glutLoopFunc);
261 glutReshapeFunc(ResizeSceneWrapper);
262 glutKeyboardFunc(keyboardDownFunc);
263 glutKeyboardUpFunc(keyboardUpFunc);
264 glutSpecialFunc(specialDownFunc);
265 glutSpecialUpFunc(specialUpFunc);
266 glutMouseFunc(mouseFunc);
267 glutMotionFunc(mouseMoveFunc);
268 glutPassiveMotionFunc(mouseMoveFunc);
269 glutMouseWheelFunc(mMouseWheelFunc);
272
273 {
274 std::lock_guard lock(mExitStateMutex);
275 mDisplayRunning = true;
276 }
277 glutMainLoop();
278 {
279 std::lock_guard lock(mExitStateMutex);
280 mDisplayControl = 2;
281 mDisplayRunning = false;
282 }
283
284 ExitDisplay();
285 return 0;
286}
287
289{
290 glutLeaveMainLoop();
291}
292
293void GPUDisplayFrontendGlut::OpenGLPrint(const char* s, float x, float y, float r, float g, float b, float a, bool fromBotton)
294{
295#ifndef GPUCA_DISPLAY_OPENGL_CORE
296 if (!fromBotton) {
297 y = mDisplayHeight - y;
298 }
299 glColor4f(r, g, b, a);
300 glRasterPos2f(x, y);
301 glutBitmapString(GLUT_BITMAP_HELVETICA_12, (const uint8_t*)s);
302#endif
303}
304
306{
307 mFullScreen = set;
308 if (set) {
309 glutFullScreen();
310 } else {
311 glutReshapeWindow(mWidth, mHeight);
312 }
313}
314
316void GPUDisplayFrontendGlut::SetVSync(bool enable) // GLUT has no swap interval API, set it via GLX directly (no-op if freeglut does not use GLX)
317{
318#ifdef GPUCA_BUILD_EVENT_DISPLAY_X11
319 if (canSetVSync()) {
320 ((PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT"))(glXGetCurrentDisplay(), glXGetCurrentDrawable(), enable);
321 }
322#endif
323}
324
326{
327#ifdef GPUCA_BUILD_EVENT_DISPLAY_X11
328 return glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT") && glXGetCurrentDisplay();
329#else
330 return false;
331#endif
332}
int32_t GetKey(int32_t key)
StringRef key
void OpenGLPrint(const char *s, float x, float y, float r, float g, float b, float a, bool fromBotton=true) override
static constexpr int32_t KEY_F9
static constexpr int32_t KEY_F2
static constexpr int32_t KEY_ALT
static constexpr int32_t KEY_F12
static constexpr int32_t KEY_F7
static constexpr int32_t KEY_END
static constexpr int32_t KEY_PAGEDOWN
static constexpr int32_t KEY_F10
static constexpr int32_t KEY_F4
static constexpr int32_t KEY_LEFT
static constexpr int32_t KEY_F6
static constexpr int32_t KEY_CTRL
static constexpr int32_t KEY_F1
static constexpr const char * DISPLAY_WINDOW_NAME
static constexpr int32_t INIT_WIDTH
static constexpr int32_t GL_MIN_VERSION_MAJOR
static constexpr int32_t KEY_SHIFT
static constexpr int32_t KEY_F3
static constexpr int32_t KEY_INSERT
static constexpr int32_t KEY_F11
static constexpr int32_t KEY_F5
static constexpr int32_t KEY_PAGEUP
static constexpr int32_t KEY_HOME
static constexpr int32_t GL_MIN_VERSION_MINOR
int32_t InitDisplay(bool initFailure=false)
static constexpr int32_t KEY_UP
static constexpr int32_t KEY_DOWN
static constexpr int32_t KEY_F8
static constexpr int32_t INIT_HEIGHT
static constexpr int32_t KEY_RIGHT
static constexpr int32_t KEY_RCTRL
GLint GLenum GLint x
Definition glcorearb.h:403
khronos_uint8_t GLubyte
Definition glcorearb.h:90
GLint GLsizei GLsizei height
Definition glcorearb.h:270
GLint GLsizei width
Definition glcorearb.h:270
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLboolean GLboolean g
Definition glcorearb.h:1233
GLboolean enable
Definition glcorearb.h:3991
GLboolean r
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
constexpr value_T me
Definition TrackUtils.h:128