查看: 3121|回复: 15

关于更改节点颜色

[复制链接]

该用户从未签到

发表于 2013-3-23 20:18:27 | 显示全部楼层 |阅读模式
请问如何更改场景中模型的颜色?  

该用户从未签到

发表于 2013-3-23 21:08:25 | 显示全部楼层
本帖最后由 anheihb03dlj 于 2013-3-23 21:09 编辑

方法很多的,很多代码都是从osg源码中抽取出来的(没事多看看源码很有收获滴)
  1. // 修改Geometry的颜色
  2. void setGeometryColor( osg::Geometry* geom, const osg::Vec4& newColor )
  3.     {
  4.         osg::Vec4Array* colorArrays = dynamic_cast< osg::Vec4Array*>( geom->getColorArray() );
  5.         if ( colorArrays )
  6.         {
  7.             for ( unsigned int i = 0; i < colorArrays->size(); i++ )
  8.             {
  9.                 osg::Vec4* color = &colorArrays->operator []( i );
  10.                 // could also use *color = newColor
  11.                 color->set( newColor._v[0], newColor._v[1], newColor._v[2], newColor._v[3] );
  12.             }
  13.         }
  14.     }
复制代码
  1. // 设置Shape的颜色
  2.   void setShapeColor( osg::ShapeDrawable* shape, const osg::Vec4& newColor )
  3.     {
  4.         shape->setColor( newColor );
  5.     }
复制代码
  1. // 设置Drawable(包括Geometry和Shape)的颜色
  2.   void setDrawableColor( osg::Drawable* drawable, const osg::Vec4& newColor )
  3.     {
  4.         osg::Geometry* curGeom = drawable->asGeometry();
  5.         // Only process if the drawable is geometry
  6.         if ( curGeom )
  7.         {
  8.             setGeometryColor( curGeom, newColor );
  9.         }
  10.         else
  11.         {
  12.             osg::ShapeDrawable* curShape = dynamic_cast< osg::ShapeDrawable*>( drawable );
  13.             if( curShape )
  14.             {
  15.                 setShapeColor( curShape, newColor );
  16.             }
  17.         }
  18.     }
复制代码
  1. // 设置叶子节点的颜色
  2. void setGeodeColor( osg::Geode* node, const osg::Vec4& newColor )
  3.     {
  4.         unsigned int numGeoms = node->getNumDrawables();
  5.         for( unsigned int geodeIdx = 0; geodeIdx < numGeoms; geodeIdx++ )
  6.         {
  7.             setDrawableColor( node->getDrawable( geodeIdx ), newColor );
  8.         }
  9.     }
复制代码
  1. // 通过材质设置颜色
  2. // 在Dragger.cpp中发现的该函数!!!
  3. void setMaterialColor( osg::Node* node, const osg::Vec4& color )
  4.     {
  5.         if( node == 0 ) return;

  6.         osg::Material* mat =
  7.             dynamic_cast<osg::Material*>( node->getOrCreateStateSet()->getAttribute( osg::StateAttribute::MATERIAL ) );
  8.         if ( !mat )
  9.         {
  10.             mat = new osg::Material;
  11.             mat->setDataVariance( osg::Object::DYNAMIC );
  12.             node->getOrCreateStateSet()->setAttribute( mat, osg::StateAttribute::ON );
  13.         }
  14.         mat->setDiffuse( osg::Material::FRONT_AND_BACK, color );
  15.     }
复制代码

该用户从未签到

 楼主| 发表于 2013-3-23 21:16:43 | 显示全部楼层
anheihb03dlj 发表于 2013-3-23 21:08
方法很多的,很多代码都是从osg源码中抽取出来的(没事多看看源码很有收获滴)

非常非常感谢!! 以后有空就看看源码 再次感谢!

该用户从未签到

 楼主| 发表于 2013-3-24 10:34:37 | 显示全部楼层
anheihb03dlj 发表于 2013-3-23 21:08
方法很多的,很多代码都是从osg源码中抽取出来的(没事多看看源码很有收获滴)
  1. osg::ref_ptr<osg::PositionAttitudeTransform> child = new osg::PositionAttitudeTransform;
  2.                                 child->addChild(osgDB::readNodeFile("data/seat.IVE"));        //读取座椅模型
复制代码
我的节点是osg::ref_ptr<osg:ositionAttitudeTransform> 类型的 调用asGeode不行啊? 返回的总是空的 请问应该怎么更改这种节点的颜色呢?

该用户从未签到

发表于 2013-3-24 11:15:49 | 显示全部楼层
本帖最后由 anheihb03dlj 于 2013-3-24 11:16 编辑

