sky11811 发表于 2011-9-3 02:43:35

无用教程第(一)集 sky1811

本帖最后由 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,_vertices.getDataPointer
    // 这样的书写没有语法错误,但是概念错误,如果运行将导致程序崩溃。这样的使用方法只有_vertices
    // 不会导致指针越界。_vertices是指向容器的
    // 指针,数据在容器中,而不在_vertices中,所以要(*_vertices)。
   
    (*_vertices)._v = (*v)._v + sin(((rand()%314)-157)/314.0)*0.6;
   }
}
else
{
   // 这段代码存储几何体顶点数据,用来参考,呵呵
   // 这个例子的效果是顶点在z方向抖动所以需要存储原始位置。
   for(unsigned int i = 0;i<_vertices->size();i++)
   {
    v->push_back((*_vertices));
   }
   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();
}

sky11811 发表于 2011-9-3 02:49:49

本帖最后由 sky11811 于 2011-9-3 03:02 编辑

贴的代码格式乱了,不知如何修改,影响阅读请见谅。要看着舒服复制代码至剪贴板,然后粘贴到vc里看吧。

xairwolfcn 发表于 2011-9-3 09:22:35

先顶个!

mijue 发表于 2011-9-3 10:29:40

多谢楼主了。。

CWorld 发表于 2011-9-4 09:25:12

本帖最后由 CWorld 于 2011-9-4 12:52 编辑

下载了,可以运行,看的出来lz写的很认真。看看编辑的时间也颇为敬佩!觉得lz有机会可以考虑兼职和参与开源的工程,这样就可以更加深入理解工业和行业的需求。

1   有个问题,如果没有设置VBO

   setUseVertexBufferObjects( true );这种情况下,关闭了显示列表。会调用VBO模式吗?

   我也很喜欢实时渲染技术,每天工作也是一堆琐事。据说osg的一部分核心功能是在Robert没有薪酬的情况下完成的,不知道他是怎么过来的。

Hadse 发表于 2011-9-5 08:24:24

先顶起!

tianxiao888 发表于 2011-9-6 11:31:45

我真是感动与楼主的精神啊,惭愧!

476080276 发表于 2011-11-11 21:52:22

支持,支持,不管怎么样,写出来了都值得我们学习

OSG_panda_2012 发表于 2011-11-21 15:46:34

顶, 第二集呢?

gong6387 发表于 2012-2-20 12:49:02

真男人,追求生命的真正价值,追求内在的极致大道,有朝一日定能飞黄腾达!

buptwenze 发表于 2012-4-13 10:47:15

支持楼主,真是令人感动啊
页: [1]
查看完整版本: 无用教程第(一)集 sky1811