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