Beispiel #1
0
void combineVertexAttributes( dp::sg::ui::ViewStateSharedPtr const& viewState )
{
  DP_ASSERT( viewState && viewState->getScene() && viewState->getScene()->getRootNode() );
  std::vector<dp::sg::core::ObjectSharedPtr> results = dp::sg::algorithm::searchClass( viewState->getScene()->getRootNode(), "class::dp::sg::core::VertexAttributeSet" );
  for ( std::vector<dp::sg::core::ObjectSharedPtr>::iterator it = results.begin(); it != results.end(); ++it )
  {
    it->inplaceCast<dp::sg::core::VertexAttributeSet>()->combineBuffers();
  }
}
Beispiel #2
0
 void SceneRenderer::beginRendering( dp::sg::ui::ViewStateSharedPtr const& viewState, dp::ui::RenderTargetSharedPtr const& renderTarget )
 {
   DP_ASSERT( viewState );
   if ( viewState )
   {
     DP_ASSERT( viewState->getRendererOptions() );
     if( viewState->getRendererOptions() && viewState->getRendererOptions() != m_rendererOptions.getSharedPtr() )
     {
       // update renderer options
       m_rendererOptions = viewState->getRendererOptions().getWeakPtr();
       addRendererOptions( viewState->getRendererOptions() );
     }
   }
 }
Beispiel #3
0
      bool saveScene( std::string const& filename, dp::sg::ui::ViewStateSharedPtr const& viewState, dp::util::PlugInCallback *callback )
      {
        bool result = false;
        // define a unique plug-interface ID for SceneLoader
        const dp::util::UPITID PITID_SCENE_SAVER(UPITID_SCENE_SAVER, UPITID_VERSION);

        dp::util::FileFinder fileFinder( dp::util::getCurrentPath() );
        fileFinder.addSearchPath( dp::util::getModulePath() );
#if defined(DP_OS_WINDOWS)
        fileFinder.addSearchPath( dp::util::getModulePath( reinterpret_cast<HMODULE>(&__ImageBase) ) );
#endif

        dp::util::UPIID piid = dp::util::UPIID(dp::util::getFileExtension( filename ).c_str(), PITID_SCENE_SAVER);

        {
          dp::util::PlugInSharedPtr plug;
          if ( getInterface( fileFinder, piid, plug ) )
          {
            SceneSaverSharedPtr ss = std::static_pointer_cast<SceneSaver>(plug);
            try
            {
              dp::sg::core::SceneSharedPtr scene( viewState->getScene() ); // DAR HACK Change SceneSaver interface later.
              result = ss->save( scene, viewState, filename );
            }
            catch(...) // catch all others
            {
            }
          }
        }

        // FIXME interface needs to be released since the cleanup order (first dp::sg::core, then dp::util) causes problems upon destruction.
        dp::util::releaseInterface(piid);

        return result;
      }
