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

Revision 4477, 7.6 kB (checked in by robert, 9 years ago)

Clean up and fixes to GraphicThread? class, and osgcamera example.

  • 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        _sceneView->setState(context->getState());
51        _sceneView->setProjectionMatrix(_camera->getProjectionMatrix());
52        _sceneView->setViewMatrix(_camera->getViewMatrix());
53        _sceneView->setViewport(_camera->getViewport());
54       
55        _sceneView->cull();
56        _sceneView->draw();
57    }
58   
59    osg::ref_ptr<osg::CameraNode>    _camera;
60    osg::ref_ptr<osg::FrameStamp>    _frameStamp;
61    osg::ref_ptr<osgUtil::SceneView> _sceneView;
62};
63
64int main( int argc, char **argv )
65{
66    if (argc<2)
67    {
68        std::cout << argv[0] <<": requires filename argument." << std::endl;
69        return 1;
70    }
71
72    // load the scene.
73    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
74    if (!loadedModel)
75    {
76        std::cout << argv[0] <<": No data loaded." << std::endl;
77        return 1;
78    }
79
80   
81    // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly
82    osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp;
83
84    unsigned int frameNum = 0;
85
86    osgUtil::UpdateVisitor updateVisitor;
87    updateVisitor.setFrameStamp(frameStamp.get());
88
89
90    unsigned int numberCameras = 3;
91    unsigned int xpos = 0;
92    unsigned int ypos = 400;
93    unsigned int width = 400;
94    unsigned int height = 400;
95   
96    typedef std::map< osg::ref_ptr<osg::CameraNode>, osg::ref_ptr<FrameOperation> > CameraMap;
97    typedef std::set< osg::GraphicsContext* > GraphicsContextSet;
98
99    CameraMap cameraMap;
100    GraphicsContextSet graphicsContextSet;
101
102    for(unsigned int i=0; i< numberCameras; ++i)
103    {
104        osg::ref_ptr<osg::CameraNode> camera = new osg::CameraNode;
105        camera->addChild(loadedModel.get());
106
107        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
108        traits->_windowName = "osgcamera";
109        traits->_x = xpos;
110        traits->_y = ypos;
111        traits->_width = width;
112        traits->_height = height;
113        traits->_windowDecoration = true;
114        traits->_doubleBuffer = true;
115
116        xpos += width;
117
118        osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get());
119
120        if (!gfxc)
121        {
122            std::cout<<"Unable to create window."<<std::endl;
123            return 1;
124        }
125
126        camera->setGraphicsContext(gfxc.get());
127
128        // initialize the view to look at the center of the scene graph
129        const osg::BoundingSphere& bs = loadedModel->getBound();
130        osg::Matrix viewMatrix;
131        viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));
132
133        camera->setViewport(0,0,traits->_width,traits->_height);
134        camera->setProjectionMatrixAsPerspective(50.0f,1.4f,1.0f,10000.0f);
135        camera->setViewMatrix(viewMatrix);
136
137        // graphics thread will realize the window.
138        gfxc->createGraphicsThread();
139
140        cameraMap[camera] = new FrameOperation(camera.get(), frameStamp.get());
141    }
142
143
144    CameraMap::iterator citr;
145    for(citr = cameraMap.begin();
146        citr != cameraMap.end();
147        ++citr)
148    {
149        graphicsContextSet.insert(const_cast<osg::GraphicsContext*>(citr->first->getGraphicsContext()));
150    }
151
152    osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation();
153    osg::ref_ptr<osg::BarrierOperation> frameEndBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION);
154    osg::ref_ptr<osg::BarrierOperation> preSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FLUSH);
155
156    std::cout<<"nubmer of gfx."<<graphicsContextSet.size()<<std::endl;
157
158    // record the timer tick at the start of rendering.   
159    osg::Timer_t start_tick = osg::Timer::instance()->tick();
160    osg::Timer_t previous_tick = start_tick;
161   
162    bool done = false;   
163
164    // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
165    while( !done )
166    {
167
168        osg::Timer_t current_tick = osg::Timer::instance()->tick();
169
170        frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,current_tick));
171        frameStamp->setFrameNumber(frameNum++);
172       
173        std::cout<<"Frame rate "<<1.0/osg::Timer::instance()->delta_s(previous_tick,current_tick)<<std::endl;
174        previous_tick = current_tick;
175
176
177        loadedModel->accept(updateVisitor);
178
179        // issue the frame for each camera.
180        for(citr = cameraMap.begin();
181            citr != cameraMap.end();
182            ++citr)
183        {
184            osg::CameraNode* camera = const_cast<osg::CameraNode*>(citr->first.get());
185            camera->getGraphicsContext()->getGraphicsThread()->add( citr->second.get(), false);
186        }
187
188        GraphicsContextSet::iterator gitr;
189        for(gitr = graphicsContextSet.begin();
190            gitr != graphicsContextSet.end();
191            ++gitr)
192        {
193            osg::GraphicsContext* context = *gitr;
194            context->getGraphicsThread()->add(frameEndBarrierOp.get(), false);
195            context->getGraphicsThread()->add(preSwapBarrierOp.get(), false);
196        }
197
198        osg::notify(osg::INFO)<<"Join frameEndBarrierOp block "<<std::endl;
199        osg::Timer_t before_tick = osg::Timer::instance()->tick();
200        frameEndBarrierOp->block();
201        osg::Timer_t after_tick = osg::Timer::instance()->tick();
202        osg::notify(osg::INFO)<<"Leave frameEndBarrierOp block "<<osg::Timer::instance()->delta_s(before_tick,after_tick)<<std::endl;
203
204        osg::notify(osg::INFO)<<"Join preSwapBarrierOp block "<<std::endl;
205        before_tick = osg::Timer::instance()->tick();
206        after_tick = osg::Timer::instance()->tick();
207        osg::notify(osg::INFO)<<"Leave preSwapBarrierOp block "<<osg::Timer::instance()->delta_s(before_tick,after_tick)<<std::endl;
208
209        for(gitr = graphicsContextSet.begin();
210            gitr != graphicsContextSet.end();
211            ++gitr)
212        {
213            osg::GraphicsContext* context = *gitr;
214            context->getGraphicsThread()->add(swapOp.get(), true);
215        }
216
217        // check if any of the windows are closed
218        for(gitr = graphicsContextSet.begin();
219            gitr != graphicsContextSet.end();
220            ++gitr)
221        {
222            osg::GraphicsContext* context = *gitr;
223            if (!context->isRealized()) done = true;
224        }
225
226    }
227
228    return 0;
229}
Note: See TracBrowser for help on using the browser.