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) ) ); } }
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(); }
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(); }
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(); }