void TransparencyManagerOITClosestArray::layersCountChanged()
 {
   if ( getShaderManager() )
   {
     unsigned int lc = getLayersCount();
     getShaderManager()->updateFragmentParameter( std::string( "sys_OITDepth" ), dp::rix::core::ContainerDataRaw( 0, &lc, sizeof(unsigned int) ) );
   }
 }
Ejemplo n.º 2
0
        SgRdrBackend::SgRdrBackend( const std::string& rendererName
                                  , const std::vector<std::string>& options )
        {
          // Initialize freeglut
          char* dummyChar[] = {"nothing"};
          int dummyInt = 0;
          glutInit(&dummyInt, nullptr);

          // Parse options
          options::options_description od("Usage: DPTApp");
          od.add_options()
            ( "renderengine", options::value<std::string>(), "The renderengine to use" )
            ( "shadermanager", options::value<std::string>(), "The shader manager to use" )
            ( "cullingengine", options::value<std::string>(), "The culling engine to use" )
            ;

          options::basic_parsed_options<char> parsedOpts = options::basic_command_line_parser<char>( options ).options( od ).allow_unregistered().run();

          options::variables_map optsMap;
          options::store( parsedOpts, optsMap );

          std::string renderEngine = optsMap["renderengine"].as<std::string>();
          std::string cullingEngine = optsMap["cullingengine"].as<std::string>();
          std::string shaderManager = optsMap["shadermanager"].as<std::string>();


          bool disableCulling = false;

          // Create the renderer as specified
          dp::culling::Mode cullingMode = dp::culling::Mode::AUTO;

          if ( cullingEngine == "cpu" )
          {
            cullingMode = dp::culling::Mode::CPU;
          }
          else if ( cullingEngine == "gl_compute" )
          {
            cullingMode = dp::culling::Mode::OPENGL_COMPUTE;
          }
          else if ( cullingEngine == "cuda" )
          {
            cullingMode = dp::culling::Mode::CUDA;
          }
          else if ( cullingEngine == "none" )
          {
            disableCulling = true;
          }
          else if ( cullingEngine != "auto" )
          {
            std::cerr << "unknown culling engine, turning culling off" << std::endl;
            disableCulling = true;
          }


          dp::fx::Manager smt = getShaderManager( shaderManager );

          //The chosen renderer takes precedence over the chosen shader manager.
          if( rendererName == "RiXGL.rdr" )
          {
            m_renderer = dp::sg::renderer::rix::gl::SceneRenderer::create
            (   renderEngine.c_str()
              , smt
              , cullingMode
            );
          }
          else
          {
            DP_ASSERT(!"Unknown Renderer");
          }

          m_renderer->setCullingEnabled( !disableCulling );
        }
