【小沐学GIS】基于OpenSceneGraph(OSG)绘制三维数字地球Earth

news2024/11/17 23:38:21
🍺三维数字地球系列相关文章如下🍺:
1【小沐学GIS】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)第一期
2【小沐学GIS】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut)第二期
3【小沐学GIS】基于OpenSceneGraph(OSG)绘制三维数字地球Earth

文章目录

  • 1、简介
  • 2、下载和编译
    • 2.1 下载OSG源码
    • 2.2 下载OSG编译后的二进制文件
    • 2.3 下载OSG依赖的第三方库文件
    • 2.4 下载OSG测试数据和文件
  • 3、代码测试
    • 3.1 绘制最简单的形状
    • 3.2 绘制一个彩色正方形
    • 3.3 绘制多个模型文件
    • 3.4 绘制osg模型文件
    • 3.5 绘制osgb倾斜摄影模型文件
    • 3.6 绘制简化模型
  • 7、地球效果
    • 7.1 绘制单个地球
    • 7.2 绘制太阳和几大行星
  • 结语

1、简介

OpenSceneGraph是一个开源的三维引擎,被广泛的应用在可视化仿真、游戏、虚拟现实、科学计算、三维重建、地理信息、太空探索、石油矿产等领域。OSG采用标准C++和OpenGL编写而成,可运行在所有的Windows平台、OSX、GNU/Linux、IRIX、Solaris、HP-Ux、AIX、Android和FreeBSD 操作系统。
在这里插入图片描述

OSG是有版权的开源引擎,基于LGPL,OSG也生成了自己的许可(OSGPL)。
在这里插入图片描述
官网地址:
https://www.openscenegraph.com/

在这里插入图片描述
https://github.com/openscenegraph/OpenSceneGraph
在这里插入图片描述
(1)快速开发。OSG场景图形内封装了几乎全部的OpenGL底层接口,并随时支持最新的扩展特性。应用程序的开发者可以将中心放在三维程序开发的实质性内容以及与各种场景对象交互的方法上,而不再过多关注底层的代码。

(2)高品质。OSG经历了许多开发成员的反复检查、测试和改善,参与OSG核心代码开发并有贡献的人数很多。

(3)高性能。OSG的核心代码支持多种场景的裁剪技术、细节层次节点、渲染状态排序、顶点数组、显示列表、VBO、PBO、FBO、OpenGL着色器语言等;以及文字显示,粒子系统,阴影系统;雨、雪、火焰、烟雾等特效模拟,场景的东塔调度,线程渲染等各种机制。它们共同使OSG逐渐成为一个高性能的三维渲染引擎。

(4)高质量代码

(5)可扩展性。基于场景图形的扩展思想,OSG提供了强大的可扩展能力,包括各种类型的扩展节点(NodeKits,节点工具箱)、扩展渲染属性、扩展回调、扩展交互事件处理器等,为用户的程序开发提供了灵活的支持能力。

(6)可移植性。OSG提供了Windows、UNIX、Linux、Mac OS X、IRIX、Solaris、HP-UX、AIX和FreeBSD系统的移植能力,基于OSG开发的程序只要经过一次编写,就可以编译并运行在这些平台上,不需要关心更多的代码移植的细节。

(7)低费用。开源意味着免费,使用和发布基于OSG开发的程序和软件是不需要额外许可费用的。

(8)没有知识产权问题。对于开源且易于所有人阅读的代码而言,不存在侵犯软件专利的可能性。

2、下载和编译

2.1 下载OSG源码

https://www.openscenegraph.com/index.php/download-section/stable-releases
在这里插入图片描述
解压后文件夹如下:
在这里插入图片描述

2.2 下载OSG编译后的二进制文件

https://objexx.com/OpenSceneGraph.html
在这里插入图片描述
解压后文件夹如下:
在这里插入图片描述

2.3 下载OSG依赖的第三方库文件

http://www.openscenegraph.com/index.php/download-section/dependencies
在这里插入图片描述
解压后文件夹如下:
在这里插入图片描述

2.4 下载OSG测试数据和文件

http://www.openscenegraph.com/index.php/download-section/data
数据资源页面提供了指向 OpenSceneGraph 可读取的各种数据库和影像文件的链接。

在这里插入图片描述
解压后文件夹如下:
在这里插入图片描述
通过cmake自动生成vs2017的工程打开如下:
在这里插入图片描述

3、代码测试

3.1 绘制最简单的形状

#include<osg/ShapeDrawable>
#include<osg/Geode>
#include<osgViewer/Viewer>