PositionAttitudeTransform是从Group类派生的,asGeode()方法当然会返回空值啊

要么使用之前提到的setMaterialColor()方法,要注意一点,如果子节点中使用了颜色,那么最好是强制覆盖
  1. // osg::StateAttribute::OVERIDE表示强制覆盖属性
  2. node->getOrCreateStateSet()->setAttribute( mat, osg::StateAttribute::ON |  osg::StateAttribute::OVERIDE);
复制代码
要么你遍历子节点都可以啊,如果PositionAttitudeTransform里面的子节点是Geode,并且你确定第几个子节点是Geode(比如第0个子节点是Geode)那么可以直接访问子节点,使用Group::getChild()方法
  1. osg::PositionAttitudeTransform* pat;
  2. osg::Geode* geode = pat->getChild(0)->asGeode();
复制代码
如果子节点嵌套层次比较深,可以使用NodeVisitor遍历

该用户从未签到

 楼主| 发表于 2013-3-24 13:11:20 | 显示全部楼层
anheihb03dlj 发表于 2013-3-24 11:15
PositionAttitudeTransform是从Group类派生的,asGeode()方法当然会返回空值啊

要么使用之前提到的setMa ...

非常感谢!!使用setMaterialColor()没有问题了

该用户从未签到

发表于 2013-3-25 07:50:21 | 显示全部楼层
shader 其实也是很不错的选择,也不会改变您模型原有的材质信息

该用户从未签到

 楼主| 发表于 2013-3-25 16:47:47 | 显示全部楼层
liuzhiyu123 发表于 2013-3-25 07:50
shader 其实也是很不错的选择,也不会改变您模型原有的材质信息

是说改变材质的话  就不能恢复到以前的颜色了么??  

该用户从未签到

发表于 2013-3-25 16:49:51 | 显示全部楼层
一大波蓝猫 发表于 2013-3-25 16:47
是说改变材质的话  就不能恢复到以前的颜色了么??

能恢复啊,但是前提是您要记住之前的材质才行,这样还不如直接替换ss 使用shader

该用户从未签到

 楼主| 发表于 2013-3-25 20:41:46 | 显示全部楼层
liuzhiyu123 发表于 2013-3-25 16:49
能恢复啊,但是前提是您要记住之前的材质才行,这样还不如直接替换ss 使用shader

shader 是用着色器语言么?

该用户从未签到

 楼主| 发表于 2013-3-25 21:52:59 | 显示全部楼层
liuzhiyu123 发表于 2013-3-25 16:49
能恢复啊,但是前提是您要记住之前的材质才行,这样还不如直接替换ss 使用shader

请问用如下代码保存一个节点的材质  是不是还少了什么? 实测了一下 效果不行 恢复不了
  1. seatMat = dynamic_cast<osg::Material*>( child->getOrCreateStateSet()->getAttribute( osg::StateAttribute::MATERIAL ) );
复制代码

该用户从未签到

 楼主| 发表于 2013-3-25 22:58:38 | 显示全部楼层
liuzhiyu123 发表于 2013-3-25 16:49
能恢复啊,但是前提是您要记住之前的材质才行,这样还不如直接替换ss 使用shader
  1. seatMat = dynamic_cast<osg::Material*>( child->getOrCreateStateSet()->getAttribute( osg::StateAttribute::MATERIAL ) );
复制代码
这个返回的是空。。请问如何保存原来的材质呢。。

该用户从未签到

发表于 2013-3-26 07:41:58 | 显示全部楼层
一大波蓝猫 发表于 2013-3-25 22:58
这个返回的是空。。请问如何保存原来的材质呢。。

没有材质  就是顶点的color 这些都是很基础的知识了吧

该用户从未签到

发表于 2013-3-26 07:42:29 | 显示全部楼层
一大波蓝猫 发表于 2013-3-25 20:41
shader 是用着色器语言么?

是着色语言

该用户从未签到

发表于 2013-3-26 07:43:43 | 显示全部楼层
一大波蓝猫 发表于 2013-3-25 22:58
这个返回的是空。。请问如何保存原来的材质呢。。

不管您是通过材质 还是 通过 顶点颜色来改变, 但是您始终的保存没有改变之前的状态,这样才能恢复到之前的颜色,这样说明白了么?

该用户从未签到

 楼主| 发表于 2013-3-26 09:49:42 | 显示全部楼层
liuzhiyu123 发表于 2013-3-26 07:43
不管您是通过材质 还是 通过 顶点颜色来改变, 但是您始终的保存没有改变之前的状态,这样才能恢复到之前 ...

嗯 明白 我以为能保存材质信息呢。。谢谢回答!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表