void SceneRendererPipeline::doRenderStandard(dp::sg::ui::ViewStateSharedPtr const& viewState, dp::ui::RenderTargetSharedPtr const& renderTarget)
{
  // Call the current scene renderer and render the whole scene into the main render target (tonemapFBO).
  DP_ASSERT( viewState->getTraversalMask() == ~0 );

  // This renders only one eye even if the renderTarget is stereoscopic.
  // Important: The m_sceneRenderer holds a NOP StereoViewStateProvider to use the already adjusted stereo ViewState camera!
  m_sceneRenderer->render(viewState, renderTarget, renderTarget->getStereoTarget());
}
Beispiel #5
0
void setLights( size_t counter = ~0 )
{
  if( !g_lightSources[0] )
  {
    dp::sg::core::GroupSharedPtr const& rootPtr = g_viewState->getScene()->getRootNode().staticCast<dp::sg::core::Group>();
    DP_ASSERT( rootPtr );

    // add own lights to the root node
    dp::math::Vec3f firstLightPos = g_viewState->getCamera()->getPosition();
    for( size_t i = 0; i < g_numLights; ++i )
    {
      g_lightSources[i] = dp::sg::core::createStandardPointLight( firstLightPos + dp::math::Vec3f( (float)2*i, 0.0f, 0.0f ) );
      rootPtr->addChild( g_lightSources[i] );
    }
  }

  for( size_t i = 0; i < g_numLights; ++i )
  {
    g_lightSources[i]->setEnabled( !!( counter & (1i64 << i) ) );
  }
}
Beispiel #6
0
      bool saveScene( std::string const& filename, dp::sg::ui::ViewStateSharedPtr const& viewState, dp::util::PlugInCallback *callback )
      {
        bool result = false;
        // define a unique plug-interface ID for SceneLoader
        const dp::util::UPITID PITID_SCENE_SAVER(UPITID_SCENE_SAVER, UPITID_VERSION);

        vector<string> searchPaths;
        searchPaths.push_back( dp::util::getCurrentPath() );

        std::string modulePath = dp::util::getModulePath();
        if ( std::find( searchPaths.begin(), searchPaths.end(), modulePath ) == searchPaths.end() )
        {
          searchPaths.push_back( modulePath );
        }

#if defined(DP_OS_WINDOWS)
        modulePath = dp::util::getModulePath( reinterpret_cast<HMODULE>(&__ImageBase) );
        if ( std::find( searchPaths.begin(), searchPaths.end(), modulePath ) == searchPaths.end() )
        {
          searchPaths.push_back( modulePath );
        }
#endif

        dp::util::UPIID piid = dp::util::UPIID(dp::util::getFileExtension( filename ).c_str(), PITID_SCENE_SAVER);

        dp::util::PlugIn * plug;

        if ( getInterface( searchPaths, piid, plug ) )
        {
          SceneSaver *ss = reinterpret_cast<SceneSaver *>(plug);
          try
          {
            dp::sg::core::SceneSharedPtr scene( viewState->getScene() ); // DAR HACK Change SceneSaver interface later.
            result = ss->save( scene, viewState, filename );
          }
          catch(...) // catch all others
          {
          }
        }

        return result;
      }
