Hi Manu,
I'm doing the very same thing, but with two views of a same scene on every
tab. Currently it works well, but I suspect there are duplicated resources, so
I have to say that my code is not in its final version.
I'm attaching it, it works for me on Linux and wx 2.6.3 unmodified.
Feel free to compare it with yours so we can learn together :)
HTH,
Alberto
El Thursday 25 October 2007 12:37:45 Emmanuel Roche escribió:
> Hello everyone!
>
> I've got a simple question, but I can't find any practical solution:
>
> In my application, I have to display a notebook with a 3D window on each
> tab... and I want to be able to add/remove tabs dynamically... so, what can
> I use to achieve this result ?
>
> I'm usig wxWidgets + OSG 2.2.0
> I'm on Win XP
>
> I tried with a CompositeViewer :
> - creating the conpositeViewer when requested (so everything should be in
> the wx event handling thread...)
> - building my graphicswindowWX
> - creating a view
> - adding this view to the compositeview
> - relying on an Idle function to call viewer->frame()...
>
> ... this works as long as there is a single tab... but when I had others,
> then only the last tab added display something : the others only display
> the blue background with no model anymore... ? why that ??
>
> by the way I had to make a small change in the
> GraphicsWindowWx::makeCurrentImplementation() :
>
> bool GraphicsWindowWX::makeCurrentImplementation() {
> // Bouml preserved body begin 0001FE83
> if(!GetParent()->IsShown())
> return false;
>
> SetCurrent();
> return true;
> // Bouml preserved body end 0001FE83
> }
>
> --> So the hidden tabs should return false here... could this be the source
> of the problem ?? (anyway wxWidgets doesn't accept SetCurrent() when the
> corresponding tab is not visible... :-S )
>
> regards !
>
> Thanks for your help !
> Manu.
#include "wx/wx.h"
#include "wx/glcanvas.h"
#include "osg/ref_ptr"
#include "osg/Vec3"
#include "osg/GraphicsContext"
#include "osgViewer/GraphicsWindow"
#include "osgViewer/CompositeViewer"
#include "osgViewer/Viewer"
#include "osgViewer/View"
#include "osgDB/ReadFile"
#include "osgGA/TrackballManipulator"
#include <iostream>
osg::State *st2;
osg::State *st1;
class programa: public wxApp
{
public:
bool OnInit();
};
DECLARE_APP( programa)
IMPLEMENT_APP( programa)
class ventanaOSGWX: public osgViewer::GraphicsWindow
{
public:
ventanaOSGWX( wxGLCanvas *wx): wxGL( wx)
{
}
bool makeCurrentImplementation()
{
wxGL->SetCurrent();
return true;
}
void swapBuffersImplementation()
{
wxGL->SwapBuffers();
}
bool realizeImplementation()
{
return true;
}
bool valid() const
{
return true;
}
bool isRealizedImplementation() const
{
return true;
}
void closeImplementation()
{
}
bool releaseContextImplementation()
{
return true;
}
void grabFocus()
{
wxGL->SetFocus();
}
void grabFocusIfPointerInWindow()
{
wxGL->SetFocus();
}
private:
wxGLCanvas *wxGL;
};
class ventana: public wxPanel
{
public:
ventana( wxWindow *p, const std::string &objeto);
void OnPaint( wxPaintEvent &e);
private:
osg::ref_ptr<ventanaOSGWX> v1, v2;
osgViewer::CompositeViewer *cViewer;
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE( ventana, wxPanel)
EVT_PAINT( ventana::OnPaint)
END_EVENT_TABLE()
bool programa::OnInit()
{
wxFrame *v = new wxFrame(0, wxID_ANY, wxT("Dos vistas con OSG"), wxDefaultPosition, wxSize( 540,305)); /* No vale con el ctor por defecto */
wxNotebook *nb = new wxNotebook( v, wxID_ANY);
ventana *panel1 = new ventana( nb, "cubo_flechas.obj");
ventana *panel2 = new ventana( nb, "prototipo.ive");
nb->AddPage( panel1, wxT("Primero"), true);
nb->AddPage( panel2, wxT("Segundo"), false);
v->Show();
return true;
}
ventana::ventana( wxWindow *p, const std::string &objeto): wxPanel( p)
{
wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL);
SetSizer( sizer);
wxGLCanvas *w1, *w2;
wxGLContext *wxglc;
w1 = new wxGLCanvas( this, 1, wxDefaultPosition, wxSize(256,256));
Show(); /* Para que se cree de manera efectiva el contexto de OpenGL */
/* Genera una advertencia de GTK acerca de un widget todavía no constuído, posiblemente porque */
/* se ordena mostrar el "wxFrame" cuando todavía no se ha salido de su constructor. Una solución */
/* posiblemente más limpia sería crear la segunda ventana en el primer evento de redibujado, */
/* mediante un bool que indique si ya estaba creado o no. */
wxglc = w1->GetContext();
w2 = new wxGLCanvas( this, wxglc, 2, wxDefaultPosition, wxSize(256,256));
sizer->Add( w1, 0, wxALL, 5);
sizer->Add( w2, 0, wxALL, 5);
sizer->Fit( this);
v1 = new ventanaOSGWX( w1);
v2 = new ventanaOSGWX( w2);
cViewer = new osgViewer::CompositeViewer;
osgViewer::View *view1, *view2;
view1 = new osgViewer::View;
view2 = new osgViewer::View;
st1 = new osg::State;
st2 = new osg::State;
st1->setContextID( osg::GraphicsContext::createNewContextID());
// Si st2 usa el mismo ID que st1, hay que llamar a incrementContextIDUsageCount
st2->setContextID( osg::GraphicsContext::createNewContextID());
v1->setState( st1);
st1->setGraphicsContext( v1.get());
v2->setState( st2);
st2->setGraphicsContext( v2.get());
view1->getCamera()->setGraphicsContext( v1.get());
view2->getCamera()->setGraphicsContext( v2.get());
view1->getCamera()->setViewport(0,0,256,256);
view1->getCamera()->setProjectionMatrixAsPerspective(30.0f, 1.0, 1.0, 1000.0);
view1->getCamera()->setViewMatrixAsLookAt(osg::Vec3(-10,-10,-10), osg::Vec3(0,0,0),osg::Vec3(0,0,1));
view2->getCamera()->setViewport(0,0,256,256);
view2->getCamera()->setProjectionMatrixAsPerspective(30.0f, 1.0, 1.0, 1000.0);
view2->getCamera()->setViewMatrixAsLookAt(osg::Vec3(-10,+10,-10), osg::Vec3(0,0,0),osg::Vec3(0,0,1));
osg::Node *nodo = osgDB::readNodeFile( objeto);
view1->setSceneData( nodo);
view2->setSceneData( nodo);
cViewer->addView( view1);
cViewer->addView( view2);
}
void ventana::OnPaint( wxPaintEvent &e)
{
wxPaintDC dc(this);
cViewer->frame();
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org