OSG学习笔记-Geode(2-2)

3.2 Geode

    osg::Geode是OSG中的叶节点,它用于保存几何信息以便渲染。同时,作为叶节点,它就不会在包含子节点。在应用程序中,所有相关的几何体的渲染都必须与Geode节点相关联。在osg::Geode类中,也提供了addDrawable()函数来关联应用程序中需要渲染的几何体信息。

10.3.2.1 Billboard节点

    Billboard节点继承自Geode节点,因此它也是一个叶节点,不可再包含其他子节点,只能像叶节点那样通过添加Drawable来绘制信息。Billboard有以下三种模式:

enum Mode

{

    POINT_ROT_EYE,  // 绕视点

    POINT_ROT_WORLD,// 绕世界坐标

    AXIAL_ROT       // 绕轴

}

    Billboard(布告板)实现的原理是:将图形绘制在朝向视点的多边形表面上,根据视点的观察方向来确定多边形的方向,随着观察角度的变化,多边形的方向也随之变换。osg::Billboard布告板与Alpha纹理和动画融合技术相结合可以实现很多没有实心表面的现象,如后面会讲到的粒子系统中的烟火雾等。

    在OSG中使用几种常见的布告板技术,主要包括面向世界的布告板和轴向布告板。其中,面向世界的布告板包括面向视平面的布告板和面向视点的布告板技术。

3.2.2 Billboard示例

#include<osgViewer/Viewer>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Geometry>
#include<osg/Group>
#include<osg/Billboard>
#include<osg/Texture2D>
#include<osg/Image>
#include<osg/PositionAttitudeTransform>
#include<osg/MatrixTransform>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
#include<osgUtil/Optimizer>

osg::ref_ptr<osg::Node>createBillboardTree(osg::ref_ptr<osg::Image>image)
{
	// 创建四边形
	osg::ref_ptr<osg::Geometry>geometry = new osg::Geometry();
	
	// 设置顶点
	osg::ref_ptr<osg::Vec3Array>v = new osg::Vec3Array();
	v.push_back(osg::Vec3(-0.5f,0.0f,-0.5f));
    v.push_back(osg::Vec3(0.5f,0.0f,-0.5f));
    v.push_back(osg::Vec3(0.5f,0.0f,0.5f));
    v.push_back(osg::Vec3(-0.5f,0.0f,0.5f));
	geometry->setVertexArray(v.get());
	
    // 设置法线
	osg::ref_ptr<osg::Vec3Array>normal = new osg:: Vec3Array();
	normal->push_back(osg::Vec3(1.0f,1.0f,1.0f)^osg::Vec3(0.0f,0.0f,0.0f));
	geometry->setNormalArray(normal.get());
    geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);

    // 设置纹理坐标
    osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array();
    vt->push_back(osg::Vec2(0.0f,0.0f));
    vt->push_back(osg::Vec2(1.0f,0.0f));
    vt->push_back(osg::Vec2(1.0f,1.0f));
    vt->push_back(osg::Vec2(0.0f,1.0f));
    
    geometry->setTexCoordArray(vt.get());
    
    // 绘制四边形
    geometry->addPrimitiveSet(new osg::DrawArray(osg::PrimitiveSet::QUADS,0,4));
    
    if(image.get())
    {
        // 状态属性对象
        osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
        
        // 创建一个Texture2D属性对象
        osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();
        
        // 关联image
        texture->setImage(image.get());
        
        // 关联Texture2D纹理对象,第三个参数默认为ON
        stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::OM);
        // 启用混合
        stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
        
        // 关闭光照
        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
        
        geometry->setStateSet(stateset.get());
    }
    
    // 创建Billboard对象
    osg::ref_ptr<osg::Billboard> billboard1 = new osg::Billboard();
    
    // 设置旋转模式为绕视点
    billboard->setMode(osg::Billboard::POINT_ROT_EYE);
    // 添加Drawable,并设置其位置,默认位置为osg::Vec3(0.0f,0.0f,0.0f)
    billboard1->addDrawable(geometry.get(),osg::Vec3(5.0f,0.0f,0.0f));
    osg::ref_ptr<osg::Billboard> billboard2 = new osg::Billboard();
    // 设置旋转模式为绕轴转,因此还需要设置旋转轴
    billboard2->setMode(osg::Billboard::AXIAL_ROT);
    // 设置旋转轴
    billboard2->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
    billboard2->addDrawable(geometry.get(),osg::Vec3(10.0f,0.0f,0.0f));
    osg::ref_ptr<osg::Group>billboard = new osg::Group();
    billboard->addChild(billboard1.get());
    billboard->addChild(billboard2.get());
    return billboard.get();
}

int main()
{
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
    osg::ref_ptr<osg::Group> root = new osg::Group();
    // 读取图像
    osg::ref_ptr<osg::Image>image = osgDB::readImageFile("Images/tree0.rgba");
    // 缩放,达到合适的大小
    osg::ref_ptr<osg::PositionAttitudeTransform>pat = new osg::PositionAttitudeTransform();
    pat->setScale(osg::Vec3(5.0f,5.0f,5.0f));
    pat->addChild(createBillboardTree(image.get()));
    
    root->addChild(pat.get());
    
    // 获取cow的模型,以进行对比
    root->addChild(osgDB::readNodeFile("cow.osg"));
    
    // 优化场景数据
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());
    
    viewer->setSceneData(root.get());
    viewer->realize();
    viewer->run();
    
    return 0;    
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
osg55-osg.dll是一个动态链接库文件,通常是用于运行OpenSceneGraph开源图形引擎的一部分。当系统在运行时发现缺少这个文件时,通常会出现错误提示,例如"osg55-osg.dll缺少"或"找不到osg55-osg.dll"。这种情况下,我们可以尝试以下解决方法: 1. 重新安装应用程序:首先,如果报错是由特定应用程序引起的,可以尝试将其完全卸载,然后重新下载并重新安装该应用程序。这将确保所有文件都被正确地安装和部署。 2. 检查回收站:有时,我们可能意外地删除了这个dll文件,然后我们可以从回收站中恢复它。如果找到了该文件,请右键点击并选择还原。 3. 从备份中恢复:如果我们以前备份过整个系统或相关文件,我们可以尝试从备份中恢复缺少的osg55-osg.dll文件。 4. 从可信来源下载:如果我们确定这个文件确实缺失,并且没有其他可行的解决方法,我们可以尝试从可信的来源下载和安装缺失的osg55osg.dll文件。要确保下载的dll文件版本与我们的系统兼容。 5. 运行系统文件检查:Windows用户可以使用系统文件检查工具,命令为"sfc /scannow",此工具将扫描系统中的问题,并自动修复或还原缺失或损坏的文件。 总之,当发现"osg55-osg.dll缺少"的错误时,我们可以尝试重新安装相关应用程序,检查回收站或从备份中恢复缺失的文件。如果这些方法都不起作用,可以尝试下载并安装可信的版本兼容的osg55-osg.dll文件,或者运行系统文件检查来修复系统错误。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听风者868

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值