root/OpenSceneGraph/trunk/examples/osgQtWidgets/osgQtWidgets.cpp @ 11610

Revision 11610, 28.3 kB (checked in by robert, 4 years ago)

From Jean-Sebastien Guay, "I've been working in the last few days
to get QWidgetImage to a point where it can fill a need we have: to be
able to use Qt to make HUDs and to display widgets over / inside an OSG
scene.


Current results


I've attached what I have at this point. The modified QWidgetImage +
QGraphicsViewAdapter classes can be rendered fullscreen (i.e. the Qt
QGraphicsView's size follows the size of the OSG window) or on a quad in
the scene as before. It will let events go through to OSG if no widget
is under the mouse when they happen (useful when used as a HUD with
transparent parts - a click-focus scheme could be added later too). It
also supercedes Martin Scheffler's submission because it adds a
getter/setter for the QGraphicsViewAdapter's background color (and the
user can set their widget to be transparent using
widget->setAttribute(Qt::WA_TranslucentBackground) themselves).

The included osgQtBrowser example has been modified to serve as a test
bed for these changes. It has lots more command line arguments than
before, some of which can be removed eventually (once things are
tested). Note that it may be interesting to change its name or split it
into two examples. Though if things go well, the specific QWebViewImage
class can be removed completely and we can consolidate to using
QWidgetImage everywhere, and then a single example to demonstrate it
would make more sense, albeit not named osgQtBrowser... You can try this
path by using the --useWidgetImage --useBrowser command line arguments -
this results in an equivalent setup to QWebViewImage, but using
QWidgetImage, and doesn't work completely yet for some unknown reason,
see below.


Remaining issues


There are a few issues left to fix, and for these I request the
community's assistance. They are not blockers for me, and with my
limited Qt experience I don't feel like I'm getting any closer to fixing
them, so if someone else could pitch in and see what they can find, it
would be appreciated. It would be really nice to get them fixed, that
way we'd really have a first-class integration of Qt widgets in an OSG
scene. The issues are noted in the osgQtBrowser.cpp source file, but
here they are too:


QWidgetImage still has some issues, some examples are:

  1. Editing in the QTextEdit doesn't work. Also when started with
    --useBrowser, editing in the search field on YouTube? doesn't
    work. But that same search field when using QWebViewImage
    works... And editing in the text field in the pop-up getInteger
    dialog works too. All these cases use QGraphicsViewAdapter
    under the hood, so why do some work and others don't?

a) osgQtBrowser --useWidgetImage [--fullscreen] (optional)
b) Try to click in the QTextEdit and type, or to select text

and drag-and-drop it somewhere else in the QTextEdit. These
don't work.

c) osgQtBrowser --useWidgetImage --sanityCheck
d) Try the operations in b), they all work.
e) osgQtBrowser --useWidgetImage --useBrowser [--fullscreen]
f) Try to click in the search field and type, it doesn't work.
g) osgQtBrowser
h) Try the operation in f), it works.

  1. Operations on floating windows (--numFloatingWindows 1 or more).
    Moving by dragging the titlebar, clicking the close button,
    resizing them, none of these work. I wonder if it's because the
    OS manages those functions (they're functions of the window
    decorations) so we need to do something special for that? But
    in --sanityCheck mode they work.

a) osgQtBrowser --useWidgetImage --numFloatingWindows 1

[--fullscreen]

b) Try to drag the floating window, click the close button, or

drag its sides to resize it. None of these work.

c) osgQtBrowser --useWidgetImage --numFloatingWindows 1

--sanityCheck

d) Try the operations in b), all they work.
e) osgQtBrowser --useWidgetImage [--fullscreen]
f) Click the button so that the getInteger() dialog is

displayed, then try to move that dialog or close it with the
close button, these don't work.

g) osgQtBrowser --useWidgetImage --sanityCheck
h) Try the operation in f), it works.

  1. (Minor) The QGraphicsView's scrollbars don't appear when
    using QWidgetImage or QWebViewImage. QGraphicsView is a
    QAbstractScrollArea and it should display scrollbars as soon as
    the scene is too large to fit the view.

a) osgQtBrowser --useWidgetImage --fullscreen
b) Resize the OSG window so it's smaller than the QTextEdit.

