Hi,

Assuming I understand you correctly you added something like this to class GraphicsWindowWX:

   void setViewer(osgViewer::Viewer *v) { _viewer = v; }
   void setView() { _viewer->getCamera()->setViewMatrixAsLookAt(
osg::Vec3(450.,-450.,1200.),osg::Vec3(450.,450.,0.),osg::Vec3(0.,0.,1.)); };
   osg::ref_ptr<osgViewer::Viewer> _viewer;

You also added the setView method() but that's not necessary to cause a crash, as the above reproduces something similar to what you get, I think.

The problem is that the GraphicsWindowWX is destructed twice on exit. Once because it is a child window of the top-level wxFrame, which automatically destroys its children on exit. And once because osg::Camera holds a reference to it whose count goes to zero when the Camera is destructed. So the ref_ptr to osgViewer::Viewer is unref()'ed once too often, causing other problems with destruction of instances the Viewer holds references to:

(gdb) bt
#0 0x005d4715 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6 #1 0x00e659a9 in ~View (this=0x8e7322c) at /usr/lib/gcc/i386-redhat-linux/4.0.2/../../../../include/c++/4.0.2/bits/basic_string.h:227
#2  0x0805357b in osg::Referenced::unref ()
#3  0x08054862 in osg::ref_ptr<osgViewer::Viewer>::~ref_ptr ()
#4  0x08051de6 in GraphicsWindowWX::~GraphicsWindowWX ()
#5 0x00d0a78d in ~Camera (this=0x8e73380) at /home/paul/c/osg-2.4.0/include/osg/Referenced:155
#6  0x0805357b in osg::Referenced::unref ()
#7 0x00e66cd3 in ~View (this=0x8e7322c, __vtt_parm=0x2ab550) at /home/paul/c/osg-2.4.0/include/osg/ref_ptr:54 #8 0x00267f71 in ~View (this=0x8e7322c, __vtt_parm=0x2ab54c) at /home/paul/c/osg-2.4.0/src/osgViewer/View.cpp:169 #9 0x0027b3eb in ~Viewer (this=0x8e731e8) at /home/paul/c/osg-2.4.0/src/osgViewer/Viewer.cpp:172
#10 0x0805357b in osg::Referenced::unref ()
#11 0x08054862 in osg::ref_ptr<osgViewer::Viewer>::~ref_ptr ()
#12 0x08051de6 in GraphicsWindowWX::~GraphicsWindowWX ()
#13 0x00b6b439 in wxWindowBase::DestroyChildren () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #14 0x00a815b8 in wxWindow::~wxWindow () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #15 0x00b66032 in wxTopLevelWindowBase::~wxTopLevelWindowBase () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #16 0x00a77326 in wxTopLevelWindowGTK::~wxTopLevelWindowGTK () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #17 0x00b220dd in wxFrameBase::~wxFrameBase () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #18 0x00acd75f in wxFrame::~wxFrame () from /usr/lib/libwx_gtk2u_core-2.6.so.0
#19 0x080549e6 in MainFrame::~MainFrame ()
#20 0x00afdf57 in wxAppBase::DeletePendingObjects () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #21 0x00afdfb7 in wxAppBase::OnIdle () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #22 0x0030d55d in wxAppConsole::HandleEvent () from /usr/lib/libwx_baseu-2.6.so.0 #23 0x0039649f in wxEvtHandler::ProcessEventIfMatches () from /usr/lib/libwx_baseu-2.6.so.0 #24 0x00396670 in wxEventHashTable::HandleEvent () from /usr/lib/libwx_baseu-2.6.so.0 #25 0x00396821 in wxEvtHandler::ProcessEvent () from /usr/lib/libwx_baseu-2.6.so.0 #26 0x00afe210 in wxAppBase::ProcessIdle () from /usr/lib/libwx_gtk2u_core-2.6.so.0
#27 0x00a53003 in ?? () from /usr/lib/libwx_gtk2u_core-2.6.so.0
#28 0x006a0730 in ?? () from /usr/lib/libglib-2.0.so.0
#29 0x0069e4ce in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#30 0x006a14d6 in ?? () from /usr/lib/libglib-2.0.so.0
#31 0x006a17c3 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#32 0x02109a46 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0
#33 0x00a6c204 in wxEventLoop::Run () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #34 0x00afdaaa in wxAppBase::MainLoop () from /usr/lib/libwx_gtk2u_core-2.6.so.0 #35 0x00afdb8f in wxAppBase::OnRun () from /usr/lib/libwx_gtk2u_core-2.6.so.0
#36 0x00341a44 in wxEntry () from /usr/lib/libwx_baseu-2.6.so.0
#37 0x00341afa in wxEntry () from /usr/lib/libwx_baseu-2.6.so.0
#38 0x08050c81 in main ()

I don't think there's an easy way out for this one, as wxWidgets uses a different memory management strategy than OSG. Even removing the GraphicsWindowWX as child of the main frame just before exit forces destruction. IMHO GraphicsWindowWX shouldn't inherit from both a wxWidgets class and an OSG class, as the former uses explicit memory management, while the latter uses an implicit style (through osg::Referenced and osg::ref_ptr).

A better solution would probably be to split GraphicsWindowWX into a class derived from wxGLCanvas and one derived from osgViewer::GraphicsWindow. The latter would then need to define some custom events for the different events handled by GraphicsWindow and use wxPostEvent to post these to the derived canvas class. But I'd need to try it out to see how this works out.

Paul


Jose Marti wrote:
i've used the osgViewerWX example for my program and I'd like to change the camera view inside the GraphicsWindowsWX class. I've done this:

- I pass the viewer to GraphicsWindowsWX in function wxOsgApp::OnInit().
    frame->SetViewer(viewer.get());
    gw->setViewer(viewer.get());
Where does setViewer() come from, and what does it do?
And I set the new camera view in class GraphicsWindowWX.

void GraphicsWindowWX::setView()
{
        _viewer->getCamera()->setViewMatrixAsLookAt(
osg::Vec3(450.,-450.,1200.),osg::Vec3(450.,450.,0.),osg::Vec3(0.,0.,1.));
}
Where is setView() called?


It works fine, but when I close the program, it crashes and i got this message in the console window:


'Warning: deleting still referenced object 08E57B70 of tye 'class osg::Referenced *' the final reference count was 1189214347, memory corruption possible.

What am I doing wrong??
Hard to say, as you don't provide enoug details to go on.
But if you're storing the osgViewer::Viewer instance in GraphicsWindowWX (which seems to be what you do).

Paul
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to