OSG 学习第三天:渲染状态
来源:互联网 发布:网络红歌2016流行歌曲 编辑:程序博客网 时间:2024/06/01 22:49
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)的属性:
// 获取变量 geom 的 StateSet 指针。osg::StateSet* state = geom->getOrCreateStateSet(); // 创建并添加 CullFace 属性类。 osg::CullFace* cf = new osg::CullFace( osg::CullFace::BACK ); state->setAttribute( cf );在上面的代码段中,geom 是一个 Geometry 几何类对象(当然也可以是任何 其它派生自 Drawable 和 Node 的对象)。获取 geom 的 StateSet 指针后,代码创建 了一个新的 osg::CullFace 对象,并将其关联到状态量。
2.设置渲染模式(Mode)
用户可以使用 osg::StateSet::setMode()允许或禁止某种模式。例如,下面的代 码将打开雾效模式的许可:
// 获取一个 StateSet 实例。 osg::StateSet* state = geom->getOrCreateStateSet(); // 允许这个 StateSet 的雾效模式。 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 融合检验的属性,同时许可颜色融合模式。
// 创建一个 BlendFunc 属性。 osg::BlendFunc* bf = new osg::BlendFunc(); // 关联 BlendFunc 并许可颜色融合模式 state->setAttributeAndMode( bf );setAttributeAndModes()的第二个输入参数用于允许或禁止第一个参数中渲 染属性对应的渲染模式。其缺省值为 ON。这样用户的应用程序只需用一个函数, 就可以方便地指定某个渲染属性,并许可其对应的渲染模式。
附上书上的一段代码:
//渲染状态(ClipeNode)#include <osgViewer/Viewer>#include <osg/Node>#include <osg/Geode>#include <osg/Geometry>#include <osg/Group>#include <osg/ClipNode>#include <osg/PolygonMode>#include <osg/MatrixTransform>#include <osg/PositionAttitudeTransform>#include <osg/AnimationPath>#include <osgDB/ReadFile>#include <osgDB/WriteFile>#include <osgUtil/Optimizer>#include <iostream>osg::ref_ptr<osg::Node> createClipeNode(osg::ref_ptr<osg::Node> subgraph){osg::ref_ptr<osg::Group> root = new osg::Group();osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();//多边形线形绘制模式,正面和反面都绘制osg::ref_ptr<osg::PolygonMode> polymode = new osg::PolygonMode();polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::FILL);//启用多边形线形绘制模式,并指定状态继承属性为OVERRIDEstateset->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);//多边形线形绘制节点osg::ref_ptr<osg::Group> wrieframe_subgraph = new osg::Group;//设置渲染状态wrieframe_subgraph->setStateSet(stateset.get());wrieframe_subgraph->addChild(subgraph.get());root->addChild(wrieframe_subgraph.get());/*osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;//更新回调,实现动态裁剪osg::ref_ptr<osg::NodeCallback> nc = new osg::AnimationPathCallback(subgraph->getBound().center(),osg::Vec3(0.0f, 0.0f, 1.0f), osg::inDegrees(45.0f));transform->setUpdateCallback(nc.get());//创建裁剪节点osg::ref_ptr<osg::ClipNode> clipnode = new osg::ClipNode;osg::BoundingSphere bs = subgraph->getBound();bs.radius() *= 0.4f;//设置裁剪节点的包围圈osg::BoundingBox bb;bb.expandBy(bs);//根据前面指定的包围盒创建6个裁剪平面clipnode->createClipBox(bb);//禁用拣选clipnode->setCullingActive(false);transform->addChild(clipnode.get());root->addChild(transform.get());//创建未被裁剪的节点osg::ref_ptr<osg::Group> clippedNode = new osg::Group;clippedNode->setStateSet(clipnode->getStateSet());clippedNode->addChild(subgraph.get());root->addChild(clippedNode.get());*/return root.get();}int main(){//创建Viewer对象osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();//osg::ref_ptr<osg::Group> root = new osg::Group();osg::ref_ptr<osg::Node> root = new osg::Node();//加载模型osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cessna.osg");root = createClipeNode(node.get());//优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root.get());//设置场景数据viewer->setSceneData(root.get());//初始化并创建窗口viewer->realize();//开始渲染viewer->run();return 0;}
运行出来是一个飞机的模型,大家也可以把注释代码打开看看效果;
改变一下模式,看看输出什么样的飞机:
polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE); //线
polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::POINT); //点
下面简单介绍贴二维纹理映射:
创建二维纹理的步骤如下:
1.指定用户几何体的纹理坐标
2.创建纹理属性对象并保存纹理图形数据
3.为StateSet设置合适的纹理属性和模式
附上一段代码:
#include <osgViewer/Viewer>#include <osg/Node>#include <osg/Geode>#include <osg/Geometry>#include <osg/Group>#include <osg/Image>#include <osg/TexGen>#include <osg/Texture1D>#include <osg/TexEnv>#include <osg/StateSet>#include <osgDB/ReadFile>#include <osgDB/WriteFile>#include <osgUtil/Optimizer>//创建一个四边形节点osg::ref_ptr<osg::Node> createNode(){osg::ref_ptr<osg::Geode> geode = new osg::Geode();osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();//设置顶点osg::ref_ptr<osg::Vec3Array> vc = new osg::Vec3Array();vc->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));vc->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));vc->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));vc->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));geom->setVertexArray(vc.get());//设置纹理坐标osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array();vt->push_back(osg::Vec2(0.0f, 0.0f));vt->push_back(osg::Vec2(1.0f, 0.0f));vt->push_back(osg::Vec2(1.0f, 1.0f));vt->push_back(osg::Vec2(0.0f, 1.0f));//第一个参数是纹理单元号, 第二个参数是纹理坐标数组geom->setTexCoordArray(0, vt.get());//设置法线 法线和光照有关osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array();nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));geom->setNormalArray(nc.get());//法线绑定方式:用一条法线绑定所有的顶点geom->setNormalBinding(osg::Geometry::BIND_OVERALL);//添加图元geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));//绘制geode->addDrawable(geom.get());return geode.get();}//创建二维纹理状态对象osg::ref_ptr<osg::StateSet> createTexture2DState(osg::ref_ptr<osg::Image> image){//创建状态集对象osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();//创建二维纹理对象osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();texture->setDataVariance(osg::Object::DYNAMIC);//设置贴图texture->setImage(image.get());stateset->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON);return stateset.get();}int main(){osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();osg::ref_ptr<osg::Group> root = new osg::Group();//读取贴图文件osg::ref_ptr<osg::Image> image = osgDB::readImageFile("Images/primitives.gif");osg::ref_ptr<osg::Node> node = createNode();//创建状态集对象osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();stateset = createTexture2DState(image.get());//使用二维纹理node->setStateSet(stateset.get());root->addChild(node.get());//优化场景数据osgUtil::Optimizer optimizer;optimizer.optimize(root.get());//设置场景数据viewer->setSceneData(root.get());//初始化并创建窗口viewer->realize();//开始渲染viewer->run();return 0;}
阅读全文
0 0
- OSG 学习第三天:渲染状态
- OSG渲染状态管理
- OSG渲染状态管理
- OSG 结点渲染状态 类图
- OSG 学习第一天:场景的组织及渲染
- 学习osg渲染内核笔记
- osg 的状态树和渲染树
- osg入门系列-渲染状态实例
- OSG的渲染树与状态树
- 学习CRYPTO第三天
- 第三天(学习记录)
- Java学习第三天
- Java学习第三天
- COBOL学习第三天
- ajax学习第三天
- 学习Java第三天
- unix学习第三天
- 程序学习第三天
- 广搜模板
- 127. Word Ladder
- JAVA基本数据类型学习总结
- 2017 Multi-University Training Contest
- 使用DevC++编程时出现无法读取自定文件的错误
- OSG 学习第三天:渲染状态
- GPS精度因子
- 最小生成树
- 从A表中选取数据列表到B表中然后统计选取的数据字段总行值的sql语句
- 【Java编程】使用List和Map存放多个图书信息
- CNN基础知识
- java-工具-tomcat-加载机制
- 【LeetCode】136 Single Number
- 1.8 C# 继承和继承关系中的构造函数