OSG天空图代码

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);

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值