在wpf工程中使用osg技术

编程入门 行业动态 更新时间:2024-10-24 23:23:16

在wpf<a href=https://www.elefans.com/category/jswz/34/1769783.html style=工程中使用osg技术"/>

在wpf工程中使用osg技术

我主要想说的是使用的后台的c#代码来添加osg场景。 需要实现:新建一个窗口Window1.xaml,然后在窗口中显示osg场景。 这里比较困难的地方是wpf中使用的是c#,是一种托管代码;而osg的代码是使用c++编写,是一种非托管代码。如何将二者结合起来使用就是最关键的步骤。 看网上说的可以使用C++/CLI可以实现c#和c++的混合编程,但由于一开始我就是写的wpf程序,不想再新建工程,于是想到可以将c++的osg代码写成dll文件,然后在wpf程序中引用便可。
WPF中除主窗口外再新建一个窗口Window1.xaml;再在MainWindow页面上随便画一个按钮 代码如下: public partial class MainWindow : Window     { //注意把 ConsoleApplication1.dll文件放到wpf的debug文件夹下           [DllImport(@"ConsoleApplication1.dll",                 EntryPoint = "osgRunCow", CallingConvention = CallingConvention.Cdecl)]           public static extern void osgRunCow(IntPtr m_hWnd);
          IntPtr handle;//c#中用IntPtr来保存窗口句柄,对应c++中的HWND           Thread th;           public MainWindow()           {                 InitializeComponent();           }           private void Button_Click_1(object sender, RoutedEventArgs e)           {                 Window win = new Window1();//Window1是新建的Window                 win.Show();                 handle = new WindowInteropHelper(win).Handle;//获取窗口句柄,提供给osgRunCow使用                 th = new Thread(new ThreadStart(func));//多开一个线程防止界面假死                 th.Start();           }
          public void func()           {                 osgRunCow(handle);           }     }
dll文件中新建一个module-definition file文件Source.def(add new item->visual c++ ->code->module definition file) 其代码如下(注意没有任何分号): LIBRARY ConsoleApplication1.dll   EXPORTS   osgRunCow  
主文件ConsoleApplication1.cpp的代码如下: // ConsoleApplication1.cpp : Defines the exported functions for the DLL application. //
#include "stdafx.h" #include <osg/Group>
#include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> #include <osgViewer/api/win32/GraphicsWindowWin32>
#include <osgDB/ReadFile>
#include <osgGA/OrbitManipulator> #include <osgGA/StateSetManipulator> #include <osgGA/CameraManipulator> #include <osgGA/KeySwitchMatrixManipulat or> #include <osgGA/GUIEventHandler>
#include <osgUtil/Optimizer> osg::ref_ptr m_Viewer; osg::ref_ptr m_Root; // 场景根节点
void initSG() { // 创建场景分类树树 m_Root = new osg::Group; m_Root->addChild(osgDB::readNodeFile("cow.osg")); // 优化场景数据 //osgUtil::Optimizer optimizer; //optimizer.optimize(m_Root); }
void initCameraCfg(HWND m_hWnd) { // 本地窗口Size RECT rect; // 为窗口创建Viewer m_Viewer = new osgViewer::Viewer(); // 取消Esc键的事件响应 m_Viewer->setKeyEventSetsDone(0); // 获得当前窗口大小 ::GetWindowRect(m_hWnd, &rect); // 初始化图形环境GraphicsContext Traits osg::ref_ptr traits = new osg::GraphicsContext::Traits; // Init the Windata Variable that holds the handle for the Window to display OSG in. osg::ref_ptr windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd); // 设置traits 参数 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->setInheritedWindowPixelF ormat = true; traits->inheritedWindowData = windata; // 创建图形环境Graphics Context osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); { // 根据分辨率确定合适的投影来保证显示的图形不变形 double fovy =0.0;  double aspectRatio =0.0; double zNear =0.0; double zFar= 0.0; m_Viewer->getCamera()->getProjectionMatrixAsPer spective(fovy,aspectRatio,zNear,zFar); double newAspectRatio =double(traits->width)/double(traits->height); double aspectRatioChange = newAspectRatio/aspectRatio; if (aspectRatioChange != 1.0) { m_Viewer->getCamera()->getProjectionMatrix()   *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); } } // 设置相机视口 m_Viewer->getCamera()->setViewport(traits->x,traits->y,traits->width,traits->height); // 为相机分配图形环境 m_Viewer->getCamera()->setGraphicsContext(gc.get()); // 为Viewer的Camera添加操纵器 m_Viewer->setCameraManipulator(new osgGA::OrbitManipulator()); // 设置线程模型 m_Viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded); // 设置场景数据 m_Viewer->setSceneData(m_Root); // 初始化并创建窗口 m_Viewer->realize(); }
void osgStartRender() { m_Viewer->run(); }
void osgRunCow(HWND m_hWnd) { initSG(); initCameraCfg(m_hWnd); osgStartRender(); } 注意:对于托管和非托管我的理解并不深刻,所以使用的时候可能会出现线程安全性问题,但起码我用的时候没出什么问题。
参考工程:ssDlgFrm(网上搜应该可以查到)
有关如何新建dll工程并在wpf中调用可以参照: 有关如何调试dll工程可以参照: @126/blog/static/1087978520102112285825/
感谢每一个愿意分享的人。

更多推荐

在wpf工程中使用osg技术

本文发布于:2024-02-10 13:33:01,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1675714.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:工程   技术   wpf   osg

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!