int main(int argc, char *argv[]){
    (void) argc;
    (void) argv;
    
    osg::ref_ptr<osg::ShapeDrawable> shape1 = new osg::ShapeDrawable;
    shape1->setShape(new osg::Box(osg::Vec3(-3.0f, 0.0f, 0.0f), 2.0f, 2.0f, 1.0f));
    
    osg::ref_ptr<osg::ShapeDrawable> shape2 = new osg::ShapeDrawable;
    shape2->setShape(new osg::Cone(osg::Vec3(0.0f, 0.0f, 0.0f), 1.0f, 1.0f));
    shape2->setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
    
    osg::ref_ptr<osg::ShapeDrawable> shape3 = new osg::ShapeDrawable;
    shape3->setShape(new osg::Sphere(osg::Vec3(3.0f, 0.0f, 0.0f), 1.0f));
    shape3->setColor(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    
    osg::ref_ptr<osg::Geode> root = new osg::Geode;
    root->addDrawable(shape1.get());
    root->addDrawable(shape2.get());
    root->addDrawable(shape3.get());
    
    osgViewer::Viewer viewer;
    viewer.setSceneData(root.get());
    
    return viewer.run();
}

在这里插入图片描述

3.2 绘制一个彩色正方形


#include<osg/Geometry>
#include<osg/Geode>
#include<osgViewer/Viewer>

int main(int argc, char *argv[]) {

	osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
	vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
	vertices->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
	vertices->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
	vertices->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));

	osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
	normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));

	osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
	colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
	colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
	colors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

	osg::ref_ptr<osg::Geometry> quad = new osg::Geometry;
	quad->setVertexArray(vertices.get());
	quad->setNormalArray(normals.get());
	quad->setNormalBinding(osg::Geometry::BIND_OVERALL);
	quad->setColorArray(colors.get());
	quad->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
	quad->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));

	osg::ref_ptr<osg::Geode> root = new osg::Geode;
	root->addDrawable(quad.get());

	osgViewer::Viewer viewer;
	viewer.setSceneData(root.get());

	return viewer.run();
}

在这里插入图片描述

3.3 绘制多个模型文件

#include <osg/Node>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

int main(int argc, char* argv[])
{
	osgViewer::Viewer viewer;
	osg::ref_ptr<osg::Group> root = new osg::Group;
	osg::ref_ptr<osg::Group> group = new osg::Group;

	root->addChild(osgDB::readNodeFile("glider.osg"));
    group->addChild(osgDB::readNodeFile("axes.osgt"));
	root->addChild(group);

	viewer.setSceneData(root);
	viewer.realize();

	viewer.addEventHandler(new osgViewer::WindowSizeHandler);
	viewer.addEventHandler(new osgViewer::StatsHandler);

	return viewer.run();

}

在这里插入图片描述

3.4 绘制osg模型文件

#include "osgViewer/Viewer"
#include "osgDB/ReadFile"

int main(int argc, char** argv)
{
	osgViewer::Viewer viewer;
	viewer.setSceneData(osgDB::readNodeFile("cow.osg"));
	return viewer.run();
}

在这里插入图片描述

3.5 绘制osgb倾斜摄影模型文件

#include <iostream>
#include <Windows.h>

#include <osgViewer/Viewer>
#include <osgDB/ReadFile>

using namespace std;

int main()
{
	string osgPath = "Tile_+000_+000.osgb";
	osg::Node * node = osgDB::readNodeFile(osgPath);
	osgViewer::Viewer viewer;
	viewer.setSceneData(node);
	viewer.setUpViewInWindow(100, 100, 800, 600);
	return viewer.run();
}

在这里插入图片描述

3.6 绘制简化模型

#include <osg/Node> //节点类
#include <osg/Geode> //是个几何节点,可以说是一个几何Group节点,一般的可绘制几何体都是通过它来传向root进行渲染,是OSG几何绘制的最高管理节点
#include <osg/Group> //对节点起到组织作用,一般作为父节点或者根节点出现
#include <osg/PositionAttitudeTransform> //位置变换节点类,提供模型的位置变换、大小缩放、原点位置的设置、坐标系的变换
#include <osgDB/ReadFile>
#include <osgDB/WriteFile> 
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers> //事件监听
#include <osgGA/StateSetManipulator> //事件响应类,对渲染状态进行控制
#include <osgUtil/Optimizer> //优化器
#include <osgUtil/Simplifier> //简化几何体

/*
加载一个模型
深拷贝该模型到其他地方
对深拷贝的模型进行简化
将两个模型添加到叶节点
对场景进行优化
显示模型
按w键显示网格化模型,可以看出网格密度不同
按t键显示去表皮模型,可以看出模型相同
*/

