// 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 traits = new osg::GraphicsContext::Traits; // Init the Windata Variable that holds the handle for the Window to display OSG in. osg::ref_ptr 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 camera = mViewer->getCamera(); // Assign Graphics Context to the Camera camera->setGraphicsContext(gc); // Set the viewport for the Camera camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); // set the draw and read buffers up for a double buffered window with rendering going to back buffer camera->setDrawBuffer(GL_BACK); camera->setReadBuffer(GL_BACK); // 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(traits->width)/static_cast(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; if (isRunning()) { cancel(); join(); } } 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 ); }