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 材质类示例截图

相关推荐
m0_7431064640 分钟前
【论文笔记】MV-DUSt3R+:两秒重建一个3D场景
论文阅读·深度学习·计算机视觉·3d·几何学
m0_7431064642 分钟前
【论文笔记】TranSplat:深度refine的camera-required可泛化稀疏方法
论文阅读·深度学习·计算机视觉·3d·几何学
王老师青少年编程3 小时前
gesp(C++五级)(14)洛谷:B4071:[GESP202412 五级] 武器强化
开发语言·c++·算法·gesp·csp·信奥赛
DogDaoDao3 小时前
leetcode 面试经典 150 题:有效的括号
c++·算法·leetcode·面试··stack·有效的括号
Coovally AI模型快速验证4 小时前
MMYOLO:打破单一模式限制,多模态目标检测的革命性突破!
人工智能·算法·yolo·目标检测·机器学习·计算机视觉·目标跟踪
一只小bit4 小时前
C++之初识模版
开发语言·c++
可为测控4 小时前
图像处理基础(4):高斯滤波器详解
人工智能·算法·计算机视觉
Milk夜雨5 小时前
头歌实训作业 算法设计与分析-贪心算法(第3关:活动安排问题)
算法·贪心算法
CodeClimb5 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
BoBoo文睡不醒5 小时前
动态规划(DP)(细致讲解+例题分析)
算法·动态规划