OSG天空图代码

news2024/11/24 18:41:48

osgEarth

    // 创建天空选项
    osgEarth::Util::SkyOptions skyOptions;

    // 设置天空的坐标系统(可选)
    skyOptions.coordinateSystem() = osgEarth::Util::SkyOptions::COORDSYS_ECEF;

    // 设置一天中的小时数(可选)
    skyOptions.hours() = 12.0f; // 中午

    // 设置环境光级别(可选)
    skyOptions.ambient() = 0.5f; // 50%的环境光

    // 使用选项创建天空节点
    osg::ref_ptr<osgEarth::Util::SkyNode> skyNode = osgEarth::Util::SkyNode::create(skyOptions);

    // 设置天空节点的日期和时间
    osgEarth::DateTime dateTime(2024, 6, 5, 12); // 2024年6月5日中午
    skyNode->setDateTime(dateTime);
    osgEarth::Util::Ephemeris* ephemeris = new osgEarth::Util::Ephemeris;
    skyNode->setEphemeris(ephemeris);

    // 设置天空节点的参考点(对于投影地图)
    osgEarth::GeoPoint refPoint(getMapNode()->getMapSRS(), 0, 0, 0); // 地球中心
    skyNode->setReferencePoint(refPoint);
    skyNode->setLighting(true);
    _root->addChild(skyNode);
    skyNode->attach(_viewer,0);
    //运行了 osgEarth 中的着色器生成器,通过对 _root 中的节点进行分析和处理,生成对应的着色器代码。着色器生成器根据节点的材质、光照、纹理等属性,自动生成相应的顶点着色器和片段着色器代码,以实现渲染效果。
    osgEarth::Registry::shaderGenerator().run(_root.get());
//    对根节点 _root 及其子节点中的所有状态集合进行优化。这个优化过程尝试将相同的状态合并为一个,以减少OpenGL状态切换次数,从而提高渲染性能。
    StateSetCache *cache = osgEarth::Registry::stateSetCache();
    cache->optimize(_root.get());

    // 添加场景数据
    _viewer->setSceneData(_root.get());```






```cpp
class MoveEarthySkyWithEyePointTransform : public osg::Transform {
public:
    virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const override {
        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
        if (cv) {
            osg::Vec3 eyePointLocal = cv->getEyeLocal();
            matrix.preMult(osg::Matrix::translate(eyePointLocal));
        }
        return true;
    }

    virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const override {
        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
        if (cv) {
            osg::Vec3 eyePointLocal = cv->getEyeLocal();
            matrix.postMult(osg::Matrix::translate(-eyePointLocal));
        }
        return true;
    }
};

// Update texture matrix for cubemaps
struct TexMatCallback : public osg::NodeCallback {
public:
    TexMatCallback(osg::TexMat& tm) : _texMat(tm) {}

    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) override {
        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
        if (cv) {
            const osg::Matrix& MV = *(cv->getModelViewMatrix());
            const osg::Matrix R = osg::Matrix::rotate(osg::DegreesToRadians(112.0f), 0.0f, 0.0f, 1.0f) *
                                  osg::Matrix::rotate(osg::DegreesToRadians(90.0f), 1.0f, 0.0f, 0.0f);

            osg::Quat q = MV.getRotate();
            const osg::Matrix C = osg::Matrix::rotate(q.inverse());

            _texMat.setMatrix(C * R);
        }
        traverse(node, nv);
    }

    osg::TexMat& _texMat;
};

