osgEarth嵌入winform中

osgearth嵌入winform效果

嵌入效果

源码下载

http://download.csdn.net/download/oXingShuJun/12591792

  • 流程

1.首先,建立一个C++ CLR工程 OSGCLRDLL。

2.建立一个OSGWrapper用来封装基本的osgEarth的C++代码。

OSGWrapper.h 文件

#pragma once
#include <windows.h>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/api/win32/GraphicsWindowWin32>
#include <osgGA/TrackballManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgDB/DatabasePager>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <string>
#include <osgGA/StateSetManipulator>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarth/Map>
#include <osgEarth/MapNode>
#include <osgEarthDrivers/tms/TMSOptions>

#include <osgEarthDrivers/model_feature_geom/FeatureGeomModelOptions>
#include <osgEarthDrivers/feature_ogr/OGRFeatureOptions>
#include <osgEarthDrivers/cache_filesystem/FileSystemCache>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/GeodeticGraticule>
#include <osgEarthUtil/LatLongFormatter>
#include <osgEarthUtil/Controls>
#include <osgEarthUtil/MouseCoordsTool>
#include <osgEarthUtil/AutoClipPlaneHandler>
#include <osg/PositionAttitudeTransform>
#include <osg/Group>
#include <osg/Node>
#include <osgDB/ReadFile>

#include <osgEarth/ImageLayer>
#include <osgEarth/Notify>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ExampleResources>
#include <osgEarth/MapNode>
#include <osgEarth/ThreadingUtils>
#include <osgEarth/Metrics>



using namespace osgEarth::Util;
class OSGWrapper
{
public:
	OSGWrapper(HWND hWnd);
	~OSGWrapper();

	void InitOSG(std::string filename);
	void InitManipulators(void);
	void InitSceneGraph(void);
	void InitCameraConfig(void);
	void PreFrameUpdate(void);
	void PostFrameUpdate(void);
	void Done(bool value) { mDone = value; }
	bool Done(void) { return mDone; }

	osg::ref_ptr<osgViewer::Viewer> getViewer() { return viewer; }
	osg::ref_ptr<EarthManipulator> getEm() { return manip; }
	osg::ref_ptr<osg::Group> getRoot() { return mRoot; }
	osg::ref_ptr<osgEarth::Map> getMap() { return mMap; }
	osg::ref_ptr<osgEarth::MapNode> getMapNode() { return mMapNode; }

private:
	bool mDone;
	std::string m_ModelName;
	HWND m_hWnd;
	osg::ref_ptr<osgViewer::Viewer> viewer;
	osg::ref_ptr<osg::Group> mRoot;
	osg::ref_ptr<osg::Node> mModel;
	osg::ref_ptr<osgEarth::Map> mMap;
	osg::ref_ptr<osgEarth::MapNode> mMapNode;

	osg::ref_ptr < EarthManipulator> manip;
};

class CRenderingThread : public OpenThreads::Thread
{
public:
	CRenderingThread(OSGWrapper* ptr);
	CRenderingThread(OSGWrapper * ptr, bool is3dThread);
	virtual ~CRenderingThread();
	void Done(bool);
	bool isEnd();
	void setOsgRuningFlag(bool);
	bool getOsgRuningState();

	virtual void run();

protected:
	OSGWrapper* _ptr;
	bool _done;
	bool _is3Dthread;
	bool _osgRuningFlag;
	bool _osgRuningState;
};

OSGWrapper.cpp文件

#include "pch.h"
#include "OSGWrapper.h"




OSGWrapper::OSGWrapper(HWND hWnd) :
	m_hWnd(hWnd)
{
}

OSGWrapper::~OSGWrapper()
{
	viewer->setDone(true);
	Sleep(100);
	viewer->stopThreading();
    viewer.~ref_ptr();
	delete viewer;
}

void OSGWrapper::InitOSG(std::string modelname)
{
	// Store the name of the model to load
	m_ModelName = modelname;

	// Init different parts of OSG
	InitManipulators();
	InitSceneGraph();
	InitCameraConfig();
}

