在OSG的Demo中找到MFC_OSG类文件。
#pragma once #include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/api/win32/GraphicsWindowWin32>
#include <osgGA/TrackballManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgDB/DatabasePager>
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <string> class cOSG
{
public:
cOSG(HWND hWnd);
~cOSG(); void InitOSG(std::string filename);
void InitManipulators(void);
void InitSceneGraph(void);
void InitCameraConfig(void);
void SetupWindow(void);
void SetupCamera(void);
void PreFrameUpdate(void);
void PostFrameUpdate(void);
void Done(bool value) { mDone = value; }
bool Done(void) { return mDone; }
static void Render(void* ptr); osgViewer::Viewer* getViewer() { return mViewer; } private:
bool mDone;
std::string m_ModelName;
HWND m_hWnd;
osgViewer::Viewer* mViewer;
osg::ref_ptr<osg::Group> mRoot;
osg::ref_ptr<osg::Node> mModel;
osg::ref_ptr<osgGA::TrackballManipulator> trackball;
osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator;
}; class CRenderingThread : public OpenThreads::Thread
{
public:
CRenderingThread( cOSG* ptr );
virtual ~CRenderingThread(); virtual void run(); protected:
cOSG* _ptr;
bool _done;
};
MFC_OSG.h
实现文件:
// 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();
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( '', "Trackball", trackball.get()); // Init the switcher to the first manipulator (in this case the only manipulator)
keyswitchManipulator->selectMatrixManipulator(); // 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 = ;
traits->y = ;
traits->width = rect.right - rect.left;
traits->height = rect.bottom - rect.top;
traits->windowDecoration = false;
traits->doubleBuffer = true;
traits->sharedContext = ;
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 );
}
MFC_OSG.cpp
新建MFC单文档程序,在视图头文件中添加:
public:
cOSG *m_OSG;
HANDLE m_ThreadHandle;
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
virtual void OnInitialUpdate();
实现代码:
int COSGMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -)
return -; // TODO: 在此添加您专用的创建代码
m_OSG = new cOSG(m_hWnd); return ;
} void COSGMFCView::OnInitialUpdate()
{
CView::OnInitialUpdate();
m_OSG->InitOSG("cessna.osg");
m_ThreadHandle = (HANDLE)_beginthread(&cOSG::Render,,m_OSG); // TODO: 在此添加专用代码和/或调用基类
}