// MFC_OSG.cpp : implementation of the cOSG class // #include "stdafx.h" #include "MFC_OSG.h" cOSG::cOSG(HWND hWnd) : m_hWnd(hWnd) { // // 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 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->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 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"); }