From Michael Hartman, "Here is an update for the closing issue with the example osgviewerMFC where the MFC rendering thread would not exit before the application and the thread would be left running in the background and the user would have to use TaskManager to kill the process.

Changes:

MFC_OSG.cpp:

            Removed pixelformatdesciptor from the class initialization.

            Used setInheritedWindowPixelFormat to true so it will setup the pixelformat for the window.

            Added class destructor code.

MFC_OSG.h:

            Removed the ref_ptr on osgViewer::Viewer

MFC_OSG_MDIViewer.cpp:

            Changed the OnDestroy function code.

            Added WaitforSingleObject with thread handle for the MFC render handle.

MFC_OSG_MDIView.h:

            Added class variable for MFC Render Thread Handle for use with the WaitforSingleObject.
"
This commit is contained in:
Robert Osfield
2007-07-23 20:37:49 +00:00
parent 9394238720
commit fee5bc9f8c
4 changed files with 19 additions and 61 deletions

View File

@@ -5,49 +5,17 @@
cOSG::cOSG(HWND hWnd) :
m_hWnd(hWnd), mDone(false)
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;
}
cOSG::~cOSG()
{
mViewer->setDone(true);
Sleep(1000);
mViewer->stopThreading();
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;
}
delete mViewer;
}
void cOSG::InitOSG(std::string modelname)
@@ -100,7 +68,7 @@ void cOSG::InitCameraConfig(void)
RECT rect;
// Create the viewer for this window
mViewer = new osgViewer::Viewer;
mViewer = new osgViewer::Viewer();
// Add a Stats Handler to the viewer
mViewer->addEventHandler(new osgViewer::StatsHandler);
@@ -122,6 +90,7 @@ void cOSG::InitCameraConfig(void)
traits->windowDecoration = false;
traits->doubleBuffer = true;
traits->sharedContext = 0;
traits->setInheritedWindowPixelFormat = true;
traits->inheritedWindowData = windata;
// Create the Graphics Context
@@ -183,6 +152,5 @@ void cOSG::Render(void* ptr)
// and you exit one then all stop rendering
AfxMessageBox("Exit Rendering Thread");
// Set Done to indicate that thread has exited
osg->Done(true);
_endthread();
}

View File

@@ -15,7 +15,7 @@ class cOSG
{
public:
cOSG(HWND hWnd);
~cOSG(){};
~cOSG();
void InitOSG(std::string filename);
void InitManipulators(void);
@@ -29,13 +29,13 @@ public:
bool Done(void) { return mDone; }
static void Render(void* ptr);
osgViewer::Viewer* getViewer() { return mViewer.get(); }
osgViewer::Viewer* getViewer() { return mViewer; }
private:
bool mDone;
std::string m_ModelName;
HWND m_hWnd;
osg::ref_ptr<osgViewer::Viewer> mViewer;
osgViewer::Viewer* mViewer;
osg::ref_ptr<osg::Group> mRoot;
osg::ref_ptr<osg::Node> mModel;
osg::ref_ptr<osgGA::TrackballManipulator> trackball;

View File

@@ -74,21 +74,10 @@ int CMFC_OSG_MDIView::OnCreate(LPCREATESTRUCT lpCreateStruct)
void CMFC_OSG_MDIView::OnDestroy()
{
// Make sure OSG was created before we try to close it.
if(mOSG)
{
// Wait while the Viewer closes
while(!mOSG->Done())
{
Sleep(10); // Allow others processor time
}
// Remove mOSG
delete mOSG;
}
if(mOSG != 0) delete mOSG;
WaitForSingleObject(mThreadHandle, 1000);
// Destroy Window
CView::OnDestroy();
}
@@ -103,7 +92,7 @@ void CMFC_OSG_MDIView::OnInitialUpdate()
mOSG->InitOSG(csFileName.GetString());
// Start the thread to do OSG Rendering
_beginthread(&cOSG::Render, 0, mOSG);
mThreadHandle = (HANDLE)_beginthread(&cOSG::Render, 0, mOSG);
}
void CMFC_OSG_MDIView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

View File

@@ -34,6 +34,7 @@ public:
protected:
cOSG* mOSG;
HANDLE mThreadHandle;
// Generated message map functions
protected: