baidu_27304211 2023-03-21 09:54 采纳率: 26.7%
浏览 42
已结题

请教如何用OSG实现长方体6个面贴不同的图

利用C++和OSG库,已经写好了关于长方体6个面贴图的程序,但是很奇怪的是,长方体坐标中心选择(0,0,0)则贴图正确(6个不同的卡通图案);长方体坐标中心选择(691940.61, 4871848.22, 236.13),该坐标值是我三维模型中某个大楼的坐标,贴图结果错误(6个面的贴图为纯色或者花条,无图案)。

请教问题出在何处

代码块如下:(转载自https://blog.csdn.net/u013719339/article/details/80974258?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167936345416800186577413%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167936345416800186577413&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-5-80974258-null-null.142^v74^insert_down4,201^v4^add_ask,239^v2^insert_chatgpt&utm_term=TextureCubeMap&spm=1018.2226.3001.4187%EF%BC%89%EF%BC%8C%E5%81%9A%E4%BA%86%E4%B8%80%E7%82%B9%E4%BF%AE%E6%94%B9

// stdafx.h

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

#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Quat>
#include <osg/Matrix>

#include <osg/ShapeDrawable> //预定义几何体类,派生自osg::Drawable类。OSG中使用该类来将OSG内嵌的预定义几何体与osg::Drawable关联以渲染这些几何体
#include <osg/Transform> //一个组节点,所有子节点都通过4x4矩阵进行变换,通常用于在场景中定位对象,生成轨迹球功能或用于动画
#include <osg/NodeCallback > //节点更新回调
#include <osg/Depth> //封装OpenGL glDepthFunc / Mask / Range函数
#include <osg/CullFace>

#include <osg/TexMat>
#include <osg/TexGen> //指定用于自动生成纹理坐标的函数,可以设置纹理的计算方式是以物体坐标空间还是相机坐标空间来进行不同的计算
#include <osg/TexEnv>
#include <osg/TextureCubeMap> //立方体纹理映射

#include <osgViewer/Viewer>

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

#include <osgUtil/Optimizer>

//.cpp

//读取立方图
osg::ref_ptr<osg::TextureCubeMap> readCubeMap()
{
    //读取纹理图片
    /*读取立方图纹理贴图时,纹理贴图要与立方体的各个面一一对应
        POSITIVE_X=0, //Left  X正方向
        NEGATIVE_X=1, //Right  X负方向
        POSITIVE_Y=2, //Front  Y正方向
        NEGATIVE_Y=3, //Back  Y负方向
        POSITIVE_Z=4, //Up  Z正方向
        NEGATIVE_Z=5 //Down  Z负方向
    */
    osg::ref_ptr<osg::Image> imagePosX = osgDB::readImageFile("F:/changchun/POSITIVE_X.bmp");
    osg::ref_ptr<osg::Image> imageNegX = osgDB::readImageFile("F:/changchun/NEGATIVE_X.bmp");
    osg::ref_ptr<osg::Image> imagePosY = osgDB::readImageFile("F:/changchun/POSITIVE_Y.bmp");
    osg::ref_ptr<osg::Image> imageNegY = osgDB::readImageFile("F:/changchun/NEGATIVE_Y.bmp");
    osg::ref_ptr<osg::Image> imagePosZ = osgDB::readImageFile("F:/changchun/POSITIVE_Z.bmp");
    osg::ref_ptr<osg::Image> imageNegZ = osgDB::readImageFile("F:/changchun/NEGATIVE_Z.bmp");

    //创建立方体纹理对象
    osg::ref_ptr<osg::TextureCubeMap> cubemap = new osg::TextureCubeMap();
    //判断纹理图片存在
    if (imagePosX.get() && imageNegX.get() && imagePosY.get() && imageNegY.get() && imagePosZ.get() && imageNegZ.get())
    {
        //设置立方图的6个面的贴图
        cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX.get());
        cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX.get());
        cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY.get());
        cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY.get());
        cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ.get());
        cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ.get());

        //设置纹理环绕模式
        /*设置纹理的坐标/包装模式
        enum WrapParmeter
        {
            WRAP_S, //x轴
            WRAP_T, //y轴
            WRAP_T //z轴
        };
        enum WrapMode
        {
            CLAMP, //截取
            CLAMP_TO_EDGE, //边框始终被忽略
            CLAMP_TO_BORDER, //它使用的纹理取自图像的边框,没有边框就使用常量边框的颜色
            REPEAT, //纹理的重复映射
            MIRROR //纹理镜像的重复映射
        };
        */
        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);

        //设置滤波:线性和mipmap
        /*设置纹理的过滤方法/过滤处理
        enum FilterParameter
        {
            MIN_FILTER, //缩小
            MAG_FILTER //放大
        };
        enum FilterMode
        {
            LINEAR, //以周围4个像素的平均值作为纹理
            LINEAR_MIPMAP_LINEAR, //使用线性均和计算两个纹理的值
            LINEAR_MIPMAP_NEAREST, //线性地改写临近的纹理单元值
            NEAREST, //取比较接近的像素作为纹理
            NEAREST_MIPMAP_LINEAR, //在两个纹理中选择最临近的纹理,并取它们之间的线性均和值
            NEAREST_MIPMAP_NEAREST //选择最临近的纹理单元值
        };
        */
        cubemap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
        cubemap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
    }

    return cubemap.release();
}

