当前位置:   article > 正文

OSG 学习第三天:渲染状态_osg渲染部分在哪里

osg渲染部分在哪里
OSG 渲染状态


前言:撸了两天代码,决定换一种学习方式试试。


渲染状态(Rendering State)  

OSG支持绝大部分的OpenGL 固定功能管道(fixed function pipeline)渲染,例如 Alpha 检验,Blending 融合, 剪切平面,颜色蒙板,面拣选(face culling),深度和模板检验,雾效,点和线 的光栅化(rasterization),等等。OSG 的渲染状态也允许应用程序指定顶点着色(vertex shader)和片段着色(fragment shader)。 用户的应用程序需要在 osg::StateSet 中设置渲染状态。

OSG 将渲染状态分成两个部分,渲染属性(attribute)和渲染模式(mode)。 
渲染属性也就是控制渲染特性的状态变量。例如,雾的颜色,或者 Blend 融合函 数都是 OSG 的状态属性。
OSG 中的渲染模式和 OpenGL 的状态特性几乎是一一 对应的,这些特性在 OpenGL 中通过函数 glEnable()和 glDisable()进行控制。用程序可以设置模式量以允许或禁止某个功能,例如纹理映射、灯光等。简单来说,渲染模式是指渲染的某个功能,而渲染属性是这个功能的控制变量和参数。

渲染的步骤如下:
1.设置渲染属性(Attribute)
如果要设置一项属性,首先将要修改的属性类实例化。设置该类的数值,然 后用 osg::StateSet::setAttribute()将其关联到 StateSet。下面的代码段用于实现面剔 除(face culling)的属性: 
  1. // 获取变量 geom 的 StateSet 指针。
  2. osg::StateSet* state = geom->getOrCreateStateSet();
  3. // 创建并添加 CullFace 属性类。
  4. osg::CullFace* cf = new osg::CullFace( osg::CullFace::BACK );
  5. state->setAttribute( cf );
在上面的代码段中,geom 是一个 Geometry 几何类对象(当然也可以是任何 其它派生自 Drawable 和 Node 的对象)。获取 geom 的 StateSet 指针后,代码创建 了一个新的 osg::CullFace 对象,并将其关联到状态量。

2.设置渲染模式(Mode)
用户可以使用 osg::StateSet::setMode()允许或禁止某种模式。例如,下面的代 码将打开雾效模式的许可:
  1. // 获取一个 StateSet 实例。
  2. osg::StateSet* state = geom->getOrCreateStateSet();
  3. // 允许这个 StateSet 的雾效模式。
  4. state->setMode( GL_FOG, osg::StateAttribute::ON );
setMode()的第一个输入参数可以是任何一个在 glEnable()或 glDisable()中合 法的 OpenGL 枚举量 GLenum。第二个输入参数可以是 osg::StateAttribute::ON 或 osg::StateAttribute::OFF。
 
3.设置渲染属性和模式
OSG 提供了一个简单的可以同时设置属性和模式的单一函数接口。在许多 情况下,属性和模式之间都存在显著的关系。例如,CullFace 属性的对应模式为 GL_CULL_FACE。如果要将某个属性关联到一个 StateSet,同时打开其对应模式 的许可,那么可以使用 osg::StateSet::setAttributeAndModes()方法。下面的代码段 将关联 Blend 融合检验的属性,同时许可颜色融合模式。 
  1. // 创建一个 BlendFunc 属性。
  2. osg::BlendFunc* bf = new osg::BlendFunc();
  3. // 关联 BlendFunc 并许可颜色融合模式
  4. state->setAttributeAndMode( bf );
setAttributeAndModes()的第二个输入参数用于允许或禁止第一个参数中渲 染属性对应的渲染模式。其缺省值为 ON。这样用户的应用程序只需用一个函数, 就可以方便地指定某个渲染属性,并许可其对应的渲染模式。 


