00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "wglWindow.h"
00020
00021 #include "global.h"
00022 #include "pipe.h"
00023 #include "wglEventHandler.h"
00024 #include "wglPipe.h"
00025
00026 #include <eq/base/log.h>
00027
00028 using namespace std;
00029
00030 namespace eq
00031 {
00032
00033 WGLWindow::WGLWindow( Window* parent )
00034 : WGLWindowIF( parent )
00035 , _wglWindow( 0 )
00036 , _wglPBuffer( 0 )
00037 , _wglContext( 0 )
00038 , _wglDC( 0 )
00039 , _wglDCType( WGL_DC_NONE )
00040 , _wglAffinityDC( 0 )
00041 , _wglEventHandler( 0 )
00042 , _wglNVSwapGroup( 0 )
00043 {
00044
00045 }
00046
00047 WGLWindow::~WGLWindow( )
00048 {
00049
00050 }
00051
00052 void WGLWindow::configExit( )
00053 {
00054 leaveNVSwapBarrier();
00055 configExitFBO();
00056 exitGLEW();
00057
00058 wglMakeCurrent( 0, 0 );
00059
00060 HGLRC context = getWGLContext();
00061 HWND hWnd = getWGLWindowHandle();
00062 HPBUFFERARB hPBuffer = getWGLPBufferHandle();
00063
00064 exitWGLAffinityDC();
00065 setWGLDC( 0, WGL_DC_NONE );
00066 setWGLContext( 0 );
00067 setWGLWindowHandle( 0 );
00068 setWGLPBufferHandle( 0 );
00069
00070 if( context )
00071 wglDeleteContext( context );
00072
00073 if( hWnd )
00074 {
00075
00076 if( getIAttribute( Window::IATTR_HINT_SCREENSAVER ) != ON )
00077 SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, _screenSaverActive,
00078 0, 0 );
00079
00080 char className[256] = {0};
00081 GetClassName( hWnd, className, 255 );
00082 DestroyWindow( hWnd );
00083
00084 if( strlen( className ) > 0 )
00085 UnregisterClass( className, GetModuleHandle( 0 ));
00086 }
00087 if( hPBuffer )
00088 wglDestroyPbufferARB( hPBuffer );
00089
00090 if( getIAttribute( Window::IATTR_HINT_FULLSCREEN ) == ON )
00091 ChangeDisplaySettings( 0, 0 );
00092
00093 EQINFO << "Destroyed WGL context and window" << std::endl;
00094 }
00095
00096 void WGLWindow::makeCurrent() const
00097 {
00098 EQCHECK( wglMakeCurrent( _wglDC, _wglContext ));
00099 WGLWindowIF::makeCurrent();
00100 }
00101
00102 void WGLWindow::swapBuffers()
00103 {
00104 ::SwapBuffers( _wglDC );
00105 }
00106
00107 void WGLWindow::setWGLContext( HGLRC context )
00108 {
00109 _wglContext = context;
00110 }
00111
00112 void WGLWindow::setWGLWindowHandle( HWND handle )
00113 {
00114 if( _wglWindow == handle )
00115 return;
00116
00117 if( _wglWindow )
00118 exitEventHandler();
00119
00120 if( !handle )
00121 {
00122 setWGLDC( 0, WGL_DC_NONE );
00123 _wglWindow = 0;
00124 return;
00125 }
00126
00127 _wglWindow = handle;
00128 setWGLDC( GetDC( handle ), WGL_DC_WINDOW );
00129
00130 initEventHandler();
00131
00132
00133 WINDOWINFO windowInfo;
00134 windowInfo.cbSize = sizeof( windowInfo );
00135
00136 GetWindowInfo( handle, &windowInfo );
00137
00138 PixelViewport pvp;
00139 pvp.x = windowInfo.rcClient.left;
00140 pvp.y = windowInfo.rcClient.top;
00141 pvp.w = windowInfo.rcClient.right - windowInfo.rcClient.left;
00142 pvp.h = windowInfo.rcClient.bottom - windowInfo.rcClient.top;
00143 _window->setPixelViewport( pvp );
00144 }
00145
00146 void WGLWindow::setWGLPBufferHandle( HPBUFFERARB handle )
00147 {
00148 if( _wglPBuffer == handle )
00149 return;
00150
00151 if( !handle )
00152 {
00153 setWGLDC( 0, WGL_DC_NONE );
00154 _wglPBuffer = 0;
00155 return;
00156 }
00157
00158 _wglPBuffer = handle;
00159 setWGLDC( wglGetPbufferDCARB( handle ), WGL_DC_PBUFFER );
00160
00161
00162 int w,h;
00163 wglQueryPbufferARB( handle, WGL_PBUFFER_WIDTH_ARB, &w );
00164 wglQueryPbufferARB( handle, WGL_PBUFFER_HEIGHT_ARB, &h );
00165
00166 PixelViewport pvp;
00167 pvp.w = w;
00168 pvp.h = h;
00169 _window->setPixelViewport( pvp );
00170 }
00171
00172 void WGLWindow::setWGLDC( HDC dc, const WGLDCType type )
00173 {
00174 if( ( type != WGL_DC_NONE && dc == 0 ) ||
00175 ( type == WGL_DC_NONE && dc != 0 ))
00176 {
00177 EQABORT( "Illegal combination of WGL device context and type" );
00178 return;
00179 }
00180
00181 switch( _wglDCType )
00182 {
00183 case WGL_DC_NONE:
00184 break;
00185
00186 case WGL_DC_WINDOW:
00187 EQASSERT( _wglWindow );
00188 EQASSERT( _wglDC );
00189 ReleaseDC( _wglWindow, _wglDC );
00190 break;
00191
00192 case WGL_DC_PBUFFER:
00193 EQASSERT( _wglPBuffer );
00194 EQASSERT( _wglDC );
00195 wglReleasePbufferDCARB( _wglPBuffer, _wglDC );
00196 break;
00197
00198 case WGL_DC_AFFINITY:
00199 EQASSERT( _wglDC );
00200 wglDeleteDCNV( _wglDC );
00201 break;
00202
00203 case WGL_DC_DISPLAY:
00204 EQASSERT( _wglDC );
00205 DeleteDC( _wglDC );
00206 break;
00207
00208 default:
00209 EQUNIMPLEMENTED;
00210 }
00211
00212 _wglDC = dc;
00213 _wglDCType = type;
00214 }
00215
00216
00217
00218
00219 bool WGLWindow::configInit()
00220 {
00221 if( !initWGLAffinityDC( ))
00222 {
00223 _window->setErrorMessage( "Can't create affinity dc" );
00224 return false;
00225 }
00226
00227 int pixelFormat = chooseWGLPixelFormat();
00228 if( pixelFormat == 0 )
00229 {
00230 exitWGLAffinityDC();
00231 return false;
00232 }
00233
00234 if( !configInitWGLDrawable( pixelFormat ))
00235 {
00236 exitWGLAffinityDC();
00237 return false;
00238 }
00239
00240 if( !_wglDC )
00241 {
00242 exitWGLAffinityDC();
00243 setWGLDC( 0, WGL_DC_NONE );
00244 _window->setErrorMessage(
00245 "configInitWGLDrawable did not set a WGL drawable" );
00246 return false;
00247 }
00248
00249 HGLRC context = createWGLContext();
00250 if( !context )
00251 {
00252 configExit();
00253 return false;
00254 }
00255
00256 setWGLContext( context );
00257 makeCurrent();
00258 initGLEW();
00259
00260 if( getIAttribute( Window::IATTR_HINT_SWAPSYNC ) != AUTO )
00261 {
00262 if( WGLEW_EXT_swap_control )
00263 {
00264
00265 const GLint vsync =
00266 ( getIAttribute( Window::IATTR_HINT_SWAPSYNC )==OFF ) ? 0 : 1;
00267 wglSwapIntervalEXT( vsync );
00268 }
00269 else
00270 EQWARN << "WGLEW_EXT_swap_control not supported, ignoring window "
00271 << "swapsync hint" << std::endl;
00272 }
00273
00274 if( getIAttribute( Window::IATTR_HINT_DRAWABLE ) == FBO )
00275 return configInitFBO();
00276
00277 return true;
00278 }
00279
00280 bool WGLWindow::configInitWGLDrawable( int pixelFormat )
00281 {
00282 switch( getIAttribute( Window::IATTR_HINT_DRAWABLE ))
00283 {
00284 case PBUFFER:
00285 return configInitWGLPBuffer( pixelFormat );
00286
00287 case FBO:
00288 return configInitWGLFBO( pixelFormat );
00289
00290 default:
00291 EQWARN << "Unknown drawable type "
00292 << getIAttribute(Window::IATTR_HINT_DRAWABLE )
00293 << ", creating a window" << std::endl;
00294
00295 case UNDEFINED:
00296 case WINDOW:
00297 return configInitWGLWindow( pixelFormat );
00298 }
00299 }
00300
00301 bool WGLWindow::configInitWGLFBO( int pixelFormat )
00302 {
00303 if( _wglAffinityDC )
00304 {
00305
00306
00307 setWGLDC( _wglAffinityDC, WGL_DC_AFFINITY );
00308 _wglAffinityDC = 0;
00309 }
00310 else
00311 {
00312 const PixelViewport pvp( 0, 0, 1, 1 );
00313 _wglWindow = _createWGLWindow( pixelFormat, pvp );
00314 if( !_wglWindow )
00315 return false;
00316
00317 const HDC dc = GetDC( _wglWindow );
00318
00319 if( !dc )
00320 return false;
00321
00322 setWGLDC( dc, WGL_DC_WINDOW );
00323 }
00324
00325 PIXELFORMATDESCRIPTOR pfd = {0};
00326 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00327 pfd.nVersion = 1;
00328
00329 DescribePixelFormat( _wglDC, pixelFormat, sizeof( pfd ), &pfd );
00330 if( !SetPixelFormat( _wglDC, pixelFormat, &pfd ))
00331 {
00332 _window->setErrorMessage( "Can't set window pixel format: " +
00333 base::getErrorString( GetLastError( )));
00334 return false;
00335 }
00336
00337 return true;
00338 }
00339
00340 bool WGLWindow::configInitWGLWindow( int pixelFormat )
00341 {
00342
00343 const PixelViewport& pvp = _window->getPixelViewport();
00344 HWND hWnd = _createWGLWindow( pixelFormat, pvp );
00345 if( !hWnd )
00346 return false;
00347
00348 HDC windowDC = GetDC( hWnd );
00349
00350 PIXELFORMATDESCRIPTOR pfd = {0};
00351 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00352 pfd.nVersion = 1;
00353
00354 DescribePixelFormat( _wglAffinityDC ? _wglAffinityDC : windowDC,
00355 pixelFormat, sizeof(pfd), &pfd );
00356 if( !SetPixelFormat( windowDC, pixelFormat, &pfd ))
00357 {
00358 ReleaseDC( hWnd, windowDC );
00359 _window->setErrorMessage( "Can't set window pixel format: " +
00360 base::getErrorString( GetLastError( )));
00361 return false;
00362 }
00363 ReleaseDC( hWnd, windowDC );
00364
00365 ShowWindow( hWnd, SW_SHOW );
00366 UpdateWindow( hWnd );
00367
00368 if( getIAttribute( Window::IATTR_HINT_SCREENSAVER ) != ON )
00369 {
00370
00371 SystemParametersInfo( SPI_GETSCREENSAVEACTIVE, 0, &_screenSaverActive,
00372 0 );
00373 SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, FALSE, 0, 0 );
00374
00375
00376 PostMessage( HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, -1 );
00377 }
00378
00379 setWGLWindowHandle( hWnd );
00380 return true;
00381 }
00382
00383 HWND WGLWindow::_createWGLWindow( int pixelFormat, const PixelViewport& pvp )
00384 {
00385
00386 const std::string& name = _window->getName();
00387
00388 std::ostringstream className;
00389 className << (name.empty() ? std::string("Equalizer") : name)
00390 << (void*)this;
00391 const std::string& classStr = className.str();
00392
00393 HINSTANCE instance = GetModuleHandle( 0 );
00394 WNDCLASS wc = { 0 };
00395 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
00396 wc.lpfnWndProc = DefWindowProc;
00397 wc.hInstance = instance;
00398 wc.hIcon = LoadIcon( 0, IDI_WINLOGO );
00399 wc.hCursor = LoadCursor( 0, IDC_ARROW );
00400 wc.lpszClassName = classStr.c_str();
00401
00402 if( !RegisterClass( &wc ))
00403 {
00404 _window->setErrorMessage( "Can't register window class: " +
00405 base::getLastErrorString( ));
00406 return false;
00407 }
00408
00409
00410 DWORD windowStyleEx = WS_EX_APPWINDOW;
00411 DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW;
00412
00413 if( getIAttribute( Window::IATTR_HINT_DECORATION ) == OFF )
00414 windowStyle = WS_POPUP;
00415
00416 if( getIAttribute( Window::IATTR_HINT_FULLSCREEN ) == ON )
00417 {
00418 windowStyleEx |= WS_EX_TOPMOST;
00419
00420 DEVMODE deviceMode = {0};
00421 deviceMode.dmSize = sizeof( DEVMODE );
00422 EnumDisplaySettings( 0, ENUM_CURRENT_SETTINGS, &deviceMode );
00423
00424 if( ChangeDisplaySettings( &deviceMode, CDS_FULLSCREEN ) !=
00425 DISP_CHANGE_SUCCESSFUL )
00426 {
00427 _window->setErrorMessage( "Can't switch to fullscreen mode: " +
00428 base::getErrorString( GetLastError( )));
00429 return false;
00430 }
00431 windowStyle = WS_POPUP | WS_MAXIMIZE;
00432 }
00433
00434
00435 RECT rect;
00436 rect.left = pvp.x;
00437 rect.top = pvp.y;
00438 rect.right = pvp.x + pvp.w;
00439 rect.bottom = pvp.y + pvp.h;
00440 AdjustWindowRectEx( &rect, windowStyle, FALSE, windowStyleEx );
00441
00442 HWND hWnd = CreateWindowEx( windowStyleEx,
00443 wc.lpszClassName,
00444 name.empty() ? "Equalizer" : name.c_str(),
00445 windowStyle, rect.left, rect.top,
00446 rect.right - rect.left, rect.bottom - rect.top,
00447 0, 0,
00448 instance, 0 );
00449 if( !hWnd )
00450 {
00451 _window->setErrorMessage( "Can't create window: " );
00452 return false;
00453 }
00454
00455 return hWnd;
00456 }
00457
00458 bool WGLWindow::configInitWGLPBuffer( int pixelFormat )
00459 {
00460 if( !WGLEW_ARB_pbuffer )
00461 {
00462 _window->setErrorMessage( "WGL_ARB_pbuffer not supported" );
00463 return false;
00464 }
00465
00466 const eq::PixelViewport& pvp = _window->getPixelViewport();
00467 EQASSERT( pvp.isValid( ));
00468
00469 const HDC displayDC = createWGLDisplayDC();
00470 if( !displayDC )
00471 return false;
00472
00473 const HDC dc = _wglAffinityDC ? _wglAffinityDC : displayDC;
00474 const int attributes[] = { WGL_PBUFFER_LARGEST_ARB, TRUE, 0 };
00475
00476 HPBUFFERARB pBuffer = wglCreatePbufferARB( dc, pixelFormat, pvp.w, pvp.h,
00477 attributes );
00478 DeleteDC( displayDC );
00479 if( !pBuffer )
00480 {
00481 _window->setErrorMessage( "Can't create PBuffer: " +
00482 base::getErrorString( GetLastError( )));
00483 return false;
00484 }
00485
00486 setWGLPBufferHandle( pBuffer );
00487 return true;
00488 }
00489
00490 void WGLWindow::exitWGLAffinityDC()
00491 {
00492 if( !_wglAffinityDC )
00493 return;
00494
00495 wglDeleteDCNV( _wglAffinityDC );
00496 _wglAffinityDC = 0;
00497 }
00498
00499 bool WGLWindow::initWGLAffinityDC()
00500 {
00501
00502
00503
00504 Pipe* pipe = getPipe();
00505 EQASSERT( pipe );
00506 EQASSERT( pipe->getOSPipe( ));
00507 EQASSERT( dynamic_cast< WGLPipe* >( pipe->getOSPipe( )));
00508
00509 WGLPipe* osPipe = static_cast< WGLPipe* >( pipe->getOSPipe( ));
00510
00511 return osPipe->createWGLAffinityDC( _wglAffinityDC );
00512 }
00513
00514 HDC WGLWindow::getWGLAffinityDC()
00515 {
00516 if( _wglAffinityDC )
00517 return _wglAffinityDC;
00518 if( _wglDCType == WGL_DC_AFFINITY )
00519 return _wglDC;
00520 return 0;
00521 }
00522
00523 HDC WGLWindow::createWGLDisplayDC()
00524 {
00525 Pipe* pipe = getPipe();
00526 EQASSERT( pipe );
00527 EQASSERT( pipe->getOSPipe( ));
00528 EQASSERT( dynamic_cast< WGLPipe* >( pipe->getOSPipe( )));
00529
00530 WGLPipe* osPipe = static_cast< WGLPipe* >( pipe->getOSPipe( ));
00531
00532 return osPipe->createWGLDisplayDC();
00533 }
00534
00535 int WGLWindow::chooseWGLPixelFormat()
00536 {
00537 EQASSERT( WGLEW_ARB_pixel_format );
00538
00539 std::vector< int > attributes;
00540 attributes.push_back( WGL_SUPPORT_OPENGL_ARB );
00541 attributes.push_back( 1 );
00542 attributes.push_back( WGL_ACCELERATION_ARB );
00543 attributes.push_back( WGL_FULL_ACCELERATION_ARB );
00544
00545 const int colorSize = getIAttribute( Window::IATTR_PLANES_COLOR );
00546 const int colorBits = colorSize>0 ? colorSize : 8;
00547
00548 if( colorSize > 0 || colorSize == AUTO ||
00549 getIAttribute( Window::IATTR_HINT_DRAWABLE ) == FBO )
00550 {
00551 attributes.push_back( WGL_COLOR_BITS_ARB );
00552 attributes.push_back( colorBits * 3 );
00553 }
00554 else if ( colorSize == RGBA16F || colorSize == RGBA32F )
00555 {
00556 const int colorBits = colorSize == RGBA16F ? 16 : 32;
00557
00558 if ( !WGLEW_ARB_pixel_format_float )
00559 {
00560 _window->setErrorMessage( "Floating-point framebuffer unsupported" );
00561 return 0;
00562 }
00563 attributes.push_back( WGL_PIXEL_TYPE_ARB );
00564 attributes.push_back( WGL_TYPE_RGBA_FLOAT_ARB );
00565
00566 attributes.push_back( WGL_COLOR_BITS_ARB );
00567 attributes.push_back( colorBits * 4);
00568 }
00569
00570 const int alphaSize = getIAttribute( Window::IATTR_PLANES_ALPHA );
00571 if( alphaSize > 0 || alphaSize == AUTO )
00572 {
00573 attributes.push_back( WGL_ALPHA_BITS_ARB );
00574 attributes.push_back( alphaSize>0 ? alphaSize : 8 );
00575 }
00576
00577 const int depthSize = getIAttribute( Window::IATTR_PLANES_DEPTH );
00578 if( depthSize > 0 || depthSize == AUTO )
00579 {
00580 attributes.push_back( WGL_DEPTH_BITS_ARB );
00581 attributes.push_back( depthSize>0 ? depthSize : 24 );
00582 }
00583
00584 const int stencilSize = getIAttribute( Window::IATTR_PLANES_STENCIL );
00585 if( stencilSize >0 || stencilSize == AUTO )
00586 {
00587 attributes.push_back( WGL_STENCIL_BITS_ARB );
00588 attributes.push_back( stencilSize>0 ? stencilSize : 1 );
00589 }
00590
00591 const int accumSize = getIAttribute( Window::IATTR_PLANES_ACCUM );
00592 const int accumAlpha = getIAttribute( Window::IATTR_PLANES_ACCUM_ALPHA );
00593 if( accumSize >= 0 )
00594 {
00595 attributes.push_back( WGL_ACCUM_RED_BITS_ARB );
00596 attributes.push_back( accumSize );
00597 attributes.push_back( WGL_ACCUM_GREEN_BITS_ARB );
00598 attributes.push_back( accumSize );
00599 attributes.push_back( WGL_ACCUM_BLUE_BITS_ARB );
00600 attributes.push_back( accumSize );
00601 attributes.push_back( WGL_ACCUM_ALPHA_BITS_ARB );
00602 attributes.push_back( accumAlpha >= 0 ? accumAlpha : accumSize );
00603 }
00604 else if( accumAlpha >= 0 )
00605 {
00606 attributes.push_back( WGL_ACCUM_ALPHA_BITS_ARB );
00607 attributes.push_back( accumAlpha );
00608 }
00609
00610 const int samplesSize = getIAttribute( Window::IATTR_PLANES_SAMPLES );
00611 if( samplesSize >= 0 )
00612 {
00613 if( WGLEW_ARB_multisample )
00614 {
00615 attributes.push_back( WGL_SAMPLE_BUFFERS_ARB );
00616 attributes.push_back( 1 );
00617 attributes.push_back( WGL_SAMPLES_ARB );
00618 attributes.push_back( samplesSize );
00619 }
00620 else
00621 EQWARN << "WGLEW_ARB_multisample not supported, ignoring samples "
00622 << "attribute" << std::endl;
00623 }
00624
00625 if( getIAttribute( Window::IATTR_HINT_STEREO ) == ON ||
00626 ( getIAttribute( Window::IATTR_HINT_STEREO ) == AUTO &&
00627 getIAttribute( Window::IATTR_HINT_DRAWABLE ) == WINDOW ))
00628 {
00629 attributes.push_back( WGL_STEREO_ARB );
00630 attributes.push_back( 1 );
00631 }
00632
00633 if( getIAttribute( Window::IATTR_HINT_DOUBLEBUFFER ) == ON ||
00634 ( getIAttribute( Window::IATTR_HINT_DOUBLEBUFFER ) == AUTO &&
00635 getIAttribute( Window::IATTR_HINT_DRAWABLE ) == WINDOW ))
00636 {
00637 attributes.push_back( WGL_DOUBLE_BUFFER_ARB );
00638 attributes.push_back( 1 );
00639 }
00640
00641 if( getIAttribute( Window::IATTR_HINT_DRAWABLE ) == PBUFFER &&
00642 WGLEW_ARB_pbuffer )
00643 {
00644 attributes.push_back( WGL_DRAW_TO_PBUFFER_ARB );
00645 attributes.push_back( 1 );
00646 }
00647 else
00648 {
00649 attributes.push_back( WGL_DRAW_TO_WINDOW_ARB );
00650 attributes.push_back( 1 );
00651 }
00652
00653 attributes.push_back( 0 );
00654
00655
00656 std::vector<int> backoffAttributes;
00657 if( getIAttribute( Window::IATTR_HINT_DRAWABLE ) == WINDOW )
00658 {
00659 if( getIAttribute( Window::IATTR_HINT_DOUBLEBUFFER ) == AUTO )
00660 backoffAttributes.push_back( WGL_DOUBLE_BUFFER_ARB );
00661
00662 if( getIAttribute( Window::IATTR_HINT_STEREO ) == AUTO )
00663 backoffAttributes.push_back( WGL_STEREO_ARB );
00664 }
00665
00666 if( stencilSize == AUTO )
00667 backoffAttributes.push_back( WGL_STENCIL_BITS_ARB );
00668
00669 HDC screenDC = GetDC( 0 );
00670 HDC pfDC = _wglAffinityDC ? _wglAffinityDC : screenDC;
00671 int pixelFormat = 0;
00672
00673 while( true )
00674 {
00675 UINT nFormats = 0;
00676 if( !wglChoosePixelFormatARB( pfDC, &attributes[0], 0, 1,
00677 &pixelFormat, &nFormats ))
00678 {
00679 EQWARN << "wglChoosePixelFormat failed: "
00680 << base::getLastErrorString() << std::endl;
00681 }
00682
00683 if( (pixelFormat && nFormats > 0) ||
00684 backoffAttributes.empty( ))
00685
00686 break;
00687
00688
00689 const int attribute = backoffAttributes.back();
00690 backoffAttributes.pop_back();
00691
00692 std::vector<GLint>::iterator iter = find( attributes.begin(),
00693 attributes.end(), attribute );
00694 EQASSERT( iter != attributes.end( ));
00695
00696 attributes.erase( iter, iter+2 );
00697
00698 }
00699
00700 ReleaseDC( 0, screenDC );
00701
00702 if( pixelFormat == 0 )
00703 {
00704 _window->setErrorMessage( "Can't find matching pixel format: " +
00705 base::getErrorString( GetLastError( )));
00706 return 0;
00707 }
00708
00709 if( _wglAffinityDC )
00710 {
00711 PIXELFORMATDESCRIPTOR pfd = {0};
00712 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00713 pfd.nVersion = 1;
00714
00715 DescribePixelFormat( _wglAffinityDC, pixelFormat, sizeof(pfd), &pfd );
00716 if( !SetPixelFormat( _wglAffinityDC, pixelFormat, &pfd ))
00717 {
00718 _window->setErrorMessage( "Can't set device pixel format: " +
00719 base::getErrorString( GetLastError( )));
00720 return 0;
00721 }
00722 }
00723
00724 return pixelFormat;
00725 }
00726
00727 HGLRC WGLWindow::createWGLContext()
00728 {
00729 EQASSERT( _wglDC );
00730
00731
00732 HGLRC context = wglCreateContext(_wglAffinityDC ? _wglAffinityDC : _wglDC );
00733 if( !context )
00734 {
00735 _window->setErrorMessage( "Can't create OpenGL context: " +
00736 base::getErrorString( GetLastError( )));
00737 return 0;
00738 }
00739
00740
00741 const Window* shareWindow = _window->getSharedContextWindow();
00742 if( shareWindow )
00743 {
00744 const OSWindow* shareOSWindow = shareWindow->getOSWindow();
00745
00746 EQASSERT( dynamic_cast< const WGLWindow* >( shareOSWindow ));
00747 const WGLWindow* shareWGLWindow = static_cast< const WGLWindow* >(
00748 shareOSWindow );
00749 HGLRC shareCtx = shareWGLWindow->getWGLContext();
00750
00751 if( shareCtx && !wglShareLists( shareCtx, context ))
00752 EQWARN << "Context sharing failed: " << base::getLastErrorString()
00753 << endl;
00754 }
00755
00756 return context;
00757 }
00758
00759 void WGLWindow::initEventHandler()
00760 {
00761 EQASSERT( !_wglEventHandler );
00762 _wglEventHandler = new WGLEventHandler( this );
00763 }
00764
00765 void WGLWindow::exitEventHandler()
00766 {
00767 delete _wglEventHandler;
00768 _wglEventHandler = 0;
00769 }
00770
00771 bool WGLWindow::processEvent( const WGLWindowEvent& event )
00772 {
00773 if( event.type == Event::WINDOW_EXPOSE )
00774 {
00775 EQASSERT( _wglWindow );
00776
00777
00778 PAINTSTRUCT ps;
00779 BeginPaint( _wglWindow, &ps );
00780 EndPaint( _wglWindow, &ps );
00781 }
00782
00783 return WGLWindowIF::processEvent( event );
00784 }
00785
00786 void WGLWindow::joinNVSwapBarrier( const uint32_t group, const uint32_t barrier)
00787 {
00788 if( group == 0 && barrier == 0 )
00789 return;
00790
00791 if( !WGLEW_NV_swap_group )
00792 {
00793 EQWARN << "NV Swap group extension not supported" << endl;
00794 return;
00795 }
00796
00797 const HDC dc = _wglAffinityDC ? _wglAffinityDC : _wglDC;
00798
00799 uint32_t maxBarrier = 0;
00800 uint32_t maxGroup = 0;
00801 wglQueryMaxSwapGroupsNV( dc, &maxGroup, &maxBarrier );
00802
00803 if( group > maxGroup )
00804 {
00805 EQWARN << "Failed to initialize WGL_NV_swap_group: requested group "
00806 << group << " greater than maxGroups (" << maxGroup << ")"
00807 << std::endl;
00808 return;
00809 }
00810
00811 if( barrier > maxBarrier )
00812 {
00813 EQWARN << "Failed to initialize WGL_NV_swap_group: requested barrier "
00814 << barrier << "greater than maxBarriers (" << maxBarrier << ")"
00815 << std::endl;
00816 return;
00817 }
00818
00819 if( !wglJoinSwapGroupNV( dc, group ))
00820 {
00821 EQWARN << "Failed to join swap group " << group << std::endl;
00822 return;
00823 }
00824 _wglNVSwapGroup = group;
00825
00826 if( !wglBindSwapBarrierNV( group, barrier ))
00827 {
00828 EQWARN << "Failed to bind swap barrier " << barrier << std::endl;
00829 return;
00830 }
00831
00832 EQINFO << "Joined swap group " << group << " and barrier " << barrier
00833 << std::endl;
00834 }
00835
00836 void WGLWindow::leaveNVSwapBarrier()
00837 {
00838 if( _wglNVSwapGroup == 0 )
00839 return;
00840
00841 const HDC dc = _wglAffinityDC ? _wglAffinityDC : _wglDC;
00842
00843 wglBindSwapBarrierNV( _wglNVSwapGroup, 0 );
00844 wglJoinSwapGroupNV( dc, 0 );
00845
00846 _wglNVSwapGroup = 0;
00847 }
00848 }