osg-材质 (osg::Material)

1.材质类

材质类 (osg::Material)继承自osg::StateAttribute 类。osg::Material 封装了 OpenGL的 glMaterial()和glColorMaterial()指令的函数功能,其继承关系图如图5-27 所示。

图 5-27 osg::Material 的继承关系图

在场景中设置节点的材质属性,首先要创建一个osg::Material 对象,然后设置颜色和其他参数,再关联到场景图形的StateSet 中,如下面的代码:

  1. osg::StateSet* state = node->getOrCreateStateSet();
  2. osg::ref_ptr<osg::Material> mat = new osg::Material;
  3. state->setAttribute(mat.get());

osg::Material类包含的主要属性如下

  1. bool _ambientFrontAndBack;// 前面与后面的环境光
  2. Vec4 _ambientFront; // 前面的环境光,r、g、b、w
  3. Vec4 _ambientBack; // 后面的环境光,r、g、b、w
  4. bool _diffuseFrontAndBack;// 前面与后面的漫射光
  5. Vec4 _diffuseFront;// 前面的漫射光,r、g、b、w
  6. Vec4 _diffuseBack: // 后面的漫射光,r、g、b、w
  7. bool _specularFrontAndBack;// 前面与后面的镜面光
  8. Vec4 _specularFront;//前面的镜面光,r、g、b、w
  9. Vec4 _specularBack;//后面的镜面光,r、g、b、w
  10. bool _emissionFrontAndBack;// 前面与后面的发射光(emission)
  11. Vec4 _emissionFront; // 前面的emission,r、g、b、w
  12. Veo4 _emissionBack: // 后面的emission,r、g、b、w
  13. bool _shininessFrontAndBack;// 前面与后面的发光(shininess)
  14. float _shininessFront:// 前面的shininess
  15. float _shinincssBack; // 后面的shininess
  • 注意:shininess是一个在0~128.0之间的值,值越大,亮点越小、越亮。

OSG材质的面如下:

  1. enum Face
  2. {
  3. FRONT=GL_FRONT,//前
  4. BACK=GL_BACK,//后
  5. FRONT_AND_BACK=GL_FRONT_AND_BACK/前、后
  6. }

OSG材质的颜色模式如下:

  1. enum ColorMode
  2. {
  3. AMBIENT = GL_AMBIENT, //环境光颜色
  4. DIFFUSE = GL_DIFFUSE, //漫射光颜色
  5. SPECULAR = GL_SPECULAR, //镜面光颜色
  6. EMISSION = GL_EMISSION, //发射光颜色
  7. AMBIENT_AND_DIFFUSE=GL_AMBIENT_AND_DIFFUSE,// 环境与漫射光颜色
  8. OFF // 关闭模式
  9. }

在进行很多 OpenGL的操作时,直接设置材质属性可能会过于耗费资源,而OSG提供了一种颜色跟踪材质的高效方法,操作比直接修改材质属性的效率更高,颜色跟踪材质 (color material)允许用户程序通过改变当前颜色的方法,自动改变某一特定的材质属性。在许多情形下,这一操作比直接修改材质属性的效率要高,能加强光照场景和无光照场景的联系,并满足应用程序对材质的需要。

允许颜色跟踪材质的特性需要调用 setColorMode()方法。osg::Material类为之定义了枚举量AMBIENT、DIFFUSE、SPECULAR、EMISSION、AMBIENT_AND_DIFFUSE 以及 OFF。默认情况下,颜色跟踪模式被设置为 OFF,颜色跟踪材质被禁止。如果用户程序设置颜色跟踪模式为其他的值,那么OSG 将为特定的材质属性开启颜色跟踪材质特性,此时主颜色的改变将会改变相应的材质属性。第5.4.2节的代码段将允许颜色跟踪材质,此时几何体正面的环境材质和散射材质颜色将自动跟踪当前颜色的改变而改变。

  • 注意:根据颜色跟踪模式的取值不同,Material 类会自动允许或禁止GL_COLOR_MATERIAL,因此,用户程序不需要调用setAttributeAndModes()来允许或禁止相关的模式值。

2.材质类示例

材质类(osg::Material)示例的代码如程序清单5-14 所示。

