root/OpenSceneGraph/trunk/examples/osgcamera/osgcamera.cpp @ 4446

Revision 4446, 7.9 kB (checked in by robert, 9 years ago)

Further work on GraphicsContext/GraphicsThread?

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
2//
3// Simple example of use of Producer::RenderSurface to create an OpenGL
4// graphics window, and OSG for rendering.
5
6#include <osg/Timer>
7#include <osg/GraphicsContext>
8#include <osg/GraphicsThread>
9
10#include <osgUtil/UpdateVisitor>
11#include <osgUtil/CullVisitor>
12#include <osgUtil/SceneView>
13
14#include <osgDB/ReadFile>
15
16#include <map>
17#include <list>
18#include <iostream>
19
20
21
22////////////////////////////////////////////////////////////////////////////////
23//
24//
25//  **************** THIS IS AN EXPERIMENTAL IMPLEMENTATION ***************
26//  ************************** PLEASE DO NOT COPY  ************************
27//
28//
29///////////////////////////////////////////////////////////////////////////////
30
31
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};
67
68int main( int argc, char **argv )
69{
70    if (argc<2)
71    {
72        std::cout << argv[0] <<": requires filename argument." << std::endl;
73        return 1;
74    }
75
76    // load the scene.
77    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
78    if (!loadedModel)
79    {
80        std::cout << argv[0] <<": No data loaded." << std::endl;
81        return 1;
82    }
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   
176    // record the timer tick at the start of rendering.   
177    osg::Timer_t start_tick = osg::Timer::instance()->tick();
178   
179    bool done = false;   
180
181    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
182    while( !done )
183    {
184        std::cout<<"Frame "<<frameNum<<std::endl;
185
186        frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick()));
187        frameStamp->setFrameNumber(frameNum++);
188       
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
241    }
242
243    return 0;
244}
Note: See TracBrowser for help on using the browser.