void SceneRendererPipeline::doRenderTonemap(dp::sg::ui::ViewStateSharedPtr const& viewState, dp::ui::RenderTargetSharedPtr const& renderTarget)
{
  dp::gl::RenderTargetSharedPtr const & renderTargetGL = renderTarget.inplaceCast<dp::gl::RenderTarget>();
  dp::gl::TargetBufferMask clearMask = renderTargetGL->getClearMask();

  // Match the size of the tonemapFBO to the destination renderTarget.
  unsigned int width;
  unsigned int height;
  renderTarget->getSize(width, height);
  m_tonemapFBO->setSize(width, height);

  // Call the current scene renderer and render the whole scene into the main render target (tonemapFBO).
  DP_ASSERT( viewState->getTraversalMask() == ~0 );

  // This renders only one eye even if the renderTarget is stereoscopic.
  // Important: The m_sceneRenderer holds a NOP StereoViewStateProvider to use the already adjusted stereo ViewState camera!
  m_sceneRenderer->render(viewState, m_tonemapFBO, renderTarget->getStereoTarget());

  if ( m_tonemapperValuesChanged )
  {
    // Set the tonemapper parameters:
    const dp::sg::core::ParameterGroupDataSharedPtr& parameterGroupData = m_tonemapperData->findParameterGroupData( std::string( "tonemapParameters" ) );
    DP_ASSERT( parameterGroupData );

    DP_VERIFY( parameterGroupData->setParameter( "invGamma", 1.0f / m_tonemapperValues.gamma ) );
    DP_VERIFY( parameterGroupData->setParameter( "invWhitePoint", m_tonemapperValues.brightness / m_tonemapperValues.whitePoint) );
    DP_VERIFY( parameterGroupData->setParameter( "saturation", m_tonemapperValues.saturation ) );
    DP_VERIFY( parameterGroupData->setParameter( "crushBlacks", m_tonemapperValues.crushBlacks + m_tonemapperValues.crushBlacks + 1.0f) ); // Note, the default if the shader variable crushBlacks is 1.0!
    DP_VERIFY( parameterGroupData->setParameter( "burnHighlights", m_tonemapperValues.burnHighlights ) );

    m_tonemapperValuesChanged = false;
  }

  // No need to clear anything. This tonemapping pass just copies pixels and ignores depth.
  renderTargetGL->setClearMask( 0 );
  m_tonemapper->render();
  renderTargetGL->setClearMask( clearMask );
}
Beispiel #8
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();
}
Beispiel #9
0
      void SceneTree::updateObjectTree( dp::sg::ui::ViewStateSharedPtr const& vs )
      {   
        //
        // first step: update node-local information
        //

        // update dirty object hints & masks
        {
          ObjectObserver::NewCacheData cd;
          m_objectObserver->popNewCacheData( cd );

          ObjectObserver::NewCacheData::const_iterator it, it_end = cd.end();
          for( it=cd.begin(); it!=it_end; ++it )
          {
            ObjectTreeNode& node = m_objectTree[ it->first ];
            node.m_localHints = it->second.m_hints;
            node.m_localMask = it->second.m_mask;

            m_objectTree.markDirty( it->first, ObjectTreeNode::DEFAULT_DIRTY );
          }
        }

        // update dirty switch information
        ObjectTreeIndexSet dirtySwitches;
        m_switchObserver->popDirtySwitches( dirtySwitches );
        if( !dirtySwitches.empty() )
        {
          ObjectTreeIndexSet::iterator it, it_end = dirtySwitches.end();
          for( it=dirtySwitches.begin(); it!=it_end; ++it )
          {
            ObjectTreeIndex index = *it;

            SwitchWeakPtr swp = m_objectTree.m_switchNodes[ index ];
            DP_ASSERT( swp );

            ObjectTreeIndex childIndex = m_objectTree[index].m_firstChild;
            // counter for the i-th child
            size_t i = 0;

            while( childIndex != ~0 )
            {
              ObjectTreeNode& childNode = m_objectTree[childIndex];
              DP_ASSERT( childNode.m_parentIndex == index );

              bool newActive = swp->isActive( checked_cast<unsigned int>(i) );
              if ( childNode.m_localActive != newActive )
              {
                childNode.m_localActive = newActive;
                m_objectTree.markDirty( childIndex, ObjectTreeNode::DEFAULT_DIRTY );
              }

              childIndex = childNode.m_nextSibling;
              ++i;
            }  
          }
        }

        // update all lods
        if( !m_objectTree.m_LODs.empty() )
        {
          float scaleFactor = vs->getLODRangeScale();
          const Mat44f& worldToView = vs->getCamera()->getWorldToViewMatrix();

          std::map< ObjectTreeIndex, LODWeakPtr >::iterator it, it_end = m_objectTree.m_LODs.end();
          for( it = m_objectTree.m_LODs.begin(); it != it_end; ++it )
          {
            ObjectTreeIndex index = it->first;
            const ObjectTreeNode& node = m_objectTree[ index ];

            const Mat44f modelToWorld = getTransformMatrix( node.m_transformIndex );
            const Mat44f modelToView = modelToWorld * worldToView;
            ObjectTreeIndex activeIndex = it->second->getLODToUse( modelToView, scaleFactor );

            ObjectTreeIndex childIndex = m_objectTree[index].m_firstChild;
            // counter for the i-th child
            size_t i = 0;

            while( childIndex != ~0 )
            {
              ObjectTreeNode& childNode = m_objectTree[childIndex];
              DP_ASSERT( childNode.m_parentIndex == index );

              bool newActive = activeIndex == i;
              if ( childNode.m_localActive != newActive )
              {
                childNode.m_localActive = newActive;
                m_objectTree.markDirty( childIndex, ObjectTreeNode::DEFAULT_DIRTY );
              }

              childIndex = childNode.m_nextSibling;
              ++i;
            }  
          }
        }

        //
        // second step: update resulting node-world information
        // 

        UpdateObjectVisitor objectVisitor( m_objectTree, this );
        PreOrderTreeTraverser<ObjectTree, UpdateObjectVisitor> objectTraverser;
        
        objectTraverser.processDirtyList( m_objectTree, objectVisitor, ObjectTreeNode::DEFAULT_DIRTY );
        m_objectTree.m_dirtyObjects.clear();
      }
