一、过程
创建MFC程序
?
?客户区事件
?然后创建一个COSGObject作为主要功能类
接着编写窗体部分代码
OnDestroy?
void OnDestroy()
{
CView::OnDestroy();
// TODO: 在此处添加消息处理程序代码
if (mOSG != 0)
delete mOSG;
//等待线程完成了再继续做其他事情
WaitForSingleObject(mThreadHandle,1000);
}
?OnCreate
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
mOSG = new COSGObject(m_hWnd);
return 0;
}
OnEraseBkgnd?
BOOL OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (0 == mOSG)
{
return CView::OnEraseBkgnd(pDC);
}
else
{
return FALSE;
}
return CView::OnEraseBkgnd(pDC);
}
OnInitialUpdate?
void OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: 在此添加专用代码和/或调用基类
mOSG->InitOSG();
//把mOSG传入线程render
mThreadHandle = (HANDLE)_beginthread(&COSGObject::Render,0,mOSG);
}
二、代码
COSGObject.h
#pragma once
#include <osgViewer/Viewer>
#include <osgDb/ReadFile>
#include <osgViewer/api/Win32/GraphicsWindowWin32>
#include <osgGA/TrackballManipulator>
#include <osgEarth/MapNode>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ExampleResources>
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>
class COSGObject
{
public:
COSGObject(HWND hWnd);
~COSGObject();
void InitOSG();
void InitSceneGraph();
void InitCameraConfig();
void PreFrameUpdate();
void PostFrameUpdate();
static void Render(void * ptr);
void InitOsgEarth();
osgViewer::Viewer *getViewer();
private:
HWND m_hWnd;
osgViewer::Viewer * mViewer;
osg::ref_ptr<osg::Group> mRoot;
osg::ref_ptr<osgEarth::MapNode> mapNode;
osg::ref_ptr<osgEarth::Util::EarthManipulator> em;
osg::ref_ptr<osg::CoordinateSystemNode> csn;
};
?COSGObject.cpp
#include "pch.h"
#include "COSGObject.h"
COSGObject::COSGObject(HWND hWnd)
{
m_hWnd = hWnd;
csn = new osg::CoordinateSystemNode;
}
COSGObject::~COSGObject()
{
}
void COSGObject::InitOSG()
{
InitSceneGraph();
InitCameraConfig();
InitOsgEarth();
}
void COSGObject::InitSceneGraph()
{
csn->setEllipsoidModel(new osg::EllipsoidModel);
mRoot = new osg::Group;
osg::ref_ptr<osg::Node> mp = osgDB::readNodeFile("clear_terrain.earth");
mRoot->addChild(mp);
mapNode = dynamic_cast<osgEarth::MapNode*>(mp.get());
//解决飞机模型被遮挡问题
mRoot->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
//解决模型变成黑色的问题
mRoot->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
mRoot->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
}
void COSGObject::InitCameraConfig()
{
RECT rect;
mViewer = new osgViewer::Viewer;
::GetWindowRect(m_hWnd, &rect);
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);
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 = windata;
osg::GraphicsContext *gc = osg::GraphicsContext::createGraphicsContext(traits);
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(gc);
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0, 1000.0);
mViewer->setCamera(camera);
// mViewer->setCameraManipulator(new osgGA::TrackballManipulator);
mViewer->setSceneData(mRoot);
mViewer->realize();
mViewer->getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
mViewer->getCamera()->setNearFarRatio(0.000003f);
//添加状态事件,可以相应键盘和鼠标事件,响应L T B W
mViewer->addEventHandler(new osgGA::StateSetManipulator(mViewer->getCamera()->getOrCreateStateSet()));
//窗口大小变化,响应F
mViewer->addEventHandler(new osgViewer::WindowSizeHandler);
//添加路径记录 Z
mViewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
//帮助文档显示H
mViewer->addEventHandler(new osgViewer::HelpHandler);
//截屏 C
mViewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
//添加一些常用状态设置,响应S
mViewer->addEventHandler(new osgViewer::StatsHandler);
}
void COSGObject::InitOsgEarth()
{
//初始化操作器
em = new osgEarth::Util::EarthManipulator;
if (mapNode.valid())
{
em->setNode(mapNode);
}
//解决视点拉近地球看不到问题
em->getSettings()->setArcViewpointTransitions(true);
mViewer->setCameraManipulator(em);
//初始化天空
osgEarth::Config skyConf;
double hours = skyConf.value("hours", 12.0);
osgEarth::DateTime datatime(2021, 9, 21, hours);
osgEarth::Util::SkyNode* sky_node = osgEarth::Util::SkyNode::create(mapNode);
sky_node->setDateTime(datatime);
sky_node->attach(mViewer, 0);
sky_node->setLighting(true);
mRoot->addChild(sky_node);
}
void COSGObject::PreFrameUpdate()
{
}
void COSGObject::PostFrameUpdate()
{
}
void COSGObject::Render(void * ptr)
{
COSGObject *osg = (COSGObject*)ptr;
osgViewer::Viewer * viewer = osg->getViewer();
while (!viewer->done())
{
osg->PreFrameUpdate();
viewer->frame();
osg->PostFrameUpdate();
}
_endthread();
}
osgViewer::Viewer * COSGObject::getViewer()
{
return mViewer;
}
2022.2.5_MFC界面的osgearthView.h?
// 这段 MFC 示例源代码演示如何使用 MFC Microsoft Office Fluent 用户界面
// (“Fluent UI”)。该示例仅供参考,
// 用以补充《Microsoft 基础类参考》和
// MFC C++ 库软件随附的相关电子文档。
// 复制、使用或分发 Fluent UI 的许可条款是单独提供的。
// 若要了解有关 Fluent UI 许可计划的详细信息,请访问
// https://go.microsoft.com/fwlink/?LinkId=238214.
//
// 版权所有(C) Microsoft Corporation
// 保留所有权利。
// 2022.2.5_MFC界面的osgearthView.h: CMy202225MFC界面的osgearthView 类的接口
//
#pragma once
#include"2022.2.5_MFC界面的osgearthDoc.h"
#include"COSGObject.h"
class CMy202225MFC界面的osgearthView : public CView
{
protected: // 仅从序列化创建
CMy202225MFC界面的osgearthView() noexcept;
DECLARE_DYNCREATE(CMy202225MFC界面的osgearthView)
// 特性
public:
CMy202225MFC界面的osgearthDoc* GetDocument() const;
// 操作
public:
COSGObject* mOSG;
HANDLE mThreadHandle;
// 重写
public:
virtual void OnDraw(CDC* pDC); // 重写以绘制该视图
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
// 实现
public:
virtual ~CMy202225MFC界面的osgearthView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// 生成的消息映射函数
protected:
afx_msg void OnFilePrintPreview();
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnDestroy();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
virtual void OnInitialUpdate();
};
#ifndef _DEBUG // 2022.2.5_MFC界面的osgearthView.cpp 中的调试版本
inline CMy202225MFC界面的osgearthDoc* CMy202225MFC界面的osgearthView::GetDocument() const
{ return reinterpret_cast<CMy202225MFC界面的osgearthDoc*>(m_pDocument); }
#endif
?2022.2.5_MFC界面的osgearthView.cpp
// 这段 MFC 示例源代码演示如何使用 MFC Microsoft Office Fluent 用户界面
// (“Fluent UI”)。该示例仅供参考,
// 用以补充《Microsoft 基础类参考》和
// MFC C++ 库软件随附的相关电子文档。
// 复制、使用或分发 Fluent UI 的许可条款是单独提供的。
// 若要了解有关 Fluent UI 许可计划的详细信息,请访问
// https://go.microsoft.com/fwlink/?LinkId=238214.
//
// 版权所有(C) Microsoft Corporation
// 保留所有权利。
// 2022.2.5_MFC界面的osgearthView.cpp: CMy202225MFC界面的osgearthView 类的实现
//
#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "2022.2.5_MFC界面的osgearth.h"
#endif
#include "2022.2.5_MFC界面的osgearthDoc.h"
#include "2022.2.5_MFC界面的osgearthView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMy202225MFC界面的osgearthView
IMPLEMENT_DYNCREATE(CMy202225MFC界面的osgearthView, CView)
BEGIN_MESSAGE_MAP(CMy202225MFC界面的osgearthView, CView)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_CREATE()
END_MESSAGE_MAP()
// CMy202225MFC界面的osgearthView 构造/析构
CMy202225MFC界面的osgearthView::CMy202225MFC界面的osgearthView() noexcept
{
// TODO: 在此处添加构造代码
}
CMy202225MFC界面的osgearthView::~CMy202225MFC界面的osgearthView()
{
mOSG = 0;
mThreadHandle = 0;
}
BOOL CMy202225MFC界面的osgearthView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
return CView::PreCreateWindow(cs);
}
// CMy202225MFC界面的osgearthView 绘图
void CMy202225MFC界面的osgearthView::OnDraw(CDC* /*pDC*/)
{
CMy202225MFC界面的osgearthDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
}
void CMy202225MFC界面的osgearthView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
ClientToScreen(&point);
OnContextMenu(this, point);
}
void CMy202225MFC界面的osgearthView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
// CMy202225MFC界面的osgearthView 诊断
#ifdef _DEBUG
void CMy202225MFC界面的osgearthView::AssertValid() const
{
CView::AssertValid();
}
void CMy202225MFC界面的osgearthView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMy202225MFC界面的osgearthDoc* CMy202225MFC界面的osgearthView::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy202225MFC界面的osgearthDoc)));
return (CMy202225MFC界面的osgearthDoc*)m_pDocument;
}
#endif //_DEBUG
// CMy202225MFC界面的osgearthView 消息处理程序
void CMy202225MFC界面的osgearthView::OnDestroy()
{
CView::OnDestroy();
// TODO: 在此处添加消息处理程序代码
if (mOSG != 0)
delete mOSG;
//等待线程完成了再继续做其他事情
WaitForSingleObject(mThreadHandle,1000);
}
BOOL CMy202225MFC界面的osgearthView::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (0 == mOSG)
{
return CView::OnEraseBkgnd(pDC);
}
else
{
return FALSE;
}
return CView::OnEraseBkgnd(pDC);
}
int CMy202225MFC界面的osgearthView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
mOSG = new COSGObject(m_hWnd);
return 0;
}
void CMy202225MFC界面的osgearthView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: 在此添加专用代码和/或调用基类
mOSG->InitOSG();
//把mOSG传入线程render
mThreadHandle = (HANDLE)_beginthread(&COSGObject::Render,0,mOSG);
}
?
|