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

Revision 4478, 7.7 kB (checked in by robert, 9 years ago)

Added name and keep member variables to osg::GraphicsThread::Operation to allow
the names of the operations to be logged for stats purposes, or used when
do searches of the operation list. The keep member variable tells the graphics
thread run loop wether to remove the entry from the list once its been called.

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