场景图形管理 - (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.mzph.cn/news/143424.shtml

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

相关文章

msvcp140.dll丢失的解决办法,msvcp140.dll丢失会导致电脑出现哪些错误

msvcp140.dll丢失的解决办法都有哪些&#xff1f;如果电脑不及时将msvcp140.dll文件进行修复的话电脑可能会出电脑可会出现哪些错误&#xff1f;今天就和大家说说都有哪些解决办法有效的解决msvcp140.dll丢失的问题。 一.缺失msvcp140.dll会有什么问题 当电脑上缺少msvcp140.d…

基于stm32f103系列的简单软件I2C和硬件I2C通讯

这篇文章主要分为三个部分来阐述&#xff0c;分别是I2C的基本知识&#xff0c;软件I2C通讯&#xff0c;硬件I2C通讯。I2C的基本知识这一块&#xff0c;部分讲解以及图表来自b站江科大的up&#xff0c;很感谢这位up&#xff0c;大家可以关注一波。操作实现的时候&#xff0c;up使…

hadoop 大数据环境配置 同步时间 centos服务器时间同步 linux 安装ntp服务更新时间 hadoop(六)

1. 安装ntp软件 yum install -y ntp 2.创建软连接 # 删除之前得时间 sudo rm -rf /etc/localtime;# 更新时区sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime3. 更新时间 # root 权限运行 sudo ntpdate -u ntp.aliyun.com 4. 开机自启&#xff0c;更新时间 …

吴恩达《机器学习》8-5->8-6:特征与直观理解I、样本与值观理解II

8.5、特征与直观理解I 一、神经网络的学习特性 神经网络通过学习可以得出自身的一系列特征。相对于普通的逻辑回归&#xff0c;在使用原始特征 x1​,x2​,...,xn​ 时受到一定的限制。虽然可以使用一些二项式项来组合这些特征&#xff0c;但仍然受到原始特征的限制。在神经网…

负载均衡原理

负载均衡原理是什么&#xff1f; 负载均衡Load Balance&#xff09;是高可用网络基础架构的关键组件&#xff0c;通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。负载均衡&#xff0c;其核心就是网络流量分发&#xff0c;分很多维度。 …

iOS OpenGL ES3.0入门实践

一、效果图 入门实践&#xff0c;做的东西比较简单&#xff0c;效果如下&#xff1a; 二、关于顶点坐标和纹理坐标 绘制图片需要设置顶点坐标和纹理坐标并加载像素数据&#xff0c;之所以要指定两组坐标是因为纹理和顶点使用不同的坐标系&#xff0c;就是告诉OpenGL&#xf…

IDEA 2023搭建 SpringMVC +FreeMarker+JDBC

1.IDEA的版本&#xff0c;目前最新是2023&#xff0c;要选择旗舰版。笔者曾选择社区版&#xff0c;发现少了很多功能。只能重新安装。 2.安装好以后的第1件事&#xff0c;是设置Maven&#xff0c;并将下载地址改为淘定站&#xff0c;参照这篇一次包会——最新IDEA配置Maven指南…

老师的保命大法

数字化高度发达的今天&#xff0c;成绩查询系统已经成为学校教育中不可或缺的一部分。不同于传统的成绩公布方式&#xff0c;成绩查询系统更加高效、便捷&#xff0c;同时也充分保障了每位学生的隐私&#xff0c;今天就来揭秘这个教师保命大法&#xff01; 1、代码查询法 对于…

下载文件时的文件名中文乱码问题,文件名丢失

涉及到的java代码如下&#xff0c;下载的时候文件名为中文 package com.example.springboot.service.impl;import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.StringU…

墨西哥专线一次最多发几条柜?

墨西哥专线一次最多发几条柜这个问题涉及到海运业务中的一些复杂因素。墨西哥是一个重要的贸易国家&#xff0c;其与美国和加拿大之间的贸易往来非常频繁&#xff0c;因此海运业务也非常活跃。在墨西哥专线上&#xff0c;一次最多发几条柜通常取决于以下几个因素&#xff1a; 1…

Vue的计算属性:让你的代码更简洁高效

Vue.js是一种流行的JavaScript框架&#xff0c;它提供了许多功能来帮助开发人员构建交互式Web应用程序。其中一个非常有用的功能是计算属性。在本文中&#xff0c;我们将讨论什么是Vue的计算属性以及如何使用它们来编写更简洁高效的代码。 什么是Vue的计算属性&#xff1f; Vu…

Java 等后端应用如何获取客户端真实IP —— 筑梦之路

需求说明 现有一套Java开发的应用&#xff0c;需要能获取到用户访问的真实IP地址&#xff0c;以此来过滤到一些不安全的因素。而实际部署的场景中Java服务提供给用户访问需要经过多次代理&#xff0c;默认情况下是无法获取到客户端真实IP地址的&#xff0c;因此要实现该需求&a…

yolov5的concat是什么层

yolov5 concat 在YOLOv5中&#xff0c;concat是指在网络的不同层之间进行张量拼接操作。YOLOv5使用了混合尺度特征融合的方式进行目标检测&#xff0c;其中concat操作是将不同尺度的特征图在通道维度上进行拼接&#xff0c;以提高目标检测的精度。 具体来说&#xff0c;YOLOv…

ubuntu 20通过docker安装onlyoffice,并配置https访问

目录 一、安装docker &#xff08;一&#xff09;更新包列表和安装依赖项 &#xff08;二&#xff09;添加Docker的官方GPG密钥 &#xff08;三&#xff09;添加Docker存储库 &#xff08;四&#xff09;安装Docker &#xff08;五&#xff09;启动Docker服务并设置它随系…

最优化基础(一)

最优化基础&#xff08;一&#xff09;1 最优化问题的数学模型 通俗地说&#xff0c;所谓最优化问题&#xff0c;就是求一个多元函数在某个给定集合上的极值. 几乎所有类型的最优化问题都可以用下面的数学模型来描述: m i n f ( x ) s . t . x ∈ Ω min\ f({x})\\ s.t. \ {…

python 实验3

姓名&#xff1a;66 学号&#xff1a; 专业年级&#xff1a;2021级 班级&#xff1a; 实验的准备阶段 (指导教师填写) 课程名称 Python开发与应用 实验名称 函数的应用 实验目的 &#xff08;1&#xff09;能够编写简单函数&#xff0c;掌握不定长参数和返回值的应…

编程怎么学习视频教程,编程实例入门教程,中文编程开发语言工具下载

编程怎么学习视频教程&#xff0c;编程实例入门教程&#xff0c;中文编程开发语言工具下载。 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的软件…

接口测试--知识问答

1 做接口测试当请求参数多时tps下降明显&#xff0c;此接口根据参数从redis中获取数据&#xff0c;每个参数与redis交互一次&#xff0c;当一组参数是tps5133&#xff0c;五组参数是tps1169&#xff0c;多次交互影响了处理性能&#xff0c;请详细阐述如何改进增进效果的方案。 …

阿里云记录保存

恭喜您&#xff0c;试用ECS创建成功 实例ID&#xff1a;i-bp1h36cszlkbxbf5gqee 您的免费试用已正式开启&#xff01;立即登录ECS控制台&#xff0c;完成新手任务&#xff0c;即可快速上手ECS。ECS实例创建需要1-5分钟&#xff0c;请您耐心等待。 121.43.231.59 公网 172.25…

mysql数据库时间

记录MySQL今天又一个新的问题&#xff1a; 场景&#xff1a;nodejs后台容器部署 问题原因&#xff1a;纯属好心办坏事&#xff0c;由于考虑了时区&#xff08;现在看来纯属多余&#xff09;&#xff0c;在写入时间时使用了time_str.toLocaleString("chinese", { ti…