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.此时在运行看一下效果
这里写图片描述

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