Scrollbars should appear but don't.

c) osgQtBrowser --useWidgetImage --sanityCheck
d) Try the operation in b), scrollbars appear. Even if you have

floating windows (by clicking the button or by adding
--numFloatingWindows 1) and move them outside the view,
scrollbars appear too. You can't test that case in OSG for
now because of problem 2 above, but that's pretty cool.

  1. (Minor) In sanity check mode, the widget added to the
    QGraphicsView is centered. With QGraphicsViewAdapter, it is not.

a) osgQtBrowser --useWidgetImage [--fullscreen]
b) The QTextEdit and button are not in the center of the image

generated by the QGraphicsViewAdapter.

c) osgQtBrowser --useWidgetImage --sanityCheck
d) The QTextEdit and button are in the center of the

QGraphicsView.


As you can see I've put specific repro steps there too, so it's clear
what I mean by a given problem. The --sanityCheck mode is useful to see
what should happen in a "normal" Qt app that demonstrates the same
situation, so hopefully we can get to a point where it behaves the same
with --sanityCheck and without."

Line 
1/* OpenSceneGraph example, osgcompositeviewer.
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#include <iostream>
20
21#include <osg/Notify>
22#include <osg/io_utils>
23
24#include <osg/ArgumentParser>
25#include <osg/MatrixTransform>
26#include <osg/AutoTransform>
27#include <osg/Camera>
28#include <osg/TexMat>
29#include <osg/TextureRectangle>
30#include <osgDB/ReadFile>
31#include <osgDB/WriteFile>
32#include <osgGA/TrackballManipulator>
33#include <osgGA/StateSetManipulator>
34#include <osgViewer/Viewer>
35#include <osgViewer/ViewerEventHandlers>
36#include <osgWidget/Browser>
37
38
39//#include <QtWebKit/QWebSettings>
40//#include <QtWebKit/QtWebKit>
41#include <QtGui/QGraphicsScene>
42#include <QtGui/QGraphicsView>
43#include <QtGui/QApplication>
44#include <QtGui/QPainter>
45#include <QtGui/QtEvents>
46#include <QtGui/QDialog>
47#include <QtGui/QVBoxLayout>
48#include <QtGui/QMainWindow>
49#include <QtOpenGL/QtOpenGL>
50
51#include <osgQt/QGraphicsViewAdapter>
52#include <osgQt/QWebViewImage>
53#include <osgQt/QWidgetImage>
54
55
56// Thread that runs the viewer's frame loop as we can't run Qt in the background...
57class ViewerFrameThread : public OpenThreads::Thread
58{
59    public:
60
61        ViewerFrameThread(osgViewer::ViewerBase* viewerBase, bool doQApplicationExit):
62            _viewerBase(viewerBase),
63            _doQApplicationExit(doQApplicationExit) {}
64
65        ~ViewerFrameThread()
66        {
67            cancel();
68            while(isRunning())
69            {
70                OpenThreads::Thread::YieldCurrentThread();
71            }
72        }
73
74        int cancel()
75        {
76            _viewerBase->setDone(true);
77            return 0;
78        }
79
80        void run()
81        {
82            int result = _viewerBase->run();
83
84            if (_doQApplicationExit) QApplication::exit(result);
85        }
86
87        osg::ref_ptr<osgViewer::ViewerBase> _viewerBase;
88        bool _doQApplicationExit;
89};
90
91
92class MyPushButton : public QPushButton
93{
94public:
95    MyPushButton(const QString& text) : QPushButton(text) {}
96
97protected:
98    virtual void mousePressEvent(QMouseEvent* e)
99    {
100        bool ok = false;
101        int val = QInputDialog::getInteger(this, "Get integer", "Please enter an integer between 0 and pi", 0, 0, 3, 1, &ok);
102        std::cout << "Ok was " << (ok ? "" : "not") << " pressed, val is " << val << std::endl;
103    }
104};
105
106
107//We would need to document the following somewhere in order to guide people on
108//what they need to use...
109//
110//----------------------------------------------
111//There are two angles to consider.
112//
113//1. If someone wants a widget in their Qt app to be an OSG-rendered scene, they
114//need GraphicsWindowQt (in the osgViewerQtContext example) or QOSGWidget (in the
115//osgViewerQt example). These two allow both OSG and Qt to manage their threads
116//in a way which is optimal to them. We've used QOSGWidget in the past and had
117//trouble when Qt tried to overlay other widgets over the QOSGWidget (since OSG
118//did its rendering independently of Qt, it would overwrite what Qt had drawn). I
119//haven't tried GraphicsWindowQt yet, but I expect since it uses QGLWidget, it
120//will result in Qt knowing when OSG has drawn and be able to do overlays at the
121//right time. Eventually GraphicsWindowQt can be brought into osgViewer I imagine...
122//
123//2. If someone wants to bring Qt widgets inside their OSG scene (to do HUDs or
124//an interface on a computer screen which is inside the 3D scene, or even
125//floating Qt widgets, for example). That's where QGraphicsViewAdapter +
126//QWidgetImage will be useful.
127//----------------------------------------------
128
129
130int main(int argc, char **argv)
131{
132    // Qt requires that we construct the global QApplication before creating any widgets.
133    QApplication app(argc, argv);
134
135    // use an ArgumentParser object to manage the program arguments.
136    osg::ArgumentParser arguments(&argc,argv);
137
138    // true = run osgViewer in a separate thread than Qt
139    // false = interleave osgViewer and Qt in the main thread
140    bool useFrameLoopThread = true;
141    if (arguments.read("--noFrameThread")) useFrameLoopThread = false;
142
143    // true = use QWidgetImage
144    // false = use QWebViewImage
145    bool useWidgetImage = false;
146    if (arguments.read("--useWidgetImage")) useWidgetImage = true;
147
148    // true = use QWebView in a QWidgetImage to compare to QWebViewImage
149    // false = make an interesting widget
150    bool useBrowser = false;
151    if (arguments.read("--useBrowser")) useBrowser = true;
152
153    // true = use a QLabel for text
154    // false = use a QTextEdit for text
155    // (only applies if useWidgetImage == true and useBrowser == false)
156    bool useLabel = false;
157    if (arguments.read("--useLabel")) useLabel = true;
158
159    // true = make a Qt window with the same content to compare to
160    // QWebViewImage/QWidgetImage
161    // false = use QWebViewImage/QWidgetImage (depending on useWidgetImage)
162    bool sanityCheck = false;
163    if (arguments.read("--sanityCheck")) sanityCheck = true;
164
165    // Add n floating windows inside the QGraphicsScene.
166    int numFloatingWindows = 0;
167    while (arguments.read("--numFloatingWindows", numFloatingWindows));
168
169    // true = Qt widgets will be displayed on a quad inside the 3D scene
170    // false = Qt widgets will be an overlay over the scene (like a HUD)
171    bool inScene = true;
172    if (arguments.read("--fullscreen")) { inScene = false; }
173
174
175    osg::ref_ptr<osg::Group> root = new osg::Group;
176
177    if (!useWidgetImage)
178    {
179        //-------------------------------------------------------------------
180        // QWebViewImage test
181        //-------------------------------------------------------------------
182        // Note: When the last few issues with QWidgetImage are fixed,
183        // QWebViewImage and this if() {} section can be removed since
184        // QWidgetImage can display a QWebView just like QWebViewImage. Use
185        // --useWidgetImage --useBrowser to see that in action.
186
187        if (!sanityCheck)
188        {
189            osg::ref_ptr<osgQt::QWebViewImage> image = new osgQt::QWebViewImage;
190
191            if (arguments.argc()>1) image->navigateTo((arguments[1]));
192            else image->navigateTo("http://www.youtube.com/");
193
194            osgWidget::GeometryHints hints(osg::Vec3(0.0f,0.0f,0.0f),
195                                           osg::Vec3(1.0f,0.0f,0.0f),
196                                           osg::Vec3(0.0f,0.0f,1.0f),
197                                           osg::Vec4(1.0f,1.0f,1.0f,1.0f),
198                                           osgWidget::GeometryHints::RESIZE_HEIGHT_TO_MAINTAINCE_ASPECT_RATIO);
199
200            osg::ref_ptr<osgWidget::Browser> browser = new osgWidget::Browser;
201            browser->assign(image.get(), hints);
202
203            root->addChild(browser.get());
204        }
205        else
206        {
207            // Sanity check, do the same thing as QGraphicsViewAdapter but in
208            // a separate Qt window.
209            QWebPage* webPage = new QWebPage;
210            webPage->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
211            webPage->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
212
213            QWebView* webView = new QWebView;
214            webView->setPage(webPage);
215
216            if (arguments.argc()>1) webView->load(QUrl(arguments[1]));
217            else webView->load(QUrl("http://www.youtube.com/"));
218
219            QGraphicsScene* graphicsScene = new QGraphicsScene;
220            graphicsScene->addWidget(webView);
221
222            QGraphicsView* graphicsView = new QGraphicsView;
223            graphicsView->setScene(graphicsScene);
224
225            QMainWindow* mainWindow = new QMainWindow;
226            //mainWindow->setLayout(new QVBoxLayout);
227            mainWindow->setCentralWidget(graphicsView);
228            mainWindow->setGeometry(50, 50, 1024, 768);
229            mainWindow->show();
230            mainWindow->raise();
231        }
232    }
233    else
234    {
235        //-------------------------------------------------------------------
236        // QWidgetImage test
237        //-------------------------------------------------------------------
238        // QWidgetImage still has some issues, some examples are:
239        //
240        // 1. Editing in the QTextEdit doesn't work. Also when started with
241        //    --useBrowser, editing in the search field on YouTube doesn't
242        //    work. But that same search field when using QWebViewImage
243        //    works... And editing in the text field in the pop-up getInteger
244        //    dialog works too. All these cases use QGraphicsViewAdapter
245        //    under the hood, so why do some work and others don't?
246        //
247        //    a) osgQtBrowser --useWidgetImage [--fullscreen] (optional)
248        //    b) Try to click in the QTextEdit and type, or to select text
249        //       and drag-and-drop it somewhere else in the QTextEdit. These
250        //       don't work.
251        //    c) osgQtBrowser --useWidgetImage --sanityCheck
252        //    d) Try the operations in b), they all work.
253        //    e) osgQtBrowser --useWidgetImage --useBrowser [--fullscreen]
254        //    f) Try to click in the search field and type, it doesn't work.
255        //    g) osgQtBrowser
256        //    h) Try the operation in f), it works.
257        //
258        // 2. Operations on floating windows (--numFloatingWindows 1 or more).
259        //    Moving by dragging the titlebar, clicking the close button,
260        //    resizing them, none of these work. I wonder if it's because the
261        //    OS manages those functions (they're functions of the window
262        //    decorations) so we need to do something special for that? But
263        //    in --sanityCheck mode they work.
264        //
265        //    a) osgQtBrowser --useWidgetImage --numFloatingWindows 1 [--fullscreen]
266        //    b) Try to drag the floating window, click the close button, or
267        //       drag its sides to resize it. None of these work.
268        //    c) osgQtBrowser --useWidgetImage --numFloatingWindows 1 --sanityCheck
269        //    d) Try the operations in b), all they work.
270        //    e) osgQtBrowser --useWidgetImage [--fullscreen]
271        //    f) Click the button so that the getInteger() dialog is
272        //       displayed, then try to move that dialog or close it with the
273        //       close button, these don't work.
274        //    g) osgQtBrowser --useWidgetImage --sanityCheck
275        //    h) Try the operation in f), it works.
276        //
277        // 3. (Minor) The QGraphicsView's scrollbars don't appear when
278        //    using QWidgetImage or QWebViewImage. QGraphicsView is a
279        //    QAbstractScrollArea and it should display scrollbars as soon as
280        //    the scene is too large to fit the view.
281        //
282        //    a) osgQtBrowser --useWidgetImage --fullscreen
283        //    b) Resize the OSG window so it's smaller than the QTextEdit.
284        //       Scrollbars should appear but don't.
285        //    c) osgQtBrowser --useWidgetImage --sanityCheck
286        //    d) Try the operation in b), scrollbars appear. Even if you have
287        //       floating windows (by clicking the button or by adding
288        //       --numFloatingWindows 1) and move them outside the view,
289        //       scrollbars appear too. You can't test that case in OSG for
290        //       now because of problem 2 above, but that's pretty cool.
291        //
292        // 4. (Minor) In sanity check mode, the widget added to the
293        //    QGraphicsView is centered. With QGraphicsViewAdapter, it is not.
294        //
295        //    a) osgQtBrowser --useWidgetImage [--fullscreen]
296        //    b) The QTextEdit and button are not in the center of the image
297        //       generated by the QGraphicsViewAdapter.
298        //    c) osgQtBrowser --useWidgetImage --sanityCheck
299        //    d) The QTextEdit and button are in the center of the
300        //       QGraphicsView.
301
302
303        QWidget* widget = 0;
304        if (useBrowser)
305        {
306            QWebPage* webPage = new QWebPage;
307            webPage->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
308            webPage->settings()->setAttribute(QWebSettings::PluginsEnabled, true);
309
310            QWebView* webView = new QWebView;
311            webView->setPage(webPage);
312
313            if (arguments.argc()>1) webView->load(QUrl(arguments[1]));
314            else webView->load(QUrl("http://www.youtube.com/"));
315
316            widget = webView;
317        }
318        else
319        {
320            widget = new QWidget;
321            widget->setLayout(new QVBoxLayout);
322
323            QString text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque velit turpis, euismod ac ultrices et, molestie non nisi. Nullam egestas dignissim enim, quis placerat nulla suscipit sed. Donec molestie elementum risus sit amet sodales. Nunc consectetur congue neque, at viverra massa pharetra fringilla. Integer vitae mi sem. Donec dapibus semper elit nec sollicitudin. Vivamus egestas ultricies felis, in mollis mi facilisis quis. Nam suscipit bibendum eros sed cursus. Suspendisse mollis suscipit hendrerit. Etiam magna eros, convallis non congue vel, faucibus ac augue. Integer ante ante, porta in ornare ullamcorper, congue nec nibh. Etiam congue enim vitae enim sollicitudin fringilla. Mauris mattis, urna in fringilla dapibus, ipsum sem feugiat purus, ac hendrerit felis arcu sed sapien. Integer id velit quam, sit amet dignissim tortor. Sed mi tortor, placerat ac luctus id, tincidunt et urna. Nulla sed nunc ante.Sed ut sodales enim. Ut sollicitudin ultricies magna, vel ultricies ante venenatis id. Cras luctus mi in lectus rhoncus malesuada. Sed ac sollicitudin nisi. Nunc venenatis congue quam, et suscipit diam consectetur id. Donec vel enim ac enim elementum bibendum ut quis augue. Nulla posuere suscipit dolor, id convallis tortor congue eu. Vivamus sagittis consectetur dictum. Duis a ante quis dui varius fermentum. In hac habitasse platea dictumst. Nam dapibus dolor eu felis eleifend in scelerisque dolor ultrices. Donec arcu lectus, fringilla ut interdum non, tristique id dolor. Morbi sagittis sagittis volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis venenatis ultrices euismod.Nam sit amet convallis libero. Integer lectus urna, eleifend et sollicitudin non, porttitor vel erat. Vestibulum pulvinar egestas leo, a porttitor turpis ullamcorper et. Vestibulum in ornare turpis. Ut nec libero a sem mattis iaculis quis id purus. Praesent ante neque, dictum vitae pretium vel, iaculis luctus dui. Etiam luctus tellus vel nunc suscipit a ullamcorper nisl semper. Nunc dapibus, eros in sodales dignissim, orci lectus egestas felis, sit amet vehicula tortor dolor eu quam. Vivamus pellentesque convallis quam aliquet pellentesque. Phasellus facilisis arcu ac orci fringilla aliquet. Donec sed euismod augue. Duis eget orci sit amet neque tempor fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In hac habitasse platea dictumst. Duis sollicitudin, lacus ac pellentesque lacinia, lacus magna pulvinar purus, pulvinar porttitor est nibh quis augue.Duis eleifend, massa sit amet mattis fringilla, elit turpis venenatis libero, sed convallis turpis diam sit amet ligula. Morbi non dictum turpis. Integer porttitor condimentum elit, sit amet sagittis nibh ultrices sit amet. Mauris ac arcu augue, id aliquet mauris. Donec ultricies urna id enim accumsan at pharetra dui adipiscing. Nunc luctus rutrum molestie. Curabitur libero ipsum, viverra at pulvinar ut, porttitor et neque. Aliquam sit amet dolor et purus sagittis adipiscing. Nam sit amet hendrerit sem. Etiam varius, ligula non ultricies dignissim, sapien dui commodo urna, eu vehicula enim nunc molestie augue. Fusce euismod, erat vitae pharetra tempor, quam eros tincidunt lorem, ut iaculis ligula erat vitae nibh. Aenean eu ultricies dolor. Curabitur suscipit viverra bibendum.Sed egestas adipiscing mi in egestas. Proin in neque in nibh blandit consequat nec quis tortor. Vestibulum sed interdum justo. Sed volutpat velit vitae elit pulvinar aliquam egestas elit rutrum. Proin lorem nibh, bibendum vitae sollicitudin condimentum, pulvinar ut turpis. Maecenas iaculis, mauris in consequat ultrices, ante erat blandit mi, vel fermentum lorem turpis eget sem. Integer ultrices tristique erat sit amet volutpat. In sit amet diam et nunc congue pellentesque at in dolor. Mauris eget orci orci. Integer posuere augue ornare tortor tempus elementum. Quisque iaculis, nunc ac cursus fringilla, magna elit cursus eros, id feugiat diam eros et tellus. Etiam consectetur ultrices erat quis rhoncus. Mauris eu lacinia neque. Curabitur suscipit feugiat tellus in dictum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed aliquam tempus ante a tempor. Praesent viverra erat quis sapien pretium rutrum. Praesent dictum scelerisque venenatis.Proin bibendum lectus eget nisl lacinia porta. Morbi eu erat in sapien malesuada vulputate. Cras non elit quam. Ut dictum urna quis nisl feugiat ac sollicitudin libero luctus. Donec leo mauris, varius at luctus eget, placerat quis arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam tristique, mauris ut lacinia elementum, mauris erat consequat massa, ac gravida nisi tellus vitae purus. Curabitur consectetur ultricies commodo. Cras pulvinar orci nec enim adipiscing tristique. Ut ornare orci id est fringilla sit amet blandit libero pellentesque. Vestibulum tincidunt sapien ut enim venenatis vestibulum ultricies ipsum tristique. Mauris tempus eleifend varius. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vitae dui ac quam gravida semper. In ac enim ac ligula rutrum porttitor.Integer dictum sagittis leo, at convallis sapien facilisis eget. Etiam cursus bibendum tortor, faucibus aliquam lectus ullamcorper sed. Nulla pulvinar posuere quam, ut sagittis ligula tincidunt ut. Nulla convallis velit ut enim condimentum pulvinar. Quisque gravida accumsan scelerisque. Proin pellentesque nisi cursus tortor aliquet dapibus. Duis vel eros orci. Sed eget purus ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ullamcorper porta congue. Nunc id velit ut neque malesuada consequat in eu nisi. Nulla facilisi. Quisque pellentesque magna vitae nisl euismod ac accumsan tellus feugiat.Nulla facilisi. Integer quis orci lectus, non aliquam nisi. Vivamus varius porta est, ac porttitor orci blandit mattis. Sed dapibus facilisis dapibus. Duis tincidunt leo ac tortor faucibus hendrerit. Morbi sit amet sapien risus, vel luctus enim. Aliquam sagittis nunc id purus aliquam lobortis. Duis posuere viverra dui, sit amet convallis sem vulputate at. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque pellentesque, lectus id imperdiet commodo, diam diam faucibus lectus, sit amet vestibulum tortor lacus viverra eros.Maecenas nec augue lectus. Duis nec arcu eget lorem tempus sollicitudin suscipit vitae arcu. Nullam vitae mauris lectus. Vivamus id risus neque, dignissim vehicula diam. Cras rhoncus velit sed velit iaculis ac dignissim turpis luctus. Suspendisse potenti. Sed vitae ligula a ligula ornare rutrum sit amet ut quam. Duis tincidunt, nibh vitae iaculis adipiscing, dolor orci cursus arcu, vel congue tortor quam eget arcu. Suspendisse tellus felis, blandit ac accumsan vitae, fringilla id lorem. Duis tempor lorem mollis est congue ut imperdiet velit laoreet. Nullam interdum cursus mollis. Pellentesque non mauris accumsan elit laoreet viverra ut at risus. Proin rutrum sollicitudin sem, vitae ultricies augue sagittis vel. Cras quis vehicula neque. Aliquam erat volutpat. Aliquam erat volutpat. Praesent non est erat, accumsan rutrum lacus. Pellentesque tristique molestie aliquet. Cras ullamcorper facilisis faucibus. In non lorem quis velit lobortis pulvinar.Phasellus non sem ipsum. Praesent ut libero quis turpis viverra semper. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In hac habitasse platea dictumst. Donec at velit tellus. Fusce commodo pharetra tincidunt. Proin lacus enim, fringilla a fermentum ut, vestibulum ut nibh. Duis commodo dolor vel felis vehicula at egestas neque bibendum. Phasellus malesuada dictum ante in aliquam. Curabitur interdum semper urna, nec placerat justo gravida in. Praesent quis mauris massa. Pellentesque porttitor lacinia tincidunt. Phasellus egestas viverra elit vel blandit. Sed dapibus nisi et lectus pharetra dignissim. Mauris hendrerit lectus nec purus dapibus condimentum. Sed ac eros nulla. Aenean semper sapien a nibh aliquam lobortis. Aliquam elementum euismod sapien, in dapibus leo dictum et. Pellentesque augue neque, ultricies non viverra eu, tincidunt ac arcu. Morbi ut porttitor lectus.");
324
325            if (useLabel)
326            {
327                QLabel* label = new QLabel(text);
328                label->setWordWrap(true);
329                label->setTextInteractionFlags(Qt::TextEditorInteraction);
330
331                QPalette palette = label->palette();
332                palette.setColor(QPalette::Highlight, Qt::darkBlue);
333                palette.setColor(QPalette::HighlightedText, Qt::white);
334                label->setPalette(palette);
335
336                QScrollArea* scrollArea = new QScrollArea;
337                scrollArea->setWidget(label);
338
339                widget->layout()->addWidget(scrollArea);
340            }
341            else
342            {
343                QTextEdit* textEdit = new QTextEdit(text);
344                textEdit->setReadOnly(false);
345                textEdit->setTextInteractionFlags(Qt::TextEditable);
346
347                QPalette palette = textEdit->palette();
348                palette.setColor(QPalette::Highlight, Qt::darkBlue);
349                palette.setColor(QPalette::HighlightedText, Qt::white);
350                textEdit->setPalette(palette);
351
352                widget->layout()->addWidget(textEdit);
353            }
354
355            QPushButton* button = new MyPushButton("Button");
356            widget->layout()->addWidget(button);
357
358            widget->setGeometry(0, 0, 800, 600);
359        }
360
361        QGraphicsScene* graphicsScene = 0;
362
363        if (!sanityCheck)
364        {
365            osg::ref_ptr<osgQt::QWidgetImage> widgetImage = new osgQt::QWidgetImage(widget);
366            widgetImage->getQWidget()->setAttribute(Qt::WA_TranslucentBackground);
367            widgetImage->getQGraphicsViewAdapter()->setBackgroundColor(QColor(0, 0, 0, 0));
368            //widgetImage->getQGraphicsViewAdapter()->resize(800, 600);
369            graphicsScene = widgetImage->getQGraphicsViewAdapter()->getQGraphicsScene();
370
371            osg::Camera* camera = 0;        // Will stay NULL in the inScene case.
372            osg::Geometry* quad = osg::createTexturedQuadGeometry(osg::Vec3(0,0,0), osg::Vec3(1,0,0), osg::Vec3(0,1,0), 1, 1);
373            osg::Geode* geode = new osg::Geode;
374            geode->addDrawable(quad);
375
376            osg::MatrixTransform* mt = new osg::MatrixTransform;
377            if (inScene)
378            {
379                mt->setMatrix(osg::Matrix::rotate(osg::Vec3(0,1,0), osg::Vec3(0,0,1)));
380                mt->addChild(geode);
381            }
382            else    // fullscreen
383            {
384                // The HUD camera's viewport needs to follow the size of the
385                // window. MyInteractiveImageHandler will make sure of this.
386                // As for the quad and the camera's projection, setting the
387                // projection resize policy to FIXED takes care of them, so
388                // they can stay the same: (0,1,0,1) with a quad that fits.
389
390                // Set the HUD camera's projection and viewport to match the screen.
391                camera = new osg::Camera;
392                camera->setProjectionResizePolicy(osg::Camera::FIXED);
393                camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1,0,1));
394                camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
395                camera->setViewMatrix(osg::Matrix::identity());
396                camera->setClearMask(GL_DEPTH_BUFFER_BIT);
397                camera->setRenderOrder(osg::Camera::POST_RENDER);
398                camera->addChild(geode);
399                camera->setViewport(0, 0, 1024, 768);
400
401                mt->addChild(camera);
402            }
403
404            mt->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
405            mt->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
406            mt->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
407            mt->getOrCreateStateSet()->setAttribute(new osg::Program);
408
409            osg::Texture2D* texture = new osg::Texture2D(widgetImage.get());
410            texture->setResizeNonPowerOfTwoHint(false);
411            texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
412            texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
413            texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
414            mt->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
415
416            osg::Group* overlay = new osg::Group;
417            overlay->addChild(mt);
418
419            root->addChild(overlay);
420
421            osgViewer::InteractiveImageHandler* handler = new osgViewer::InteractiveImageHandler(widgetImage.get(), camera);
422            quad->setEventCallback(handler);
423            quad->setCullCallback(handler);
424        }
425        else
426        {
427            // Sanity check, do the same thing as QWidgetImage and
428            // QGraphicsViewAdapter but in a separate Qt window.
429
430            graphicsScene = new QGraphicsScene;
431            graphicsScene->addWidget(widget);
432
433            QGraphicsView* graphicsView = new QGraphicsView;
434            graphicsView->setScene(graphicsScene);
435
436            QMainWindow* mainWindow = new QMainWindow;
437            mainWindow->setCentralWidget(graphicsView);
438            mainWindow->setGeometry(50, 50, 1024, 768);
439            mainWindow->show();
440            mainWindow->raise();
441        }
442
443        // Add numFloatingWindows windows to the graphicsScene.
444        for (unsigned int i = 0; i < (unsigned int)numFloatingWindows; ++i)
445        {
446            QWidget* window = new QWidget(0, Qt::Window);
447            window->setWindowTitle(QString("Window %1").arg(i));
448            window->setLayout(new QVBoxLayout);
449            window->layout()->addWidget(new QLabel(QString("This window %1").arg(i)));
450            window->layout()->addWidget(new MyPushButton(QString("Button in window %1").arg(i)));
451            window->setGeometry(100, 100, 300, 300);
452
453            QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(0, Qt::Window);
454            proxy->setWidget(window);
455            proxy->setFlag(QGraphicsItem::ItemIsMovable, true);
456
457            graphicsScene->addItem(proxy);
458        }
459
460    }
461
462    root->addChild(osgDB::readNodeFile("cow.osg.(15,0,5).trans.(0.1,0.1,0.1).scale"));
463
464    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(arguments);
465    viewer->setSceneData(root.get());
466    viewer->setCameraManipulator(new osgGA::TrackballManipulator());
467    viewer->addEventHandler(new osgGA::StateSetManipulator(root->getOrCreateStateSet()));
468    viewer->addEventHandler(new osgViewer::StatsHandler);
469    viewer->addEventHandler(new osgViewer::WindowSizeHandler);
470
471    viewer->setUpViewInWindow(50, 50, 1024, 768);
472    viewer->getEventQueue()->windowResize(0, 0, 1024, 768);
473
474    if (useFrameLoopThread)
475    {
476        // create a thread to run the viewer's frame loop
477        ViewerFrameThread viewerThread(viewer.get(), true);
478        viewerThread.startThread();
479
480        // now start the standard Qt event loop, then exists when the viewerThead sends the QApplication::exit() signal.
481        return QApplication::exec();
482
483    }
484    else
485    {
486        // run the frame loop, interleaving Qt and the main OSG frame loop
487        while(!viewer->done())
488        {
489            // process Qt events - this handles both events and paints the browser image
490            QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
491
492            viewer->frame();
493        }
494
495        return 0;
496    }
497}
Note: See TracBrowser for help on using the browser.