1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
// MFC_OSG.cpp : implementation of the cOSG class
//
#include "stdafx.h"
#include "MFC_OSG.h"
cOSG::cOSG(HWND hWnd) :
m_hWnd(hWnd)
{
}
cOSG::~cOSG()
{
mViewer->setDone(true);
Sleep(1000);
mViewer->stopThreading();
delete mViewer;
}
void cOSG::InitOSG(std::string modelname)
{
// Store the name of the model to load
m_ModelName = modelname;
// Init different parts of OSG
InitManipulators();
InitSceneGraph();
InitCameraConfig();
}
void cOSG::InitManipulators(void)
{
// Create a trackball manipulator
trackball = new osgGA::TrackballManipulator();
// Create a Manipulator Switcher
keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
// Add our trackball manipulator to the switcher
keyswitchManipulator->addMatrixManipulator( '1', "Trackball", trackball.get());
// Init the switcher to the first manipulator (in this case the only manipulator)
keyswitchManipulator->selectMatrixManipulator(0); // Zero based index Value
}
void cOSG::InitSceneGraph(void)
{
// Init the main Root Node/Group
mRoot = new osg::Group;
// Load the Model from the model name
mModel = osgDB::readNodeFile(m_ModelName);
if (!mModel) return;
// Optimize the model
osgUtil::Optimizer optimizer;
optimizer.optimize(mModel.get());
optimizer.reset();
// Add the model to the scene
mRoot->addChild(mModel.get());
}
void cOSG::InitCameraConfig(void)
{
// Local Variable to hold window size data
RECT rect;
// Create the viewer for this window
mViewer = new osgViewer::Viewer();
// Add a Stats Handler to the viewer
mViewer->addEventHandler(new osgViewer::StatsHandler);
// Get the current window size
::GetWindowRect(m_hWnd, &rect);
// Init the GraphicsContext Traits
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
// Init the Windata Variable that holds the handle for the Window to display OSG in.
osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);
// Setup the traits parameters
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;
// Create the Graphics Context
osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());
// Init Master Camera for this View
osg::ref_ptr<osg::Camera> camera = mViewer->getCamera();
// Assign Graphics Context to the Camera
camera->setGraphicsContext(gc);
// Set the viewport for the Camera
camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));
// Set projection matrix and camera attribtues
camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
camera->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.4f, 1.0f));
camera->setProjectionMatrixAsPerspective(
30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0, 1000.0);
// Add the Camera to the Viewer
//mViewer->addSlave(camera.get());
mViewer->setCamera(camera.get());
// Add the Camera Manipulator to the Viewer
mViewer->setCameraManipulator(keyswitchManipulator.get());
// Set the Scene Data
mViewer->setSceneData(mRoot.get());
// Realize the Viewer
mViewer->realize();
// Correct aspect ratio
/*double fovy,aspectRatio,z1,z2;
mViewer->getCamera()->getProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);
aspectRatio=double(traits->width)/double(traits->height);
mViewer->getCamera()->setProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);*/
}
void cOSG::PreFrameUpdate()
{
// Due any preframe updates in this routine
}
void cOSG::PostFrameUpdate()
{
// Due any postframe updates in this routine
}
/*void cOSG::Render(void* ptr)
{
cOSG* osg = (cOSG*)ptr;
osgViewer::Viewer* viewer = osg->getViewer();
// You have two options for the main viewer loop
// viewer->run() or
// while(!viewer->done()) { viewer->frame(); }
//viewer->run();
while(!viewer->done())
{
osg->PreFrameUpdate();
viewer->frame();
osg->PostFrameUpdate();
//Sleep(10); // Use this command if you need to allow other processes to have cpu time
}
// For some reason this has to be here to avoid issue:
// if you have multiple OSG windows up
// and you exit one then all stop rendering
AfxMessageBox("Exit Rendering Thread");
_endthread();
}*/
CRenderingThread::CRenderingThread( cOSG* ptr )
: OpenThreads::Thread(), _ptr(ptr), _done(false)
{
}
CRenderingThread::~CRenderingThread()
{
_done = true;
while( isRunning() )
OpenThreads::Thread::YieldCurrentThread();
}
void CRenderingThread::run()
{
if ( !_ptr )
{
_done = true;
return;
}
osgViewer::Viewer* viewer = _ptr->getViewer();
do
{
_ptr->PreFrameUpdate();
viewer->frame();
_ptr->PostFrameUpdate();
} while ( !testCancel() && !viewer->done() && !_done );
}
|