OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式

若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/97614261

目录

前言

目标效果

纹理混合模式

原图

设置纹理混合模式方法(多重纹理映射,颜色也算一层)

纹理混合模式

枚举效果

代码

HUB绘制两个图形:纯色和纹理

入坑

入坑一:纹理第一个图形A有颜色后,B绑定纹理有A最后一个点的颜色

工程模板:对应版本号1.18.0


 

OSG三维开发专栏

OSG开发笔记(一):OSG介绍、编译

OSG开发笔记(二):OSG帮助文档编译

OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序

OSG开发笔记(四):OSG不使用osgQt重写类嵌入Qt应用程序》:

OSG开发笔记(五):OSG场景理解与基础类概述

OSG开发笔记(六):OSG内存管理

OSG开发笔记(七):OSG复现OpenGL入门示例和OSG坐标系

OSG开发笔记(八):OSG模型文件存储与读取

OSG开发笔记(九):OSG模型的基本操作之添加/删除、显示/隐藏、开关节点开/》:

OSG开发笔记(十):OSG模型的变换之平移、旋转和缩放

OSG开发笔记(十一):OSG渲染状态与2D纹理映射

OSG开发笔记(十二):OSG基本几何图形、内置几何类型

OSG开发笔记(十三):OSG三维纹理映射(体渲染)

OSG开发笔记(十四):OSG交互

OSG开发笔记(十五):OSG光照

OSG开发笔记(十六):OSG视口、相机和视点

OSG开发笔记(十七):OSG中的相机移动

OSG开发笔记(十八):OSG鼠标拾取pick、拽托球体以及多光源

OSG开发笔记(十九):OSG文字显示

OSG开发笔记(二十):OSG使用HUD显示文字

OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式

OSG开发笔记(二十二):OSG场景背景

OSG开发笔记(二十三):Qt使用QOpenGLWidget渲染OSG地球仪

OSG开发笔记(二十四):OSG漫游之平移、转向和低抬头

OSG开发笔记(二十五):OSG漫游之CS移动、碰撞检测与跳跃

OSG开发笔记(二十六):OSG漫游之上下楼梯

《OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画

《OSG开发笔记(二十八):OSG模型固定路径动画

  持续补充中…

 

        OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式

前言

       前面显示文字抬头显示(HUD),现在将图片和图片纹理也添加进HUD。

 

目标效果

       OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式_第1张图片

       本章节完,基本扫清达到目标效果的技术障碍。

 

纹理混合模式

原图

       纹理混合模式,2个图形,第一个是纯色,第二个是贴白色纹理。

       OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式_第2张图片

设置纹理混合模式方法(多重纹理映射,颜色也算一层)

// 设置纹理环境,模式为REPLACE
osg::ref_ptr pTexEnv=new osg::TexEnv;
pTexEnv->setMode(osg::TexEnv::Mode::REPLACE);
pTexEnv->setColor(osg::Vec4(0.0,0.0,0.0,0.0));
// Texture类关联到渲染状态StateSet
osg::ref_ptr pStateSet = pGeometry->getOrCreateStateSet();
// 将纹理关联给StateSet纹理单元0,同时将纹理环境混合模式关联到纹理单元0
pStateSet->setTextureAttributeAndModes(0, texture2D.get(), osg::StateAttribute::ON);
pStateSet->setTextureAttributeAndModes(0, pTexEnv.get(), osg::StateAttribute::ON);

纹理混合模式

enum Mode {
    DECAL     = GL_DECAL,
    MODULATE  = GL_MODULATE,
    BLEND     = GL_BLEND,
    REPLACE   = GL_REPLACE,
    ADD       = GL_ADD
};

枚举效果

        OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式_第3张图片

 

代码

HUB绘制两个图形:纯色和纹理

