bool OculusRift::attachToWindow( const ci::app::WindowRef& window ) { if( ! mHmd ) return false; if( ! isValid( window ) ) return false; if( isDesktopExtended() ) { mImpl = std::unique_ptr<ExtendedModeImpl>( new ExtendedModeImpl{ this } ); } else { mImpl = std::unique_ptr<DirectModeImpl>( new DirectModeImpl{ this } ); } if( ! mImpl->initialize( window ) ) return false; // Override the window's startDraw() and finishDraw() methods, so we can inject our own code. RendererGlRef rendererGl = std::dynamic_pointer_cast<RendererGl>( window->getRenderer() ); if( rendererGl ) { rendererGl->setStartDrawFn( std::bind( &OculusRift::startDrawFn, this, std::placeholders::_1 ) ); rendererGl->setFinishDrawFn( std::bind( &OculusRift::finishDrawFn, this, std::placeholders::_1 ) ); } else { throw std::runtime_error( "OculusRift can only be used in combination with RendererGl." ); } // Connect to the window close event, so we can properly destroy our HMD. window->getSignalClose().connect( std::bind( [&]( ovrHmd hmd ) { assert( hmd == mHmd ); detachFromWindow(); }, mHmd ) ); ovrHmd_ConfigureTracking( mHmd, mTrackingCaps, 0 ); ovrGLConfig cfg; cfg.OGL.Header.API = ovrRenderAPI_OpenGL; cfg.OGL.Header.BackBufferSize = mHmd->Resolution; cfg.OGL.Header.Multisample = 1; // TODO: support multi-sampling #if defined( CINDER_MSW ) cfg.OGL.Window = static_cast<HWND>( window->getNative() ); cfg.OGL.DC = window->getDc(); #endif if( ! ovrHmd_ConfigureRendering( mHmd, &cfg.Config, mDistortionCaps, mHmd->MaxEyeFov, mEyeRenderDesc ) ) { throw std::runtime_error( "Failed to configure rendering." ); } updateHmdSettings(); mWindow = window; return true; }