场景交互与场景漫游-osgGA库(5)
osgGA库
osgGA库是OSG的一个附加的工具库,它为用户提供各种事件处理及操作处理。通过osgGA库读者可以像控制Windows窗口一样来处理各种事件
osgGA的事件处理器主要由两大部分组成,即事件适配器和动作适配器。osgGA:GUIEventHandler类主要提供了窗口系统的GUI事件接口它使用osgGA::GUIEventAdapter 实例来接收更新,使用osgGA::GUIActionAdapter 实例向系统发出请求
在osgGA::GUIEventHandler 中包含了一系列的枚举事件类型,如NONE、PUSH、RELEASE、DOUBLECLICK2、DRAG、MOVE、KEYDOWN 和KEYUP 等。但osgGA::GUIEventHandler 会根据不同的事件类型实现一些相关的操作,主要包括下面的类型:
NONE
PUSH//鼠标事件
RELEASE//松开
DOUBLECLICK//双击
DRAG//拖动
MOVE//移动
KEYDOWN//按键
KEYUP//松开
FRAME//每一帧
RESIZE//大小缩放
SCROLL//滚轮
PEN_PRESSURE/鼠标笔压力
PEN_ORIENTATION//鼠标笔的方位
PEN_PROXIMITY_ENTER //开始鼠标笔
PEN_PROXIMITY_LEAVE标笔离开
CLOSE_WINDOW//关闭窗口
QUIT_APPLICATIONG//退出程序
USER
这些事件类型与Windows的窗口事件非常类似。但在使用这些事件类型时,需要注意,有些OSG并没有实现好,如鼠标滑轮的事件。如果读者有兴趣实现的话,可以向 OSG 官方提供读者的实现代码,读者的大名将会出现在贡献人之列。
相对而言,osgGA::GUIActionAdapter 类就简单多了,它主要包含系统执行的动作,如重新绘制和光标重置之类的请求。
osgGA库还包含很多操作器,主要包含一个基类osgGA::MatrixManipulator和它的一些派生类osgGA::MatrixManipulator类是一个基类,提供了各种接口,这也是漫游会用到的一个基类。它提供的接口包括矩阵变换和事件处理,编写自己的操作器需要通过继承osgGA::MatrixManipulator 来实现,需要重载里面的矩阵变换函数和时间处理函数。这里只是简单介绍,后面会有详细说明。
从osgGA::MatrixManipulator 类派生的子类就是OSG中默认的操作器,主要包括
osgGA::AnimalionPathManipulator//动画路径操作器
osgGA::DriveManipulator//车行操作器
osgGA::FlightManipulator//飞行操作器
osgGA::KeySwitchMatrixManipulator//按键切换操作器
osgGA::NodeTrackerManipulator//节点跟踪操作器
osgGA::TerrainManipulator//地形操作器
osgGA::TrackballManipulator//跟踪球操作器
osgGA::UFOManipulator//UFO操作器
在默认情况下,OSG通常使用的是osgGA::TrackballManipulator 操作器。在前面很多程序中,都是直接使用 viewer->run(),其实,使用的操作器就是该跟踪球操作器。当然,读者可以将其设置为其他的操作器来处理,例如:
viewer->setCameraManipulator(new osgGA::TerrainManipulator());
OSG中预设了很多操作器,读者可以在适当的时候选择适当的操作器来完成相应的功能,这里不再赘述,因为不可能把所有操作器的源代码都拿来讲解,在实际应用中,更偏向于编写自己的操作器。
键盘事件消息处理
在osgGA库中,存在一个事件处理器 osgGA::GUIEventHandler,可以提供窗口系统的GUI事件接口。在OSG中,默认有很多已经写好的事件处理器。在osgViewer 应用程序中添加了很多在OSG中预定义的事件处理器,实现的功能有显示帧率、操作器切换和帮助等,这些事件处理器主要包括
class HelpHandler //帮助事件处理器
class StatsHandler //状态事件处理器
class WindowSizeHandler //窗口大小事件处理器
class ThreadingHandler //线程模型设置事件处理器
class RecordCameraPathHandler //动画记录事件处理器
class LODScaleHandler//LOD缩放事件处理器
class ScrccnCaptureHandler //截屏事件处理器
这些事件处理器的源代码可以在osgViewer目录下找到,有兴趣的读者可以去研究一下,或者改写为自己的事件处理器。
在实际过程中,编写自己的事件处理器是一件不可避免的事情,这也是交互的重要部分之一。如果一个平台没有交互,那就只是给客户放电影,就没有必要用到3D这样充满挑战的技术。
编写一个自己的事件处理器是非常简单的,主要操作步骤如下:
<1> 编写一个新类,继承自osgGA:GUIEventHandler类。
<2> 重载成员函数handle(),在osgGA::GUIEventHandler中,该函数原型如下,是一个虚函数:
virtual bool handle(const GUIEventAdapter &, GUIActionAdapter &)
这一步是非常关键的,也是十分重要的。通过重载该函数,可以根据事件的类型执行自定义动作(可参看第8.2.3节的示例)。
<3> 将事件处理器压入处理器列表。这一步是非常必要的,如果没有这一步,所写的事件处理器将不会执行,这相当于启动该事件处理器的作用,在使用时一定要注意。
在编写自己的事件处理器时,在事件处理函数中,事件处理函数的返回值与事件处理器列表中的当前处理器的键盘和鼠标时间相关,并保持一一对应关系。如果返回值为true,则系统会认为该事件已经处理,就不再传递给下一个事件处理器。如果返回值是false,那么它会继续传递给下一个事件处理器,执行对应事件的动作。在用户的应用程序中,可以包含多个事件处理器,在编写时要注意事件不要重复,否则可能会造成有些事件没有响应,有些事件却重复响应。
在第8.2.3节将演示一个抓图的示例。抓图本身比较简单,可以通过下面的代码实现:
// 读取像素信息抓图image->readPixels(0, 0, width, height, GL_RGB,GL_UNSIGNED_BYTE);
但在OSG2x系列以后,这样简单的执行会出现问题,读者会发现使用上面代码根本抓不到图片因为此时并没有得到当前的 RC 设备,这个问题曾经在邮件列表上也讨论过,最好的解决方案就是使用osg::Camera::DrawCallback,这样可以确保在当前RC设备下执行 readPixels(),从而可以保证抓取到图片。这时写一个简单的类,继承自 osg:Camera::DrawCallback类,在开始渲染前就执行绘制回调可以很容易抓到图片。
抓图示例的代码如程序如下所示。
/******************************************* 键盘事件-抓图示例 *************************************/
osg::ref_ptr<osg::Image> image_c = new osg::Image();// 定义一个全局变量// 得到抓图
struct CaptureDrawCallback :public osg::Camera::DrawCallback
{CaptureDrawCallback(osg::ref_ptr<osg::Image>image){_image = image;}~CaptureDrawCallback(){}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);}osg::ref_ptr<osg::Image> _image;
};// 抓图时间处理器
class ImageHandle :public osgGA::GUIEventHandler
{
public:ImageHandle(){}~ImageHandle(){}// 重置handle()函数bool ImageHandle::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa){osg::ref_ptr<osgViewer::Viewer> viewer = dynamic_cast<osgViewer::Viewer*>(&aa);if (viewer == nullptr){return false;}// 定义一个静态变量static int _screenCaptureSequence = 0;switch (ea.getEventType()){case osgGA::GUIEventAdapter::KEYDOWN:// 按键{int iValue = ea.getKey();if (ea.getKey() == 'c' || ea.getKey() == 'C'){char filename[128];// 确定一个合理的文件名,以保证能够连续抓图sprintf_s(filename, "D:\\ScreenShot%04d.bmp", _screenCaptureSequence);++_screenCaptureSequence;// 写入文件osgDB::writeImageFile(*(image_c.get()), filename);}break;}default:{return false;}}return true;}
};
// 键盘事件之抓图示例
void CaptureImage_8_7(const string &strDataFolder)
{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());// 优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root.get());// 设置绘制回调viewer->getCamera()->setPostDrawCallback(new CaptureDrawCallback(image_c.get()));viewer->setSceneData(root.get());// 添加抓图时间viewer->addEventHandler(new ImageHandle());viewer->realize();viewer->run();
}
图8-16 抓图示例截图
相关文章:

