查看: 3918|回复: 8

求教!OSG图形渲染后怎样改变形状?

[复制链接]

该用户从未签到

发表于 2009-7-24 19:02:40 | 显示全部楼层 |阅读模式
我在osg中画了一个长方形,请问怎样随时改变这个长方形的长和宽的大小?比如我用OSG+MFC,我每次点击按钮后,让长加5,宽减5。我用geometrycallback,但总无法改变,请问该怎么做?最好能给出callback部分的代码,我是新手,万分感谢!!!

该用户从未签到

发表于 2009-7-24 23:32:33 | 显示全部楼层
用callback是没有问题的。但是要注意,如果使用显示列表(Display List,默认是这个)模式,则每次修改之后需要dirtyDisplayList()来应用修改;如果是VBO模式,则需要执行顶点数组的dirty()函数,建议配置好一些的机器选用VBO而非DisplayList来完成动态几何体的绘制

该用户从未签到

 楼主| 发表于 2009-7-25 10:26:13 | 显示全部楼层
谢谢array,这些我都试过了呀,就是每次执行时感觉好像只执行一次callback函数,再以后更改参数就不起作用了,虽然确实都执行了回调,郁闷,再仔细看看吧,不知哪里出了问题

该用户从未签到

 楼主| 发表于 2009-7-25 10:28:29 | 显示全部楼层
谁能给段代码看看,毕竟自己是新手,谢谢

该用户从未签到

发表于 2009-7-25 15:25:07 | 显示全部楼层
那就设置setUseDisplayList(false),关闭显示列表
然后最好设置setUseVertexBufferObjects(true),启用VBO

该用户从未签到

 楼主| 发表于 2009-7-25 19:23:31 | 显示全部楼层
osg::Geometry* polyGeom = new osg::Geometry();
                //mirror = new osg::Geometry();
                //设置该几何体不使用显示列表
                polyGeom->setDataVariance( osg::Object:YNAMIC );
                polyGeom->setSupportsDisplayList(true);

                //创建顶点数组,并添加数据
                osg::Vec3Array* vertices = new osg::Vec3Array;
                vertices->push_back( osg::Vec3(0.0f,0.0f,0.0f)+mirrorcenter );
                vertices->push_back( osg::Vec3(0.0f,mirror_width,0.0f)+mirrorcenter );               
                vertices->push_back( osg::Vec3(0.0f,mirror_width,mirror_height)+mirrorcenter );
                vertices->push_back( osg::Vec3(0.0f,0.0f,mirror_height)+mirrorcenter );

                //创建纹理数组,并添加数据
                osg::Vec2Array* texcoords = new osg::Vec2Array();
                texcoords->push_back( osg::Vec2(0.0f,0.0f) );
                texcoords->push_back( osg::Vec2(1.0f,0.0f) );
                texcoords->push_back( osg::Vec2(1.0f,1.0f) );
                texcoords->push_back( osg::Vec2(0.0f,1.0f) );
               

                polyGeom->setVertexArray(vertices);
               

                //使用vbo扩展
                {
                        osg::VertexBufferObject* vbObject = new osg::VertexBufferObject;
                        //vertices->setVertexBufferObject(vbObject);

                        //polyGeom->setUseVertexBufferObjects(true);
                }

                polyGeom->setTexCoordArray(0,texcoords);

                //创建颜色数组,并设置绑定方式及添加数据
                //                 osg::Vec4Array* colors = new osg::Vec4Array;
                //                 colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
                //                 polyGeom->setColorArray(colors);
                //                 polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL);

                polyGeom->addPrimitiveSet(new osg::DrawArrays(osg:rimitiveSet:UADS,0,vertices->size()));

                //现在我们需要将纹理附加到该几何体上,我们创建一个包含该纹理的StateSet
                osg::StateSet* stateset = new osg::StateSet;

                stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
                stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);

                polyGeom->setStateSet(stateset);
                //polyGeom->setUpdateCallback(new MirrorCallback((*vertices)[0],(*vertices)[1],(*vertices)[2],(*vertices)[3]));
                               Mycallback* mycb = new osg::Mycallback(osg::Vec3(0.f,0.f,0.f),osg::Vec3(2.f,0.f,0.f),osg::Vec3(2.f,2.f,0.f),osg::Vec3(0.f,2.f,0.f));
                polyGeom->setUpdateCallback(mycb);

