root/OpenSceneGraph/trunk/examples/osgwidgetwindow/osgwidgetwindow.cpp @ 8867

Revision 8867, 8.3 kB (checked in by robert, 6 years ago)

Updated osgwidget examples to use the new osg::clone() methods

Line 
1// -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
2// $Id: osgwidgetwindow.cpp 66 2008-07-14 21:54:09Z cubicool $
3
4#include <iostream>
5#include <osgDB/ReadFile>
6#include <osgGA/StateSetManipulator>
7#include <osgViewer/Viewer>
8#include <osgViewer/ViewerEventHandlers>
9#include <osgWidget/WindowManager>
10#include <osgWidget/ViewerEventHandlers>
11#include <osgWidget/Box>
12
13const unsigned int MASK_2D = 0xF0000000;
14const unsigned int MASK_3D = 0x0F000000;
15
16// Here we create (and later demonstrate) the use of a simple function callback.
17bool windowClicked(osgWidget::Event& ev) {
18        std::cout << "windowClicked: " << ev.getWindow()->getName() << std::endl;
19
20        if(ev.getData()) {
21                std::string* s = static_cast<std::string*>(ev.getData());
22
23                std::cout << "This is data attached to the event: " << *s << std::endl;
24        }
25
26        return true;
27}
28
29bool windowScrolled(osgWidget::Event& ev) {
30        osgWidget::warn()
31                << "scrolling up? " << ev.getWindowManager()->isMouseScrollingUp()
32                << std::endl
33        ;
34
35        return true;
36}
37
38// Here we dcreate a new class and show how to use a method callback (which differs from
39// a function callback in that we are required to also pass the "this" argument).
40struct Object {
41        bool windowClicked(osgWidget::Event& ev) {
42                std::cout << "Object::windowClicked " << ev.getWindow()->getName() << std::endl;
43
44                return true;
45        }
46};
47
48int main(int argc, char** argv) {
49        osgViewer::Viewer viewer;
50       
51        // Let's get busy! The WindowManager class is actually an osg::Switch,
52        // so you can add it to (ideally) an orthographic camera and have it behave as
53        // expected. Note that you create a WindowManager with a NodeMask--it is very important
54        // that this be unique for picking to work properly. This also makes it possible to have
55        // multiple WindowManagers each operating on their own, unique set of Window objects.
56        // The final bool argument is a group of flags that introduce optional functionality
57        // for the WindowManager. In our case we include the flags USE_PYTHON and USE_LUA,
58        // to demonstrate (and test) their usage. Finally, we pass the temporary WM_NO_BETA_WARN
59        // argument, which prevents creating the orange warning window. :) It will be shown
60        // in other examples...
61        osgWidget::WindowManager* wm = new osgWidget::WindowManager(
62                &viewer,
63                1280.0f,
64                1024.0f,
65                MASK_2D,
66                osgWidget::WindowManager::WM_USE_LUA |
67                osgWidget::WindowManager::WM_USE_PYTHON |
68                osgWidget::WindowManager::WM_PICK_DEBUG |
69                osgWidget::WindowManager::WM_NO_BETA_WARN
70        );
71
72        // An actual osgWidget::Window is pure virtual, so we've got to use the osgWidget::Box
73        // implementation for now. At a later time, support for Tables and other kinds of
74        // advanced layout Window types will be added.
75        osgWidget::Window* box = new osgWidget::Box("box", osgWidget::Box::HORIZONTAL);
76
77        // Now we actually attach our two types of callbacks to the box instance. The first
78        // uses the simple function signature, the second uses a bound method, passing "this"
79        // as the second argument to the Callback constructor.
80        Object obj;
81
82        static std::string data = "lol ur face!";
83
84        box->addCallback(osgWidget::Callback(&windowClicked, osgWidget::EVENT_MOUSE_PUSH, &data));
85        box->addCallback(osgWidget::Callback(&windowScrolled, osgWidget::EVENT_MOUSE_SCROLL));
86        box->addCallback(osgWidget::Callback(
87                &Object::windowClicked,
88                &obj,
89                osgWidget::EVENT_MOUSE_PUSH
90        ));
91
92        // Create some of our "testing" Widgets; included are two Widget subclasses I made
93        // during testing which I've kept around for testing purposes. You'll notice
94        // that you cannot move the box using the NullWidget, and that the NotifyWidget
95        // is a bit verbose. :)
96        osgWidget::Widget* widget1 = new osgWidget::NotifyWidget("widget1", 300.0f, 100.0f);
97        osgWidget::Widget* widget2 = new osgWidget::NullWidget("widget2", 400.0f, 75.0f);
98        osgWidget::Widget* widget3 = new osgWidget::Widget("widget3", 100.0f, 100.0f);
99        // Set the colors of widget1 and widget3 to green.
100        widget1->setColor(0.0f, 1.0f, 0.0f, 1.0f);
101        widget1->setCanFill(true);
102        widget3->setColor(0.0f, 1.0f, 0.0f, 1.0f);
103
104        widget1->setImage(osgDB::readImageFile("Images/Saturn.TGA"), true);
105
106        // Set the color of widget2, to differentiate it and make it sassy. This is
107        // like a poor man's gradient!
108        widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_LEFT);
109        widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_RIGHT);
110        widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_RIGHT);
111        widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_LEFT);
112
113        // Now add our newly created widgets to our box.
114        box->addWidget(widget1);
115        box->addWidget(widget2);
116        box->addWidget(widget3);
117
118        // For maximum efficiency, Windows don't automatically reallocate their geometry
119        // and internal positioning every time a widget is added. Thus, we either have to
120        // call the WindowManger::resizeAllWindows method or manually call
121        // Window::resize when we're ready.
122        box->resize();
123
124        // Now, lets clone our existing box and create a new copy of of it, also adding that
125        // to the WindowManager. This demonstrates the usages of OSG's ->clone() support,
126        // though that is abstracted by our META_UIObject macro.
127        osgWidget::Window* boxCopy = osg::clone(box,"newBox");
128
129        // Move our copy to make it visible.
130        boxCopy->setOrigin(0.0f, 125.0f);
131
132        boxCopy->getByName("widget1")->setColor(0.5f, 0.0f, 1.0f, 1.0f);
133        boxCopy->getByName("widget3")->setColor(0.5f, 0.0f, 1.0f, 1.0f);
134
135        // Add the successfully created Box (if we get this far) into the WindowManager, so
136        // that they can receive events.
137        wm->addChild(box);
138        wm->addChild(boxCopy);
139
140        // Now, ask our new box to be 100% the width of the WindowManager.
141        boxCopy->resizePercent(100.0f, 0.0f);
142
143        // Here we demonstrate the use of osgWidget/io_utils. This is really only useful for
144        // debugging at the moment, but later I'll make it more generic for .osg and .ive
145        // creation.
146        // std::cout << *box << std::endl << *boxCopy << std::endl;
147
148        // Add our event handler; is this better as a MatrixManipulator? Add a few other
149        // helpful ViewerEventHandlers.
150        viewer.addEventHandler(new osgWidget::MouseHandler(wm));
151        viewer.addEventHandler(new osgWidget::KeyboardHandler(wm));
152        viewer.addEventHandler(new osgViewer::StatsHandler());
153        viewer.addEventHandler(new osgViewer::WindowSizeHandler());
154        viewer.addEventHandler(new osgGA::StateSetManipulator(
155                viewer.getCamera()->getOrCreateStateSet()
156        ));
157
158        // Setup our OSG objects for our scene; note the use of the utility function
159        // createOrthoCamera, which is just a helper for setting up a proper viewing area.
160        // An alternative (and a MUCH easier alternative at that!) is to
161        // simply use the createParentOrthoCamera method of the WindowManager class,
162        // which will wrap the calls to createOrthoCamera and addChild for us! Check out
163        // some of the other examples to see this in action...
164        osg::Group*  group  = new osg::Group();
165        osg::Camera* camera = osgWidget::createInvertedYOrthoCamera(1280.0f, 1024.0f);
166        osg::Node*   model  = osgDB::readNodeFile("cow.osg");
167
168        // Set our first non-UI node to be something other than the mask we created our
169        // WindowManager with to avoid picking.
170        // TODO: Do I need to create a mechanism for doing this automatically, or should
171        // that be the responsibility of the users of osgWidget?
172        model->setNodeMask(MASK_3D);
173
174        // Add the WindowManager instance to the 2D camera. This isn't strictly necessary,
175        // and you can get some cool results putting the WindowManager directly into a
176        // 3D scene. This is not necessary if you use WindowManager::createParentOrthoCamera.
177        camera->addChild(wm);
178
179        // Add our camera and a testing 3D model to the scene.
180        group->addChild(camera);
181        group->addChild(model);
182
183        // Here we show how to both run simple strings of code AND run entire files. These
184        // assume that you're running the osgwidgetwindow example from the build directory,
185        // otherwise you'll need to adjust the file path below in the call to runFile().
186        wm->getLuaEngine()->eval("window = osgwidget.newWindow()");
187        wm->getLuaEngine()->runFile("osgWidget/osgwidgetwindow.lua");
188
189        wm->getPythonEngine()->eval("import osgwidget");
190        wm->getPythonEngine()->runFile("osgWidget/osgwidgetwindow.py");
191
192        viewer.setUpViewInWindow(0, 0, 1280, 1024);
193        viewer.setSceneData(group);
194
195        /*
196        osgViewer::Viewer::Cameras cameras;
197        viewer.getCameras(cameras);
198        osg::Camera* c = cameras[0];
199        osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
200        c->setProjectionMatrix(s * c->getProjectionMatrix());
201        */
202
203        return viewer.run();
204}
Note: See TracBrowser for help on using the browser.