|
本帖最后由 sky11811 于 2011-9-3 02:48 编辑
前一段时间,发表了过激言论,遭到了猛烈的抨击,被指有腐败公务员做派,呵呵,那些腐败的公务员被你们低估啦,
他们说话极为圆滑,绝不激怒大众,像我这样说话有棱角的根本没有腐败的资格,混得凄惨无比,在家还被老婆指责没出息,“人家吃吃喝喝,从不加班,都科长了,你天天加班写你的狗屁程序,没给家里创造一分收入,一次没有升迁,一直是个科员,人家都有车了,你就好好骑你的电动车吧”。
作为一个30岁的人,我郁闷无比,喜欢实时渲染技术,但只能等老婆睡觉了再看文档学习,上班倒是可以看,但是成果很难和大家分享,办公室不能上网且绝不允许使用u盘。
所以只有凌晨3点以后才有时间给大家贡献点东西啦,见谅。
--------------------------------废话完毕开始正事----------------------------------------------
这个例子的效果是顶点在z方向抖动,要展示的是顶点数组的访问修改,其他数组如:纹理坐标数组、法线数组等均可参考。这个例子新手觉得没意思,老手也觉得没意思,适合
有图形基础,但不熟悉osg的同志参考。我学习osg有一个月了,但学习openGL有接近10年了,我知道熟悉OpenGL的同志最希望看到什么样的osg文档。通过近一个月的集中学习,我的感触是OSG真是太好了,我爱不释手,我对osg的源代码做了一些改动,完成了FirstPersonManipulator中的未实现部分,达到了和cs一样的操作效果,修改了osgearth的skynode源代码,实现了地球和大气的散射效果共存(skynode原本只有大气有散射效果而地球本身没有)。熟悉了osgDEM命令,发现现有书籍里对“--xx --xt --yy --yt --zz --zt 指定每个像素所指的大小” 的解释都是残缺或者错误的。
-
- #include <osg/Geode>
- #include <osg/Geometry>
- #include <osg/Point>
- #include <osg/StateSet>
- #include <osgViewer/Viewer>
- #ifdef _DEBUG
- #pragma comment(lib,"osgd.lib")
- #pragma comment(lib,"osgDBd.lib")
- #pragma comment(lib,"osgViewerd.lib")
- #endif
- #ifdef NDEBUG
- #pragma comment(lib,"osg.lib")
- #pragma comment(lib,"osgDB.lib")
- #pragma comment(lib,"osgViewer.lib")
- #endif
- class ChangeVertex : public osg::NodeCallback
- {
- public:
- ChangeVertex()
- {
- haveStored = false;
- v = new osg::Vec3Array;
- }
- virtual void operator()( osg::Node* node,
- osg::NodeVisitor* nv )
- {
- // 这个node本来就是osg::Geode,所以下面的代码可以轻松的转换node为osg::Geode类型。
- osg::Geode * geode = node->asGeode();
- // 我们只添加了一个几何体所以getDrawable(0)就可以了,不用
- // for( unsigned int i=0; i < geode.getNumDrawables(); ++i ) getDrawable(i);
- // 要是你愿意也没人拦你。
- osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode->getDrawable(0));
- // 接下来这一句是所有图形基础较好的同志最关心的问题了,基础较好者往往关心底层的
- // 东西,希望有更多的控制。这一句获取顶点存储容器的指针,极易犯错。在下面的for循环
- // 里我会解释为什么容易犯错。
- osg::Vec3Array* _vertices = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());
- if(haveStored)
- {
- for(unsigned int i = 0;i<_vertices->size();i++)
- {
- // 这里C++功夫不过关的同志容易犯错,常见错误如下: _vertices[i],_vertices[i].getDataPointer
- // 这样的书写没有语法错误,但是概念错误,如果运行将导致程序崩溃。这样的使用方法只有_vertices[0]
- // 不会导致指针越界。_vertices是指向容器的
- // 指针,数据在容器中,而不在_vertices中,所以要(*_vertices)[i]。
-
- (*_vertices)[i]._v[2] = (*v)[i]._v[2] + sin(((rand()%314)-157)/314.0)*0.6;
- }
- }
- else
- {
- // 这段代码存储几何体顶点数据,用来参考,呵呵
- // 这个例子的效果是顶点在z方向抖动所以需要存储原始位置。
- for(unsigned int i = 0;i<_vertices->size();i++)
- {
- v->push_back((*_vertices)[i]);
- }
- haveStored = true;
- }
- traverse( node, nv );
- }
- private:
- osg::ref_ptr<osg::Vec3Array> v;
- bool haveStored;
- };
- osg::ref_ptr<osg::Geode>
- createPoints()
- {
- // 创建几何体类,该类用于绘制几何体,并存储几何体的相关数据。
- // 例如:顶点数组、法线数组、纹理坐标数组等等。要访问修改几
- // 何体数据就要找这个类。注意这个类和osg::Geode的关系,osg::Geode
- // 用来管理osg::Geometry,一个osg::Geode可以有多个osg::Geometry。
- osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
- osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
- geom->setVertexArray( v.get() );
- v->push_back( osg::Vec3( 0.f, 0.f, 0.f ) );
- v->push_back( osg::Vec3( 0.f, 0.f, 4.f ) );
- v->push_back( osg::Vec3( -1.f, 0.f, 0.f ) );
- v->push_back( osg::Vec3( 1.f, 0.f, 0.f ) );
- v->push_back( osg::Vec3( 1.f, 0.f, 4.f ) );
- v->push_back( osg::Vec3( -1.f, 0.f, 4.f ) );
- v->push_back( osg::Vec3( 0.f, -1.f, 0.f ) );
- v->push_back( osg::Vec3( 0.f, 1.f, 0.f ) );
- v->push_back( osg::Vec3( 0.f, 1.f, 4.f ) );
- v->push_back( osg::Vec3( 0.f, -1.f, 4.f ) );
- // 这个例子中我们需要动态的修改顶点数组的数据,所以不希望使用显示列表来加速。
- geom->setUseDisplayList(false);
- // 指定绘制图元的类型及数量,对OpenGL熟悉的同志应该对这个十分有感情。
- geom->addPrimitiveSet( new osg::DrawArrays( GL_POINTS, 0, 10 ) );
- // 创建叶节点,准备收容几何体类
- osg::ref_ptr<osg::Geode> geode = new osg::Geode;
- // 收容几何体。
- geode->addDrawable( geom.get() );
- // 下面一段代码关闭光照,指定点尺寸。
- osg::StateSet* state = geode->getOrCreateStateSet();
- state->setMode( GL_LIGHTING, osg::StateAttribute::OFF |
- osg::StateAttribute::PROTECTED );
- osg::ref_ptr<osg::Point> pt = new osg::Point;
- pt->setSize( 10.f );
- state->setAttribute( pt.get() );
- geode->setUpdateCallback(new ChangeVertex());
- return geode.get();
- }
- int
- main( int, char ** )
- {
- osgViewer::Viewer viewer;
- viewer.setSceneData( createPoints().get() );
- return viewer.run();
- }
复制代码 |
|