class CSkyLight {
public:
    osg::TextureCubeMap* readCubeMap(const std::string& path) {
        osg::TextureCubeMap* cubemap = new osg::TextureCubeMap;

        osg::Image* images[6];
//        std::string faces[6] = {"front3", "back3", "right3", "left3", "bottom3", "top3"};
//        std::string faces[6] = {"front3", "back3", "top3", "bottom3", "left3", "right3"};
        std::string faces[6] = {"front3", "back3", "bottom3", "top3", "left3", "right3"};
        osg::TextureCubeMap::Face faceEnums[6] = {
                osg::TextureCubeMap::POSITIVE_X,
                osg::TextureCubeMap::NEGATIVE_X,
                osg::TextureCubeMap::POSITIVE_Y,
                osg::TextureCubeMap::NEGATIVE_Y,
                osg::TextureCubeMap::POSITIVE_Z,
                osg::TextureCubeMap::NEGATIVE_Z
        };

        for (int i = 0; i < 6; ++i) {
            images[i] = osgDB::readImageFile(path + faces[i] + ".png");
            if (!images[i]) return nullptr;
            cubemap->setImage(faceEnums[i], images[i]);
        }

        cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
        cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
        cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);
        cubemap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
        cubemap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);

        return cubemap;
    }

    osg::Node* createSkyBox(const std::string& path) {
        osg::StateSet* stateset = new osg::StateSet();

        osg::TexEnv* te = new osg::TexEnv;
        te->setMode(osg::TexEnv::REPLACE);
        stateset->setTextureAttributeAndModes(0, te, osg::StateAttribute::ON);

        osg::TexGen* tg = new osg::TexGen;
        tg->setMode(osg::TexGen::NORMAL_MAP);
        stateset->setTextureAttributeAndModes(0, tg, osg::StateAttribute::ON);

        osg::TexMat* tm = new osg::TexMat;
        stateset->setTextureAttribute(0, tm);

        osg::TextureCubeMap* skymap = readCubeMap(path);
        stateset->setTextureAttributeAndModes(0, skymap, osg::StateAttribute::ON);

        stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
        stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);

        osg::Depth* depth = new osg::Depth;
        depth->setFunction(osg::Depth::ALWAYS);
        depth->setRange(1.0, 1.0);
        stateset->setAttributeAndModes(depth, osg::StateAttribute::ON);

        stateset->setRenderBinDetails(-1, "RenderBin");

        osg::Drawable* drawable = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f), 1));

        osg::Geode* geode = new osg::Geode;
        geode->setCullingActive(false);
        geode->setStateSet(stateset);
        geode->addDrawable(drawable);

        osg::Transform* transform = new MoveEarthySkyWithEyePointTransform;
        transform->setCullingActive(false);
        transform->addChild(geode);

        osg::ClearNode* clearNode = new osg::ClearNode;
        clearNode->setCullCallback(new TexMatCallback(*tm));
        clearNode->addChild(transform);

        return clearNode;
    }
};
int main() {

    osgViewer::Viewer viewer;
    viewer.setUpViewInWindow(100, 100, 800, 600);


    osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("./osgb/Tractor.OSGB");
    if (!model)
    {
        std::cout << "无法加载模型" << std::endl;
        return 1;
    }
    osg::ref_ptr<osg::Group> geode = new osg::Group;

    geode->addChild(model);

    CSkyLight c;
    geode->addChild(c.createSkyBox("./osgb/"));
    viewer.setSceneData(geode);

在这里插入图片描述

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

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

相关文章

Vulnhub-DC-3

joomla3.7.0的提权 信息收集 靶机IP:192.168.20.136 kaliIP:192.168.20.128 网络有问题的可以看下搭建Vulnhub靶机网络问题(获取不到IP) 首先nmap扫端口和版本&#xff0c;dirsearch跑下目录&#xff0c;wappalyzer也可以用下 发现服务器用的ubuntu&#xff0c;JoomlaCMS…

实验9 浮动静态路由配置

--名称-- 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 浮动静态路由也是一种特殊的静态路由&#xff0c;主要考虑链路冗余。浮动静态路由通过配置一条比主路由优先级低的静态路由&#xff0c;用于保证在主路由失效的情况下&#xff0c;…

RabbitMQ小结

MQ分类 Acitvemq kafka 优点&#xff1a;性能好&#xff0c;吞吐量高百万级&#xff0c;分布式&#xff0c;消息有序 缺点&#xff1a;单机超过64分区&#xff0c;cpu会飙高&#xff0c;消费失败不支持重试 &#xff0c; Rocket 阿里的mq产品 优点&#xff1a;单机吞吐量也…

PHP质量工具系列之php-depend

php-depend是一个开源的静态代码分析工具&#xff0c;它的主要功能包括&#xff1a; 代码质量分析 复杂度度量&#xff1a;计算类、方法和函数的Cyclomatic Complexity&#xff08;循环复杂度&#xff09;&#xff0c;帮助识别潜在的复杂代码段。 耦合度度量&#xff1a;分析类…

pytorch笔记:自动混合精度(AMP)

1 理论部分 1.1 FP16 VS FP32 FP32具有八个指数位和23个小数位&#xff0c;而FP16具有五个指数位和十个小数位Tensor内核支持混合精度数学&#xff0c;即输入为半精度&#xff08;FP16&#xff09;&#xff0c;输出为全精度&#xff08;FP32&#xff09; 1.1.1 使用FP16的优缺…

【AR开发-开源框架】使用Sceneform-EQR快速开发AR应用,当前接入了AREngine、ORB-SLAM,可快速地适配不同的安卓设备

Sceneform-EQR Sceneform 概览 Sceneform是一个3D框架&#xff0c;具有基于物理的渲染器&#xff0c;针对移动设备进行了优化&#xff0c;使您可以轻松构建增强现实应用程序&#xff0c;而无需OpenGL。 借助 Sceneform&#xff0c;您可以轻松地在 AR 应用和非 AR 应用中渲染…

【C语言】10.C语言指针(4)

文章目录 1.回调函数是什么&#xff1f;2.qsort 使⽤举例2.1 使⽤qsort函数排序整型数据2.2 使⽤qsort排序结构数据 3.qsort函数的模拟实现 1.回调函数是什么&#xff1f; 回调函数就是一个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数…

如何为律师制作专业的商务名片?含电子名片二维码

律师关注细节&#xff0c;律师名片也不例外。它们不仅仅是身份的象征&#xff0c;更是律师专业形象的代表&#xff0c;传递专业知识和信任。今天就来和我们一起来看看制作律师商务名片的注意事项&#xff0c;以及如何制作商务名片上的电子名片二维码&#xff1f; 一、名片的主…

kafka学习笔记 @by_TWJ

目录 1. 消息重复消费怎么解决1.1. 确保相同的消息不会被重复发送(消费幂等性)1.2. 消息去重1.3. 消息重试机制1.4. kafka怎么保证消息的顺序性1.4.1. 利用分区的特征&#xff1a;1.4.2. 解决办法&#xff1a;1.4.3. 分区分配策略1.4.3.1. RangeAssignor &#xff08;每组(Topi…

Windows下安装和配置Redis

目录 1、下载redis压缩包 2、解压redis文件 3、启动redis临时服务 4、打开Redis客户端进行连接 5、使用一些基础操作来测试 5.1、输入ping命令来检测redis服务器与redis客户端的连通性 5.2、使用set和get命令测试redis数据库进行数据存储和获取 5.3、在命令中通过shut…

vs中C++项目中没有QT(.pro)文件怎么生成翻译ts文件

目录 使用 CMake 生成翻译文件 1.创建 CMakeLists.txt 文件 2.添加翻译生成规则 3.运行 CMake 4.生成翻译文件 使用命令行工具生成翻译文件 1.运行 lupdate 2.编辑 .ts 文件 3.运行 lrelease 网络上说的情况都是一个qt程序在VS中打开&#xff0c;拥有.pro文件的情况&a…

解决远程服务器连接报错

最近使用服务器进行数据库连接和使用的时候出现了一个报错&#xff1a; Error response from daemon: Conflict. The container name “/mysql” is already in use by container “1bd3733123219372ea7c9377913da661bb621156d518b0306df93cdcceabb8c4”. You have to remove …

什么是WEB应用防火墙,云服务器有带吗

伴随着Web软件、SaaS应用及API交互的使用普及&#xff0c;网络安全威胁也随之而来。网络攻击者一直不断改进他们的方法&#xff0c;使用自动爬虫程序、僵尸网络和漏洞扫描器来发动多媒介攻击&#xff0c;试图瘫痪应用。而WAF防火墙可以帮助保护Web应用程序免受这些攻击&#xf…

10.爬虫---XPath插件安装并解析爬取数据

10.XPath插件安装并解析爬取数据 1.XPath简介2.XPath helper安装3.XPath 常用规则4.实例引入4.1 //匹配所有节点4.2 / 或 // 匹配子节点或子孙节点4.3 ..或 parent::匹配父节点4.4 匹配属性4.5 text()文本获取4.6 属性获取4.7 属性多值匹配 1.XPath简介 XPath是一门在XML文档中…

让你工作效率飞起的五款软件

&#x1f31f; No.1&#xff1a;亿可达 作为一款自动化工具&#xff0c;亿可达被誉为国内版的免费Zaiper。它允许用户无需编程知识即可将不同软件连接起来&#xff0c;构建自动化的工作流程。其界面设计清新且直观&#xff0c;描述语言简洁易懂&#xff0c;使得用户可以轻松上…

一个可以自动生成随机区组试验的excel VBA小程序

在作物品种区域试验时&#xff0c;通常会采用随机区组试验设计&#xff0c;特制作了一个可以自动生成随机区组试验的小程序。excel参数界面如下&#xff1a; 参数含义如下&#xff1a; 1、生成新表的名称&#xff1a;程序将新建表格&#xff0c;用于生成随机区组试验。若此处为…

探索通信技术的未来:2024中国通信技术和智能装备产业博览会

探索通信技术的未来&#xff1a;2024通信技术产业专场 随着信息技术的飞速发展&#xff0c;通信技术已成为现代社会不可或缺的基础设施。2024年10月11日至13日&#xff0c;青岛将迎来一场通信技术的盛会——2024中国军民两用智能装备与通信技术产业博览会。本次博览会不仅将展…

调试线上资源文件失效问题

之前的老项目&#xff0c;突然报红&#xff0c;为了定位问题&#xff0c;使用注入和文件替换的方式进行问题定位&#xff01; 1.使用注入 但是刷新后就没有了&#xff0c;不是特别好用&#xff01; const jqScript document.createElement(script); jqScript.src https://…

视频推广短信:新时代的营销利器(视频短信XML接口示例)

随着移动互联网的普及&#xff0c;短信已经不再是简单的文字信息传递工具&#xff0c;而是逐渐演变为一种有效的推广手段。特别是当视频与短信结合时&#xff0c;它所带来的营销效率更是令人瞩目。 一、视频推广短信的特点 1.直观性&#xff1a;与传统的文字短信相比&#xf…

MySQL存储引擎的区别和比较

MyISAM存储引擎 MyISAM基于ISAM存储引擎&#xff0c;并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度&#xff0c;但不支持事务。 MyISAM主要特性有&#xff1a; 1、大文件&#xff08;达到63位文件长度&#x…