查看: 1461|回复: 1

如何在已有的OpenGL代码中用osg粒子系统实现特效

[复制链接]

该用户从未签到

发表于 2010-5-16 14:12:48 | 显示全部楼层 |阅读模式
如何在已有的OpenGL代码中用osg的粒子系统实现雨雪特效?

该用户从未签到

发表于 2010-5-16 18:10:47 | 显示全部楼层
Q 34: 可以在一个已有的渲染系统中使用OSG吗? ¶
A: 这有一定的难度,不过在一个已有的渲染系统中使用OSG是完全可能的。
首先,OSG的核心部件是osgUtil::SceneView。这个类负责管理OSG特有的渲染任务。如果你希望用到OSG的动画特性,那么还需要构建自己的FrameStamp对象。
这两个对象的设置如下所示:
unsigned int frameNumber = 0;
osg::Timer timer;
osg::Timer_t start_tick = timer.tick();
osg::ref_ptr<osgUtil::SceneView> sceneViewer = new osgUtil::SceneView();
osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp();

sceneViewer->setDefaults();
sceneViewer->setComputeNearFarMode( osgUtil::CullVisitor:O_NOT_COMPUTE_NEAR_FAR );
sceneViewer->setSceneData( rootNode );
注意,这里需要把rootNode替换为实际的OSG模型节点。
注意,上面的代码调用了setComputeNearFarMode函数,这一点非常重要。否则的话,OSG可能会在渲染对象时使用不同的远/近平面,因而对象在深度缓存中的数值也可能与其它场景不同,因而产生一些古怪的错误。
如果你希望使用与渲染器其它部分不同的光照,在这里可以调用:
sceneViewer->setLightingMode( osgUtil::SceneView::SKY_LIGHT );
或者
sceneViewer->setLightingMode( osgUtil::SceneView::HEADLIGHT );
基本的设置过程就是这样。
现在我们需要调用SceneView以进行渲染,这还需要下面所述的一些工作。
第一,建议用户在OpenGL代码执行之前,对所有的模型观察矩阵(modelview),投影矩阵(projection)和纹理矩阵(texture)都调用glPushAttribs( GL_ALL_ATTRIB_BITS )和glPushMatrix,并在用户代码执行完毕之后调用相应的glPopAttribs和glPopMatrix函数,对OSG代码也作同样处理。这样可以避免OSG与其它OpenGL代码产生冲突,示例如下:
glPushAttrib( GL_ALL_ATTRIB_BITS );
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();

用户或者OSG的执行代码...

glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
此外,在使用SceneView时,用户需要将已有的视口、投影和模型观察矩阵传递给该对象。示例代码如下:
GLint viewParams[4];
glGetIntegerv( GL_VIEWPORT, viewParams );
sceneViewer->setViewport(viewParams[0], viewParams[1], viewParams[2], viewParams[3]);

GLfloat glMat[16];
osg::Matrix osgMat;

glGetFloatv( GL_PROJECTION_MATRIX, glMat );
osgMat.set( glMat );
sceneViewer->getProjectionMatrix().set( osgMat );

glGetFloatv( GL_MODELVIEW_MATRIX, glMat );
osgMat.set( glMat );
sceneViewer->getViewMatrix().set( osgMat );
下一步是更新FrameStamp对象(如果你使用自己编写的类):
double time_since_start = timer.delta_s( start_tick, timer.tick() );
frameStamp->setReferenceTime( time_since_start );
frameStamp->setFrameNumber( frameNumber++ );
sceneViewer->setFrameStamp( frameStamp.get() );
最后,你可以调用SceneView对象的方法了:
sceneViewer->update ();
sceneViewer->cull ();
sceneViewer->draw ();
如果上述的过程都正确,应当可以成功地在另外的渲染系统中使用OSG了,这样可以利用OSG的诸多优势,而不必担心出现系统之间的冲突
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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