hi i wrote a basic program to display a osg file. and then make it to be a page
in a wxNoteBook Control.
but, it only display the background color without the scene data.
following is the code :
1. open osg file and add a new page
//this is the code of an event handler to a menu item in mainframe
wxFileDialog fd(this,wxT("Please Select Your OSG File"),
wxEmptyString,wxEmptyString,wxT("OSG File(*.osg)|*.osg"),wxOPEN);
int result=fd.ShowModal();
if(wxID_OK==result)
{
wxOSGSceneCanvas* canvas=new wxOSGSceneCanvas(_viewer.get(),pSceneBook);
osg::Node* node=osgDB::readNodeFile(string(fd.GetPath().mb_str()));
wxOSGSceneCanvas::View *view=new wxOSGSceneCanvas::View();
view->setSceneData(node);
canvas->setView(view);
//pSceneBook is a wxNoteBook Control
pSceneBook->AddPage (canvas,fd.GetFilename(),true);
}
2.wxOSGSceneCanvas.h
//wxOSGSceneCanvas derived from wxGLCanvas.
#include <string>
#include <osg/Geode>
#include <osg/Node>
#include <osg/Geometry>
#include <osgDB/Registry>
#include <osgDB/WriteFile>
#include <osg/Notify>
#include <osg/ref_ptr>
#include <osgViewer/Viewer>
#include <osgUtil/SceneView>
#include "wx/defs.h"
#include "wx/app.h"
#include "wx/cursor.h"
#include "wx/glcanvas.h"
#include "wxscenecanvas.h"
using namespace osg;
using namespace std;
class wxOSGSceneCanvas :
public wxGLCanvas
{
public:
wxOSGSceneCanvas(osgViewer::CompositeViewer* viewer,wxWindow*
parent=(wxWindow*)NULL,
wxWindowID id=wxID_ANY,
const wxPoint &pos=wxDefaultPosition,
const wxSize &size=wxDefaultSize,
const wxString &name=wxT("OSG"),
long style=0,
int *attributes=0
);
virtual ~wxOSGSceneCanvas();
class View : public osgViewer::View
{
public:
View();
void requestRedraw();
void requestContinuousUpdate(bool needed=true);
void requestWarpPointer(float x,float y);
private:
void setCanvas(wxOSGSceneCanvas* _canvas);
friend class wxOSGSceneCanvas;
wxOSGSceneCanvas* _canvas;
};
void setView(View* view);
void updateWhenIdle(bool update);
void setUpdateWhenIdleOverride(bool status);
void OnPaint(wxPaintEvent& event);
void OnEraseBackground(wxEraseEvent& event);
void OnIdle(wxIdleEvent& event);
void OnSize(wxSizeEvent& event);
void OnMouse(wxMouseEvent &event);
void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
void OnKey(wxKeyEvent& event);
void OnShow(wxShowEvent& event);
private:
osg::ref_ptr<osgViewer::CompositeViewer> _viewer;
osg::ref_ptr<View> _view;
class GraphicsContext : public osgViewer::GraphicsWindow
{
protected:
virtual ~GraphicsContext();
public:
GraphicsContext(wxOSGSceneCanvas* canvas);
void detachFromCanvas();
bool valid() const;
bool realizeImplementation();
bool isRealizedImplementation() const;
void closeImplementation();
bool makeCurrentImplementation();
bool makeContextCurrentImplementation(osg::GraphicsContext *context);
bool releaseContextImplementation();
void bindPBufferToTextureImplementation(GLenum buffer);
void swapBuffersImplementation();
wxGLContext* getWxContext();
unsigned int getGlContext();
private:
wxGLContext* _wxContext;
wxOSGSceneCanvas* _canvas;
static unsigned int _s_glContexts;
unsigned int _glContext;
};
osg::ref_ptr<GraphicsContext> _context;
bool _renderingActive;
int _mouseButtonCaptured;
bool _updateWhenIdle;
bool _updateWhenIdleOverride;
DECLARE_EVENT_TABLE();
};
3.wxOSGSceneCanvas.cpp
#include "wxOSGSceneCanvas.h"
#include <osgGA/TrackballManipulator>
#include <osgviewer/CompositeViewer>
#include <osgViewer/GraphicsWindow>
// ===========================================================================
// Canvas implementation
// ===========================================================================
BEGIN_EVENT_TABLE(wxOSGSceneCanvas, wxGLCanvas)
EVT_ERASE_BACKGROUND(wxOSGSceneCanvas::OnEraseBackground)
EVT_PAINT(wxOSGSceneCanvas::OnPaint)
EVT_IDLE(wxOSGSceneCanvas::OnIdle)
EVT_SIZE(wxOSGSceneCanvas::OnSize)
EVT_MOUSE_EVENTS(wxOSGSceneCanvas::OnMouse)
EVT_MOUSE_CAPTURE_LOST(wxOSGSceneCanvas::OnMouseCaptureLost)
EVT_KEY_DOWN(wxOSGSceneCanvas::OnKey)
EVT_KEY_UP(wxOSGSceneCanvas::OnKey)
EVT_SHOW(wxOSGSceneCanvas::OnShow)
END_EVENT_TABLE()
wxOSGSceneCanvas::wxOSGSceneCanvas(osgViewer::CompositeViewer* viewer,
wxWindow* parent,
wxWindowID id,
const wxPoint &pos,
const wxSize &size,
const wxString &name,
long style,
int *attributes
):wxGLCanvas(parent,id,pos,size,style,name,attributes)
{
_viewer = viewer;
_context = new GraphicsContext(this);
osg::State* state = new osg::State;
state->setContextID(_context->getGlContext());
_context->incrementContextIDUsageCount(_context->getGlContext());
_context->setState(state);
_context->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_renderingActive = true;
_mouseButtonCaptured = 0;
_updateWhenIdle = false;
_updateWhenIdleOverride = false;
}
wxOSGSceneCanvas::~wxOSGSceneCanvas(void)
{
if (_view.valid())
{
_view->setCanvas(NULL);
_viewer->removeView(_view.get());
_view = NULL;
}
_context->detachFromCanvas();
}
void wxOSGSceneCanvas::setView(View* view)
{
if (_view.valid())
{
_viewer->removeView(_view.get());
}
_view = view;
if (_view.valid())
{
_view->setCanvas(this);
_viewer->addView(_view.get());
_view->getCamera()->setGraphicsContext(_context.get());
_view->setCameraManipulator(new osgGA::TrackballManipulator);
}
}
void wxOSGSceneCanvas::updateWhenIdle(bool update)
{
_updateWhenIdle = update;
if (_updateWhenIdle)
{
wxIdleEvent ev;
::wxPostEvent(this, ev);
}
}
void wxOSGSceneCanvas::setUpdateWhenIdleOverride(bool status)
{
_updateWhenIdleOverride = status;
if (_updateWhenIdleOverride)
{
wxIdleEvent ev;
::wxPostEvent(this, ev);
}
}
void wxOSGSceneCanvas::OnPaint(wxPaintEvent& event)
{
// if (!_windowSizeAcknowledged)
// windowSizeChanged();
wxPaintDC dc(this);
_viewer->frame();
}
void wxOSGSceneCanvas::OnEraseBackground(wxEraseEvent& event)
{
}
void wxOSGSceneCanvas::OnIdle(wxIdleEvent& event)
{
if (_updateWhenIdle || _updateWhenIdleOverride)
{
Refresh();
event.RequestMore();
}
}
void wxOSGSceneCanvas::OnSize(wxSizeEvent& event)
{
int width = event.GetSize().x, height = event.GetSize().y;
_view->getEventQueue()->windowResize(0, 0, width, height);
_view->getCamera()->setViewport(0, 0, width, height);
_view->getCamera()->setProjectionMatrixAsPerspective(45.0, (double)width /
(double)height, 1.0, 100.0);
}
void wxOSGSceneCanvas::OnMouse(wxMouseEvent& event)
{
if (!_view.valid())
return;
bool isFocusAction = false;
if (event.ButtonDown())
{
isFocusAction = true;
int button = event.GetButton();
_view->getEventQueue()->mouseButtonPress(event.GetX(), event.GetY(),
button);
}
else if (event.ButtonUp())
{
isFocusAction = true;
int button = event.GetButton();
if (_mouseButtonCaptured == button && GetCapture() == this)
{
ReleaseMouse();
_mouseButtonCaptured = 0;
}
_view->getEventQueue()->mouseButtonRelease(event.GetX(), event.GetY(),
button);
}
else if (event.Dragging())
{
isFocusAction = true;
if (_mouseButtonCaptured == wxMOUSE_BTN_NONE)
{
if (event.LeftIsDown())
_mouseButtonCaptured = wxMOUSE_BTN_LEFT;
else if (event.MiddleIsDown())
_mouseButtonCaptured = wxMOUSE_BTN_MIDDLE;
else if (event.RightIsDown())
_mouseButtonCaptured = wxMOUSE_BTN_RIGHT;
else
assert(false);
CaptureMouse();
}
Refresh();
_view->getEventQueue()->mouseMotion(event.GetX(), event.GetY());
}
else if (event.LeftDClick() || event.MiddleDClick() || event.RightDClick())
{
isFocusAction = true;
int button = event.GetButton();
_view->getEventQueue()->mouseDoubleButtonPress(event.GetX(),
event.GetY(), button);
}
if (isFocusAction)
SetFocus();
}
void wxOSGSceneCanvas::OnKey(wxKeyEvent& event)
{
if (event.GetEventType() == wxEVT_KEY_DOWN)
_view->getEventQueue()->keyPress(event.GetKeyCode());
else if (event.GetEventType() == wxEVT_KEY_UP)
_view->getEventQueue()->keyRelease(event.GetKeyCode());
Refresh();
}
void wxOSGSceneCanvas::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
{
if (GetCapture() == this)
{
wxASSERT(_mouseButtonCaptured != 0);
ReleaseMouse();
_mouseButtonCaptured = 0;
}
}
void wxOSGSceneCanvas::OnShow(wxShowEvent& event)
{
_renderingActive = event.GetShow();
event.Skip();
}
// ===========================================================================
// wxOSGSceneCanvas::GraphicsContext implementation
// ===========================================================================
unsigned int wxOSGSceneCanvas::GraphicsContext::_s_glContexts(0);
wxOSGSceneCanvas::GraphicsContext::GraphicsContext(wxOSGSceneCanvas* canvas)
{
_canvas = canvas;
_wxContext = new wxGLContext(_canvas);
_glContext = _s_glContexts++;
}
wxOSGSceneCanvas::GraphicsContext::~GraphicsContext()
{
assert(_wxContext);
delete _wxContext;
}
void wxOSGSceneCanvas::GraphicsContext::detachFromCanvas()
{
_canvas = NULL;
}
wxGLContext* wxOSGSceneCanvas::GraphicsContext::getWxContext()
{
return _wxContext;
}
unsigned int wxOSGSceneCanvas::GraphicsContext::getGlContext()
{
return _glContext;
}
bool wxOSGSceneCanvas::GraphicsContext::valid() const
{
return _canvas ? _canvas->IsShownOnScreen() : false;
}
bool wxOSGSceneCanvas::GraphicsContext::realizeImplementation()
{
if (_canvas)
{
_canvas->Show(true);
return true;
}else{
return false;
}
}
bool wxOSGSceneCanvas::GraphicsContext::isRealizedImplementation() const
{
return _canvas ? _canvas->IsShownOnScreen() : false;
}
void wxOSGSceneCanvas::GraphicsContext::closeImplementation()
{
osg::notify(osg::WARN) <<
"wxOSGSceneCanvas::GraphicsContext::closeImplementation() : unimplemented" <<
std::endl;
}
bool wxOSGSceneCanvas::GraphicsContext::makeCurrentImplementation()
{
if (_canvas)
{
if (!_canvas->_renderingActive)
return false;
#ifdef HAS_OSG_WXGL_ADDONS
return _canvas->SetCurrent(*_context);
#else
#ifdef _WIN32
SetLastError(0); // utterly clumsy (part I)
_canvas->SetCurrent(*_wxContext);
return GetLastError() == 0; // utterly clumsy (part II)
#else
_canvas->SetCurrent(*_context);
return true; // even worse
#endif //_WIN32
#endif //HAS_OSG_WXGL_ADDONS
}
else
return false;
}
bool
wxOSGSceneCanvas::GraphicsContext::makeContextCurrentImplementation(osg::GraphicsContext*)
{
osg::notify(osg::WARN) <<
"wxOSGSceneCanvas::GraphicsContext::makeContextCurrentImplementation() :
unimplemented" << std::endl;
return false;
}
bool wxOSGSceneCanvas::GraphicsContext::releaseContextImplementation()
{
// osg::notify(osg::WARN) <<
"wxOSGSceneCanvas::GraphicsContext::releaseContextImplementation() :
unimplemented" << std::endl;
return false; // The OSG does not check for the return value anyway
}
void
wxOSGSceneCanvas::GraphicsContext::bindPBufferToTextureImplementation(GLenum
buffer)
{
osg::notify(osg::WARN) <<
"wxOSGSceneCanvas::GraphicsContext::bindPBufferToTextureImplementation() :
unimplemented" << std::endl;
}
void wxOSGSceneCanvas::GraphicsContext::swapBuffersImplementation()
{
if (_canvas)
_canvas->SwapBuffers();
}
// ===========================================================================
// wxOSGSceneCanvas::View implementation
// ===========================================================================
wxOSGSceneCanvas::View::View()
{
_canvas = NULL;
}
void wxOSGSceneCanvas::View::setCanvas(wxOSGSceneCanvas* canvas)
{
_canvas = canvas;
}
void wxOSGSceneCanvas::View::requestRedraw()
{
if (_canvas)
_canvas->Refresh();
}
void wxOSGSceneCanvas::View::requestContinuousUpdate(bool needed)
{
if (_canvas)
_canvas->updateWhenIdle(needed);
}
void wxOSGSceneCanvas::View::requestWarpPointer(float x,float y)
{
osg::notify(osg::WARN) << "wxOSGSceneCanvas::View::requestWarpPointer() :
unimplemented" << std::endl;
}
It is a long piece, hope anyone can help me . I have worked on it for a whole
day!
HAPPY CHINESE NEW YEAR!
best
zhu liangxiong _______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org