Show
Ignore:
Timestamp:
08/31/05 11:21:34 (9 years ago)
Author:
robert
Message:

Add comments explain how example works.

Files:
1 modified

Legend:

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

    r4481 r4482  
    3131 
    3232 
     33// Compile operation, that compile OpenGL objects. 
    3334struct CompileOperation : public osg::GraphicsThread::Operation 
    3435{ 
     
    5354}; 
    5455 
     56// Frame operation, that does a cull and draw on the scene graph. 
    5557struct FrameOperation : public osg::GraphicsThread::Operation 
    5658{ 
     
    8688}; 
    8789 
     90 
     91// main does the following steps to create a multi-thread, multiple camera/graphics context view of a scene graph. 
     92// 
     93// 1) load the scene graph 
     94// 
     95// 2) create a list of camera, each with their own graphis context, with a graphics thread for each context. 
     96// 
     97// 3) set up the graphic threads so that the do an initial compile OpenGL objects operation, this is done once, and then this compile op is disgarded 
     98// 
     99// 4) set up the graphics thread so that it has all the graphics ops required for the main loop, these ops are: 
     100// 4.a) frame begin barrair, syncronizes all the waiting graphic threads so they don't run while update is occuring 
     101// 4.b) frame operation - the cull and draw for each camera 
     102// 4.c) frame end barrier, releases the update thread once all graphic threads have dispatched all their OpenGL commands 
     103// 4.d) pre swap barrier, barrier which ensures that all graphics threads have sent their data down to the gfx card. 
     104// 4.e) swap buffers, do the swap buffers on all the graphics contexts. 
     105// 
     106// 5. The main loop: 
     107// 5.a) update 
     108// 5.b) join the frame begin barrrier, releasing all the graphics threads to do their stuff 
     109// 5.c) block on the frame end barrier, waiting till all the graphics threads have done their cull/draws. 
     110// 5.d) check to see if any of the windows has been closed.  
     111// 
    88112int main( int argc, char **argv ) 
    89113{ 
     
    118142    unsigned int height = 400; 
    119143     
    120     typedef std::map< osg::ref_ptr<osg::CameraNode>, osg::ref_ptr<FrameOperation> > CameraMap; 
     144    typedef std::list< osg::ref_ptr<osg::CameraNode> > CameraList; 
    121145    typedef std::set< osg::GraphicsContext* > GraphicsContextSet; 
    122146 
    123     CameraMap cameraMap; 
     147    CameraList cameraList; 
    124148    GraphicsContextSet graphicsContextSet; 
    125149 
    126  
     150    // create the cameras, graphic contexts and graphic threads. 
    127151    bool shareContexts = false; 
    128152    osg::GraphicsContext* previousContext = 0; 
     
    166190        gfxc->createGraphicsThread(); 
    167191 
    168         cameraMap[camera] = new FrameOperation(camera.get(), frameStamp.get()); 
     192        cameraList.push_back(camera); 
    169193 
    170194        previousContext = gfxc.get(); 
     
    172196 
    173197 
    174     CameraMap::iterator citr; 
    175     for(citr = cameraMap.begin(); 
    176         citr != cameraMap.end(); 
     198    // build the list of unique graphics contexts. 
     199    CameraList::iterator citr; 
     200    for(citr = cameraList.begin(); 
     201        citr != cameraList.end(); 
    177202        ++citr) 
    178203    { 
    179         graphicsContextSet.insert(const_cast<osg::GraphicsContext*>(citr->first->getGraphicsContext())); 
    180     } 
    181  
     204        graphicsContextSet.insert(const_cast<osg::GraphicsContext*>((*citr)->getGraphicsContext())); 
     205    } 
     206 
     207 
     208    std::cout<<"Number of cameras = "<<cameraList.size()<<std::endl; 
     209    std::cout<<"Number of graphics contexts = "<<graphicsContextSet.size()<<std::endl; 
     210 
     211 
     212    // first the compile of the GL Objects, do it syncronously. 
     213    GraphicsContextSet::iterator gitr; 
    182214    osg::ref_ptr<CompileOperation> compileOp = new CompileOperation(loadedModel.get()); 
    183  
     215    for(gitr = graphicsContextSet.begin(); 
     216        gitr != graphicsContextSet.end(); 
     217        ++gitr) 
     218    { 
     219        osg::GraphicsContext* context = *gitr; 
     220        context->getGraphicsThread()->add(compileOp.get(), true); 
     221    } 
     222 
     223 
     224    // second the begin frame barrier to all graphics threads 
    184225    osg::ref_ptr<osg::BarrierOperation> frameBeginBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION); 
     226    for(gitr = graphicsContextSet.begin(); 
     227        gitr != graphicsContextSet.end(); 
     228        ++gitr) 
     229    { 
     230        osg::GraphicsContext* context = *gitr; 
     231        context->getGraphicsThread()->add(frameBeginBarrierOp.get(), false); 
     232    } 
     233 
     234    // third add the frame for each camera. 
     235    for(citr = cameraList.begin(); 
     236        citr != cameraList.end(); 
     237        ++citr) 
     238    { 
     239        osg::CameraNode* camera = citr->get(); 
     240        camera->getGraphicsContext()->getGraphicsThread()->add( new FrameOperation(camera, frameStamp.get()), false);  
     241    } 
     242 
     243    // fourth add the frame end barrier, the pre swap barrier and finally the swap buffers to each graphics thread. 
     244    // The frame end barrier tells the main thead that the draw dispatch/read phase of the scene graph is complete. 
     245    // The pre swap barrier is an optional extra, which does a flush before joining the barrier, using this all graphics threads 
     246    // are held back until they have all dispatched their fifo to the graphics hardware.   
     247    // The swapOp just issues a swap buffers for each of the graphics contexts. 
     248    // The post swap barrier is an optional extra which does a glFinish after the swap buffers. 
    185249    osg::ref_ptr<osg::BarrierOperation> frameEndBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION); 
    186250    osg::ref_ptr<osg::BarrierOperation> preSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FLUSH); 
    187251    osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation(); 
    188  
    189     std::cout<<"nubmer of gfx."<<graphicsContextSet.size()<<std::endl; 
    190  
    191     // record the timer tick at the start of rendering.     
    192     osg::Timer_t start_tick = osg::Timer::instance()->tick(); 
    193     osg::Timer_t previous_tick = start_tick; 
    194      
    195     bool done = false;     
    196  
    197     // first the compile of the GL Objects, do it syncronously. 
    198     GraphicsContextSet::iterator gitr; 
    199     for(gitr = graphicsContextSet.begin(); 
    200         gitr != graphicsContextSet.end(); 
    201         ++gitr) 
    202     { 
    203         osg::GraphicsContext* context = *gitr; 
    204         context->getGraphicsThread()->add(compileOp.get(), true); 
    205     } 
    206  
    207  
    208     // second the begin frame barrier to all graphics threads 
    209     for(gitr = graphicsContextSet.begin(); 
    210         gitr != graphicsContextSet.end(); 
    211         ++gitr) 
    212     { 
    213         osg::GraphicsContext* context = *gitr; 
    214         context->getGraphicsThread()->add(frameBeginBarrierOp.get(), false); 
    215     } 
    216  
    217     // third add the frame for each camera. 
    218     for(citr = cameraMap.begin(); 
    219         citr != cameraMap.end(); 
    220         ++citr) 
    221     { 
    222         osg::CameraNode* camera = const_cast<osg::CameraNode*>(citr->first.get()); 
    223         camera->getGraphicsContext()->getGraphicsThread()->add( citr->second.get(), false);  
    224     } 
    225  
    226     // fourth add the frame end barrier, the pre swap barrier and finally the swap buffers to each graphics thread 
     252    osg::ref_ptr<osg::BarrierOperation> postSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FINISH); 
     253    bool waitTillSwapBufferFinished = false; 
    227254    for(gitr = graphicsContextSet.begin(); 
    228255        gitr != graphicsContextSet.end(); 
     
    233260        context->getGraphicsThread()->add(preSwapBarrierOp.get(), false); 
    234261        context->getGraphicsThread()->add(swapOp.get(), false); 
    235     } 
     262        if (waitTillSwapBufferFinished) context->getGraphicsThread()->add(postSwapBarrierOp.get(), false); 
     263    } 
     264 
     265 
     266    // record the timer tick at the start of rendering.     
     267    osg::Timer_t start_tick = osg::Timer::instance()->tick(); 
     268    osg::Timer_t previous_tick = start_tick; 
     269     
     270    bool done = false;     
    236271 
    237272    // main loop -  update scene graph, dispatch frame, wait for frame done.