场景图形管理 - (2)

      1. 裁剪平面示例(二)

裁剪平面(osg::Scissor)示例(二)的代码如程序清单8-2所示

// 裁剪平面测试(2)

void scissor_8_2(const string strDataFolder)

{

    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;

    traits->x = 50;

    traits->y = 50;

    traits->width = 1000;

    traits->height = 800;

    traits->windowDecoration = true;

    traits->doubleBuffer = true;

    traits->sharedContext = 0;

    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

    osg::ref_ptr<osg::Camera> camera = new osg::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);

    viewer->addSlave(camera.get());

    // 创建一个裁剪面

    osg::ref_ptr<osg::Scissor> scissor = new osg::Scissor;

    // 设置裁剪面矩形(左下角坐标,长和宽)

    scissor->setScissor(150, 150, 800, 600);

    osg::ref_ptr<osg::Group> root = new osg::Group();

    string strDataPath = strDataFolder + "cow.osg";

    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);

    if (node == nullptr)

    {

        cout << "读取cow.osg失败!" << endl;

        return;

    }

    root->addChild(node.get());

    osgUtil::Optimizer optimizer;

    optimizer.optimize(root.get());

    viewer->setSceneData(root.get());

    viewer->realize();

    viewer->run();

}

运行程序,截图如图 8-9 所示。

图8-9裁剪平面示例(二)截图

      1. 单视图与相机

在OSG中,单视图的管理是通过osgViewer.:Viewer来实现的。osgViewer.:Viewer 继承自多个类,负责OSG中单视图的管理,继承关系图如图8-10所示

图8-10 osgViewer::Viewer 的继承关系图

从继承关系图中可以看出osgViewer:Viewer继承自osgVicwer:View类和osg:Viewer:ViewerBase同样它也间接继承自osg::Referenced 类。因此,可以使用智能指针来管理

  • osg::View:主要用来管理所有相机视图。它包含一个主相机(Master Camera)和N个从属相机(Slave)。如果 View 仅有一个主相机,则该主相机用来负责控制和染视图场景。如果包含从属相机,则主相机用来负责控制管理视图,从属相机用于渲染场景。
  • osgViewer.:View:可以挂节事件、处理事件,并负责创建相机和创建图形环境窗口。
  • osgViewer.:ViewerBase:具有管理染的线程、负责设置线程模式、启动相关线程等功能。
  • osgGA::GUIActionAdapter类:GUI动作适配器用来向系统发送一些请求,以实现一些特定的操作。这也是后面说到的 GUI时间处理器的主要组成部分之一。

在osgViewer:Viewer中,只允许单视图,单视图可以同时包含多个相机渲染,也可以在多窗口中渲染。为了能够进行正常的渲染,还需要创建一个图形环境(默认的情况下已经创建了一个)。有时为了方便控制场景渲染,需要设置一个合适的图形环境窗口。

创建图形环境的主要步骤如下:

  1. 通过 WindowingSystemInterface 类得到系统窗口接口,该系统接口主要是为了关联窗口系统与图形环境。
  2. 下面是OSG中图形环境的主要特性,但在实际应用的过程中,没有必要设置每一个参数,只需根据实际需要来设置合理的参数即可。

x;y,width,height;// 窗口的坐标、高度及宽度,默认值都为0;windowDecration(false); // 是否支持窗口扩展的功能,Wi32中style

supportsResize(truc),// 是否支持窗口编放

red(8). //红色位数,默认8位

blue(8)//蓝色位数,默认8位

green(8)//绿色位数,默认8位

alpha(0)//alpha值位数,透明度,默认没有alpha通道,为RGB格式

depth(24)//颜色的深度(16,24,32),默认使用24位

stencil(0)//模板默认无

sampleBuffers(0)//采样缓存,默认无

samples(0).//采样倍数(抗锯齿的倍数),默认无

pbuffer(false)//pbuffer,默认不支持

quadBufferStereo(false)//立体四缓存,主要在高端显卡上有,如QUDRO显卡上

doubleBuffer(false) //是否支持双缓存,默认不支持

target(0),//目标

format(0)//格式

level(0)//嵌套的层数,默认无

face(0)./

mipMapGeneration(false),//是否支持生成Mipmap,默认不支持

vsync(true)//是否支持同步,默认同步模式

useMultiThreadedOpenGLEngine(false)/是否采用多线程,默认不支持

useCursor(true)//是否使用鼠标的指针,默认使用

sharedContext(0),//共享上下文

setInheritedWindowPixelFormat(false)//是否继承Window 中的位格式

  1. 通过图形环境特性创建图形环境。通过调用一个静态成员函数创建图形环境的代码如下:

osg::GraphicsContext:createGraphics(trait.get());

<4> 通过图形环境建窗口(hwnd)

有时仅用上面的方法创建一个图形环境是远远不够的,在OSG2.x系列以后,窗口的控制方式发生了变换,主要由宽度来控制场景的缩放。当窗口的宽度和高度不是 4:3 时,会出现一系列的问题,如变形等。这时调整宽度和高度肯定是可以的,还有一种方法就是设置投影矩阵。可以通过得到默认的对称透视投影,然后根据当前窗口的比例来确定一个合适的投影矩阵,代码可参看第 8.1.5节的示例。

      1. 宽屏变形示例