//读取模型
osg::Node *readModel()
{
	osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
	return node.release();
}

//深拷贝并简化新模型
osg::Node *deepCopy(osg::Node *node)
{
	/*
	创建简化对象
	simplifier(sampleRatio, maxError)
	参数:样本比率、点的误差或边的长度
	样本比率<1 设置点的误差
	样本比率>1 设置边的长度限制
	比率越大,简化越少
	使用的是边塌陷算法
	*/
	float sampleRatio = 0.3f;
	float maxError = 4.0f;
	osgUtil::Simplifier simplifier(sampleRatio, maxError);

	//深拷贝
	osg::ref_ptr<osg::Node> deepnode = (osg::Node *)(node->clone(osg::CopyOp::DEEP_COPY_ALL));
	//创建一个位置变换节点,将之设置为新位置,将深拷贝的模型移到新位置
	osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();
	pat->setPosition(osg::Vec3(10.0f, 0.0f, 0.0f));
	pat->addChild(deepnode);

	pat->accept(simplifier);

	return pat.release();
}

int main()
{
	//创建一个叶节点对象并添加节点 
	osg::ref_ptr<osg::Group> root = new osg::Group();
	osg::ref_ptr<osg::Node> node1 = readModel();
	osg::ref_ptr<osg::Node> node2 = deepCopy(node1);
	root->addChild(node1);
	root->addChild(node2);

	//优化场景数据
	osgUtil::Optimizer optimizer;
	optimizer.optimize(root.get());

	//显示模型
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
	//切换网格模式,方便比较
	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));
	viewer->setSceneData(root.get());
	viewer->realize();

	return viewer->run();
}

在这里插入图片描述

7、地球效果

7.1 绘制单个地球

在这里插入图片描述

7.2 绘制太阳和几大行星

在这里插入图片描述
在这里插入图片描述

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

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

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

相关文章

CSS 一行三列布局,可换行(含grid网格布局、flex弹性布局/inline-block布局 + 伪类选择器)

效果 一、HTML <div class"num-wrap"><div class"num-item" v-for"num in 8" :key"num">{{ num }}</div></div> 二、CSS 1、grid网格布局&#xff08;推荐&#xff09; .num-wrap {// grid网格布局display…

Python轻松实现炫酷的手势检测

大家好&#xff0c;今天分享一个非常有意思且十分简单的python库——mediapipe库。该库集成了大量的深度学习模型&#xff0c;短短几行代码&#xff0c;就可以快速实现一个炫酷的实例&#xff0c;本文就以手势检测为例&#xff0c;展示一下这个强大的开源库。 mediapipe由Goog…

书生·浦语大模型实战营作业(四)

基础作业&#xff1a; 构建数据集&#xff0c;使用 XTuner 微调 InternLM-Chat-7B 模型, 让模型学习到它是你的智能小助手&#xff0c;效果如下图所示&#xff0c;本作业训练出来的模型的输出需要将不要葱姜蒜大佬替换成自己名字或昵称&#xff01; 数据集 回答结果 进阶作…

抽象类--java学习笔记

什麽是抽象类&#xff1f; 在java中有一个关键字叫&#xff1a;abstract&#xff0c;它就是抽象的意思&#xff0c;可以用它修饰类、成员方法abstract修饰类&#xff0c;这个类就是抽象类&#xff1b;修饰方法&#xff0c;这个方法就是抽象方法 认识抽象类 抽象类的注意事项…

2024.1.15每日一题

LeetCode 82.删除排序链表中的重复元素 II 82. 删除排序链表中的重复元素 II - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例…

Mac M1 Parallels CentOS7.9 Rancher + K8S + Gitlab + Jenkins +Harbor CICD

一、资源清单 机器名称IP地址角色k8srancher高可用部署: https://blog.csdn.net/qq_41594280/article/details/135312148rancher10.211.55.200管理K8S集群k8svip10.211.55.199K8S VIPmaster0110.211.55.201K8S集群主节点master0210.211.55.202K8S集群主节点master0310.211.55.…

AC修炼计划(AtCoder Beginner Contest 335)E-F

传送门&#xff1a; AtCoder Beginner Contest 335 (Sponsored by Mynavi) - AtCoder A&#xff0c;B&#xff0c;C&#xff0c;D还算比较基础&#xff0c;没有什么思路&#xff0c;纯暴力就可以过。 这里来总结一下E和F E - Non-Decreasing Colorful Path 最开始以为是树形…

JVM:从零到入门

