|
大家好! 我建了一个MFC的OSG应用程序,基本上就是实现了osgViewerMFC例子中的模型查看的功能,尚未添加其他任何功能。
现在我想在场景中实现求交判断,目的是想实现对象选取。参考了《OpenSceneGraph三维渲染引擎编程指南》这本书中8.3.3例子的代码。
但是,鼠标点击场景中的模型后,会出现堆内存损坏的错误提示。下面是具体的代码和错误提示截图:
////pickhandler
CPickHandler::CPickHandler()
{
}
CPickHandler::~CPickHandler()
{
}
bool CPickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
{
switch(ea.getEventType())
{
case(osgGA::GUIEventAdapter:USH):
{
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
if (view)
{
pick(view,ea);
}
return false;
}
default:
return false;
}
}
void CPickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
{
osgUtil:ineSegmentIntersector::Intersections intersections;
float x = ea.getX();
float y = ea.getY();
if (view->computeIntersections(x,y,intersections))
{
}
}
//////初始化
void CMFCOSG::InitSceneGraph(void)
{
//初始化组
Root=new osg::Group;
//读取模型
Model=osgDB::readNodeFile(ModelName);
//优化模型
osgUtil::Optimizer optimizer;
optimizer.optimize( Model.get());
optimizer.reset();
Root->addChild(Model.get());
}
void CMFCOSG::InitCameraConfig(void)
{
RECT rect;
Viewer = new osgViewer::Viewer;
::GetWindowRect(HWnd,&rect);
osg::ref_ptr<osg::GraphicsContext::Traits>traits = new osg::GraphicsContext::Traits;
//初始化窗口变量
osg::ref_ptr<osg::Referenced>windata = new osgViewer::GraphicsWindowWin32::WindowData(HWnd);
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;
//创建图形上下文
osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());
//初始化一个相机
osg::ref_ptr<osg::Camera>camera=new osg::Camera;
//将相机绑定到窗口设备
camera->setGraphicsContext(gc);
//相机视口设置
camera->setViewport(new osg::Viewport(traits->x,traits->y,traits->width,traits->height));
//添加相机到VIEWER
Viewer->addSlave(camera.get());
Viewer->setCameraManipulator(KeyswitchManipulator.get());
CPickHandler* pickHandler = new CPickHandler();
Viewer->addEventHandler(pickHandler);
//设置数据
Viewer->setSceneData(Root.get());
//实现VIEWER
Viewer->realize();
double fovy,aspectRatio,z1,z2;
Viewer->getCamera()->getProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);
aspectRatio=double(traits->width)/double(traits->height);
Viewer->getCamera()->setProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);
}
void CMFCOSG::Render(void* ptr)
{
CMFCOSG* mfcosg= (CMFCOSG*) ptr;
osgViewer::Viewer* osgviewer=mfcosg->GetViewer();
while(!osgviewer->done())
{
mfcosg->reFrameUpdate();
osgviewer->frame();
mfcosg->PostFrameUpdate();
//Sleep(10);//让其它程也占用CPU,放出M
}
//退出了程序,弹出个对话框
//AfxMessageBox("线程退出");
_endthread();
}
错误提示:
"Windows 已在 osgMFC.exe 中触发一个断点。
其原因可能是堆被损坏,这也说明 osgMFC.exe 中或它所加载的任何 DLL 中有 bug。
输出窗口可能提供了更多诊断信息"
可以看出,void CPickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
里除了求交判断,几乎什么都没做,调试的时候发现,程序运行到这个函数体的最后,再下一步F10就出错了,弄了两天了,一直不知道问题出在哪里。 |
|