OpenSceneGraph学习笔记

目录

  • 引言
  • 第一章:OSG概述
    • 一、前言
      • (1)为什么要学习OSG?
      • (2)OSG的组成
      • (3)OSG的智能指针
      • (4)OSG的安装编译
    • 二、第一个OSG程序
      • (1)Hello OSG程序
      • (2)OSG渲染程序的基本流程
  • 第二章:数学基础
    • 一、坐标系统
      • (1)世界坐标系
      • (2)物体坐标系
      • (3)摄像机坐标系
    • 二、坐标系变化
      • (1)物体坐标系-世界坐标系变化
      • (2)访问器

引言

 本文为我学习OSG库的笔记,其目的是在已有计算机图形学的基础上,记录OSG的关键知识,以达到快速学习的目的。
 教材:OSG-DOC.pdf。

第一章:OSG概述

一、前言

(1)为什么要学习OSG?

  我在本科毕业时尝试使用DirectX去设计一个通用图形库,它旨在为Windows上应用程序提供图像计算和渲染服务,使得程序开发者不需要了解计算机图形学以及图像API,就能渲染出满意的图形。
 在设计过程中,学习DirectX12并不是我遇到最难的问题,而是如何设计通用图形库的架构,如何构建通用的Shader接口?如何提供和Shader配套的设置?如何组织场景对象?这些是需要思考的问题。
 OSG场景图像系统是使用OpenGL开发的库,它能让程序员更快速、便捷地创建高性能和跨平台的交互式图像程序。也许你会用OpenGL,但你是否能够设计出通用、高性能、跨平台的OpenGL封装库呢?
 无论是工作要使用OSG,还是学习如何设计图形引擎甚至游戏引擎,学习OSG都将使你受益匪浅。

(2)OSG的组成

 在系统的底层绘图硬件和相应的软件驱动程序之上,OSG封装了OpenGL。
在这里插入图片描述

 OSG由多个模块组成,它主要包括如下4个库(通读一遍下文即可)。
在这里插入图片描述
在这里插入图片描述

(3)OSG的智能指针

 OSG提供了智能指针类osg::ref_ptr来管理内存并防止内存泄漏,智能指针使用示例如下。

// 创建场景浏览器实例osgViewer::Viewer
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(); // 推荐写法
osgViewer::Viewer* viewer = new osgViewer::Viewer(); // 不推荐写法

(4)OSG的安装编译

 在此不再赘述,可查阅OSG中文社区或非官方教程。

二、第一个OSG程序

(1)Hello OSG程序

 程序代码如下,本文所有代码具有注释,非关键点不再赘述。

#include<osgViewer/Viewer>#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>#include<osgDB/ReadFile>
#include<osgDB/WriteFile>#include<osgUtil/Optimizer>int main()
{// 创建场景浏览器实例osgViewer::Viewerosg::ref_ptr<osgViewer::Viewer> viewer= new osgViewer::Viewer();// 创建一个场景组节点osg::Grouposg::ref_ptr<osg::Group> root= new osg::Group();// 创建一个节点osg::node,并将牛模型读入到此节点中osg::ref_ptr<osg::Node> node= osgDB::readNodeFile("cow.osg");// 将node节点加入为group节点的子节点root->addChild(node.get());// 优化场景数据结构osgUtil::Optimizer optimizer;optimizer.optimize(root.get());// 将group节点设置为场景浏览器的场景数据viewer->setSceneData(root.get());// 初始化并创建窗口viewer->realize();// 开始渲染viewer->run();return 0;
}

 代码的学习,建议大家首先照着代码和注释打一遍,然后理解注释和代码,再然后删掉注释按照理解自己重写注释,最后删掉原代码按照注释还原代码。(找不到cow.osg文件的安装OSG-DATA并配置到环境变量,若使用了vcpkg可能会忽略环境变量,可在vs中进行设置)

(2)OSG渲染程序的基本流程

 根据上述程序,可知OSG场景渲染程序的基本流程如下:

步骤内容
1创建场景浏览器,即通过osgViewer::Viewer类创建对象,用于渲染场景
2加载模型和场景数据
3建立场景树,确定场景数据之间的关系
4执行渲染场景的循环

 OSG提供许多丰富功能可使用命令行使用,本文专注于图像库的使用和设计,因此不再叙述,详情可看教材原文。

