OSGMFC
在OSG的Demo中找到MFC_OSG类文件。
1 #pragma once
2
3 #include <osgViewer/Viewer>
4 #include <osgViewer/ViewerEventHandlers>
5 #include <osgViewer/api/win32/GraphicsWindowWin32>
6 #include <osgGA/TrackballManipulator>
7 #include <osgGA/KeySwitchMatrixManipulator>
8 #include <osgDB/DatabasePager>
9 #include <osgDB/Registry>
10 #include <osgDB/ReadFile>
11 #include <osgUtil/Optimizer>
12 #include <string>
13
14 class cOSG
15 {
16 public:
17 cOSG(HWND hWnd);
18 ~cOSG();
19
20 void InitOSG(std::string filename);
21 void InitManipulators(void);
22 void InitSceneGraph(void);
23 void InitCameraConfig(void);
24 void SetupWindow(void);
25 void SetupCamera(void);
26 void PreFrameUpdate(void);
27 void PostFrameUpdate(void);
28 void Done(bool value) { mDone = value; }
29 bool Done(void) { return mDone; }
30 static void Render(void* ptr);
31
32 osgViewer::Viewer* getViewer() { return mViewer; }
33
34 private:
35 bool mDone;
36 std::string m_ModelName;
37 HWND m_hWnd;
38 osgViewer::Viewer* mViewer;
39 osg::ref_ptr<osg::Group> mRoot;
40 osg::ref_ptr<osg::Node> mModel;
41 osg::ref_ptr<osgGA::TrackballManipulator> trackball;
42 osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator;
43 };
44
45 class CRenderingThread : public OpenThreads::Thread
46 {
47 public:
48 CRenderingThread( cOSG* ptr );
49 virtual ~CRenderingThread();
50
51 virtual void run();
52
53 protected:
54 cOSG* _ptr;
55 bool _done;
56 };
实现文件:
1 // MFC_OSG.cpp : implementation of the cOSG class
2 //
3 #include "stdafx.h"
4 #include "MFC_OSG.h"
5
6
7 cOSG::cOSG(HWND hWnd) :
8 m_hWnd(hWnd)
9 {
10 }
11
12 cOSG::~cOSG()
13 {
14 mViewer->setDone(true);
15 Sleep(1000);
16 mViewer->stopThreading();
17
18 delete mViewer;
19 }
20
21 void cOSG::InitOSG(std::string modelname)
22 {
23 // Store the name of the model to load
24 m_ModelName = modelname;
25
26 // Init different parts of OSG
27 InitManipulators();
28 InitSceneGraph();
29 InitCameraConfig();
30 }
31
32 void cOSG::InitManipulators(void)
33 {
34 // Create a trackball manipulator
35 trackball = new osgGA::TrackballManipulator();
36
37 // Create a Manipulator Switcher
38 keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
39
40 // Add our trackball manipulator to the switcher
41 keyswitchManipulator->addMatrixManipulator( ‘1‘, "Trackball", trackball.get());
42
43 // Init the switcher to the first manipulator (in this case the only manipulator)
44 keyswitchManipulator->selectMatrixManipulator(0); // Zero based index Value
45 }
46
47
48 void cOSG::InitSceneGraph(void)
49 {
50 // Init the main Root Node/Group
51 mRoot = new osg::Group;
52
53 // Load the Model from the model name
54 mModel = osgDB::readNodeFile(m_ModelName);
55 if (!mModel) return;
56
57 // Optimize the model
58 osgUtil::Optimizer optimizer;
59 optimizer.optimize(mModel.get());
60 optimizer.reset();
61
62 // Add the model to the scene
63 mRoot->addChild(mModel.get());
64 }
65
66 void cOSG::InitCameraConfig(void)
67 {
68 // Local Variable to hold window size data
69 RECT rect;
70
71 // Create the viewer for this window
72 mViewer = new osgViewer::Viewer();
73
74 // Add a Stats Handler to the viewer
75 mViewer->addEventHandler(new osgViewer::StatsHandler);
76
77 // Get the current window size
78 ::GetWindowRect(m_hWnd, &rect);
79
80 // Init the GraphicsContext Traits
81 osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
82
83 // Init the Windata Variable that holds the handle for the Window to display OSG in.
84 osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);
85
86 // Setup the traits parameters
87 traits->x = 0;
88 traits->y = 0;
89 traits->width = rect.right - rect.left;
90 traits->height = rect.bottom - rect.top;
91 traits->windowDecoration = false;
92 traits->doubleBuffer = true;
93 traits->sharedContext = 0;
94 traits->setInheritedWindowPixelFormat = true;
95 traits->inheritedWindowData = windata;
96
97 // Create the Graphics Context
98 osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());
99
100 // Init Master Camera for this View
101 osg::ref_ptr<osg::Camera> camera = mViewer->getCamera();
102
103 // Assign Graphics Context to the Camera
104 camera->setGraphicsContext(gc);
105
106 // Set the viewport for the Camera
107 camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));
108
109 // Set projection matrix and camera attribtues
110 camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
111 camera->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.4f, 1.0f));
112 camera->setProjectionMatrixAsPerspective(
113 30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0, 1000.0);
114
115 // Add the Camera to the Viewer
116 //mViewer->addSlave(camera.get());
117 mViewer->setCamera(camera.get());
118
119 // Add the Camera Manipulator to the Viewer
120 mViewer->setCameraManipulator(keyswitchManipulator.get());
121
122 // Set the Scene Data
123 mViewer->setSceneData(mRoot.get());
124
125 // Realize the Viewer
126 mViewer->realize();
127
128 // Correct aspect ratio
129 /*double fovy,aspectRatio,z1,z2;
130 mViewer->getCamera()->getProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);
131 aspectRatio=double(traits->width)/double(traits->height);
132 mViewer->getCamera()->setProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);*/
133 }
134
135 void cOSG::PreFrameUpdate()
136 {
137 // Due any preframe updates in this routine
138 }
139
140 void cOSG::PostFrameUpdate()
141 {
142 // Due any postframe updates in this routine
143 }
144
145 void cOSG::Render(void* ptr)
146 {
147 cOSG* osg = (cOSG*)ptr;
148
149 osgViewer::Viewer* viewer = osg->getViewer();
150
151 // You have two options for the main viewer loop
152 // viewer->run() or
153 // while(!viewer->done()) { viewer->frame(); }
154
155 //viewer->run();
156 while(!viewer->done())
157 {
158 osg->PreFrameUpdate();
159 viewer->frame();
160 osg->PostFrameUpdate();
161 //Sleep(10); // Use this command if you need to allow other processes to have cpu time
162 }
163
164 // For some reason this has to be here to avoid issue:
165 // if you have multiple OSG windows up
166 // and you exit one then all stop rendering
167 AfxMessageBox("Exit Rendering Thread");
168
169 _endthread();
170 }
171
172 CRenderingThread::CRenderingThread( cOSG* ptr )
173 : OpenThreads::Thread(), _ptr(ptr), _done(false)
174 {
175 }
176
177 CRenderingThread::~CRenderingThread()
178 {
179 _done = true;
180 while( isRunning() )
181 OpenThreads::Thread::YieldCurrentThread();
182 }
183
184 void CRenderingThread::run()
185 {
186 if ( !_ptr )
187 {
188 _done = true;
189 return;
190 }
191
192 osgViewer::Viewer* viewer = _ptr->getViewer();
193 do
194 {
195 _ptr->PreFrameUpdate();
196 viewer->frame();
197 _ptr->PostFrameUpdate();
198 } while ( !testCancel() && !viewer->done() && !_done );
199 }
新建MFC单文档程序,在视图头文件中添加:
1 public:
2 cOSG *m_OSG;
3 HANDLE m_ThreadHandle;
4 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
5 virtual void OnInitialUpdate();
实现代码:
1 int COSGMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
2 {
3 if (CView::OnCreate(lpCreateStruct) == -1)
4 return -1;
5
6 // TODO: 在此添加您专用的创建代码
7 m_OSG = new cOSG(m_hWnd);
8
9 return 0;
10 }
11
12
13 void COSGMFCView::OnInitialUpdate()
14 {
15 CView::OnInitialUpdate();
16 m_OSG->InitOSG("cessna.osg");
17 m_ThreadHandle = (HANDLE)_beginthread(&cOSG::Render,0,m_OSG);
18
19 // TODO: 在此添加专用代码和/或调用基类
20 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。