cpp 复制代码
1.	osg::ref_ptr<osg::Node> createNode_5_14() // 创建一个四边形节点  
2.	{  
3.	    osg::ref_ptr<osg::Geode> geode = new osg::Geode();  
4.	  
5.	    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();  
6.	  
7.	    // 设置顶点  
8.	    osg::ref_ptr<osg::Vec3Array> vc = new osg::Vec3Array();  
9.	    vc->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));  
10.	    vc->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));  
11.	    vc->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));  
12.	    vc->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));  
13.	    geom->setVertexArray(vc.get());  
14.	  
15.	    // 设置纹理坐标  
16.	    osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array();  
17.	    vt->push_back(osg::Vec2(0.0f, 0.0f));  
18.	    vt->push_back(osg::Vec2(1.0f, 0.0f));  
19.	    vt->push_back(osg::Vec2(1.0f, 1.0f));  
20.	    vt->push_back(osg::Vec2(0.0f, 1.0f));  
21.	    geom->setTexCoordArray(0, vt.get());  
22.	  
23.	    // 设置法线  
24.	    osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array();  
25.	    nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));  
26.	    geom->setNormalArray(nc.get());  
27.	    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);  
28.	    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4)); // 添加图元  
29.	    geode->addDrawable(geom.get()); // 绘制  
30.	  
31.	    return geode.get();  
32.	}  
33.	  
34.	void material_5_14()  
35.	{  
36.	    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();  
37.	    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
38.	    traits->x = 40;  
39.	    traits->y = 40;  
40.	    traits->width = 600;  
41.	    traits->height = 480;  
42.	    traits->windowDecoration = true;  
43.	    traits->doubleBuffer = true;  
44.	    traits->sharedContext = 0;  
45.	  
46.	    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
47.	    osg::ref_ptr<osg::Camera> camera = new osg::Camera;  
48.	    camera->setGraphicsContext(gc.get());  
49.	    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));  
50.	    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;  
51.	    camera->setDrawBuffer(buffer);  
52.	    camera->setReadBuffer(buffer);  
53.	    viewer->addSlave(camera.get());  
54.	    osg::ref_ptr<osg::Group> root = new osg::Group();  
55.	  
56.	    osg::ref_ptr<osg::Node> node = createNode_5_14();  
57.	  
58.	    // 得到状态属性  
59.	    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();  
60.	    stateset = node->getOrCreateStateSet();  
61.	  
62.	    // 创建材质对象  
63.	    osg::ref_ptr<osg::Material> mat = new osg::Material();      
64.	    mat->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); // 设置正面散射颜色      
65.	    mat->setSpecular(osg::Material::FRONT, osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); // 设置正面镜面颜色     
66.	    mat->setShininess(osg::Material::FRONT, 90.0f); // 设置正面指数  
67.	    stateset->setAttribute(mat.get());  
68.	  
69.	    // 设置背面剔除  
70.	    osg::ref_ptr<osg::CullFace> cullface = new osg::CullFace(osg::CullFace::BACK);  
71.	    stateset->setAttribute(cullface.get());  
72.	    stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);  
73.	    root->addChild(node.get());  
74.	  
75.	    // 优化场景数据  
76.	    osgUtil::Optimizer optimizer;  
77.	    optimizer.optimize(root.get());  
78.	    viewer->setSceneData(root.get());  
79.	    viewer->realize();  
80.	    viewer->run();  
81.	}  

运行程序,截图如图5-28所示。

图5-28 材质类示例截图

相关推荐
knighthood20016 分钟前
解决:ros进行gazebo仿真,rviz没有显示传感器数据
c++·ubuntu·ros
云卓SKYDROID11 分钟前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
半盏茶香35 分钟前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
徐子童39 分钟前
双指针算法习题解答
算法
小堇不是码农41 分钟前
在VScode中配置C_C++环境
c语言·c++·vscode
Jack黄从零学c++44 分钟前
C++ 的异常处理详解
c++·经验分享
想要打 Acm 的小周同学呀1 小时前
LRU缓存算法
java·算法·缓存
劲夫学编程2 小时前
leetcode:杨辉三角
算法·leetcode·职场和发展
毕竟秋山澪2 小时前
孤岛的总面积(Dfs C#
算法·深度优先
浮生如梦_4 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测