在mfc上显示osg本地文件:
https://blog.csdn.net/weixin_30526593/article/details/97294251
将获取的livox点云模型写入osg文件:
bool result = osgDB::writeNodeFile(*root.get(), "my.osg");
if (!result)
osg::notify(osg::FATAL) << "Failed in osgDB::writeNodeFile()" << std::endl;
但是这个方法保存数据很慢。
获取主窗口句柄:AfxGetMainWnd()->m_hWnd。在类外无法获取。
把MFC_OSG.cpp里的void cOSG::InitSceneGraph(void)重写,将mRoot的初始化部分从读取本地文件替换成OSGShowPoint里的方法。
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());*/
//ref_ptr<Group> root = new Group();
ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
{
ref_ptr<osg::GraphicsContext::Traits> traits = new GraphicsContext::Traits;
traits->x = 40;
traits->y = 40;
traits->width = 600;
traits->height = 480;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
ref_ptr<GraphicsContext> gc = GraphicsContext::createGraphicsContext(traits.get());
gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ref_ptr<Camera> camera = new Camera;
camera->setGraphicsContext(gc.get());
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
camera->setDrawBuffer(buffer);
camera->setReadBuffer(buffer);
// add this slave camera to the viewer, with a shift left of the projection matrix
viewer->addSlave(camera.get());
}
//顶点数组
ref_ptr<osg::Vec3Array> coords = new Vec3Array();
ref_ptr<osg::Vec4Array> color = new Vec4Array();
//读取文件
char* filePath = "e:\\livox\\txtFiles\\2020-07-16_10-59-04.txt";
FILE* pfData;
errno_t err = fopen_s(&pfData, filePath, "r");
//FILE* pfData = fopen(FileName, "r");
int num = 0;//数据点数量
if (pfData == NULL)
{
cout << "File does not exist!!!" << endl;
return;
}
else
{
char strLine[100];
while ((!feof(pfData)) && num<500000)
{
int fx = 0, fy = 0, fz = 0, fref = 0;
fgets(strLine, 100, pfData);
int DataIntegrity = 0;//点云数据完整
char *ptr;
char *p;
char strs[] = " ";
if (strcmp(strLine, strs) != 0)
{
ptr = strtok_s(strLine, ",", &p);
if (ptr != NULL)
{
fx = atoi(ptr);
ptr = strtok_s(NULL, ",", &p);
DataIntegrity++;
}
if (ptr != NULL)
{
fy = atoi(ptr);
ptr = strtok_s(NULL, ",", &p);
DataIntegrity++;
}
if (ptr != NULL)
{
fz = atoi(ptr);
ptr = strtok_s(NULL, ",", &p);
DataIntegrity++;
}
if (ptr != NULL)
{
fref = atoi(ptr);
ptr = strtok_s(NULL, ",", &p);
DataIntegrity++;
}
}
if (DataIntegrity == 4)
{
coords->push_back(osg::Vec3(fx, fy, fz));
color->push_back(osg::Vec4(1.f, 0.f, 0.0f, 0.3f));
num++;
}
DataIntegrity = 0;
}
fclose(pfData);
}
//创建几何体
ref_ptr<Geometry> geometry = new Geometry();
//设置顶点数组
geometry->setVertexArray(coords.get());
geometry->setColorArray(color.get());
geometry->setColorBinding(Geometry::BIND_PER_VERTEX);
Vec3Array *normals = new Vec3Array;
normals->push_back(Vec3(0.0f, 1.0f, 0.0f));
geometry->setNormalArray(normals);
geometry->setNormalBinding(Geometry::BIND_OVERALL);
geometry->addPrimitiveSet(new DrawArrays(PrimitiveSet::POINTS, 0, num)); //设置关联方式
ref_ptr<Geode> geode = new Geode();
geode->addDrawable(geometry.get());
mRoot->addChild(geode.get());
}
开始采样的按钮的点击响应事件里,用MFC_OSG的方法显示点云:
CEdit* e1 = (CEdit*)GetDlgItem(editOSG);
mOsg = new cOSG(e1->m_hWnd);
mOsg->InitOSG("cow.osg");
mThreadHandle = (HANDLE)_beginthread(&cOSG::Render, 0, mOsg);
新建MFC项目的时候为了精简,把所有可选项都取消勾选了。现在为对话框添加最大化最小化按钮。
对话框属性页-system menu设置为ture,然后把maximize box和minimize box设置为true。
把窗体内的控件也设置为随对话框大小而改变。
dlg头文件添加定义:
POINT Old;//存放对话框的宽和高。
dlg的cpp文件中初始化。在OnInitDialog函数内添加:
CRect rect;
GetClientRect(&rect); //取客户区大小
Old.x = rect.right - rect.left;
Old.y = rect.bottom - rect.top;
类向导为MW_SIZE添加响应函数。内部添加代码:
// TODO: 在此处添加消息处理程序代码
if (nType == SIZE_RESTORED || nType == SIZE_MAXIMIZED)//窗体大小发生变动。处理程序
{
float fsp[2];
POINT Newp; //获取现在对话框的大小
CRect recta;
GetClientRect(&recta); //取客户区大小
Newp.x = recta.right - recta.left;
Newp.y = recta.bottom - recta.top;
fsp[0] = (float)Newp.x / Old.x;
fsp[1] = (float)Newp.y / Old.y;
CRect Rect;
int woc;
CPoint OldTLPoint, TLPoint; //左上角
CPoint OldBRPoint, BRPoint; //右下角
HWND hwndChild = ::GetWindow(m_hWnd, GW_CHILD); //列出所有控件
while (hwndChild)
{
woc = ::GetDlgCtrlID(hwndChild);//取得ID
GetDlgItem(woc)->GetWindowRect(Rect);
ScreenToClient(Rect);
OldTLPoint = Rect.TopLeft();
TLPoint.x = long(OldTLPoint.x*fsp[0]);
TLPoint.y = long(OldTLPoint.y*fsp[1]);
OldBRPoint = Rect.BottomRight();
BRPoint.x = long(OldBRPoint.x *fsp[0]);
BRPoint.y = long(OldBRPoint.y *fsp[1]); //高度不可读的控件(如:combBox),不要改变此值.
Rect.SetRect(TLPoint, BRPoint);
GetDlgItem(woc)->MoveWindow(Rect, TRUE);
hwndChild = ::GetWindow(hwndChild, GW_HWNDNEXT);
}
Old = Newp;
}
参考:https://blog.csdn.net/why19940926/article/details/53946546