第二章:数学基础

 虽然学习过计算机图形学,但学习OSG是怎样对图形学系统进行封装的,是非常有必要的。
 OSG中的向量类有如下种类。
在这里插入图片描述

一、坐标系统

 坐标系是什么?坐标系是一个精确定位对象位置的框架,所有的图形变换都是基于一定的坐标系进行的。
 常见坐标系有世界坐标系、物体坐标系和摄像机坐标系。

(1)世界坐标系

 世界坐标系又称为全局坐标系,它描述的是整个场景中的所有对象,它为所有对象的位置提供一个绝对的参考标准,可以理解为绝对坐标系,因为所有对象的位置都是绝对坐标。

(2)物体坐标系

 物体坐标系是针对某一特定的物体建立的独立坐标系,它使得描述单独物体非常方便,比如建模师可能会在空间原点附近建模一个人体,这个人体模型就位于物体坐标系。
 建模师通常不在乎模型会被放到世界的哪个角落,它只需要在物体坐标系下建模好人物,然后生成人物的多个动画,当3D开发者使用时将模型变换到世界坐标即可。

(3)摄像机坐标系

 摄像机坐标系是和观察者相关的坐标系。摄像机坐标系和屏幕坐标系类似,但二者的差异在于摄像机坐标系处于3D空间中,而屏幕坐标系在2D平面里。
 摄像机坐标系描述的问题是:“哪些物体应该渲染并显示在屏幕上?”,主要包括物体是否在摄像机坐标系区域内、物体的渲染顺序和物体的遮挡剔除。
 OSG和OpenGL的世界坐标系都是左手坐标系,并且X轴都是向右,但OpenGL的Y轴向上且Z轴向你(即垂直指向屏幕外),而OSG的Z轴向上且Y轴垂直屏幕向里,具体见下图。
在这里插入图片描述

二、坐标系变化

(1)物体坐标系-世界坐标系变化

 三维实体对象需要经过一系列的坐标变化才能正确、真实地显示在屏幕上。
 每个物体对象都定义在自己的物体坐标系下,当渲染时,每个物体对象通过变化矩阵变换到世界坐标系中。
 如何在OSG中实现从物体坐标系到世界坐标系呢?OSG以节点组成场景树,每个节点都有自己的父节点和自己的变化矩阵,变化矩阵记录了如何从自己的坐标系变化到父节点坐标系,因此只需将该节点与根节点之间所有节点的变化矩阵相乘即可。
 如何实现上述遍历和计算过程呢?在OSG中有多种方式,如回调、访问器等。用访问器的好处是方便可控,每一帧都会自动计算矩阵变化,但缺点是回调在一定程度上不可操控,并且会增加额外开销而影响渲染效率。

(2)访问器

 访问器通过遍历的方式记录场景中节点的路径,并根据路径上的变化矩阵计算出世界坐标。下面以代码的形式展示访问器的使用。

#include<osgViewer/Viewer>#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>#include<osgDB/ReadFile>
#include<osgDB/WriteFile>#include<osgUtil/Optimizer>// 手工如何计算?从节点到根节点,将变换矩阵逐个相乘计算最终结果。// 定义新的节点访问器类,以实现对节点和场景树的自定义形式访问
// 新访问器类需要继承osg::NodeVisitor
class GetWorldCoordinateOfNodeVisitor : public osg::NodeVisitor
{
public:// 节点访问器类的构造函数,需要初始化osg::NodeVisitor// NodeVisitor::TRAVERSE_PARENTS表示访问目标节点和其父节点GetWorldCoordinateOfNodeVisitor() :osg::NodeVisitor(NodeVisitor::TRAVERSE_PARENTS), done(false){/*osg::ref_ptr主要用于自动管理那些继承自osg::Referenced类的对象,而osg::VecN和osg::MatrixT类似整数和浮点数直接使用即可,但是osg::VecN*和osg::MatrixT*搭配new申请空间时,需要自己手动释放,否则会造成内存泄漏*/wcMatrix = new osg::Matrixd();}// 自定义访问节点和场景树的方式virtual void apply(osg::Node& node){// done标识是否遍历到根节点,就像手算一样若遍历到根节点则逐层回退if (!done){// 虽然说场景是树,但其实它是一个无环图,因为一个节点可能有多个父节点// 若一个场景需要渲染多棵同样的树,让树节点被多个具有不同变换的父节点引用即可if (0 == node.getNumParents()){// 若没有父节点则到达场景根节点,计算最终世界坐标并标识根节点已到达wcMatrix->set(osg::computeLocalToWorld(this->getNodePath()));done = true;}traverse(node);}}// 要返回最终变换矩阵的地址,因此该类没有处理osg::Matrixd可能造成的内存泄漏osg::Matrixd* giveUpDaMat(){return wcMatrix;}private:bool done;osg::Matrix* wcMatrix;
};// 访问节点node计算其最终变换矩阵
osg::Matrixd* getWorldCoords(osg::Node* node)
{/** 若使用osg::ref_ptr<osg::node>作为参数,则该函数可能使得计数增加,使得node永远不能释放,造成内存泄漏* 因此若一个函数不应记录某参数,则应向其传入osg::T*即类型指针,并因此要检查此指针是否为空*/ // 创建自定义访问器对象,由于其被节点所引用,因此应使用new申请方式GetWorldCoordinateOfNodeVisitor* ncv = new GetWorldCoordinateOfNodeVisitor();if (node && ncv){// 将访问器应用到节点,节点会引用该访问器node->accept(*ncv);// 返回访问器的遍历结果return ncv->giveUpDaMat();}else{return NULL;}
}

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

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