osg::ref_ptr<osg::Node> createSkyBox()
{
    //osg::ref_ptr<osg::Drawable> drawable = new osg::ShapeDrawable(new osg::Box(osg::Vec3(691940.61, 4871848.22, 236.13), 53.0, 45.0, 80.0));    //建筑物
    //osg::ref_ptr<osg::Drawable> drawable = new osg::ShapeDrawable(new osg::Box(osg::Vec3(691940.61, 4871848.22, 236.13), 10.0, 10.0, 10.0));    //建筑物
    osg::ref_ptr<osg::Drawable> drawable = new osg::ShapeDrawable(new osg::Box(osg::Vec3(0, 0, 0), 10.0, 10.0, 10.0));    //建筑物

    //设置立方图纹理
    osg::ref_ptr<osg::TextureCubeMap> skymap = readCubeMap();

    auto stateset = drawable->getOrCreateStateSet();
    stateset->setTextureAttributeAndModes(0, skymap, osg::StateAttribute::ON);

    osg::ref_ptr<osg::TexGen> tg = new osg::TexGen();
    tg->setMode(osg::TexGen::EYE_LINEAR);
    tg->setPlane(osg::TexGen::S, osg::Plane(-1,0,0,0));
    stateset->setTextureAttributeAndModes(0, tg, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);






    //把球体加入到叶节点
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    //geode->setCullingActive(false);
    //geode->setStateSet(stateset.get());
    geode->addDrawable(drawable.get());

    return geode.release();
}

int main()
{
    osg::ref_ptr<osg::Group> root = new osg::Group();
    //加入天空盒
    root->addChild(createSkyBox());

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

    osgDB::writeNodeFile(*root, "F:/changchun/test3.osgb");

    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    viewer->setSceneData(root.get());
    viewer->realize();

    return viewer->run();
}

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-03-21 21:43
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月13日
  • 创建了问题 3月21日

悬赏问题

  • ¥15 Arcgis河网分级报错
  • ¥200 java+appium2.1+idea
  • ¥20 请帮我做一个EXE的去重TXT文本
  • ¥15 工价表引用工艺路线,应如何制作py和xml文件
  • ¥15 根据历史数据,推荐问题类型
  • ¥15 需要仿真图,简单的二阶系统实例
  • ¥15 stm32光控照明仿真
  • ¥15 使用人工智能的方法生成满足一定统计参数要求的随机数序列
  • ¥15 SENT协议中相关问题咨询
  • ¥15 URL地址href跳转问题