前幾天研究了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.此時在運行看一下效果