宽屏变形示例的代码如程序清单8-3所示

// 单视图+单相机 宽屏变形示例(3)

void wideScreen_8_3(const string strDataFolder)

{

    // 创建Viewer对象,场景浏览器

    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

    // 创建场景组节点

    osg::ref_ptr<osg::Group> root = new osg::Group();

    // 读取模型

    string strDataPath = strDataFolder + "cow.osg";

    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);

    root->addChild(node.get());

    // 设置图像环境特性

    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits();

    traits->x = 0;

    traits->y = 0;

    traits->width = 1000;

    traits->height = 800;

    traits->windowDecoration = true;

    traits->doubleBuffer = true;

    traits->sharedContext = 0;

    // 创建图像环境特性

    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

    if (gc.valid())

    {

        osg::notify(osg::INFO) << " GraphicsWindow has been created successfully." << endl;

        // 清除窗口颜色及清除颜色和深度缓冲

        gc->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.6f, 1.0f));

        gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    }

    else

    {

        osg::notify(osg::NOTICE) << " GraphicsWindow has not been created successfully" << endl;

    }

    // 根据分辨率确定合适的投影来保证显示的图形不变形

    double fovy, aspectRatio, zNear, zFar;

    viewer->getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);

    double newAspectRatio = double(traits->width) / double(traits->height);

    double aspectRatioChange = newAspectRatio / aspectRatio;

    if (aspectRatioChange != 1.0)

    {

        // 设置投影矩阵

        viewer->getCamera()->getProjectionMatrix() *= osg::Matrix::scale(1.0 / aspectRatioChange, 1.0, 1.0);

    }

    // 设置视口

    viewer->getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));

    // 设置图形环境

    viewer->getCamera()->setGraphicsContext(gc.get());

    // 优化场景数据

    osgUtil::Optimizer optimizer;

    optimizer.optimize(root.get());

    viewer->setSceneData(root.get());

    viewer->realize();

    viewer->run();

}

运行程序,截图如图8-11所示

图8-11宽屏变形示例截图

      1. 单视图多相机渲染示例

单视图多相机渲染示例的代码如程序清单8-4所示

// 单视图多相机示例(4)

void singleWindowMultipleCameras(osg::ref_ptr<osgViewer::Viewer> viewer)

{

    // 创建窗口系统接口

    osg::ref_ptr<osg::GraphicsContext::WindowingSystemInterface> wsi = osg::GraphicsContext::getWindowingSystemInterface();

    if (!wsi)

    {

        osg::notify(osg::NOTICE) << "Error, no WindowSystemInterface available cannot create windows." << endl;

        return;

    }

    // 得到窗口分辨率

    unsigned int width, height;

    wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);

    // 设置图形环境特性

    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;

    traits->x = 0;

    traits->y = 0;

    traits->width = width;

    traits->height = height;

    traits->windowDecoration = true;

    traits->doubleBuffer = true;

    traits->sharedContext = 0;

    // 创建图形环境

    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

    if (gc->valid())

    {

        osg::notify(osg::INFO) << " GraphicsWindow has been created successfully." << endl;

        // 确保窗口清除干净

        gc->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.6f, 1.0f));

        gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    }

    else

    {

        osg::notify(osg::NOTICE) << " GraphicsWindow has not been created successfully." << endl;

    }

    // 得到cameraMaster(主相机)

    osg::ref_ptr<osg::Camera> cameraMaster = viewer->getCamera();

    // 设置图形环境

    cameraMaster->setGraphicsContext(gc.get());

    // 根据分辨率确定合适的投影来保证显示的图形不变形

    double fovy, aspectRatio, zNear, zFar;

    cameraMaster->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);

    double newAspectRatio = double(traits->width) / double(traits->height);

    double aspectRatioChange = newAspectRatio / aspectRatio;

    if (aspectRatioChange != 1.0)

    {

        cameraMaster->getProjectionMatrix() *= osg::Matrix::scale(1.0 / aspectRatioChange, 1.0, 1.0);

    }

    // 设置视口

    cameraMaster->setViewport(new osg::Viewport(0, 0, width, height));

    GLenum bufferMaster = traits->doubleBuffer ? GL_BACK : GL_FRONT;

    // 设置缓冲区

    cameraMaster->setDrawBuffer(bufferMaster);

    cameraMaster->setReadBuffer(bufferMaster);

    // 创建从属相机

    osg::ref_ptr<osg::Camera> cameraClient = new osg::Camera();

    cameraClient->setGraphicsContext(gc.get());

    cameraClient->setViewport(new osg::Viewport(9, 0, 400, 400));

    GLenum bufferClient = traits->doubleBuffer ? GL_BACK : GL_FRONT;

    cameraClient->setDrawBuffer(bufferClient);

    cameraClient->setReadBuffer(bufferClient);

    // 添加从属相机

    viewer->addSlave(cameraClient, osg::Matrix::scale(aspectRatio, 1.0, 1.0), osg::Matrix());

}

