#pragma once
#include <wx/glcanvas.h>
#include <osgViewer/GraphicsWindow>
class GraphicsWindowWX : public wxGLCanvas, public osgViewer::GraphicsWindow
{
public:
GraphicsWindowWX(wxWindow * parent);
void OnSize(wxSizeEvent & event);
void OnChar(wxKeyEvent & event);
virtual bool makeCurrentImplementation() override;
virtual void swapBuffersImplementation() override;
virtual bool valid() const override { return true; }
virtual bool realizeImplementation() override { return true; }
virtual bool isRealizedImplementation() const override{ return true; }
virtual void closeImplementation() override{}
virtual bool releaseContextImplementation() override{ return true; }
void OnMouseEnter(wxMouseEvent &);
void OnMouseDown(wxMouseEvent &event);
void OnMouseUp(wxMouseEvent &event);
void OnMouseMotion(wxMouseEvent &event);
void OnMouseWheel(wxMouseEvent &event);
private:
wxGLContext * m_pGLContext;
};
#include "GraphicsWindowWX.h"
GraphicsWindowWX::GraphicsWindowWX(wxWindow * parent)
:wxGLCanvas(parent, wxGLAttributes().PlatformDefaults().Defaults().DoubleBuffer())
{
wxGLContextAttrs contextAttr;
contextAttr.PlatformDefaults().OGLVersion(4, 0).CompatibilityProfile().EndList();
m_pGLContext = new wxGLContext(this, nullptr, &contextAttr);
_traits = new GraphicsContext::Traits;
_traits->x = 0;
_traits->y = 0;
_traits->width = 1024;
_traits->height = 800;
if (valid())
{
setState( new osg::State );
getState()->setGraphicsContext(this);
if (_traits.valid() && _traits->sharedContext.valid())
{
getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
incrementContextIDUsageCount( getState()->getContextID() );
}
else
{
getState()->setContextID( osg::GraphicsContext::createNewContextID() );
}
}
Bind(wxEVT_SIZE, &GraphicsWindowWX::OnSize, this);
Bind(wxEVT_CHAR, &GraphicsWindowWX::OnChar, this);
Bind(wxEVT_LEFT_DOWN, &GraphicsWindowWX::OnMouseDown, this);
Bind(wxEVT_MIDDLE_DOWN, &GraphicsWindowWX::OnMouseDown, this);
Bind(wxEVT_RIGHT_DOWN, &GraphicsWindowWX::OnMouseDown, this);
Bind(wxEVT_LEFT_UP, &GraphicsWindowWX::OnMouseUp, this);
Bind(wxEVT_MIDDLE_UP, &GraphicsWindowWX::OnMouseUp, this);
Bind(wxEVT_RIGHT_UP, &GraphicsWindowWX::OnMouseUp, this);
Bind(wxEVT_MOTION, &GraphicsWindowWX::OnMouseMotion, this);
Bind(wxEVT_MOUSEWHEEL, &GraphicsWindowWX::OnMouseWheel, this);
}
void GraphicsWindowWX::OnSize(wxSizeEvent &)
{
int width;
int height;
GetClientSize(&width, &height);
getEventQueue()->windowResize(0, 0, width, height);
resized(0,0,width,height);
}
void GraphicsWindowWX::OnChar(wxKeyEvent &event)
{
int key = event.GetKeyCode();
getEventQueue()->keyPress(key);
}
bool GraphicsWindowWX::makeCurrentImplementation()
{
SetCurrent(*m_pGLContext);
return true;
}
void GraphicsWindowWX::swapBuffersImplementation()
{
SwapBuffers();
}
void GraphicsWindowWX::OnMouseEnter(wxMouseEvent & /*event*/)
{
SetFocus();
}
void GraphicsWindowWX::OnMouseDown(wxMouseEvent &event)
{
getEventQueue()->mouseButtonPress(event.GetX(), event.GetY(),
event.GetButton());
}
void GraphicsWindowWX::OnMouseUp(wxMouseEvent &event)
{
getEventQueue()->mouseButtonRelease(event.GetX(), event.GetY(),
event.GetButton());
}
void GraphicsWindowWX::OnMouseMotion(wxMouseEvent &event)
{
getEventQueue()->mouseMotion(event.GetX(), event.GetY());
}
void GraphicsWindowWX::OnMouseWheel(wxMouseEvent &event)
{
int delta = event.GetWheelRotation() / event.GetWheelDelta() * event.GetLinesPerAction();
getEventQueue()->mouseScroll(
delta>0 ?
osgGA::GUIEventAdapter::SCROLL_UP :
osgGA::GUIEventAdapter::SCROLL_DOWN);
}
#include <wx/wx.h>
#include <wx/frame.h>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include "GraphicsWindowWX.h"
#include <iostream>
#include <osgDB/ReadFile>
#include <osg/Version>
#include <osg/Config>
#include <osgGA/TrackballManipulator>
#include <osgEarth/MapNode>
#include <osgEarth/Registry>
#include <osgEarthDrivers/gdal/GDALOptions>
#include <osgEarth/ImageLayer>
#include <osgEarthUtil/EarthManipulator>
#include <osgGA/StateSetManipulator>
#if 1
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
m_pFrame = new wxFrame(nullptr, wxID_ANY, wxT(""));
wxMenuBar * menuBar = new wxMenuBar();
m_pFrame->SetMenuBar(menuBar);
wxMenu * fileMenu = new wxMenu;
menuBar->Append(fileMenu, "文件");
fileMenu->Append(wxID_OPEN, "Open");
m_pFrame->SetSize(1024, 800);
m_pViewer = new osgViewer::Viewer;
m_pViewer->setThreadingModel(osgViewer::ViewerBase::DrawThreadPerContext);
m_pGW = new GraphicsWindowWX(m_pFrame);
m_pViewer->getCamera()->setGraphicsContext(m_pGW);
m_pViewer->getCamera()->setViewport(0,0, 1024, 800);
m_pViewer->addEventHandler(new osgViewer::StatsHandler);
m_pViewer->setCameraManipulator(new osgEarth::Util::EarthManipulator);
Bind(wxEVT_IDLE, &MyApp::OnIdle, this);
Bind(wxEVT_COMMAND_MENU_SELECTED, &MyApp::OnFileOpen, this, wxID_OPEN);
osgEarth::Registry::instance()->overrideTerrainEngineDriverName() = "mp";
osgEarth::MapNode * mapNode = new osgEarth::MapNode;
osgEarth::Drivers::GDALOptions opt;
opt.url() = "/Users/cc/Pro/osgearth-osgearth-2.10.2/data/world.tif";
osgEarth::ImageLayer * layer = new osgEarth::ImageLayer(opt);
mapNode->getMap()->addLayer(layer);
m_pViewer->setSceneData(mapNode);
m_pViewer->addEventHandler(new osgGA::StateSetManipulator(mapNode->getOrCreateStateSet()));
m_pFrame->Show();
return true;
}
void OnIdle(wxIdleEvent & event)
{
if (!m_pViewer->isRealized())
return;
m_pViewer->frame();
event.RequestMore();
}
void OnFileOpen(wxCommandEvent &)
{
wxFileDialog dlg(m_pFrame);
dlg.ShowModal();
wxArrayString fileNames;
dlg.GetPaths(fileNames);
if (fileNames.IsEmpty())
{
return;
}
osg::Node * node = osgDB::readNodeFile(fileNames.at(0));
if (node != nullptr)
{
m_pViewer->setSceneData(node);
}
}
private:
osgViewer::Viewer * m_pViewer;
wxFrame * m_pFrame;
GraphicsWindowWX * m_pGW;
};
int main(int argc, char ** argv)
{
MyApp * app = new MyApp;
wxApp::SetInstance(app);
return wxEntry(argc, argv);
}
#else
int main()
{
osgViewer::Viewer viewer;
viewer.setSceneData(osgDB::readNodeFile("/Users/cc/Pro/F-16.ive"));
viewer.run();
}
#endif