Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
EGLWindow.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #include <vlEGL/EGLWindow.hpp>
33 #include <vlCore/Log.hpp>
34 #include <vlCore/Say.hpp>
35 #include <vlCore/Time.hpp>
36 #include <shellapi.h>
37 
38 using namespace vl;
39 using namespace vlEGL;
40 
41 //-----------------------------------------------------------------------------
42 namespace
43 {
44  #if 0
45  // used for debugging purposes
46  void win32PrintError(LPTSTR lpszFunction)
47  {
48  TCHAR szBuf[80];
49  LPVOID lpMsgBuf;
50  DWORD dw = GetLastError();
51 
52  FormatMessage(
53  FORMAT_MESSAGE_ALLOCATE_BUFFER |
54  FORMAT_MESSAGE_FROM_SYSTEM,
55  NULL,
56  dw,
57  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
58  (LPTSTR) &lpMsgBuf,
59  0, NULL );
60 
61  wsprintf(szBuf,
62  L"%s failed with error %d: %s",
63  lpszFunction, dw, lpMsgBuf);
64 
65  MessageBox(NULL, szBuf, L"Visualization Library Error", MB_OK);
66 
67  LocalFree(lpMsgBuf);
68  }
69  #endif
70 
71  bool registerClass()
72  {
73  static bool class_already_registered = false;
74  if (!class_already_registered)
75  {
76  WNDCLASS wc;
77  memset(&wc, 0, sizeof(wc));
78  /* only register the window class once. */
79  wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
80  wc.lpfnWndProc = (WNDPROC)EGLWindow::WindowProc;
81  wc.cbClsExtra = 0;
82  wc.cbWndExtra = 0;
83  wc.hInstance = GetModuleHandle(NULL);
84  wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
85  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
86  wc.hbrBackground = NULL;
87  wc.lpszMenuName = NULL;
88  wc.lpszClassName = EGLWindow::EGLWindowClassName;
89 
90  if (!RegisterClass(&wc))
91  MessageBox(NULL, L"Class registration failed.", L"Visualization Library Error", MB_OK);
92  else
93  class_already_registered = true;
94  }
95  return class_already_registered;
96  }
97 }
98 //-----------------------------------------------------------------------------
99 const wchar_t* EGLWindow::EGLWindowClassName = L"VisualizationLibraryWindowClass";
100 //-----------------------------------------------------------------------------
101 std::map< HWND, EGLWindow* > EGLWindow::mWinMap;
102 //-----------------------------------------------------------------------------
103 LONG WINAPI EGLWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
104 {
105  EGLWindow* win = EGLWindow::getWindow(hWnd);
106  if (!win)
107  return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam);
108 
109  switch(uMsg)
110  {
111  case WM_PAINT:
112  {
113  // handle event and then dispatch: solves MessageBox dialog problem.
114  LONG val = (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam);
115  if (win->eglContext() && win->eglSurface() && win->hwnd())
116  win->dispatchUpdateEvent();
117  return val;
118  }
119 
120  case WM_SIZE:
121  {
122  win->framebuffer()->setWidth( LOWORD(lParam) );
123  win->framebuffer()->setHeight( HIWORD(lParam) );
124  win->dispatchResizeEvent( LOWORD(lParam), HIWORD(lParam) );
125  break;
126  }
127 
128  case WM_MOUSEMOVE:
129  {
130  POINTS pt = MAKEPOINTS(lParam);
131  win->dispatchMouseMoveEvent( pt.x, pt.y );
132  break;
133  }
134 
135  case WM_LBUTTONDBLCLK:
136  case WM_LBUTTONDOWN:
137  case WM_MBUTTONDBLCLK:
138  case WM_MBUTTONDOWN:
139  case WM_RBUTTONDBLCLK:
140  case WM_RBUTTONDOWN:
141  {
142  win->mMouseDownCount++;
143  if (win->mMouseDownCount == 1)
144  SetCapture(win->hwnd());
145  EMouseButton button = UnknownButton;
146  if (uMsg == WM_LBUTTONDBLCLK || uMsg == WM_LBUTTONDOWN)
147  button = LeftButton;
148  else if (uMsg == WM_MBUTTONDBLCLK || uMsg == WM_MBUTTONDOWN)
149  button = MiddleButton;
150  else if (uMsg == WM_RBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN)
151  button = RightButton;
152  POINTS pt = MAKEPOINTS(lParam);
153  win->dispatchMouseDownEvent( button, pt.x, pt.y );
154  break;
155  }
156 
157  case WM_LBUTTONUP:
158  case WM_RBUTTONUP:
159  case WM_MBUTTONUP:
160  {
161  win->mMouseDownCount--;
162  if (win->mMouseDownCount <= 0)
163  {
164  ReleaseCapture();
165  win->mMouseDownCount = 0;
166  }
167  EMouseButton button = UnknownButton;
168  if (uMsg == WM_LBUTTONUP)
169  button = LeftButton;
170  else if (uMsg == WM_MBUTTONUP)
171  button = MiddleButton;
172  else if (uMsg == WM_RBUTTONUP)
173  button = RightButton;
174  POINTS pt = MAKEPOINTS(lParam);
175  win->dispatchMouseUpEvent( button, pt.x, pt.y );
176  break;
177  }
178 
179  // If you get a compilation error here:
180  // 1 - you didn't define _WIN32_WINNT as 0x0400 or above.
181  // 2 - you are trying to compile VL with a VERY old (unsupported) Visual Studio / Platform SDK.
182  case WM_MOUSEWHEEL:
183  {
184  win->dispatchMouseWheelEvent( GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA );
185  break;
186  }
187 
188  /*case WM_CLOSE:
189  {
190  win->dispatchDestroyEvent();
191  win->destroyEGLGLWindow();
192  break;
193  }*/
194 
195  case WM_DESTROY:
196  {
197  EGLWindow::mWinMap.erase(hWnd);
198  win->dispatchDestroyEvent();
199  win->destroyEGLGLWindow();
200  break;
201  }
202 
203  case WM_KEYDOWN:
204  {
205  unsigned short unicode_out = 0;
206  vl::EKey key_out = Key_None;
207  translateKeyEvent(wParam, lParam, unicode_out, key_out);
208  win->dispatchKeyPressEvent(unicode_out, key_out);
209  break;
210  }
211 
212  case WM_KEYUP:
213  {
214  unsigned short unicode_out = 0;
215  vl::EKey key_out = Key_None;
216  translateKeyEvent(wParam, lParam, unicode_out, key_out);
217  win->dispatchKeyReleaseEvent(unicode_out, key_out);
218  break;
219  }
220 
221  case WM_DROPFILES:
222  {
223  HDROP hDrop = (HDROP)wParam;
224  int count = DragQueryFile(hDrop, 0xFFFFFFFF, 0, 0);
225  const int char_count = 1024;
226  std::vector<String> files;
227  for(int i=0; i<count; ++i)
228  {
229  wchar_t file_path[char_count];
230  memset(file_path, 0, char_count);
231  DragQueryFile(hDrop,i,file_path,char_count);
232  files.push_back(file_path);
233  }
234  win->dispatchFileDroppedEvent(files);
235  break;
236  }
237 
238  // WM_SYSKEYDOWN
239  // WM_SYSKEYUP
240  // WM_GETICON
241  // WM_SETCURSOR
242  // WM_SETICON
243  // WM_CAPTURECHANGED
244  // WM_MOUSEFIRST
245  }
246 
247  return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam);
248 }
249 //-----------------------------------------------------------------------------
250 // EGLWindow
251 //-----------------------------------------------------------------------------
252 EGLWindow::EGLWindow()
253 {
254  mEGL_Display = 0;
255  mEGL_Context = 0;
256  mEGL_Surface = 0;
257 
258  mHWND = NULL;
259  mMouseDownCount = 0;
260 
261  mStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
262  mExStyle = WS_EX_APPWINDOW | WS_EX_ACCEPTFILES;
263  mWindowClassName = EGLWindowClassName;
264 }
265 //-----------------------------------------------------------------------------
266 EGLWindow::~EGLWindow()
267 {
268  destroyEGLGLWindow();
269 }
270 //-----------------------------------------------------------------------------
271 bool EGLWindow::initEGLWindow(HWND parent, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height)
272 {
273  destroyEGLGLWindow();
274 
275  if (!registerClass())
276  return false;
277 
278  unsigned style = mStyle & ~(WS_CHILD|WS_OVERLAPPEDWINDOW);;
279  style |= parent?WS_CHILD:WS_OVERLAPPEDWINDOW;
280 
281  mHWND = CreateWindowEx(
282  mExStyle,
283  mWindowClassName,
284  L"Visualization Library's EGLWindow",
285  style,
286  x, y, width, height,
287  parent, NULL, GetModuleHandle(NULL), NULL);
288 
289  setWindowTitle(title);
290 
291  // EGL initialization
292 
293  EGLint client_version[] = { EGL_CONTEXT_CLIENT_VERSION, fmt.contextClientVersion(), EGL_NONE };
294 
295  EGLint attrib_list[] =
296  {
297  EGL_RED_SIZE, fmt.rgbaBits().r(),
298  EGL_GREEN_SIZE, fmt.rgbaBits().g(),
299  EGL_BLUE_SIZE, fmt.rgbaBits().b(),
300  EGL_ALPHA_SIZE, fmt.rgbaBits().a() ? fmt.rgbaBits().a() : EGL_DONT_CARE,
301  EGL_DEPTH_SIZE, fmt.depthBufferBits() ? fmt.depthBufferBits() : EGL_DONT_CARE,
302  EGL_STENCIL_SIZE, fmt.stencilBufferBits() ? fmt.stencilBufferBits() : EGL_DONT_CARE,
303  EGL_SAMPLE_BUFFERS, fmt.multisample() ? 1 : 0,
304  EGL_SAMPLES, fmt.multisample() ? fmt.multisampleSamples() : EGL_DONT_CARE,
305  EGL_NONE
306  };
307 
308  // Get Display
309  mEGL_Display = eglGetDisplay(GetDC(mHWND));
310  if ( mEGL_Display == EGL_NO_DISPLAY )
311  {
312  return false;
313  }
314 
315  // Initialize EGL
316  EGLint maj_version=0, min_version=0;
317  if ( !eglInitialize(mEGL_Display, &maj_version, &min_version) )
318  {
319  return false;
320  }
321 
322  // Get configs
323  EGLint num_configs = 0;
324  if ( !eglGetConfigs(mEGL_Display, NULL, 0, &num_configs) )
325  {
326  return false;
327  }
328 
329  // Choose config
330  EGLConfig configurations[32] = {0};
331  if ( !eglChooseConfig(mEGL_Display, attrib_list, configurations, 32, &num_configs) )
332  {
333  return false;
334  }
335 
336 #if 0
337  for(int i=0; i<num_configs; ++i)
338  {
339  printf("EGLConfig #%d:\n", i);
340  EGLint value = 0;
341  eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_RED_SIZE, &value); printf("EGL_RED_SIZE = %d\n", value);
342  eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_GREEN_SIZE, &value); printf("EGL_GREEN_SIZE = %d\n", value);
343  eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_BLUE_SIZE, &value); printf("EGL_BLUE_SIZE = %d\n", value);
344  eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_ALPHA_SIZE, &value); printf("EGL_ALPHA_SIZE = %d\n", value);
345  eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_DEPTH_SIZE, &value); printf("EGL_DEPTH_SIZE = %d\n", value);
346  eglGetConfigAttrib( mEGL_Display, configurations[i], EGL_STENCIL_SIZE, &value); printf("EGL_STENCIL_SIZE = %d\n", value);
347  }
348 #endif
349 
350  // Sorting explained here: http://www.khronos.org/opengles/documentation/opengles1_0/html/eglChooseConfig.html
351  EGLConfig selected_config = configurations[0];
352 
353  // Create a surface
354  mEGL_Surface = eglCreateWindowSurface(mEGL_Display, selected_config, (EGLNativeWindowType)mHWND, NULL);
355  if ( mEGL_Surface == EGL_NO_SURFACE )
356  {
357  return false;
358  }
359 
360  // Create a GL context
361  mEGL_Context = eglCreateContext(mEGL_Display, selected_config, EGL_NO_CONTEXT, client_version );
362  if ( mEGL_Context == EGL_NO_CONTEXT )
363  {
364  return false;
365  }
366 
367  // Make the context current
368  if ( !eglMakeCurrent(mEGL_Display, mEGL_Surface, mEGL_Surface, mEGL_Context) )
369  {
370  return false;
371  }
372 
373  if ( !initGLContext() )
374  return false;
375 
376  // register window
377  mWinMap[mHWND] = this;
378 
379  // vSync
380  eglSwapInterval(mEGL_Display, fmt.vSync() ? 1 : 0);
381 
382  dispatchInitEvent();
383 
384  setPosition(x, y);
385 
386  setSize(width, height);
387 
388  return true;
389 }
390 //-----------------------------------------------------------------------------
391 void EGLWindow::swapBuffers()
392 {
393  // Due to the fact that eglSwapBuffers() can call WM_DESTROY mEGL_Surface might become NULL after calling it.
394  if ( !eglSwapBuffers(mEGL_Display, mEGL_Surface) && mEGL_Surface )
395  {
396  Log::error("EGLWindow::swapBuffers() failed!\n");
397  }
398 }
399 //-----------------------------------------------------------------------------
400 void EGLWindow::makeCurrent()
401 {
402  if ( !eglMakeCurrent(mEGL_Display, mEGL_Surface, mEGL_Surface, mEGL_Context) )
403  {
404  Log::error("EGLWindow::makeCurrent() failed!\n");
405  }
406 }
407 //-----------------------------------------------------------------------------
408 void EGLWindow::update()
409 {
410  if (mHWND)
411  PostMessage(hwnd(), WM_PAINT, 0, 0);
412 }
413 //-----------------------------------------------------------------------------
414 void EGLWindow::quitApplication()
415 {
416  PostQuitMessage(0);
417 }
418 //-----------------------------------------------------------------------------
419 void EGLWindow::setMouseVisible(bool visible)
420 {
421  mMouseVisible = visible;
422  if (visible)
423  while(ShowCursor(TRUE ) < 0) {}
424  else
425  while(ShowCursor(FALSE) >= 0) {}
426 }
427 //-----------------------------------------------------------------------------
428 void EGLWindow::setPosition(int x, int y)
429 {
430  if (hwnd())
431  SetWindowPos(hwnd(), 0, x, y, 0, 0, SWP_NOSIZE );
432 }
433 //-----------------------------------------------------------------------------
434 void EGLWindow::setSize(int w, int h)
435 {
436  if (hwnd())
437  {
438  RECT windowRect = { 0, 0, w, h };
439  AdjustWindowRectEx(&windowRect, (DWORD)GetWindowLongPtr(hwnd(), GWL_STYLE), 0, (DWORD)GetWindowLongPtr(hwnd(), GWL_EXSTYLE) );
440  // computes the actual window based on the client dimensions
441  int cx = windowRect.right - windowRect.left;
442  int cy = windowRect.bottom - windowRect.top;
443  SetWindowPos(hwnd(), 0, 0, 0, cx, cy, SWP_NOMOVE );
444  }
445 }
446 //-----------------------------------------------------------------------------
447 void EGLWindow::setWindowSize(int w, int h)
448 {
449  // Sset by WM_SIZE event handler:
450  // mFramebuffer->setWidth(w);
451  // mFramebuffer->setHeight(h);
452 
453  SetWindowPos(hwnd(), 0, 0, 0, w, h, SWP_NOMOVE);
454 }
455 //-----------------------------------------------------------------------------
456 vl::ivec2 EGLWindow::position() const
457 {
458  RECT r = {0,0,0,0};
459  if (hwnd())
460  GetWindowRect(hwnd(), &r);
461  return vl::ivec2(r.left,r.top);
462 }
463 //-----------------------------------------------------------------------------
464 vl::ivec2 EGLWindow::windowSize() const
465 {
466  RECT r = {0,0,0,0};
467  if (hwnd())
468  GetWindowRect(hwnd(), &r);
469  return vl::ivec2(r.right - r.left, r.bottom - r.top);
470 }
471 //-----------------------------------------------------------------------------
472 vl::ivec2 EGLWindow::size() const
473 {
474  RECT r = {0,0,0,0};
475  if (hwnd())
476  GetClientRect(hwnd(), &r);
477  return vl::ivec2(r.right - r.left, r.bottom - r.top);
478 }
479 //-----------------------------------------------------------------------------
480 void EGLWindow::setWindowTitle(const String& title)
481 {
482  if (hwnd())
483  SetWindowText(hwnd(), (wchar_t*)title.ptr());
484 }
485 //-----------------------------------------------------------------------------
486 void EGLWindow::show()
487 {
488  if (hwnd())
489  ShowWindow(hwnd(), SW_SHOW);
490 }
491 //-----------------------------------------------------------------------------
492 void EGLWindow::hide()
493 {
494  if (hwnd())
495  ShowWindow(hwnd(), SW_HIDE);
496 }
497 //-----------------------------------------------------------------------------
498 void EGLWindow::getFocus()
499 {
500  if (hwnd())
501  SetFocus(hwnd());
502 }
503 //-----------------------------------------------------------------------------
504 void EGLWindow::setMousePosition(int x, int y)
505 {
506  if (hwnd())
507  {
508  POINT pt = {x, y};
509  ClientToScreen( hwnd(), &pt );
510  SetCursorPos(pt.x, pt.y);
511  }
512 }
513 //-----------------------------------------------------------------------------
514 EGLWindow* EGLWindow::getWindow(HWND hWnd)
515 {
516  std::map< HWND, EGLWindow* >::const_iterator it = mWinMap.find(hWnd);
517  if (it != mWinMap.end())
518  return it->second;
519  else
520  return NULL;
521 }
522 //-----------------------------------------------------------------------------
523 void EGLWindow::destroyEGLGLWindow()
524 {
525  if (hwnd())
526  {
527  bool destroy_win = mWinMap.find(mHWND) != mWinMap.end();
528 
529  // WM_DESTROY must be dispatched while the OpenGL context is still available!
530  if (destroy_win)
531  {
532  DestroyWindow(mHWND);
533  mHWND = NULL;
534  }
535 
536  eglDestroyContext ( eglDisplay(), eglContext() ); mEGL_Context = NULL;
537  eglDestroySurface ( eglDisplay(), eglSurface() ); mEGL_Surface = NULL;
538  eglTerminate ( eglDisplay() ); mEGL_Display = NULL;
539  }
540 }
541 //-----------------------------------------------------------------------------
543 {
544  // iterate over all opengl contexts
545  std::map< HWND, EGLWindow* > wins = EGLWindow::winMap();
546  for( std::map< HWND, EGLWindow* >::iterator it = wins.begin();
547  it != wins.end();
548  ++it )
549  {
550  EGLWindow* win = it->second;
551  if ( win->continuousUpdate() )
552  win->update();
553  else
554  Sleep(10);
555  }
556 }
557 //-----------------------------------------------------------------------------
558 void vlEGL::peekMessage(MSG& msg)
559 {
560  if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
561  {
562  if (msg.message != WM_QUIT)
563  {
564  TranslateMessage(&msg);
565  DispatchMessage(&msg);
566  }
567  }
568  else
569  dispatchUpdate();
570 }
571 //-----------------------------------------------------------------------------
573 {
574  while(!EGLWindow::winMap().empty())
575  {
576  MSG msg = {0,0,0,0,0,0,0};
577  peekMessage(msg);
578  if (msg.message == WM_QUIT)
579  return (int)msg.wParam;
580  }
581  return 0; /* never reached */
582 }
583 //-----------------------------------------------------------------------------
584 void vlEGL::translateKeyEvent(WPARAM wParam, LPARAM lParam, unsigned short& unicode_out, vl::EKey& key_out)
585 {
586  // translate non unicode characters
587  key_out = Key_None;
588  unicode_out = 0;
589 
590  switch(wParam)
591  {
592  case VK_CLEAR: key_out = Key_Clear; break;
593  case VK_CONTROL: key_out = Key_Ctrl; break;
594  case VK_LCONTROL: key_out = Key_LeftCtrl; break;
595  case VK_RCONTROL: key_out = Key_RightCtrl; break;
596  case VK_MENU: key_out = Key_Alt; break;
597  case VK_LMENU: key_out = Key_LeftAlt; break;
598  case VK_RMENU: key_out = Key_RightAlt; break;
599  case VK_SHIFT: key_out = Key_Shift; break;
600  case VK_LSHIFT: key_out = Key_LeftShift; break;
601  case VK_RSHIFT: key_out = Key_RightShift; break;
602  case VK_INSERT: key_out = Key_Insert; break;
603  case VK_DELETE: key_out = Key_Delete; break;
604  case VK_HOME: key_out = Key_Home; break;
605  case VK_END: key_out = Key_End; break;
606  case VK_PRINT: key_out = Key_Print; break;
607  case VK_PAUSE: key_out = Key_Pause; break;
608  case VK_PRIOR: key_out = Key_PageUp; break;
609  case VK_NEXT: key_out = Key_PageDown; break;
610  case VK_LEFT: key_out = Key_Left; break;
611  case VK_RIGHT: key_out = Key_Right; break;
612  case VK_UP: key_out = Key_Up; break;
613  case VK_DOWN: key_out = Key_Down; break;
614  case VK_F1: key_out = Key_F1; break;
615  case VK_F2: key_out = Key_F2; break;
616  case VK_F3: key_out = Key_F3; break;
617  case VK_F4: key_out = Key_F4; break;
618  case VK_F5: key_out = Key_F5; break;
619  case VK_F6: key_out = Key_F6; break;
620  case VK_F7: key_out = Key_F7; break;
621  case VK_F8: key_out = Key_F8; break;
622  case VK_F9: key_out = Key_F9; break;
623  case VK_F10: key_out = Key_F10; break;
624  case VK_F11: key_out = Key_F11; break;
625  case VK_F12: key_out = Key_F12; break;
626 
627  /*
628  * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
629  * 0x40 : is unassigned
630  * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
631  */
632 
633  case L'0': key_out = Key_0; break;
634  case L'1': key_out = Key_1; break;
635  case L'2': key_out = Key_2; break;
636  case L'3': key_out = Key_3; break;
637  case L'4': key_out = Key_4; break;
638  case L'5': key_out = Key_5; break;
639  case L'6': key_out = Key_6; break;
640  case L'7': key_out = Key_7; break;
641  case L'8': key_out = Key_8; break;
642  case L'9': key_out = Key_9; break;
643 
644  case L'A': key_out = Key_A; break;
645  case L'B': key_out = Key_B; break;
646  case L'C': key_out = Key_C; break;
647  case L'D': key_out = Key_D; break;
648  case L'E': key_out = Key_E; break;
649  case L'F': key_out = Key_F; break;
650  case L'G': key_out = Key_G; break;
651  case L'H': key_out = Key_H; break;
652  case L'I': key_out = Key_I; break;
653  case L'J': key_out = Key_J; break;
654  case L'K': key_out = Key_K; break;
655  case L'L': key_out = Key_L; break;
656  case L'M': key_out = Key_M; break;
657  case L'N': key_out = Key_N; break;
658  case L'O': key_out = Key_O; break;
659  case L'P': key_out = Key_P; break;
660  case L'Q': key_out = Key_Q; break;
661  case L'R': key_out = Key_R; break;
662  case L'S': key_out = Key_S; break;
663  case L'T': key_out = Key_T; break;
664  case L'U': key_out = Key_U; break;
665  case L'V': key_out = Key_V; break;
666  case L'W': key_out = Key_W; break;
667  case L'X': key_out = Key_X; break;
668  case L'Y': key_out = Key_Y; break;
669  case L'Z': key_out = Key_Z; break;
670  }
671 
672  // fill unicode
673  BYTE mskeys[256];
674  memset( mskeys, 0, sizeof(BYTE)*256 );
675  WCHAR unicode[4] = { 0, 0 };
676  if ( ToUnicode( (UINT)wParam, (UINT)((lParam >> 16) & 0xFF), mskeys, unicode, 4, 0 ) == 1 )
677  {
678  unicode_out = unicode[0];
679 
680  // fill key
681  switch(unicode_out)
682  {
683  case L'0': key_out = Key_0; break;
684  case L'1': key_out = Key_1; break;
685  case L'2': key_out = Key_2; break;
686  case L'3': key_out = Key_3; break;
687  case L'4': key_out = Key_4; break;
688  case L'5': key_out = Key_5; break;
689  case L'6': key_out = Key_6; break;
690  case L'7': key_out = Key_7; break;
691  case L'8': key_out = Key_8; break;
692  case L'9': key_out = Key_9; break;
693 
694  case L'A': key_out = Key_A; break;
695  case L'B': key_out = Key_B; break;
696  case L'C': key_out = Key_C; break;
697  case L'D': key_out = Key_D; break;
698  case L'E': key_out = Key_E; break;
699  case L'F': key_out = Key_F; break;
700  case L'G': key_out = Key_G; break;
701  case L'H': key_out = Key_H; break;
702  case L'I': key_out = Key_I; break;
703  case L'J': key_out = Key_J; break;
704  case L'K': key_out = Key_K; break;
705  case L'L': key_out = Key_L; break;
706  case L'M': key_out = Key_M; break;
707  case L'N': key_out = Key_N; break;
708  case L'O': key_out = Key_O; break;
709  case L'P': key_out = Key_P; break;
710  case L'Q': key_out = Key_Q; break;
711  case L'R': key_out = Key_R; break;
712  case L'S': key_out = Key_S; break;
713  case L'T': key_out = Key_T; break;
714  case L'U': key_out = Key_U; break;
715  case L'V': key_out = Key_V; break;
716  case L'W': key_out = Key_W; break;
717  case L'X': key_out = Key_X; break;
718  case L'Y': key_out = Key_Y; break;
719  case L'Z': key_out = Key_Z; break;
720 
721  case L'a': key_out = Key_A; break;
722  case L'b': key_out = Key_B; break;
723  case L'c': key_out = Key_C; break;
724  case L'd': key_out = Key_D; break;
725  case L'e': key_out = Key_E; break;
726  case L'f': key_out = Key_F; break;
727  case L'g': key_out = Key_G; break;
728  case L'h': key_out = Key_H; break;
729  case L'i': key_out = Key_I; break;
730  case L'j': key_out = Key_J; break;
731  case L'k': key_out = Key_K; break;
732  case L'l': key_out = Key_L; break;
733  case L'm': key_out = Key_M; break;
734  case L'n': key_out = Key_N; break;
735  case L'o': key_out = Key_O; break;
736  case L'p': key_out = Key_P; break;
737  case L'q': key_out = Key_Q; break;
738  case L'r': key_out = Key_R; break;
739  case L's': key_out = Key_S; break;
740  case L't': key_out = Key_T; break;
741  case L'u': key_out = Key_U; break;
742  case L'v': key_out = Key_V; break;
743  case L'w': key_out = Key_W; break;
744  case L'x': key_out = Key_X; break;
745  case L'y': key_out = Key_Y; break;
746  case L'z': key_out = Key_Z; break;
747 
748  case 13: key_out = Key_Return; break;
749  case 8: key_out = Key_BackSpace; break;
750  case 9: key_out = Key_Tab; break;
751  case L' ': key_out = Key_Space; break;
752 
753  case 27: key_out = Key_Escape; break;
754  case L'!': key_out = Key_Exclam; break;
755  case L'"': key_out = Key_QuoteDbl; break;
756  case L'#': key_out = Key_Hash; break;
757  case L'$': key_out = Key_Dollar; break;
758  case L'&': key_out = Key_Ampersand; break;
759  case L'\'': key_out = Key_Quote; break;
760  case L'(': key_out = Key_LeftParen; break;
761  case L')': key_out = Key_RightParen; break;
762  case L'*': key_out = Key_Asterisk; break;
763  case L'+': key_out = Key_Plus; break;
764  case L',': key_out = Key_Comma; break;
765  case L'-': key_out = Key_Minus; break;
766  case L'.': key_out = Key_Period; break;
767  case L'\\': key_out = Key_Slash; break;
768  case L':': key_out = Key_Colon; break;
769  case L';': key_out = Key_Semicolon; break;
770  case L'<': key_out = Key_Less; break;
771  case L'=': key_out = Key_Equal; break;
772  case L'>': key_out = Key_Greater; break;
773  case L'?': key_out = Key_Question; break;
774  case L'@': key_out = Key_At; break;
775  case L'[': key_out = Key_LeftBracket; break;
776  case L'/': key_out = Key_BackSlash; break;
777  case L']': key_out = Key_RightBracket; break;
778  case L'|': key_out = Key_Caret; break;
779  case L'_': key_out = Key_Underscore; break;
780  case L'`': key_out = Key_QuoteLeft; break;
781  }
782  }
783 }
784 //-----------------------------------------------------------------------------
void dispatchKeyReleaseEvent(unsigned short unicode_ch, EKey key)
Dispatches the UIEventListener::keyReleaseEvent() notification to the subscribed UIEventListener obje...
Vector2< int > ivec2
A 2 components vector with int precision.
Definition: Vector2.hpp:278
void setWidth(int width)
The width of a render target.
Definition: Framebuffer.hpp:78
void dispatchMouseDownEvent(EMouseButton button, int x, int y)
Dispatches the UIEventListener::mouseDownEvent() notification to the subscribed UIEventListener objec...
VLEGL_EXPORT int messageLoop()
Definition: EGLWindow.cpp:572
Framebuffer * framebuffer()
The default render target (always returns leftFramebuffer()).
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
Definition: String.hpp:62
int multisampleSamples() const
const T_Scalar & r() const
Definition: Vector4.hpp:111
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
const EGLSurface & eglSurface() const
Definition: EGLWindow.hpp:110
void dispatchKeyPressEvent(unsigned short unicode_ch, EKey key)
Dispatches the UIEventListener::keyPressEvent() notification to the subscribed UIEventListener object...
void dispatchResizeEvent(int w, int h)
Dispatches the UIEventListener::resizeEvent() notification to the subscribed UIEventListener objects...
const wchar_t * ptr() const
Returns the 0-terminated utf16 string.
Definition: String.hpp:127
void destroyEGLGLWindow()
Destroys the window and the OpenGL rendering context.
Definition: EGLWindow.cpp:523
Visualization Library main namespace.
VLEGL_EXPORT void peekMessage(MSG &msg)
Definition: EGLWindow.cpp:558
const EGLContext & eglContext() const
Definition: EGLWindow.hpp:109
const T_Scalar & g() const
Definition: Vector4.hpp:112
bool continuousUpdate() const
If the OpenGL context is a widget this function returns whether its area is continuously updated at e...
void dispatchUpdateEvent()
Dispatches the UIEventListener::updateEvent() notification to the subscribed UIEventListener objects...
The OpenGLContextFormat class encapsulates the settings of an OpenGL rendering context.
const ivec4 & rgbaBits() const
EMouseButton
void update()
If the OpenGLContext is a widget this function requests a redraw and generates an updateEvent()...
Definition: EGLWindow.cpp:408
const T_Scalar & b() const
Definition: Vector4.hpp:113
void dispatchMouseWheelEvent(int n)
Dispatches the UIEventListener::mouseWheelEvent() notification to the subscribed UIEventListener obje...
int contextClientVersion() const
Used by EGLWindow to initialize either GLES 1.x or GLES 2.x contexts.
#define NULL
Definition: OpenGLDefs.hpp:81
VLEGL_EXPORT void translateKeyEvent(WPARAM wParam, LPARAM lParam, unsigned short &unicode_out, vl::EKey &key_out)
Definition: EGLWindow.cpp:584
bool registerClass()
Definition: Win32Window.cpp:44
The experimental EGL bindings namespace.
void dispatchDestroyEvent()
Dispatches the UIEventListener::destroyEvent() notification to the subscribed UIEventListener(s), calls destroyAllOpenGLResources() and eraseAllEventListeners() This event must be issued just before the actual GL context is destroyed.
void dispatchFileDroppedEvent(const std::vector< String > &files)
Dispatches the UIEventListener::fileDroppedEvent() notification to the subscribed UIEventListener obj...
The EGLWindow class is a EGLContext that can be used as a top or child window.
Definition: EGLWindow.hpp:52
void dispatchMouseMoveEvent(int x, int y)
Dispatches the UIEventListener::mouseMoveEvent() notification to the subscribed UIEventListener objec...
void setHeight(int height)
The height of a render target.
Definition: Framebuffer.hpp:81
HWND hwnd() const
Definition: EGLWindow.hpp:88
const T_Scalar & a() const
Definition: Vector4.hpp:114
void dispatchMouseUpEvent(EMouseButton button, int x, int y)
Dispatches the UIEventListener::mouseUpEvent() notification to the subscribed UIEventListener objects...
VLEGL_EXPORT void dispatchUpdate()
Definition: EGLWindow.cpp:542