Beispiel #10
0
      void SceneTree::updateTransformTree( dp::sg::ui::ViewStateSharedPtr const& vs )
      {
        //
        // first step: update node local information
        // 

        // update dirty transforms from transform observer
        {
          const TransformObserver::DirtyPayloads& cd = m_transformObserver->getDirtyPayloads();

          TransformObserver::DirtyPayloads::const_iterator it, it_end = cd.end();
          for( it = cd.begin(); it != it_end; ++it )
          {
            TransformTreeIndex index = (*it)->m_index;
            TransformTreeNode& node = m_transformTree[index];
            DP_ASSERT( node.m_transform != nullptr );

            const Trafo& t = node.m_transform->getTrafo();
            node.m_localMatrix = t.getMatrix();

            const Vec3f& s( t.getScaling() );
            node.setLocalBits( TransformTreeNode::ISMIRRORTRANSFORM, s[0]*s[1]*s[2] < 0.0f );

            m_transformTree.markDirty( index, TransformTreeNode::DEFAULT_DIRTY );

            // mark the transform's corresponding object tree node's bounding volume dirty
            DP_ASSERT( node.m_objectTreeIndex != ~0 );

            (*it)->m_dirty = false;
          }
          m_transformObserver->clearDirtyPayloads();
        }

        // update dynamic transforms
        {
          TransformTreeIndexSet::const_iterator it, it_end = m_dynamicTransformIndices.end();
          for( it=m_dynamicTransformIndices.begin(); it!=it_end; ++it )
          {
            TransformTreeIndex index = *it;
            TransformTreeNode& node = m_transformTree[index];

            if( node.m_transform )
            {
              Trafo t = node.m_transform->getTrafo();
              node.m_localMatrix = t.getMatrix();

              const Vec3f& s( t.getScaling() );
              node.setLocalBits( TransformTreeNode::ISMIRRORTRANSFORM, s[0]*s[1]*s[2] < 0.0f );
            }
            m_transformTree.markDirty( index, TransformTreeNode::DEFAULT_DIRTY );
          }
        }

        //
        // second step: update resulting node-world information
        // 

        m_changedTransforms.clear();
        UpdateTransformVisitor visitor( m_transformTree, *this, vs->getCamera(), m_changedTransforms );
        PreOrderTreeTraverser<TransformTree, UpdateTransformVisitor> traverser;

        traverser.processDirtyList( m_transformTree, visitor, TransformTreeNode::DEFAULT_DIRTY);
        m_transformTree.m_dirtyObjects.clear();
      }
void SceneRendererPipeline::doRenderHighlight(dp::sg::ui::ViewStateSharedPtr const& viewState, dp::ui::RenderTargetSharedPtr const& renderTarget)
{
  // only call this if objects need to be rendered highlighted
  DP_ASSERT(m_highlighting);

  // Highlight pass:
  // Match the size of the highlightFBO to the destination renderTarget.
  unsigned int width;
  unsigned int height;
  renderTarget->getSize(width, height);
  m_highlightFBO->setSize(width, height);

  unsigned int originalTraversalMask = viewState->getTraversalMask();
  viewState->setTraversalMask(2); // Render only the highlighted objects.

  glPushAttrib( GL_STENCIL_BUFFER_BIT );

  // If an object is highlighted, render the highlighted object into the stencil buffer of the FBO.

  // Setup the proper stencil state.
  // Write a 1 for every rendered fragment into the stencil buffer
  glStencilFunc(GL_NEVER, 1, ~0);
  glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
  glEnable(GL_STENCIL_TEST);

  // This is always using a SceneRendererGL2 to render the highlighted objects.
  m_highlightFBO->setClearMask( dp::gl::TBM_COLOR_BUFFER
                              | dp::gl::TBM_DEPTH_BUFFER
                              | dp::gl::TBM_STENCIL_BUFFER); // Clear all.

  // A SceneRenderer always uses the scene background color to clear. Temporarily change it to black here.
  dp::math::Vec4f backgroundColor = viewState->getScene()->getBackColor();
  viewState->getScene()->setBackColor( dp::math::Vec4f(0.0f, 0.0f, 0.0f, 0.0f) );

  m_sceneRendererHighlight->render(viewState, m_highlightFBO);

  viewState->getScene()->setBackColor(backgroundColor);

  viewState->setTraversalMask(originalTraversalMask); // Reset the traversal mask.

  // Highlight post-processing:
  // Migrate the stencil bit contents as white color into the texture rectangle.
  m_highlightFBO->setClearMask( dp::gl::TBM_COLOR_BUFFER ); // Do not clear the stencil! Don't care for depth.

  // set the stencil as needed for the stencil to color pass
  glStencilFunc( GL_EQUAL, 1, ~0 );
  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );

  m_rendererStencilToColor->render();

  glPopAttrib();

  // Render the outline around the highlighted object onto the main renderTarget (framebuffer).
  dp::gl::RenderTargetSharedPtr const & renderTargetGL = renderTarget.inplaceCast<dp::gl::RenderTarget>();
  dp::gl::TargetBufferMask clearMask = renderTargetGL->getClearMask();

  // keep the following render call from clearing the previous rendered content
  renderTargetGL->setClearMask( 0 );
  m_rendererHighlight->render();
  // restore the clear mask
  renderTargetGL->setClearMask( clearMask );
}