Ejemplo n.º 3
0
int runApp( options::variables_map const& opts )
{
  // Create renderer
  std::string cullingEngine = opts["cullingengine"].as<std::string>();
  dp::culling::Mode cullingMode = dp::culling::Mode::AUTO;
  if ( cullingEngine == "cpu" )
  {
    cullingMode = dp::culling::Mode::CPU;
  }
  else if ( cullingEngine == "gl_compute" )
  {
    cullingMode = dp::culling::Mode::OPENGL_COMPUTE;
  }
  else if ( cullingEngine == "cuda" )
  {
    cullingMode = dp::culling::Mode::CUDA;
  }
  else if ( cullingEngine != "auto" )
  {
    std::cerr << "unknown culling engine, abort" << std::endl;
    return -1;
  }

  CFRPipelineSharedPtr renderer = CFRPipeline::create
  (
      opts["renderengine"].as<std::string>().c_str()
    , getShaderManager( opts["shadermanager"].as<std::string>() )
    , cullingMode
  );
  //renderer->setCullingEnabled( opts["culling"].as<bool>() );

  dp::sg::ui::ViewStateSharedPtr viewStateHandle = loadScene( opts["filename"].as<std::string>() );

  g_viewState = viewStateHandle;

  if ( opts.count("replace") )
  {
    // process replacements
    std::vector< std::string> replacementStrings = opts["replace"].as< std::vector<std::string > >();
    dp::sg::algorithm::ReplacementMapNames replacements;
    for ( std::vector<std::string>::iterator it = replacementStrings.begin(); it != replacementStrings.end(); ++it )
    {
      size_t equalChar = it->find_first_of(':');
      if ( equalChar != std::string::npos && equalChar < it->size() - 1)
      {
        std::string str1 = it->substr( 0, equalChar );
        std::string str2 = it->substr( equalChar + 1, it->size() - equalChar - 1);
        replacements[str1] = str2;
      }
      else
      {
        std::cerr << "invalid replacement token: " << *it << std::endl;
      }
    }
    dp::sg::algorithm::replacePipelineData( viewStateHandle->getScene(), replacements );
  }

  if ( !opts["statistics"].empty() )
  {
    showStatistics( viewStateHandle );
  }

  dp::sg::ui::setupDefaultViewState( viewStateHandle );

  if ( !opts["combineVertexAttributes"].empty() )
  {
    combineVertexAttributes( viewStateHandle );
  }

  {
    // Replace MatrixCamera by PerspectiveCamera to get all manipulator features
    if ( viewStateHandle->getCamera()->getObjectCode() == dp::sg::core::ObjectCode::MATRIX_CAMERA )
    {
      dp::sg::core::PerspectiveCameraSharedPtr perspectiveCamera = dp::sg::core::PerspectiveCamera::create();
      perspectiveCamera->setOrientation(viewStateHandle->getCamera()->getOrientation());
      perspectiveCamera->setDirection((viewStateHandle->getCamera()->getDirection()));
      perspectiveCamera->setPosition(viewStateHandle->getCamera()->getPosition());

      viewStateHandle->setAutoClipPlanes(true);
      viewStateHandle->setCamera(perspectiveCamera);
    }
  }

  if ( !opts["headlight"].empty() )
  {
    // TODO is this still a bug?
    // Bug 914976 containsLight() doesn't find lights in the scene. Force adding the headlight anyway when the user specified it.
    if ( viewStateHandle /* && viewStateHandle->getScene() && !SceneLock( viewStateHandle->getScene() )->containsLight() */
      && viewStateHandle->getCamera() && ( viewStateHandle->getCamera()->getNumberOfHeadLights() == 0 ) )
    {
      // Use the defaults! Note that LightSource ambientColor is black.
      viewStateHandle->getCamera()->addHeadLight( dp::sg::core::createStandardPointLight() );
    }
  }

  // Setup default OpenGL format descriptor
  // We need to create a default format first to be able to check if a stereo pixelformat is available later.
  // (An unfortunate RenderContextFormat.isAvailable() interface due to Linux.)
  dp::gl::RenderContextFormat format;

  // create a widget which shows the scene
  //dp::sg::ui::glut::SceneRendererWidget w( format );
  GLUTMinimalCFR w;

  // TODO format is not yet supported
#if 0
  if (stereo)
  {
    format.setStereo( stereo );
    if ( !w.setFormat( format ) )  // This automatically checks if the format is available.
    {
      std::cout << "Warning: No stereo pixelformat available." << std::endl;
    }
  }
#endif

  viewStateHandle->setAutoClipPlanes( opts["autoclipplanes"].as<bool>() );

  w.setViewState( viewStateHandle );
  w.setSceneRenderer( renderer );
//always on  if ( !opts["continuous"].empty() )
  {
    w.setContinuousUpdate( true );
    w.setShowFrameRate( true );
  }

  if( opts["frames"].as<int>() != -1 )
  {
    w.setNumberOfFrames( opts["frames"].as<int>() );
  }
  w.setDuration( opts["duration"].as<double>() );

  w.setWindowSize( 1280, 720 );
  //w.show();

  // Keep only once reference to the renderer in the widget. This is necessary since the OpenGL resources
  // used by the renderer must be deleted before the window gets destroyed.
  renderer.reset();

  g_viewState->getCamera()->setPosition(dp::math::Vec3f(0.0f, 0.0f, 5.0f));
  setLights();

  glutMainLoop();

  return w.getExitCode();
}
Ejemplo n.º 4
0
int runApp( options::variables_map const& opts )
{
  // Create renderer

  dp::sg::renderer::rix::gl::SceneRendererSharedPtr renderer = dp::sg::renderer::rix::gl::SceneRenderer::create
  ( 
      opts["renderengine"].as<std::string>().c_str()
    , getShaderManager( opts["shadermanager"].as<std::string>() )
  );
  renderer->setCullingEnabled( false );

  dp::math::Vec3f offset( 0.0f, 0.0f, 0.0f );
  std::vector<float> resolution = opts["resolution"].as<std::vector<float> >();
  if ( !opts["offset"].empty() )
  {
    std::vector<float> ov = opts["resolution"].as<std::vector<float> >();
    if ( ov.size() == 3 )
    {
      offset[0] = ov[0];
      offset[1] = ov[1];
      offset[2] = ov[2];
    }
    else
    {
      std::cerr << "resolution argument count is wrong, skipping." << std::endl;
    }
  }

  dp::sg::ui::ViewStateSharedPtr viewStateHandle = loadTerrain( opts["heightmap"].as<std::string>(), opts["texturemap"].as<std::string>(), dp::math::Vec3f(resolution[0], resolution[1], resolution[2]), offset );

  dp::sg::ui::setupDefaultViewState( viewStateHandle );

  viewStateHandle->setAutoClipPlanes(true);

  if ( !opts["headlight"].empty() )
  {
    if ( viewStateHandle && viewStateHandle->getScene() && !dp::sg::algorithm::containsLight( viewStateHandle->getScene() )
      && viewStateHandle->getCamera() && ( viewStateHandle->getCamera()->getNumberOfHeadLights() == 0 ) )
    {
      // Use the defaults! Note that LightSource ambientColor is black.
      viewStateHandle->getCamera()->addHeadLight( dp::sg::core::createStandardPointLight() );
    }
  }

  // Setup default OpenGL format descriptor
  // We need to create a default format first to be able to check if a stereo pixelformat is available later.
  // (An unfortunate RenderContextFormat.isAvailable() interface due to Linux.)
  dp::gl::RenderContextFormat format;

  // create a widget which shows the scene
  //dp::sg::ui::glut::SceneRendererWidget w( format );
  TerrainRenderer w;

  // TODO format is not yet supported
#if 0
  if (stereo)
  {
    format.setStereo( stereo );
    if ( !w.setFormat( format ) )  // This automatically checks if the format is available.
    {
      std::cout << "Warning: No stereo pixelformat available." << std::endl;
    }
  }
#endif

  viewStateHandle->setAutoClipPlanes( opts["autoclipplanes"].as<bool>() );

  //w.setNumberOfFrames( frames );
  w.setViewState( viewStateHandle );
  w.setSceneRenderer( renderer );
  if ( !opts["continuous"].empty() )
  {
    w.setContinuousUpdate( true );
    w.setShowFrameRate( true );
  }

  if( opts["frames"].as<int>() != -1 )
  {
    w.setNumberOfFrames( opts["frames"].as<int>() );
  }
  w.setDuration( opts["duration"].as<double>() );
  
  w.setWindowSize( 640, 480 );
  //w.show();

  // Keep only once reference to the renderer in the widget. This is necessary since the OpenGL resources
  // used by the renderer must be deleted before the window gets destroyed.
  renderer.reset(); 

  glutMainLoop();

  return w.getExitCode();
}
Ejemplo n.º 5
0
int runApp( options::variables_map const& opts )
{
  // Create renderer
  std::string cullingEngine = opts["cullingengine"].as<std::string>();
  dp::culling::Mode cullingMode = dp::culling::MODE_AUTO;
  if ( cullingEngine == "cpu" )
  {
    cullingMode = dp::culling::MODE_CPU;
  }
  else if ( cullingEngine == "gl_compute" )
  {
    cullingMode = dp::culling::MODE_OPENGL_COMPUTE;
  }
  else if ( cullingEngine == "cuda" )
  {
    cullingMode = dp::culling::MODE_CUDA;
  }
  else if ( cullingEngine != "auto" )
  {
    std::cerr << "unknown culling engine, abort" << std::endl;
    return -1;
  }

  dp::sg::renderer::rix::gl::SceneRendererSharedPtr renderer = dp::sg::renderer::rix::gl::SceneRenderer::create
  (
      opts["renderengine"].as<std::string>().c_str()
    , getShaderManager( opts["shadermanager"].as<std::string>() )
    , cullingMode
    //, dp::sg::renderer::rix::gl::TM_NONE
  );
  renderer->setCullingEnabled( opts["culling"].as<bool>() );

  if ( !opts["effectlibrary"].empty() )
  {
    dp::fx::EffectLibrary::instance()->loadEffects( opts["effectlibrary"].as<std::string>() );
  }

  dp::sg::ui::ViewStateSharedPtr viewState = loadScene( opts["filename"].as<std::string>() );

  if ( opts.count("replace") )
  {
    // process replacements
    std::vector< std::string> replacementStrings = opts["replace"].as< std::vector<std::string > >();
    dp::sg::algorithm::ReplacementMapNames replacements;
    for ( std::vector<std::string>::iterator it = replacementStrings.begin(); it != replacementStrings.end(); ++it )
    {
      size_t equalChar = it->find_first_of(':');
      if ( equalChar != std::string::npos && equalChar < it->size() - 1)
      {
        std::string str1 = it->substr( 0, equalChar );
        std::string str2 = it->substr( equalChar + 1, it->size() - equalChar - 1);
        replacements[str1] = str2;
      }
      else
      {
        std::cerr << "invalid replacement token: " << *it << std::endl;
      }
    }
    dp::sg::algorithm::replaceEffectDatas( viewState->getScene(), replacements );
  }
  else if ( !opts["replaceAll"].empty() )
  {
    dp::sg::core::EffectDataSharedPtr replacement = dp::sg::core::EffectData::create( dp::fx::EffectLibrary::instance()->getEffectData( opts["replaceAll"].as<std::string>() ) );
    DP_ASSERT( replacement );

    dp::sg::algorithm::SearchTraverser searchTraverser;
    searchTraverser.setClassName( "class dp::sg::core::GeoNode" );
    searchTraverser.setBaseClassSearch( true );
    searchTraverser.apply( viewState->getScene() );
    const std::vector<dp::sg::core::ObjectSharedPtr> &vp = searchTraverser.getResults();
    for ( size_t i=0 ; i<vp.size() ; i++ )
    {
      vp[i].inplaceCast<dp::sg::core::GeoNode>()->setMaterialEffect( replacement );
    }
  }

  if ( opts.count("gridSize") )
  {
    DP_ASSERT( viewState && viewState->getScene() && viewState->getScene()->getRootNode() );

    std::vector<unsigned int> gridSizes = opts["gridSize"].as<std::vector<unsigned int> >();
    dp::math::Vec3ui gridSize;
    int i;
    for ( i=0 ; i<3 && i<gridSizes.size() ; i++ )
    {
      gridSize[i] = gridSizes[i];
    }
    for ( ; i<3 ; i++ )
    {
      gridSize[i] = 1;
    }

    dp::math::Vec3f gridSpacing = dp::math::Vec3f( 1.0f, 1.0f, 1.0f );
    if ( opts.count("gridSpacing") )
    {
      std::vector<float> gridSpacings = opts["gridSpacing"].as<std::vector<float> >();
      for ( int i=0 ; i<3 && i<gridSpacings.size() ; i++ )
      {
        gridSpacing[i] = gridSpacings[i];
      }
    }

    viewState->getScene()->setRootNode( dp::sg::generator::replicate( viewState->getScene()->getRootNode(), gridSize, gridSpacing, opts["gridClone"].as<bool>() ) );
  }

  if ( !opts["statistics"].empty() )
  {
    showStatistics( viewState );
  }

  dp::sg::ui::setupDefaultViewState( viewState );

  if ( !opts["combineVertexAttributes"].empty() )
  {
    combineVertexAttributes( viewState );
  }

  {
    // Replace MatrixCamera by PerspectiveCamera to get all manipulator features
    if ( viewState->getCamera()->getObjectCode() == dp::sg::core::OC_MATRIXCAMERA )
    {
      dp::sg::core::PerspectiveCameraSharedPtr perspectiveCamera = dp::sg::core::PerspectiveCamera::create();
      perspectiveCamera->setOrientation(viewState->getCamera()->getOrientation());
      perspectiveCamera->setDirection((viewState->getCamera()->getDirection()));
      perspectiveCamera->setPosition(viewState->getCamera()->getPosition());

      viewState->setAutoClipPlanes(true);
      viewState->setCamera(perspectiveCamera);
    }
  }

  if ( !opts["headlight"].empty() )
  {
    if ( viewState && viewState->getScene() && !dp::sg::algorithm::containsLight( viewState->getScene() )
      && viewState->getCamera() && ( viewState->getCamera()->getNumberOfHeadLights() == 0 ) )
    {
      // Use the defaults! Note that LightSource ambientColor is black.
      viewState->getCamera()->addHeadLight( dp::sg::core::createStandardPointLight() );
    }
  }

  if ( !opts["environment"].empty() )
  {
    dp::sg::core::TextureSharedPtr texture = dp::sg::core::TextureFile::create( opts["environment"].as<std::string>() );
    dp::sg::core::SamplerSharedPtr sampler = dp::sg::core::Sampler::create( texture );
    renderer->setEnvironmentSampler( sampler );
  }

  // Setup default OpenGL format descriptor
  // We need to create a default format first to be able to check if a stereo pixelformat is available later.
  // (An unfortunate RenderContextFormat.isAvailable() interface due to Linux.)
  dp::gl::RenderContextFormat format;

  // create a widget which shows the scene
  //dp::sg::ui::glut::SceneRendererWidget w( format );
  GLUTMinimal w;

  // TODO format is not yet supported
#if 0
  if (stereo)
  {
    format.setStereo( stereo );
    if ( !w.setFormat( format ) )  // This automatically checks if the format is available.
    {
      std::cout << "Warning: No stereo pixelformat available." << std::endl;
    }
  }
#endif

  viewState->setAutoClipPlanes( opts["autoclipplanes"].as<bool>() );

  //w.setNumberOfFrames( frames );
  w.setViewState( viewState );
  w.setSceneRenderer( renderer );
  if ( !opts["continuous"].empty() )
  {
    w.setContinuousUpdate( true );
    w.setShowFrameRate( true );
  }

  if( opts["frames"].as<int>() != -1 )
  {
    w.setNumberOfFrames( opts["frames"].as<int>() );
  }
  w.setDuration( opts["duration"].as<double>() );

  if ( opts["fullscreen"].empty() )
  {
    size_t width = 640;
    size_t height = 480;

    if ( opts.count("windowSize") )
    {
      std::vector<size_t> sizes = opts["windowSize"].as<std::vector<size_t> >();
      if ( 1 <= sizes.size() )
      {
        width = sizes[0];
        if ( 2 <= sizes.size() )
        {
          height = sizes[1];
        }
      }
    }

    w.setWindowSize( width, height );
  }
  else
  {
    w.setWindowFullScreen();
  }
  //w.show();

  // Keep only once reference to the renderer in the widget. This is necessary since the OpenGL resources
  // used by the renderer must be deleted before the window gets destroyed.
  renderer.reset();

  glutMainLoop();

  return w.getExitCode();
}
Ejemplo n.º 6
0
int runApp( int argc, char *argv[], options::variables_map const& opts )
{
  QApplication app( argc, argv );

  // Create rendering engine
  dp::sg::renderer::rix::gl::SceneRendererSharedPtr renderer = dp::sg::renderer::rix::gl::SceneRenderer::create
  (
      opts["renderengine"].as<std::string>().c_str()
    , getShaderManager( opts["shadermanager"].as<std::string>() )
    , getCullingMode( opts["cullingengine"].as<std::string>() )
    , getTransparencyMode( opts["transparency"].as<std::string>() )
  );
  renderer->setCullingEnabled( opts["culling"].as<bool>() );
  renderer->setDepthPass( opts["depthPass"].as<bool>() );

  if ( !opts["effectlibrary"].empty() )
  {
    dp::fx::EffectLibrary::instance()->loadEffects( opts["effectlibrary"].as<std::string>() );
  }

  if ( !opts["environment"].empty() )
  {
    dp::sg::core::TextureSharedPtr texture = dp::sg::core::TextureFile::create( opts["environment"].as<std::string>() );
    dp::sg::core::SamplerSharedPtr sampler = dp::sg::core::Sampler::create( texture );
    renderer->setEnvironmentSampler( sampler );
  }

  dp::sg::ui::ViewStateSharedPtr viewState = loadScene( opts["filename"].as<std::string>() );

  if ( opts.count("replace") )
  {
    // process replacements
    std::vector< std::string> replacementStrings = opts["replace"].as< std::vector<std::string > >();
    dp::sg::algorithm::ReplacementMapNames replacements;
    for ( std::vector<std::string>::iterator it = replacementStrings.begin(); it != replacementStrings.end(); ++it )
    {
      size_t equalChar = it->find_first_of(':');
      if ( equalChar != std::string::npos && equalChar < it->size() - 1)
      {
        std::string str1 = it->substr( 0, equalChar );
        std::string str2 = it->substr( equalChar + 1, it->size() - equalChar - 1);
        replacements[str1] = str2;
      }
      else
      {
        std::cerr << "invalid replacement token: " << *it << std::endl;
      }
    }
    dp::sg::algorithm::replaceEffectDatas( viewState->getScene(), replacements );
  }
  else if ( !opts["replaceAll"].empty() )
  {
    dp::sg::core::EffectDataSharedPtr replacement = dp::sg::core::EffectData::create( dp::fx::EffectLibrary::instance()->getEffectData( opts["replaceAll"].as<std::string>() ) );
    DP_ASSERT( replacement );

    DP_ASSERT( viewState && viewState->getScene() && viewState->getScene()->getRootNode() );
    const std::vector<dp::sg::core::ObjectSharedPtr> vp = dp::sg::algorithm::searchClass( viewState->getScene()->getRootNode(), "class dp::sg::core::GeoNode", true );
    for ( size_t i=0 ; i<vp.size() ; i++ )
    {
      vp[i].inplaceCast<dp::sg::core::GeoNode>()->setMaterialEffect( replacement );
    }
  }

  if ( !opts["generateTexCoords"].empty() )
  {
    dp::sg::core::TextureCoordType tct = getTextureCoordType( opts["generateTexCoords"].as<std::string>() );

    DP_ASSERT( viewState && viewState->getScene() && viewState->getScene()->getRootNode() );
    const std::vector<dp::sg::core::ObjectSharedPtr> vp = dp::sg::algorithm::searchClass( viewState->getScene()->getRootNode(), "class dp::sg::core::Primitive", true );
    for ( size_t i=0 ; i<vp.size() ; i++ )
    {
      vp[i].inplaceCast<dp::sg::core::Primitive>()->generateTexCoords( tct, dp::sg::core::VertexAttributeSet::DP_SG_TEXCOORD0, false );
      // don't overwrite if there already are some texture coordinate                                                          ^^^^^
    }
  }

  if ( !opts["generateTangentSpace"].empty() )
  {
    DP_ASSERT( viewState && viewState->getScene() && viewState->getScene()->getRootNode() );
    const std::vector<dp::sg::core::ObjectSharedPtr> vp = dp::sg::algorithm::searchClass( viewState->getScene()->getRootNode(), "class dp::sg::core::Primitive", true );
    for ( size_t i=0 ; i<vp.size() ; i++ )
    {
      vp[i].inplaceCast<dp::sg::core::Primitive>()->generateTangentSpace( dp::sg::core::VertexAttributeSet::DP_SG_TEXCOORD0
                                                                        , dp::sg::core::VertexAttributeSet::DP_SG_TANGENT
                                                                        , dp::sg::core::VertexAttributeSet::DP_SG_BINORMAL
                                                                        , false );
      // don't overwrite if there already are some texture coordinate     ^^^^^
    }
  }

  if ( opts.count("gridSize") )
  {
    DP_ASSERT( viewState && viewState->getScene() && viewState->getScene()->getRootNode() );

    std::vector<unsigned int> gridSizes = opts["gridSize"].as<std::vector<unsigned int> >();
    dp::math::Vec3ui gridSize;
    int i;
    for ( i=0 ; i<3 && i<gridSizes.size() ; i++ )
    {
      gridSize[i] = gridSizes[i];
    }
    for ( ; i<3 ; i++ )
    {
      gridSize[i] = 1;
    }

    dp::math::Vec3f gridSpacing = dp::math::Vec3f( 1.0f, 1.0f, 1.0f );
    if ( opts.count("gridSpacing") )
    {
      std::vector<float> gridSpacings = opts["gridSpacing"].as<std::vector<float> >();
      for ( int i=0 ; i<3 && i<gridSpacings.size() ; i++ )
      {
        gridSpacing[i] = gridSpacings[i];
      }
    }

    viewState->getScene()->setRootNode( dp::sg::generator::replicate( viewState->getScene()->getRootNode(), gridSize, gridSpacing, opts["gridClone"].as<bool>() ) );
  }

  if ( !opts["statistics"].empty() )
  {
    showStatistics( viewState );
  }

  dp::sg::ui::setupDefaultViewState( viewState );

  if ( !opts["combineVertexAttributes"].empty() )
  {
    combineVertexAttributes( viewState );
  }

  {
    // Replace MatrixCamera by PerspectiveCamera to get all manipulator features
    if ( viewState->getCamera()->getObjectCode() == dp::sg::core::OC_MATRIXCAMERA )
    {
      dp::sg::core::PerspectiveCameraSharedPtr perspectiveCamera = dp::sg::core::PerspectiveCamera::create();
      perspectiveCamera->setOrientation(viewState->getCamera()->getOrientation());
      perspectiveCamera->setDirection((viewState->getCamera()->getDirection()));
      perspectiveCamera->setPosition(viewState->getCamera()->getPosition());

      viewState->setAutoClipPlanes(true);
      viewState->setCamera(perspectiveCamera);
    }
  }

  viewState->setAutoClipPlanes( opts["autoclipplanes"].as<bool>() );

  if ( !opts["zoom"].empty() )
  {
    DP_ASSERT( viewState && viewState->getCamera() );
    viewState->getCamera()->zoom( opts["zoom"].as<float>() );
  }

  if ( !opts["headlight"].empty() )
  {
    if ( viewState && viewState->getScene() && !dp::sg::algorithm::containsLight( viewState->getScene() )
      && viewState->getCamera() && ( viewState->getCamera()->getNumberOfHeadLights() == 0 ) )
    {
      // Use the defaults! Note that LightSource ambientColor is black.
      viewState->getCamera()->addHeadLight( dp::sg::core::createStandardPointLight() );
    }
  }

  // Setup default OpenGL format descriptor
  // We need to create a default format first to be able to check if a stereo pixelformat is available later.
  // (An unfortunate RenderContextFormat.isAvailable() interface due to Linux.)
  dp::gl::RenderContextFormat format;

  // create a widget which shows the scene
  QtMinimalWidget w( format );
  w.setSceneName( opts["filename"].as<std::string>() );
  w.setViewState( viewState );
  w.setSceneRenderer( renderer );

  if ( opts["multiSample"].as<unsigned int>() != 0 )
  {
    unsigned int samples = opts["multiSample"].as<unsigned int>();
    unsigned int coverage = std::max( samples, opts["multiSampleCoverage"].as<unsigned int>() );
    format.setMultisampleCoverage( samples, coverage );
    if ( !w.setFormat( format ) )
    {
      std::cout << "Warning: No Coverage Sampling Antialiasing ( " << samples << "/" << coverage << " ) pixelformat available." << std::endl;
      if ( samples != coverage )
      {
        format.setMultisample( samples );
        if ( !w.setFormat( format ) )
        {
          std::cout << "Warning: No Multisample Antialiasing ( " << samples << " ) pixelformat available." << std::endl;
        }
      }
    }
  }

  if ( !opts["stereo"].empty() )
  {
    format.setStereo( true );
    if ( !w.setFormat( format ) )  // This automatically checks if the format is available.
    {
      std::cout << "Warning: No stereo pixelformat available." << std::endl;
    }
  }

  if( opts["frames"].as<unsigned int>() != ~0 )
  {
    w.setNumberOfFrames( opts["frames"].as<unsigned int>() );
  }
  w.setDuration( opts["duration"].as<double>() );

  if ( !opts["continuous"].empty() )
  {
    w.setContinuousUpdate( true );
    w.setShowFrameRate( true );
  }

  if ( !opts["orbit"].empty() )
  {
    w.setOrbit( opts["orbit"].as<float>() );
  }

  if ( !opts["fullscreen"].empty() )
  {
    w.showFullScreen();
  }
  else if ( !opts["maximized"].empty() )
  {
    w.showMaximized();
  }
  else
  {
    int width = 640;
    int height = 480;

    if ( opts.count("windowSize") )
    {
      std::vector<unsigned int> sizes = opts["windowSize"].as<std::vector<unsigned int> >();
      if ( 1 <= sizes.size() )
      {
        width = sizes[0];
        if ( 2 <= sizes.size() )
        {
          height = sizes[1];
        }
      }
    }

    w.resize( width, height );
  }

  w.show();

  // Keep only once reference to the renderer in the widget. This is necessary since the OpenGL resources
  // used by the renderer must be deleted before the window gets destroyed.
  renderer.reset();

  int result = app.exec();

  return result;
}