OpenSceneGraph/examples/osgviewerMFC/MFC_OSG.cpp

189 lines
4.8 KiB
C++
Raw Normal View History

// MFC_OSG.cpp : implementation of the cOSG class
//
#include "stdafx.h"
#include "MFC_OSG.h"
cOSG::cOSG(HWND hWnd) :
m_hWnd(hWnd), mDone(false)
{
//
// We must set the pixelformat before we can create the OSG Rendering Surface
//
PIXELFORMATDESCRIPTOR pixelFormat =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
24,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC hdc = ::GetDC(m_hWnd);
if (hdc==0)
{
::DestroyWindow(m_hWnd);
return;
}
int pixelFormatIndex = ::ChoosePixelFormat(hdc, &pixelFormat);
if (pixelFormatIndex==0)
{
::ReleaseDC(m_hWnd, hdc);
::DestroyWindow(m_hWnd);
return;
}
if (!::SetPixelFormat(hdc, pixelFormatIndex, &pixelFormat))
{
::ReleaseDC(m_hWnd, hdc);
::DestroyWindow(m_hWnd);
return;
}
}
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);
// 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->inheritedWindowData = windata;
// Create the Graphics Context
osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());
// Init a new Camera (Master for this View)
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
// 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));
// Add the Camera to the Viewer
mViewer->addSlave(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();
}
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");
// Set Done to indicate that thread has exited
osg->Done(true);
}