相关文章

美式键盘 QWERTY 布局的来历

注&#xff1a;机翻&#xff0c;未校对。 The QWERTY Keyboard Is Tech’s Biggest Unsolved Mystery QWERTY 键盘是科技界最大的未解之谜 It’s on your computer keyboard and your smartphone screen: QWERTY, the first six letters of the top row of the standard keybo…

Linux热键,shell含义及权限介绍

君子忧道不忧贫。 —— 孔丘 Linux操作系统的权限 1、几个常用的热键介绍1、1、[Tab]键1、2、[ctrl]-c1、3、[ctrl]-d1、4、[ctrl]-r 2、shell命令以及运行原理3、权限3、1、什么是权限3、2、权限的本质3、3、Linux中的用户3、4、Linux中文件的权限3、4、1、快速掌握修改权限的…

vue引用js html页面 vue引用js动态效果

要引用的index.html页面&#xff1a;&#xff08;资源来自网络&#xff09;在pubilc下建一个static文件放入js文件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>数字翻转</title><meta con…

速部署 HBase 测试环境

快速部署 HBase 测试环境 第一步&#xff1a;下载软件&#xff0c;在HBase官网下载最新版&#xff0c; 找到 bin&#xff0c;点击下载&#xff0c;比如我这里下载的是 hbase-2.5.6-bin.tar.gz 第二步&#xff1a;解压软件 $ tar -zxvf hbase-2.5.6-bin.tar.gz $ cd hbase-2.…

Lora模型训练的参数-学习笔记

任何一个lora都会有三重属性&#xff0c;易调用性、泛化性和还原性&#xff0c;任何一个lora只能完美满足其中的两项&#xff1b; 易调用性&#xff1a;在已调用lora后&#xff0c;还需要多少提示词才能让该lora完全生效&#xff1b; 泛化性&#xff1a;能不能还原lora训练素…

杜甫很 忙

我 我希望大家别再乱搞了

Windows终端远程登陆Linux服务器(SSH+VScode)

W i n d o w s 终端远程登陆 L i n u x 服务器&#xff08; S S H V S c o d e &#xff09; \huge{Windows终端远程登陆Linux服务器&#xff08;SSHVScode&#xff09;} Windows终端远程登陆Linux服务器&#xff08;SSHVScode&#xff09; 文章目录 写在前面通过SSH远程连接L…

golang程序性能提升改进篇之文件的读写---第一篇

背景&#xff1a;接手的项目是golang开发的&#xff08;本人初次接触golang&#xff09;经常出现oom。这个程序是计算和io密集型&#xff0c;调用流量属于明显有波峰波谷&#xff0c;但是因为各种原因&#xff0c;当前无法快速通过serverless或者动态在高峰时段调整资源&#x…

「邀您参会」首个中国可观测日即将盛大开幕

在云计算领域不断探索与创新的背景下&#xff0c;亚马逊云科技与观测云今日宣布&#xff0c;将联合举办中国可观测日&#xff08;Observability Day&#xff09;活动&#xff0c;旨在深化双方合作&#xff0c;共同推动中国可观测性的发展。 中国站首站&#xff0c;选址上海&am…