附上书上的一段代码:
  1. //渲染状态(ClipeNode)
  2. #include <osgViewer/Viewer>
  3. #include <osg/Node>
  4. #include <osg/Geode>
  5. #include <osg/Geometry>
  6. #include <osg/Group>
  7. #include <osg/ClipNode>
  8. #include <osg/PolygonMode>
  9. #include <osg/MatrixTransform>
  10. #include <osg/PositionAttitudeTransform>
  11. #include <osg/AnimationPath>
  12. #include <osgDB/ReadFile>
  13. #include <osgDB/WriteFile>
  14. #include <osgUtil/Optimizer>
  15. #include <iostream>
  16. osg::ref_ptr<osg::Node> createClipeNode(osg::ref_ptr<osg::Node> subgraph)
  17. {
  18. osg::ref_ptr<osg::Group> root = new osg::Group();
  19. osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
  20. //多边形线形绘制模式,正面和反面都绘制
  21. osg::ref_ptr<osg::PolygonMode> polymode = new osg::PolygonMode();
  22. polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::FILL);
  23. //启用多边形线形绘制模式,并指定状态继承属性为OVERRIDE
  24. stateset->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
  25. //多边形线形绘制节点
  26. osg::ref_ptr<osg::Group> wrieframe_subgraph = new osg::Group;
  27. //设置渲染状态
  28. wrieframe_subgraph->setStateSet(stateset.get());
  29. wrieframe_subgraph->addChild(subgraph.get());
  30. root->addChild(wrieframe_subgraph.get());
  31. /*
  32. osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
  33. //更新回调,实现动态裁剪
  34. osg::ref_ptr<osg::NodeCallback> nc = new osg::AnimationPathCallback(subgraph->getBound().center(),
  35. osg::Vec3(0.0f, 0.0f, 1.0f), osg::inDegrees(45.0f));
  36. transform->setUpdateCallback(nc.get());
  37. //创建裁剪节点
  38. osg::ref_ptr<osg::ClipNode> clipnode = new osg::ClipNode;
  39. osg::BoundingSphere bs = subgraph->getBound();
  40. bs.radius() *= 0.4f;
  41. //设置裁剪节点的包围圈
  42. osg::BoundingBox bb;
  43. bb.expandBy(bs);
  44. //根据前面指定的包围盒创建6个裁剪平面
  45. clipnode->createClipBox(bb);
  46. //禁用拣选
  47. clipnode->setCullingActive(false);
  48. transform->addChild(clipnode.get());
  49. root->addChild(transform.get());
  50. //创建未被裁剪的节点
  51. osg::ref_ptr<osg::Group> clippedNode = new osg::Group;
  52. clippedNode->setStateSet(clipnode->getStateSet());
  53. clippedNode->addChild(subgraph.get());
  54. root->addChild(clippedNode.get());
  55. */
  56. return root.get();
  57. }
  58. int main()
  59. {
  60. //创建Viewer对象
  61. osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
  62. //osg::ref_ptr<osg::Group> root = new osg::Group();
  63. osg::ref_ptr<osg::Node> root = new osg::Node();
  64. //加载模型
  65. osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cessna.osg");
  66. root = createClipeNode(node.get());
  67. //优化场景数据
  68. osgUtil::Optimizer optimizer;
  69. optimizer.optimize(root.get());
  70. //设置场景数据
  71. viewer->setSceneData(root.get());
  72. //初始化并创建窗口
  73. viewer->realize();
  74. //开始渲染
  75. viewer->run();
  76. return 0;
  77. }

运行出来是一个飞机的模型,大家也可以把注释代码打开看看效果;

改变一下模式,看看输出什么样的飞机:
polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);   //线
polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::POINT);  //点


  
  



下面简单介绍贴二维纹理映射:

创建二维纹理的步骤如下:
1.指定用户几何体的纹理坐标
2.创建纹理属性对象并保存纹理图形数据
3.为StateSet设置合适的纹理属性和模式

附上一段代码:
  1. #include <osgViewer/Viewer>
  2. #include <osg/Node>
  3. #include <osg/Geode>
  4. #include <osg/Geometry>
  5. #include <osg/Group>
  6. #include <osg/Image>
  7. #include <osg/TexGen>
  8. #include <osg/Texture1D>
  9. #include <osg/TexEnv>
  10. #include <osg/StateSet>
  11. #include <osgDB/ReadFile>
  12. #include <osgDB/WriteFile>
  13. #include <osgUtil/Optimizer>
  14. //创建一个四边形节点
  15. osg::ref_ptr<osg::Node> createNode()
  16. {
  17. osg::ref_ptr<osg::Geode> geode = new osg::Geode();
  18. osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();
  19. //设置顶点
  20. osg::ref_ptr<osg::Vec3Array> vc = new osg::Vec3Array();
  21. vc->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
  22. vc->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
  23. vc->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
  24. vc->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
  25. geom->setVertexArray(vc.get());
  26. //设置纹理坐标
  27. osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array();
  28. vt->push_back(osg::Vec2(0.0f, 0.0f));
  29. vt->push_back(osg::Vec2(1.0f, 0.0f));
  30. vt->push_back(osg::Vec2(1.0f, 1.0f));
  31. vt->push_back(osg::Vec2(0.0f, 1.0f));
  32. //第一个参数是纹理单元号, 第二个参数是纹理坐标数组
  33. geom->setTexCoordArray(0, vt.get());
  34. //设置法线 法线和光照有关
  35. osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array();
  36. nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
  37. geom->setNormalArray(nc.get());
  38. //法线绑定方式:用一条法线绑定所有的顶点
  39. geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
  40. //添加图元
  41. geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
  42. //绘制
  43. geode->addDrawable(geom.get());
  44. return geode.get();
  45. }
  46. //创建二维纹理状态对象
  47. osg::ref_ptr<osg::StateSet> createTexture2DState(osg::ref_ptr<osg::Image> image)
  48. {
  49. //创建状态集对象
  50. osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
  51. //创建二维纹理对象
  52. osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();
  53. texture->setDataVariance(osg::Object::DYNAMIC);
  54. //设置贴图
  55. texture->setImage(image.get());
  56. stateset->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON);
  57. return stateset.get();
  58. }
  59. int main()
  60. {
  61. osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
  62. osg::ref_ptr<osg::Group> root = new osg::Group();
  63. //读取贴图文件
  64. osg::ref_ptr<osg::Image> image = osgDB::readImageFile("Images/primitives.gif");
  65. osg::ref_ptr<osg::Node> node = createNode();
  66. //创建状态集对象
  67. osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
  68. stateset = createTexture2DState(image.get());
  69. //使用二维纹理
  70. node->setStateSet(stateset.get());
  71. root->addChild(node.get());
  72. //优化场景数据
  73. osgUtil::Optimizer optimizer;
  74. optimizer.optimize(root.get());
  75. //设置场景数据
  76. viewer->setSceneData(root.get());
  77. //初始化并创建窗口
  78. viewer->realize();
  79. //开始渲染
  80. viewer->run();
  81. return 0;
  82. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/314899
推荐阅读
相关标签
  

闽ICP备14008679号