void OSGWrapper::InitManipulators(void)
{
}

void OSGWrapper::InitSceneGraph(void)
{
	// Init the main Root Node/Group
	mRoot = new osg::Group;

	int argc = 2;
	char* argv[2];

	argv[0] = _pgmptr;
	argv[1] = (char*)m_ModelName.c_str();
	osg::ArgumentParser arguments(&argc, argv);

	// Create the viewer for this window
	viewer = new osgViewer::Viewer();

	// Load the Model from the model name
	mModel = MapNodeHelper().load(arguments, viewer);
	if (!mModel) return;

	// Optimize the model
	osgUtil::Optimizer optimizer;
	optimizer.optimize(mModel);
	optimizer.reset();

	// Add the model to the scene
	mRoot->addChild(mModel);
}

void OSGWrapper::InitCameraConfig(void)
{
	// Local Variable to hold window size data
	RECT rect;

	// Add a Stats Handler to the viewer
	viewer->addEventHandler(new osgViewer::StatsHandler);

	// Get the current window size
	::GetWindowRect(m_hWnd, &rect);

	// Init the GraphicsContext Traits
	osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;

	// Init the Windata Variable that holds the handle for the Window to display OSG in.
	osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);

	// Setup the traits parameters
	traits->x = 0;
	traits->y = 0;
	traits->width = rect.right - rect.left;
	traits->height = rect.bottom - rect.top;
	traits->windowDecoration = false;
	traits->doubleBuffer = true;

	traits->sharedContext = 0;

	traits->setInheritedWindowPixelFormat = true;
	traits->inheritedWindowData = windata;

	// Create the Graphics Context
	osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());

	// Init Master Camera for this View
	osg::ref_ptr<osg::Camera> camera = viewer->getCamera();

	// Assign Graphics Context to the Camera
	camera->setGraphicsContext(gc);

	// Set the viewport for the Camera
	camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));

	// set the draw and read buffers up for a double buffered window with rendering going to back buffer
	camera->setDrawBuffer(GL_BACK);
	camera->setReadBuffer(GL_BACK);

	// Set projection matrix and camera attribtues
	camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	camera->setClearColor(osg::Vec4f(0.0f, 0.0f, 0.0f, 1.0f));
	camera->setProjectionMatrixAsPerspective(
		30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0, 1000.0);

	viewer->setCamera(camera.get());

	osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode(mRoot);
	mMapNode = mapNode;
	osgEarth::Map* map = mapNode->getMap();
	mMap = map;
	double equatorRadius = map->getSRS()->getEllipsoid()->getRadiusEquator();
	viewer->getCamera()->addCullCallback(new osgEarth::Util::AutoClipPlaneCullCallback(mapNode));

	manip = new EarthManipulator();
	manip->setHomeViewpoint(osgEarth::Util::Viewpoint("北京", 116.3, 39.9, 0, 0, -90, equatorRadius * 4));
	viewer->setCameraManipulator(manip);

	// Set the Scene Data
	viewer->setSceneData(mRoot);
	viewer->setThreadingModel(osgViewer::ViewerBase::ThreadingModel::SingleThreaded);

	viewer->addEventHandler(new osgViewer::StatsHandler);
	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
	viewer->addEventHandler(new osgViewer::ThreadingHandler);
	viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
	viewer->addEventHandler(new osgViewer::LODScaleHandler);
	viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
	viewer->realize();
}

void OSGWrapper::PreFrameUpdate()
{
	// Due any preframe updates in this routine
}

void OSGWrapper::PostFrameUpdate()
{
	// Due any postframe updates in this routine
}