osg::ref_ptr OsgWidget::getHudTextAndShapeNode()
{
    osg::ref_ptr pGroup = new osg::Group();
    osg::ref_ptr pGeode = new osg::Geode();
    osg::ref_ptr pText = 0;

    // 步骤一:创建HUD摄像机
    osg::ref_ptr pCamera = new osg::Camera;
    // 步骤二:设置投影矩阵
    pCamera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1920, 0, 1080));
    // 步骤三:设置视图矩阵,同时确保不被场景中其他图形位置变换影响, 使用绝对帧引用
    pCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    pCamera->setViewMatrix(osg::Matrix::identity());
    // 步骤四:清除深度缓存
    pCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
    // 步骤五:设置POST渲染顺序(最后渲染)
    pCamera->setRenderOrder(osg::Camera::POST_RENDER);
    // 步骤六:设置为不接收事件,始终得不到焦点
    pCamera->setAllowEventFocus(false);
    // 步骤七:添加文字
    {
        pText = new osgText::Text();
        pText->setFont(osgText::readFontFile("fonts/simsun.ttc"));
        QString text = QString("苔原带");
        pText->setText(text.toStdString(), osgText::String::ENCODING_UTF8);
        pText->setPosition(osg::Vec3f(0, 0, 0));
        pText->setCharacterSize(10);
        pText->setColor(osg::Vec4f(1.0, 1.0, 1.0, 1.0));
        pText->setDrawMode(osgText::Text::TEXT);
        pText->setAxisAlignment(osgText::Text::XY_PLANE);
        pText->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
        pText->setFontResolution(32, 32);
        pText->setAlignment(osgText::Text::LEFT_TOP);
        pText->setAlignment(osgText::Text::LEFT_CENTER);
        pText->setAlignment(osgText::Text::LEFT_BOTTOM);
        pText->setLayout(osgText::Text::LEFT_TO_RIGHT);
        pText->setBackdropType(osgText::Text::NONE);
        pText->setColorGradientMode(osgText::Text::SOLID);
        pGeode = new osg::Geode();
        osg::ref_ptr pStateSet = pGeode->getOrCreateStateSet();
        pStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
        pStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
        pGeode->addDrawable(pText.get());
    }
    pCamera->addChild(pGeode);

    // 步骤八:添加图形-纯色
    {
        // 绘制四边形
        // 创建一个用户保存几何信息的对象
        osg::ref_ptr pGeometry = new osg::Geometry;
        // 创建四个顶点的数组
        osg::ref_ptr pVec3Array = new osg::Vec3Array;
        // 添加四个顶点
        pGeometry->setVertexArray(pVec3Array.get());
        // 注意:HUD中的XY是正常屏幕坐标,而OSG中Y屏幕向里
        pVec3Array->push_back(osg::Vec3( 0.0, 0.0, 0.0));
        pVec3Array->push_back(osg::Vec3( 300.0, 0.0, 0.0));
        pVec3Array->push_back(osg::Vec3( 300.0, 100.0, 0.0));
        pVec3Array->push_back(osg::Vec3( 0.0, 100.0, 0.0));
        // 注意:此处若不绑定画笔,则表示使用之前绑定的画笔
        // 创建四种颜色的数据
        osg::ref_ptr pVec4Array = new osg::Vec4Array;
        // 添加四种颜色
        pGeometry->setColorArray(pVec4Array.get());
        // 绑定颜色
        pGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
        pVec4Array->push_back(osg::Vec4(141/255.0, 179/255.0, 222/255.0, 1.0));
        pVec4Array->push_back(osg::Vec4(141/255.0, 179/255.0, 222/255.0, 1.0));
        pVec4Array->push_back(osg::Vec4(141/255.0, 179/255.0, 222/255.0, 1.0));
        pVec4Array->push_back(osg::Vec4(141/255.0, 179/255.0, 222/255.0, 1.0));
        // Texture类关联到渲染状态StateSet
        osg::ref_ptr pStateSet = pGeometry->getOrCreateStateSet();
        // 将纹理关联给StateSet纹理单元0
        pStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
        pStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
        // 为唯一的法线创建一个数组    法线: normal
        osg::ref_ptr pVec3ArrayNormal = new osg::Vec3Array;
        pGeometry->setNormalArray(pVec3ArrayNormal.get());
        pGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
        pVec3ArrayNormal->push_back(osg::Vec3(0.0, 1.0, 0.0));
        // 由保存的数据绘制四个顶点的多边形
        pGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
        // 向Geode类添加几何体(Drawable)
        pGeode = new osg::Geode;
        pGeode->addDrawable(pGeometry.get());
    }
    pCamera->addChild(pGeode);
    // 步骤九:添加图形-纹理
    {
        // 绘制四边形
        // 创建一个用户保存几何信息的对象
        osg::ref_ptr pGeometry = new osg::Geometry;
        // 创建四个顶点的数组
        osg::ref_ptr pVec3Array = new osg::Vec3Array;
        // 添加四个顶点
        pGeometry->setVertexArray(pVec3Array.get());
        // 注意:HUD中的XY是正常屏幕坐标,而OSG中Y屏幕向里
        pVec3Array->push_back(osg::Vec3( 300.0, 100.0, 0.0));
        pVec3Array->push_back(osg::Vec3( 600.0, 100.0, 0.0));
        pVec3Array->push_back(osg::Vec3( 600.0, 200.0, 0.0));
        pVec3Array->push_back(osg::Vec3( 300.0, 200.0, 0.0));
        // 创建四种颜色的数据
        osg::ref_ptr pVec4Array = new osg::Vec4Array;
        // 添加四种颜色
//        pGeometry->setColorArray(pVec4Array.get());
        // 绑定颜色:清空颜色,不然纹理会带有前面的颜色
        pGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
        pVec4Array->push_back(osg::Vec4(0, 0, 0, 0));
        pVec4Array->push_back(osg::Vec4(0, 0, 1, 1));
        pVec4Array->push_back(osg::Vec4(0, 0, 0, 1));
        pVec4Array->push_back(osg::Vec4(0, 1, 0, 0));
        // 读取纹理图片
        osg::ref_ptr pImage = 0;
        pImage = osgDB::readImageFile(QString("D:/qtProject/osgDemo/osgDemo/modules/osgWidget/image/iceSheet.jpg").toStdString());
        // 将图片关联到纹理
        if(!pImage->valid())
        {
            LOG_WARN(QString("Failed to open image file: %1").arg(QString::fromStdString(pImage->getFileName())));
            return 0;
        }
        osg::ref_ptr texture2D = new osg::Texture2D;
        texture2D->setImage(pImage.get());
        // 绑定纹理后,释放内部的ref_ptr,删除image图像
        texture2D->setUnRefImageDataAfterApply(true);
        // 创建纹理顶点
        osg::ref_ptr pVec2Array = new osg::Vec2Array;
        // 纹理单元号
        pVec2Array->push_back(osg::Vec2(0.0, 0.0));
        pVec2Array->push_back(osg::Vec2(1.0, 0.0));
        pVec2Array->push_back(osg::Vec2(1.0, 1.0));
        pVec2Array->push_back(osg::Vec2(0.0, 1.0));
        pGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
        // 设置纹理环境(决定是否和原先的颜色融合)
        // 设置纹理环境,模式为REPLACE
        osg::ref_ptr pTexEnv=new osg::TexEnv;
//        pTexEnv->setMode(osg::TexEnv::Mode::DECAL);
//        pTexEnv->setMode(osg::TexEnv::Mode::MODULATE);
//        pTexEnv->setMode(osg::TexEnv::Mode::BLEND);
//        pTexEnv->setMode(osg::TexEnv::Mode::REPLACE);
        pTexEnv->setMode(osg::TexEnv::Mode::ADD);
        pTexEnv->setColor(osg::Vec4(1.0,0.0,0.0,1.0));
        // Texture类关联到渲染状态StateSet
        osg::ref_ptr pStateSet = pGeometry->getOrCreateStateSet();
        // 将纹理关联给StateSet纹理单元0
        pStateSet->setTextureAttributeAndModes(0, texture2D.get(), osg::StateAttribute::ON);
        pStateSet->setTextureAttributeAndModes(0, pTexEnv.get(), osg::StateAttribute::ON);
        pGeometry->setTexCoordArray(0, pVec2Array.get());
        pStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
        pStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
        // 为唯一的法线创建一个数组    法线: normal
        osg::ref_ptr pVec3ArrayNormal = new osg::Vec3Array;
        pGeometry->setNormalArray(pVec3ArrayNormal.get());
        pGeometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
        pVec3ArrayNormal->push_back(osg::Vec3(0.0, 1.0, 0.0));
        // 由保存的数据绘制四个顶点的多边形
        pGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
        // 向Geode类添加几何体(Drawable)
        pGeode = new osg::Geode;
        pGeode->addDrawable(pGeometry.get());
    }
    pCamera->addChild(pGeode);

    pGroup->addChild(pCamera.get());
    return pGroup.get();
}

 

入坑

入坑一:纹理第一个图形A有颜色后,B绑定纹理有A最后一个点的颜色

解决方法:

       设置纹理混合模式为替代。

       OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式_第4张图片

 

工程模板:对应版本号1.18.0

        对应版本号1.18.0


原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/97614261

你可能感兴趣的:(OSG,HUD纹理,Qt开发专栏,OSG,OSG三维开发专栏)