osg::NotifyHandler

本文介绍了一种解决MFC程序中osg调试信息无法正常显示的问题的方法。通过定义一个自定义通知处理器类MyNotifyHandler并设置调试级别,使得调试信息能够被正确地输出。

MFC程序 osg的调试信息 OSG_INFO等打印不出,可以按如下:

class MyNotifyHandler : public osg::NotifyHandler
{
public:
void notify(osg::NotifySeverity severity, const char *message)
{
TRACE( “\n MyNotifyHandler) ” message);
}
};

osg::setNotifyHandler(new MyNotifyHandler);
osg::setNotifyLevel(osg::NOTICE);
#include<osgViewer/Viewer> #include<osgViewer/ViewerEventHandlers> #include<osgGA/StateSetManipulator> #include<osg/Node> #include<osg/Geode> #include<osg/Geometry> #include<vector> #include<fstream> #include<iostream> #include<random> #include<osg/Group> #include<osg/MatrixTransform> using namespace std; struct P { //平面 int v1, v2, v3; //旧的,后面要改 }; vector<double> X, Y, Z, RAD; vector<P>PLANE; void readData(); //读原始数据 osg::ref_ptr<osg::Node> createTriangle(); //创建三角面 osg::ref_ptr<osg::Node> createTriangle2(); //创建三角面 class RotationCallback : public osg::NodeCallback { public: RotationCallback() : _angle(0.0) {} virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { // 计算时间差 osg::Timer_t now = osg::Timer::instance()->tick(); double deltaTime = osg::Timer::instance()->delta_s(_lastTick, now); _lastTick = now; // 更新旋转角度 _angle += deltaTime * 10; // 调整旋转速度 // 限制角度在 [0, 2π) 范围内 if (_angle >= osg::PI * 2.0) { _angle -= osg::PI * 2.0; } // 创建旋转矩阵,指定旋转轴的位置 osg::Matrix rotationMatrix; rotationMatrix.makeRotate(_angle, osg::Vec3(0.0, 0.0, 1.0)); // 旋转角度围绕Z轴 osg::Matrix translateMatrix; translateMatrix.makeTranslate(0.1, 0.0, -0.01); // 平移旋转轴到左侧 osg::Matrix finalMatrix = translateMatrix * rotationMatrix; // 设置旋转变换节点的变换矩阵 dynamic_cast<osg::MatrixTransform*>(node)->setMatrix(finalMatrix); // 继续遍历子节点 traverse(node, nv); } protected: double _angle; osg::Timer_t _lastTick; }; struct CaptureCallback :public osg::Camera::DrawCallback { CaptureCallback(osg::ref_ptr<osg::Image> image) { image_ = image; } ~CaptureCallback() {} virtual void operator()(const osg::Camera& camera) const { //得到窗口系统接口 osg::ref_ptr<osg::GraphicsContext::WindowingSystemInterface> wsi = osg::GraphicsContext::getWindowingSystemInterface(); unsigned int width, height; //得到分辨率 wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); //分配一个image image_->allocateImage(width, height, 1, GL_RGB, GL_UNSIGNED_BYTE); //读取像素信息抓图 image_->readPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE); cout << 111 << endl; } private: osg::ref_ptr<osg::Image> image_; }; void main() { cout << "loading...\n"; readData(); cout << "OK\n"; osgViewer::Viewer viewer; // 观察器,用来查看模型 osg::Group* root = new osg::Group(); // 添加第一个模型 root->addChild(createTriangle().get()); // 创建第二个模型的旋转变换节点 osg::ref_ptr<osg::MatrixTransform> rotateTransform = new osg::MatrixTransform; rotateTransform->addChild(createTriangle2().get()); // 将旋转变换节点添加到根节点 root->addChild(rotateTransform.get()); // 附加回调到旋转变换节点 rotateTransform->setUpdateCallback(new RotationCallback); viewer.setSceneData(root); viewer.addEventHandler(new osgViewer::WindowSizeHandler); viewer.realize(); viewer.run(); } void readData() { fstream in("example.txt",ios::in); in.rdbuf()->pubsetbuf(0, 300*1024 * 1024); int cnt = 0; int N, E; in >> N >> E; for (int i = 0; i < N; i++) { double num; in >> num; X.push_back(num); } for (int i = 0; i < N; i++) { double num; in >> num; Y.push_back(num); } for (int i = 0; i < N; i++) { double num; in >> num; Z.push_back(num); } for (int i = 0; i < N; i++) { double num; in >> num; RAD.push_back(num); } for (int i = 0; i < E; i++) { int n1, n2, n3; in >> n1 >> n2 >> n3; PLANE.push_back({n1-1,n2-1,n3-1}); } in.close(); } osg::ref_ptr<osg::Node> createTriangle() { int numVertices = X.size(); // 获取顶点数量 int numFaces = PLANE.size(); // 获取面数量 // 创建顶点数组 osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array; for (int i = 0; i < numVertices; ++i) { vertices->push_back(osg::Vec3(X[i], Y[i], Z[i])); } // 创建几何体 osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry; geometry->setVertexArray(vertices.get()); // 计算并设置法线 osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array; normals->resize(numVertices, osg::Vec3(0.0f, 0.0f, 0.0f)); // 初始化法线为零向量 for (int i = 0; i < numFaces; ++i) { const P& plane = PLANE[i]; osg::Vec3 v1 = (*vertices)[plane.v1]; osg::Vec3 v2 = (*vertices)[plane.v2]; osg::Vec3 v3 = (*vertices)[plane.v3]; osg::Vec3 normal = (v2 - v1) ^ (v3 - v1); // 计算面的法线 // 将法线加到每个顶点上 (*normals)[plane.v1] += normal; (*normals)[plane.v2] += normal; (*normals)[plane.v3] += normal; } // 归一化法线 for (int i = 0; i < numVertices; ++i) { (*normals)[i].normalize(); } geometry->setNormalArray(normals.get()); geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); // 创建顶点索引数组 osg::ref_ptr<osg::DrawElementsUInt> indices = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); for (int i = 0; i < numFaces; ++i) { if (Z[PLANE[i].v3] >= -0.568&& X[PLANE[i].v3]<=8) continue; const P& plane = PLANE[i]; indices->push_back(plane.v1); indices->push_back(plane.v2); indices->push_back(plane.v3); } geometry->addPrimitiveSet(indices.get()); // 设置几何体的颜色 osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array; colors->push_back(osg::Vec4(0.4f, 0.4f, 0.4f, 1.0f)); geometry->setColorArray(colors.get()); geometry->setColorBinding(osg::Geometry::BIND_OVERALL); // 设置几何体的渲染状态 osg::StateSet* stateset = geometry->getOrCreateStateSet(); //stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); // 创建几何组结点 osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable(geometry.get()); return geode.get(); } osg::ref_ptr<osg::Node> createTriangle2() { int numVertices = X.size(); // 获取顶点数量 int numFaces = PLANE.size(); // 获取面数量 // 创建顶点数组 osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array; for (int i = 0; i < numVertices; ++i) { vertices->push_back(osg::Vec3(X[i], Y[i], Z[i])); } // 创建几何体 osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry; geometry->setVertexArray(vertices.get()); // 计算并设置法线 osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array; normals->resize(numVertices, osg::Vec3(0.0f, 0.0f, 0.0f)); // 初始化法线为零向量 for (int i = 0; i < numFaces; ++i) { const P& plane = PLANE[i]; osg::Vec3 v1 = (*vertices)[plane.v1]; osg::Vec3 v2 = (*vertices)[plane.v2]; osg::Vec3 v3 = (*vertices)[plane.v3]; osg::Vec3 normal = (v2 - v1) ^ (v3 - v1); // 计算面的法线 // 将法线加到每个顶点上 (*normals)[plane.v1] += normal; (*normals)[plane.v2] += normal; (*normals)[plane.v3] += normal; } // 归一化法线 for (int i = 0; i < numVertices; ++i) { (*normals)[i].normalize(); } geometry->setNormalArray(normals.get()); geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); // 创建顶点索引数组 osg::ref_ptr<osg::DrawElementsUInt> indices = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES); for (int i = 0; i < numFaces; ++i) { if (Z[PLANE[i].v3] <= -0.568 || X[PLANE[i].v3] > 8) continue; const P& plane = PLANE[i]; indices->push_back(plane.v1); indices->push_back(plane.v2); indices->push_back(plane.v3); } geometry->addPrimitiveSet(indices.get()); // 设置几何体的颜色 osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array; colors->push_back(osg::Vec4(0.5f, 0.5f, 0.5f, 1.0f)); geometry->setColorArray(colors.get()); geometry->setColorBinding(osg::Geometry::BIND_OVERALL); // 设置几何体的渲染状态 osg::StateSet* stateset = geometry->getOrCreateStateSet(); //stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); // 创建几何组结点 osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable(geometry.get()); return geode.get(); } Camera::DrawCallback实现连续截图并导出图片
最新发布
06-05
#include "OsgEarthWidget.h" #include <osgEarth/MapNode> #include <osgEarth/EarthManipulator> #include <osgEarth/ImageLayer> #include <osgEarth/GDAL> #include <osgEarth/GeoTransform> #include <osgViewer/Viewer> #include <osgDB/ReadFile> #include <osg/MatrixTransform> #include <osgEarth/Map> #include <osg/GraphicsContext> #include <osg/Material> void OsgEarthWidget::initializeGL() { if (!isValid()) { qWarning() << "OpenGL 上下文未正确初始化!"; return; } // 确保 OpenGL 上下文有效 makeCurrent(); // 初始化 osgEarth osgEarth::initialize(); // 创建地图和 MapNode osg::ref_ptr<osgEarth::Map> map = new osgEarth::Map(); osg::ref_ptr<osgEarth::MapNode> mapNode = new osgEarth::MapNode(map); // 添加 TMS 图层 auto imagery = new osgEarth::GDALImageLayer(); imagery->setName("MyGeoTiff"); imagery->setURL("D:\\Map\\tif\\map3.tif"); mapNode->getMap()->addLayer(imagery); // 创建根节点组 osg::ref_ptr<osg::Group> root = new osg::Group(); root->addChild(mapNode); // 加载 .ive 模型 osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("D:\\Source\\moxing\\IVE\\feiji\\F-16.ive"); if (model) { // 创建红色材质使模型更醒目 osg::ref_ptr<osg::Material> mat = new osg::Material(); mat->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 0.0, 0.0, 1.0)); model->getOrCreateStateSet()->setAttributeAndModes(mat); // 放大模型(XYZ 轴各放大 50 倍) osg::ref_ptr<osg::MatrixTransform> scaleTransform = new osg::MatrixTransform(); scaleTransform->setMatrix(osg::Matrix::scale(90000.0, 90000.0, 90000.0)); scaleTransform->addChild(model); // 设置模型地理坐标 osgEarth::GeoTransform* geoTransform = new osgEarth::GeoTransform(); geoTransform->setPosition( osgEarth::GeoPoint( osgEarth::SpatialReference::get("wgs84"), 116.39, // 经度 39.9, // 纬度 100000.0 // 海拔高度(米) ) ); geoTransform->addChild(scaleTransform); root->addChild(geoTransform); } else { osg::notify(osg::WARN) << "无法加载 .ive 模型文件" << std::endl; } // 配置 Viewer _viewer->setSceneData(root); // 创建并设置 EarthManipulator osgEarth::Util::EarthManipulator* manip = new osgEarth::Util::EarthManipulator(); _viewer->setCameraManipulator(manip); // 设置初始视点(观察地球中心) osgEarth::Viewpoint viewpoint; viewpoint.setFocalPoint(osgEarth::GeoPoint( osgEarth::SpatialReference::get("earth"), // 使用 ECEF 坐标系 0.0, 0.0, 0.0 // 地球中心坐标为 (0,0,0) )); viewpoint.setRange(osgEarth::Distance(30000000.0, osgEarth::Units::METERS)); // 视距足够远 viewpoint.setPitch(osgEarth::Angle(-30.0, osgEarth::Units::DEGREES)); // 俯仰角 manip->setViewpoint(viewpoint, 3.0); // 平滑过渡 // 调整操作器设置 osgEarth::Util::EarthManipulator::Settings* settings = manip->getSettings(); settings->setArcViewpointTransitions(true); // 平滑过渡 settings->setSingleAxisRotation(false); // 允许多轴旋转(关键!) settings->setThrowingEnabled(false); // 禁用惯性滑动 // 优化渲染上下文 osg::ref_ptr<osg::GraphicsContext> gc = _viewer->getCamera()->getGraphicsContext(); if (gc) { gc->getState()->setUseModelViewAndProjectionUniforms(true); gc->getState()->setUseVertexAttributeAliasing(true); } // 完成初始化 _viewer->realize(); osg::notify(osg::INFO) << "场景初始化完成,地球绕球心旋转" << std::endl; }我的是基于VS的Qt工程,要怎么改才能点击飞机出现一个新的Qt界面
03-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值