# Visualization Library

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

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlWin32/Win32Window.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #include <vlWin32/Win32Window.hpp>
    00033 #include <vlCore/Log.hpp>
    00034 #include <vlCore/Say.hpp>
    00035 #include <vlCore/Time.hpp>
    00036 #include <shellapi.h>
    00037
    00038 using namespace vl;
    00039 using namespace vlWin32;
    00040
    00041 //-----------------------------------------------------------------------------
    00042 namespace
    00043 {
    00044   #if 0
    00045     // used for debugging purposes
    00046     void win32PrintError(LPTSTR lpszFunction)
    00047     {
    00048         TCHAR szBuf[80];
    00049         LPVOID lpMsgBuf;
    00050         DWORD dw = GetLastError();
    00051
    00052         FormatMessage(
    00053             FORMAT_MESSAGE_ALLOCATE_BUFFER |
    00054             FORMAT_MESSAGE_FROM_SYSTEM,
    00055             NULL,
    00056             dw,
    00057             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    00058             (LPTSTR) &lpMsgBuf,
    00059             0, NULL );
    00060
    00061         wsprintf(szBuf,
    00062             L"%s failed with error %d: %s",
    00063             lpszFunction, dw, lpMsgBuf);
    00064
    00065         MessageBox(NULL, szBuf, L"Visualization Library Error", MB_OK);
    00066
    00067         LocalFree(lpMsgBuf);
    00068     }
    00069   #endif
    00070
    00071   bool registerClass()
    00072   {
    00073     static bool class_already_registered = false;
    00074     if (!class_already_registered)
    00075     {
    00076       WNDCLASS wc;
    00077       memset(&wc, 0, sizeof(wc));
    00078       /* only register the window class once. */
    00079       wc.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
    00080       wc.lpfnWndProc   = (WNDPROC)Win32Window::WindowProc;
    00081       wc.cbClsExtra    = 0;
    00082       wc.cbWndExtra    = 0;
    00083       wc.hInstance     = GetModuleHandle(NULL);
    00084       wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
    00085       wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    00086       wc.hbrBackground = NULL;
    00087       wc.lpszMenuName  = NULL;
    00088       wc.lpszClassName = Win32Window::Win32WindowClassName;
    00089
    00090       if (!RegisterClass(&wc))
    00091         MessageBox(NULL, L"Class registration failed.", L"Visualization Library Error", MB_OK);
    00092       else
    00093         class_already_registered = true;
    00094     }
    00095     return class_already_registered;
    00096   }
    00097 }
    00098 //-----------------------------------------------------------------------------
    00099 const wchar_t* Win32Window::Win32WindowClassName = L"VisualizationLibraryWindowClass";
    00100 //-----------------------------------------------------------------------------
    00101 std::map< HWND, Win32Window* > Win32Window::mWinMap;
    00102 //-----------------------------------------------------------------------------
    00103 LONG WINAPI Win32Window::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    00104 {
    00105   Win32Window* win = Win32Window::getWindow(hWnd);
    00106   if (!win)
    00107     return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam);
    00108
    00109   switch(uMsg)
    00110   {
    00111     case WM_PAINT:
    00112     {
    00113       // handle event and then dispatch: solves MessageBox dialog problem.
    00114       LONG val = (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam);
    00115       if (win->hglrc() && win->hdc() && win->hwnd())
    00116         win->dispatchRunEvent();
    00117       return val;
    00118     }
    00119
    00120     case WM_SIZE:
    00121     {
    00122       win->renderTarget()->setWidth( LOWORD(lParam) );
    00123       win->renderTarget()->setHeight( HIWORD(lParam) );
    00124       win->dispatchResizeEvent( LOWORD(lParam), HIWORD(lParam) );
    00125       break;
    00126     }
    00127
    00128     case WM_MOUSEMOVE:
    00129     {
    00130       POINTS pt = MAKEPOINTS(lParam);
    00131       win->dispatchMouseMoveEvent( pt.x, pt.y );
    00132       break;
    00133     }
    00134
    00135     case WM_LBUTTONDBLCLK:
    00136     case WM_LBUTTONDOWN:
    00137     case WM_MBUTTONDBLCLK:
    00138     case WM_MBUTTONDOWN:
    00139     case WM_RBUTTONDBLCLK:
    00140     case WM_RBUTTONDOWN:
    00141     {
    00142       win->mMouseDownCount++;
    00143       if (win->mMouseDownCount == 1)
    00144         SetCapture(win->hwnd());
    00145       EMouseButton button = UnknownButton;
    00146       if (uMsg == WM_LBUTTONDBLCLK || uMsg == WM_LBUTTONDOWN)
    00147         button = LeftButton;
    00148       else if (uMsg == WM_MBUTTONDBLCLK || uMsg == WM_MBUTTONDOWN)
    00149         button = MiddleButton;
    00150       else if (uMsg == WM_RBUTTONDBLCLK || uMsg == WM_RBUTTONDOWN)
    00151         button = RightButton;
    00152       POINTS pt = MAKEPOINTS(lParam);
    00153       win->dispatchMouseDownEvent( button, pt.x, pt.y );
    00154       break;
    00155     }
    00156
    00157     case WM_LBUTTONUP:
    00158     case WM_RBUTTONUP:
    00159     case WM_MBUTTONUP:
    00160     {
    00161       win->mMouseDownCount--;
    00162       if (win->mMouseDownCount <= 0)
    00163       {
    00164         ReleaseCapture();
    00165         win->mMouseDownCount = 0;
    00166       }
    00167       EMouseButton button = UnknownButton;
    00168       if (uMsg == WM_LBUTTONUP)
    00169         button = LeftButton;
    00170       else if (uMsg == WM_MBUTTONUP)
    00171         button = MiddleButton;
    00172       else if (uMsg == WM_RBUTTONUP)
    00173         button = RightButton;
    00174       POINTS pt = MAKEPOINTS(lParam);
    00175       win->dispatchMouseUpEvent( button, pt.x, pt.y );
    00176       break;
    00177     }
    00178
    00179     // If you get a compilation error here:
    00180     // 1 - you didn't define _WIN32_WINNT as 0x0400 or above.
    00181     // 2 - you are trying to compile VL with a VERY old (unsupported) Visual Studio / Platform SDK.
    00182     case WM_MOUSEWHEEL:
    00183     {
    00184       win->dispatchMouseWheelEvent( GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA );
    00185       break;
    00186     }
    00187
    00188     /*case WM_CLOSE:
    00189     {
    00190       win->dispatchDestroyEvent();
    00191       win->destroyWin32GLWindow();
    00192       break;
    00193     }*/
    00194
    00195     case WM_DESTROY:
    00196     {
    00197       Win32Window::mWinMap.erase(hWnd);
    00198       win->dispatchDestroyEvent();
    00199       win->destroyWin32GLWindow();
    00200       break;
    00201     }
    00202
    00203     case WM_KEYDOWN:
    00204     {
    00205       unsigned short unicode_out = 0;
    00206       vl::EKey       key_out     = Key_None;
    00207       translateKeyEvent(wParam, lParam, unicode_out, key_out);
    00208       win->dispatchKeyPressEvent(unicode_out, key_out);
    00209       break;
    00210     }
    00211
    00212     case WM_KEYUP:
    00213     {
    00214       unsigned short unicode_out = 0;
    00215       vl::EKey       key_out     = Key_None;
    00216       translateKeyEvent(wParam, lParam, unicode_out, key_out);
    00217       win->dispatchKeyReleaseEvent(unicode_out, key_out);
    00218       break;
    00219     }
    00220
    00221     case WM_DROPFILES:
    00222     {
    00223       HDROP hDrop = (HDROP)wParam;
    00224       int count = DragQueryFile(hDrop, 0xFFFFFFFF, 0, 0);
    00225       const int char_count = 1024;
    00226       std::vector<String> files;
    00227       for(int i=0; i<count; ++i)
    00228       {
    00229         wchar_t file_path[char_count];
    00230         memset(file_path, 0, char_count);
    00231         DragQueryFile(hDrop,i,file_path,char_count);
    00232         files.push_back(file_path);
    00233       }
    00234       win->dispatchFileDroppedEvent(files);
    00235       break;
    00236     }
    00237
    00238     // WM_SYSKEYDOWN
    00239     // WM_SYSKEYUP
    00240     // WM_GETICON
    00241     // WM_SETCURSOR
    00242     // WM_SETICON
    00243     // WM_CAPTURECHANGED
    00244     // WM_MOUSEFIRST
    00245   }
    00246
    00247   return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam);
    00248 }
    00249 //-----------------------------------------------------------------------------
    00250 // Win32Window
    00251 //-----------------------------------------------------------------------------
    00252 Win32Window::Win32Window()
    00253 {
    00254   mHWND  = NULL;
    00255   mHDC   = NULL;
    00256   mHGLRC = NULL;
    00257   mMouseDownCount = 0;
    00258
    00259   mStyle   = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    00260   mExStyle = WS_EX_APPWINDOW | WS_EX_ACCEPTFILES;
    00261   mWindowClassName = Win32WindowClassName;
    00262 }
    00263 //-----------------------------------------------------------------------------
    00264 Win32Window::~Win32Window()
    00265 {
    00266   destroyWin32GLWindow();
    00267 }
    00268 //-----------------------------------------------------------------------------
    00269 bool Win32Window::initWin32GLWindow(HWND parent, HGLRC share_context, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height)
    00270 {
    00271   destroyWin32GLWindow();
    00272
    00273   if (!registerClass())
    00274     return false;
    00275
    00276   unsigned style = mStyle & ~(WS_CHILD|WS_OVERLAPPEDWINDOW);;
    00277   style |= parent?WS_CHILD:WS_OVERLAPPEDWINDOW;
    00278
    00279   mHWND = CreateWindowEx(
    00280     mExStyle,
    00281     mWindowClassName,
    00282     L"Visualization Library Win32",
    00283     style,
    00284     x, y, width, height,
    00285     parent, NULL, GetModuleHandle(NULL), NULL);
    00286
    00287   if (initWin32GLContext(share_context, title, fmt, x, y, width, height))
    00288   {
    00289     mWinMap[mHWND] = this;
    00290     return true;
    00291   }
    00292   else
    00293     return false;
    00294 }
    00295 //-----------------------------------------------------------------------------
    00296 Win32Window* Win32Window::getWindow(HWND hWnd)
    00297 {
    00298   std::map< HWND, Win32Window* >::const_iterator it = mWinMap.find(hWnd);
    00299   if (it != mWinMap.end())
    00300     return it->second;
    00301   else
    00302     return NULL;
    00303 }
    00304 //-----------------------------------------------------------------------------
    00305 void Win32Window::destroyWin32GLWindow()
    00306 {
    00307   // wglMakeCurrent(NULL, NULL) not needed
    00308
    00309   if (hwnd())
    00310   {
    00311     bool destroy_win = mWinMap.find(mHWND) != mWinMap.end();
    00312
    00313     // WM_DESTROY must be dispatched while the OpenGL context is still available!
    00314     if (destroy_win)
    00315     {
    00316       DestroyWindow(mHWND);
    00317       mHWND = NULL;
    00318     }
    00319     if (mHGLRC)
    00320     {
    00321       if ( wglDeleteContext(mHGLRC) == FALSE )
    00322       {
    00323         MessageBox(NULL, L"OpenGL context creation failed.\n"
    00324          L"The handle either doesn't specify a valid context or the context is being used by another thread.", L"Visualization Library Error", MB_OK);
    00325       }
    00326       mHGLRC = NULL;
    00327     }
    00328     if (mHDC)
    00329     {
    00330       DeleteDC(mHDC);
    00331       mHDC = NULL;
    00332     }
    00333   }
    00334 }
    00335 //-----------------------------------------------------------------------------
    00336 void vlWin32::dispatchUpdate()
    00337 {
    00338   // iterate over all opengl contexts
    00339   std::map< HWND, Win32Window* > wins = Win32Window::winMap();
    00340   for( std::map< HWND, Win32Window* >::iterator it = wins.begin();
    00341        it != wins.end();
    00342        ++it )
    00343   {
    00344     Win32Window* win = it->second;
    00345     if ( win->continuousUpdate() )
    00346       win->update();
    00347     else
    00348       Sleep(10);
    00349   }
    00350 }
    00351 //-----------------------------------------------------------------------------
    00352 void vlWin32::peekMessage(MSG& msg)
    00353 {
    00354   if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
    00355   {
    00356     if (msg.message != WM_QUIT)
    00357     {
    00358       TranslateMessage(&msg);
    00359       DispatchMessage(&msg);
    00360     }
    00361   }
    00362   else
    00363     dispatchUpdate();
    00364 }
    00365 //-----------------------------------------------------------------------------
    00366 int vlWin32::messageLoop()
    00367 {
    00368   while(!Win32Window::winMap().empty())
    00369   {
    00370     MSG msg = {0,0,0,0,0,0,0};
    00371     peekMessage(msg);
    00372     if (msg.message == WM_QUIT)
    00373       return (int)msg.wParam;
    00374   }
    00375   return 0; /* never reached */
    00376 }
    00377 //-----------------------------------------------------------------------------
    00378 void vlWin32::translateKeyEvent(WPARAM wParam, LPARAM lParam, unsigned short& unicode_out, vl::EKey& key_out)
    00379 {
    00380   // translate non unicode characters
    00381   key_out     = Key_None;
    00382   unicode_out = 0;
    00383
    00384   switch(wParam)
    00385   {
    00386     case VK_CLEAR:    key_out = Key_Clear; break;
    00387     case VK_CONTROL:  key_out = Key_Ctrl; break;
    00388     case VK_LCONTROL: key_out = Key_LeftCtrl; break;
    00389     case VK_RCONTROL: key_out = Key_RightCtrl; break;
    00390     case VK_MENU:     key_out = Key_Alt; break;
    00391     case VK_LMENU:    key_out = Key_LeftAlt; break;
    00392     case VK_RMENU:    key_out = Key_RightAlt; break;
    00393     case VK_SHIFT:    key_out = Key_Shift; break;
    00394     case VK_LSHIFT:   key_out = Key_LeftShift; break;
    00395     case VK_RSHIFT:   key_out = Key_RightShift; break;
    00396     case VK_INSERT:   key_out = Key_Insert; break;
    00397     case VK_DELETE:   key_out = Key_Delete; break;
    00398     case VK_HOME:     key_out = Key_Home; break;
    00399     case VK_END:      key_out = Key_End; break;
    00400     case VK_PRINT:    key_out = Key_Print; break;
    00401     case VK_PAUSE:    key_out = Key_Pause; break;
    00402     case VK_PRIOR:    key_out = Key_PageUp; break;
    00403     case VK_NEXT:     key_out = Key_PageDown; break;
    00404     case VK_LEFT:     key_out = Key_Left; break;
    00405     case VK_RIGHT:    key_out = Key_Right; break;
    00406     case VK_UP:       key_out = Key_Up; break;
    00407     case VK_DOWN:     key_out = Key_Down; break;
    00408     case VK_F1:       key_out = Key_F1; break;
    00409     case VK_F2:       key_out = Key_F2; break;
    00410     case VK_F3:       key_out = Key_F3; break;
    00411     case VK_F4:       key_out = Key_F4; break;
    00412     case VK_F5:       key_out = Key_F5; break;
    00413     case VK_F6:       key_out = Key_F6; break;
    00414     case VK_F7:       key_out = Key_F7; break;
    00415     case VK_F8:       key_out = Key_F8; break;
    00416     case VK_F9:       key_out = Key_F9; break;
    00417     case VK_F10:      key_out = Key_F10; break;
    00418     case VK_F11:      key_out = Key_F11; break;
    00419     case VK_F12:      key_out = Key_F12; break;
    00420
    00421     /*
    00422      * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
    00423      * 0x40 : is unassigned
    00424      * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
    00425      */
    00426
    00427     case L'0': key_out = Key_0; break;
    00428     case L'1': key_out = Key_1; break;
    00429     case L'2': key_out = Key_2; break;
    00430     case L'3': key_out = Key_3; break;
    00431     case L'4': key_out = Key_4; break;
    00432     case L'5': key_out = Key_5; break;
    00433     case L'6': key_out = Key_6; break;
    00434     case L'7': key_out = Key_7; break;
    00435     case L'8': key_out = Key_8; break;
    00436     case L'9': key_out = Key_9; break;
    00437
    00438     case L'A': key_out = Key_A; break;
    00439     case L'B': key_out = Key_B; break;
    00440     case L'C': key_out = Key_C; break;
    00441     case L'D': key_out = Key_D; break;
    00442     case L'E': key_out = Key_E; break;
    00443     case L'F': key_out = Key_F; break;
    00444     case L'G': key_out = Key_G; break;
    00445     case L'H': key_out = Key_H; break;
    00446     case L'I': key_out = Key_I; break;
    00447     case L'J': key_out = Key_J; break;
    00448     case L'K': key_out = Key_K; break;
    00449     case L'L': key_out = Key_L; break;
    00450     case L'M': key_out = Key_M; break;
    00451     case L'N': key_out = Key_N; break;
    00452     case L'O': key_out = Key_O; break;
    00453     case L'P': key_out = Key_P; break;
    00454     case L'Q': key_out = Key_Q; break;
    00455     case L'R': key_out = Key_R; break;
    00456     case L'S': key_out = Key_S; break;
    00457     case L'T': key_out = Key_T; break;
    00458     case L'U': key_out = Key_U; break;
    00459     case L'V': key_out = Key_V; break;
    00460     case L'W': key_out = Key_W; break;
    00461     case L'X': key_out = Key_X; break;
    00462     case L'Y': key_out = Key_Y; break;
    00463     case L'Z': key_out = Key_Z; break;
    00464   }
    00465
    00466   // fill unicode
    00467   BYTE mskeys[256];
    00468   memset( mskeys, 0, sizeof(BYTE)*256 );
    00469   WCHAR unicode[4] = { 0, 0 };
    00470   if ( ToUnicode( (UINT)wParam, (UINT)((lParam >> 16) & 0xFF), mskeys, unicode, 4, 0 ) == 1 )
    00471   {
    00472     unicode_out = unicode[0];
    00473
    00474     // fill key
    00475     switch(unicode_out)
    00476     {
    00477       case L'0': key_out = Key_0; break;
    00478       case L'1': key_out = Key_1; break;
    00479       case L'2': key_out = Key_2; break;
    00480       case L'3': key_out = Key_3; break;
    00481       case L'4': key_out = Key_4; break;
    00482       case L'5': key_out = Key_5; break;
    00483       case L'6': key_out = Key_6; break;
    00484       case L'7': key_out = Key_7; break;
    00485       case L'8': key_out = Key_8; break;
    00486       case L'9': key_out = Key_9; break;
    00487
    00488       case L'A': key_out = Key_A; break;
    00489       case L'B': key_out = Key_B; break;
    00490       case L'C': key_out = Key_C; break;
    00491       case L'D': key_out = Key_D; break;
    00492       case L'E': key_out = Key_E; break;
    00493       case L'F': key_out = Key_F; break;
    00494       case L'G': key_out = Key_G; break;
    00495       case L'H': key_out = Key_H; break;
    00496       case L'I': key_out = Key_I; break;
    00497       case L'J': key_out = Key_J; break;
    00498       case L'K': key_out = Key_K; break;
    00499       case L'L': key_out = Key_L; break;
    00500       case L'M': key_out = Key_M; break;
    00501       case L'N': key_out = Key_N; break;
    00502       case L'O': key_out = Key_O; break;
    00503       case L'P': key_out = Key_P; break;
    00504       case L'Q': key_out = Key_Q; break;
    00505       case L'R': key_out = Key_R; break;
    00506       case L'S': key_out = Key_S; break;
    00507       case L'T': key_out = Key_T; break;
    00508       case L'U': key_out = Key_U; break;
    00509       case L'V': key_out = Key_V; break;
    00510       case L'W': key_out = Key_W; break;
    00511       case L'X': key_out = Key_X; break;
    00512       case L'Y': key_out = Key_Y; break;
    00513       case L'Z': key_out = Key_Z; break;
    00514
    00515       case L'a': key_out = Key_A; break;
    00516       case L'b': key_out = Key_B; break;
    00517       case L'c': key_out = Key_C; break;
    00518       case L'd': key_out = Key_D; break;
    00519       case L'e': key_out = Key_E; break;
    00520       case L'f': key_out = Key_F; break;
    00521       case L'g': key_out = Key_G; break;
    00522       case L'h': key_out = Key_H; break;
    00523       case L'i': key_out = Key_I; break;
    00524       case L'j': key_out = Key_J; break;
    00525       case L'k': key_out = Key_K; break;
    00526       case L'l': key_out = Key_L; break;
    00527       case L'm': key_out = Key_M; break;
    00528       case L'n': key_out = Key_N; break;
    00529       case L'o': key_out = Key_O; break;
    00530       case L'p': key_out = Key_P; break;
    00531       case L'q': key_out = Key_Q; break;
    00532       case L'r': key_out = Key_R; break;
    00533       case L's': key_out = Key_S; break;
    00534       case L't': key_out = Key_T; break;
    00535       case L'u': key_out = Key_U; break;
    00536       case L'v': key_out = Key_V; break;
    00537       case L'w': key_out = Key_W; break;
    00538       case L'x': key_out = Key_X; break;
    00539       case L'y': key_out = Key_Y; break;
    00540       case L'z': key_out = Key_Z; break;
    00541
    00542       case 13: key_out = Key_Return; break;
    00543       case 8: key_out = Key_BackSpace; break;
    00544       case 9: key_out = Key_Tab; break;
    00545       case L' ': key_out = Key_Space; break;
    00546
    00547       case 27: key_out = Key_Escape; break;
    00548       case L'!': key_out = Key_Exclam; break;
    00549       case L'"': key_out = Key_QuoteDbl; break;
    00550       case L'#': key_out = Key_Hash; break;
    00551       case L'$': key_out = Key_Dollar; break;
    00552       case L'&': key_out = Key_Ampersand; break;
    00553       case L'\'': key_out = Key_Quote; break;
    00554       case L'(': key_out = Key_LeftParen; break;
    00555       case L')': key_out = Key_RightParen; break;
    00556       case L'*': key_out = Key_Asterisk; break;
    00557       case L'+': key_out = Key_Plus; break;
    00558       case L',': key_out = Key_Comma; break;
    00559       case L'-': key_out = Key_Minus; break;
    00560       case L'.': key_out = Key_Period; break;
    00561       case L'\\': key_out = Key_Slash; break;
    00562       case L':': key_out = Key_Colon; break;
    00563       case L';': key_out = Key_Semicolon; break;
    00564       case L'<': key_out = Key_Less; break;
    00565       case L'=': key_out = Key_Equal; break;
    00566       case L'>': key_out = Key_Greater; break;
    00567       case L'?': key_out = Key_Question; break;
    00568       case L'@': key_out = Key_At; break;
    00569       case L'[': key_out = Key_LeftBracket; break;
    00570       case L'/': key_out = Key_BackSlash; break;
    00571       case L']': key_out = Key_RightBracket; break;
    00572       case L'|': key_out = Key_Caret; break;
    00573       case L'_': key_out = Key_Underscore; break;
    00574       case L'`': key_out = Key_QuoteLeft; break;
    00575     }
    00576   }
    00577 }
    00578 //-----------------------------------------------------------------------------
    00579 int vlWin32::choosePixelFormat(const vl::OpenGLContextFormat& fmt, bool verbose)
    00580 {
    00581   if (!registerClass())
    00582     return false;
    00583
    00584   // this is true only under Win32
    00585   // VL_CHECK( sizeof(wchar_t) == sizeof(short int) )
    00586
    00587   HWND hWnd = CreateWindowEx(
    00588     WS_EX_APPWINDOW | WS_EX_ACCEPTFILES,
    00589     Win32Window::Win32WindowClassName,
    00590     L"Temp GL Window",
    00591     WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
    00592     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    00593     NULL, NULL, GetModuleHandle(NULL), NULL);
    00594
    00595   if (!hWnd)
    00596   {
    00597     if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not create window.", L"Visualization Library error", MB_OK);
    00598     return -1;
    00599   }
    00600
    00601   HDC hDC = GetDC(hWnd);
    00602   if (!hDC)
    00603   {
    00604     if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not create HDC.", L"Visualization Library error", MB_OK);
    00605     DestroyWindow(hWnd);
    00606     return -1;
    00607   }
    00608
    00609   PIXELFORMATDESCRIPTOR pfd;
    00610   memset(&pfd, 0, sizeof(pfd));
    00611   pfd.nSize           = sizeof(pfd);
    00612   pfd.nVersion        = 1;
    00613   pfd.dwFlags         = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
    00614   pfd.dwFlags         |= fmt.doubleBuffer() ? PFD_DOUBLEBUFFER : 0;
    00615   pfd.dwFlags         |= fmt.stereo() ? PFD_STEREO : 0;
    00616   pfd.iPixelType      = PFD_TYPE_RGBA;
    00617   pfd.cColorBits      = 0;
    00618   pfd.cRedBits        = (BYTE)fmt.rgbaBits().r();
    00619   pfd.cGreenBits      = (BYTE)fmt.rgbaBits().g();
    00620   pfd.cBlueBits       = (BYTE)fmt.rgbaBits().b();
    00621   pfd.cAlphaBits      = (BYTE)fmt.rgbaBits().a();
    00622   pfd.cAccumRedBits   = (BYTE)fmt.accumRGBABits().r();
    00623   pfd.cAccumGreenBits = (BYTE)fmt.accumRGBABits().g();
    00624   pfd.cAccumBlueBits  = (BYTE)fmt.accumRGBABits().b();
    00625   pfd.cAccumAlphaBits = (BYTE)fmt.accumRGBABits().a();
    00626   pfd.cDepthBits      = (BYTE)fmt.depthBufferBits();
    00627   pfd.cStencilBits    = (BYTE)fmt.stencilBufferBits();
    00628   pfd.iLayerType      = PFD_MAIN_PLANE;
    00629
    00630   int pixel_format_index = ChoosePixelFormat(hDC, &pfd);
    00631
    00632   if (pixel_format_index == 0)
    00633   {
    00634     if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not choose temporary format.", L"Visualization Library error", MB_OK);
    00635     DeleteDC(hDC);
    00636     DestroyWindow(hWnd);
    00637     return -1;
    00638   }
    00639
    00640   if (SetPixelFormat(hDC, pixel_format_index, &pfd) == FALSE)
    00641   {
    00642     if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not set temporary format.", L"Visualization Library error", MB_OK);
    00643     DeleteDC(hDC);
    00644     DestroyWindow(hWnd);
    00645     return -1;
    00646   }
    00647
    00648   // OpenGL Rendering Context
    00649   HGLRC hGLRC = wglCreateContext(hDC);
    00650   if (!hGLRC)
    00651   {
    00652     if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not create temporary OpenGL context.", L"Visualization Library error", MB_OK);
    00653     DeleteDC(hDC);
    00654     DestroyWindow(hWnd);
    00655     return -1;
    00656   }
    00657
    00658   wglMakeCurrent(hDC, hGLRC);
    00659
    00660   // init glew for each rendering context
    00661   GLenum err = glewInit();
    00662   if (GLEW_OK != err)
    00663   {
    00664     if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure during GLEW initialization.", L"Visualization Library error", MB_OK);
    00665     DeleteDC(hDC);
    00666     DestroyWindow(hWnd);
    00667     return -1;
    00668   }
    00669
    00670   // if this is not supported we use the current 'pixel_format_index' returned by ChoosePixelFormat above.
    00671
    00672   int samples = 0;
    00673   if(WGLEW_ARB_pixel_format && fmt.multisample())
    00674   {
    00675     float fAttributes[] = { 0, 0 };
    00676     int iAttributes[] =
    00677     {
    00678       // multi sampling
    00679         WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
    00680       WGL_SAMPLES_ARB,        -1, // this is set below
    00681       // generic
    00682         WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
    00683         WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
    00684         WGL_ACCELERATION_ARB,   WGL_FULL_ACCELERATION_ARB,
    00685       // color buffer
    00686       WGL_RED_BITS_ARB,         pfd.cRedBits,
    00687       WGL_GREEN_BITS_ARB,       pfd.cGreenBits,
    00688       WGL_BLUE_BITS_ARB,        pfd.cBlueBits,
    00689       WGL_ALPHA_BITS_ARB,       pfd.cAlphaBits,
    00690       // accumulation buffer
    00691       WGL_ACCUM_RED_BITS_ARB,   pfd.cAccumRedBits,
    00692       WGL_ACCUM_GREEN_BITS_ARB, pfd.cAccumGreenBits,
    00693       WGL_ACCUM_BLUE_BITS_ARB,  pfd.cAccumBlueBits,
    00694       WGL_ACCUM_ALPHA_BITS_ARB, pfd.cAccumAlphaBits,
    00695       // depth buffer
    00696       WGL_DEPTH_BITS_ARB,       pfd.cDepthBits,
    00697       WGL_DOUBLE_BUFFER_ARB,    fmt.doubleBuffer() ? GL_TRUE : GL_FALSE,
    00698       // stencil buffer
    00699       WGL_STENCIL_BITS_ARB,     pfd.cStencilBits,
    00700       // stereo
    00701       WGL_STEREO_ARB,           fmt.stereo() ? GL_TRUE : GL_FALSE,
    00702         0,0
    00703     };
    00704
    00705     for(samples = fmt.multisampleSamples(); samples > 1; samples/=2)
    00706     {
    00707       // sets WGL_SAMPLES_ARB value
    00708       iAttributes[3] = samples;
    00709       pixel_format_index = -1;
    00710       UINT num_formats  = 0;
    00711       if ( wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&pixel_format_index,&num_formats) && num_formats >= 1 )
    00712         break;
    00713       else
    00714         pixel_format_index = -1;
    00715     }
    00716   }
    00717
    00718   // destroy temporary HWND, HDC, HGLRC
    00719   if ( wglDeleteContext(hGLRC) == FALSE )
    00720     if (verbose) MessageBox(NULL, L"Error deleting temporary OpenGL context, wglDeleteContext(hGLRC) failed.", L"Visualization Library error", MB_OK);
    00721   DeleteDC(hDC);
    00722   DestroyWindow(hWnd);
    00723
    00724   if (verbose)
    00725   {
    00726     if(pixel_format_index == -1)
    00727       vl::Log::error("No suitable pixel format found.\n");
    00728     else
    00729     {
    00730       // check the returned pixel format
    00731       #if defined(DEBUG) || !defined(NDEBUG)
    00732         DescribePixelFormat(hDC, pixel_format_index, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
    00733         vl::Log::print(" --- vlWin32::choosePixelFormat() ---\n");
    00734         // This one returns "not supported" even when its supported...
    00735         // vl::Log::print( vl::Say("  OpenGL        = %s\n") << (pfd.dwFlags & PFD_SUPPORT_OPENGL ? "Supported" : "Not supported") );
    00736         vl::Log::print( vl::Say("RGBA Bits     = %n %n %n %n\n") << pfd.cRedBits << pfd.cGreenBits << pfd.cBlueBits << pfd.cAlphaBits);
    00737         vl::Log::print( vl::Say("Depth Bits    = %n\n")  << pfd.cDepthBits );
    00738         vl::Log::print( vl::Say("Stencil Bits  = %n \n") << pfd.cStencilBits);
    00739         vl::Log::print( vl::Say("Double Buffer = %s\n")  << (pfd.dwFlags & PFD_DOUBLEBUFFER ? "Yes" : "No") );
    00740         vl::Log::print( vl::Say("Stereo        = %s\n")  << (pfd.dwFlags & PFD_STEREO ? "Yes" : "No") );
    00741         vl::Log::print( vl::Say("Samples       = %n\n")  << samples );
    00742         vl::Log::print("\n");
    00743       #endif
    00744     }
    00745   }
    00746
    00747   return pixel_format_index;
    00748 }
    00749 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:26.
Permission is granted to use this page to write and publish articles regarding Visualization Library.