前几天研究了WPF开发UI COM组件,今天结合OSG给大家演示一下如何开发OSG的UI COM组件。
我这里的OSG环境是之前搭建好的,编译的是64位的。环境没有搭建好可以参考如下网站:
OSG+VS2015+Win10配置
https://blog.csdn.net/wangshubo1989/article/details/51591802
win10 + VS2015 + 64位OSG3.4.0
https://www.cnblogs.com/smbx-ztbz/p/7197983.html
1.首先虚构32位的UI COM组件,以管理员启动VS,新建项目
2.设置32位的环境
3.在OnDraw中添加如下代码
void CGViewCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& /* rcInvalid */)
{
if (!pdc)
return;
// TODO: 用您自己的绘图代码替换下面的代码。
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
//pdc->SetBkColor(RGB(255, 0, 0));//背景颜色
pdc->SetBkMode(TRANSPARENT);//背景模式
RECT rect;
GetWindowRect(&rect);
double x = ((rect.right - rect.left) - 11) / 2.0;
double y = ((rect.bottom - rect.top) - 2) / 2.0;
pdc->SetTextColor(RGB(0, 255, 0));
pdc->SetTextAlign(TA_LEFT | TA_BOTTOM);//设置文本对齐方式
pdc->TextOut(x, y, _T("GView 64位"));
}
4.注册32位COM组件
注册
regsvr32 "F:\MyCode\COM\Release\x86\GView.ocx"
注销:
regsvr32 -u "F:\MyCode\COM\Release\x86\GView.ocx"
5.C#加载32位COM组件,设计效果(和运行效果相同)如下
6.以管理员启动VS,新建项目
7.设置64位环境
8.链接OSG开发环境
连接器->输入->添加依赖项
osgViewer.lib
osgText.lib
opengl32.lib
osgGA.lib
osgDB.lib
osgUtil.lib
osg.lib
OpenThreads.lib
9.编译通过后,添加消息
10.在GViewCtrl.h中添加引用
#include<osgViewer/Viewer>
#include<osgDB/ReadFile>
#include <osgViewer/viewer>
#include <osg/Node>
#include <osg/geode>
#include <osg\group>
#include <osgDB/readfile>
#include <osgDB/writefile>
#include <osgUtil\optimizer>
#include <osgViewer/api/win32/GraphicsWindowWin32>
定义变量
osg::ref_ptr<osgViewer::Viewer> viewer;
bool m_flag; //设置方法只执行一次
申明方法
void configViewer(HWND hWnd);
static DWORD WINAPI ThreadRun(LPVOID lparam);
11.在GViewCtrl.cpp中实现(直接上代码)
// 构造函数
CGViewCtrl::CGViewCtrl()
{
InitializeIIDs(&IID_DGView, &IID_DGViewEvents);
// TODO: 在此初始化控件的实例数据。
viewer = new osgViewer::Viewer;
m_flag = true;
}
void CGViewCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& /* rcInvalid */)
{
if (!pdc)
return;
// TODO: 用您自己的绘图代码替换下面的代码。
if (m_flag)
{
m_flag = false;
// 配置默认的viewer
configViewer(m_hWnd);
HANDLE hHandle = CreateThread(NULL, 0, ThreadRun, (LPVOID)(viewer.get()), 0, NULL);
CloseHandle(hHandle);
}
}
void CGViewCtrl::OnDestroy()
{
COleControl::OnDestroy();
// TODO: 在此处添加消息处理程序代码
viewer->setDone(true);
Sleep(1000);
viewer->stopThreading();
}
DWORD WINAPI CGViewCtrl::ThreadRun(LPVOID lparam)
{
return ((osgViewer::Viewer*)(lparam))->run();
}
void CGViewCtrl::configViewer(HWND hWnd)
{
RECT rect;
//得到控件的大小
::GetWindowRect(hWnd, &rect);
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::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->setInheritedWindowPixelFormat = true;
traits->inheritedWindowData = new osgViewer::GraphicsWindowWin32::WindowData(hWnd);
osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(gc);
// 函数内部把traits的值给改变了,viewoort的前两个参数改为0
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
viewer->addSlave(camera.get());
osg::ref_ptr<osg::Group> root = new osg::Group();
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("world.earth");
root->addChild(node.get());
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
viewer->setSceneData(root.get());
viewer->realize();
}
// OnCreate和OnSize暂时没用到
12.注册64位COM组件
注册
regsvr32 "F:\MyCode\COM\Release\x64\GView.ocx"
注销:
regsvr32 -u "F:\MyCode\COM\Release\x64\GView.ocx"
13.记得上次说过,64位的COM组件注册之后再VS中找不到。故需要先注册32位的COM组件,然后在注册64的COM组件,在设计期使用32位COM组件进行设计,但是平台需要改为64位的
14.此时在运行看一下效果