场景交互与场景漫游-osgGA库(5)
osgGA库 osgGA库是OSG的一个附加的工具库,它为用户提供各种事件处理及操作处理。通过osgGA库读者可以像控制Windows窗口一样来处理各种事件 osgGA的事件处理器主要由两大部分组成,即事件适配器和动作适配器。osgGA:GUIEventHandler类主要提供了窗口系统的…...
Leetcode -1
Leetcode Leetcode -521.最长特殊序列Leetcode - 541.反转字符串Ⅱ Leetcode -521.最长特殊序列 题目:给你两个字符串 a 和 b,请返回 这两个字符串中 最长的特殊序列的长度。如果不存在,则返回 - 1 。 「最长特殊序列」 定义如下࿱…...

系列四、JVM的内存结构【本地接口(Native Interface)】
一、组成 本地接口由本地方法栈(Native Method Stack)、本地方法接口(Native Interface)、本地方法库组成。 二、本地接口的作用 本地接口的作用是融合不同的编程语言为Java所用,它的初衷是融合C/C程序,Jav…...

大型语言模型中的幻觉研究综述:原理、分类、挑战和未决问题11.15+11.16+11.17
大型语言模型中的幻觉研究综述:原理、分类、挑战和未决问题11.15 摘要1 引言2 定义2.1 LLM2.3 大语言模型中的幻觉 3 幻觉的原因3.1 数据的幻觉3.1.1 有缺陷的数据源3.1.2 较差的数据利用率3.1.3 摘要 3.2 来自训练的幻觉3.2.1训练前的幻觉3.2.2来自对齐的幻觉3.2.3…...
redis悲观锁和乐观锁
redis悲观锁 Redis加锁命令分有INCR、SETNX、SET 一、INCR锁 key不存在时,key的值会先被初始化为0,其它用户在执行INCR操作进行加一, 如果返回的数大于1,说明这个锁正在被使用当中,通常用在同时只能有一个人可以操作某…...
前端项目练习,首页退出登录功能,清除token --点击事件 quitFn
<el-menu-item index"2" click"quitFn"><i class"el-icon-switch-button">退出</i> </el-menu-item>quitFn() {// 为了让用户体验更好,来个确认提示框this.$confirm("确认退出登录吗?退出登…...

nodejs+vue杰和牧场管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计
系统涉及的对象是奶牛。 系统使用员工有管理员和普通员工。 管理员有修改的权限,普通员工没有。系统包含新闻功能,最好是有个后台管理,在后台输入新闻标题和内容,插入图片,在网页上就可以展示。最好再有个轮播图。 新闻…...

基于STM32的蓝牙低功耗(BLE)通信方案设计与实现
蓝牙低功耗(Bluetooth Low Energy,简称BLE)是一种能够在低功耗环境下实现无线通信的技术。在物联网应用中,BLE被广泛应用于传感器数据采集、健康监测设备、智能家居等领域。本文将基于STM32微控制器,设计并实现一个简单…...

qt 重载信号,使用““方式进行connect()调用解决方案
问题 在Qt中,重载的信号默认是无法使用&这种方式调用的。 因为&只能绑定到一个具体的信号,而重载的信号名称相同,编译器无法确定要绑定哪一个信号。 解决方案 如果非要使用&绑定重载的信号,可以使用函数指针进行转…...

阿里云+宝塔部署项目(Java+React)
阿里云服务器宝塔面板部署项目(SpringBoot React) 1. 上传所需的文件到服务器 比如jdk包和java项目的jar:这里以上传jar 为例,创建文件夹,上传文件; 在创建的文件夹下上传jar包 上传jdk 2. 配置jdk环境 3.…...

Linux_系统信息_uname查看内核版本、内核建立时间、处理器类型、顺便得到操作系统位数等
1、uname --help 使用uname --help查看uname命令的帮助信息 2、uname -a 通过上面的help就知道-a选项显示全部内容时的含义了。 内核名是Linux主机名是lubancat,如果想看主机名可以使用命令hostname;内核版本是Linux 4.19.232,建立时间为2…...
screen中conda激活环境后登录jupyter notebook导入包提示找不到,但是在命令行中就可以导入包
问题:screen中conda激活环境后登录jupyter notebook导入包提示找不到,但是在命令行中就可以导入包 解决方法: screen可能有bug,当在screen中conda激活环境后登录jupyter notebook出现问题,import torch提示没有安装好…...

基于SSM的中小型企业财务管理设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
工厂模式之简单工厂模式(常用)
工厂模式的分类 简单工厂模式工厂方法模式抽象工厂模式 简单工厂模式 简单工厂模式又称为静态工厂模式,实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。简单工厂模式的…...

Kafka入门教程与详解(一)
Kafka入门教程与详解(一) 一、Kafka入门教程 1.1 消息队列(Message Queue) Message Queue消息传送系统提供传送服务。消息传送依赖于大量支持组件,这些组件负责处理连接服务、消息的路由和传送、持久性、安全性以及日志记录。消…...
GoFrame学习随便记1
用Yii1.1中典型的 blog 项目作为例子来学习Web应用应该不错。数据库 sqlite3,windows下可以下载 sqlite-tools-win-x64-*** (https://www.sqlite.org/download.htm),把下载的几个exe放到 %GOPATH%\bin 目录下,而该目…...

最新自动定位版本付费进群系统源码
更新内容: 1.在网站首页增加了付款轮播功能。 2.新增了城市定位功能,方便用户查找所在城市的相关信息。 3.对域名库及支付设置进行了更新和优化。 4.增加了一种图模板设置模式,简化了后台模板设置流程。 5.此外还进行了前后台的其他优化…...

freeswitch的一个性能问题
概述 freeswitch是一款简单好用的VOIP开源软交换平台。 在fs的使用过程中,会遇到各种各样的问题,各种问题中,性能问题是最头疼的。 最近在测试某些场景的时候,压测会造成fs的内存占用持续升高,并在达到某个临界点的…...

各机构如何加强网络渗透、“渗透”防御
数据渗透,例如黑客攻击和“渗透”,或未经授权的信息传输。 联邦调查局、国家安全局以及网络安全和基础设施安全局最近的联合报告证明,网络安全仍然是当今国防部门面临的两个最大的网络威胁。 所谓的零日攻击尤其有害,因为组织在…...
Docker命令 常用中间件运维部署,方便构建自己服务
Tips:记录了如何安装不同中间件的Docker命令,帮助大家更方便的搭建自己服务,会不定期更新。 MySQL # Mysql 5版本: docker run -d -p 3306:3306 --privilegedtrue \ -v /itholmes/mysql/log:/var/log/mysql \ -v /itholmes/mysql…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...