00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
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
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
00180
00181
00182 case WM_MOUSEWHEEL:
00183 {
00184 win->dispatchMouseWheelEvent( GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA );
00185 break;
00186 }
00187
00188
00189
00190
00191
00192
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
00239
00240
00241
00242
00243
00244
00245 }
00246
00247 return (LONG)DefWindowProc(hWnd, uMsg, wParam, lParam);
00248 }
00249
00250
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
00308
00309 if (hwnd())
00310 {
00311 bool destroy_win = mWinMap.find(mHWND) != mWinMap.end();
00312
00313
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
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;
00376 }
00377
00378 void vlWin32::translateKeyEvent(WPARAM wParam, LPARAM lParam, unsigned short& unicode_out, vl::EKey& key_out)
00379 {
00380
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
00423
00424
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
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
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
00585
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
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
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
00671
00672 int samples = 0;
00673 if(WGLEW_ARB_pixel_format && fmt.multisample())
00674 {
00675 float fAttributes[] = { 0, 0 };
00676 int iAttributes[] =
00677 {
00678
00679 WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
00680 WGL_SAMPLES_ARB, -1,
00681
00682 WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
00683 WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
00684 WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
00685
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
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
00696 WGL_DEPTH_BITS_ARB, pfd.cDepthBits,
00697 WGL_DOUBLE_BUFFER_ARB, fmt.doubleBuffer() ? GL_TRUE : GL_FALSE,
00698
00699 WGL_STENCIL_BITS_ARB, pfd.cStencilBits,
00700
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
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
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
00731 #if defined(DEBUG) || !defined(NDEBUG)
00732 DescribePixelFormat(hDC, pixel_format_index, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
00733 vl::Log::print(" --- vlWin32::choosePixelFormat() ---\n");
00734
00735
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