场景图形管理 - (2)

news2024/11/13 9:32:14

      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.coloradmin.cn/o/1212656.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

甲方与三方渗透团队的协作注意点

文章目录 以下是优化后的内容&#xff1a; 作为甲方安全团队主导的渗透攻击&#xff0c;以下几点需要注意&#xff1a; 预备充分 与测试团队协调&#xff0c;提供乙方攻击所需的必要资源&#xff0c;以及具有甲方特色的资源。例如&#xff0c;如果认为自己的权限系统需要重点评…

JSON vs. CSV vs. YAML vs. XML vs. HDF5vs. XLS:数据格式之争

前言 数据处理是现代计算机科学和信息技术中至关重要的一部分。有效地选择和处理数据格式是数据科学、工程和各种应用中的关键环节。本文将深入探讨各种常见数据格式及其Python库的应用&#xff0c;旨在帮助读者更好地理解和应用这些数据格式&#xff0c;以及如何选择最适合自…

UE5 - UI Material Lab 学习笔记

1、学习资料收集 UI Material Lab : https://www.unrealengine.com/marketplace/zh-CN/product/ui-material-lab 视频1&#xff1a;https://www.bilibili.com/video/BV1Hm4y1t7Kn/?spm_id_from333.337.search-card.all.click&vd_source707ec8983cc32e6e065d5496a7f79ee6 视…

FDTD自定义材料

官方原文档链接 该文档内容摘自原文档及相关链接 从txt导入材料数据 各项同性材料的3Dmaterials数据 txt文件中应包含以下三列。第一列为波长或频率&#xff1b;第二列为折射率或介电常数实部&#xff1b;第三列为折射率或介电常数虚部。 420 5.08894 0.237724 440 4.78…

性能测试场景的设计方法

作者&#xff5c;李文&#xff0c;自如-质量中心 来源&#xff5c;自如技术公众号 背景 引用&#xff1a;根据2008年Aberdeen Group的研究报告&#xff0c;对于Web网站&#xff0c;1秒的页面加载延迟相当于少了11%的PV&#xff08;page view&#xff09;&#xff0c;相当于降低…

Unity--互动组件(Toggle Group)||Unity--互动组件(Slider)

Toggle Group 属于同一组的切换开关受到限制&#xff0c;因此一次只能打开其中一个开关&#xff0c;按下其中一个开关时&#xff0c;其他的开关将会自动关闭&#xff1b; Allow Switch Off&#xff1a;&#xff08;允许关闭&#xff09; 如果禁用此设置&#xff0c;则按下当前…

Hadoop的概述

1、Hadoop的发展史&#xff1a; Google首先发布三篇文章&#xff1a;GFS(Google File System)、Mapreduce&#xff08;计算引擎&#xff09;、Bigtable &#xff0c;随着时间的推移&#xff1a; hadoop1.0与2.0 的区别是在2.0的版本中出现了yarn&#xff0c;主要是负责资源的调…

【轨道机器人】实现Windows与下位机串口通信(未完成)

方案一&#xff1a;QT&#xff0c;编写类似串口调试助手的APP&#xff0c;连接上硬件&#xff0c;qt有个好像是串口缓存函数&#xff0c;可以防止占用CPU。&#xff08;缺点qt估计要时间学&#xff09; 方案二&#xff1a;利用vscode、C&#xff0c;编写一个可执行exe文件&…

面向对象和原型/原型链学习

##构造函数执行的机制 函数的其中一个作用,就是构造函数. ###new关键字 1.创建一个对象; 2.这个对象的原型,可以看到这个Function 3.该对象,实现了这个构造函数的方法. 4.根据一些特定情况,返回: (1)如果没有返回值,就返回一个对象; (2)如果返回一个基本类型,则还是返回…

利用Vue+Echarts完成可视化任务

文章目录 任务一&#xff1a;用柱状图展示消费额最高的省份&#xff08;一&#xff09;提出任务&#xff08;二&#xff09;准备工作1、利用postman访问接口数据2、安装node.js3、输入更换镜像源为淘宝源4、清除npm缓存5、安装vue脚手架 任务一&#xff1a;用柱状图展示消费额最…

2023.11.15-hivesql之炸裂函数explode练习

把一个容器的多个数据炸裂出单独展示: explode(容器) 需求:将NBA总冠军球队数据使用explode进行拆分&#xff0c;并且根据夺冠年份进行倒序排序。 1.建表 --step1:建表 create table the_nba_championship(team_name string,champion_year array<string> ) row format…

手摸手入门Springboot2.7集成Swagger2.9.2

环境介绍 技术栈 springbootmybatis-plusmysqloracleSwagger 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 REST软件架构风格 REST即表述性状态传递&#xff08;英文&#xff1a;Representational State T…

【informer】 时间序列的预测学习 2021 AAAI best paper

文章目录 前言1.引入2.数据集训练 前言 数据集 https://github.com/zhouhaoyi/ETDataset/blob/main/README_CN.md 代码&#xff1a;https://github.com/zhouhaoyi/Informer2020#reproducibility 21年的paper:https://arxiv.org/pdf/2012.07436.pdf 论文在代码上有连接&#xf…

Promise 重写 (第一部分)

学习关键语句&#xff1a; promise 重写 写在前面 重新学习了怎么重写 promise &#xff0c; 我觉得最重要的就是要有思路&#xff0c;不然有些 A 规范是完全想不到的 开始 重写函数的过程中, 最重要的是有思路 我们从哪里获取重写思路? 从正常的代码中 我们先看正常的代码…

C语言判断水仙花数(ZZULIOJ1027:判断水仙花数)

题目描述 春天是鲜花的季节&#xff0c;水仙花就是其中最迷人的代表&#xff0c;数学上有个水仙花数&#xff0c;他是这样定义的&#xff1a;“水仙花数”是指一个三位数&#xff0c;它的各位数字的立方和等于其本身&#xff0c;比如153135333。 现在要求输入一个三位数&#…

delete 与 truncate 命令的区别

直接去看原文 原文链接:【SQL】delete 与 truncate 命令的区别_truncate和delete的区别-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- 1. 相同点 二者都能删除表中的数据…

不敢信,30+岁的项目经理会是这样

大家好&#xff0c;我是老原。 你们知道&#xff0c;每个阶段的项目经理都是什么样的吗&#xff1f; 20多岁时&#xff0c;刚踏入项目管理的你可能是个什么都不懂的职场小白&#xff0c;或者只能在旁边打打下手&#xff1b; 到了30岁&#xff0c;经历了项目的人情冷暖&#…

QT中的鼠标事件

鼠标追踪打开后进去一动就显示

我把微信群聊机器人项目开源

▍PART 序 开源项目地址》InsCode - 让你的灵感立刻落地 目前支持的回复 ["抽签", "天气", "讲笑话", "讲情话", "梦到", "解第", "动漫图", "去水印-", "历史今天", "星座-…

Linux控制---进程程序替换

前言&#xff1a;前面我们学洗了Linux进程退出的相关知识&#xff0c;了解了什么是进程退出&#xff0c;已经进程等待的相关话题&#xff0c;今天&#xff0c;我们来学习Linux中的进程程序替换&#xff0c;进程程序替换在Linux中可以用于实现新程序的启动、程序升级、多进程程序…