软件测试——非功能测试

工作职责&#xff1a; 1.负责产品系统测试&#xff0c;包括功能测试、性能测试、稳定性测试、用户场景测试、可靠性测试等。 2.负责测试相关文档的编写&#xff0c;包括测试计划、测试用例、测试报告等。 3.负责自动化测试框架、用例的维护。 岗位要求&#xff1a; 1.熟练…

【启明智显方案分享】工业级HMI芯片MODEL3\MODEL4应用于电梯系统多媒体

一、方案概述 本方案采用工业级HMI芯片MODEL3或MODEL4作为核心处理器&#xff0c;结合7寸以上高清显示屏&#xff0c;为电梯系统提供多媒体解决方案。该方案不仅能够显示日期、时间、楼层信息等基础信息&#xff0c;还能播放广告、通知、视频等多媒体内容&#xff0c;增强电梯…

HTTPS请求头缺少HttpOnly和Secure属性解决方案

问题描述&#xff1a; 建立Filter拦截器类 package com.ruoyi.framework.security.filter;import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.…

友讯随身WiFi和格行随身WiFi真实测评!彩屏款随身WiFi谁更胜一筹?随身WiFi哪个最好用?随身WiFi哪个口碑最好?哪个性价比更高?

在众多随身WiFi品牌中&#xff0c;友讯&#xff08;D-Link&#xff09;与格行&#xff08;Gexing&#xff09;都是彩屏款随身WiFi因其相似的设计和各自独特的品牌背景&#xff0c;常常让消费者难以抉择。今天&#xff0c;我们就来一场真实测评&#xff0c;深入剖析这两款彩屏随…

求解答word图标变白

把WPS卸载了之后就变成白色了&#xff0c;然后在注册表中把word的地址改成office word的地址之后图标变成这样了&#xff0c;怎么办

Talk|清华大学袁天远:PreSight - 利用NeRF先验帮助自动驾驶场景在线感知

本期为TechBeat人工智能社区第605期线上Talk。 北京时间7月3日(周三)20:00&#xff0c;清华大学博士生—袁天远的Talk已经准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “PreSight - 利用NeRF先验帮助自动驾驶场景在线感知”&#xff0c;他向大家介绍了新…

【XSS】

文章目录 0x01 简介0x02 XSS Payload用法XSS攻击平台及调试JavaScript 0x03 XSS构造技巧XSS漏洞防御策略 跨站脚本攻击&#xff0c;Cross Site Script。&#xff08;重点在于脚本script&#xff09; 分类 反射型、存储型DOM型 漏洞原理&#xff1a;通过插入script篡改“HTML”…

AI 生成时代,现有编程语言还够用吗?

7月14日下午&#xff0c;知乎「AI 先行者沙龙」在深圳南山举行&#xff0c;本次沙龙以 “探航” 为主题&#xff0c;粤港澳大湾区数字经济研究院基础软件中心首席科学家、MoonBit 平台负责人张宏波受邀发表主旨演讲——《AI 生成时代&#xff0c;现有编程语言还够用吗&#xff…

PyTorch论文

2019-12 PyTorch: An Imperative Style, High-Performance Deep Learning Library 设计迎合4大趋势&#xff1a; 1. array-based (Tensor) 2. GPU加速 3. 自动求导 (Auto Differentiation) 4. 拥抱Python生态 4大设计原则&#xff1a; 1. 使用算法和数据开发者熟悉的Python做编…

华为USG6000V防火墙NAT智能选举

目录 一、拓扑图 二、要求 三、配置思路及方法 要求1&#xff1a;通过多对多的NAT实现上网功能 思路&#xff1a;基础IP地址配置按照之前的进行配置&#xff0c;接着在策略里配置多对多的NAT 要求2&#xff1a;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的…

stm32入门-----GPIO口输入的学习与使用

目录 前言 一、硬件介绍 1.按键 2.传感器模块 二、按键控制LED灯亮灭 1.电路连线图 2. 工程文件添加 3.GPIO口读取函数介绍 &#xff08;1&#xff09;输入数据的读取 &#xff08;2&#xff09;输出数据的读取 4.代码编写 &#xff08;1&#xff09;按键模块 …