CRenderingThread::CRenderingThread(OSGWrapper* ptr)
	: OpenThreads::Thread(), _ptr(ptr), _done(false)
{
	_osgRuningFlag = true;
	_osgRuningState = true;
}
CRenderingThread::CRenderingThread(OSGWrapper* ptr, bool is3dThread)
	: OpenThreads::Thread(), _ptr(ptr), _done(false)
{
	_is3Dthread = is3dThread;
	_osgRuningFlag = true;
	_osgRuningState = true;
}

CRenderingThread::~CRenderingThread()
{
	_done = true;
	if (isRunning())
	{
		cancel();
		join();
	}
}

void CRenderingThread::Done(bool flag)
{
	_done = flag;
}

void  CRenderingThread::setOsgRuningFlag(bool b)
{
	_osgRuningFlag = b;
}

bool  CRenderingThread::getOsgRuningState()
{
	return _osgRuningState;
}
bool CRenderingThread::isEnd()
{
	osgViewer::Viewer* viewer = _ptr->getViewer();
	if (!testCancel() && !viewer->done() && !_done)
		return false;
	else
		return true;
}

void CRenderingThread::run()
{
	if (!_ptr)
	{
		_done = true;
		return;
	}

	osgViewer::Viewer* viewer = _ptr->getViewer();
	do
	{
		if (_osgRuningFlag)
		{
			_ptr->PreFrameUpdate();
			viewer->frame();
			_ptr->PostFrameUpdate();
			_osgRuningState = true;
		}
		else
		{
			_osgRuningState = false;
			Sleep(5);
		}
	} while (!testCancel() && !viewer->done() && !_done);
}

 3.封装C#调用接口

osgclr.h文件

#pragma once

#include "OSGWrapper.h"

using namespace System;
using namespace System::Runtime::InteropServices;


namespace OSGCLR {
	public ref class OSGCLRDLL
	{
		// TODO: 在此处为此类添加方法。

	private:
		static OSGCLRDLL m_instance;

	public:
		static property OSGCLRDLL^ Instance { OSGCLRDLL^ get() { return %m_instance; } }

		int   InitDLL(IntPtr _hwnd2, bool is3D);
	};
}

osgclr.cpp文件

#include "pch.h"

#include "OSGCLR.h"

namespace OSGCLR 
{
	OSGWrapper* mOSG3D = nullptr;                                       //三维地图osg
	OSGWrapper* mOSG2D = nullptr;                                       //二维地图osg

	CRenderingThread* m3DThreadHandle = nullptr;					    //三维地图线程
	CRenderingThread* m2DThreadHandle = nullptr;					    //二维地图线程
}


int OSGCLR::OSGCLRDLL::InitDLL(IntPtr _hwnd2, bool is3D)
{
	HWND _hwnd = (HWND)_hwnd2.ToPointer();
	if (is3D)
	{
		//通过传入的句柄初始化cOSG对象
		mOSG3D = new OSGWrapper(_hwnd);
		mOSG3D->InitOSG("Earth3D.earth");

		//创建渲染线程并开始渲染
		m3DThreadHandle = new CRenderingThread(mOSG3D, false);
		m3DThreadHandle->start();
	}
	else
	{
		//通过传入的句柄初始化cOSG对象
		mOSG2D = new OSGWrapper(_hwnd);
		mOSG2D->InitOSG("Map2D.earth");
		double fov, ratio, near1, far1;
		mOSG2D->getViewer()->getCamera()->getProjectionMatrixAsPerspective(fov, ratio, near1, far1);
		mOSG2D->getViewer()->getCamera()->setProjectionMatrixAsPerspective(7.5, ratio, near1, far1);

		//创建渲染线程并开始渲染
		m2DThreadHandle = new CRenderingThread(mOSG2D, true);
		m2DThreadHandle->start();
	}
	return 0;
}

4.新建一个winfrom程序,调用clr接口,调用前请先引用osgclr.dll

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace OSGWinForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            OSGCLR.OSGCLRDLL oSGCLRDLL = OSGCLR.OSGCLRDLL.Instance;
            oSGCLRDLL.InitDLL(this.Handle, true);
        }

    }
}

 

 

 

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值