在回调函数里我是这样做的:
class MyCallback :
        public osg::Drawable::UpdateCallback
{
public:
        MyCallback(osg::Vec3& lu,osg::Vec3& lb,osg::Vec3& ru,osg::Vec3& rb):
          leftup(lu),
                  leftbottom(lb),
                  rightup(ru),
                  rightbottom(rb)
          {
                  //extracted_verts=new osg::Vec3Array;
          }
          ~MyCallback()
          {

          }


          virtual void update(osg::NodeVisitor* nv,osg::Drawable* drawable)
          {                   
                  //drawable->dirtyBound();

                  osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(drawable);       
                                     osg::Vec3Array* vertices= dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
                  
                                   (*vertices)[0]=leftup;
                                   (*vertices)[1]=leftbottom;
                                   (*vertices)[2]=rightup;
                                   (*vertices)[3]=rightbottom;

                                   geometry->setVertexArray(vertices);
                                                                geometry->dirtyDisplayList();

                                  

          }


public:
        osg::Vec3 leftup,leftbottom,rightup,rightbottom;
};
通过改变leftup,leftbottom,rightup,rightbottom来改变长方形的大小,但是没反应,什么地方不对呢?

该用户从未签到

发表于 2009-7-25 20:16:19 | 显示全部楼层
简单的给一段我正在编写的书中的示例代码吧,这段代码画了一条转圈的线,我没有试验您的程序。我用的VBO(您的VBO用法有误)
不过我真的很不愿意提供整段的代码,因为这在大多数情况下只能妨碍您的学习~~
  1. class DynamicLineCallback : public osg::Drawable::UpdateCallback
  2. {
  3. public:
  4.     DynamicLineCallback() : _angle(0.0) {}
  5.    
  6.     virtual void update( osg::NodeVisitor* nv, osg::Drawable* drawable )
  7.     {
  8.         osg::Geometry* geom = dynamic_cast<osg::Geometry*>( drawable );
  9.         if ( !geom ) return;
  10.         
  11.         osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() );
  12.         if ( vertices )
  13.         {
  14.             for ( osg::Vec3Array::iterator itr=vertices->begin(); itr!=vertices->end()-1; ++itr )
  15.                 itr->set( (*(itr+1)) );
  16.             
  17.             _angle += 1.0 / 10.0;
  18.             osg::Vec3& pt = vertices->back();
  19.             pt.set( 10.0*cos(_angle), 0.0, 10.0*sin(_angle) );
  20.             vertices->dirty();
  21.         }
  22.     }

  23. protected:
  24.     float _angle;
  25. };

  26. int main( int argc, char** argv )
  27. {
  28.     osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array( 10 );
  29.     for ( unsigned int i=0; i<10; ++i )
  30.         (*vertices)[i].set( float(i), 0.0, 0.0 );
  31.    
  32.     osg::ref_ptr<osg::Geometry> lineGeom = new osg::Geometry;
  33.     lineGeom->setVertexArray( vertices.get() );
  34.     lineGeom->addPrimitiveSet( new osg::DrawArrays(osg::DrawArrays::LINE_STRIP, 0, 10) );
  35.    
  36.     lineGeom->setInitialBound( osg::BoundingBox(osg::Vec3(-10.0,-10.0,-10.0), osg::Vec3(10.0,10.0,10.0)) );
  37.     lineGeom->setUpdateCallback( new DynamicLineCallback );
  38.     lineGeom->setUseDisplayList( false );
  39.     lineGeom->setUseVertexBufferObjects( true );
  40.    
  41.     osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  42.     geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
  43.     geode->getOrCreateStateSet()->setAttribute( new osg::LineWidth(2.0) );
  44.     geode->addDrawable( lineGeom.get() );
  45.    
  46.     osgViewer::Viewer viewer;
  47.     viewer.setSceneData( geode.get() );
  48.     return viewer.run();
  49. }
复制代码

该用户从未签到

 楼主| 发表于 2009-7-25 20:39:51 | 显示全部楼层
非常感谢!回去学习下。

该用户从未签到

发表于 2009-7-26 08:52:06 | 显示全部楼层
如果仅是改变矩形的大小,没必要每次改变顶点,使用Transform更好一些
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表