Show
Ignore:
Timestamp:
08/20/05 10:59:03 (9 years ago)
Author:
robert
Message:

Further work on GraphicsContext/GraphicsThread?

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgcamera/osgcamera.cpp

    r4440 r4446  
    66#include <osg/Timer> 
    77#include <osg/GraphicsContext> 
     8#include <osg/GraphicsThread> 
    89 
    910#include <osgUtil/UpdateVisitor> 
    1011#include <osgUtil/CullVisitor> 
     12#include <osgUtil/SceneView> 
    1113 
    1214#include <osgDB/ReadFile> 
    1315 
     16#include <map> 
     17#include <list> 
    1418#include <iostream> 
    1519 
     
    2630 
    2731 
    28 #if 1 
     32struct FrameOperation : public osg::GraphicsThread::Operation 
     33{ 
     34    FrameOperation(osg::CameraNode* camera, osg::FrameStamp* frameStamp): 
     35        _camera(camera), 
     36        _frameStamp(frameStamp) 
     37    { 
     38        _sceneView = new osgUtil::SceneView; 
     39        _sceneView->setDefaults(); 
     40        _sceneView->setFrameStamp(_frameStamp.get()); 
     41             
     42        if (camera->getNumChildren()>=1) 
     43        { 
     44            _sceneView->setSceneData(camera->getChild(0)); 
     45        } 
     46    } 
     47     
     48    virtual void operator () (osg::GraphicsContext* context) 
     49    { 
     50        std::cout<<"FrameOperation draw begin"<<context<<std::endl; 
     51 
     52        _sceneView->setState(context->getState()); 
     53        _sceneView->setProjectionMatrix(_camera->getProjectionMatrix()); 
     54        _sceneView->setViewMatrix(_camera->getViewMatrix()); 
     55        _sceneView->setViewport(_camera->getViewport()); 
     56         
     57        _sceneView->cull(); 
     58        _sceneView->draw(); 
     59 
     60        std::cout<<"FrameOperation draw end"<<context<<std::endl; 
     61    } 
     62     
     63    osg::ref_ptr<osg::CameraNode>    _camera; 
     64    osg::ref_ptr<osg::FrameStamp>    _frameStamp; 
     65    osg::ref_ptr<osgUtil::SceneView> _sceneView; 
     66}; 
    2967 
    3068int main( int argc, char **argv ) 
     
    4381        return 1; 
    4482    } 
    45      
    46     osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; 
    47     traits->_windowName = "osgcamera"; 
    48     traits->_x = 100; 
    49     traits->_y = 100; 
    50     traits->_width = 800; 
    51     traits->_height = 800; 
    52     traits->_windowDecoration = true; 
    53     traits->_doubleBuffer = true; 
    54      
    55     osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get()); 
    56      
    57     if (!gfxc) 
    58     { 
    59         std::cout<<"Unable to create window."<<std::endl; 
    60         return 1; 
    61     } 
    62      
    63     // realise the window 
    64     gfxc->realize(); 
    65  
    66     // create the view of the scene. 
    67     osg::ref_ptr<osg::CameraNode> camera = new osg::CameraNode; 
    68     camera->setRenderOrder(osg::CameraNode::NESTED_RENDER); 
    69     camera->setClearColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); 
    70     camera->setCullingActive(false); 
    71      
    72     camera->addChild(loadedModel.get()); 
    73      
    74      
    75  
    76     // initialize the view to look at the center of the scene graph 
    77     const osg::BoundingSphere& bs = loadedModel->getBound(); 
    78     osg::Matrix viewMatrix; 
    79     viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); 
    80  
     83 
     84     
     85    // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly 
     86    osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp; 
     87 
     88    unsigned int frameNum = 0; 
     89 
     90    osgUtil::UpdateVisitor updateVisitor; 
     91    updateVisitor.setFrameStamp(frameStamp.get()); 
     92 
     93 
     94    unsigned int numberCameras = 3; 
     95    unsigned int xpos = 0; 
     96    unsigned int ypos = 400; 
     97    unsigned int width = 400; 
     98    unsigned int height = 400; 
     99     
     100    typedef std::map< osg::ref_ptr<osg::CameraNode>, osg::ref_ptr<FrameOperation> > CameraMap; 
     101    typedef std::set< osg::GraphicsContext* > GraphicsContextSet; 
     102 
     103    CameraMap cameraMap; 
     104    GraphicsContextSet graphicsContextSet; 
     105 
     106    for(unsigned int i=0; i< numberCameras; ++i) 
     107    { 
     108        osg::ref_ptr<osg::CameraNode> camera = new osg::CameraNode; 
     109        camera->addChild(loadedModel.get()); 
     110 
     111        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; 
     112        traits->_windowName = "osgcamera"; 
     113        traits->_x = xpos; 
     114        traits->_y = ypos; 
     115        traits->_width = width; 
     116        traits->_height = height; 
     117        traits->_windowDecoration = true; 
     118        traits->_doubleBuffer = true; 
     119 
     120        xpos += width; 
     121 
     122        osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get()); 
     123 
     124        if (!gfxc) 
     125        { 
     126            std::cout<<"Unable to create window."<<std::endl; 
     127            return 1; 
     128        } 
     129 
     130        // realise the window 
     131        gfxc->realize(); 
     132 
     133        camera->setGraphicsContext(gfxc.get()); 
     134 
     135        // initialize the view to look at the center of the scene graph 
     136        const osg::BoundingSphere& bs = loadedModel->getBound(); 
     137        osg::Matrix viewMatrix; 
     138        viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); 
     139 
     140        camera->setViewport(0,0,traits->_width,traits->_height); 
     141        camera->setProjectionMatrixAsPerspective(50.0f,1.4f,1.0f,10000.0f); 
     142        camera->setViewMatrix(viewMatrix); 
     143 
     144 
     145        gfxc->createGraphicsThread(); 
     146 
     147        cameraMap[camera] = new FrameOperation(camera.get(), frameStamp.get()); 
     148    } 
     149 
     150 
     151    CameraMap::iterator citr; 
     152    for(citr = cameraMap.begin(); 
     153        citr != cameraMap.end(); 
     154        ++citr) 
     155    { 
     156        graphicsContextSet.insert(const_cast<osg::GraphicsContext*>(citr->first->getGraphicsContext())); 
     157    } 
     158 
     159    osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation(); 
     160    osg::ref_ptr<osg::BarrierOperation> frameEndBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION); 
     161    osg::ref_ptr<osg::BarrierOperation> preSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FLUSH); 
     162 
     163    std::cout<<"nubmer of gfx."<<graphicsContextSet.size()<<std::endl; 
     164 
     165 
     166    GraphicsContextSet::iterator gitr; 
     167    for(gitr = graphicsContextSet.begin(); 
     168        gitr != graphicsContextSet.end(); 
     169        ++gitr) 
     170    { 
     171        std::cout<<"Issue swap."<<std::endl; 
     172        osg::GraphicsContext* context = *gitr; 
     173        context->getGraphicsThread()->add(swapOp.get(), true); 
     174    } 
     175     
    81176    // record the timer tick at the start of rendering.     
    82177    osg::Timer_t start_tick = osg::Timer::instance()->tick(); 
    83178     
    84     unsigned int frameNum = 0; 
    85      
    86     // make the graphics context current 
    87     gfxc->makeCurrent(); 
    88      
    89     osg::ref_ptr<osgUtil::UpdateVisitor> updateVisitor = new osgUtil::UpdateVisitor; 
    90     osg::ref_ptr<osgUtil::CullVisitor> cullVisitor = new osgUtil::CullVisitor; 
    91  
    92     osg::ref_ptr<osgUtil::RenderGraph> renderGraph = new osgUtil::RenderGraph; 
    93     cullVisitor->setRenderGraph(renderGraph.get()); 
    94  
    95     osg::ref_ptr<osgUtil::RenderStage> renderStage = new osgUtil::RenderStage; 
    96     cullVisitor->setRenderStage(renderStage.get()); 
     179    bool done = false;     
    97180 
    98181    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) 
    99     while( gfxc->isRealized() ) 
    100     { 
    101         // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly 
    102         osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp; 
     182    while( !done ) 
     183    { 
     184        std::cout<<"Frame "<<frameNum<<std::endl; 
     185 
    103186        frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); 
    104187        frameStamp->setFrameNumber(frameNum++); 
    105188         
    106         updateVisitor->reset(); 
    107                  
    108         // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp 
    109         updateVisitor->setFrameStamp(frameStamp.get()); 
    110         updateVisitor->setTraversalNumber(frameStamp->getFrameNumber()); 
    111  
    112          
    113         // set the view 
    114         camera->setViewMatrix(viewMatrix); 
    115  
    116         // do the update traversal the scene graph - such as updating animations 
    117         camera->accept(*updateVisitor); 
    118          
    119         cullVisitor->reset(); 
    120         cullVisitor->setFrameStamp(frameStamp.get()); 
    121         cullVisitor->setTraversalNumber(frameStamp->getFrameNumber()); 
    122  
    123          
    124         // update the viewport dimensions, incase the window has been resized. 
    125         camera->setViewport(0,0,traits->_width,traits->_height); 
    126  
    127         renderGraph->clean(); 
    128         renderStage->reset(); 
    129         renderStage->setViewport(camera->getViewport()); 
    130          
    131         osg::ref_ptr<osg::RefMatrix> proj = new osg::RefMatrix(camera->getProjectionMatrix()); 
    132         osg::ref_ptr<osg::RefMatrix> mv = new osg::RefMatrix(camera->getViewMatrix()); 
    133  
    134         cullVisitor->pushViewport(camera->getViewport()); 
    135         cullVisitor->pushProjectionMatrix(proj.get()); 
    136         cullVisitor->pushModelViewMatrix(mv.get()); 
    137  
    138         // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins 
    139         //camera->accept(*cullVisitor); 
    140         loadedModel->accept(*cullVisitor); 
    141  
    142         cullVisitor->popModelViewMatrix(); 
    143         cullVisitor->popProjectionMatrix(); 
    144         cullVisitor->popViewport(); 
    145          
    146         renderStage->sort(); 
    147  
    148         // prune out any empty RenderGraph children. 
    149         // note, this would be not required if the rendergraph had been 
    150         // reset at the start of each frame (see top of this method) but 
    151         // a clean has been used instead to try to minimize the amount of 
    152         // allocation and deleteing of the RenderGraph nodes. 
    153         renderGraph->prune(); 
    154          
    155         renderStage->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); 
    156          
    157         gfxc->getState()->setInitialViewMatrix(mv.get()); 
    158  
    159         std::cout<<"before"<<std::endl; 
    160  
    161         // draw traversal 
    162         osgUtil::RenderLeaf* previous = NULL; 
    163         renderStage->draw(*(gfxc->getState()), previous); 
    164  
    165         // Swap Buffers 
    166         gfxc->swapBuffers(); 
    167          
    168         std::cout<<"swap"<<std::endl; 
     189        std::cout<<"Frame rate "<<(double)frameNum / frameStamp->getReferenceTime()<<std::endl; 
     190 
     191 
     192        loadedModel->accept(updateVisitor); 
     193 
     194        // issue the frame for each camera. 
     195        for(citr = cameraMap.begin(); 
     196            citr != cameraMap.end(); 
     197            ++citr) 
     198        { 
     199            osg::CameraNode* camera = const_cast<osg::CameraNode*>(citr->first.get()); 
     200            camera->getGraphicsContext()->getGraphicsThread()->add( citr->second.get(), false);  
     201        } 
     202 
     203        for(gitr = graphicsContextSet.begin(); 
     204            gitr != graphicsContextSet.end(); 
     205            ++gitr) 
     206        { 
     207            osg::GraphicsContext* context = *gitr; 
     208            context->getGraphicsThread()->add(frameEndBarrierOp.get(), false); 
     209            context->getGraphicsThread()->add(preSwapBarrierOp.get(), false); 
     210        } 
     211 
     212        std::cout<<"Join frameEndBarrierOp block "<<std::endl; 
     213        osg::Timer_t before_tick = osg::Timer::instance()->tick(); 
     214        frameEndBarrierOp->block(); 
     215        osg::Timer_t after_tick = osg::Timer::instance()->tick(); 
     216        std::cout<<"Leave frameEndBarrierOp block "<<osg::Timer::instance()->delta_s(before_tick,after_tick)<<std::endl; 
     217 
     218        std::cout<<"Join preSwapBarrierOp block "<<std::endl; 
     219        before_tick = osg::Timer::instance()->tick(); 
     220//        preSwapBarrierOp->block(); 
     221        after_tick = osg::Timer::instance()->tick(); 
     222        std::cout<<"Leave preSwapBarrierOp block "<<osg::Timer::instance()->delta_s(before_tick,after_tick)<<std::endl; 
     223 
     224        for(gitr = graphicsContextSet.begin(); 
     225            gitr != graphicsContextSet.end(); 
     226            ++gitr) 
     227        { 
     228            osg::GraphicsContext* context = *gitr; 
     229            context->getGraphicsThread()->add(swapOp.get(), false); 
     230        } 
     231 
     232        // check if any of the windows are closed 
     233        for(gitr = graphicsContextSet.begin(); 
     234            gitr != graphicsContextSet.end(); 
     235            ++gitr) 
     236        { 
     237            osg::GraphicsContext* context = *gitr; 
     238            if (!context->isRealized()) done = true; 
     239        } 
     240 
    169241    } 
    170242 
    171243    return 0; 
    172244} 
    173  
    174 #else 
    175  
    176 int main( int argc, char **argv ) 
    177 { 
    178     if (argc<2)  
    179     { 
    180         std::cout << argv[0] <<": requires filename argument." << std::endl; 
    181         return 1; 
    182     } 
    183  
    184     // load the scene. 
    185     osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]); 
    186     if (!loadedModel)  
    187     { 
    188         std::cout << argv[0] <<": No data loaded." << std::endl; 
    189         return 1; 
    190     } 
    191      
    192     osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; 
    193     traits->_windowName = "osgcamera"; 
    194     traits->_x = 100; 
    195     traits->_y = 100; 
    196     traits->_width = 800; 
    197     traits->_height = 800; 
    198     traits->_windowDecoration = true; 
    199     traits->_doubleBuffer = true; 
    200      
    201     osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get()); 
    202      
    203     if (!gfxc) 
    204     { 
    205         std::cout<<"Unable to create window."<<std::endl; 
    206         return 1; 
    207     } 
    208      
    209     // realise the window 
    210     gfxc->realize(); 
    211  
    212     // create the view of the scene. 
    213     osg::ref_ptr<osgUtil::SceneView> sceneView = new osgUtil::SceneView; 
    214     sceneView->setDefaults(); 
    215     sceneView->setSceneData(loadedModel.get()); 
    216  
    217     // initialize the view to look at the center of the scene graph 
    218     const osg::BoundingSphere& bs = loadedModel->getBound(); 
    219     osg::Matrix viewMatrix; 
    220     viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); 
    221  
    222     // record the timer tick at the start of rendering.     
    223     osg::Timer_t start_tick = osg::Timer::instance()->tick(); 
    224      
    225     unsigned int frameNum = 0; 
    226      
    227     // make the graphics context current 
    228     gfxc->makeCurrent(); 
    229  
    230     // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) 
    231     while( gfxc->isRealized() ) 
    232     { 
    233         // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly 
    234         osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp; 
    235         frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); 
    236         frameStamp->setFrameNumber(frameNum++); 
    237          
    238         // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp 
    239         sceneView->setFrameStamp(frameStamp.get()); 
    240          
    241         // update the viewport dimensions, incase the window has been resized. 
    242         sceneView->setViewport(0,0,traits->_width,traits->_height); 
    243          
    244         // set the view 
    245         sceneView->setViewMatrix(viewMatrix); 
    246  
    247         // do the update traversal the scene graph - such as updating animations 
    248         sceneView->update(); 
    249          
    250         // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins 
    251         sceneView->cull(); 
    252          
    253         // draw the rendering bins. 
    254         sceneView->draw(); 
    255  
    256         // Swap Buffers 
    257         gfxc->swapBuffers(); 
    258     } 
    259  
    260     return 0; 
    261 } 
    262  
    263 #endif