root/OpenSceneGraph/trunk/examples/osgsidebyside/osgsidebyside.cpp @ 13798

Revision 13798, 10.3 kB (checked in by robert, 35 hours ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • Property svn:eol-style set to native
Line 
1/* OpenSceneGraph example, osgcamera.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19
20#include <osgDB/ReadFile>
21#include <osgDB/WriteFile>
22#include <osgViewer/Viewer>
23#include <osgViewer/ViewerEventHandlers>
24#include <osgGA/TrackballManipulator>
25#include <osgGA/FlightManipulator>
26#include <osgGA/AnimationPathManipulator>
27#include <osgGA/GUIEventHandler>
28#include <osgGA/StateSetManipulator>
29#include <osg/PolygonMode>
30#include <osgUtil/Optimizer>
31#include <osg/Depth>
32#include <iostream>
33#include <osg/Switch>
34#include <osgSim/MultiSwitch>
35#include <osgSim/DOFTransform>
36
37#include <osg/AlphaFunc>
38#include <osg/BlendFunc>
39
40using namespace osg;
41using namespace osgGA;
42
43
44class SwitchDOFVisitor : public osg::NodeVisitor, public osgGA::GUIEventHandler
45{
46public:
47    SwitchDOFVisitor():
48      osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
49    {
50    }
51
52    SwitchDOFVisitor(const SwitchDOFVisitor& sdfv, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) {}
53
54    META_Object(osg, SwitchDOFVisitor)
55   
56    virtual void apply(Group& node)
57    {
58        osgSim::MultiSwitch* pMSwitch = dynamic_cast<osgSim::MultiSwitch*>(&node);
59       
60        if (pMSwitch)
61        {
62            mSwitches.push_back(pMSwitch);
63        }
64
65        osg::NodeVisitor::apply(node);
66    }
67   
68    virtual void apply(Transform& node)
69    {
70        osgSim::DOFTransform* pDof = dynamic_cast<osgSim::DOFTransform*>(&node);
71       
72        if (pDof)
73        {
74            mDofs.push_back(pDof);
75            pDof->setAnimationOn(true);
76        }
77
78        osg::NodeVisitor::apply(node);
79    }
80
81    void nextSwitch()
82    {
83        for (size_t i=0; i < mSwitches.size(); i++)
84        {
85            if (mSwitches[i]->getSwitchSetList().size() > 1)
86            {
87                // Toggle through switchsets
88                unsigned int nextSwitchSet = mSwitches[i]->getActiveSwitchSet();
89                nextSwitchSet++;
90                if (nextSwitchSet >= mSwitches[i]->getSwitchSetList().size())
91                    nextSwitchSet = 0;
92                mSwitches[i]->setActiveSwitchSet(nextSwitchSet);
93            }
94            else if (mSwitches[i]->getSwitchSetList().size() == 1)
95            {
96                // If we have only one switchset, toggle values within this switchset
97                osgSim::MultiSwitch::ValueList values = mSwitches[i]->getValueList(0);
98                for (size_t j=0; j < values.size(); j++)
99                {
100                    if (values[j])
101                    {
102                        unsigned int nextValue = j+1;
103                        if (nextValue >= values.size())
104                            nextValue = 0;
105                        mSwitches[i]->setSingleChildOn(0, nextValue);
106                    }
107                }
108            }
109        }
110    }
111
112    void multiplyAnimation(float scale)
113    {
114        for (size_t i=0; i < mDofs.size(); i++)
115        {
116            mDofs[i]->setIncrementHPR(mDofs[i]->getIncrementHPR() * scale);
117            mDofs[i]->setIncrementScale(mDofs[i]->getIncrementScale() * scale);
118            mDofs[i]->setIncrementTranslate(mDofs[i]->getIncrementTranslate() * scale);
119        }
120    }
121
122    bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
123    {
124        osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
125        if (!viewer) return false;
126
127        if (ea.getHandled()) return false;
128
129        if(ea.getEventType()==GUIEventAdapter::KEYDOWN)
130        {
131
132            switch( ea.getKey() )
133            {
134                case osgGA::GUIEventAdapter::KEY_Right:
135                    // Toggle next switch
136                    nextSwitch();
137                    return true;
138                    break;
139                case osgGA::GUIEventAdapter::KEY_Up:
140                    // Increase animation speed
141                    multiplyAnimation(2);
142                    return true;
143                    break;
144                case osgGA::GUIEventAdapter::KEY_Down:
145                    // Decrease animation speed
146                    multiplyAnimation(0.5);
147                    return true;
148                    break;
149            }
150        }
151        return false;
152    }
153
154private:
155    std::vector<osgSim::MultiSwitch*> mSwitches;
156    std::vector<osgSim::DOFTransform*> mDofs;
157};
158
159void singleWindowSideBySideCameras(osgViewer::Viewer& viewer)
160{
161    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
162    if (!wsi)
163    {
164        osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
165        return;
166    }
167   
168    unsigned int width, height;
169    wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
170
171
172
173    // Not fullscreen
174    width /= 2;
175    height /= 2;
176
177    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
178    traits->x = 100;
179    traits->y = 100;
180    traits->width = width;
181    traits->height = height;
182    traits->windowDecoration = true;
183    traits->doubleBuffer = true;
184    traits->sharedContext = 0;
185
186    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
187    if (gc.valid())
188    {
189        osg::notify(osg::INFO)<<"  GraphicsWindow has been created successfully."<<std::endl;
190
191        // need to ensure that the window is cleared make sure that the complete window is set the correct colour
192        // rather than just the parts of the window that are under the camera's viewports
193        gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
194        gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
195    }
196    else
197    {
198        osg::notify(osg::NOTICE)<<"  GraphicsWindow has not been created successfully."<<std::endl;
199    }
200
201
202    osg::Camera* master = viewer.getCamera();
203
204    // get the default settings for the camera
205    double fovy, aspectRatio, zNear, zFar;
206    master->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
207
208    // reset this for the actual apsect ratio of out created window
209    double windowAspectRatio = double(width)/double(height);
210    master->setProjectionMatrixAsPerspective(fovy, windowAspectRatio, 1.0, 10000.0);
211
212    master->setName("MasterCam");
213
214    osg::ref_ptr<osg::Camera> camera = new osg::Camera;
215    camera->setCullMask(1);
216    camera->setName("Left");
217    camera->setGraphicsContext(gc.get());
218    camera->setViewport(new osg::Viewport(0, 0, width/2, height));
219    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
220    camera->setDrawBuffer(buffer);
221    camera->setReadBuffer(buffer);
222    viewer.addSlave(camera.get(), osg::Matrixd::scale(1.0,0.5,1.0), osg::Matrixd());
223
224    camera = new osg::Camera;
225    camera->setCullMask(2);
226    camera->setName("Right");
227    camera->setGraphicsContext(gc.get());
228    camera->setViewport(new osg::Viewport(width/2, 0, width/2, height));
229    buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
230    camera->setDrawBuffer(buffer);
231    camera->setReadBuffer(buffer);
232    viewer.addSlave(camera.get(), osg::Matrixd::scale(1.0,0.5,1.0), osg::Matrixd());
233}
234
235int main( int argc, char **argv )
236{
237    // use an ArgumentParser object to manage the program arguments.
238    osg::ArgumentParser arguments(&argc,argv);
239
240    if (argc<2)
241    {
242        std::cout << argv[0] <<": requires filename argument." << std::endl;
243        return 1;
244    }
245
246    osgViewer::Viewer viewer(arguments);
247   
248    std::string outputfile("output.osgt");
249    while (arguments.read("-o",outputfile)) {}
250
251    while (arguments.read("-s")) { viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); }
252    while (arguments.read("-g")) { viewer.setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext); }
253    while (arguments.read("-d")) { viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext); }
254    while (arguments.read("-c")) { viewer.setThreadingModel(osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext); }
255   
256    singleWindowSideBySideCameras(viewer);
257
258    viewer.setCameraManipulator( new osgGA::TrackballManipulator() );
259    viewer.addEventHandler(new osgViewer::StatsHandler);
260    viewer.addEventHandler(new osgViewer::ThreadingHandler);
261    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
262    viewer.addEventHandler(new osgViewer::LODScaleHandler());
263    viewer.addEventHandler(new osgGA::StateSetManipulator());
264
265    SwitchDOFVisitor* visit = new SwitchDOFVisitor;
266    viewer.addEventHandler(visit);
267   
268    osg::ref_ptr<osg::Node> loadedModel;
269    // load the scene.
270    loadedModel = osgDB::readNodeFiles(arguments);
271
272    if (!loadedModel)
273    {
274        std::cout << argv[0] <<": No data loaded." << std::endl;
275        return 1;
276    }
277
278    osg::Group* group = new osg::Group;
279   
280    osg::Group* group1 = new osg::Group;
281    group1->addChild(loadedModel.get());
282    group1->setNodeMask(1);
283
284    // Uncomment these lines if you like to compare the loaded model to the resulting model in a merge/diff tool
285    //osgDB::writeNodeFile(*loadedModel.get(), "dummy1.osgt");
286
287    osgDB::writeNodeFile(*loadedModel.get(), outputfile);
288    osg::ref_ptr<osg::Node> convertedModel = osgDB::readNodeFile(outputfile);
289
290    //osgDB::writeNodeFile(*convertedModel.get(), "dummy2.osgt");
291
292    osg::Group* group2 = new osg::Group;
293    group2->addChild(convertedModel.get());
294    group2->setNodeMask(2);
295
296    // Activate DOF animations and collect switches
297    loadedModel->accept(*visit);
298    convertedModel->accept(*visit);
299
300    group->addChild(group1);
301    group->addChild(group2);
302
303    viewer.setSceneData(group);
304
305    viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext);
306    viewer.realize();
307
308    viewer.run();
309
310    return 0;
311}
Note: See TracBrowser for help on using the browser.