刻线特效
刻线特效(osgFX::Scribe)是一个双通道的特效,第一个通道以通常的方式渲染图形,第二个通道使用线框模式。用户设置好光照和材质之后,即可使用指定的颜色进行渲染。这个特效使用了PolygonOffset渲染属性类来避免多边形斑驳(Z-fighting)的现象,它所需的OpenGL版本至少为1.1。
osgFX::Scribe 的继承关系图如图12-8 所示。
图12-8 osgFX::Scribe 的继承关系图
下面介绍osgFX::Scribe的一些成员函数:
- // 得到刻线的颜色
- const osg::Vec4 & getWireframeColor()const
- // 设置刻线的颜色
- void setWireframeColor(const osg::Vec4 &color)
- // 得到刻线的宽度
- float getWireframeLineWidth() const
- // 设置刻线的宽度
- void setWireframeLineWidth (float w)
刻线特效示例
下面通过一个例子来学习如何在场景中添加osgFX::Scribe 特效代码如程序清单 12-4 所示。
1. /********************************** 刻线特效示例12-4 ************************************/
2. void scribe_12_4(const string &strDataFolder)
3. {
4. osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
5. osg::ref_ptr<osg::Group> root = new osg::Group();
6. osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
7. traits->x = 40;
8. traits->y = 40;
9. traits->width = 600;
10. traits->height = 480;
11. traits->windowDecoration = true;
12. traits->doubleBuffer = true;
13. traits->sharedContext = 0;
14.
15. osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
16.
17. osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
18. camera->setGraphicsContext(gc.get());
19. camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
20. GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
21. camera->setDrawBuffer(buffer);
22. camera->setReadBuffer(buffer);
23.
24. // 读取模型,读取飞机模型
25. string strDataPath = strDataFolder + "cessna.osg";//axes.osgt
26. osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);
27.
28. // 创建刻线对象
29. osg::ref_ptr<osgFX::Scribe> sc = new osgFX::Scribe();
30. sc->setWireframeColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); // 设置轮廓线的颜色
31. sc->setWireframeLineWidth(2.0);// 设置刻线的宽度
32. sc->addChild(node.get());//添加子节点
33.
34. root->addChild(sc.get());
35.
36. // 优化场景数据
37. osgUtil::Optimizer optimizer;
38. optimizer.optimize(root.get());
39.
40. viewer->setSceneData(root.get());
41.
42. viewer->realize();
43. viewer->run();
44. }
运行程序,截图如图12-9 所示
图12-9刻线特效示例截图
立方图镜面高光特效
立方图镜面高光特效(osgFX::SpecularHighlights)在片断层级(fragment level)上(而不是OpenGL通常的顶点层级)应用了镜面高光。它使用了立方映射图和反射纹理生成(reflective texgen)的技术,首先要计算出纹理矩阵以实现立方映射图的自动旋转,这样无论从观察的方向和光照位置上来说,镜面光的效果都将始终不变。用户可以选择使用何种光照来计算纹理矩阵。该特效需要GL_ARB_texture_env_add扩展以及任意一种立方映射图扩展(GL_EXT_texture_cube_map、GL_ARB_texture_cube_map或OpenGL1.3)的支持。
osgFX::SpecularHighlights 的继承关系图如图12-10所示。
图12-10 osgFX::SpecularHighlights 的继承关系图
下面介绍osgFX::SpecularHighlights 的一些成员函数:
- int getLightNumber() const // 得到光源数
- void setLightNumber(int n) // 设置光源数
- int getTextureUnit()const // 得到纹理单元
- void setTextureUnit(int n) // 设置纹理单元
- const osg::Vec4 & getSpecularColor()const // 得到镜面高光的颜色
- void setSpecularColor(const osg::Vec4 &color) // 设置镜面高光的颜色
- float getSpecularExponent()const // 得到镜面高光指数
- void setSpecularExponent(float c) // 设置镜面高光指数
立方图镜面高光特效示例
下面通过一个例子来学习如何在场景中添加osgFX::SpecularHighlights特效。
代码如程序清单12-5所示。
1. /********************************** 立方图镜面高光特效示例 12-5 ************************************/
2. void specularHighlights_12_5(const string &strDataFolder)
3. {
4. osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
5. osg::ref_ptr<osg::Group> root = new osg::Group();
6. osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
7. traits->x = 40;
8. traits->y = 40;
9. traits->width = 600;
10. traits->height = 480;
11. traits->windowDecoration = true;
12. traits->doubleBuffer = true;
13. traits->sharedContext = 0;
14.
15. osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
16.
17. osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
18. camera->setGraphicsContext(gc.get());
19. camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
20. GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
21. camera->setDrawBuffer(buffer);
22. camera->setReadBuffer(buffer);
23.
24. // 读取模型,读取飞机模型
25. string strDataPath = strDataFolder + "cessna.osg";//axes.osgt
26. osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);
27.
28. // 创建镜面高光对象
29. osg::ref_ptr<osgFX::SpecularHighlights> shl = new osgFX::SpecularHighlights();
30. shl->setTextureUnit(0); // 设置纹理单元,被设置的纹理单元将应用于立方图纹理
31. shl->setLightNumber(6); // 设置光源数
32. shl->setSpecularColor(osg::Vec4(1.0, 1.0, 1.0, 1.0));// 设置镜面光颜色
33. shl->setSpecularExponent(16.0);// 设置镜面指数
34.
35. shl->addChild(node.get());//添加子节点
36.
37. root->addChild(shl.get());
38.
39. // 优化场景数据
40. osgUtil::Optimizer optimizer;
41. optimizer.optimize(root.get());
42.
43. viewer->setSceneData(root.get());
44.
45. viewer->realize();
46. viewer->run();
47. }
运行程序,截图如图12-11 所示。
图12-11立方图镜面高光特效示例截图