void sinGraphMulCam_8_4(const string strDataFolder)

{

    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

    // 读取牛的模型

    string strDataPath = strDataFolder + "cow.osg";

    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);

    // 启用单视图多相机渲染

    singleWindowMultipleCameras(viewer.get());

    // 优化场景数据

    osgUtil::Optimizer optimizer;

    optimizer.optimize(node.get());

    viewer->setSceneData(node.get());

    viewer->realize();

    viewer->run();

}

运行程序,截图如图8-12所示

图8-12单视图多相机染示例截图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/179032.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

原力CEO赵锐:ToDesk是国内唯一适合高精远程办公需求的解决方案

随着数字办公在各行业的渗透&#xff0c;远程办公也逐渐成为一种常态。2000多名艺术家员工遍布全球各地的江苏原力数字科技股份有限公司&#xff08;下称&#xff1a;原力&#xff09;&#xff0c;是一家国内业务范围、规模均遥遥领先的数字业务内容提供商。一直以来&#xff0…

在webstorm中配置sass编译环境

1.下载ruby 下载地址&#xff1a;ruby下载 2.安装ruby 下载之后&#xff0c;有一个exe安装包 双击exe文件 &#xff0c;并选择自己的安装位置&#xff08;这个位置一定要记得&#xff0c;需要在webstorm中使用&#xff09;。其他的步骤默认安装即可。 3.安装sass ruby安装成功后…

【MATLAB源码-第75期】基于模拟退火算法(SA)的栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 模拟退火算法是一种启发式优化算法&#xff0c;通常用于解决组合优化问题&#xff0c;例如旅行商问题和图着色问题。它模拟了固体材料在退火过程中逐渐冷却达到稳定状态的行为&#xff0c;以寻找问题的全局最优解。 以下是模…

故障演练的关键要素及重要性

故障演练是一种有计划的、模拟真实生产环境故障的活动。通过故意引入故障、模拟系统组件失效或模拟其他异常条件&#xff0c;团队可以观察并评估系统在这些情况下的反应。这有助于发现潜在的问题、改进应急响应和提高系统整体的可用性。 一、故障演练的关键要素 计划性&#xf…

异常--Java

cry…catch使用 /*需求&#xff1a;测试除法器&#xff08;try...catch&#xff09;* 测试人&#xff1a;小王* 测试日期&#xff1a;2023/11/15* */ package yichang_test1;import java.util.InputMismatchException; import java.util.Scanner;public class TestException2 …

【ROS导航Navigation】四 | SLAM与导航 | 自主移动的地图构建 (更新ing)

致谢&#xff1a;ROS赵虚左老师 Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 参考赵虚左老师的实战教程 实现比较简单&#xff0c;步骤如下: 编写launch文件&#xff0c;集成SLAM与move_base相关节点&#xff1b;执行launch文件并测试。 <la…

无人机内存卡数据恢复

1.插入内存卡 2.选择对应的品牌 3.点击恢复 建议&#xff1a;发现数据打不开或者丢失情况&#xff0c;建议及时断电&#xff0c;以免影响数据的正常恢复&#xff01; #无人机##数据恢复##储存卡#

刚开始测试自动化? 这些错误不要犯,一定要看!别踩坑!!

我经常与一些客户打交道&#xff0c;他们的测试自动化能力要么刚刚开始&#xff0c;要么正在努力成长&#xff0c;而且他们常常都犯同样的致命错误。 虽然他们可能了解测试自动化的基础知识&#xff0c;但是他们仍然认为脚本化测试的价值在于通过自动执行脚本而不是手工执行来…

如何在Windows 10中进行屏幕截图

本文介绍如何在Windows 10中捕获屏幕截图&#xff0c;包括使用键盘组合、使用Snipping Tool、Snipp&Sketch Tool或Windows游戏栏。 使用打印屏幕在Windows 10中捕获屏幕截图 在Windows 10中捕获屏幕截图的最简单方法是按下键盘上的PrtScWindows键盘组合。你将看到屏幕短暂…

linux 网络 cat /proc/net/dev 查看测试网络丢包情况

可以通过 cat /proc/net/dev 查看测试网络丢包情况&#xff0c;drop关键字&#xff0c;查看所有网卡的丢包情况 还可以看其他数据&#xff0c; /proc/net/下面有如下文件

2023年 华为杯数学建模 E题

本科大三的时候&#xff0c;打过一次美赛&#xff0c;当时租了一个民宿&#xff0c;和队友一起度过了专注的四天。当时比赛结束之后&#xff0c;拿着手机&#xff0c;看到四天没回的消息&#xff0c;四天没刷过的朋友圈&#xff0c;有种很新奇的感觉&#xff0c;谢谢美赛给了我…

微信这4个功能容易暴露隐私,记得关闭

每天高频使用微信的我们&#xff0c;常常觉得安全无忧&#xff0c;然而这样的想法并不准确。尽管微信本身的安全性能极高&#xff0c;但若我们不主动设置相关功能&#xff0c;个人隐私和位置信息仍可能被暴露。 在微信朋友圈上&#xff0c;有些人喜欢分享生活的点滴&#xff0c…