1 // MFC_OSG.cpp : implementation of the cOSG class
2 //
3 #include "stdafx.h"
4 #include "MFC_OSG.h"
5
6
cOSG(HWND hWnd)7 cOSG::cOSG(HWND hWnd) :
8 m_hWnd(hWnd)
9 {
10 }
11
~cOSG()12 cOSG::~cOSG()
13 {
14 mViewer->setDone(true);
15 Sleep(1000);
16 mViewer->stopThreading();
17
18 delete mViewer;
19 }
20
InitOSG(std::string modelname)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
InitManipulators(void)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
InitSceneGraph(void)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
InitCameraConfig(void)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
PreFrameUpdate()135 void cOSG::PreFrameUpdate()
136 {
137 // Due any preframe updates in this routine
138 }
139
PostFrameUpdate()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
CRenderingThread(cOSG * ptr)172 CRenderingThread::CRenderingThread( cOSG* ptr )
173 : OpenThreads::Thread(), _ptr(ptr), _done(false)
174 {
175 }
176
~CRenderingThread()177 CRenderingThread::~CRenderingThread()
178 {
179 _done = true;
180 if (isRunning())
181 {
182 cancel();
183 join();
184 }
185 }
186
run()187 void CRenderingThread::run()
188 {
189 if ( !_ptr )
190 {
191 _done = true;
192 return;
193 }
194
195 osgViewer::Viewer* viewer = _ptr->getViewer();
196 do
197 {
198 _ptr->PreFrameUpdate();
199 viewer->frame();
200 _ptr->PostFrameUpdate();
201 } while ( !testCancel() && !viewer->done() && !_done );
202 }
203