JVM&#xff0c;就是Java虚拟机。 JVM是一个巨大的话题&#xff0c;我们本文主要简单介绍一些围绕JVM相关的基础知识。 目录 JVM内存区域划分 本地方法栈 虚拟机栈 堆 程序计数器 方法区/ 元数据区 类加载 1.加载 2.验证 3.准备 4.解析 5.初始化 双亲委派模型 …

任务7:安装MySQL数据库

任务描述 知识点&#xff1a; MySQL数据库安装与使用 重 点&#xff1a; 基于CentOS系统&#xff0c;安装MySQL数据库 内 容&#xff1a; 安装MySQL数据库修改root用户密码 任务指导 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c…

gcd得最大公约数,辗转相除法理解

欧几里得算法_百度百科 (baidu.com) —————— 百度百科证法一的一些便于理解的细节&#xff1a; 我们求 a 和 b 的最大公约数。 &#xff08;如果a是b的倍数&#xff0c;那么b就是最大公约数。&#xff09; a>b&#xff0c;a可以表示为 a kb r 设d为a和b的最大公约…

一二三应用开发平台文件处理设计与实现系列之5——MinIO技术预研

背景 上篇介绍了文件读写框架设计与实现&#xff0c;同时顺便说明了本地磁盘存储模式的实现模式。 今天来说下基于文件读写框架&#xff0c;如何集成对象存储组件minio&#xff0c;集成之前&#xff0c;需要对minio进行必要的了解&#xff0c;本篇是minio的技术预研。 minio简…

pip查看某个包存在的历史版本

简介&#xff1a;当我们想查看某个包有哪些可安装版本&#xff0c;但是又不想去官网查询&#xff0c;如何用pip命令查询出全部历史版本&#xff1f; 历史版本&#xff1a; Python&#xff1a;pip升级超时解决方案 Python&#xff1a;指定的Python版本pip Python&#xff1a…

把模板作为元函数参数传递。

C模板元编程是一种典型的函数式编程&#xff0c;函数在整个编程体系中处于核心的地位。 这里的函数与一般C程序中定义的函数有所区别&#xff0c;其更接近数学意义上的函 数——是无副作用的映射或变换&#xff1a;在输入相同的前提下&#xff0c;多次调用同一个函数&…

mac vscode latex实用

网上有教程怎么在vscode里安装macTex以及插件&#xff0c;然后就可以在latex里写代码了&#xff0c;这里需要修改的是对应的json文件&#xff0c;输入command P,可以看到最近打开的json设置文件&#xff0c;结果如下 然后设置这个json文件&#xff0c;我的json文件设置如下 …

个人网站制作 Part 5 优化网站性能(图片压缩、代码优化) | Web开发项目

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 优化网站性能&#x1f528;图片优化&#x1f527;步骤 1: 使用压缩工具 &#x1f528;代码优化&#x1f527;步骤 2: 压缩CSS和JavaScript&#x1f527;步骤 3: 合并文件…

js(JavaScript)数据结构之堆(Heap)

什么是数据结构&#xff1f; 下面是维基百科的解释&#xff1a; 数据结构是计算机存储、组织数据的方式。数据结构意味着接口或封装&#xff1a;一个数据结构可被视为两个函数之间的接口&#xff0c;或者是由数据类型联合组成的存储内容的访问方法封装。 我们每天的编码中都会…

聊聊websocket那些事

前端必备工具推荐网站(免费图床、API和ChatAI等实用工具): http://luckycola.com.cn/ 一、什么是websocket? WebSocket 是一种在单个 TCP 连接上进行全双工通信的网络协议。 它是 HTML5 中的一种新特性&#xff0c;能够实现 Web 应用程序和服务器之间的实时通信&#xff0c;…

事件分析应急响应-Server2229(环境+解析)

任务环境说明: 服务器场景:Server2229(开放链接)用户名:root,密码:

1116: 删除元素(数组)

题目描述 输入一个递增有序的整型数组A有n个元素&#xff0c;删除下标为i的元素&#xff0c;使其仍保持连续有序。注意&#xff0c;有效下标从0开始。 定义如下两个函数分别实现删除元素操作和数组输出操作。 void del(int a[], int n, int i); /*删除数组a中下标为i的元素*…

鸿蒙Harmony-相对布局(RelativeContainer)详解

成年人的世界&#xff0c;从来没有容易二字&#xff0c;想要什么&#xff0c;就得凭自己的努力去拿&#xff0c;遇到事情就得自己生生的硬抗&#xff0c;希望你即使再辛苦&#xff0c;但还是会选择这滚烫的人生&#xff0c;加油陌生的朋友们 目录 一&#xff0c;定义 二&#x…