MFC+OSG之UI COM組件開發

前幾天研究了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.此時在運行看一下效果
這裏寫圖片描述

示例代碼中我添加的是一個球,當然大家可以換爲其他的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章